Values & references
Functions that stand in for a value found somewhere else: a custom property, an environment variable from the browser or device, an HTML attribute, a condition, a counter, or the position and size of an anchor element. Custom properties themselves are declared as described under Cascade & custom properties; the anchor positioning properties are under Anchor positioning, and the counter properties under Lists, tables & content.
Custom properties & environment
var()
Substitutes the value of a custom property (a --name). The optional second argument is a fallback, used when the property is not set or is the guaranteed-invalid value; everything after the first comma counts as the fallback, commas included.
| Syntax | var( <custom-property-name> , <declaration-value>? ) |
|---|---|
| Returns | The custom property's value, substituted as tokens |
| Support | Chrome 49 · Firefox 31 · Safari 9.1 |
| Spec | css-variables-2 |
Substitution happens at computed-value time. If the result does not make sense for the property, the declaration is not dropped at parse time; the property instead becomes invalid at computed-value time and falls back to its inherited or initial value.
:root { --space: 1rem; }
.card { padding: var(--space); color: var(--card-text, var(--text, black)); }
env()
Substitutes the value of an environment variable defined by the browser, such as the safe area of a phone screen with a notch. Unlike custom properties, environment variables are global and the same for every element. The optional integers index into variables that have more than one value; the last argument is a fallback.
| Syntax | env( <custom-ident> <integer [0,∞]>*, <declaration-value>? ) |
|---|---|
| Returns | The environment variable's value, substituted as tokens |
| Support | Chrome 69 · Firefox 65 · Safari 11.1 |
| Spec | css-env-1 |
| Variable | Value | Support |
|---|---|---|
safe-area-inset-top, safe-area-inset-right, safe-area-inset-bottom, safe-area-inset-left | The distance from each edge of the viewport to the area that is not hidden by rounded corners, notches or system bars. Needs viewport-fit=cover in the viewport meta tag to be non-zero. | Chrome 69 · Firefox 65 · Safari 11 |
keyboard-inset-top, keyboard-inset-right, keyboard-inset-bottom, keyboard-inset-left, keyboard-inset-width, keyboard-inset-height | The position and size of the on-screen keyboard, when the page has asked for the keyboard to overlay its content with the VirtualKeyboard API. | Chrome 94 · Firefox no · Safari no |
titlebar-area-x, titlebar-area-y, titlebar-area-width, titlebar-area-height | The free title bar area beside the window controls, for an installed desktop web app using the window controls overlay. | Chrome 93 · Firefox no · Safari no |
viewport-segment-top, viewport-segment-right, viewport-segment-bottom, viewport-segment-left, viewport-segment-width, viewport-segment-height | The edges and size of each screen segment on a foldable or dual-screen device. Two integers pick the segment by column and row, for example env(viewport-segment-width 0 0). | Chrome 138 · Firefox no · Safari no |
preferred-text-scale | The user's preferred text size as a number, where 1 is the default size. | Chrome 138 · Firefox no · Safari no |
.toolbar { padding-bottom: max(1rem, env(safe-area-inset-bottom)); }
Attributes & conditions
attr()
Substitutes the value of an attribute on the element. Without a type, the value is a string, which has always worked in the content property. With type(), the attribute is parsed as another type, such as a colour or a length, and works in any property.
| Syntax | attr( <attr-name> <attr-type>? , <declaration-value>?) |
|---|---|
| Returns | The attribute's value, as a string or parsed as the given type |
| Support | As a string in content: Chrome 2 · Firefox 1 · Safari 3.1Fallback value: Chrome 133 · Firefox 119 · Safari 18.4 Typed with type(), in any property: Chrome 133 · Firefox 155 · Safari noraw-string: Chrome 136 · Firefox 155 · Safari no |
| Spec | css-values-5 |
type(<syntax>) takes the same syntax strings as @property, for example type(<color>), type(<length>) or type(<number> | auto). raw-string keeps the value as an unparsed string. If the attribute is missing or does not parse, the fallback after the comma is used.
abbr[title]::after { content: " (" attr(title) ")"; }
.swatch { background: attr(data-color type(<color>), gray); }
data-color attribute.if()
Chooses a value inline from a list of conditions, so one declaration can hold several alternatives. Each branch is a condition, a colon and a value; branches are separated by semicolons, the first true condition wins, and else matches anything.
| Syntax | if( [ <if-branch> ; ]* <if-branch> ;? ) |
|---|---|
| Returns | The value of the first branch whose condition is true, substituted as tokens |
| Support | Chrome 137 · Firefox no · Safari no |
| Spec | css-values-5 |
A condition is a style() query on the element's custom properties, a media() query or a supports() test, and can combine them with and, or and not. If no branch matches and there is no else, the property becomes invalid at computed-value time.
.button {
background: if(style(--variant: danger): #c62828; style(--variant: quiet): transparent; else: var(--brand));
padding: if(media(width < 40rem): 0.5rem; else: 1rem);
}
Counters
counter()
The current value of a counter, as a string for the content property. The optional second argument is the counter style, such as decimal (the default), lower-roman or upper-alpha.
| Syntax | counter( <counter-name>, <counter-style>? ) |
|---|---|
| Returns | <string> |
| Support | Chrome 1 · Firefox 1 · Safari 3 |
| Spec | css-lists-3 |
body { counter-reset: figure; }
figure { counter-increment: figure; }
figcaption::before { content: "Figure " counter(figure) ": "; }
counters()
The values of every counter with that name in scope, from the outermost to the innermost, joined by the given string. Use it for nested numbering such as 1.2.3.
| Syntax | counters( <counter-name>, <string>, <counter-style>? ) |
|---|---|
| Returns | <string> |
| Support | Chrome 1 · Firefox 1.5 · Safari 3 |
| Spec | css-lists-3 |
ol { counter-reset: item; list-style: none; }
li { counter-increment: item; }
li::before { content: counters(item, ".") " "; }
symbols()
An anonymous counter style defined inline, for when a one-off style does not need a full @counter-style rule. It takes a counter system (cyclic, numeric, alphabetic, symbolic or fixed; the default is symbolic) and the list of symbols.
| Syntax | symbols( <symbols-type>? [ <string> | <image> ]+ ) |
|---|---|
| Returns | A counter style, as <counter-style> |
| Support | Chrome 155 · Firefox 35 · Safari no |
| Spec | css-counter-styles-3 |
ul { list-style-type: symbols(cyclic "◆" "◇"); }
Anchor positioning
anchor()
The position of one side of an anchor element, for use in the inset properties (top, left, inset-block-start and so on) of an absolutely or fixed positioned box. The anchor is named with anchor-name or defaults to position-anchor; the optional last argument is a fallback length.
| Syntax | anchor( <anchor-name>? && <anchor-side>, <length-percentage>? ) |
|---|---|
| Returns | <length> |
| Support | Chrome 125 · Firefox 147 · Safari 26 |
| Spec | css-anchor-position-1 |
<anchor-side> is a physical side (top, right, bottom, left), a logical one (start, end, self-start, self-end), inside or outside, center, or a percentage of the way across the anchor.
.trigger { anchor-name: --menu; }
.menu { position: absolute; top: anchor(--menu bottom); left: anchor(--menu left); }
anchor-size()
The width or height of an anchor element, for sizing a positioned box to match it. It takes an optional anchor name, an optional dimension (width, height, block, inline, self-block or self-inline) and an optional fallback.
| Syntax | anchor-size( [ <anchor-name> || <anchor-size> ]? , <length-percentage>? ) |
|---|---|
| Returns | <length> |
| Support | In sizing properties: Chrome 125 · Firefox 147 · Safari 26 In inset and margin properties: Chrome 132 · Firefox 147 · Safari 26 |
| Spec | css-anchor-position-1 |
.menu { min-width: anchor-size(width); }