{"componentChunkName":"component---src-templates-post-jsx","path":"/blog/strategies-for-dealing-with-horizontal-overflows/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nconst _frontmatter = {\n  \"title\": \"How to find the cause of horizontal scrollbars\",\n  \"slug\": \"Strategies for dealing with horizontal overflows\",\n  \"cover\": \"/blogs/detect-overflow/overflow.svg\",\n  \"date\": \"2020-10-08\",\n  \"updated\": \"2026-05-22\",\n  \"type\": [\"tutorial\"]\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n    components\n  } = _ref,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, `One of the most time consuming issues when it comes to web development is `, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `debugging horizontal scrollbars`), `.`), mdx(\"p\", null, `They're easy to overlook while developing (especially on macs) and if users scrolls horizontally, your layout will look broken to them.`), mdx(\"p\", null, `On top of that it's hard to determine which element is causing the overflow.`), mdx(\"h2\", {\n    \"id\": \"what-causes-horizontal-scrollbars\"\n  }, `What causes horizontal scrollbars?`), mdx(\"p\", null, `There area few common causes for horizontal scrollbars and overflows:`), mdx(\"h3\", {\n    \"id\": \"setting-the-width-of-the-body-to-100vw\"\n  }, `Setting the width of the body to `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `100vw`)), mdx(\"p\", null, `The viewport width unit (`, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `vw`), `) is a useful way to make things a certain percentage of the screen wide.`), mdx(\"p\", null, `When you use `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `100vw`), ` however, you make something the full width of the viewport and this `, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `includes the width of scrollbars`), ` in all browsers except for Chromium 145 and up. Tthat means that your page is slightly wider than the available width (which is the full width of the viewport `, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `without the scrollbars`), `).`), mdx(\"p\", null, `In short: if you use `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: 100vw`), ` on a page that has a vertical scrollbar you end up with a horizontal overflow.`), mdx(\"p\", null, `The easy fix is to use `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: 100%`), ` instead. Percentages don't include the width of the scrollbar, so will automatically fit.`), mdx(\"p\", null, `If you can't do that, or you're setting the width on another element, add `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `overflow-x: hidden`), ` or `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `overflow: hidden`), ` to the surrounding element to prevent the scrollbar.`), mdx(\"h3\", {\n    \"id\": \"fixed-width-elements\"\n  }, `Fixed width elements`), mdx(\"p\", null, `An image or element might have a width of 500px in your desktop layout. When you hardcode that in your CSS, it's going to cause a scrollbar on mobile screens that are only 375 pixels wide.`), mdx(\"p\", null, `That might sound overly simple, but it's often the cause of overflow issues. Particularly when images are added through a CMS.`), mdx(\"p\", null, `This happens more when you develop the desktop version first, so `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/blog/responsive-design-ground-rules/#rule-2-mobile-first\"\n  }), `Mobile first design`), ` is a good prevention.`), mdx(\"h3\", {\n    \"id\": \"using-width-100-instead-of-width-stretch\"\n  }, `Using `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: 100%`), ` instead of `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: stretch`)), mdx(\"p\", null, `When you use `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: 100%`), ` on an element, it will be as wide as its parent element (well, containing block). if that parent element then shows a scrollbar, that width 100% will be wider than the available space (which is 100% minus the width of the scrollbar) and cause a horizontal overflow.`), mdx(\"p\", null, `The solution to this is to use `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: stretch`), ` instead of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `width: 100%`), `. Stretch will make the element as wide as the available space and will automatically adjust to the presence of a scrollbar. While \"new\" relative to other width properties, it has support in all evergreen browsers since the end of 2025, so you can probably use it in production today.`), mdx(\"h3\", {\n    \"id\": \"not-clipping-off-screen-elements-or-elements-that-are-wider-than-the-viewport\"\n  }, `Not clipping off-screen elements or elements that are wider than the viewport`), mdx(\"p\", null, `Some design elements might require you to place them outside of the viewport.`), mdx(\"p\", null, `Like a menu that slides in the from the right or a wider-than-the-viewport-element with rounded corners to get a certain curve in your design like in this video:`), mdx(Tweet, {\n    tweetLink: \"polypane/status/1297889899450859524\",\n    align: \"center\",\n    mdxType: \"Tweet\"\n  }), mdx(\"p\", null, `The curve on that site extended past the viewport. Because it wasn't contained in an element with `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `overflow: hidden`), `, all of it was visible after you scrolled.`), mdx(\"h2\", {\n    \"id\": \"finding-horizontal-scrolling-issues\"\n  }, `Finding horizontal scrolling issues`), mdx(\"p\", null, `Now that we know some of the reasons overflow happens, lets look at how to find them.`), mdx(\"h3\", {\n    \"id\": \"using-the-devtools\"\n  }, `Using the devtools`), mdx(\"p\", null, `To find out which elements cause a horizontal scrollbar, you can use the devtools to delete elements one by one until the scrollbar disappears.`), mdx(\"p\", null, `When that happens, press `, mdx(\"kbd\", null, `ctrl/cmd Z`), ` to undo the delete, and drill down into the element to figure out which of the child elements cause the horizontal scrollbar. That works in all browser devtools.`), mdx(\"p\", null, `This is obviously very time consuming, so it helps to make all elements visible.`), mdx(\"h3\", {\n    \"id\": \"adding-outlines-to-all-elements\"\n  }, `Adding outlines to all elements`), mdx(\"p\", null, `By default, elements are \"invisible\". They're there and take up space, but unless they have a background or border you won't see where they are. So when you make all of them visible, it becomes easier to find the one causing an overflow. A common solution for this it to add outlines to all elements by adding the following style to your CSS:`), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"css\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"className\": \"language-css\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-css\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token selector\"\n  }), `*`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `{`), `\n  `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token property\"\n  }), `outline`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `:`), ` 1px solid red`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`), `\n`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `}`)))), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, `We're using `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `outline`), ` here and not `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `border`), `, because outline does not affect the rest of the layout in a way that border does. Adding a border to all elements might `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `cause`), ` a horizontal overflow where there wasn't one before.`)), mdx(\"p\", null, `Of course, editing your CSS file every time you need to debug something is also not very time efficient. Instead you can paste the following line into your console to add an outline to all elements.`), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"javascript\"\n  }, mdx(\"pre\", _extends({\n    parentName: \"div\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token function\"\n  }), `$$`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `(`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token string\"\n  }), `'*'`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `)`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `.`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token function\"\n  }), `forEach`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `(`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `(`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token parameter\"\n  }), `el`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `)`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token operator\"\n  }), `=>`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `(`), `el`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `.`), `style`, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `.`), `outline `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token operator\"\n  }), `=`), ` `, mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token string\"\n  }), `'1px solid red'`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `)`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `)`), mdx(\"span\", _extends({\n    parentName: \"code\"\n  }, {\n    \"className\": \"token punctuation\"\n  }), `;`)))), mdx(\"p\", null, `To get rid of it you reload the page. Doing that also gets rid of any changes you made in the devtools to fix the overflow, so it's not ideal but it will work in any browser.`), mdx(\"h3\", {\n    \"id\": \"polypane-adding-outlines-with-a-shortcut\"\n  }, `Polypane: Adding outlines with a shortcut`), mdx(\"p\", null, `Polypane has this outline built-in under a handy shortcut: `, mdx(ShortCutDisplay, {\n    letter: \"d\",\n    cmdKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), `.`), mdx(\"p\", null, `When activated Polypane draws boxes around all elements in all panes. It also uses a different color per element to keep them apart, something that would be a lot of work to do in your own CSS:`), mdx(\"img\", {\n    src: \"/blogs/detect-overflow/layoutdebug.png\",\n    className: \"imgshadow\",\n    alt: \"Polypane with layout debugging turned on\"\n  }), mdx(\"p\", null, `While you can now clearly see which elements are overflowing the page, you still have to hunt down their 1px outlines to find them.`), mdx(\"h3\", {\n    \"id\": \"polypane-highlighting-overflowing-elements\"\n  }, `Polypane: Highlighting overflowing elements`), mdx(\"p\", null, `When Polypane detects a pane that has a horizontal scrollbar, it `, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `automatically highlights elements that cause the overflow`), `. See this video for an example.`), mdx(\"video\", {\n    src: \"/blogs/detect-overflow/overflow1.mp4\",\n    autoPlay: true,\n    loop: true,\n    controls: true,\n    className: \"breakout\"\n  }), mdx(\"p\", null, `With this feature you won't have to hunt around for them any longer. All overflowing elements are visually highlighted so you don't have to spend time hunting them down any longer.`), mdx(\"p\", null, `With the shared elements editor you quickly verify that the changes you made fix the overflow in all panes.`), mdx(\"h2\", {\n    \"id\": \"polypane-detecting-horizontal-overflows-automatically\"\n  }, `Polypane: Detecting horizontal overflows automatically`), mdx(\"p\", null, `In Polypane, any pane that has a horizonal overflow or contains a layout that uses `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `100vw`), ` for the width is highlighted\nwith a `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/horizontal-overflow/\"\n  }), `horizontal overflow icon`), ` that tells you which issue it found.`), mdx(\"img\", {\n    src: \"/doc-img/horizoverflow.png\",\n    className: \"imgshadow\",\n    alt: \"The horizontal overflow icon.\"\n  }), mdx(\"p\", null, `Clicking the icon will help you detect the overflow causing elements by highlighting them in red, or show you which\nlayout element has `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `100vw`), ` applied.`), mdx(\"p\", null, `All overflow-causing elements are also logged to the console so you can quickly inspect them.`), mdx(\"p\", null, `With Polypane, debugging horizontal layout issues goes from diving into the devtools to delete elements one by one to your\nbrowser telling you there's an issue and giving you the solution by clicking a single button.`), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, mdx(\"a\", _extends({\n    parentName: \"strong\"\n  }, {\n    \"href\": \"https://dashboard.polypane.app/register?ref=detect-overflow-article\"\n  }), `Start a trial`), ` and try Polypane for yourself.`)));\n}\n;\nMDXContent.isMDXComponent = true;","timeToRead":4,"tableOfContents":{"items":[{"url":"#what-causes-horizontal-scrollbars","title":"What causes horizontal scrollbars?","items":[{"url":"#setting-the-width-of-the-body-to-100vw","title":"Setting the width of the body to 100vw"},{"url":"#fixed-width-elements","title":"Fixed width elements"},{"url":"#using-width-100-instead-of-width-stretch","title":"Using width: 100% instead of width: stretch"},{"url":"#not-clipping-off-screen-elements-or-elements-that-are-wider-than-the-viewport","title":"Not clipping off-screen elements or elements that are wider than the viewport"}]},{"url":"#finding-horizontal-scrolling-issues","title":"Finding horizontal scrolling issues","items":[{"url":"#using-the-devtools","title":"Using the devtools"},{"url":"#adding-outlines-to-all-elements","title":"Adding outlines to all elements"},{"url":"#polypane-adding-outlines-with-a-shortcut","title":"Polypane: Adding outlines with a shortcut"},{"url":"#polypane-highlighting-overflowing-elements","title":"Polypane: Highlighting overflowing elements"}]},{"url":"#polypane-detecting-horizontal-overflows-automatically","title":"Polypane: Detecting horizontal overflows automatically"}]},"excerpt":"One of the most time consuming issues when it comes to web development is  debugging horizontal scrollbars . They're easy to overlook while developing…","frontmatter":{"title":"How to find the cause of horizontal scrollbars","cover":"/blogs/detect-overflow/overflow.svg","date":"2020-10-08","updated":"2026-05-22"},"fields":{"slug":"/blog/strategies-for-dealing-with-horizontal-overflows/","date":"2020-10-07T22:00:00.000Z","ogFileName":"how-to-find-the-cause-of-horizontal-scrollbars"}}},"pageContext":{"slug":"/blog/strategies-for-dealing-with-horizontal-overflows/"}},"staticQueryHashes":["4164364741","425175329"]}