DEV Community

Daniel Pertu
Daniel Pertu

Posted on

Our comparison tables cut off the competitor's column on a 320px phone, and the rounded corner is why you cannot scroll to it

WCAG 1.4.10 asks that content reflow to 320 CSS pixels without needing to scroll in two directions. 320 is a small phone at default zoom, or a normal phone at 400% zoom, which is the case the criterion is really about.

I had never tested our site at 320. So I drove Chrome over the DevTools protocol, set the device metrics to 320, 360, 390 and 430 by 844, loaded six representative pages at each width, and for every element inside main, header and footer compared its bounding rectangle against the viewport.

The good half

The pages that make up most of the site pass cleanly. A guide, a question page, a free tool: at all four widths, document.documentElement.scrollWidth equals clientWidth. No element sticks out, nothing scrolls sideways, the body copy wraps into a 288px column at 320 and reads fine.

That is not a compliment to anybody's craft. Those pages are a heading, paragraphs and a labelled list rendered by one component, and a column of text is the easiest thing in the world to reflow. The interesting results are where a page does something else.

The comparison tables

We have six comparison pages, and each one has a three-column table: the feature, what we do, what they do. Kahoot for pub quiz is the one I measured hardest.

At a 320px viewport:

wrapper client width   286
table scroll width     382
clipped                 96px
wrapper overflow-x     hidden
Enter fullscreen mode Exit fullscreen mode

The table will not go below 382px, because its three columns have content that will not go narrower. The wrapper it sits in is 286px. So 96 pixels of the table are outside the box, and the box is overflow: hidden, which means they are not merely outside, they are gone. A finger swipe does nothing. The only thing that can reach that column is element.scrollLeft from the console, which I used to confirm the content is really there: it scrolls to 96.5 and the Kahoot column appears.

Nine of the table's 27 cells are partly or wholly past the clip: the "Kahoot" header and all eight of its answers. What a visitor on a small phone sees is our column in full, then a tick or a cross for the competitor at the right edge, with the sentence that explains it cut off.

All six pages have the same shape at 320:

page table width visible clipped
paper-vs-app-quiz 400 286 114
sporcle-live-alternative 394 286 108
speedquizzing-alternative 392 286 106
ahaslides-alternative 383 286 97
kahoot-for-pub-quiz 382 286 96
quizxpress-alternative 369 286 83

By 430px the Kahoot table fits with nothing clipped.

Why the overflow-hidden is there

The wrapper's classes are border-border overflow-hidden rounded-lg border. That is a standard combination and it has a reason: a table inside a rounded container will square off the corners by painting over them, and overflow-hidden is what makes the radius clip the table's corner cells.

So the rule is doing exactly what it was added to do. It is a border-radius fix that silently became a content-deletion rule at small widths, and nothing noticed because at the width you build a comparison table on, the table fits.

The fix is small: overflow-x-auto on the wrapper, which keeps the clip and makes the overflow reachable, plus the usual accompanying tabindex="0" so a keyboard can reach a scrollable region, and a visible hint that there is more to the right. That gets us from "content missing" to "content requires horizontal scroll", which is still not a pass on reflow, but is honest and usable. The real pass is a stacked layout under the table's breakpoint.

The 10 pixels on the homepage

One more finding at 320, on the homepage:

document scrollWidth  330
document clientWidth  320
Enter fullscreen mode Exit fullscreen mode

Ten pixels of horizontal scroll on the whole document. The cause is the pair of buttons under the hero. The row is flex flex-row gap-2, the buttons measure 156 and 177 wide, the gap is 8, which totals 341 inside a 320 viewport. The row is centred, so it hangs 10px off the left and 10px off the right, and the document grows to match.

There is no flex-wrap and no stacked variant below the small breakpoint, so the two buttons never become one column. At 360 the arithmetic works out and the overflow disappears, which is why the problem is invisible on nearly every device anybody tests on. 320 is iPhone SE territory, plus everybody who zooms.

While I was there I measured the sticky header at the same width. The wordmark's right edge lands at x=119 and the "Sign in" link starts at x=119. They do not overlap, they touch exactly, with zero gap, and the "Get started" button ends 9px from the right edge of the screen.

The thing that looks broken and is not

The animated product mock on the homepage measures 900px wide at every viewport, sitting 49px from the left, running 629px past the right edge. That is deliberate: it has an explicit min-w-[900px], a negative right margin and a clipping wrapper, so on a phone you see the left portion of a full-size interface rather than a shrunken illegible one. It is the only element on the site that overflows on purpose, and it does not add to the document width.

Which is the whole lesson of the sweep: an automated overflow check gives you a list of elements sticking out of the viewport, and that list contains deliberate design, harmless internal scroll, and genuine content loss, in no particular order. The one that mattered was the quietest of the three, because it does not look broken at all. It looks like a table with a column of ticks.

Check it yourself

Open any of our comparison pages in DevTools with the device toolbar at 320px wide, scroll to the table, and try to swipe it sideways. Then paste this into the console:

const w = document.querySelector("main table").parentElement
console.log(w.clientWidth, w.scrollWidth, getComputedStyle(w).overflowX)
w.scrollLeft = 300
Enter fullscreen mode Exit fullscreen mode

The last line is the only thing on that page that can show you the right-hand column.

Top comments (0)