At-rules

CSS at-rules start with the @ character and are followed by a keyword or identifier. They always have to end with a semicolon (;) character.

Some of the most popular at-rules are @font-face, which is used to declare custom fonts; @import that is used to import external CSS files (not recommended by the way for performance reasons), and it is also used in some CSS preprocessors to bring external partial files that will eventually get compiled into a single CSS file (recommended method); @media is used to declare media queries in our responsive projects or print style sheets and so on; @keyframes is used to create animations and so on.

At-rules, let's see where they're at.

@charset

The @charset() at-rule defines the character encoding to be used by a style sheet, and it looks like this:

@charset "UTF-8";

Description

We rarely need to define the character encoding in a style sheet as long as it's defined in the HTML. When the browser detects the character encoding in the HTML, it implies that it's the same character encoding for the CSS file(s).

If you like to declare the character encoding in your CSS files, that's fine too. If you plan to use this in a style sheet, it should be the first thing at the top of the file. It cannot have a space character before the @ symbol, or a blank line above it. The character encoding name should always be inside quotes, either single (' ') or double quotes (" ").

CSS:

/*Correct character encoding directive*/
@charset "UTF-8";
/*Character encoding of the CSS is set to Latin-9 (Western European languages, with Euro sign)*/
@charset 'iso-8859-15';
/*This is invalid, there is a space before the @ symbol*/
 @charset "UTF-8";
/*This is invalid, character encoding name should be inside single [''] or double quotes [""]*/
@charset UTF-8;

@document()

The @document() at-rule allows to define styles that only apply to a certain pages of a site, and it looks like this in one of its forms:

@document url('http://website.com/page.html') { ... }

Description

There are four CSS functions that are exclusive to the @document() at-rule: url(), url-prefix(), domain(), and regexp(" "). Multiple functions can be defined in a single declaration.

The values inside the functions can either be declared without quotation marks, or use single (' ') or double quotes (" "). Only the regexp("") function requires the use of double quotes (" ").

  • url(): This restricts the styles to a document that matches the URL
  • url-prefix(): This restricts the styles to a document that start with the specified URL
  • domain(): This restricts the styles to a document's specific domain
  • regexp(""): This restricts the styles to a document that match the regular expression

CSS:

/*url() function*/
@document url('http://website.com/page.html') { ... }
/*url-prefix() function*/
@document url-prefix("http://website.com/about/") { ... }
/*domain() function*/
@document domain(website.com) { ... }
/*regexp() function*/
@document regexp("https:.*")
/*Multiple functions in a single declaration*/
@document url('http://website.com/page.html') { ... },
  url-prefix("http://website.com/about/") { ... },
  domain(website.com) { ... },
  regexp("https:.*") { ... }

@font-face

The @font-face() at-rule is used to define custom fonts to use on a document, and it looks like this in its simplest form:

@font-face {
  font-family: Franchise; 
  src: url("../fonts/franchise.woff") format("woff");
}

Description

The @font-face() at-rule has been around for actually more years than many believe, so our buddy IE6 supports this function. With the @font-face() at-rule, we can target custom font files to use on a website/webapp and extend the design and branding possibilities way beyond system fonts.

One peculiarity of custom fonts is that different versions of each browser support one format but not another or even has its own proprietary font format.

Paul Irish's article Bulletproof @font-face Syntax, where the smiley face technique originated, is a must-read @font-face article for all web designers and developers (http://tiny.cc/paul-irish-font-face).

The five font formats we need to account for are: WOFF/WOFF2, EOT, TTF, OTF, and SVG.

WOFF/WOFF2

WOFF stands for Web Open Font Format and was created by Mozilla. The WOFF format is a wrapper for OTF/TTF font formats and it provides better font data compression than any other format, thus making the file(s) smaller.

WOFF2 is basically WOFF on steroids. It provides even more compression, about 30 percent in average and in some cases up to 50 percent more.

All modern browsers support these two formats.

EOT

