{%- comment -%} MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections {%- endcomment -%} {%- comment -%} Featured collection: product cards from one collection, as a grid or a swipeable row. Cards show the featured image (second product image on hover), optional vendor, price with compare-at price, sale and sold-out badges, and a quick add button. Quick add is a plain Shopify product form that posts the only variant to /cart/add; products with options link to the product page instead. The row scrolls by touch, trackpad and keyboard on its own; a small custom element adds previous/next buttons. Blank collection: placeholder cards in the editor only. Depends on: snippets/lib-image.liquid, snippets/lib-button.liquid {%- endcomment -%} {%- liquid assign s = section.settings assign c = s.collection assign heading_tag = s.heading_tag | default: 'h2' assign card_tag = 'h3' if heading_tag == 'h3' or heading_tag == 'p' assign card_tag = 'h4' endif assign cols = s.columns | plus: 0 assign cols_m = s.columns_mobile | plus: 0 assign limit = s.products_to_show | plus: 0 assign track_id = 'LibFeaturedCollection-' | append: section.id assign img_vw = 100 | divided_by: cols assign img_vw_m = 100 | divided_by: cols_m if s.layout == 'carousel' assign img_vw_m = 80 | divided_by: cols_m endif assign img_sizes = '(min-width: 990px) ' | append: img_vw | append: 'vw, (min-width: 750px) 33vw, ' | append: img_vw_m | append: 'vw' assign show = true if c == blank and request.design_mode == false assign show = false endif if c != blank and c.products.size == 0 and request.design_mode == false assign show = false endif -%} {%- if show -%} {%- endif -%} {% stylesheet %} .lib-featured-collection { 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-featured-collection__inner { display: block; max-width: 1200px; margin: 0 auto; } .lib-featured-collection--full .lib-featured-collection__inner { max-width: none; } @media (max-width: 749px) { .lib-featured-collection { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); } .lib-featured-collection[data-show='desktop'] { display: none; } } @media (min-width: 750px) { .lib-featured-collection[data-show='mobile'] { display: none; } } /* Header: copy, then "View all" and arrows; alignment per device. */ .lib-featured-collection__header { display: flex; flex-direction: column; gap: 1.25rem; margin-bottom: clamp(1.75rem, 4vw, 2.5rem); align-items: flex-start; text-align: left; } .lib-featured-collection__header[data-align='center'] { align-items: center; text-align: center; } .lib-featured-collection__header[data-align='right'] { align-items: flex-end; text-align: right; } @media (min-width: 750px) { .lib-featured-collection__header[data-align='left'] { flex-direction: row; align-items: flex-end; justify-content: space-between; } } @media (max-width: 749px) { .lib-featured-collection__header[data-align-m='left'] { align-items: flex-start; text-align: left; } .lib-featured-collection__header[data-align-m='center'] { align-items: center; text-align: center; } .lib-featured-collection__header[data-align-m='right'] { align-items: flex-end; text-align: right; } } .lib-featured-collection__copy { max-width: 40rem; } .lib-featured-collection__heading { margin: 0; font-size: clamp(1.75rem, 3.4vw, 2.75rem); line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance; } .lib-featured-collection__heading--small { font-size: clamp(1.5rem, 2.4vw, 2rem); } .lib-featured-collection__heading--large { font-size: clamp(2rem, 4.4vw, 3.5rem); } .lib-featured-collection__heading--xlarge { font-size: clamp(2.5rem, 6vw, 4.5rem); } .lib-featured-collection__text { margin-top: 0.75rem; font-size: 1.0625rem; line-height: 1.6; opacity: 0.75; } .lib-featured-collection__text > :first-child { margin-top: 0; } .lib-featured-collection__text > :last-child { margin-bottom: 0; } .lib-featured-collection__actions { display: flex; flex: none; flex-wrap: wrap; align-items: center; gap: 1.25rem; } .lib-featured-collection__nav { display: none; gap: 0.5rem; } .lib-featured-collection__inner[data-overflow] .lib-featured-collection__nav { display: flex; } @media (max-width: 749px) { .lib-featured-collection__inner[data-overflow] .lib-featured-collection__nav { display: none; } } .lib-featured-collection__arrow { display: inline-flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; padding: 0; border: 1px solid color-mix(in srgb, var(--lib-text) 22%, transparent); border-radius: 50%; background: transparent; color: var(--lib-text); cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease; } .lib-featured-collection__arrow:hover:not(:disabled) { background: var(--lib-accent); border-color: var(--lib-accent); color: var(--lib-accent-text); } .lib-featured-collection__arrow:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 2px; } .lib-featured-collection__arrow:disabled { opacity: 0.35; cursor: default; } /* Track: grid, or a scroll-snap row (works by swipe, trackpad and keyboard without JS). */ .lib-featured-collection__track { display: grid; grid-template-columns: repeat(var(--lib-cols-m), minmax(0, 1fr)); gap: calc(var(--lib-gap) * 1.5) var(--lib-gap); margin: 0; padding: 0; list-style: none; } @media (min-width: 750px) { .lib-featured-collection__track { grid-template-columns: repeat(min(var(--lib-cols), 3), minmax(0, 1fr)); } } @media (min-width: 990px) { .lib-featured-collection__track { grid-template-columns: repeat(var(--lib-cols), minmax(0, 1fr)); } } .lib-featured-collection[data-layout='carousel'] .lib-featured-collection__track { --lib-per: var(--lib-cols-m); display: flex; gap: var(--lib-gap); overflow-x: auto; margin-inline: -1rem; padding: 0.25rem 1rem 0.75rem; scroll-snap-type: x mandatory; scroll-padding-inline: 1rem; scrollbar-width: thin; overscroll-behavior-x: contain; } .lib-featured-collection[data-layout='carousel'] .lib-featured-collection__item { flex: 0 0 calc((100% - (var(--lib-per) - 1) * var(--lib-gap)) / var(--lib-per)); scroll-snap-align: start; } @media (max-width: 749px) { /* A peek of the next card says "swipe me". */ .lib-featured-collection[data-layout='carousel'] .lib-featured-collection__item { flex-basis: calc((88% - (var(--lib-per) - 1) * var(--lib-gap)) / var(--lib-per)); } } @media (min-width: 750px) { .lib-featured-collection[data-layout='carousel'] .lib-featured-collection__track { --lib-per: min(var(--lib-cols), 3); margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; } } @media (min-width: 990px) { .lib-featured-collection[data-layout='carousel'] .lib-featured-collection__track { --lib-per: var(--lib-cols); } } .lib-featured-collection__track:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 4px; border-radius: 4px; } /* Card */ .lib-featured-collection__item { display: flex; min-width: 0; } .lib-featured-collection__card { position: relative; display: flex; flex: 1; flex-direction: column; min-width: 0; border-radius: var(--lib-radius-card); } .lib-featured-collection[data-card='card'] .lib-featured-collection__card { background: var(--lib-card); } .lib-featured-collection__media { position: relative; overflow: hidden; aspect-ratio: 1; border-radius: var(--lib-radius-card); background: color-mix(in srgb, var(--lib-text) 6%, transparent); } .lib-featured-collection__media[data-ratio='portrait'] { aspect-ratio: 4 / 5; } .lib-featured-collection__media[data-ratio='tall'] { aspect-ratio: 2 / 3; } .lib-featured-collection__media[data-ratio='landscape'] { aspect-ratio: 4 / 3; } .lib-featured-collection[data-card='card'] .lib-featured-collection__media { border-end-start-radius: 0; border-end-end-radius: 0; } .lib-featured-collection__img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); } svg.lib-featured-collection__img { fill: color-mix(in srgb, var(--lib-text) 22%, transparent); } .lib-featured-collection__img2 { position: absolute; inset: 0; opacity: 0; transition: opacity 0.4s ease; } @media (hover: hover) { .lib-featured-collection__card:hover .lib-featured-collection__img2 { opacity: 1; } .lib-featured-collection__card:hover .lib-featured-collection__img { transform: scale(1.03); } } .lib-featured-collection__card:focus-within .lib-featured-collection__img2 { opacity: 1; } .lib-featured-collection__card.is-sold-out .lib-featured-collection__media img { opacity: 0.6; } .lib-featured-collection__badge { position: absolute; z-index: 2; top: 0.75rem; left: 0.75rem; padding: 0.3rem 0.7rem; border-radius: 999px; background: var(--lib-accent); color: var(--lib-accent-text); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.03em; line-height: 1.2; pointer-events: none; } .lib-featured-collection__badge--sold-out { background: var(--lib-bg); color: var(--lib-text); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lib-text) 20%, transparent); } .lib-featured-collection__body { display: flex; flex: 1; flex-direction: column; gap: 0.3rem; padding-top: 0.9rem; } .lib-featured-collection[data-card='card'] .lib-featured-collection__body { padding: 0.9rem 1rem 1rem; } .lib-featured-collection__vendor { margin: 0; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.6; } .lib-featured-collection__title { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.3; } .lib-featured-collection__link { color: inherit; text-decoration: none; } /* The title link covers the whole card; the quick add button sits above it. */ .lib-featured-collection__link::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: var(--lib-radius-card); } .lib-featured-collection__link:hover { text-decoration: underline; text-underline-offset: 0.2em; } .lib-featured-collection__link:focus-visible { outline: none; } .lib-featured-collection__link:focus-visible::after { outline: 2px solid var(--lib-accent); outline-offset: 3px; } .lib-featured-collection__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin: 0; font-size: 0.9375rem; } .lib-featured-collection__price-now--sale { font-weight: 600; } .lib-featured-collection__price-was { opacity: 0.55; font-size: 0.875rem; } .lib-featured-collection__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .lib-featured-collection__cta { position: relative; z-index: 2; margin-top: auto; padding-top: 0.75rem; } .lib-featured-collection__form { margin: 0; } .lib-featured-collection__add { display: inline-flex; align-items: center; justify-content: center; width: 100%; min-height: 2.75rem; padding: 0.6rem 1rem; border: 1.5px solid var(--lib-text); border-radius: min(var(--lib-radius-card), 999px); background: transparent; color: var(--lib-text); font: inherit; font-size: 0.875rem; font-weight: 600; line-height: 1.2; text-align: center; text-decoration: none; cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; } .lib-featured-collection__add:hover:not(:disabled) { background: var(--lib-accent); border-color: var(--lib-accent); color: var(--lib-accent-text); } .lib-featured-collection__add:focus-visible { outline: 2px solid var(--lib-accent); outline-offset: 2px; } .lib-featured-collection__add:disabled, .lib-featured-collection__add[aria-disabled='true'] { opacity: 0.45; cursor: default; } @media (prefers-reduced-motion: reduce) { .lib-featured-collection__img, .lib-featured-collection__img2, .lib-featured-collection__arrow, .lib-featured-collection__add { transition: none; } .lib-featured-collection__card:hover .lib-featured-collection__img { transform: none; } } {% endstylesheet %} {% javascript %} if (!customElements.get('lib-featured-collection-slider')) { customElements.define( 'lib-featured-collection-slider', class extends HTMLElement { connectedCallback() { this.track = this.querySelector('[data-track]'); this.buttons = this.querySelectorAll('.lib-featured-collection__arrow'); if (!this.track || !this.buttons.length || this.observer) return; this.onScroll = () => this.update(); this.track.addEventListener('scroll', this.onScroll, { passive: true }); this.buttons.forEach((button) => button.addEventListener('click', () => this.step(Number(button.dataset.dir)))); this.observer = new ResizeObserver(() => this.update()); this.observer.observe(this.track); this.update(); } disconnectedCallback() { this.observer?.disconnect(); this.observer = null; this.track?.removeEventListener('scroll', this.onScroll); } step(dir) { // One page of visible cards per click. const item = this.track.firstElementChild; const gap = parseFloat(getComputedStyle(this.track).columnGap) || 0; const width = item ? item.getBoundingClientRect().width + gap : this.track.clientWidth; const per = Math.max(1, Math.floor((this.track.clientWidth + gap) / width)); const rtl = getComputedStyle(this.track).direction === 'rtl'; const smooth = !matchMedia('(prefers-reduced-motion: reduce)').matches; this.track.scrollBy({ left: dir * per * width * (rtl ? -1 : 1), behavior: smooth ? 'smooth' : 'auto' }); } update() { const max = this.track.scrollWidth - this.track.clientWidth; const x = Math.abs(this.track.scrollLeft); this.toggleAttribute('data-overflow', max > 2); const [prev, next] = this.buttons; if (prev) prev.disabled = x <= 2; if (next) next.disabled = x >= max - 2; } } ); } {% endjavascript %} {% schema %} { "name": "Lib · Featured collection", "tag": "section", "class": "lib-section", "settings": [ { "type": "header", "content": "Content" }, { "type": "inline_richtext", "id": "heading", "label": "Heading", "default": "New in for the table" }, { "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" }, { "value": "xlarge", "label": "Extra large" } ], "default": "medium" }, { "type": "richtext", "id": "text", "label": "Text", "default": "

Stoneware, linen and beeswax, made in small batches.

" }, { "type": "collection", "id": "collection", "label": "Collection", "info": "In the theme editor a blank collection shows placeholder cards; on the live store the section is hidden until you pick one." }, { "type": "range", "id": "products_to_show", "label": "Products to show", "min": 2, "max": 24, "step": 1, "default": 8 }, { "type": "header", "content": "Button" }, { "type": "text", "id": "view_all_label", "label": "\"View all\" label", "info": "Links to the collection. Leave blank 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": "text" }, { "type": "header", "content": "Product cards" }, { "type": "select", "id": "image_ratio", "label": "Image shape", "options": [ { "value": "square", "label": "Square" }, { "value": "portrait", "label": "Portrait (4:5)" }, { "value": "tall", "label": "Tall (2:3)" }, { "value": "landscape", "label": "Landscape (4:3)" } ], "default": "portrait" }, { "type": "select", "id": "card_style", "label": "Card style", "options": [ { "value": "plain", "label": "Plain" }, { "value": "card", "label": "Card with background" } ], "default": "plain" }, { "type": "checkbox", "id": "show_secondary_image", "label": "Show second image on hover", "info": "Uses the product's second media item.", "default": true }, { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false }, { "type": "text", "id": "sale_label", "label": "Sale badge", "info": "Shown when the compare-at price is higher than the price. Leave blank to hide.", "default": "Sale" }, { "type": "text", "id": "sold_out_label", "label": "Sold out badge", "info": "Leave blank to hide.", "default": "Sold out" }, { "type": "checkbox", "id": "show_quick_add", "label": "Show quick add button", "info": "Products without options are added to the cart directly; products with options link to the product page.", "default": true }, { "type": "text", "id": "quick_add_label", "label": "Quick add label", "default": "Quick add", "visible_if": "{{ section.settings.show_quick_add }}" }, { "type": "text", "id": "choose_label", "label": "Label for products with options", "default": "Choose options", "visible_if": "{{ section.settings.show_quick_add }}" }, { "type": "range", "id": "card_radius", "label": "Corner radius", "min": 0, "max": 32, "step": 2, "unit": "px", "default": 12 }, { "type": "header", "content": "Layout" }, { "type": "select", "id": "layout", "label": "Layout", "options": [ { "value": "grid", "label": "Grid" }, { "value": "carousel", "label": "Carousel (swipeable row)" } ], "default": "carousel" }, { "type": "range", "id": "columns", "label": "Columns on desktop", "info": "Tablets show up to 3.", "min": 2, "max": 6, "step": 1, "default": 4 }, { "type": "select", "id": "columns_mobile", "label": "Columns on mobile", "options": [ { "value": "1", "label": "1" }, { "value": "2", "label": "2" } ], "default": "2" }, { "type": "range", "id": "gap", "label": "Space between cards", "min": 8, "max": 40, "step": 4, "unit": "px", "default": 20 }, { "type": "select", "id": "section_width", "label": "Width", "options": [ { "value": "page", "label": "Page width" }, { "value": "full", "label": "Full width" } ], "default": "page" }, { "type": "text_alignment", "id": "text_alignment", "label": "Heading alignment on desktop", "default": "left" }, { "type": "select", "id": "text_alignment_mobile", "label": "Heading alignment on mobile", "options": [ { "value": "left", "label": "Left" }, { "value": "center", "label": "Center" }, { "value": "right", "label": "Right" } ], "default": "left" }, { "type": "header", "content": "Colors" }, { "type": "color", "id": "color_bg", "label": "Background", "default": "#FAF8F4" }, { "type": "color_background", "id": "color_bg_gradient", "label": "Background gradient", "info": "Optional. Covers the background color." }, { "type": "color", "id": "color_text", "label": "Text", "default": "#1C1917" }, { "type": "color", "id": "color_accent", "label": "Accent (badges, buttons on hover)", "default": "#1C1917" }, { "type": "color", "id": "color_accent_text", "label": "Text on accent", "default": "#FAF8F4" }, { "type": "color", "id": "color_card", "label": "Card background", "default": "#FFFFFF", "visible_if": "{{ section.settings.card_style == 'card' }}" }, { "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": 80 }, { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 80 }, { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 48 }, { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 48 }, { "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." } ], "presets": [ { "name": "Lib · Featured collection" } ] } {% endschema %}