3

What CSS properties should I set so that the columns will wrap underneath one another, ignoring the height of horizontally-adjacent columns?

Desired layout for wrapping to fit 2 columns across.

Unsuccessful attempt

I'm attempting to do this with display: grid, but it doesn't behave how I want. An example:

header {
    height: 2.0rem;
    background: PeachPuff;
}
footer {
    height: 2.0rem;
    background: PaleGreen;
}

header,
footer,
section.app-column {
    padding: 1.0rem;
}

section#main section#app-column-primary {
    grid-area: primary;
    height: 5.0rem;
    background: Cyan;
}
section#main section#app-column-secondary {
    grid-area: secondary;
    height: 15.0rem;
    background: Thistle;
}
section#main section#app-column-tertiary {
    grid-area: tertiary;
    height: 10.0rem;
    background: Coral;
}

section#main {
    display: grid;
    grid-template-columns: repeat(3, 10.0rem);
    grid-row-gap: 0.2rem;
    grid-column-gap: 0.5rem;
}

section#main {
    content: "This application requires a display at least 200 pixels wide.";
}

@media(min-width: 200px) {
    section#main {
        grid-template-areas:
            "primary"
            "secondary"
            "tertiary";
    }
}

@media(min-width: 350px) {
    section#main {
        grid-template-areas:
            "primary secondary"
            "tertiary .";
    }
}

@media(min-width: 520px) {
    section#main {
        grid-template-areas:
            "primary secondary tertiary";
    }
}
<header>Header ipsum, dolor sit amet.</header>
<section id="main">
    <section class="app-column" id="app-column-primary">
        Primary app column
    </section>
    <section class="app-column" id="app-column-secondary">
        Secondary app column
    </section>
    <section class="app-column" id="app-column-tertiary">
        Tertiary app column
    </section>
</section>
<footer>Footer ipsum, dolor sit amet.</footer>

Correct result for 3 columns and 1 column

That does what I need for the three-column ("primary secondary tertiary") and one-column ("primary" "secondary" "tertiary") layouts.

Correct layout for 3 columns across. Correct layout for 1 column across.

Unwanted layout for 2 columns

But the two-column layout has the tertiary column starting below the secondary column:

Incorrect layout for 2 columns across.

Desired layout for 2 columns

What I want is for the tertiary column placement to ignore the secondary column because they won't overlap at all:

Desired layout for wrapping to fit 2 columns across.

How can I do this with CSS? Is display: grid appropriate for this? Should I be using display: flex or something different (if so, exactly what CSS properties do I need)?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
bignose
  • 30,281
  • 14
  • 77
  • 110

2 Answers2

2

Instead of this:

@media(min-width: 350px) {
    section#main {
        grid-template-areas:
            "primary secondary"
            "tertiary .";
    }
}

... which creates a 2x2 grid, like this:

[ primary ] [ secondary ]

[tertiary ] [ empty space ]

... and is exactly what you're showing as the problem:

enter image description here

Do this:

@media(min-width: 350px) {
    section#main {
        grid-template-areas:
            "primary secondary"
            "tertiary secondary";
    }
}

jsFiddle demo

header {
  height: 2.0rem;
  background: PeachPuff;
}

footer {
  height: 2.0rem;
  background: PaleGreen;
}

header,
footer,
section.app-column {
  padding: 1.0rem;
}

section#main section#app-column-primary {
  grid-area: primary;
  height: 5.0rem;
  background: Cyan;
}

section#main section#app-column-secondary {
  grid-area: secondary;
  height: 15.0rem;
  background: Thistle;
}

section#main section#app-column-tertiary {
  grid-area: tertiary;
  height: 10.0rem;
  background: Coral;
}

section#main {
  display: grid;
  grid-template-columns: repeat(3, 10.0rem);
  grid-row-gap: 0.2rem;
  grid-column-gap: 0.5rem;
}

section#main {
  content: "This application requires a display at least 200 pixels wide.";
}

@media(min-width: 200px) {
  section#main {
    grid-template-areas: "primary" "secondary" "tertiary";
  }
}

@media(min-width: 350px) {
  section#main {
    grid-template-areas: "primary secondary" "tertiary secondary";
  }
}

@media(min-width: 520px) {
  section#main {
    grid-template-areas: "primary secondary tertiary";
  }
}
<header>Header ipsum, dolor sit amet.</header>
<section id="main">
  <section class="app-column" id="app-column-primary">
    Primary app column
  </section>
  <section class="app-column" id="app-column-secondary">
    Secondary app column
  </section>
  <section class="app-column" id="app-column-tertiary">
    Tertiary app column
  </section>
</section>
<footer>Footer ipsum, dolor sit amet.</footer>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

I try to give you a solution using the property grid-row-end and auto-fill.

Firstable: this solution works well with your dimentions (it is not very scalable, but unfortunatly, without using javascript, there isn't a perfect and pure CSS solution I think).

BTW, this is how it works:

  • I create a grid with grid-template-columns: repeat(auto-fill, 10rem); property
  • For every grid items I put a grid-row-end: span [dimension];=> for 5rem I put [1], for 15rem I put [3] and for 10 rem I put [2] (this is when I said "it is not scalable" 'cause if you change the dimentions you have to change here too)

For all these property you can find very usefull information here: https://css-tricks.com/snippets/css/complete-guide-grid/ and here: https://rachelandrew.co.uk/archives/2017/01/18/css-grid-one-layout-method-not-the-only-layout-method/ (I mentioned my CSS guru, I'm a bit excited (^_^;))

This is the code in action:

header {
    height: 2.0rem;
    background: PeachPuff;
}
footer {
    height: 2.0rem;
    background: PaleGreen;
}

header,
footer,
section.app-column {
    padding: 1rem;
}

section#main section#app-column-primary {
    height: 5rem;
    grid-row-end: span 1;
    background: Cyan;
}
section#main section#app-column-secondary {
    grid-row-end: span 3;
    height: 15rem;
    background: Thistle;
}
section#main section#app-column-tertiary {
    grid-row-end: span 2;
    height: 10rem;
    background: Coral;
}

section#main {
    display: grid;
    grid-template-columns: repeat(auto-fill, 10rem);
    grid-row-gap: 0.5rem;
    grid-column-gap: 0.5rem;
}
<header>Header ipsum, dolor sit amet.</header>
<section id="main">
    <section class="app-column" id="app-column-primary">
        Primary app column
    </section>
    <section class="app-column" id="app-column-secondary">
        Secondary app column
    </section>
    <section class="app-column" id="app-column-tertiary">
        Tertiary app column
    </section>
</section>
<footer>Footer ipsum, dolor sit amet.</footer>

Hope it helps. Cheers.

PS: See also the property grid-auto-flow: dense;, in a real world, with some limitations, it can help you to fit the various elements together (I removed it to my example 'cause here we have only 3 elements => the Rachel Andrew articole is very useful for you, I think)

ReSedano
  • 4,970
  • 2
  • 18
  • 31