Grow your CSS skills. Land your dream job.

Finding/Fixing Unintended Body Overflow

Published by Chris Coyier

Ughck, accidental horizontal scrollbar, amiright?

That can be a pain, but you can usually find the offending element by surfing around the ol' DevTools and selecting elements until you find something that extends too far over to to the right (off-page to the left doesn't tend to trigger a scrollbar the same way) and adjusting it.

Sometimes I use the "Delete Node" feature of DevTools to remove stuff from the page until the scrollbar goes away. Then I know which element caused it and can drill down from there. Here's a super quick video of that kind of troubleshooting:

In some cases, there might be an element that is literally wider than the document is, which might cause horizontal overflow scrolling. You could use a little JavaScript to help you find the culprit.

var docWidth = document.documentElement.offsetWidth;

[].forEach.call(
  document.querySelectorAll('*'),
  function(el) {
    if (el.offsetWidth > docWidth) {
      console.log(el);
    }
  }
);

Which might find something like:

Another minor little trick that helps me sometimes is to scroll over so you can see offending overflow area, and then click and Inspect Element in that space to see if you can target the offending element.

Hidden Horizontal Overflow

Sometimes horizontal overflow is more elusive. Like when it doesn't trigger a horizontal scrollbar, but you can still expose the overflow by swiping with a touchpad or select-and-dragging.

I've made a basic demo of that scenario, see this GIF:

What's going on there is that there is an element that is positioned there, offscreen, with opacity: 0; so you can't see it. Normally that would trigger horizontal overflow and a horizontal scrollbar, but we're explicitly hiding it:

body {
  overflow-x: hidden;
}
.hidden-thing {
  position: absolute;
  left: 100%;
  width: 50px;
  height: 50px;
  opacity: 0;
}

In most scenarios, when an element is hidden outside of the bounds of an element with hidden overflow, it's just kinda lost to the visual world. But with the document itself, you can still force a scroll over there. Weird but true. It's likely even a bug, since if you do overflow: hidden; rather than overflow-x: hidden; - it stops it. It's just more common and practical to use overflow-x.

Note this is an issue in desktop Blink or WebKit based browsers. Not an issue in Gecko or anything mobile that I've seen.

Having hidden offscreen elements isn't particularly rare. I think it's getting more and more common with, you know, animations! transitions! 3D fancy! material design! transitional interfaces! I ran into this issue designing the search form on CodePen that kinda slides out when you click a thing. Simplified, that would be like this:

The solution, in this case, is to hide the overflow on a parent element, rather than relying on the hidden overflow on the body.

Comments

  1. Neato, thks

  2. daddison

    normally go for *{ border:1px solid #red !important} to find the element but the .js solution looks v useful

  3. fgvv

    You should really get into keyboard shortcuts. Nodes can be deleted via the del key. So much faster.

    • Little hard to screencast a keyboard shortcut. They make little apps to show off what key you are pressing when you press them, but it’s kinda annoying.

    • Tem Corner
      Permalink to comment#

      Sure, for the screencast it may be more visible. But you’ll also want to teach the way that’s more productive (as developers we’d also use the keyboard to copy/paste, or delete text characters, not by selecting and removing via a context menu).

      Also, you don’t have to refresh the page to bring the last one back (when going deeper), simply undo the last removal via the menu (or cmd Z).

      I must say that having neither of these in the video made it quite painful to watch. I hope you can appreciate these two tips!

  4. with a bookmarklet it’s awesome :) Thanks :)

  5. MaxArt

    One element may trigger the horizontal scrollbar even when its width is smaller than document.documentElement.offsetWidth. That’s when getBoundClientRect comes in handy, because it gives the position of an element in relation to the current viewport:

    var all = document.getElementsByTagName("*"), i = 0, rect;
    for (; i < all.length; i++) {
        rect = all[i].getBoundingClientRect();
        if (rect.right < 0) all[i].style.outline = "1px solid red";
    }

    Remember, using outline is better than border because an outline doesn't take space in DOM positioning.

    • I like your idea of using ‘getBoundingClientRect’! But I don’t understand the if statment.

      Don’t you need something like:

      if (rect.right > DOCUMENT_WIDTH || rect.left < 0)
      

      btw, tuts+ is a great place to test this code :)

      (P.S. You are right, the TreeWalker is unnecessary.)

  6. Yaswanth
    Permalink to comment#

    Guys I think, if the problem is not from overflow (but it wont be a problem in GECKO!)…

    We can use the gecko instead. I mean, if your graphics driver supports “WEBGL”, you can use ‘3d’ view of the default inspect tool of Firefox on pc..!?

    When we use, 3d view we can see the stack perfectly & also we can observe what exceeds the particular box in dimensions.

  7. Chris Dill
    Permalink to comment#

    I ran across this exact problem the other day on a WordPress site I was developing. fixing it was actually a huge pain in the butt because of how other items were positioned. Next time, come out with these tips a few days earlier!

  8. Our approach has been to always have a div sitting just inside the body tag with an inline style applied of overflow:hidden on.

    I find I can then have all sorts of things intentionally hanging off the edge left and right with no need to debug individually, which are mainly off canvas menus, stylistically placed images that need to show their hidden area at some other viewport size and miscellaneous elements that are animated on/off screen.

    I know this is a slightly different angle to the post which is trying to diagnose and remedy unintentional breaks, but thought that it might help someone.

    +1 to the js snippet and the bookmarklet :)

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".