TocTable of Contents
Css baseline 2024
Overview of 2024 baseline css features
@starting-style
@starting-style defines the initial style state for an element before it first participates in a CSS transition. This lets you animate elements into view when they first appear in the DOM — something previously only possible with JavaScript.
| |
When .dialog is first inserted, it starts from the @starting-style values and transitions to its normal state.
Can be used with <dialog> and [popover]
| |
Before @starting-style, transitions only worked when a property changed — not when an element first appeared. This fills a long-standing gap in CSS animation.
align-content-block
align-content now works in block layout contexts, not just flexbox and grid. When applied to a block-level element that has more height available than its content requires, align-content controls how that content is distributed along the block axis — vertically in horizontal writing modes.
This was previously only possible in block contexts by reaching for flexbox or grid just to center content vertically. Now, a regular block element can use align-content: center to vertically center its children without changing the layout model.
| |
Values like center, start, end, space-between, and space-around all apply. This is a meaningful simplification for common layout patterns where flexbox or grid was used purely as a centering mechanism rather than for its full layout capabilities.
Alt text for generated content
The content property now supports an alternative text string for accessibility purposes, using a slash separator after the content value. This allows CSS-generated content — inserted via ::before and ::after — to carry a meaningful text alternative that assistive technologies can expose, rather than reading out the raw generated string or nothing at all.
| |
The syntax is content: <value> / <alt-text>. An empty string as the alt text (/ '') signals that the generated content is purely decorative and should be ignored by screen readers, equivalent to aria-hidden. A non-empty alt text provides a spoken alternative to the visual content.
This removes a significant accessibility gap — previously, meaningful icons or indicators inserted via CSS had no way to communicate their purpose to assistive technology without additional HTML attributes or ARIA.
backdrop-filter
The backdrop-filter property applies graphical filter effects to the area behind an element, rather than to the element itself. The element must be at least partially transparent for the effect to be visible. This enables the frosted glass aesthetic — a blurred, color-tinted view of content behind a translucent panel — that is common in modern UI design.
| |
backdrop-filter accepts the same filter functions as the filter property: blur(), brightness(), contrast(), grayscale(), hue-rotate(), invert(), opacity(), saturate(), and sepia(). Multiple functions can be chained.
Because the effect is composited from the live content behind the element, it updates dynamically as that content scrolls or changes. Performance varies by device and complexity of the filter; blur() in particular can be GPU-intensive at large radii or on complex backgrounds.
font-size-adjust
font-size-adjust scales a font so its x-height (lowercase letter height) matches a specified ratio, keeping text visually consistent when the primary font fails to load and a fallback is used.
Different fonts at the same font-size can look dramatically different sizes because they have different x-heights. A fallback font may appear much smaller or larger than the intended web font.
| |
0.5 means the x-height should be half the font-size. The browser scales the fallback font so its x-height matches this ratio.
The value is the font’s aspect ratio: x-height ÷ font-size. Tools like Capsize can calculate it for any font.
| |
The from-font keyword extracts the ratio automatically from the loaded font.
Most valuable in long-form reading where a flash of a differently-sized fallback font is jarring. Pairs well with font metric overrides.
font-variant-emoji
The font-variant-emoji property controls whether emoji characters are rendered in their colorful emoji presentation or as plain text symbols. Unicode defines variation selectors that influence this (VS15 for text, VS16 for emoji), but font-variant-emoji gives you CSS-level control over the default presentation when no variation selector is present in the markup.
| |
The text value renders the character as a monochrome text glyph, while emoji requests the full-color emoji rendering. unicode defers to the character’s default presentation as defined by Unicode, and normal leaves the decision to the browser and font.
This is useful when you want to use emoji characters as icon-like elements that blend with surrounding text styling, or conversely when you want to ensure colorful rendering in contexts where the text presentation might otherwise be selected.
Gradient interpolation
CSS gradients now support in <colorspace> syntax, letting you specify which color space is used when blending between gradient stops — dramatically improving the quality of color transitions.
Gradients through complementary colors in sRGB pass through a dull grey midpoint:
| |
| |
oklch produces a vivid, natural-looking transition because it interpolates through perceptually uniform hue space.
| |
For hue-based spaces, control which way hue rotates with the shorter, longer and increasing keywords:
| |
light-dark()
light-dark() is a CSS function that returns one of two values depending on whether the active color scheme is light or dark. It condenses what previously required a prefers-color-scheme media query into a single expression.
| |
The page (or element) must declare color-scheme:
| |
| |
paint-order
The paint-order property controls the order in which the fill, stroke, and markers of text and SVG shapes are painted. By default, fill is painted first and stroke is painted on top of it, which means a thick stroke bleeds inward and partially covers the fill. Reversing this order lets the fill render on top of the stroke, keeping the fill clean and pushing the stroke outward.
| |
With paint-order: stroke fill, the stroke is drawn first — acting as an outline — and the fill is rendered on top of it. This creates a crisp outlined text effect without the stroke obscuring the fill color.
paint-order accepts fill, stroke, and markers in any order. Omitted keywords are painted after the listed ones in their default order. The property applies to both SVG elements and HTML text content in supporting browsers, making it a useful tool for accessible high-contrast text effects and decorative typographic treatments.
relative-color
Relative color syntax allows you to derive a new color from an existing one by taking it as a base and modifying individual channels. The from keyword introduces the origin color, whose channels are then exposed as named variables you can use and manipulate inside any color function.
This makes it straightforward to generate tints, shades, transparencies, and hue-shifted variants from a single source color — without leaving CSS, without a preprocessor, and without hardcoding intermediate values.
| |
Relative colors work across all supported color spaces and functions, including oklch, oklch, hsl, rgb, and others. Using a perceptually uniform color space like oklch typically produces the most visually consistent results when adjusting lightness or chroma. This feature effectively brings the color manipulation capabilities of Sass and design tokens into native CSS.
round(), mod(), and rem()
These CSS math functions bring rounding and modulo operations into stylesheets, enabling snapping values to grids, cycles, and intervals.
round(strategy, value, step) rounds a value to the nearest multiple of step:
| |
mod(value, divisor) returns the remainder with the same sign as the divisor:
| |
rem(value, divisor) returns the remainder with the same sign as the dividend (like % in most programming languages):
| |
When to use:
- Snap sizes to a grid:
round(var(--size), 8px) - Cycle through N states with
mod() - Normalise angles:
mod(var(--angle), 360deg)
text-wrap
The text-wrap property controls how text wraps within its container. It is a shorthand that encompasses text-wrap-mode (whether wrapping is allowed at all) and text-wrap-style (the algorithm used when wrapping does occur).
The most practically impactful values are balance and pretty. text-wrap: balance distributes text evenly across lines, eliminating the awkward single-word orphans that frequently appear on the last line of headings. text-wrap: pretty applies a similar improvement to body text, optimising the last few lines of a paragraph to avoid orphans — at a slightly higher computational cost than the default wrap.
| |
text-wrap: nowrap prevents wrapping entirely, equivalent to the older white-space: nowrap. The wrap value is the default behaviour.
These values give you typographic control that previously required JavaScript or manual line-break insertion, and they adapt automatically as container widths change.
text-wrap: balance
text-wrap: balance instructs the browser to distribute text across lines as evenly as possible, eliminating the single short word left dangling on the last line of a heading.
| |
The browser adjusts where lines break so that all lines are approximately the same length.
Without balancing, a heading might render as:
The Quick Brown Fox Jumps Over
With text-wrap: balance:
The Quick Brown Fox Jumps Over
Balancing is computationally expensive for long passages of text. It is intentionally limited to short strings — browsers cap it at around 6 lines. Use it on headings and pull quotes, not body text.
For body text, text-wrap: pretty is the better choice — it avoids orphans (single words on the last line) without the full cost of balancing.
transition-behavior
transition-behavior controls whether CSS transitions apply to properties with discrete (non-interpolatable) values, such as display, visibility, and content-visibility.
Normally, display: none cannot be transitioned — it switches instantly, so fade-out animations are cut short, but with transition-behavior: allow-discrete it can.
| |
With allow-discrete, the display: none is applied at the end of the transition, giving the opacity time to animate first.
Shorthand:
| |
allow-discrete can be included directly in the transition shorthand.
Pair this with @starting-style for the entering animation, use @starting-style to define where the transition begins:
| |
Vertical form controls
CSS now allows range inputs, progress bars, and meter elements to be oriented vertically using writing-mode or appearance, replacing non-standard attributes and workarounds.
| |
This is the standard CSS approach — writing-mode: vertical-lr or vertical-rl orients the slider vertically.
| |
Previously, developers used the non-standard orient="vertical" attribute on range inputs, or applied transform: rotate(90deg) which caused layout issues.
white-space-collapse
white-space-collapse is a longhand property extracted from the white-space shorthand, controlling only how whitespace characters are collapsed — independently of line wrapping behaviour.
| |
Previously you had to use white-space for everything:
| |
white-space-collapse pairs with text-wrap to replace the full white-space shorthand:
| |
Where to use:
- Code blocks:
preservefor indentation and newlines - Chat interfaces:
preserve-breaksto honour user newlines without preserving spaces - Inline labels:
collapseto normalise authored whitespace
Page setup
The @page at-rule controls the layout of printed pages — margins, size, and orientation — giving you meaningful influence over how your content looks on paper.
| |