abu abu
abu abu

Reputation: 7028

Place div one below another using CSS flex

I am learning CSS flex. My HTML code is like below

.box {
  display: flex;
  align-items: flex-start;
  height: 200px;
}

.box>*:first-child {
  align-self: stretch;
}

.box .selected {
  align-self: center;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div class="selected">Three</div>
  <div>Four</div>
</div>

My output is like below

enter image description here

I would like to place Three just below Two and Four just below Three.

How can I do that ?

Upvotes: 0

Views: 2427

Answers (2)

cssyphus
cssyphus

Reputation: 40028

Flexbox works with parent and immediate child containers. Once you get beyond immediate children, you need to create a new flexbox (that is, nested flexboxes).

To make this solution very simple, just put divs 2,3,4 into a div. That way, the parent (.box) will have two immediate child divs to arrange side by side. Then, the new right-side container will have 3 child divs that it can style (using flex) to be stacked vertically. (A div can be both a child flex container and a parent flex container at the same time -- see div .rside, and each div with the class centerVertHoriz)

.box {
  display: flex;
  width:300px;
  min-height: 300px;
}
.rside{
  display:flex;
  flex-direction: column;
}

/*  For appearance only */
.lside{
  padding: 10px;
  min-height: 200px;
  background: wheat;
}
.rside div{
  padding: 10px;
  min-height: 90px;
  border: 1px solid #ccc;
}

/*  Center text within each div */
.centerVertHoriz{
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="box">
  <div class="lside centerVertHoriz">One</div>
  <div class="rside">
    <div class="centerVertHoriz">Two</div>
    <div class="selected centerVertHoriz">Three</div>
    <div class="centerVertHoriz">Four</div>
  </div>
</div>

References:

Brief, concise, video tutorial

Concise flexbox cheatsheet

Upvotes: 1

corn on the cob
corn on the cob

Reputation: 2282

Just set your align-self to flex-end for the last one. This is the best you can do with flexbox, because grid is better in this case. You might need to adjust the height of your .box

.box {
  display: flex;
  align-items: flex-start;
  height: 120px;
}

.box>* {
  padding: 10px;
  border: 2px solid red;
}

.box>*:first-child {
  align-self: stretch;
}

.box .selected {
  align-self: center;
}

.box>*:last-child {
  align-self: flex-end;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div class="selected">Three</div>
  <div>Four</div>
</div>

Following on from the comments, you should be using grid to make your exact result. Try using this:

.box {
  display: grid;
  grid-template-columns: 100px;
  grid-template-rows: 50px;
  height: 120px;
}

.box>* {
  padding: 10px;
  border: 2px solid red;
  grid-column: 2;
}

.box>*:first-child {
  grid-column: 1;
  grid-row: 1 / 4;
}

.box .selected {
  align-self: center;
}

.box>*:last-child {
  align-self: flex-end;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div class="selected">Three</div>
  <div>Four</div>
</div>

Upvotes: 1

Related Questions