Home > OS >  Drop middle item to new row when its content wraps in CSS Grid
Drop middle item to new row when its content wraps in CSS Grid

Time:08-16

I've got 3 items as a calendar header that (when there is enough space) should be in 1 row:

 ┌─────────────────────────────────────────┐
 │ Month  |  Title, possibly long  |  Nav  │
 └─────────────────────────────────────────┘
<header >
  <div >August 2022</div>
  <div >A Dynamic Title</div>
  <div >Prev/Next</div>
</header>

The text in the middle item is a dynamic title and can be variable length.

On smaller screens and/or if the title is long enough to text wrap, I'd like that div to wrap to a new row:

 ┌─────────────────┐
 │ Month   |   Nav │
 │ ─────────────── │
 │ Title, possibly │
 | long            │
 └─────────────────┘

I haven't figured out how to do it, but it sure seems like some combination of auto-fill or grid auto placement would make it possible. I'm also open to flex or changing the HTML if needed.

Any help is appreciated!

CodePudding user response:

Here's one way to do it with media query, I'm sure there's better grid shorthand but this works. You might also consider flexbox for this as that might be a simpler way to style this component.

Expand the snippet and use the inspector's responsive mode to see the media query effect - top line goes orangered and bottom line goes teal.

Another though you could detect the width of the center column and when that reaches a certain length you add the class to alter the grid styling, but media query is probably the best way.

.calHeader {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
border: 1px dotted #999;
}

.calHeader div {
padding: 1em;
}

@media screen and (max-width: 400px){

.calHeader {
grid-template-columns: 1fr 1fr;
}

.calHeader__nav,
.calHeader__month {
grid-row-start: 0;
grid-row-end: 1;
background: teal;
}

.calHeader___month {
grid-row-start: 1;
grid-row-end: 2;
grid-column: 1/2;
}

.calHeader___nav {
grid-row-start: 1;
grid-row-end: 2;
grid-column: 3/4;
}

.calHeader__title {
  background: orangered;
  grid-row-start: 1;
  grid-row-end: 2;
  grid-column: 1 / 4;
}
}
<header >
  <div >August 2022</div>
  <div >A Dynamic Title</div>
  <div >Prev/Next</div>
</header>

CodePudding user response:

Float can do this if you can update your HTML by moving the title and the end. Resize the container to see the result:

.calHeader > *{
  float:left;
  margin: 0 5px;
}

.calHeader__nav {
  float: right;
}

.calHeader {
  overflow: auto;
  border: 1px solid;
  padding: 10px;
  resize: horizontal;
  max-width: 500px;
}
<header >
  <div >August 2022</div>
  <div >Prev/Next</div>
  <div >A Dynamic Title with long content</div>
</header>

  • Related