RNA
RNA

Reputation: 153521

how to fill the right column first and then the left in a 2-column layout

I have 5 div elements (in a simplified manner here). How can I set css to make a 2-column layout with the first 2 divs on the right and the rest divs on the left like shown in the picture (each div element can be identified with different classes or ids if needed)? The number of divs on the right or left can be fixed and known ahead of time, rather than dynamically flew. The 2 columns may have different heights, but they need aligned on the top (i.e. div3 and div1 start from the same vertical position). Ideally, I don't want to set a fixed height on either each div elements or on the left or right column.

<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>

enter image description here

Upvotes: 3

Views: 2173

Answers (2)

Rahul
Rahul

Reputation: 2071

I did using grid CSS. Here is the Pen.

HTML

<div class="parents">
  <div class="child box-1">
    <img src="https://w3bits.com/files/img/cherry-plant.jpg" />
  </div>
  <div class="child box-2">
    <img src="https://w3bits.com/files/img/oranges-pomegranates.jpg" />
  </div>
  <div class="child box-3">
    <img src="https://w3bits.com/files/img/strawberry.jpg" />
  </div>
  <div class="child box-4">
    <img src="https://w3bits.com/files/img/blueberries.jpg" />
  </div>
  <div class="child box-5">
    <img src="https://w3bits.com/files/img/pears.jpg" />
  </div>
</div>

CSS

*,
*:after,
*:before{
  box-sizing: border-box;
}
body{
  margin: 0;
  padding: 0;
}
.parents{
  direction: rtl;
  column-count: 2;
  column-fill: initial;
  column-gap: 20px;
  margin-left: auto;
  margin-right: auto;
  max-width: 600px;
}
.parents .child{
  border: 2px solid red;
  border-radius: 10px;
  direction: ltr;
  display: inline-block;
  margin-bottom: 10px;
  height: 200px;
  overflow: hidden;
}
.parents .child img{
  flex-grow: 0;
  height: 100%;
  width: 100%;
  object-fit: cover;
}
.parents .child.box-1{
  height: 300px;
}
.parents .child.box-2{
  height: 300px;
}

If you want to masonry view. HTML and CSS in Pen.

Editing ANS after question change for auto height

column auto height will work if you change your html like this.

<div class="item-group">
    <div class="item-group-left">
        <div class="item-box">
            <p>Item 1</p>
            <img src="https://loremflickr.com/320/500/winter" />
        </div>
        <div class="item-box">
            <p>Item 2</p>
            <img src="https://loremflickr.com/320/500/home" />
        </div>
    </div>
    <div class="item-group-right">
        <div class="item-box">
            <p>Item 3</p>
            <img src="https://loremflickr.com/320/240/tree" />
        </div>
        <div class="item-box">
            <p>Item 4</p>
            <img src="https://loremflickr.com/320/240/fish" />
        </div>
        <div class="item-box">
            <p>Item 5</p>
            <img src="https://loremflickr.com/320/240/rock" />
        </div>
    </div>
</div>

Auto height HTML and CSS is here.

If you don't want to change html then you have to set a fixed based height(based height 100px). Then you will able to increase item height using grid. Also you will able to set First and Second item on right side. Pen.

CSS

*,
*:after,
*:before{
  box-sizing: border-box;
}
body{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  padding: 50px 15px;
}
.container{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 100px; /* Based height. Change if you want */
  gap: 20px;
  max-width: 600px;
}
.item{
  display: inline-block;
}
.item.item-1{
  grid-column-start: 2;
  grid-row-start: 1;
  grid-row-end: 4;
}
.item.item-2{
  grid-column-start: 2;
  grid-row-start: 4;
  grid-row-end: 7;
}
.item.item-3{
  grid-column-start: 1;
  grid-row-start: 1;
  grid-row-end: 3;
}
.item.item-4{
  grid-column-start: 1;
  grid-row-start: 3;
  grid-row-end: 5;
}
.item.item-5{
  grid-column-start: 1;
  grid-row-start: 5;
  grid-row-end: 7;
}
img{
  border: 5px solid red;
  border-radius: 5px;
  flex-grow: 0;
  height: 100%;
  width: 100%;
  object-fit: cover;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

Upvotes: 2

Danield
Danield

Reputation: 125561

1) Set display:flex on the container

2) Set flex container's main-axis as the block-axis with flex-direction: column; (see flex-direction)

3) Switch wrap direction with flex-wrap: wrap-reverse; (see flex-wrap)

Note: This will only work correctly if the container has a fixed height. (thanks @Paulie_D)

Demo:

.wpr {
  width: 30vw;
  height: 30vw;
  border: 1px solid;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap-reverse;
  justify-content: space-between;
}
.wpr div {
  width: 45%;
  height: 45%;
  border: 1px solid;
  margin: 1% 1% 1% 6%;
}
.wpr div:nth-child(n+3) {
  height: 30%;
}
<div class="wpr">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>


Since the OP added clarifications that:

1) The wrapper may not have a fixed height

2) The number of divs on the right can be fixed (say 2)

we can implement this with floats by floating (and clearing) the first 2 divs

.wpr {
  border: 1px solid;
  width: 50vw;
  padding: 1em;
  display: flow-root; /* create new block formatting context */
  /* Note: if ie/edge support is required use overflow: hidden
           instead of display: flow-root */
}
.wpr div {
  color: green;
  border: 1px solid;
  margin: 0.3em;
  padding: 1em;
  width: 35%;
}
.wpr div:nth-child(-n + 2) {
  color: red;
  float: right;
  clear: right;
}
<div class="wpr">
  <div>1 Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard </div>
  <div>2 Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type </div>
  <div>3 Lorem Ipsum is simply dummy when an unknown printer took a g </div>
  <div>4 Lorem Ipsum is simply dummy text of the printing </div>
  <div>5 Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem  </div>
</div>

Upvotes: 5

Related Questions