Other rules

The remaining at-rules: animation keyframes and transition starting points, view transitions between pages, typed custom properties and custom functions, fallback positions for anchored boxes, printed pages, and the encoding marker. The properties these rules work with, such as animation and transition, are under Transitions & animation; conditions, layers and fonts have pages of their own under At-rules.

Animation & transitions

@keyframes

Defines a named animation as a list of keyframes, each giving property values at a point in the animation's progress. Apply it with the animation properties.

Syntax@keyframes <keyframes-name> { <qualified-rule-list> }
SupportChrome 43 · Firefox 16 · Safari 9
Speccss-animations-1
FeatureSupport
Keyframe selectors from, to and percentagesChrome 43 · Firefox 16 · Safari 9
Named timeline ranges in keyframe selectors, e.g. entry 0%, for scroll-driven animationsChrome 115 · Firefox no · Safari 26
@keyframes fade-up {
  from { opacity: 0; translate: 0 1rem; }
  to   { opacity: 1; translate: 0 0; }
}

.notice { animation: fade-up 0.4s ease-out; }
Fade and slide an element in once when it appears.

Each keyframe selector is from (0%), to (100%) or a percentage, and one block can list several, as in 0%, 50% { … }. A property left out of a keyframe is interpolated from the neighbouring keyframes that set it. Declarations marked !important inside a keyframe are ignored. If two @keyframes rules share a name, the last one wins.

@starting-style

Gives the styles an element transitions from when it first gets a style, such as when it is added to the page or changes from display: none. Without it, a newly shown element has no previous style and its transitions do not run.

Syntax@starting-style { <rule-list> }
SupportChrome 117 · Firefox 129 · Safari 17.5
Speccss-transitions-2
.toast {
  opacity: 1;
  transition: opacity 0.3s;

  @starting-style {
    opacity: 0;
  }
}
A toast fades in from transparent each time one is added to the page.

The rule can stand at the top level holding style rules, or be nested inside a style rule holding declarations, as above. To animate an element out to display: none as well, transition display with transition-behavior: allow-discrete.

@view-transition

Opts a page in to view transitions across navigations between documents, so moving to another same-origin page animates like a same-document view transition. Both the old and the new page must opt in.

Syntax@view-transition { <declaration-list> }
SupportChrome 126 · Firefox no · Safari 18.2
Speccss-view-transitions-2
DescriptorSyntaxInitialSupport
navigationauto | nonenoneChrome 126 · Firefox no · Safari 18.2
typesnone | <view-transition-type>+noneChrome 126 · Firefox no · Safari 18.2
@view-transition {
  navigation: auto;
}
Put this in the style sheet of both pages to cross-fade between them.

types names the transition, so the pages can style it differently with :active-view-transition-type().

Custom properties & functions

@property

Registers a custom property with a type, an initial value and whether it inherits. A registered property is checked against its type, and because the browser knows the type it can transition and animate the value smoothly.

Syntax@property <custom-property-name># { <declaration-list> }
SupportChrome 85 · Firefox 128 · Safari 16.4
Speccss-properties-values-api-1
DescriptorSyntaxInitialSupport
syntax<string>"*"Chrome 85 · Firefox 128 · Safari 16.4
inheritstrue | falsetrueChrome 85 · Firefox 128 · Safari 16.4
initial-value<declaration-value>?The guaranteed-invalid valueChrome 85 · Firefox 128 · Safari 16.4
@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.dial {
  background: conic-gradient(from var(--angle), teal, gold, teal);
  transition: --angle 1s;
}
.dial:hover { --angle: 180deg; }
Typed as an angle, the custom property can transition, so the gradient turns.

The syntax string names a type such as "<length>" or "<color>+", a set of keywords such as "small | large", or "*" for any value. When it is anything other than "*", initial-value is required and must be computationally independent, so 10px is allowed but 3em is not. Give all three descriptors for the widest support.

@function

Defines a custom function, named like a custom property, that takes arguments and returns a value. Call it anywhere a value is allowed, as in --double(4px).

Syntax@function <function-token> <function-parameter>#? ) [ returns <css-type> ]? { <declaration-rule-list> }
SupportChrome 139 · Firefox no · Safari no
Speccss-mixins-1
DescriptorSyntaxInitialSupport
result<declaration-value>?n/aChrome 139 · Firefox no · Safari no
@function --double(--value) {
  result: calc(var(--value) * 2);
}

.box { padding: --double(0.75rem); }
A custom function that doubles its argument.

<function-token> is the function's dashed name followed directly by an opening parenthesis. Each <function-parameter> is a custom property name, optionally followed by a type and a default value after a colon. Inside the body, parameters are read with var(), and the result descriptor gives the value the call returns.

Positioning

@position-try

Defines a named fallback position for an anchor-positioned box. When the box would overflow its containing block in its normal position, the browser tries the options listed in position-try-fallbacks in turn and uses the first one that fits.

Syntax@position-try <dashed-ident> { <declaration-list> }
SupportChrome 125 · Firefox 147 · Safari 26
Speccss-anchor-position-1
@position-try --below {
  position-area: bottom;
  margin-top: 0.5rem;
}

.tooltip {
  position: absolute;
  position-anchor: --trigger;
  position-area: top;
  position-try-fallbacks: --below;
}
Show the tooltip above its anchor, or below it when there is no room above.

Only positioning properties are allowed inside: the inset properties, margins, sizing properties, self-alignment properties, position-anchor and position-area.

Paged media

@page

Styles the page boxes used when a document is printed or otherwise paginated: their size, orientation and margins. A page selector can target the :first, :left, :right or :blank pages, or pages named with the page property.

Syntax@page <page-selector-list>? { <declaration-rule-list> }
SupportChrome 2 · Firefox 19 · Safari 18.2
Speccss-page-3
DescriptorSyntaxInitialSupport
size<length [0,∞]>{1,2} | auto | [ <page-size> || [ portrait | landscape ] ]autoChrome 15 · Firefox 95 · Safari 18.2
page-orientationupright | rotate-left | rotate-rightuprightChrome 85 · Firefox 122 · Safari no
page-margin-safetynone | clamp | addautoChrome 150 · Firefox no · Safari no
@page {
  size: A4;
  margin: 2cm;
}

@page :first {
  margin-top: 4cm;
}
A4 pages with 2cm margins and a deeper top margin on the first page.

The margin properties also apply inside @page and set the page margins. size takes a named size such as A4, letter or JIS-B5, or explicit lengths. page-orientation rotates the page when it is shown or printed, without changing the layout. page-margin-safety controls whether the page margins are adjusted to stay clear of the area the printer cannot print on.

@top-left-corner … @left-top

The sixteen page-margin rules, written inside @page. Each one styles a box in the page margin, and is usually given content to make running headers, footers and page numbers.

Syntax@top-left-corner { <declaration-list> };, and the same for each rule below
SupportChrome 131 · Firefox no · Safari no
Speccss-page-3
@page {
  margin: 2cm;

  @bottom-center {
    content: "Page " counter(page) " of " counter(pages);
  }
}
A page number centred in the bottom margin of every printed page.

Encoding

@charset

Declares the character encoding of a style sheet file. It is not a real at-rule: the browser looks for these exact bytes at the very start of the file while choosing an encoding, and otherwise ignores the rule.

Syntax@charset "<encoding>";
SupportChrome 2 · Firefox 1.5 · Safari 4
Speccss-syntax-3

It must be the first thing in the file, with no space or comment before it, written exactly as @charset "UTF-8"; with one space and double quotes. An HTTP Content-Type charset or a byte order mark takes priority over it. Files saved as UTF-8 do not need it.