EOT stands for Embedded Open Type and was created by Microsoft. Only old versions of IE (IE6 to IE8) require the use of this font format. No other browsers support this format, so if we don't need to support legacy browsers, we do not need to declare a link to this font format in the @font-face() at-rule declaration.

OTF and TTF

OTF and TTF stand for OpenType Font and TrueType Font. These font formats are cross-platform compatible and include advanced layout features and information for expert typographic control. OTF is a newer format and has a few more features than TTF, such as small caps, ligatures, fractions, and so on.

SVG

SVG stands for Scalable Vector Graphic. An SVG font file doesn't really have a font; it has vector representations of the font. This type of font file is used when old iOS devices need to be supported. However, if this type of font is not declared, the old iOS device will simply use a system font instead, which if you ask me, I'm totally fine with.

The values inside the @font-face brackets are called the font descriptors. In it, we can declare several values: font-family, src, font-variant, font-stretch, font-style, font-weight, and unicode-range.

font-family

This is a required value. It defines the name of the font to be used in the style sheet.

src

This is a required value. It defines the location or URL of the font file(s). Multiple URLs can be defined in the same src declaration block to account for the different types of fonts that each browser supports. However, legacy IEs choke when it finds multiple URLs in the same src declaration block, so an independent src declaration block needs to be declared if support for legacy IEs is required.

In addition to targeting external files with URLs, we can also target locally installed files with the local() function.

font-variant

The font-variant CSS property turns the targeted text into small caps. In CSS3, it's considered a shorthand and has been extended with new values, which developers rarely use. Refer to Chapter 5, CSS Properties – Part 2, for more information.

font-stretch

The font-stretch CSS property allows us to select a condensed, normal, or expanded face from the font family in question. Refer to Chapter 5, CSS Properties – Part 2, for more information.

font-weight

The font-weight CSS property defines the thickness (weight) of the font. Refer to Chapter 5, CSS Properties – Part 2, for more information.

unicode-range

The unicode-range CSS property descriptor defines a specific range of characters or glyphs that should be downloaded from a font declared in a @font-face declaration. This is helpful, for example, when working on a site with different languages. By declaring unicode-range, the browser only downloads the specific characters of that language for that page, thus saving bandwidth and optimizing performance.

This property is rarely used.

Google fonts

We can't talk about @font-face without talking about Google Fonts. Google Fonts is a free web font service that allows us to practically skip all the manual work of creating @font-face declaration block in our CSS files by giving us an HTML <link> that points to the font(s) we selected.

Check out Google Fonts at http://tiny.cc/google-fonts

HTML:

<!-- Google Fonts link snippet -->
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>

CSS:

/*Full descriptive @font-face declaration*/
@font-face {
  font-family: Roboto;
    /*IE9 Compat Modes*/
  src: url("../fonts/roboto.eot");
    /*Locally installed font file*/
  src: local("roboto"),
    /*IE6-IE8*/
    url("../fonts/roboto.eot?#iefix") format("embedded-opentype"),
    /*Modern Browsers*/
    url("../fonts/roboto.woff2") format("woff2"),
    url("../fonts/roboto.woff") format("woff"),
    /*Safari, Android, iOS*/
    url("../fonts/roboto.ttf") format("truetype"),
    /*Old iOS devices*/
    url("../fonts/roboto.svg#roboto") format("svg");
  /*Unicode range*/
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  /*Font properties*/
  font-weight: normal;
  font-style: normal;
}

