2

I want to lay out some divs in the arrangement I've diagrammed below. It's two squarish blocks side by side and then 2 half height blocks arranged vertically where a 3rd big block might have fit.

+---------+ +---------+ +---------+ 
| BOX1    | | BOX2    | | BOX3    |
|         | |         | +---------+
|         | |         | +---------+
|         | |         | | BOX4    |
+---------+ +---------+ +---------+

So far, the only way I've gotten close is to create 3 left floated boxes and put the two smaller boxes in the 3rd floated box. That doesn't feel right to me. Like, I'm adding extra divs just to control layout. Maybe that's OK but it doesn't feel right.

See it here:

https://jsfiddle.net/a84kv4wo/1/

.big_box {
  height: 8em;
  width: 8em;
  border: 1px solid black;
  float: left;
}
.small_box {
  height: 4em;
  width: 8em;
  border: 1px solid black;
}
<div class="big_box">BOX1</div>
<div class="big_box">BOX2</div>
<div class="big_box">
  <div class="small_box">BOX3</div>
  <div class="small_box">BOX4</div>
</div>

For one thing, I might want to start applying more styles to the big box to control how the text is laid out and I don't want those styles to affect boxes 3 & 4.

It seems like the two big blocks should be left floated and then the two smaller boxes should just wrap around them, stacking vertically as divs tend to do. But that doesn't happen. I don't know what the answer is but it seems you should be able to just layout 4 divs and then arrange them how you want in CSS. Like in this fiddle:

https://jsfiddle.net/agfbrz5x/

.big_box {
  height: 8em;
  width: 8em;
  border: 1px solid black;
  float: left;
}
.small_box {
  height: 4em;
  width: 8em;
  border: 1px solid black;
  float: left;
}
<div class="big_box">BOX1</div>
<div class="big_box">BOX2</div>
<div class="small_box">BOX3</div>
<div class="small_box">BOX4</div>

That has the html I think I want but I can't get the css right.

Any ideas?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
dl__
  • 4,500
  • 5
  • 28
  • 34
  • 1
    What's wrong with adding divs for layout...that's exactly what they are for? – Paulie_D Dec 17 '15 at 18:47
  • I'm not a css expert but, I seem to remember something about divs are used to group semantically related things together and are not supposed to be added simply to achieve a specific layout effect. – dl__ Dec 17 '15 at 19:24

2 Answers2

5

There's really nothing wrong with wrapping elements in a div in order to achieve a certain layout.

In fact, a div is a generic container which is meant to group elements for styling purposes, among other things (see MDN definition).

Here's one way to solve the problem using CSS flexbox.

#flex-container {
  display: flex;
}
#flex-container-nested {
  display: flex;
  flex-direction: column;
}
.big_box {
  height: 8em;
  width: 8em;
  border: 1px solid black;
}
.small_box {
  height: 4em;
  width: 8em;
  border: 1px solid black;
}
* { box-sizing: border-box; }
<div id="flex-container">
  <div class="big_box">BOX1</div>
  <div class="big_box">BOX2</div>
  <div id="flex-container-nested">
    <div class="small_box">BOX3</div>
    <div class="small_box">BOX4</div>
  </div>
</div>

jsFiddle


Benefits of flexbox:

  1. minimal code; very efficient
  2. centering, both vertically and horizontally, is simple and easy
  3. equal height columns are simple and easy
  4. multiple options for aligning flex elements
  5. it's responsive
  6. unlike floats and tables, which offer limited layout capacity because they were never intended for building layouts, flexbox is a modern (CSS3) technique with a broad range of options.

Browser support:

Flexbox is supported by all major browsers, except IE < 10.

Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes.

For a quick way to add prefixes use Autoprefixer.

More details in this answer.

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

You can get this with flex box, and without an additional wrapper. But you need to set some height to the container, bigger than the big boxes and smaller than the sum of two big boxes.

.container {
  display: flex;
  flex-flow: column;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 10em;
}

.big_box{
  height: 8em;
  width: 8em;
  border: 1px solid black;
}
.small_box{
  height: 4em;
  width: 8em;
  border: 1px solid black;
}
<div class="container">
<div class="big_box">BOX1</div>
<div class="big_box">BOX2</div>
<div class="small_box">BOX3</div>
<div class="small_box">BOX4</div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138