Use @media for responsive design with media queries
Apply @supports for progressive enhancement and feature detection
Create animations with @keyframes and control their behavior
Organize styles with @layer to control cascade priority
Scope styles with @scope to prevent style leakage
Build component-responsive layouts with @container queries
Register typed custom properties with @property for animations
Load custom fonts with @font-face and optimize display
Understand other at-rules: @import, @charset, @namespace, @page, @counter-style
Introduction to At-Rules
CSS at-rules are statements that begin with @ and instruct CSS how to behave. Unlike regular CSS rules that select and style elements, at-rules control broader aspects: importing stylesheets, defining animations, querying device features, organizing cascade layers, and more.
Metadata - @charset, @namespace (provide information about the stylesheet)
Print - @page (control printed output)
@media - Media Queries
Media queries apply CSS conditionally based on device characteristics like viewport width, orientation, color scheme preferences, and more. They're the foundation of responsive design.
Define the intermediate steps in a CSS animation sequence. You specify styles at various points (0%, 50%, 100%) and the browser smoothly interpolates between them.
Conditionally apply CSS based on whether the browser supports a specific feature. Perfect for progressive enhancement - provide fallbacks for older browsers while using modern features in newer ones.
/* Simple feature detection */
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
@supports not (display: grid) {
.container {
display: flex;
flex-wrap: wrap;
}
}
/* Combined conditions with AND */
@supports (display: flex) and (gap: 1rem) {
.flex-container {
display: flex;
gap: 1rem; /* Only use gap if both features supported */
}
}
/* Alternative conditions with OR */
@supports (display: grid) or (display: flex) {
.layout {
/* Use modern layout if either is supported */
}
}
/* Progressive enhancement example */
.card {
background: white; /* Fallback */
}
@supports (backdrop-filter: blur(10px)) {
.card {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(10px);
}
}
@layer - Cascade Layers
Explicitly control the cascade order of your styles, making specificity more predictable. Layers defined earlier have lower priority than layers defined later, regardless of selector specificity.
Limit CSS rules to a specific part of the DOM, preventing style leakage. Provides style encapsulation without Shadow DOM, perfect for component-based design.
/* Scope styles to .card */
@scope (.card) {
h2 {
color: blue;
font-size: 1.25rem;
}
p {
margin: 1rem 0;
}
button {
background: green;
}
}
/* Scope with boundary - excludes .card-footer */
@scope (.card) to (.card-footer) {
/* Styles apply to .card descendants,
but NOT to anything inside .card-footer */
p {
color: gray;
}
}
/* Different scope for different component */
@scope (.sidebar) {
h2 {
color: purple; /* Won't affect .card h2 */
}
}
@container - Container Queries
Apply styles based on a parent container's size, not the viewport. Enables true component-based responsive design - the same component adapts differently in a sidebar vs. main content area.
Register custom CSS properties with explicit types, enabling animations, better browser optimization, and validation. Without @property, custom properties are just strings and can't be animated!