Solution 1 :

CSS-Grid can do that without wrapping the items into groups….

body {
  display: inline-grid;
  grid-template-columns: repeat(3, max-content);
  gap: 1em;
  border: 1px solid black;
  margin: 1em;
  padding: 1em;
}

.group-item {
  border: 1px solid red;
}
<div class="group-item">
  1 Cont
</div>
<div class="group-item">
  2 Cont
</div>
<div class="group-item">
  3 Content Content
</div>
<div class="group-item">
  4 Contentttt
</div>

<div class="group-item">
  5 Content Contentttt
</div>

<div class="group-item">
  6 Content
</div>

For smaller viewports just use a media query and change the display property of the overall wrapper (here I used the body) to display:block and your items will naturally become a column.

Codepen Demo

Problem :

I am trying to achieve the following layout. The goal is to have the content boxes align and have equal widths with each other vertically, based on their content. The first layout is a desktop page, and the second is how it should look on mobile. I have numbered the boxes to show the desired order.

I’ve included a JSFiddle with how I’ve managed to get the desktop view to work, but the problem is that the order is incorrect for the mobile view, due to the HTML structure.

The only ways I can see getting this to work would be to simplify the HTML into 6 direct child li elements, and then assign them widths with CSS, or use JS to programmatically assign the widths. Or, I can create two separate HTML modules, one for desktop and one for mobile, and use CSS to hide/display them.

Those solutions seem over complicated, though. Is there a more elegant solution, which requires less lines of code and time to develop?

enter image description here

https://jsfiddle.net/2sLdpk4e/2/

ul{
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  width: 600px;
  border: 2px solid black;
  padding: 20px;
}

li{
  display: block;
  margin-right: 20px;
}

li:last-child{
  margin-right: 0;
}

.group-item{
  background: green;
  padding: 20px;
  margin-bottom: 20px;
}

.group-item:last-child{
  margin-bottom: 0;
}
<ul>
  <li>
    <div class="group">
      <div class="group-item">
        1 Cont
      </div>
      <div class="group-item">
        4 Contentttt
      </div>
    </div>
  </li>
  <li>
    <div class="group">
      <div class="group-item">
        2 Cont
      </div>
      <div class="group-item">
        5 Content Contentttt
      </div>
    </div>
  </li>
  <li>
    <div class="group">
      <div class="group-item">
        3 Content Content
      </div>
      <div class="group-item">
        6 Cont
      </div>
    </div>
  </li>
</ul>

Comments

Comment posted by css-tricks.com/snippets/css/a-guide-to-flexbox

You’re probably looking to use something like flexbox to get this effect. See an overview

Comment posted by Jordan Carter

@JayBee I tried, please see my demo. I can’t use order, because they are grandchild elements, in respect with the flex container.

Comment posted by TylerH

What do you mean by “efficient”? It looks like you already have a working solution to do it in your question.

Comment posted by Jordan Carter

@TylerH Check Paulie_D’s answer for what I consider to be efficient. I’ll have to try it out later, but it looks like it may be the solution I’m looking for.

Comment posted by Jordan Carter

@halfer Brevity of code. I can see how my use of the word “efficient” could be misleading there. I meant efficient in the sense that it takes less time to develop and edit, so it’s an efficient use of time. I edited my original post to hopefully make it more clear to future readers : ).

Comment posted by JayBee

This is a good answer. Ungrouping the elements will solve the problems you’re having the “grandchild” components.

Comment posted by Jordan Carter

Thank you! This is exactly the kind of solution I was looking for. Have a wonderful day.

By