Collection Tabs

Section

Tabbed collection browser using JS-free radio inputs with CSS-only panel switching.

ProductFreeA11yDynamic
Edit
Copied 0 times
Preview
Accent
Section code
<section class="sl-collection-tabs" style="padding:clamp(32px,6vw,64px) 1rem;color:inherit;font-family:inherit;">
  <div style="max-width:1200px;margin:0 auto;">
    <h2 style="margin:0 0 1.25rem;font-size:clamp(1.5rem,3vw,2rem);text-align:center;">{{ section.settings.heading }}</h2>
    <style>
      .sl-ct-panel { display: none; }
      {%- for block in section.blocks -%}
        #sl-ct-{{ section.id }}-{{ block.id }}:checked ~ .sl-ct-tabs label[for="sl-ct-{{ section.id }}-{{ block.id }}"] { background: var(--sl-accent,#0a5cff); color:#fff; border-color: var(--sl-accent,#0a5cff); }
        #sl-ct-{{ section.id }}-{{ block.id }}:checked ~ .sl-ct-panels [data-panel="{{ block.id }}"] { display: grid; }
      {%- endfor -%}
    </style>
    {%- for block in section.blocks -%}
      <input type="radio" name="sl-ct-{{ section.id }}" id="sl-ct-{{ section.id }}-{{ block.id }}" {% if forloop.first %}checked{% endif %} style="position:absolute;opacity:0;pointer-events:none;" />
    {%- endfor -%}
    <div class="sl-ct-tabs" role="tablist" style="display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center;margin:0 0 1.5rem;">
      {%- for block in section.blocks -%}
        <label for="sl-ct-{{ section.id }}-{{ block.id }}" style="cursor:pointer;padding:.5rem 1rem;border:1px solid currentColor;border-radius:999px;font-size:.9rem;">{{ block.settings.tab_name }}</label>
      {%- endfor -%}
    </div>
    <div class="sl-ct-panels">
      {%- for block in section.blocks -%}
        {%- assign coll = collections[block.settings.collection] -%}
        <div class="sl-ct-panel" data-panel="{{ block.id }}" style="gap:1rem;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));" {{ block.shopify_attributes }}>
          {%- if coll.products.size > 0 -%}
            {%- for product in coll.products limit: 4 -%}
              <article style="border:1px solid currentColor;border-radius:.5rem;overflow:hidden;">
                <a href="{{ product.url }}" style="color:inherit;text-decoration:none;display:block;">
                  <img src="{{ product.featured_image | image_url: width: 400 }}" alt="{{ product.featured_image.alt | default: product.title }}" loading="lazy" style="width:100%;aspect-ratio:1/1;object-fit:cover;display:block;" />
                  <div style="padding:.75rem;">
                    <h3 style="margin:0 0 .25rem;font-size:.95rem;">{{ product.title }}</h3>
                    <p style="margin:0;color:var(--sl-accent,#0a5cff);font-weight:600;">{{ product.price | money }}</p>
                  </div>
                </a>
              </article>
            {%- endfor -%}
          {%- else -%}
            {%- for i in (1..4) -%}
              <article style="border:1px solid currentColor;border-radius:.5rem;overflow:hidden;">
                <img src="https://picsum.photos/seed/ct{{ block.id }}{{ i }}/400/400" alt="{{ block.settings.placeholder_alt | default: 'Product placeholder' }}" loading="lazy" style="width:100%;aspect-ratio:1/1;object-fit:cover;display:block;" />
                <div style="padding:.75rem;">
                  <h3 style="margin:0 0 .25rem;font-size:.95rem;">Product {{ i }}</h3>
                  <p style="margin:0;color:var(--sl-accent,#0a5cff);font-weight:600;">$29.00</p>
                </div>
              </article>
            {%- endfor -%}
          {%- endif -%}
        </div>
      {%- endfor -%}
    </div>
  </div>
</section>
{% schema %}
{
  "name": "Collection Tabs",
  "settings": [
    { "type": "text", "id": "heading", "label": "Heading", "default": "Shop by category" }
  ],
  "blocks": [
    {
      "type": "tab",
      "name": "Tab",
      "settings": [
        { "type": "text", "id": "tab_name", "label": "Tab name", "default": "New" },
        { "type": "collection", "id": "collection", "label": "Collection" },
        { "type": "text", "id": "placeholder_alt", "label": "Alt text (placeholder)", "default": "Product placeholder" }
      ]
    }
  ],
  "presets": [
    {
      "name": "Collection Tabs",
      "blocks": [
        { "type": "tab" },
        { "type": "tab" },
        { "type": "tab" }
      ]
    }
  ]
}
{% endschema %}

Internal notesTeam only

Freeform markdown notes visible only to signed-in team members. Separate from the public description.