CSS At-Rules Reference

All CSS at-rules (@media, @keyframes, @layer, @container, etc.) with syntax.

A searchable CSS at-rule reference covering @media, @supports, @container, @layer, @keyframes, @font-face, @property and more, with syntax, whether it is a statement or block, nesting behaviour and browser support. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is a CSS at-rule?

An at-rule is a CSS statement that begins with an @ keyword and instructs the engine how to behave. Some are single statements ending in a semicolon, like @import, while others wrap a block of nested rules or descriptors, like @media or @font-face.

This is a searchable reference for CSS at-rules — the @-prefixed instructions that configure the stylesheet, load resources, and apply styles conditionally. It covers the conditional group rules (@media, @supports, @container), the cascade and scoping rules (@layer, @scope), animation and font rules (@keyframes, @font-face), and modern additions like @property and @starting-style.

How it works

Every at-rule starts with @ and a keyword. There are two shapes. A statement at-rule ends in a semicolon and carries no body — @charset "UTF-8"; and @import url(reset.css); are examples, and these must appear at the very top of the file. A block at-rule wraps braces containing either nested style rules (a conditional group rule like @media or @supports) or a set of descriptors (like @font-face, which takes font-family, src and similar declarations rather than ordinary properties). The conditional group rules can be nested inside one another, so you can put a @supports inside a @media, and modern engines allow nesting them inside style rules too.

The modern at-rules worth knowing

Several newer at-rules changed how CSS is structured and are now stable in all major engines:

@layer declares cascade layers, giving you an explicit ordering for specificity battles. Rules in a layer declared earlier always lose to rules in a later layer, regardless of selector specificity. This makes it practical to include third-party resets or component libraries in a controlled layer without their specificity bleeding into your own styles.

@container queries an ancestor container’s size rather than the viewport. Before it existed, responsive design could only react to the window width; with @container a sidebar component adapts to the column it is placed in, not the screen.

@property registers a CSS custom property with an explicit type such as <color> or <angle>. Unregistered custom properties animate discretely (they snap between values), but a registered property with a concrete type can be interpolated smoothly by the transition engine.

@starting-style (part of the CSS Transitions Level 2 spec) lets you declare the initial style an element transitions from when it first enters the page or appears from display: none. This closes the gap that previously required JavaScript to trigger entry animations.

Nesting and ordering tips

Order matters for the statement rules: @charset first, then @layer statement declarations and @import, then everything else. Cascade layers from @layer resolve before specificity, so an unlayered rule beats any layered rule — keep that in mind when mixing layered frameworks with ad-hoc overrides. @container only works against an ancestor that has opted in with container-type, and @property lets a custom property declare its syntax, whether it inherits, and an initial-value, which is what unlocks smooth animation of custom properties.

Example

@layer reset, base, components;

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@container (min-width: 30rem) {
  .card { display: grid; grid-template-columns: 1fr 2fr; }
}

@starting-style {
  .toast { opacity: 0; transform: translateY(-8px); }
}

The @starting-style block defines where .toast elements begin their transition when they first appear — the browser then transitions them to whatever opacity and transform are set in the main stylesheet.

Everything runs in your browser; nothing you search is uploaded.