Trufa
Trufa

Reputation: 40717

Divs don't stack right below each other or div not accepting height

I have a row container and three 100% width columns in my layout.

They stack on one another as expected, but when I give a small height to the first of them, I have a behavior I can't explain.

The height doesn't seem to be respected by the next divs.

I would expect the yellow divs to cover the light-blue area that I don't understand why it's there.

enter image description here

* {
  outline: 1px solid red
}

.row {
  background-color: lightblue;
  height: 200px;
  box-sizing: border-box;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-flex: 0;
  -ms-flex: 0 1 auto;
  flex: 0 1 auto;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}

.col {
  flex-basis: 100%;
  max-width: 100%;
}

.line {
  background-color: blue;
  height: 10px;
}

.second {
  background-color: #EEE8AA;
}
<div class="row">
  <div class="col line">
    
  </div>
  <div class="col second">
    hello
  </div>
  <div class="col second">
    goodbye
  </div>
</div>

Here is a live demo (fiddle).

Upvotes: 1

Views: 948

Answers (3)

M. Kumar
M. Kumar

Reputation: 19

Remove ".line{Height:10px}" your prob will solve.

Upvotes: -1

Michael Benjamin
Michael Benjamin

Reputation: 371231

An initial setting of a flex container is align-content: stretch. This means that, in a row-direction container, the height of the container will be distributed evenly among the lines.

In your case, you have three flex lines. Each line gets an equal share of the vertical space.

If you switch to align-content: flex-start, you'll pack the lines at the top.

.row {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start; /* NEW */
  background-color: lightblue;
  height: 200px;
  box-sizing: border-box;
}

.col {
  flex-basis: 100%;
  max-width: 100%;
}

.line {
  background-color: blue;
  height: 10px;

}

.second {
  background-color: #EEE8AA;
}

* {
  outline: 1px solid red
}
<div class="row">
  <div class="col line"></div>
  <div class="col second">hello</div>
  <div class="col second">goodbye</div>
</div>

The quick and easy solution would be to use flex-direction: column:

.row {
  display: flex;
  flex-direction: column;
  background-color: lightblue;
  height: 200px;
  box-sizing: border-box;
}

.col {
  flex: 1; /* lines will consume whatever vertical space is available */
  width: 100%;
  max-width: 100%;
}

.line {
  flex: 0 0 10px;
  background-color: blue;
}

.second {
  background-color: #EEE8AA;
}

* {
  outline: 1px solid red
}
<div class="row">
  <div class="col line"></div>
  <div class="col second">hello</div>
  <div class="col second">goodbye</div>
</div>

Learn more about flex alignment along the main axis here:

Learn more about flex alignment along the cross axis here:

Upvotes: 3

Michael Coker
Michael Coker

Reputation: 53674

I think what's happening is, since it's a flex row, the height of each flex item is going to be the same - or the space each item will occupy vertically will be the same, even if you've specified a different height for one of the items. So since you've set each of these to flex-basis: 100%, they will occupy the entire height of the parent evenly. The first element is the dark blue area + the light blue area (1/3rd), and the other two are 1/3rd each, too. So the light blue + dark blue is flex-basis: 100% (1/3rd).

It's easier to conceptualize if you replace flex-basis with flex-grow: 1, then you can see the same behavior horizontally https://jsfiddle.net/mLzm2y7y/3/

Upvotes: 2

Related Questions