Bramus
banner
bram.us
Bramus
@bram.us
Chrome DevRel at Google (CSS + Web UI + DevTools). CSSWG Member. PADI Divemaster. Blogs at bram.us. Lives in Belgium.
Nice Jizzmas tree 😬
November 29, 2025 at 3:54 PM
The pudding or the terrier? 🤔
November 28, 2025 at 2:07 PM
Keep those lists coming! 🤩
November 28, 2025 at 1:53 PM
I read that post in a Michael McIntyre voice, to give it some extra panache. 😁
November 28, 2025 at 6:37 AM
Reposted by Bramus
When we first reviewed JPEG XL, as far as we could see no other browser engine wanted it. Our judgement was the benefit wasn't worth the cost. Then Safari decided otherwise and shipped it. Once Mozilla expressed their openness to shipping, it was inevitable that Chromium would too.
November 27, 2025 at 9:04 PM
I also asked it to build a demo for me and it got it right on the 1st try (without using any React or Tailwind as well).

codepen.io/bramus/full/...
@bramus/sticky-observer demo – Observer `position: sticky` elements getting stuck or unstuck
...
codepen.io
November 27, 2025 at 7:36 PM
It took a few nudges into the right direction, but out came a an actual TypeScript class.

I then continued with Gemini Code Assist in VS Code to create the package structure and some other related files.

And look: github.com/bramus/stick...
GitHub - bramus/sticky-observer: Observe CSS `position: sticky` elements getting stuck or unstuck
Observe CSS `position: sticky` elements getting stuck or unstuck - bramus/sticky-observer
github.com
November 27, 2025 at 7:36 PM
The “I can’t believe that worked” at the end is the cherry on top 😄
November 27, 2025 at 11:16 AM
I read it when your newsletter got sent and had it bookmarked to leave a reply. But by the looks of it you’ve got it figured out :)
November 27, 2025 at 11:15 AM
The prefers-colors-scheme media query does not replace color-scheme, but it goes hand-in-hand with it.

Set `color-scheme: light dark` on `:root`, and its used value ends up being either `light` or `dark`, based on your preference.

(Could it be that the post got updated? Because it mentions this)
November 27, 2025 at 11:03 AM
Winging back to the initial snap thing: Here’s a reworked version that uses either `scroll-initial-target` or the animation hack.

A subtle difference though, is that the animation uses a `from` keyframe. That way you don’t need a permanently-fill-forward-animation.

gist.github.com/bramus/94b0e...
Set the initial scroll offset of a scrollable container with `scroll-initial-target`
Set the initial scroll offset of a scrollable container with `scroll-initial-target` - scroll-initial-target-with-fallback.css
gist.github.com
November 27, 2025 at 10:49 AM
The problem is that you can introduce cycles that way, so you need the parent-child relationship.

As an alternative you can use inline if(), which has built-in protection for cycles.
November 26, 2025 at 11:14 PM
Nice work!
November 26, 2025 at 8:12 PM
Everything from Scroll-Driven Animations, and soon Scroll-Triggered Animations.

(Although some require 2 lines of CSS … but that still beats +100 of lines of JS)
November 26, 2025 at 4:02 PM
Scroll detection nowadays can be done with Scroll-State Queries: developer.chrome.com/blog/css-scr...

But browser support for Scroll-Driven Animations is better than that for Scroll-State Queries, so perhaps better to stick to SDA (for now).
CSS scroll-state()  |  Blog  |  Chrome for Developers
Like container queries; but for stuck, snapped, and overflowing queries.
developer.chrome.com
November 26, 2025 at 10:07 AM
This is how it should have worked from the start, as the spec says it applies to a “scroll container” without making a distinction between a scrollable or non-scrollable one.

There are links to bugs with other vendors in the post, so feel free to star/+1 those bugs to indicate interest.
November 26, 2025 at 9:27 AM
Yeah, the styles have to be in the stylesheet in the Shadow Root.

codepen.io/bramus/pen/J...

/me mumbles something about shadow-piercing selectors …
Use `overscroll-behavior: contain;` on `::backdrop` to prevent a page from scrolling when a <dialog> is open! (Shadow DOM)
...
codepen.io
November 26, 2025 at 8:58 AM