Why does my Shopify store scroll sideways on mobile?
Your store scrolls sideways because one element on the page is wider than the phone screen, and the page stretches to contain it. It is almost never the wrapper the browser appears to blame: it is a row inside that wrapper which cannot wrap onto a second line or cannot shrink below its natural width, and one line pasted into a browser console will name it in about thirty seconds.
The numbers on this page come from our own audit. We sweep every theme we generate at a 390 by 844 viewport and fail the build on horizontal overflow, and in August 2026 that sweep found four distinct defect classes across 20 design presets. Every measurement below is from that run rather than from general advice.
What causes a Shopify theme to scroll sideways on mobile?
A phone gives you less room than the viewport number suggests. At 390px wide, a container with the usual 1.5rem gutter on each side leaves 342px of usable content width. Anything whose minimum width exceeds 342px pushes the page open. These are the five causes we actually measured, ranked by how often they occurred.
| Cause | What it looks like in the code | Measured example | Fix |
|---|---|---|---|
| A flex row that cannot wrap | display: flex with no flex-wrap, holding more items than fit |
A footer social row of 9 icons at 30px with 1rem gaps has a minimum width of 398px. That is 56px past the 342px available, and it broke 20 of 20 presets by exactly 32px | flex-wrap: wrap |
| A grid or flex child stuck at its natural width | No min-width rule, so the item keeps the min-width: auto default and refuses to shrink |
The footer brand column had no rule at all, so it expanded its own grid track to 398px inside a 342px container | min-width: 0 on the child |
| Inline content with no break opportunity | Liquid tag whitespace stripped, so links and separators render back to back and the browser treats the whole row as one unbreakable word | One footer style overflowed by 407px, more than the width of the phone itself | Make the row a wrapping flex container so every item gets a break point |
| A mobile override that was silently inert | A media query sets grid-template-columns on an element whose base rule is display: flex, so the property is ignored and the mobile stack never happens |
35px of overflow on a footer preset that appeared to have a mobile layout and did not | Match the property to the display mode the element is actually in |
| Letter spacing on a logo or heading | A tracking value tuned for desktop, applied at every width | Tracking added up to 115px to a 16 character store name whose glyphs measured only about 141px. The spacing was most of the width | Cap tracking inside the mobile media query |
Two causes that everyone suggests first were not responsible for a single one of these: width: 100vw (which is wider than the content area because it includes the scrollbar) and a missing box-sizing: border-box. Both are real, both are worth ruling out in ten seconds, and neither is the common case in a modern Shopify 2.0 theme where border-box is usually already global. The common case is a row that cannot fold.
Why does only one product page scroll sideways?
When one product or page scrolls sideways and the rest of the store does not, the cause is almost always something pasted into that product's description, not the theme. A size chart table, a YouTube embed or text copied from a word processor carries its own width, and Dawn caps images in the description but not those.
We measured it on 28 October 2026: Dawn 16.0.0's own stylesheet (base.css) loaded in Chromium at a 390 by 844 phone viewport, each pasted element placed inside Dawn's rich text container (the rte class that product descriptions render in), then the page width read back.
| Pasted into the description | Page width at 390px | Overflows? |
|---|---|---|
| Plain paragraph text | 390px | No |
Image with width="800", or style="width:800px" | 390px | No. Dawn sets max-width: 100% on description images |
Size chart table with width="600" | 615px | Yes, by 225px |
Table with style="width:600px" | 615px | Yes |
| Table with no width at all, 8 columns | 619px | Yes. Removing the width is not enough on a wide chart |
| Table with no width, 5 long one word headers (Measurement, Circumference and so on) | 558px | Yes |
YouTube embed code, width="560" | 575px | Yes |
<video> tag, width="640" | 655px | Yes |
A preformatted SKU line (<pre>) | 526px | Yes |
A div with style="width:500px", typical of page builder pastes | 515px | Yes |
A sentence joined by non breaking spaces ( ), common in text pasted from Word or Google Docs | 1,030px | Yes, by 640px |
Images were the one thing Dawn already handled. Everything else overflowed, which is why the problem follows the product rather than the template: the template is fine until a particular description puts a 600px table inside it.
There are two ways to fix it. The first is to fix the content: open the product, click Show HTML (the <> button in the description editor), and delete the width attribute or inline width on the table, video or div. That cures the fixed width cases but not a wide chart with no width set, as the table shows. The second fixes every product at once. This block brought all ten overflowing cases above back to exactly 390px in the same test:
.rte { overflow-wrap: anywhere; }
.rte table { display: block; max-width: 100%; overflow-x: auto; }
.rte iframe { max-width: 100%; height: auto; aspect-ratio: 16 / 9; }
.rte img, .rte video { max-width: 100%; height: auto; }
.rte pre { white-space: pre-wrap; }
.rte div { max-width: 100%; }
Paste it into Online Store, Themes, Customize, then Theme settings and Custom CSS. The table rule does not squeeze an 8 column chart into 342px, which would make it unreadable: it lets the chart scroll sideways inside its own box while the page stays put, the same way the tables on this page behave on a phone. The aspect-ratio line assumes a widescreen video. Dawn and most Shopify themes use the rte class for descriptions; if yours does not, right click the description, choose Inspect, and use the class name you find there.
How do I find the element causing horizontal scroll?
Open your store in a desktop browser, open developer tools, switch on the device toolbar and set the viewport to 390 by 844. Then paste this into the console:
const w = document.documentElement.clientWidth;
document.querySelectorAll('*').forEach(el => {
const r = el.getBoundingClientRect();
if (r.right > w + 1 || r.left < -1) {
console.log(Math.round(Math.max(r.right - w, -r.left)) + 'px', el);
}
});
Every element that pokes past the edge is logged with how far past it goes, and you can hover each result to highlight it on the page. Three details matter:
- Use
clientWidth, notwindow.innerWidth. On a desktop browserinnerWidthincludes the scrollbar, which gives you false readings of a few pixels. - Allow one pixel of tolerance. Sub pixel rounding produces harmless 0.4px results constantly. Our own build gate ignores anything at or under 1px and fails above it.
- Check the left edge too. A negative margin or an absolutely positioned badge sitting at
right: -6pxcan hang off either side. A cart count badge doing exactly that lost 6 of its 17 pixels off screen on 7 of our presets.
Why the element the tool names is usually not the culprit
The snippet above will often log a generic wrapper, something like div.container. That is a symptom, not a cause. A block level element cannot decide to be wider than its parent on its own. It gets dragged out to its minimum content width by a descendant that refuses to shrink, and the wrapper simply inherits that floor.
So when a wrapper is named, look inside it for the widest child, then inside that child, until you reach a row of items rather than another box. That row is the offender. The fastest confirmation is to add flex-wrap: wrap to it in developer tools and watch whether the overflow disappears. If it does, you have found it, and the permanent fix is that same one line in your stylesheet.
The reverse mistake is expensive. Adding overflow-x: hidden to the body is the fix recommended most often online and it is the one to avoid, because it hides the scrollbar without moving the element. The content is still off screen, it is now unreachable instead of awkward, and it can disable smooth scrolling behaviour elsewhere on the page. Fix the row.
Does overflow-x: hidden stop the sideways scroll?
Not where most people put it. On the body, it stopped the scroll in a narrow desktop window but left the page wider than the screen with phone emulation on, and two of the three placements that did work there broke a sticky header. We tested eight placements on a page holding one 600px element and a sticky header, in Chromium at 390px, on 28 October 2026.
| Where the rule goes | Narrow desktop window: sideways scroll stopped? | Phone emulation: page back to 390px wide? | Sticky header still sticks? |
|---|---|---|---|
| No rule (control) | No, scrolled 210px | No, laid out 600px wide | Yes |
overflow-x: hidden on body | Yes | No, still 600px | Yes |
overflow-x: hidden on html | Yes | No, still 600px | Yes |
overflow-x: hidden on both html and body | Yes | Yes | No, scrolled away with the page |
overflow-x: clip on body | Yes | No, still 600px | Yes |
overflow-x: clip on html | Yes | No, still 600px | Yes |
overflow-x: hidden on a wrapper inside body | Yes | Yes | No, scrolled away with the page |
overflow-x: clip on a wrapper inside body | Yes | Yes | Yes |
"Still 600px" means the browser's layout width (window.innerWidth) read 600 on a 390px screen with the rule in place: the page was still laid out wider than the phone. That is the usual story behind "I added overflow-x: hidden and it looks fixed in developer tools but still moves on my phone". A desktop window with the device toolbar off is the one setup where the body rule appears to work.
Only one placement passed all three columns: overflow-x: clip on an element inside body that wraps the content. Two cautions before you lean on it. In Dawn the header and footer sit outside main, so clipping main covers the template's sections but not the footer, which is where our most common cause, the unwrapped social icon row, lives. And clipping still cuts the element off rather than moving it, so anything past the edge stays unreachable. Use it as a stopgap while you find the row. This test ran in Chromium only; Safari on an iPhone was not tested.
How much width does a phone really give you?
Design at the narrow end, not the average. These are the logical viewport widths that matter in 2026, with the content width left after a standard 24px gutter on each side.
| Device | Logical viewport | Usable content width |
|---|---|---|
| Older and budget Android | 320px | 272px |
| iPhone SE | 375px | 327px |
| iPhone 12 through 14 | 390px | 342px |
| iPhone 15 and 16 | 393px | 345px |
| Common large Android | 412px | 364px |
We test at 390 because it is the narrowest width still held by a large share of current iPhones, so passing there covers everything above it. If your customers skew toward budget Android, test 320 as well. The gap between 320 and 412 is 92px, more than a quarter of the screen, and plenty of rows fit in one and not the other.
What a horizontal scroll check will not catch
This is the trap that cost us a month of clean reports. A page can be badly broken on a phone while every scroll measurement says it is fine, because two elements can sit on top of each other without making the page a single pixel wider.
That is exactly what happened to us. The sweep reported 20 of 20 presets passing while 11 of them printed the store name straight through the header icon row, overlapping by up to 102px. No check based on scrollWidth can see that. We had to add a separate assertion comparing the bounding boxes of the two elements directly.
So test three things at 390px, not one:
- Horizontal overflow. The snippet above.
- Overlap. Look hard at the header, the announcement bar and any two column section. Compare bounding boxes if you want it automated.
- Tap target size. WCAG 2.2 sets a minimum of 24 by 24 CSS pixels at the AA level, and Apple recommends 44 by 44 points. Close buttons on announcement bars are the usual offender, because they are often sized by padding alone and any later padding override shrinks them back under the floor.
How do I test my Shopify theme on mobile without a phone?
Five minutes, no device needed, and you can do it on an unpublished theme before it ever reaches a customer:
- In your Shopify admin go to Online Store, then Themes, and choose Preview on the theme you want to check. A draft theme previews against your real products without touching the live store.
- Open developer tools, switch on the device toolbar, and set a custom size of 390 by 844. Do not rely on the named device presets, which change between browser versions.
- Run the console snippet on each page and note anything over 1px.
- Repeat on every template, not just the homepage. Home, product, collection, cart, search, blog article, 404 and the customer account pages each assemble a different set of sections, so a footer bug appears on all of them while a search bug appears on exactly one. In our own sweeps, the templates nobody thinks to open are consistently the ones that fail.
- Scroll the full page at 390px and watch for a heading colliding with an icon or an image, which is the class of defect that measurements miss.
- While you are there, check whether the photos fill their frames, because an image that leaves blank space inside its container is another fault a width measurement cannot see.
If you want it automated, driving the same measurement with a headless browser is straightforward and it is what our build gate does: load each template at 390 by 844, compare document.documentElement.scrollWidth against window.innerWidth, and fail above a one pixel tolerance.
The fixes, in the order to try them
| Symptom | Try this first | Why it works |
|---|---|---|
| A row of icons, links or payment badges overflows | flex-wrap: wrap on the row | Gives the row permission to fold onto a second line instead of setting an unshrinkable floor |
| Only one product or page overflows | The description CSS block in Custom CSS, or remove the pasted width | Dawn caps images in a description but not tables, embeds or pasted widths |
| A column inside a grid or flex layout will not narrow | min-width: 0 on that child | Overrides the auto default that pins an item to its content width |
| A long word, URL or SKU breaks the layout | overflow-wrap: anywhere on the text container | Allows a break inside a token that has no natural break point |
| A logo or heading is far wider than its letters | Cap letter-spacing inside the mobile media query | Tracking multiplies by character count, so it costs the most on the smallest screen |
| An image or embed pushes past the edge | max-width: 100% with height: auto | Stops the intrinsic width of the asset from setting the layout width |
| The page is wider by roughly the width of a scrollbar | Replace 100vw with 100% | 100vw includes the scrollbar gutter, 100% does not |
| Your mobile media query appears to do nothing | Check the display mode and the specificity | Grid properties are inert on a flex container, and a more specific unmediated rule outranks a less specific one inside a media query |
Where these bugs actually come from
Every defect described here shipped inside CSS that was correct at 1280px. None of it was sloppy code, and none of it was visible to the person who wrote it, because a desktop browser hands a footer row 1272px and never asks it to fold. Mobile breakage is less a quality problem than a measurement problem, and the only reliable cure is to measure at the narrow width automatically rather than to remember to look.
That is why Themr runs the 390px sweep as a build gate on the themes it generates rather than as a manual review step. If you are moving to a new theme, our guide to what survives a theme switch covers what carries over and what resets, if the ZIP itself is being rejected, the 11 errors that stop a Shopify theme upload lists every message Shopify returns and what each one means, if the page is not narrow but blank outright, the same habit of measuring rather than guessing applies at desktop widths, and if the layout is fine but the mobile menu will not open, that one is invisible to a width check because a hidden panel has no width to measure.
Frequently asked questions
Why does my Shopify store scroll sideways on mobile?
Because a single element on the page is wider than the phone viewport, and the page expands to contain it. At 390px wide, a container with a 1.5rem gutter on each side leaves only 342px of usable width, so any row whose minimum width exceeds 342px forces horizontal scroll. The most common offender by far is a flex row with no flex-wrap, such as a footer social icon row.
How do I find the element causing horizontal scroll on my Shopify theme?
Set your browser viewport to 390 by 844, then run a script that loops over every element, compares its bounding rectangle against document.documentElement.clientWidth, and logs anything more than one pixel past the edge. Use clientWidth rather than window.innerWidth, because innerWidth includes the scrollbar and produces false positives of a few pixels.
Should I fix horizontal scroll with overflow-x hidden?
No. Setting overflow-x: hidden on the body hides the scrollbar without moving the element, so the content stays off screen and becomes unreachable rather than awkward, and it can disable smooth scrolling behaviour elsewhere on the page. Find the row that cannot shrink and let it wrap instead.
What screen width should I test a Shopify theme at?
Use 390 by 844 as the baseline. That is the logical viewport of the iPhone 12 through 14 and the narrowest width still common on current iPhones, so passing there covers every wider device. Add 320px if your customers use budget Android devices.
Why does my theme look fine in the Shopify theme editor but broken on a real phone?
The editor preview pane is not a real phone viewport, so a layout that folds correctly inside it can still overflow on a device. Preview the theme in a normal browser tab with developer tools set to a 390px viewport, or open the preview link on an actual phone. A draft theme can be previewed against your real products without publishing it.
Why does only one product page on my Shopify store scroll sideways?
Because something pasted into that product description has its own width. In a test with Dawn 16.0.0 at 390px, a size chart table with width 600 made the page 615px wide, a YouTube embed made it 575px, and a sentence joined by non breaking spaces from a word processor made it 1,030px. Images did not overflow, because Dawn caps description images at 100% width. Remove the pasted width in Show HTML, or add CSS that limits tables, iframes and videos inside the description.
How do I make a size chart table fit on mobile in Shopify?
Give tables inside the description display: block, max-width: 100% and overflow-x: auto, in Theme settings then Custom CSS, using the description class of your theme (rte in Dawn and most Shopify themes). The chart then scrolls sideways inside its own box while the page stays at the phone width. Removing the width attribute alone is not enough for a wide chart: an 8 column table with no width set still made the page 619px wide at 390px.
Does overflow-x: hidden on the body stop horizontal scroll on phones?
Not reliably. In Chromium at 390px it stopped the scroll in a narrow desktop window, but with phone emulation on the page was still laid out 600px wide around a 600px element. The same was true for overflow-x: hidden on html and for overflow-x: clip on html or body. Only a rule on a wrapper element inside body brought the page back to 390px, and fixing the element that is too wide remains the real cure.
Why did my sticky header stop working after I added overflow-x: hidden?
Because overflow hidden turns the element into a scroll container, and a sticky header sticks to its nearest scroll container rather than the window. In our test, overflow-x: hidden on both html and body, or on a wrapper around the header, made the header scroll off the page. overflow-x: clip on the same wrapper stopped the sideways scroll and kept the header sticky.
Can a Shopify theme be broken on mobile without scrolling sideways?
Yes, and this is the failure mode automated checks miss. Two elements can overlap perfectly inside the viewport without making the page a single pixel wider. In one audit of 20 design presets, every preset passed the horizontal scroll check while 11 of them printed the store name over the header icon row by up to 102 pixels. Overlap needs its own check that compares bounding boxes.
Does horizontal scroll on mobile hurt my Shopify SEO?
Indirectly. Google indexes mobile first, so the mobile rendering of your page is the version assessed, and content sitting off screen is a usability problem on the page that ranks. The larger cost is commercial rather than algorithmic: a checkout button or a size selector that has drifted past the edge of the screen cannot be tapped.
Generate a theme that looks like your brand
A complete Shopify 2.0 theme with conversion features built in, ready in minutes. No credit card required.
Generate my theme freeNo Shopify store yet? Start one here, then bring the theme. Themr may earn a commission if you start a paid plan; it does not change what you pay.