10

When I use overflow: hidden, top and bottom margins appear around these containers. I really don't understand why this should be. I'm looking for an explanation to help me understand CSS better.

Here is the code:

CSS CODE:

#container {
    border: 2px solid black;
    overflow: auto;
}
.field {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    display: inline-block;
    padding: 0 5px;
    border: 5px solid #FC0;
    line-height: 1.5em;
    overflow: hidden;
}
.w50 {
    width: 50%;
}
.w100 {
    width: 100%;
}

HTML CODE:

<div class="w50" id="container">
    <div class="field w50">
        <input type="text" size="100" value="input field that overflows @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@">
    </div>
    <div class="field w50">content</div>
    <div class="field w100">content</div>
</div>

If I don't use overflow: hidden, the container has no top and bottom margins, but I do have overflow issues.

http://jsfiddle.net/8ErHQ/2/

If I use overflow: hidden, the container (apparently) has top and bottom margins, but my overflow issues go away.

http://jsfiddle.net/8ErHQ/1/

Is there a way to use overflow: hidden and avoid this extra white space?

xec
  • 17,349
  • 3
  • 46
  • 54
pbarney
  • 2,529
  • 4
  • 35
  • 49

3 Answers3

13

The mysterious whitespace you're seeing is because you made the divs inline-block, and inline elements are adjusted to text baseline, leaving room for descenders (letters that "hang low") like "j" and "g".

You can avoid the issue by setting a vertical-align value to something other than baseline (which is the default), like middle:

.field {
    vertical-align: middle;
}

http://jsfiddle.net/8ErHQ/3/

...or just avoid using inline-block (float: left; instead, for instance)

For more information, you can check out https://developer.mozilla.org/en/docs/Images,_Tables,_and_Mysterious_Gaps

xec
  • 17,349
  • 3
  • 46
  • 54
  • Vertical-align: middle is only usable if inside a display: table-cell. http://phrogz.net/CSS/vertical-align/ – Cam Jan 24 '14 at 19:01
  • @Cam It also applies to **inline** elements ;) Read my answer again (and then the link if you still don't see what I mean) – xec Jan 24 '14 at 19:03
  • Perfect! This is exactly what I need. But I would have expected the border to be below the baseline... it was made more interesting by the fact that Firebug wouldn't select that area of the screen. – pbarney Jan 24 '14 at 20:10
  • But wait a minute, I still don't understand why this baseline problem appears only when I use `overflow: hidden`. Shouldn't it be there regardless? – pbarney Jan 24 '14 at 20:48
  • @pbarney Yes, I'm not 100% sure to be honest, but I believe it has to do with one of the "hidden properties" of `overflow: hidden`, namely that it is one of the css rules that will trigger the *block formatting context* https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context ...and as a result, the box will "contain" the overflow produced by the baseline alignment. Another good read which might explain what I'm talking about is: http://colinaarts.com/articles/the-magic-of-overflow-hidden/ – xec Jan 24 '14 at 21:36
  • 2
    @xec - Yes, that's pretty much it. At the very bottom of chapter 10 of the CSS 2,1 spec it says "The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.". Which means that overflow:hidden 'contains' the baseline in the way you say. – Alohci Jan 24 '14 at 21:49
  • @Alohci That explains it! Thank you very much, learned something new :) Basically I was wrong about the BFC having anything to do with it then. – xec Jan 25 '14 at 09:33
  • 1
    Found a great explanation for why this happens: http://stackoverflow.com/questions/9943503/why-does-css2-1-define-overflow-values-other-than-visible-to-establish-a-new-b/11854515#11854515 – pbarney Jan 27 '14 at 23:50
1

There is one other option you can do. Using the one without overflow: hidden; you can use this approach to fix your overflow issue.

Set your css to this.

   .field input {
       width: 100%;
    }

And change your input field to this.

         <input type="text" size="auto" value="input field that overflows @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"> //Size was changed to AUTO

Here is what you get. http://jsfiddle.net/cornelas/8ErHQ/5/

Cam
  • 1,884
  • 11
  • 24
  • You could also just *remove* the `size` attribute alltogether: http://jsfiddle.net/8ErHQ/6/ - the value of the size attribute on an `` element refers to **number of characters** as opposed to pixels. – xec Jan 24 '14 at 19:13
  • In perspective yes. My worry is that there are a hundred input fields. Which would make this approach not a good one. But different. – Cam Jan 24 '14 at 19:14
-1

Put a margin value in your .w50 and .w100 statement.There might be other fixes, but that's the fastest I could think of.

    .w50 { margin: 0 0 -7px 0; width: 50%; }
    .w100 { margin: 0 0 -4px 0; width: 100%; }
Stefan Gruenwald
  • 2,582
  • 24
  • 30
  • 4
    -1 This is a horrible idea - a different font size would mean another px value is needed for the negative margin. See my answer (posted half an hour ago) – xec Jan 24 '14 at 18:59