Commit 37809cf
authored
Fix iOS end-snap drift in filters carousel by using vi instead of cqw (#2360)
### Summary
On the homepage **Backdrop filters** carousel, the **last card** (e.g.,
`sepia`) ends up **horizontally offset to the right** on **real iOS
devices** (Safari and Chrome). Chrome DevTools mobile emulation does
**not** reproduce it. I noticed this while working on the tooltip PR.
### Proof
<img
src="https://github.com/user-attachments/assets/01068d94-5d62-43ba-86d5-aedcd53b3e34"
width="400px"/>
### Repro
1. Open [https://tailwindcss.com/](https://tailwindcss.com) on an iPhone
(iOS 17+).
2. Scroll to the filters carousel.
3. Let auto-scroll advance to the last item.
4. Observe the card sits offset to the right.
### Minimal Fix (tested hotfix)
```diff
- w-[calc(50cqw-(var(--size)/2)-(var(--gap)))]
+ w-[calc(50vi-(var(--size)/2)-(var(--gap)))]
```
**Rationale:** In this full-bleed section, `50cqw ≈ 50vi`. Swapping to
`vi` avoids the container-unit code path that exhibits end-snap bias on
iOS while keeping identical layout intent.
### Explanation
* The section uses **container query units** (`cqw`) for spacer math at
the ends; `cqw` = 1% of the query container’s width. [MDN Web
Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries#:~:text=cqw%3A%201%25%20of%20a%20query%20container%27s%20width)
* When the container is effectively full-bleed on mobile, `50cqw` ≈
**`50vi`** (viewport inline size). `vi` is the writing-mode-aware
"viewport width" (LTR pages: `vi === vw`).
* Defining the snap "center" via **`scroll-padding`** (or
`scroll-padding-inline`) is spec-intended and used during **scroll
snap** and **scroll-into-view** operations. [MDN Web
Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding)
* Switching the spacer calc from `cqw`→`vi` removed the offset on real
devices (no other changes). This suggests the issue is tied to
container-unit rounding + end snap behavior, not content layout.
### Follow-up (separate PR if desired; not included here)
* Remove end spacer nodes and define center with
`scroll-padding-inline: calc(50vi - var(--size)/2);`
* Use programmatic centering that honors scroll-padding:
`node.scrollIntoView({ inline: 'center', block: 'nearest' });`1 parent efc3311 commit 37809cf
1 file changed
+2
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
276 | 276 | | |
277 | 277 | | |
278 | 278 | | |
279 | | - | |
| 279 | + | |
280 | 280 | | |
281 | 281 | | |
282 | 282 | | |
| |||
298 | 298 | | |
299 | 299 | | |
300 | 300 | | |
301 | | - | |
| 301 | + | |
302 | 302 | | |
303 | 303 | | |
304 | 304 | | |
| |||
0 commit comments