CSS At-Rules
In this page:
@media (condition) { }
@import url("file.css");
@font-face { }
@keyframes name { }
@supports (property: value) { }
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.
- 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.
- Accepted values:
- @charset "UTF-8"; — the only widely supported encoding
- must be first — nothing may precede it, not even a comment
- double quotes — required, single quotes are not valid
- exactly one — only the first is honored
Example: Declaring File Encoding with @charset
<style>
p { font-size: 1.2rem; }
@charset "UTF-8";
p::before {
content: "“";
}
</style>
<p>The opening quote before this text comes from CSS.</p>
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.
- Reach for @namespace mainly when styling inline SVG elements that mix custom XML namespaces alongside standard SVG markup.
- Accepted values:
- @namespace url(<uri>); — sets the default namespace
- @namespace <prefix> url(<uri>); — declares a prefix
- prefix|element — selector using a prefix
- |element — any namespace
Example: Naming XML Namespaces with @namespace
<style>
@namespace svg url(http://www.w3.org/2000/svg);
svg|circle {
fill: red;
}
</style>
<!-- @namespace svg targets SVG elements; it must precede other rules -->
<svg width="120" height="120"><circle cx="60" cy="60" r="50" /></svg>
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.
- 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.
- Accepted values:
- @scope (<root>) — styles apply inside the root
- @scope (<root>) to (<limit>) — donut scope with a lower boundary
- :scope — refers to the scope root
- proximity — the closer scope wins over specificity ties
Example: Limiting Rule Scope with @scope
<style>
.card { border: 2px solid #1e6fd9; padding: 8px; }
@scope (.card) {
p {
color: red;
}
}
</style>
<div class="card"><p>Inside @scope: red</p></div>
<p>Outside the scope: unaffected</p>
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.
- Pair @starting-style with transition-behavior: allow-discrete when animating properties like display, so the entrance transition has a defined starting point.
- Accepted values:
- @starting-style { ... } — defines the style before the first render
- transition: opacity 0.3s — animates from the starting style
- display: none to block — works with allow-discrete transitions
Example: Animating Entrances with @starting-style
<style>
.box { padding: 20px; background: #cfe8ff; border: 2px solid #1e6fd9; }
@starting-style {
.box {
opacity: 0;
}
}
.box {
opacity: 1;
transition: opacity 0.3s;
}
</style>
<div class="box">Fades in when inserted</div>
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.
- Give your @counter-style a descriptive name and reuse it across multiple lists via list-style-type for consistent custom bullets sitewide.
- Accepted values:
- system: cyclic | numeric | alphabetic | symbolic | additive | fixed | extends — how counters are generated
- symbols: <symbol> — the markers used
- suffix: <string> — text after the marker
- prefix: <string> — text before the marker
- range: <lower> <upper> | auto — counter range
Example: Building Custom Counters with @counter-style
<style>
@counter-style thumbs {
system: cyclic;
symbols: "👍";
suffix: " ";
}
ul {
list-style: thumbs;
}
</style>
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
- 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