{%- comment -%} MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections {%- endcomment -%} {%- comment -%} Collection tabs: a product grid with tabs, one tab per collection (New in, Best sellers, Sale…), in a single section. Every tab's products are rendered by Liquid, so search engines and shoppers without JavaScript see all of them, one titled group after another; a small custom element turns the groups into tabs (WAI-ARIA tabs pattern: arrow keys, Home, End). Each tab can end with a "view all" link to its collection. Cards show price, badges and an optional quick add. Depends on: snippets/lib-product-card.liquid, snippets/lib-image.liquid, snippets/lib-button.liquid {%- endcomment -%} {%- liquid assign s = section.settings assign heading_tag = s.heading_tag | default: 'h2' assign panel_tag = 'h3' assign card_tag = 'h3' if heading_tag == 'h3' or heading_tag == 'p' assign panel_tag = 'h4' assign card_tag = 'h4' endif assign cols = s.columns | plus: 0 assign cols_m = s.columns_mobile | plus: 0 assign limit = s.products_per_tab | plus: 0 assign img_vw = 100 | divided_by: cols assign img_sizes = '(min-width: 990px) ' | append: img_vw | append: 'vw, (min-width: 750px) 33vw, 50vw' -%}
{%- if s.heading != blank -%} <{{ heading_tag }} class="lib-tabs__heading lib-tabs__heading--{{ s.heading_size }}"> {{- s.heading -}} {%- endif -%} {%- if s.text != blank -%}
{{ s.text }}
{%- endif -%} {%- if section.blocks.size > 1 -%} {%- comment -%} The script shows the tab list; without it every group shows with its own title. {%- endcomment -%} {%- endif -%}
{%- for block in section.blocks -%} {%- liquid assign b = block.settings assign c = b.collection assign label = b.label | default: c.title | default: 'Collection' assign id_prefix = 'LibTabs-' | append: block.id assign first_tab = forloop.first -%}
<{{ panel_tag }} class="lib-tabs__panel-title">{{ label | escape }}
    {%- if c != blank and c.products.size > 0 -%} {%- for item in c.products limit: limit -%} {%- liquid assign eager = false if section.index <= 2 and first_tab and forloop.index <= cols assign eager = true endif -%}
  • {%- render 'lib-product-card', product: item, title_tag: card_tag, ratio: s.image_ratio, sizes: img_sizes, eager: eager, show_vendor: s.show_vendor, show_second_image: s.show_second_image, show_quick_add: s.show_quick_add, quick_add_label: s.quick_add_label, choose_label: s.choose_label, sold_out_label: s.sold_out_label, sale_label: s.sale_label, sale_price_label: s.sale_price_label, regular_price_label: s.regular_price_label, id_prefix: id_prefix -%}
  • {%- endfor -%} {%- elsif request.design_mode -%} {%- for i in (1..cols) -%}
  • {%- render 'lib-product-card', title_tag: card_tag, ratio: s.image_ratio -%}
  • {%- endfor -%} {%- endif -%}
{%- if s.view_all_label != blank and c != blank -%}
{%- render 'lib-button', label: s.view_all_label, url: c.url, style: s.view_all_style -%}
{%- endif -%}
{%- endfor -%}
{% stylesheet %} .lib-tabs { display: block; background-color: var(--lib-bg); background-image: var(--lib-bg-image, none); color: var(--lib-text); padding: var(--lib-pt) 1rem var(--lib-pb); } .lib-tabs__inner { max-width: 1200px; margin: 0 auto; } .lib-tabs--full .lib-tabs__inner { max-width: none; } @media (max-width: 749px) { .lib-tabs { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); } .lib-tabs[data-show='desktop'] { display: none; } } @media (min-width: 750px) { .lib-tabs[data-show='mobile'] { display: none; } } .lib-tabs__header { display: grid; gap: 0.75rem; margin-bottom: clamp(1.25rem, 3vw, 2rem); } .lib-tabs__heading { margin: 0; font-size: clamp(1.75rem, 3vw, 2.5rem); line-height: 1.15; letter-spacing: -0.02em; text-wrap: balance; } .lib-tabs__heading--small { font-size: clamp(1.25rem, 1.8vw, 1.5rem); } .lib-tabs__heading--large { font-size: clamp(2rem, 4vw, 3.25rem); } .lib-tabs__text { max-width: 40rem; font-size: 1rem; line-height: 1.6; opacity: 0.85; } .lib-tabs__text > :first-child { margin-top: 0; } .lib-tabs__text > :last-child { margin-bottom: 0; } .lib-tabs__header[data-align='center'] { justify-items: center; text-align: center; } @media (max-width: 749px) { .lib-tabs__header[data-align-m='left'] { justify-items: start; text-align: left; } .lib-tabs__header[data-align-m='center'] { justify-items: center; text-align: center; } } /* Tabs: a row that scrolls sideways when the labels don't fit. */ .lib-tabs__tablist { display: flex; gap: 0.5rem; max-width: 100%; margin-top: 0.5rem; padding: 0.25rem; overflow-x: auto; scrollbar-width: none; } .lib-tabs__tablist[hidden] { display: none; } .lib-tabs__tab { flex: none; min-height: 2.75rem; padding: 0.55rem 1.1rem; border: 1.5px solid color-mix(in srgb, var(--lib-text) 22%, transparent); border-radius: 999px; background: transparent; color: inherit; font: inherit; font-size: 0.9375rem; font-weight: 600; line-height: 1.2; white-space: nowrap; cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; } .lib-tabs__tab:hover { border-color: var(--lib-text); } .lib-tabs__tab[aria-selected='true'] { background: var(--lib-text); border-color: var(--lib-text); color: var(--lib-bg); } .lib-tabs__tab:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 2px; } .lib-tabs[data-tab-style='underline'] .lib-tabs__tablist { gap: 1.5rem; padding-inline: 0; } .lib-tabs[data-tab-style='underline'] .lib-tabs__tab { padding-inline: 0; border: 0; border-bottom: 2px solid transparent; border-radius: 0; opacity: 0.7; } .lib-tabs[data-tab-style='underline'] .lib-tabs__tab[aria-selected='true'] { background: none; color: inherit; border-bottom-color: currentColor; opacity: 1; } .lib-tabs__panel + .lib-tabs__panel { margin-top: clamp(2rem, 5vw, 3.5rem); } .lib-tabs[data-ready] .lib-tabs__panel + .lib-tabs__panel { margin-top: 0; } .lib-tabs__panel[hidden] { display: none; } .lib-tabs__panel:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 6px; border-radius: 4px; } .lib-tabs__panel-title { margin: 0 0 1rem; font-size: 1.25rem; line-height: 1.3; } .lib-tabs[data-ready] .lib-tabs__panel-title { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .lib-tabs__grid { display: grid; grid-template-columns: repeat(var(--lib-cols), minmax(0, 1fr)); gap: clamp(1rem, 2vw, 1.5rem); margin: 0; padding: 0; list-style: none; } .lib-tabs__item { display: flex; min-width: 0; } @media (max-width: 749px) { .lib-tabs__grid { grid-template-columns: repeat(var(--lib-cols-m), minmax(0, 1fr)); } .lib-tabs[data-layout-m='row'] .lib-tabs__grid { grid-auto-flow: column; grid-template-columns: none; grid-auto-columns: calc((100% - 1rem) / var(--lib-cols-m) - 2.5rem); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: 0.25rem; } .lib-tabs[data-layout-m='row'] .lib-tabs__item { scroll-snap-align: start; } } .lib-tabs__more { display: flex; justify-content: center; margin-top: clamp(1.5rem, 3vw, 2.25rem); } @media (prefers-reduced-motion: no-preference) { .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item { animation: lib-tabs-in 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both; } .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(2) { animation-delay: 40ms; } .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(3) { animation-delay: 80ms; } .lib-tabs[data-animate] .lib-tabs__panel[data-shown] .lib-tabs__item:nth-child(n + 4) { animation-delay: 120ms; } } @media (prefers-reduced-motion: reduce) { .lib-tabs__tab { transition: none; } } @keyframes lib-tabs-in { from { opacity: 0; transform: translateY(10px); } } {% endstylesheet %} {% javascript %} (() => { if (customElements.get('lib-collection-tabs')) return; class LibCollectionTabs extends HTMLElement { connectedCallback() { this.tablist = this.querySelector('[data-tablist]'); if (!this.tablist) return; this.tabs = [...this.tablist.querySelectorAll('[role="tab"]')]; this.panels = this.tabs.map((tab) => this.querySelector(`#${CSS.escape(tab.getAttribute('aria-controls'))}`)); this.panels.forEach((panel, i) => { panel.setAttribute('role', 'tabpanel'); panel.setAttribute('aria-labelledby', this.tabs[i].id); panel.tabIndex = 0; }); this.tablist.hidden = false; this.toggleAttribute('data-ready', true); this.select(Math.max(0, this.tabs.findIndex((t) => t.getAttribute('aria-selected') === 'true')), false); this.tablist.addEventListener('click', (event) => { const tab = event.target.closest('[role="tab"]'); if (tab) this.select(this.tabs.indexOf(tab), true); }); this.tablist.addEventListener('keydown', (event) => this.onKey(event)); // Theme editor: selecting a tab's block shows its panel. this.addEventListener('shopify:block:select', (event) => { const index = this.tabs.findIndex((t) => t.id === `LibTab-${event.detail.blockId}`); if (index >= 0) this.select(index, false); }); } onKey(event) { const current = this.tabs.indexOf(document.activeElement); if (current < 0) return; const last = this.tabs.length - 1; const moves = {ArrowRight: current + 1, ArrowLeft: current - 1, Home: 0, End: last}; if (!(event.key in moves)) return; event.preventDefault(); const next = (moves[event.key] + this.tabs.length) % this.tabs.length; this.select(next, true); } select(index, focus) { this.tabs.forEach((tab, i) => { const active = i === index; tab.setAttribute('aria-selected', String(active)); tab.tabIndex = active ? 0 : -1; this.panels[i].hidden = !active; this.panels[i].toggleAttribute('data-shown', active && focus); }); if (focus) { this.tabs[index].focus(); this.tabs[index].scrollIntoView({block: 'nearest', inline: 'nearest'}); } } } customElements.define('lib-collection-tabs', LibCollectionTabs); })(); {% endjavascript %} {% schema %} { "name": "Lib · Collection tabs", "tag": "section", "class": "lib-section", "max_blocks": 6, "settings": [ { "type": "header", "content": "Content" }, { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "Shop the range" }, { "type": "select", "id": "heading_tag", "label": "Heading tag", "info": "Use H1 only when this is the page's main heading.", "options": [ { "value": "h1", "label": "H1" }, { "value": "h2", "label": "H2" }, { "value": "h3", "label": "H3" }, { "value": "p", "label": "Paragraph" } ], "default": "h2" }, { "type": "select", "id": "heading_size", "label": "Heading size", "options": [ { "value": "small", "label": "Small" }, { "value": "medium", "label": "Medium" }, { "value": "large", "label": "Large" } ], "default": "medium" }, { "type": "richtext", "id": "text", "label": "Intro text" }, { "type": "text", "id": "tabs_label", "label": "Tab list name (screen readers)", "default": "Collections" }, { "type": "select", "id": "tab_style", "label": "Tab style", "options": [ { "value": "pill", "label": "Pills" }, { "value": "underline", "label": "Underline" } ], "default": "pill" }, { "type": "text", "id": "view_all_label", "label": "View all link", "info": "Shown under each tab, linking to its collection. Leave empty to hide.", "default": "View all" }, { "type": "select", "id": "view_all_style", "label": "View all style", "options": [ { "value": "primary", "label": "Solid" }, { "value": "outline", "label": "Outline" }, { "value": "text", "label": "Text link" } ], "default": "outline" }, { "type": "header", "content": "Products" }, { "type": "range", "id": "products_per_tab", "label": "Products per tab", "min": 2, "max": 16, "step": 1, "default": 4 }, { "type": "select", "id": "image_ratio", "label": "Image shape", "options": [ { "value": "square", "label": "Square" }, { "value": "portrait", "label": "Portrait" }, { "value": "tall", "label": "Tall" }, { "value": "landscape", "label": "Landscape" } ], "default": "portrait" }, { "type": "select", "id": "card_style", "label": "Card style", "options": [ { "value": "plain", "label": "Plain" }, { "value": "card", "label": "Card" } ], "default": "plain" }, { "type": "range", "id": "card_radius", "label": "Corner radius", "min": 0, "max": 24, "step": 2, "unit": "px", "default": 12 }, { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false }, { "type": "checkbox", "id": "show_second_image", "label": "Show second image on hover", "default": true }, { "type": "checkbox", "id": "show_quick_add", "label": "Show quick add", "info": "Products with options link to their page instead.", "default": false }, { "type": "text", "id": "quick_add_label", "label": "Quick add button", "default": "Add to cart" }, { "type": "text", "id": "choose_label", "label": "Link for products with options", "default": "Choose options" }, { "type": "text", "id": "sale_label", "label": "Sale badge", "default": "Sale" }, { "type": "text", "id": "sold_out_label", "label": "Sold out badge", "default": "Sold out" }, { "type": "text", "id": "sale_price_label", "label": "Sale price label (screen readers)", "default": "Sale price" }, { "type": "text", "id": "regular_price_label", "label": "Regular price label (screen readers)", "default": "Regular price" }, { "type": "header", "content": "Layout" }, { "type": "range", "id": "columns", "label": "Columns on desktop", "min": 2, "max": 6, "step": 1, "default": 4 }, { "type": "range", "id": "columns_mobile", "label": "Columns on mobile", "min": 1, "max": 2, "step": 1, "default": 2 }, { "type": "select", "id": "layout_mobile", "label": "Layout on mobile", "options": [ { "value": "grid", "label": "Grid" }, { "value": "row", "label": "Swipeable row" } ], "default": "grid" }, { "type": "select", "id": "section_width", "label": "Width", "options": [ { "value": "page", "label": "Page width" }, { "value": "full", "label": "Full width" } ], "default": "page" }, { "type": "select", "id": "text_alignment", "label": "Heading and tabs alignment on desktop", "options": [ { "value": "left", "label": "Left" }, { "value": "center", "label": "Center" } ], "default": "center" }, { "type": "select", "id": "text_alignment_mobile", "label": "Heading and tabs alignment on mobile", "options": [ { "value": "left", "label": "Left" }, { "value": "center", "label": "Center" } ], "default": "left" }, { "type": "header", "content": "Colors" }, { "type": "color", "id": "color_bg", "label": "Background", "default": "#FFFFFF" }, { "type": "color_background", "id": "color_bg_gradient", "label": "Background gradient", "info": "Optional. Covers the background color." }, { "type": "color", "id": "color_text", "label": "Text", "default": "#1F1B17" }, { "type": "color", "id": "color_accent", "label": "Accent (buttons, badges)", "default": "#7A5A3A" }, { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FFFFFF" }, { "type": "color", "id": "color_card", "label": "Card background", "default": "#FAF6F1" }, { "type": "header", "content": "Spacing and visibility" }, { "type": "range", "id": "padding_top", "label": "Top padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 64 }, { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 64 }, { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 40 }, { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 40 }, { "type": "select", "id": "show_on", "label": "Show on", "options": [ { "value": "all", "label": "All devices" }, { "value": "desktop", "label": "Desktop only" }, { "value": "mobile", "label": "Mobile only" } ], "default": "all" }, { "type": "text", "id": "anchor_id", "label": "Anchor ID", "info": "Optional. Link to this section with #your-id." }, { "type": "header", "content": "Motion" }, { "type": "checkbox", "id": "animate", "label": "Fade products in when switching tabs", "info": "Never when reduced motion is on.", "default": true } ], "blocks": [ { "type": "tab", "name": "Tab", "settings": [ { "type": "collection", "id": "collection", "label": "Collection" }, { "type": "text", "id": "label", "label": "Tab label", "info": "Optional. Uses the collection's title when empty." } ] } ], "presets": [ { "name": "Lib · Collection tabs", "blocks": [ { "type": "tab", "settings": { "label": "New in" } }, { "type": "tab", "settings": { "label": "Best sellers" } }, { "type": "tab", "settings": { "label": "Sale" } } ] } ] } {% endschema %}