Div with absolute width is smaller than specified

Viewed 555

I am trying to have a number of columns with exact widths, and their heights split evenly between some number of elements. For some reason, despite my indicating an exact 200px width on each column, they are instead getting a computed width of 162px somehow.

Chrome dev tools is showing some weird arrow thing indicating that it it was shrunk from it's intended size for some reason. I've even tried removing all of the content from the div's as possible so as to rule out some weird interaction with the size of children.

The HTML content for the relevant area is this:

div {
  background: rgba(255, 0, 0, .1);
}
<div style="display: flex;">
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 200px;"></div>
    <div style="height: 200px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 400px;"></div>
  </div>
</div>

Including some dev-tools highlighting (showing the arrow thing I described) it is rendering like this (the "round" labels at the top are not in the HTML content above but are properly 200px + 100px margin):

Bizarre sizing stuff

I have never seen anything like this before, especially those arrow things from the dev tools. Is there something obvious I'm missing or something I should look for to diagnose this?

2 Answers

Setting display: flex turns the sizing of child elements over to the flex container. If you don't want the individual elements to resize, set flex-grow: 0, flex-shrink: 0, and flex-basis: 200px. You can do all three using the flex shorthand:

flex: 0 0 200px;

.container {
  display: flex;
}

.container > * {
  flex: 0 0 200px;
  margin-right: 100px;
}

div {
  background: #cccccccc;
}
<div class="container">
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
    <div style="height: 50px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
    <div style="height: 100px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 200px;"></div>
    <div style="height: 200px;"></div>
  </div>
  <div style="width: 200px; margin-right: 100px;">
    <div style="height: 400px;"></div>
  </div>
</div>

This is the default behaviour for Flexbox. If you add up all your widths, so 200 width + the 100 margin, you get 300 * 4 = 1200px. If your viewport is smaller than 1200px then the browser will try to calculate the best width it can to fit all your div along the main axis. thus you are getting 162 + 100 * 4 is just shy of 1200. Try resize your viewport or the browser screen to bigger than this and you should get the expected behaviour.

The arrow you are seeing is Chrome dev tools way of telling you your original width has been made smaller to fit all content.

Related