CSS At-Rules
In this page:
Declaring File Encoding with @charset
@charset tells the browser which character encoding a stylesheet file uses, which matters when your CSS contains non-ASCII characters like curly quotes or accented letters inside content: strings. It must be the literal first characters in the file -- not even a comment can come before it -- or the browser silently ignores it.
Note: Save your CSS file itself as UTF-8 and declare @charset "UTF-8"; together, so the declared encoding always matches the file's actual bytes.
Warning: Any character, comment, or whitespace before @charset in the file causes browsers to ignore the declaration entirely.
Example: Declaring File Encoding with @charset
@charset "UTF-8";
p::before {
content: "“";
}
Naming XML Namespaces with @namespace
@namespace is used mainly in XML-based documents like SVG or XHTML to associate a CSS prefix with an XML namespace URI, letting selectors like svg|circle target elements from a specific namespace only. In plain HTML documents it is rarely needed, since HTML has just one implicit namespace.
Note: Reach for @namespace mainly when styling inline SVG elements that mix custom XML namespaces alongside standard SVG markup.
Warning: @namespace must be declared after any @charset or @import rules but before all other style rules, or it will be ignored.
Example: Naming XML Namespaces with @namespace
@namespace svg url(http://www.w3.org/2000/svg);
svg|circle {
fill: red;
}
Limiting Rule Scope with @scope
@scope wraps a block of CSS rules so their selectors only match elements within a specific DOM subtree, defined by a scoping root and an optional scoping limit. This solves a long-standing problem: applying a rule only "within this card" without needing to prefix every single selector with a unique class name.
Note: Use @scope for component-style CSS where you want a rule like "p { color: red; }" to apply only inside a specific card, not globally across the page.
Warning: The scoping limit you set (to:) excludes elements from that point downward, which can accidentally exclude nested content you meant to still style.
Example: Limiting Rule Scope with @scope
@scope (.card) {
p {
color: red;
}
}
Animating Entrances with @starting-style
@starting-style defines the "before" values a transition animates from when an element that was previously display: none (or newly added to the DOM) first becomes visible. Normally CSS transitions cannot animate an element's very first appearance, since there is no prior state to transition from -- @starting-style provides that missing starting point.
Note: Pair @starting-style with transition-behavior: allow-discrete when animating properties like display, so the entrance transition has a defined starting point.
Warning: @starting-style only affects the very first render after a discrete property change (like display: none to block); it does not apply to ordinary hover or class-toggle transitions.
Example: Animating Entrances with @starting-style
@starting-style {
.box {
opacity: 0;
}
}
.box {
opacity: 1;
transition: opacity 0.3s;
}
Building Custom Counters with @counter-style
@counter-style lets you define an entirely custom counter symbol system beyond the built-in list (decimal, roman, disc, and so on) -- for example, custom bullet glyphs, a specific prefix and suffix, or a repeating custom symbol set. It gives ordered and unordered lists a level of styling control that list-style-type alone cannot reach.
Note: Give your @counter-style a descriptive name and reuse it across multiple lists via list-style-type for consistent custom bullets sitewide.
Warning: @counter-style requires a system descriptor (like cyclic or fixed) to be declared, or the browser will not know how to cycle through your custom symbols.
Example: Building Custom Counters with @counter-style
@counter-style thumbs {
system: cyclic;
symbols: "👍";
suffix: " ";
}
ul {
list-style: thumbs;
}
- Placing @charset anywhere other than the very first line of the very first stylesheet, where browsers require it to be recognized at all.
- Using @scope and assuming it behaves like a CSS class-based namespace, when it actually limits which elements a rule's selectors can match based on DOM position.
- Forgetting that @starting-style only applies to a transition when the element is also changing display from none, not on every entrance transition.
- @charset declares a stylesheet's text encoding and must be the very first thing in the file to take effect.
- @scope limits a block of CSS rules to a specific DOM subtree, and @counter-style defines fully custom counter symbols beyond the built-in list.
- @starting-style defines the "before" state for CSS transitions that animate an element as it first appears in the DOM.
@charset, @namespace, and @counter-style are broadly supported; @scope and @starting-style are newer additions supported in current Chromium and Firefox releases, with Safari catching up.
Chapter Quiz — Complete all 25 topics to unlock
0/25 topics done
Complete these topics first:
- CSS Container Queries
- CSS Subgrid
- CSS Logical Properties
- CSS Logical Sizing
- CSS Writing Modes
- CSS Aspect Ratio
- CSS Object Fit
- CSS object-position
- CSS Masking
- CSS Math Functions
- CSS Motion Path
- CSS @supports
- CSS @property
- CSS At-Rules
- CSS Cursor
- CSS Will Change
- CSS User Interface
- CSS Print Styles
- CSS Pagination (Print)
- CSS Dark Mode
- CSS Accessibility
- CSS Performance
- CSS Preprocessors
- CSS Frameworks Overview
- CSS Interview Prep