/*Recommended @font-face syntax*/
@font-face {
  font-family: Roboto;
  src: url("../fonts/roboto.woff2") format("woff2"),
       url("../fonts/roboto.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

/*Usage*/
.element {
  font-family: Roboto, Arial, Helvetica, san-serif;
}

@import

The @import() at-rule is used to import a style sheet into another, and it looks like this:

@import "other-style-sheet.css";

Description

The previous example targets another style sheet with a string value. But style sheets can also be imported using the url() function.

The @import rules should always precede any other rules except the @charset rule, otherwise, it will be ignored by the browser.

One thing to take into consideration is cascading. Imported style sheets cascade in the order they are imported. There is also a way to specify the media a specific imported style sheet is for via media queries. If more than one media query is declared, it needs to be separated by commas.

Tip

It's a known fact that using @import has a negative impact on performance due to sequential downloading instead of parallel downloads and multiple HTTP requests. Read more about this issue on Steve Souders' article Don't Use @import at http://tiny.cc/steve-souders-avoidimport

CSS:

/*Import a style sheet in the same directory*/
@import "other-style-sheet.css";
/*Import a style sheet from a relative path*/
@import url(../other-stylesheets/other-style-sheet.css);
/*Import a style sheet with an absolute path*/
@import url(http://website.com/other-stylesheets/other-style-sheet.css);
/*Define a print style sheet with the 'print' media query*/
@import "print.css" print;
/*Declare multiple media queries*/
@import "screen.css" screen, projection;
/*Use more a commonly known media query*/
@import url("portrait.css") screen and (orientation: portrait);

@keyframes

The @keyframes() at-rule is used to list CSS properties to be animated, and it looks like this:

@keyframes animationName {
  from {
    /*Animation properties START here*/
  }
  to {
    /*Animation properties END here*/
  }
}

Description

The animation created with the @keyframes at-rule only runs for one cycle. If we want the animation to play over and over, ease-in, ease-out, or show other behavior, we need to declare those properties in the element itself, outside the @keyframes at-rule.

Please refer to the Animation section in Chapter 4, CSS Properties – Part 1, for detailed explanations of those CSS properties.

The animation's name (also called an identifier) always comes after the @keyframes keyword separated by a space. This animation name will later be referenced with the animation-name or animation shorthand CSS properties.

The beginning and end of an animation can be declared with the two selector keywords from and to, or with two keyframe selectors 0% and 100%. Negative values are not allowed.

Obviously, we can declare intermediate waypoints but we can only do this using keyframe selectors. There is no limit to the amount of properties that can be declared in the @keyframes at-rule. However, some browsers animate properties that the spec says can't be animated, while others follow the spec correctly. Granted, the spec is unclear about some of the definitions, so make sure to run proper tests.

Now the difference between using @keyframes at-rule and the transition property is that with the @keyframes at-rule we have the power of defining what happens in the middle waypoints rather than letting the browser figure it out for us.

Basically, if we have a simple animation, we can just use the transition property. If we have somewhat more complex and elaborate animations, use @keyframes.

CSS:

@keyframes diamond {
  from {
    top: 0;
    left: 0;
  }
  25% {
    top: 200px;
    left: -200px;
  }
  50% {
    top: 400px;
    left: 0;
  }
  75% {
    top: 200px;
    left: 200px;
  }
  to {
    top: 0;
    left: 0;
  }
}

.element {
  position: relative;
  animation: diamond 3s infinite ease-in-out;
}

@media

The @media() at-rule allows us to define a set of CSS styles that apply to a certain media type, and it looks like this:

@media (min-width: 40em) { ... }

You can use the preceding code or the following code as well:

@media print { ... }

Description

This piece of CSS allows us to declare any set of styles to a specific media type.

The two types of directives that come after the @media() at-rule, for example, print and screen and even (min-width: 40em) or (max-width: 40em), and they are called media queries.

The keywords (print and screen) are called media types. And the ones that test specific features of a User Agent (UA) or display are called media features.

Media types

Media types are case-sensitive. There are 10 media types that we can use with the @media() at-rule:

  • all: This is meant to work on all devices
  • braille: This is meant to work with braille tactile-feedback devices
  • embossed: This is meant to work on braille printers
  • handheld: This is meant to work with handled "mobile" devices
  • print: This is meant to work for printing documents
  • projection: This is meant to work with projectors
  • screen: This is meant to work with computer screens of all sizes
  • speech: This is meant to work with speech synthesizers
  • tty: This is meant to work with teletypes
  • tv: This is meant to work with televisions

CSS:

/*Viewport width media query*/
@media (min-width: 40em) {
  header { background: red; }
}
/*Print media query*/
@media print {
  *, *:before, *:after { background-image: none; }
}

@namespace

The @namespace() at-rule is used to define the XML namespaces in a style sheet, and it looks like this:

@namespace url(http://www.w3.org/1999/xhtml);

You can use the preceding code or the following code as well:

@namespace svg url(http://www.w3.org/2000/svg);

Description

We use the @namespace() at-rule in a CSS document when we need to use selectors that apply or target certain elements in a specific namespace. For example, we can have an embedded SVG file in our HTML document. The thing is that SVGs share common elements with HTML and XML, such as the <a> element. So instead of creating a separate style sheet to target the SVG elements, we can declare an SVG namespace with the @namespace() at-rule to target the <a> elements within the same HTML document, thus we only have to work in one style sheet rather than two (or more).

Now, the @namespace() at-rule is mostly used for legacy XHTML documents where it's necessary to declare a namespace in the <html> element:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

With the xmlns directive in place, we can now declare the namespaces in our CSS. Finally, we can then target the <a> elements in the SVG block without affecting the HTML <a> elements.

The URLs are merely to make the markup more readable and easier to understand when someone is reading through it.

XHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

CSS:

@namespace "http://www.w3.org/1999/xhtml";
@namespace svg "http://www.w3.org/2000/svg";

svg|a {
  background: orange;
}

@page

The @page() at-rule is used to modify certain properties of a page to get it ready for printing, and it looks like this:

@page {
  margin: 2cm;
}

Description

When using the @page() at-rule, only a few properties of the page can be changed: margins, widows, orphans, and page breaks. Declaring any other types of properties will be ignored.

We can also declare if we want to target only the first page, all the left pages only, or all the right pages only with the :first, :left and :right pseudo-classes. The @page() at-rule is most commonly used to change the margins.

CSS:

/*Affects all pages*/
@page {
  margin: 2cm;
}
/*Affects all left pages only*/
@page :left {
  margin: .8in;
  orphans: 3;
}
/*Affects all right pages only*/
@page :right {
  margin: 15mm;
}

@supports

The @supports() at-rule is used to detect a feature on a browser, and it looks like this:

@supports (display: flex) { ... }

Description

Feature detection is something that's usually done with polyfills like Modernizr. With the @supports() at-rule, we can accomplish similar results via CSS only.

In order for this function to work properly, we need to specify a property and a value. There are three keyword operators that we can use with the @supports() at-rule: not, and and or.

The not operator

Just like we can check for features that the browser supports, we can also check for features that the browser does not support using the not operator.

The and operator

The and operator allows us to check for multiple CSS properties in the same declaration.

The or operator

A good example of this operator is when we need to check for a vendor-prefixed CSS property in case we need to support legacy browsers. When using this operator, if one of the expressions is true, it will make all other expressions valid as well. Additionally, we can also combine operators when necessary.

CSS:

/*Detect a feature that is supported*/
@supports (transform: translateX(-50%)) {
  .element {
    transform: translateY(-50%)
  }
}
/*Detect a feature that is NOT supported*/
@supports not (transform: translateX(-50%)) {
  .element {
    margin-left: 120px;
  }
}
/*Detect multiple features*/
@supports (transform: translateX(-50%)) and (display: flex) {
  .element {
    transform: translateY(-50%);
    justify-content: space-between;
  }
}
/*Detect at least one feature*/
@supports (-webkit-box-pack: justify) or (-webkit-justify-content: space-between) or (-ms-flex-pack: justify) or (justify-content: space-between) {
  .element {
    justify-content: space-between;
  }
}
/*Combining conditions*/
@supports (transform: translateX(-50%)) and ( (-webkit-justify-content: space-between) or (justify-content: space-between) ) {
  transform: translateY(-50%);
  justify-content: space-between;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.39.144