JUMP TO:
1. Popover API & Anchor positioning
2. Scroll driven animations
3. New color functions
4. @property (custom properties)
1. Popover API & Anchor positioning
The Popover API provides a native, accessible way to show floating UI (menus, tooltips, dialogs) without JavaScript libraries.
Basic usage
<button popovertarget="menu">Open menu</button>
<div id="menu" popover>
Menu content
</div>
The browser handles:
- opening / closing
- focus management
- Escape key
- click-outside dismissal
Key features
- No JS required for basic behavior
- Built-in accessibility
- Works well with keyboard & screen readers
Styling a popover
[popover] {
padding: 1rem;
border-radius: 8px;
}
Popover types
popover="auto"(default): dismisses on outside clickpopover="manual": fully controlled by JS- Because a popover has no positioning instructions, the browser uses a safe, default placement: centered in the viewport unless specified otherwise
Anchor Positioning
What it is (one sentence)
Anchor positioning lets you position an element relative to another element in pure CSS, without JavaScript calculations.
Basic example
<button id="btn">Info</button>
<div popover anchor="btn">
Tooltip text
</div>
[popover] {
position-anchor: --btn;
position: absolute;
inset-area: bottom;
}
The popover stays attached even if layout changes.
Why this matters
Before:
- JS measured positions
- window resize listeners
- fragile calculations
Now:
- CSS handles alignment
- responds to layout automatically
- less JS, more reliability
Why they’re often paired
Popover handles:
- visibility
- focus
- dismissal
Anchor positioning handles:
- where it appears
- how it tracks its anchor
Together they replace many tooltip / dropdown libraries.
2. Scroll driven animations
Scroll-driven animations let CSS animations progress based on scroll position instead of time.
The problem they solve
Traditionally:
- scroll animations → JavaScript scroll listeners
- poor performance
- hard to sync with layout
Scroll-driven animations move this into the browser’s rendering engine.
Core concepts
1️⃣ Scroll timelines
A scroll timeline maps scroll progress → animation progress.
@scroll-timeline scroll-progress {
source: auto;
}
(New syntax is evolving)
2️⃣ animation-timeline
.box {
animation: fade-in linear;
animation-timeline: scroll();
}
The animation advances as you scroll.
3️⃣ View timelines (element-based)
.card {
animation: slide-in linear;
animation-timeline: view();
}
The animation runs as the element enters and leaves the viewport.
Why this is a big deal
- compositor-driven (very smooth)
- browser understands layout + scroll
- espects
prefers-reduced-motion - no JS math or listeners
Typical use cases
- progress bars
- parallax effects
- fade/slide on enter
- storytelling layouts
- section reveals
3. New color functions
Modern CSS color functions let you define colors in perceptual color spaces, making color adjustments more predictable, accessible, and design-friendly.
Why new color functions were needed
Older formats (rgb(), hex) are:
- device-based
- not perceptually uniform
- hard to adjust logically (lighten, darken, mix)
New functions fix this.
Key modern CSS color functions
🎨 lab()
color: lab(60% 40 30);
- Based on CIELAB, a perceptual color space
- Changes to lightness behave how humans expect
- Great for accessible color systems
Mental model:
“If I increase lightness, it actually looks lighter.”
lch()
color: lch(60% 70 40);
- Lightness, Chroma, Hue
- Easier for designers than LAB
- Ideal for gradients and themes
Very popular for design systems
oklab() & oklch()
color: oklch(65% 0.15 240);
- Improved perceptual accuracy over LAB/LCH
- Better hue consistency
- Increasingly recommended for modern work
Best choice today for color systems.
color-mix()
color: color-mix(in oklch, red 40%, blue);
- Mixes colors in a chosen color space
- Predictable results
- Great for hover states and themes
color()
color: color(display-p3 1 0.5 0);
- Access to wide-gamut color spaces
- Supports Display-P3, Rec2020, etc.
- Enables richer colors on modern displays
relative-color() (emerging)
color: relative-color(currentColor lch l +10%);
- Adjusts a color relative to another
- Ideal for hover / active states
- Still evolving support
Why this matters in real projects
- Better contrast control
- More consistent themes
- Easier dark mode
- Fewer magic numbers
4. @property (custom properties)
@propertylets you register a CSS custom property with a type, initial value, and inheritance behavior, so the browser can understand and animate it properly.
The problem it solves
Normal CSS variables (--x) are:
- just strings
- not type-aware
- not animatable in a meaningful way
/* This cannot animate smoothly */
.box {
--angle: 0deg;
}
The browser doesn’t know 0deg → 360deg is an angle.
What @property adds
When you register a property, you tell the browser:
- what type it is
- whether it inherits
- its initial value
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
Now the browser understands --angle as an angle.
Why this matters (key benefits)
✅ Smooth animations
.box {
animation: spin 2s linear infinite;
}
@keyframes spin {
to {
--angle: 360deg;
}
}
Without @property, this would jump, not animate.
✅ Type safety
syntax: "<number>" | "<length>" | "<color>" | "<angle>";
Invalid values are rejected early.
✅ Better performance
- Browser can animate on the compositor
- No JS required
Common use cases
- animated gradients
- rotating elements
- progress indicators
- scroll-driven animations
- theme transitions

Leave a Reply