Home > Software design >  Why does setting a border give an element 1px extra internal height?
Why does setting a border give an element 1px extra internal height?

Time:04-19

When putting a border around a block element, why does the apparent visual height of the element inside the border increase by 1? The reported offsetHeight is still equal to the desired height plus the border widths.

This becomes problematic when trying to make an inner block element the same height as an outer element. Notice the extra 1px of height the outer element has in this example, causing the inner element's background color to not fill the entire container:

#outer { height: 10px; border: 1px solid red; }
#inner { height: 10px; width: 50%; background-color: black; }
/* Setting #inner height to 100% has the same problem. */
<div id="outer"><div id="inner"></div></div>

On my device, there's a one-pixel-high gap between the black background and the red border.

What causes this, and how can I remove the "extra" bit of height inside the outer element so that my inner element takes up the full visual height of its container?

Does this have something to do with subpixel rendering?

CodePudding user response:

It's because default box-sizing of element is content-box meaning width and height will be applied only to element content box.

Setting it to border-box will include border into width and height too

#without,
#with {
  width: 40%;
  float: left;
  display: inline-block;
  margin-left: 2px;
}

#without .inner {
    height: 30px;
    border-bottom: 5px solid green;
    background: yellow;
}

#with .inner {
    height: 30px;
    border-bottom: 5px solid green;
    background: yellow;
    box-sizing: border-box;
}
<div id="without">
  <div >Without</div>
</div>

<div id="with">
  <div >With</div>
</div>

CodePudding user response:

Browsers calculate sizes starting on the content then add padding and border (except IE but that's another story).

You can now changes box-sizing to tell the browser when you say width: 100px you mean "I want 100px border to border".

.outer { height: 50px; border: 10px solid red; }
.inner { height: 50px; width: 50%; background-color: black; }

.border * { box-sizing: border-box; }
.content * { box-sizing: content-box; }

.border, .content {
  margin: 1em 0;
}
<p>Content based</p>
<div >
  <div ><div ></div></div>
</div>
<p>Border based</p>
<div >
  <div ><div ></div></div>
</div>

With box-sizing: border-box and both div with the same height, the inner one must overflow the outer

  •  Tags:  
  • css
  • Related