Skip to content

Commit 37809cf

Browse files
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

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

src/components/home/why-tailwind-css-section.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ export default function WhyTailwindCssSection() {
276276
<div className="@container relative flex size-full items-center justify-center">
277277
<Autoscroll className="no-scrollbar z-10 -my-1 flex snap-x snap-mandatory gap-(--gap) overflow-x-auto py-1 [--gap:--spacing(10)] [--size:--spacing(72)]">
278278
<div className="flex snap-proximity snap-end">
279-
<div className="w-[calc(50cqw-(var(--size)/2)-(var(--gap)))]" />
279+
<div className="w-[calc(50vi-(var(--size)/2)-(var(--gap)))]" />
280280
</div>
281281

282282
{[
@@ -298,7 +298,7 @@ export default function WhyTailwindCssSection() {
298298
})}
299299

300300
<div className="flex snap-proximity snap-end">
301-
<div className="w-[calc(50cqw-(var(--size)/2)-(var(--gap)))]" />
301+
<div className="w-[calc(50vi-(var(--size)/2)-(var(--gap)))]" />
302302
</div>
303303
</Autoscroll>
304304

0 commit comments

Comments
 (0)