Search topics
Pages that scroll sideways on a narrow screen
A card grid whose columns can't shrink below 320 pixels doesn't fit a 320-pixel screen once the page's padding is added, so every card runs off the right edge.
The problem
People who zoom in to read have to scroll sideways to read every line, and can miss what is past the edge.
A pottery studio lists its classes as cards: Wheel basics, Glazing, Hand building. Each card has a title, a date, a price and a Book button. On a laptop the cards sit three to a row; on the phones the team tests on they stack in one column. Someone with low vision zooms the page to 400% in a window 1280 pixels wide, which gives the page 320 CSS pixels to work with. The cards no longer fit. Every card runs 20 pixels off the right edge, the ends of its longer lines are cut off, and the page scrolls sideways. To read each card they scroll right, then back left, and again for the next card.
The grid uses repeat(auto-fill, minmax(320px, 1fr)), which looks responsive: it drops to fewer columns as the screen narrows. But it never makes a column narrower than 320 pixels, a width chosen so that one card exactly fills a 360-pixel phone, the narrowest the team tests on. The page has 20 pixels of padding on each side, so a 320-pixel screen leaves 280 pixels for the grid, and the one remaining column sticks out of it by 40 pixels, 20 of them past the edge of the screen. Phone testing never shows it: few phones in use today are narrower than 360 pixels. Zoom is what gets the page down to 320. Success criterion 1.4.10 asks that content can be read at a width of 320 CSS pixels without scrolling in two directions, except for content such as data tables, maps and diagrams that needs a two-dimensional layout. A list of cards is not that kind of content.
Anyone who sees the page at 320 CSS pixels wide. Today that is mostly people who zoom a desktop browser to 400% or use a magnifier; on a phone it takes zoom or a larger display size setting, since few phones are that narrow on their own. A wide window does not help at that zoom, because zoom shrinks the width in CSS pixels.
3 of 10 groups affected
- No vision (not affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited vision People who zoom the page to 400%, or use a screen magnifier, see only part of each line and have to scroll sideways and back again for every line they read. What lies past the edge, such as a price or a Book button, is easy to miss altogether.
- Limited manipulation Scrolling in two directions takes far more effort for people using a keyboard, a switch or a mouth stick, and a horizontal scrollbar is a small, hard target.
- Limited language, cognitive and learning abilities Lines that run off the screen break up reading, and people who lose their place have to find the start of the next line again each time.
Most scanners load the page once, at desktop width, where three columns fit with room to spare. axe has no rule for reflow. A probe has to set the viewport to 320 pixels and compare the page's scroll width with its visible width, then find which element is too wide. AI fixes often go wrong in one of three ways:
overflow-x: hiddenon the body: the scrollbar goes, but the right edge of every card, and the end of every long line in it, is now cut off with no way to reach it.- A breakpoint at 360 or 390 pixels, the widths of popular phones: it misses 320, the width zoom produces and the criterion names.
- Shrinking the text or the padding until it fits: it moves the edge a little and breaks again with the next long title.
Try it
Zoom the page to 400% and read the classes.
Drag the Zoom slider. The window stays 1280 pixels wide, so at 400% the page has 320 CSS pixels. Do the cards still fit?
Broken Can you fix this?
A recreated demo. The broken version is intentionally inaccessible.
The fix
Wrap the column minimum in min(100%, …), so a column is never wider than its container.
- 1Never give a column or container a minimum width wider than 320 pixels minus the padding around it.
- 2Let images, embeds and long words shrink or break to fit.
- 3Only tables, maps, diagrams, code and media may scroll sideways, and then inside their own box.
<main class="page"> <h1>Classes this month</h1> <ul class="classes"> <li class="class-card"> <h2>Wheel basics</h2> <p>Saturday 14 November, 10:00 to 13:00</p> <p class="price">$65</p> <a href="/classes/wheel-basics" class="book">Book</a> </li> <!-- Glazing, Hand building --> </ul></main>At 320 pixels the grid has 280 pixels, but each column insists on 320, so every card runs 20 pixels past the right edge of the screen and the page scrolls sideways.
min(100%, 320px) is 320 pixels while the grid is wider than that, and the grid's own width when it is narrower. On a wide screen nothing changes: columns are still at least 320 pixels and fill the row. At 320 pixels the single column shrinks to 280 and fits. Because it measures the grid itself, not the window, it holds wherever the grid is placed: beside a sidebar, inside a dialog, or in a narrow column.
Both options make the class list fit at 320 pixels and pass 1.4.10 on this page. Capping the minimum with min() is recommended: it is one change to one line, it keeps the wide layout exactly as designed, and it measures the space the grid really has, so it can't be broken by a change elsewhere in the layout. The breakpoint option is the more familiar pattern and is fine where you already have a mobile-first stylesheet, but it is only as good as its breakpoint, which has to be checked again each time the grid moves into a different layout.
Find the other fixed widths. The grid is rarely the only one. Look for width and min-width in pixels on containers, sidebars, forms, buttons and cards, and for 100vw, which includes the vertical scrollbar and is a few pixels wider than the page. Prefer max-width with width: 100%, or min(100%, …).
Flex and grid children. A flex child's minimum width defaults to the width of its content, so one long word or wide table inside it pushes the whole layout wide. Add min-width: 0 to the child and let the content wrap.
Long words. Email addresses, URLs, order numbers and German compound words don't wrap by default. overflow-wrap: anywhere on text containers lets them break when nothing else fits, without changing ordinary text.
Media. Images, video and iframes keep their width attribute unless told otherwise; give them max-width: 100% and height: auto. An embedded map or chart that needs two dimensions can scroll inside its own box.
Content that may scroll. The exception in 1.4.10 covers data tables, maps, diagrams, video, games, toolbars that must stay on one line, and code where line breaks change meaning. Wrap a wide table in an element with overflow-x: auto, a visible edge, tabindex="0", and a role and name (role="region" with aria-labelledby pointing at the caption), so keyboard users can scroll it. The rest of the page must still reflow.
Don't hide the overflow. overflow-x: hidden or clip on the body or a wrapper removes the scrollbar but not the problem; the cut-off part becomes unreachable, which also fails 1.4.10 (failure F102 covers content that disappears).
The viewport tag. Without <meta name="viewport" content="width=device-width, initial-scale=1"> a phone lays the page out at about 980 pixels and shrinks it. A fixed width=1024 in that tag has the same effect, and stops the page from reflowing on any phone.
Vertical text and short screens. For content that scrolls sideways by design, such as a horizontal timeline, the criterion asks the same at a height of 256 pixels. Sticky headers and footers at 400% can cover most of a short screen; see the focus-not-obscured guide.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Zoom, Keyboard
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared layout or grid styles change.
Limits
This is a starting pattern, not a guarantee for every application. Passing at 320 pixels doesn't make a layout good at 320 pixels: check that the reading order still makes sense once the columns stack, and that nothing important has been pushed far down the page. Paths and class names in the snippets are placeholders. Test every page template, not only the one with the card grid.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.