- From: Lea Verou via GitHub <noreply@w3.org>
- Date: Thu, 07 May 2026 15:56:12 +0000
- To: public-css-archive@w3.org
LeaVerou has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-contain] `scroll-state(stuck)` CQs cause flickering when used with layout-affecting properties, and it is very hard to work around == > [!WARNING] > Some of the videos include rapidly flashing content that could affect photosensitive viewers. ## The problem When `scroll-state(stuck)` queries are used in conjunction with properties that affect layout in a way that makes stuck elements *smaller*, there is flickering when scrolling slowly. Since there is only one shipped implementation, I can't quite tell if this is a Blink bug or a spec bug, but if it's per spec, the spec is buggy. Here's a testcase that makes the `font-size` smaller: https://codepen.io/leaverou/pen/vEyOZXy Video: https://github.com/user-attachments/assets/7d493f0c-37d9-495a-b81f-51ae0685cbf5 This is particularly egregious because it only has a transition one way, but the problem is visible even [with a two-way transition](https://codepen.io/leaverou/pen/WborppY), or [none at all](https://codepen.io/leaverou/pen/zxorZwG): https://github.com/user-attachments/assets/3967dc4a-b724-463d-8743-4c3960da61dc [No transition](https://codepen.io/leaverou/pen/zxorZwG) even ends up "fighting" the user's scrolling (though is harder to trigger programmatically, like the others)! https://github.com/user-attachments/assets/f9ac3468-2b6c-45d5-8f8e-8b8bc5205de2 The reason becomes clear if we apply the same styling on `:hover`: https://github.com/user-attachments/assets/441eebce-d149-4249-b292-585f0c3f7317 Note that many, if not most, use cases require such properties, we can't just say the feature can't be used with layout affecting properties or force it to also require size containment. ## Is there a reasonable workaround? In the last couple of days, I have spent a _considerable_ amount of time trying to find a workaround for this that works in the general case, and it has proven incredibly difficult. ### 1. [`min-height` on the `header`](https://codepen.io/leaverou/pen/ogYgQEB/d55b91866af3ded04b11d916865f6613) Overshooting affects non-stuck state as well (by adding extra space). Undershooting does not fix the problem. It is nearly impossible to find a length that does both in the general case, since headings tend to have variable content that wraps differently in different viewports. https://github.com/user-attachments/assets/75b0ba30-9329-423c-99b0-7b987daf05d2 ### 2. [Transparent border on the `h2` when stuck](https://codepen.io/leaverou/pen/bNBdbMW/c1317daef8d9a709d42608415fc80717) Not practical in many cases (existing border, shadows, etc). Inserts extra space when going stuck → unstuck. ### 3. [`header::after` with non-zero height only when stuck](https://codepen.io/leaverou/pen/YPpPoqp) Practical in a wider array of cases, but: - `::after` is a shared resource and may already be used (relevant: #13860) - Inserts extra space when going stuck → unstuck. ### 4. [`header::after` + `scrolled` CQ](https://codepen.io/leaverou/pen/ogYXNxb) Uses a `scroll-state(scrolled: top)` CQ to avoid the extra space when going stuck → unstuck. Best solution so far, but not without cons: - Overly complex - Flashing can still happen, just in a much narrower range of scroll positions and only when scrolling up. ---- 1. Is this a Blink implementation bug or per spec? 2. If per spec, how can we fix it? Agenda+ since `scroll-state()` CQs have shipped in Chrome, are a feature with [strong developer signals](https://github.com/web-platform-dx/developer-signals/issues/272), and are discussed as a progressive enhancement that causes no harm. Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/13898 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Thursday, 7 May 2026 15:56:16 UTC