at-rules Flashcards
aka @rules
What is an at-rule?
At-rules are CSS statements that instruct CSS how to behave. They begin with an at sign, @
(U+0040 COMMERCIAL AT
), followed by an identifier and includes everything up to the next semicolon, ;
(U+003B SEMICOLON
), or the next CSS block, whichever comes first.
“At-rules - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 26, 2024.
Syntax of at-rules
At-rules begin with an at sign, @
(U+0040 COMMERCIAL AT
), followed by an identifier and includes everything up to the next semicolon, ;
(U+003B SEMICOLON
), or the next CSS block, whichever comes first.
Regular
/* General structure */ @identifier (RULE); /* Example: tells browser to use UTF-8 character set */ @charset "utf-8";
There are several regular at-rules, designated by their identifiers, each with a different syntax:
-
@charset
— Defines the character set used by the style sheet. -
@import
— Tells the CSS engine to include an external style sheet. -
@namespace
— Tells the CSS engine that all its content must be considered prefixed with an XML namespace.
Nested
@identifier (RULE) { }
A subset of nested statements, which can be used as a statement of a style sheet as well as inside of conditional group rules.
-
@media
— A conditional group rule that will apply its content if the device meets the criteria of the condition defined using a media query. -
@scope
- A conditional group rule that will apply its content if the device meets the criteria of the given condition. -
@starting-style
- A conditional group rule that will apply starting transition if the browser meets the criteria of the given condition. -
@supports
— A conditional group rule that will apply its content if the browser meets the criteria of the given condition. -
@page
— Describes the aspect of layout changes that will be applied when printing the document. -
@font-face
— Describes the aspect of an external font to be downloaded. -
@keyframes
— Describes the aspect of intermediate steps in a CSS animation sequence. -
@counter-style
— Defines specific counter styles that are not part of the predefined set of styles. -
@font-feature-values
(plus@swash
,@ornaments
,@annotation
,@stylistic
,@styleset
and@character-variant
) — Define common names in font-variant-alternates for feature activated differently in OpenType. -
@property
— Describes the aspect of custom properties and variables. -
@layer
– Declares a cascade layer and defines the order of precedence in case of multiple cascade layers.
“At-rules - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 26, 2024.
What are conditional group rules?
Each at-rule has a different syntax. Nevertheless, several of them can be grouped into a special category named conditional group rules. These statements share a common syntax and each of them can include nested statements—either rulesets or nested at-rules. Furthermore, they all convey a common semantic meaning—they all link some type of condition, which at any time evaluates to either true or false. If the condition evaluates to true, then all of the statements within the group will be applied.
Conditional group rules are:
-
@media
— A conditional group rule that will apply its content if the device meets the criteria of the condition defined using a media query. -
@scope
- A conditional group rule that will apply its content if the device meets the criteria of the given condition. -
@supports
— A conditional group rule that will apply its content if the browser meets the criteria of the given condition.
Since each conditional group may also contain nested statements, there may be an unspecified amount of nesting.
“Conditional group rules” (MDN Web Docs). Retrieved March 26, 2024.
@import
CSS at-rule
The @import
CSS at-rule is used to import style rules from other valid stylesheets. An @import
rule must be defined at the top of the stylesheet, before any other at-rule (except @charset
and @layer
) and style declarations, or it will be ignored.
The @import
rule is not a nested statement. Therefore, it cannot be used inside conditional group at-rules.
The @import
rule can also be used to create a cascade layer by importing rules from a linked resource. Rules can also be imported into an existing cascade layer. The layer
keyword or the layer()
function is used with @import
for this purpose. Declarations in style rules from imported stylesheets interact with the cascade as if they were written literally into the stylesheet at the point of the import.
Syntax
@import url; @import url layer; @import url layer(layer-name); @import url layer(layer-name) supports(supports-condition); @import url layer(layer-name) supports(supports-condition) list-of-media-queries; @import url layer(layer-name) list-of-media-queries; @import url supports(supports-condition); @import url supports(supports-condition) list-of-media-queries; @import url list-of-media-queries;
where:
-
url
- Is a<string>
, a<url>
or aurl()
function representing the location of the resource to import. The URL may be absolute or relative. -
list-of-media-queries
- Is a comma-separated list of media queries, which specify the media-dependent conditions for applying the CSS rules defined in the linked URL. If the browser does not support any of these queries, it does not load the linked resource. -
layer-name
- Is the name of a cascade layer into which the contents of the linked resource are imported. -
supports-condition
- Indicates the feature(s) that the browser must support in order for the stylesheet to be imported. If the browser does not conform to the conditions specified in the supports-condition, it may not fetch the linked stylesheet, and even if downloaded through some other path, will not load it. The syntax ofsupports()
is almost identical to that described in@supports
, and that topic can be used as a more complete reference.
“@import - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 27, 2024.
What is the problem with this styles?
* { margin: 0; padding: 0; } /* more styles */ @import url("my-imported-styles.css");
As the @import
at-rule is declared after the styles, it is invalid and hence ignored.
@import url("my-imported-styles.css"); * { margin: 0; padding: 0; } /* more styles */
“@import” (MDN Web Docs). Retrieved March 27, 2024.
Explain the following CSS rules
@import url("fineprint.css") print; @import url("bluish.css") print, screen; @import "common.css" screen; @import url("landscape.css") screen and (orientation: landscape)
The @import
rules in the above examples show media-dependent conditions that will need to be true before the linked CSS rules are applied. So for instance, the last @import
rule will load the landscape.css
stylesheet only on a screen device in landscape orientation.
“Importing CSS rules conditional on media queries” (MDN Web Docs). Retrieved March 27, 2024.
Explain the following CSS rules
@import url("gridy.css") supports(display: grid) screen and (max-width: 400px); @import url("flexy.css") supports(not (display: grid) and (display: flex)) screen and (max-width: 400px);
The @import
rules above illustrate how you might import a layout that uses a grid if display: grid
is supported, and otherwise imports CSS that uses display: flex
. While you can only have one supports()
statement, you can combine any number of feature checks with not
, and
, and or
, as long as you wrap each condition to be tested in parentheses. You can also use parentheses to indicate precedence. Note that if you just have a single declaration then you don’t need to wrap it in additional parenthese: this is shown in the first example above.
“Importing CSS rules conditional on feature support” (MDN Web Docs). Retrieved March 27, 2024.
Explain the following CSS rule
@import url("whatever.css") supports((selector(h2 > p)) and (font-tech(color-COLRv1)));
The CSS rule above shows an @import
that is conditional on both child combinators (selector()
) and the font-tech()
function.
“Importing CSS rules conditional on feature support” (MDN Web Docs). Retrieved March 27, 2024.
Explain the following CSS rules
@import url(headings.css) layer(default); @import url(links.css) layer(default); @layer default { audio[controls] { display: block; } }
The CSS rules in headings.css
and links.css
stylesheets cascade within the same layer as the audio[controls]
rule.
“Importing CSS rules into a cascade layer” (MDN Web Docs). Retrieved March 27, 2024.
@namespace
CSS at-rule
@namespace
is an at-rule that defines XML namespaces to be used in a CSS style sheet.
Syntax
/* Default namespace */ @namespace url(XML-namespace-URL); @namespace "XML-namespace-URL"; /* Prefixed namespace */ @namespace prefix url(XML-namespace-URL); @namespace prefix "XML-namespace-URL";
Description
The defined namespaces can be used to restrict the universal, type, and attribute selectors to only select elements within that namespace. The @namespace
rule is generally only useful when dealing with documents containing multiple namespaces—such as HTML with inline SVG or MathML, or XML that mixes multiple vocabularies.
Any @namespace
rules must follow all @charset
and @import
rules, and precede all other at-rules and style declarations in a style sheet.
@namespace
can be used to define the default namespace for the style sheet. When a default namespace is defined, all universal and type selectors (but not attribute selectors, see note below) apply only to elements in that namespace.
The @namespace
rule can also be used to define a namespace prefix. When a universal, type, or attribute selector is prefixed with a namespace prefix, then that selector only matches if the namespace and name of the element or attribute matches.
In HTML, known foreign elements will automatically be assigned namespaces. This means that HTML elements will act as though they are in the XHTML namespace, even if there is no xmlns
attribute anywhere in the document, and the <svg>
and <math>
elements will be assigned their proper namespaces.
Note: In XML, unless a prefix is defined directly on an attribute (e.g., xlink:href
), that attribute has no namespace. In other words, attributes do not inherit the namespace of the element they’re on. To match this behavior, the default namespace in CSS does not apply to attribute selectors.
Examples:
@namespace url(http://www.w3.org/1999/xhtml); @namespace svg url(http://www.w3.org/2000/svg); /* This matches all XHTML <a> elements, as XHTML is the default unprefixed namespace */ a { } /* This matches all SVG <a> elements */ svg|a { } /* This matches both XHTML and SVG <a> elements */ *|a { }
“@namespace - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 28, 2024.
@charset
CSS rule
The @charset
CSS rule specifies the character encoding used in the style sheet. Although the first character in @charset
is the @
symbol, it is not an at-rule. The CSS syntax module deprecates this rule, defining it as an unrecognized legacy rule to be dropped when a stylesheet is grammar-checked, but it is fully supported in all browsers.
Syntax
@charset "UTF-8"; @charset "iso-8859-15";
Formal syntax
@charset "<charset>";
charset
- A <string>
denoting the character encoding to be used. It must be the name of a web-safe character encoding defined in the IANA-registry, and must be double-quoted, following exactly one space character (U+0020
), and immediately terminated with a semicolon. If several names are associated with an encoding, only the one marked with preferred must be used.
“@charset - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 29, 2024.
@scope
CSS at-rule
The @scope
CSS at-rule enables you to select elements in specific DOM subtrees, targeting elements precisely without writing overly-specific selectors that are hard to override, and without coupling your selectors too tightly to the DOM structure.
In JavaScript, @scope
can be accessed via the CSS object model interface CSSScopeRule.
Syntax
@scope
can be used in two ways:
- As a standalone block inside your CSS, in which case it includes a prelude section that includes scope root and optional scope limit selectors — these define the upper and lower bounds of the scope.
@scope (scope root) to (scope limit) { rulesets }
- As inline styles included inside a
<style>
element in your HTML, in which case the prelude is omitted, and the enclosed ruleset is automatically scoped to the<style>
element’s enclosing parent element.
HTML
<parent-element> <style> @scope { rulesets } </style> </parent-element>
NOTE: It is important to understand that, while @scope
allows you to isolate the application of selectors to specific DOM subtrees, it does not completely isolate the applied styles to within those subtrees. This is most noticeable with inheritance — properties that are inherited by children (for example color
or font-family
) will still be inherited, beyond any set scope limit.
NOTE 2: At the moment of this writing support for this at-rule is limite please check its browser compatibility table before use.
“@scope - CSS: Cascading Style Sheets | MDN” (MDN Web Docs). Retrieved March 29, 2024.
What does :scope
pseudo-class refers to in the following CSS ruleset
@scope (.feature) { :scope { background: rebeccapurple; color: antiquewhite; font-family: sans-serif; } }
In the context of a @scope
block, the :scope
pseudo-class represents the scope root — it provides an easy way to apply styles to the scope root itself, from inside the scope. In the example CSS provided :scope
will refer to .feature
elements.
In fact, :scope
is implicitly prepended to all scoped style rules. If you want, you can explicitly prepend :scope
or prepend the nesting selector (&
) to get the same effect if you find these representations easier to understand.
The three rules in the following block are all equivalent in what they select:
@scope (.feature) { img { ... } :scope img { ... } & img { ... } }
“The :scope pseudo-class” (MDN Web Docs). Retrieved March 29, 2024.
What is the difference between :scope
and &
inside @scope
at-rule?
:scope
represents the matched scope root, whereas &
represents the selector used to match the scope root. Because of this, it is possible to chain &
multiple times. However, you can only use :scope
once — you can’t match a scope root inside a scope root.
@scope (.feature) { /* Selects a .feature inside the matched root .feature */ & & { ... } /* Doesn't work */ :scope :scope { ... } }
“The difference between :scope and & inside @scope” (MDN Web Docs). Retrieved March 29, 2024.
How are @scope
conflicts are resolved?
@scope
adds a new criterion to the CSS cascade: scoping proximity. This states that when two scopes have conflicting styles, the style that has the smallest number of hops up the DOM tree hierarchy to the scope root is applied. Let’s look at an example to see what this means.
Take the following HTML snippet, where different-themed cards are nested inside one another:
HTML
<div class="light-theme"> <p>Light theme text</p> <div class="dark-theme"> <p>Dark theme text</p> <div class="light-theme"> <p>Light theme text</p> </div> </div> </div>
If you wrote the theme CSS like so, you’d run into trouble:
.light-theme { background: #ccc; } .dark-theme { background: #333; } .light-theme p { color: black; } .dark-theme p { color: white; }
The innermost paragraph is supposed to be colored black because it is inside a light theme card. However, it’s targeted by both .light-theme p
and .dark-theme p
. Because the .dark-theme p
rule appears later in the source order, it is applied, and the paragraph ends up being wrongly colored white.
To fix this, you can use @scope
as follows:
CSS
@scope (.light-theme) { :scope { background: #ccc; } p { color: black; } } @scope (.dark-theme) { :scope { background: #333; } p { color: white; } }
Now the innermost paragraph is correctly colored black. This is because it is only one DOM tree hierarchy level away from the .light-theme
scope root, but two levels away from the .dark-theme
scope root. Therefore, the light style wins.
“How @scope conflicts are resolved” (MDN Web Docs). Retrieved March 29, 2024.