Search code examples
htmlcsscss-grid

Dynamic css grid with custom styling for odds/even rows


I'm trying to get familiar to CSS grid system. However, right now I'm struggling trying to figure out how to build a dynamic grid that will have custom style for odds/even rows.

So basically I want to implement this pattern for a nx2 grid:

[     lg-item     ] [ sm-item ]
[ sm-item ] [     lg-item     ]
[     lg-item     ] [ sm-item ]
.
.
.

Where rows will always start either with a large item or a small item

The 100% success for me will also be when this grid can automatically resize whenever viewport has enough width size to hold another element in the same row. Example:

Small screen:
[     lg-item     ] [ sm-item ]
[ sm-item ]   [     lg-item     ]
[     lg-item     ] [ sm-item ]
.
.
.
Med screen:
[     lg-item     ] [ sm-item ]  [     lg-item     ]
[ sm-item ]  [     lg-item     ]  [ sm-item ]
[     lg-item     ] [ sm-item ]  [     lg-item     ]
.
.
.
Lg screen:
[     lg-item     ] [ sm-item ]  [     lg-item     ]   [ sm-item ]
[ sm-item ]  [     lg-item     ]  [ sm-item ]  [     lg-item     ]
[     lg-item     ] [ sm-item ]  [     lg-item     ]   [ sm-item ]
.
.
.

The thing is that it doesn't matter in which item it ends. Rows will always start with small or large item and it alternates between rows

I'm plain new with this so right now i only have this:

    <div class="search-by__inner-container">
        <div class="search-by__item">
            Flavour
        </div>
        <div class="search-by__item">
            Size
        </div>
        <div class="search-by__item">
            New
        </div>
        <div class="search-by__item">
            bundle
        </div>
    </div>

SCSS:

    .search-by__inner-container{
        display: grid;
        grid-template-columns: 70% 30%;
        grid-template-rows: 50% 50%;
        gap: .8rem;

    }
    .search-by__item{
        background: red;
        padding: 1.5rem;
    }

Which only gives me Something like this:

enter image description here

I don't know if there's a way to reverse my row (like Flex prop) or if I should think of another way to figure this out. On top of this, my desire is to dynamically add these items and they will automatically fit to this grid system.

Can someone give me some hints in order to figure this out?


Solution

  • Updated to stripe the rows in addition to alternating sizes.

    You could achieve the alternating rows and sizes with nth-child, and adapt to different screen sizes via media queries:

    .container {
      list-style: none;
      text-align: center;
      margin: 0;
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px;
    }
    
    .container > * {
      border: 1px dashed gray;
      padding: 8px;
      color: skyblue;
    }
    
    /* alternate large/small item order per row */
    .container > *:nth-child(4n + 1),
    .container > *:nth-child(4n + 4) {
      background: aliceblue;
      grid-column: auto / span 2;
    }
    
    /* alternate background color per row */
    .container > *:nth-child(4n + 1),
    .container > *:nth-child(4n + 2){
      background: cornflowerblue;
    }
    <ul class="container">
      <li>item</li>
      <li>item</li>
      <li>item</li>
      <li>item</li>  
      <li>item</li>
      <li>item</li>
      <li>item</li>
      <li>item</li>  
      <li>item</li>
      <li>item</li>
      <li>item</li>
      <li>item</li>  
      <li>item</li>
      <li>item</li>
      <li>item</li>
      <li>item</li>  
    </ul>

    grid-column: auto / span 2;
    

    The grid-column property is specifying that each item that matches the selector should start at its natural column position ("auto") and it should occupy 2 columns instead of one ("span 2").