1

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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
edezzie
  • 1,657
  • 4
  • 14
  • 12

3 Answers3

1

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.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

The problem is that you are calculating the images sizes (child divs) in base to an absolute width view port (vw), and you are including borders. The sections fit well when the web browser have a size that match exactly with the calculation of the border.

My recomendation is to use to calculate the size using the old % method,

Try to replace:

width: calc(50vw - (5*5px + 9px));

by:

width: calc(50% - 10px);

See the example in jsFiddle

Juan Lago
  • 960
  • 1
  • 10
  • 20
0

The problem is with the scrollbars (which are included in the vw/vw).

If you make the body hide its overflow it will work with your initial calculations (see https://jsfiddle.net/yLgcLd7j/6/).

But to make life simpler you can avoid these by setting box-sizing:border-box and using the vh/vw units on the containers and the rest make them percentage based.

#wrapper, #wrapper *{box-sizing:border-box;}
#wrapper {
    background:pink; 
    border:5px red solid;
  width:100vw;
  height:100vh;
    }

#container, #content, #parent{width:100%;height:100%;}
#image1, #image2, #image3, #image4 {
    border:5px orange solid;
    float:left;
    width:50%;
    height:50%;
    /* set and center a background image to the div */
    background-image: url("http://dev.bowdenweb.com/tools/i/pixelgrid.png");
    background-position: center;
  }  

Demo at https://jsfiddle.net/yLgcLd7j/8/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317