htmlcsssassshopifyliquid

How to dynamically repeat grid layout for two columns then three columns and so on? Liquid/SCSS/CSS


I'm trying to do the following grid layout in liquid code for our Shopify store:

[![grid layout of two columns by three columns repeatedly][1]][1]

The blocks (each logo with text) are loaded through a theme customizer, meaning that we can remove or add blocks.

My issue here is that I'm trying to do a repeated patter of two columns, then three columns (then repeat beginning with two, then three, etc) and so on. So far I have this code, I'm in need to organize the html. Accepting solutions with Sass/css/javascript

<div class="container mattresses__certifications">
  {% assign blocks = section.blocks %}
  {% assign total_blocks = blocks | size %}
  {% assign total_containers = total_blocks | divided_by: 5 | times: 2 %}
  {% assign block_modulo = total_blocks | modulo: 5 %}

  {% if block_modulo > 0 %}
    {% assign total_containers = total_containers | plus: 1 %}
  {% endif %}

  {% for container_index in (1..total_containers) %}
    <div class="container">      
      {{ container_index }}
      {% assign block_index = container_index %}
      {% assign max_blocks_per_container = 2 %}

      {% assign cont_remainder = container_index | modulo: 2 %}
      {% if container_index > 1 and cont_remainder == 0 %}
        {% assign max_blocks_per_container = 3 %}
      {% endif %}


      {% assign block_offset = container_index | times: max_blocks_per_container %}
      {% assign block_index_max = block_offset | plus: max_blocks_per_container %}

      {% for a in (block_index..block_index_max) %}
        {{ blocks[block_index].settings.mattress_cert_text }}<br>
      {% endfor %}
  
    </div>
  {% endfor %}
</div>

I gathered this code with ChatGPT, which works... but the thing is that I can't use this snippet because my team pointed out (code review) that I can't use opening and closing divs in this following manner:

  {% for block in blocks %}
    {% assign row_size = index | modulo: 5 %}

    {% capture opening_div %}
      {% if row_size == 0 or row_size == 2 %}
        <div class="mattresses__cert-row">
      {% endif %}
    {% endcapture %}

    {% capture closing_div %}
      {% if row_size == 1 or row_size == 4 or index == total_blocks %}
        </div>
      {% endif %}
    {% endcapture %}

    {{ opening_div }}

    <div class="mattresses__cert-wrapper">
      {% assign cert_image = block.settings.mattress_cert_image %}
      {{ cert_image | image_url: width: cert_image.width, height: cert_image.height | image_tag }}
      <span class="mattresses__cert-text">{{ block.settings.mattress_cert_text }}</span>
    </div>

    {% assign index = index | plus: 1 %}

    {{ closing_div }}
  {% endfor %}

And this is the SCSS that is linked to the working example above:

.mattresses__certifications {
  display: flex;
  flex-flow: column nowrap;
  gap: $spacing-lg;
  padding: $spacing-base;
  margin: $spacing-sm auto;

  @include media-breakpoint-up(md) {
    flex-flow: row wrap;
    justify-content: center;
  }

  @include media-breakpoint-up(lg) {
    border-radius: $border-radius-4xl;
    background: $color-primary-10;
  }

  .mattresses__cert-row {
    display: flex;
    justify-content: space-evenly;
    gap: $spacing-lg;
  }

  .mattresses__cert-wrapper {
    display: flex;
    align-items: center;
    flex-direction: column;
    gap: $spacing-xs;
    text-align: center;
    align-self: center;

    @include media-breakpoint-up(md) {
      flex-direction: row;
      text-align: left;
    }
  }

  .mattresses__cert-text {
    font-size: $font-size-sm;
  }
  
}

Is there any way I can improve the logic and without opening and closing divs like in the example above? I'm a bit lost here. This must be dynamic and not hardcoded like some examples I've seen on other pages. [1]: https://i.sstatic.net/m5hTVlDs.png


Solution

  • You can a grid with 6 column, set the default grid-column of each .mattresses__cert-wrapper to span 2. Use :nth-child() to select all 5th and 6th elements (starting from 1 and 2), and set them to grid-column: span 3;.

    .mattresses__certifications {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      gap: 1rem;
      justify-items: center;
    }
    
    .mattresses__cert-wrapper {
      grid-column: span 2;
      text-align: center;
    
      &:is(:nth-child(5n+1), :nth-child(5n+2)) {
        grid-column: span 3;
      }
    }
    
    .mattresses__cert-text {
      display: block;
    }
    <div class="container mattresses__certifications">
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/25/50/50" alt=""><span class="mattresses__cert-text">Lorem ipsum dolor sit amet.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/26/50/50" alt=""><span class="mattresses__cert-text">Debitis hic quaerat illo fuga?</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/27/50/50" alt=""><span class="mattresses__cert-text">Hic architecto temporibus laudantium velit!</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/28/50/50" alt=""><span class="mattresses__cert-text">Earum possimus maxime repellendus repudiandae!</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/29/50/50" alt=""><span class="mattresses__cert-text">Nisi animi aliquid explicabo et.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/30/50/50" alt=""><span class="mattresses__cert-text">Aliquid consectetur temporibus praesentium rerum.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/31/50/50" alt=""><span class="mattresses__cert-text">Deleniti maiores est illo dignissimos?</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/32/50/50" alt=""><span class="mattresses__cert-text">Similique voluptas officiis nam a!</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/33/50/50" alt=""><span class="mattresses__cert-text">Aspernatur neque iste placeat voluptatibus.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/34/50/50" alt=""><span class="mattresses__cert-text">Sint quia culpa et animi.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/35/50/50" alt=""><span class="mattresses__cert-text">Quas quis error facere enim.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/36/50/50" alt=""><span class="mattresses__cert-text">Iste voluptates veniam architecto unde.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/37/50/50" alt=""><span class="mattresses__cert-text">Distinctio accusantium qui magni dolorem?</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/38/50/50" alt=""><span class="mattresses__cert-text">Deleniti dicta veritatis laboriosam quo?</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/39/50/50" alt=""><span class="mattresses__cert-text">Deserunt quidem quo nostrum amet!</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/40/50/50" alt=""><span class="mattresses__cert-text">Repudiandae praesentium totam dolor voluptatum.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/41/50/50" alt=""><span class="mattresses__cert-text">Neque est harum aspernatur repellendus.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/42/50/50" alt=""><span class="mattresses__cert-text">Eos accusantium facilis rerum corrupti.</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/43/50/50" alt=""><span class="mattresses__cert-text">Maiores debitis beatae architecto! Excepturi!</span></div>
      <div class="mattresses__cert-wrapper"><img src="https://picsum.photos/id/44/50/50" alt=""><span class="mattresses__cert-text">Cumque provident alias error ducimus!</span></div>
    </div>