edezzie edezzie - 7 months ago 13
HTML Question

Floated divs not fitting side by side, and leaving unexplained gap

I'm testing something where I show 4 over-sized images centered in quadrants that fill a screen. So 2 rows and 2 columns.

□□

□□

The images are in the backgrounds of 4 divs which should stack. All divs have small borders.

My issue is that the height works but for the width I need to deduct 9px from the width of each box to make them stack and they no longer fill the screen. Without 9px they look like:









What is this 9px gap?

Best to see it in a jsfiddle



#wrapper {
background: pink;
border: 5px red solid;
}
#container {
background: fuchsia;
border: 5px purple solid;
}
#content {
background: aqua;
border: 5px blue solid;
}
#parent {
background: lime;
border: 5px green solid;
}
#image1,
#image2,
#image3,
#image4 {
background: yellow;
border: 5px orange solid;

/* Each div fill 1/4 screen so get 50% user screen viewport height/width and deduct the height/width of everything outside of the image divs content area (box model).
So here we must deduct the 1 x 5px border on one side (image border) and 4 x 5px borders on the other side (image, parent, content & wrapper borders)*/
height: calc(50vh - (5*5px));

/* The line below should be the same as above ie:
width: calc(50vw - (5*5px)) but I need to deduct a further unexplained 9px and now
the 4 image divs wont fill the screen? */
width: calc(50vw - (5*5px + 9px));

float: left;

/* set and center a background image to the div */
background-image: url("http://dev.bowdenweb.com/tools/i/pixelgrid.png");
background-position: center;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}

<div id="wrapper">
<div id="content">
<div id="parent" class="clearfix">
<div id="image1">
</div>
<div id="image2">
</div>
<div id="image3">
</div>
<div id="image4">
</div>
</div>
</div>
</div>




Answer

Floats aren't designed for layouts. Yes, they've been used this way for decades... as a hack (CSS offered no better alternative). Floats were designed to wrap text around images, not build grids.

Viewport percentage lengths are relative to the initial containing block, not the parent element, like percentage lengths.

You combine floats, borders, viewport percentage widths and box-sizing:content-box, and you get your 9px mystery gap. (I didn't delve any further as my focus was a modern solution to your problem.)


Today there is CSS3, which offers two methods for building layouts: Flex Layout and Grid Layout

Browser support for grid layout is still weak.

Browser support for flex layout is almost complete.


Here's your layout using flex, box-sizing:border-box, and percentage heights:

html {
  height: 100%;
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;                      /* https://css-tricks.com/box-sizing/ */
}

body { 
  height: 100%;
  margin: 0;                                /* remove default margin */
}

#wrapper {
  background: pink;
  border: 5px red solid;
  height: 100%;
}

#container {
  background: fuchsia;
  border: 5px purple solid;
  height: 100%;
}

#content {
  background: aqua;
  border: 5px blue solid;
  height: 100%;
}

#parent {
  background: lime;
  border: 5px green solid;
  display: flex;                               /* establish flex container */
  flex-wrap: wrap;                             /* allow children to wrap */
  height: 100%;
}

#image1, #image2, #image3, #image4 {
  background: yellow;
  border: 5px orange solid;
  height: 50%;
  flex-basis: 50%;                              /* each item 50% wide */
  background-image: url("http://dev.bowdenweb.com/tools/i/pixelgrid.png");
  background-position: center;
}
<div id="wrapper">
  <div id="content">
    <div id="parent" class="clearfix">
      <div id="image1"></div>
      <div id="image2"></div>
      <div id="image3"></div>
      <div id="image4"></div>
    </div>
  </div>
</div>

jsFiddle


Benefits:

  • No more mystery gap.
  • No more floats.
  • No more clearfix.
  • No need to add up borders and use calc.
  • Cleaner, more efficient code
  • Layout is responsive
  • Unlike floats and tables, which offer limited layout capacity because they were never intended for building layouts, flexbox is a modern technique with a broad range of options.

To learn more about flexbox visit:


Browser support:

Flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, use Autoprefixer. More details in this answer.

Comments