0

I want to arrange differently sized boxes in a "newspaper-style", but with elements arranged left-to-right first, and then top-to-bottom. So the goal is to get something that looks like this:

left-to-right newspaper with flush alignment

I know that the column module was built for news-paper-style layouts, but it arranges the elements top-to-bottom first, and then left-to-right:

top-to-bottom newspaper style layout

Here's the most important CSS, a full example is in this Codepen:

.container {
  column-count: 3;
  max-width: 960px;
  width: 100%;
}
.box {
  width: 300px;
  break-inside: avoid;
  height: fit-content;
}

Using a flexbox with wrapping will arrange the elements left-to-right first, but it will create gaps below the shorter elements (Codepen):

left-to-right arrangement with gap

.container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  max-width: 960px;
  width: 100%;
}

Is there a way to achieve the desired layout using plain CSS?

Chris_77
  • 173
  • 1
  • 5
  • 2
    One day you'll be able to use `grid-template-rows: masonry;` but it's not for today as you can see on [caniuse.com](https://caniuse.com/mdn-css_properties_grid-template-rows_masonry). – Amaury Hanser Sep 26 '22 at 15:53

1 Answers1

1

The idea is quite simple. flex-flow: column with wrap can do precisely what column-count does. You'll need two conditions to make it work: 1. The flexbox container needs to have a fixed height and it needs to be taller than your tallest column. 2. Flex children need width, 50% for 2-column layout, 33% for 3-column layout, etc.

This approach has the same problem as column-count: the elements are ordered by column, top-down. But since we're using flexbox, now we get access to the order property.

Using :nth-child() and order we can override the default order.

Items with order: 1 will go in the first column, order: 2 will go in the second column, and order: 3 in the third column.

In (an + b) formula a represents a cycle size, n is a counter (starts at 0), and b is an offset value. So (3n+1) selects every third item starting with the first one. (3n+2) selects every third item but starting with the second item. And (3n) selects every third item starting with the third item, since there's nothing at index 0.

In certain layouts, columns might merge. To solve this issue,insert pseudo-elements between columns: Read more about the method

This is Another Post about Horizontal Line Masonry

I have also changed margin-bottom: 0px; on .box & used gap:5px on the flex-container/your .container

.container {
  display: flex;
  flex-flow: column wrap;
  gap:5px;
  height: 600px;
  max-width: 960px;
  width: 100%;
}

.box {
  width: 300px;
  break-inside: avoid;
  height: fit-content;
  padding: 7px;
  border-radius: 15px;
  margin-bottom: 0px;
  cursor: pointer;
  border: 1px solid grey;
  text-align: justify;
}

.box:nth-child(3n+1) {
  order: 1;
}

.box:nth-child(3n+2) {
  order: 2;
}

.box:nth-child(3n) {
  order: 3;
}

.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

.header {
  font-size: 1.5rem;
  font-weight: bold;
}

body {
  font-family: monospace;
}
<div class="container">
  <div class="box">
    <div class="header">1 Heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum sint praesentium accusantium quidem magnam laborum atque harum, distinctio facilis amet. Quidem nulla beatae fugiat modi repellat laborum, animi natus quaerat?
      </a>
    </div>
  </div>
  <div class="box">
    <div class="header">2 Another heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Odit quos optio doloribus eaque ex. Nesciunt harum vel maxime eaque vero, ipsum nihil at ipsam numquam blanditiis esse voluptate, iste aspernatur! Earum asperiores praesentium ipsam illo eius
      sed ut autem velit consequatur adipisci voluptate, expedita voluptatem mollitia saepe, rem amet maiores dolorem et quos. Nulla temporibus necessitatibus inventore assumenda consequatur optio!</div>
  </div>
  <div class="box">
    <div class="header">3 Another heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Sequi dolores doloribus, soluta dicta cumque rem iusto quibusdam! Quae earum, consequuntur impedit adipisci culpa vero amet minima, modi laboriosam asperiores illum! Doloremque pariatur repudiandae
      aspernatur quidem ad voluptates vero! Commodi perspiciatis enim porro possimus quidem! Veritatis cumque repellat neque laborum commodi assumenda, vitae in saepe quae quibusdam officia corrupti, adipisci tempora.</div>
  </div>
  <div class="box">
    <div class="header">4 Heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum sint praesentium accusantium quidem magnam laborum atque harum, distinctio facilis amet. Quidem nulla beatae fugiat modi repellat laborum, animi natus quaerat?</div>
  </div>
  <div class="box">
    <div class="header">5 Heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Reprehenderit, voluptate. Fugiat labore tenetur quidem cum! Consectetur mollitia quas, veritatis nulla maiores, neque ullam fugiat ea explicabo tenetur perspiciatis enim sit. Ipsum tempora sunt
      delectus repellendus sed, quisquam error quos rem, ipsa aspernatur unde inventore culpa saepe est iusto. Eaque doloremque illum incidunt, quo vel magni libero rem sunt natus alias. Fuga vitae consectetur cumque repellat id fugit et molestiae unde
      facilis eos. Dolore accusantium id fugiat debitis quod iusto odit, quam, illum corporis minima eius. Eum quam numquam exercitationem sed.
    </div>
  </div>
  <div class="box">
    <div class="header">6 Heading</div>
    <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum sint praesentium accusantium quidem magnam laborum atque harum, distinctio facilis amet. Quidem nulla beatae fugiat modi repellat laborum, animi natus quaerat?</div>
  </div>
</div>
UmairFarooq
  • 1,269
  • 1
  • 3
  • 8
  • Thanks! That does fulfill the specification I asked for, but I realized I should also have asked for a non-fixed height, since I want to be able to just add elements. The linked question seems to answer quite comprehensively that that's not possible as long as the masonry layout isn't supported by modern browsers. – Chris_77 Sep 26 '22 at 18:01
  • https://css-tricks.com/piecing-together-approaches-for-a-css-masonry-layout/#aa-is-horizontal-line-masonry-ok read this aswell – UmairFarooq Sep 26 '22 at 18:07
  • look for ` horizontal line masonry` – UmairFarooq Sep 26 '22 at 18:09
  • Ineresting write-up, thanks! – Chris_77 Sep 26 '22 at 19:20