4

In my css grid I have one large item in the left column and three smaller items in the right column:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-template-rows: repeat(3, 50px);
  grid-auto-flow: column;
}

.item-1 {
  background-color: black;
  grid-column: span 1;
  grid-row: span 3;
}

.item-2,
.item-3,
.item-4 {
  grid-column: span 1;
  grid-row: span 1;
}

.item-2 {
  background-color: deeppink;
}

.item-3 {
  background-color: yellow;
}

.item-4 {
  background-color: blue;
}
<div class="container">
  <div class="item-1"></div>
  <div class="item-2"></div>
  <div class="item-3"></div>
  <div class="item-4"></div>
</div>

Now on smaller screens the three items on the right just disappear and only the black one is visible. This is because I have declared exactly 3 rows in grid-template-rows: repeat(3, 200px);, correct?

What I want however is that all 4 items wrap under each other (e.g. the grid should have 1 column and 6 rows):

Desired result

I know that this could be reached using media queries, but I wanted to avoid those in this scenario if possible.

I have tried grid-template-rows: repeat(auto-fit, 200px) but this didn't provide the desired result.

Thanks for you help!

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Giraphi
  • 1,383
  • 1
  • 11
  • 26
  • *"Now on smaller screens the three items on the right just disappear and only the black one is visible. This is because I have declared exactly 3 rows in `grid-template-rows: repeat(3, 200px)`, correct?"* No. That's not correct. – Michael Benjamin Jan 21 '20 at 16:07
  • The right column disappears because it has no content inside and no defined width. Therefore, once the browser window shrinks below 600px (based on `grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))`, and a two-column grid), the second column just collapses to 0 width. – Michael Benjamin Jan 21 '20 at 16:20
  • If even one grid item in the second column had some kind of width, you would see it. http://jsfiddle.net/9og5d6zt/2 – Michael Benjamin Jan 21 '20 at 16:22
  • In terms of shifting to a vertical layout on smaller screens, if a media query is not an option, how is the browser supposed to know to make the transition? – Michael Benjamin Jan 21 '20 at 16:22
  • My hope was that I could make the grid switch to a vertical layout once the two columns (minimal width 300px) don't fit next to each other anymore. – Giraphi Jan 21 '20 at 16:58
  • Understood. I don't think you can accomplish that with Grid. However, `flex-wrap` in flexbox *may* be useful to you: https://jsfiddle.net/4breog3k/ – Michael Benjamin Jan 21 '20 at 18:23
  • Keep in mind that the layout you want is not possible in Grid because you have specified the position of items using line-based placement (e.g., `grid-row: span 3`). If you leave the items to flow naturally, they would wrap as you expect. https://jsfiddle.net/am3Lr5fh/ – Michael Benjamin Jan 21 '20 at 18:52
  • Yes, a possible approach would be to treat the two columns as two items of a flexbox with `flex-wrap`. However, I am trying to accomplish that behavior with a grid and not introduce wrappers for the items. – Giraphi Jan 21 '20 at 23:14
  • hm, I am using `grid-row: span 3` to give the black item three times the height of the other ones. In your fiddle (jsfiddle.net/am3Lr5fh) this is unfortunately not the case anymore and all four items have the same height :( – Giraphi Jan 21 '20 at 23:17
  • I'm aware of that. The purpose of that fiddle was to illustrate the only way `auto-fit` and `auto-fill` could work. Using `grid-row: span 3` disables the functions. – Michael Benjamin Jan 22 '20 at 00:00

1 Answers1

-1

you could try

.container {
    display: grid;
    grid-template-areas: 'a a';
    grid-template-columns: 50% 50%;
    grid-template-rows: repeat(3, 50px);
    grid-auto-flow: column; 
}

3 Black Lines - 3 color lines

@media only screen and (max-width: 600px) {
   .container {
     grid-template-areas: 'a';
     grid-template-columns: 100%;
     grid-template-rows: repeat(6, 50px);
   }
}

1 Black line and 3 Color lines

@media only screen and (max-width: 600px) {
   .container {
     grid-template-areas: 'a';
     grid-template-columns: 100%;
     grid-template-rows: repeat(4, 50px);
   }

  .item-1 {
    grid-row: span 1;
  }
}

You can set the width for the media query as you want.

  • Seems like this does not make the columns wrap, it just keeps the three colored items right of the black one. Or did you also change the css for the items? – Giraphi Jan 21 '20 at 11:39
  • Thank you. I know that it is possible with media queries. However I was looking for a way to achieve this without media queries. – Giraphi Jan 21 '20 at 12:32
  • The reason I want to avoid media queries is that the breakpoints need to be calculated in dependence of the constants used to create the grid. I was hoping that css-grid provides a cleaner solution that does not require such dependencies. Articles like [this](https://css-tricks.com/look-ma-no-media-queries-responsive-layouts-using-css-grid/) demonstrate the responsive power of css grids without media queries, however I could not figure out how to apply such techniques to my scenario. – Giraphi Jan 21 '20 at 12:45
  • I understand. Grids and Flex boxes are powerful but the structure can not be that dynamic. The responsiveness of the given structure, can be. Without media queries it will be harder. The given structure..You want them to be 1-3 which means you want them to behave like a column at first and wrap after. To change the current structure like that you'll need media queries. If you change your HTML structure you will achieve it. Let's say if you wrap these 3 color divs in a parent div, then you'll have two main elements to position and play around. – Nicolas Vlachos Jan 21 '20 at 12:57