# Collection banner: free Shopify section

> Collection page header with the collection's title, description, image and product count, over the image or beside it, plus an optional breadcrumb.

Collection banner is a free Shopify section for the top of collection pages. It reads the collection itself, so its title, description, image and product count stay in step with Shopify admin, and shows them over the image, beside it or as text only, with an optional breadcrumb. A separate mobile image, nine text positions and an H1 title by default make it a complete collection header in Online Store 2.0 themes without an app or JavaScript.

- **Category:** Hero and banners
- **Use on:** Collection, Landing pages, Any page
- **Reads:** The page's collection or one you pick
- **Size:** 23 KB in 2 files, no JavaScript
- **License:** MIT, © 2026 Lintel
- **Page:** https://lintelagency.com/resources/shopify-sections/collection-banner
- **Live demo:** https://lintelagency.com/resources/shopify-sections/demo/lib-collection-banner.html
- **Added:** 2026-11-02

## What it’s for

- Header of every collection page, filled from the collection's own title, description and image
- Seasonal or campaign collection with its own photo and a separate mobile crop
- A category landing page that points to one collection, using the collection picker

## Editor settings

In the theme editor the section is called “Lib · Collection banner”. IDs, types, labels and defaults come from the section’s schema; the labels are what the theme editor shows.

### Content

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `collection` | `collection` | Collection | – |  |
| `heading_tag` | `select` | Title tag | h1 | `h1`, `h2`, `h3`, `p` |
| `heading_size` | `select` | Title size | large | `small`, `medium`, `large`, `xlarge` |
| `show_description` | `checkbox` | Show collection description | `true` |  |
| `show_count` | `checkbox` | Show product count | `true` |  |
| `count_singular` | `text` | Product count word, one | product |  |
| `count_plural` | `text` | Product count word, more than one | products |  |
| `show_breadcrumb` | `checkbox` | Show breadcrumb | `false` |  |
| `breadcrumb_home` | `text` | Breadcrumb home link | Home |  |
| `breadcrumb_label` | `text` | Breadcrumb label for screen readers | Breadcrumb |  |
| `placeholder_title` | `text` | Title in the editor preview | Collection title |  |
| `placeholder_text` | `text` | Description in the editor preview | The collection's description from Shopify admin appears here. |  |

### Image

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `use_collection_image` | `checkbox` | Use the collection's image | `true` |  |
| `image` | `image_picker` | Desktop image | – |  |
| `image_mobile` | `image_picker` | Mobile image | – |  |
| `layout` | `select` | Layout | overlay | `overlay`, `split`, `text` |
| `height` | `select` | Banner height | medium | `small`, `medium`, `large` |
| `overlay_opacity` | `range` | Image overlay | `35` | 0–80 %, step 5 |
| `image_position` | `select` | Image side (beside the text) | right | `left`, `right` |
| `content_position` | `select` | Text position over the image on desktop | bottom-left | `top-left`, `top-center`, `top-right`, `middle-left`, `middle-center`, `middle-right`, `bottom-left`, `bottom-center`, `bottom-right` |
| `content_position_mobile` | `select` | Text position over the image on mobile | bottom-left | `top-left`, `top-center`, `middle-left`, `middle-center`, `bottom-left`, `bottom-center` |

### Layout

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `section_width` | `select` | Width | page | `page`, `full` |
| `text_alignment` | `text_alignment` | Text alignment on desktop | left |  |
| `text_alignment_mobile` | `select` | Text alignment on mobile | left | `left`, `center`, `right` |

### Colors

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `color_bg` | `color` | Background | #FFFDF9 |  |
| `color_bg_gradient` | `color_background` | Background gradient | – |  |
| `color_text` | `color` | Text | #1C1917 |  |
| `color_overlay_text` | `color` | Text over the image | #FFFFFF |  |
| `color_accent` | `color` | Accent (product count) | #7A5C3E |  |

### Spacing and visibility

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `padding_top` | `range` | Top padding on desktop | `24` | 0–200 px, step 4 |
| `padding_bottom` | `range` | Bottom padding on desktop | `40` | 0–200 px, step 4 |
| `padding_top_mobile` | `range` | Top padding on mobile | `16` | 0–160 px, step 4 |
| `padding_bottom_mobile` | `range` | Bottom padding on mobile | `28` | 0–160 px, step 4 |
| `show_on` | `select` | Show on | all | `all`, `desktop`, `mobile` |
| `anchor_id` | `text` | Anchor ID | – |  |

### Motion

| ID | Type | Label | Default | Options or range |
| --- | --- | --- | --- | --- |
| `animate` | `checkbox` | Slow image zoom and text fade on load | `false` |  |

## Install

### In Shopify admin

1. Work on a copy, not your live theme: in Shopify admin go to **Online Store > Themes**, open the **…** menu on your current theme and choose **Duplicate**.
2. On the copy, open the **…** menu and choose **Edit code**.
3. In the `sections` folder, add a new file named `lib-collection-banner.liquid` and paste the contents of `sections/lib-collection-banner.liquid` from the source below. Save.
4. In the `snippets` folder, add `lib-image.liquid` the same way. If a snippet is already there from another Lib section, it is the same file; keep one copy.
5. Open **Customize** on the copy, choose **Add section** and pick **Lib · Collection banner**. Replace the sample content with your own and set the colors.
6. Preview the copy, then publish it when it looks right.

### With Shopify CLI

From your local theme folder, download the files and push only them to an unpublished theme (find its ID with `shopify theme list`):

```sh
curl -fsSL -o sections/lib-collection-banner.liquid https://lintelagency.com/resources/shopify-sections/files/lib-collection-banner.liquid
curl -fsSL -o snippets/lib-image.liquid https://lintelagency.com/resources/shopify-sections/files/lib-image.liquid
shopify theme push --theme <unpublished-theme-id> --only sections/lib-collection-banner.liquid --only snippets/lib-image.liquid
```

Never push to the live theme: always pass the ID of an unpublished theme and never use `--live` or `--allow-live`. Then add the section in the theme editor as above.

## Files

- [sections/lib-collection-banner.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-collection-banner.liquid): goes in `sections/`
- [snippets/lib-image.liquid](https://lintelagency.com/resources/shopify-sections/files/lib-image.liquid): goes in `snippets/`

## Questions

### Where do the title, description and image come from?

From the collection in Shopify admin (Products > Collections). On a collection template the section uses the page's collection; anywhere else you pick one. You can replace the collection image with your own desktop and mobile images in the section settings.

### Why is the title an H1?

On a collection page the collection name is the page's main heading, which helps search engines and screen readers. If your theme's collection template already has an H1, set the title tag to H2 so the page keeps one H1.

### What if a collection has no image?

The banner falls back to text only, with the title, count and description on the section background, so collections without a photo still get a tidy header.

### Does the product count update by itself?

Yes. It is Shopify's products_count for the collection, read when the page renders, and the words for one and several products are settings you can translate.

## Source

### sections/lib-collection-banner.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{%- comment -%}
  Collection banner: the header of a collection page. Collection title, description, product count
  and an optional breadcrumb, over the collection's image or beside it, or as text only. On a
  collection template it reads the page's collection; elsewhere it uses the collection picked in
  the settings. The collection image can be replaced, with a separate mobile image. No JavaScript.
  Depends on: snippets/lib-image.liquid
{%- endcomment -%}

{%- liquid
  assign s = section.settings
  assign c = s.collection
  if c == blank
    assign c = collection
  endif
  assign heading_tag = s.heading_tag | default: 'h1'
  assign eager = false
  if section.index <= 2
    assign eager = true
  endif

  assign img = s.image
  if img == blank and s.use_collection_image
    assign img = c.image
  endif
  assign layout = s.layout
  if img == blank and s.image_mobile == blank and request.design_mode == false
    assign layout = 'text'
  endif

  assign title = c.title
  if title == blank
    assign title = s.placeholder_title
  endif
-%}

{%- if c != blank or request.design_mode -%}
  <div
    class="lib-collection-banner lib-collection-banner--{{ s.section_width }}"
    {% if s.anchor_id != blank %}
      id="{{ s.anchor_id | handleize }}"
    {% endif %}
    data-show="{{ s.show_on }}"
    data-layout="{{ layout }}"
    data-height="{{ s.height }}"
    data-image-position="{{ s.image_position }}"
    data-pos="{{ s.content_position }}"
    data-pos-m="{{ s.content_position_mobile }}"
    {% if s.animate %}
      data-animate
    {% endif %}
    style="
      --lib-bg: {{ s.color_bg }};
      {% if s.color_bg_gradient != blank %}--lib-bg-image: {{ s.color_bg_gradient }};{% endif %}
      --lib-text: {{ s.color_text }};
      --lib-overlay-text: {{ s.color_overlay_text }};
      --lib-accent: {{ s.color_accent }};
      --lib-overlay: {{ s.overlay_opacity | divided_by: 100.0 }};
      --lib-pt: {{ s.padding_top }}px;
      --lib-pb: {{ s.padding_bottom }}px;
      --lib-pt-m: {{ s.padding_top_mobile }}px;
      --lib-pb-m: {{ s.padding_bottom_mobile }}px;
    "
  >
    <div class="lib-collection-banner__inner">
      {%- if layout != 'text' -%}
        <div class="lib-collection-banner__media">
          {%- render 'lib-image',
            image: img,
            image_mobile: s.image_mobile,
            class: 'lib-collection-banner__img',
            sizes: '100vw',
            eager: eager,
            placeholder: 'collection-1'
          -%}
        </div>
      {%- endif -%}

      <div class="lib-collection-banner__content">
        <div class="lib-collection-banner__copy" data-align="{{ s.text_alignment }}" data-align-m="{{ s.text_alignment_mobile }}">
          {%- if s.show_breadcrumb -%}
            <nav class="lib-collection-banner__crumbs" aria-label="{{ s.breadcrumb_label | escape }}">
              <ol role="list">
                <li><a href="{{ routes.root_url }}">{{ s.breadcrumb_home | escape }}</a></li>
                <li><span aria-current="page">{{ title | escape }}</span></li>
              </ol>
            </nav>
          {%- endif -%}

          <{{ heading_tag }} class="lib-collection-banner__heading lib-collection-banner__heading--{{ s.heading_size }}">
            {{- title | escape -}}
          </{{ heading_tag }}>

          {%- if s.show_count and c != blank -%}
            {%- assign count = c.products_count -%}
            <p class="lib-collection-banner__count">
              {{ count }}
              {% if count == 1 %}{{ s.count_singular | escape }}{% else %}{{ s.count_plural | escape }}{% endif %}
            </p>
          {%- endif -%}

          {%- if s.show_description -%}
            {%- if c.description != blank -%}
              <div class="lib-collection-banner__text">{{ c.description }}</div>
            {%- elsif c == blank -%}
              <div class="lib-collection-banner__text"><p>{{ s.placeholder_text | escape }}</p></div>
            {%- endif -%}
          {%- endif -%}
        </div>
      </div>
    </div>
  </div>
{%- endif -%}

{% stylesheet %}
  .lib-collection-banner {
    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-collection-banner__inner { position: relative; max-width: 1200px; margin: 0 auto; }
  .lib-collection-banner--full { padding-left: 0; padding-right: 0; }
  .lib-collection-banner--full .lib-collection-banner__inner { max-width: none; }
  @media (max-width: 749px) {
    .lib-collection-banner { padding-top: var(--lib-pt-m); padding-bottom: var(--lib-pb-m); }
    .lib-collection-banner[data-show='desktop'] { display: none; }
  }
  @media (min-width: 750px) {
    .lib-collection-banner[data-show='mobile'] { display: none; }
  }

  .lib-collection-banner__media { position: relative; overflow: hidden; background: color-mix(in srgb, var(--lib-text) 8%, transparent); }
  .lib-collection-banner__img { display: block; width: 100%; height: 100%; object-fit: cover; }
  svg.lib-collection-banner__img { fill: color-mix(in srgb, var(--lib-text) 22%, transparent); }

  /* Overlay: text over the image, at one of nine positions per device. */
  .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__inner {
    display: grid;
    min-height: var(--lib-h);
    overflow: hidden;
    --lib-h: 26rem;
  }
  .lib-collection-banner--page[data-layout='overlay'] .lib-collection-banner__inner { border-radius: 16px; }
  .lib-collection-banner[data-layout='overlay'][data-height='small'] .lib-collection-banner__inner { --lib-h: 18rem; }
  .lib-collection-banner[data-layout='overlay'][data-height='large'] .lib-collection-banner__inner { --lib-h: 36rem; }
  @media (max-width: 749px) {
    .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__inner { --lib-h: 20rem; }
    .lib-collection-banner[data-layout='overlay'][data-height='small'] .lib-collection-banner__inner { --lib-h: 14rem; }
    .lib-collection-banner[data-layout='overlay'][data-height='large'] .lib-collection-banner__inner { --lib-h: 28rem; }
  }
  .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__media,
  .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__content { grid-area: 1 / 1; }
  .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / var(--lib-overlay));
  }
  .lib-collection-banner[data-layout='overlay'] .lib-collection-banner__content {
    position: relative;
    z-index: 1;
    display: flex;
    padding: clamp(1.5rem, 5vw, 3.5rem);
    color: var(--lib-overlay-text);
  }
  .lib-collection-banner[data-layout='overlay'][data-pos$='left'] .lib-collection-banner__content { justify-content: flex-start; }
  .lib-collection-banner[data-layout='overlay'][data-pos$='center'] .lib-collection-banner__content { justify-content: center; }
  .lib-collection-banner[data-layout='overlay'][data-pos$='right'] .lib-collection-banner__content { justify-content: flex-end; }
  .lib-collection-banner[data-layout='overlay'][data-pos^='top'] .lib-collection-banner__content { align-items: flex-start; }
  .lib-collection-banner[data-layout='overlay'][data-pos^='middle'] .lib-collection-banner__content { align-items: center; }
  .lib-collection-banner[data-layout='overlay'][data-pos^='bottom'] .lib-collection-banner__content { align-items: flex-end; }
  @media (max-width: 749px) {
    .lib-collection-banner[data-layout='overlay'][data-pos-m$='left'] .lib-collection-banner__content { justify-content: flex-start; }
    .lib-collection-banner[data-layout='overlay'][data-pos-m$='center'] .lib-collection-banner__content { justify-content: center; }
    .lib-collection-banner[data-layout='overlay'][data-pos-m$='right'] .lib-collection-banner__content { justify-content: flex-end; }
    .lib-collection-banner[data-layout='overlay'][data-pos-m^='top'] .lib-collection-banner__content { align-items: flex-start; }
    .lib-collection-banner[data-layout='overlay'][data-pos-m^='middle'] .lib-collection-banner__content { align-items: center; }
    .lib-collection-banner[data-layout='overlay'][data-pos-m^='bottom'] .lib-collection-banner__content { align-items: flex-end; }
  }

  /* Split: image on one side, text on the other; stacked on mobile, image first. */
  .lib-collection-banner[data-layout='split'] .lib-collection-banner__inner { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
  .lib-collection-banner[data-layout='split'] .lib-collection-banner__media { aspect-ratio: 4 / 3; border-radius: 16px; }
  .lib-collection-banner--full[data-layout='split'] .lib-collection-banner__content { padding: 0 1rem; }
  @media (min-width: 750px) {
    .lib-collection-banner[data-layout='split'] .lib-collection-banner__inner { grid-template-columns: 1fr 1fr; }
    .lib-collection-banner[data-layout='split'][data-image-position='right'] .lib-collection-banner__media { order: 2; }
    .lib-collection-banner[data-layout='split'][data-height='small'] .lib-collection-banner__media { aspect-ratio: 16 / 9; }
    .lib-collection-banner[data-layout='split'][data-height='large'] .lib-collection-banner__media { aspect-ratio: 1; }
  }

  .lib-collection-banner--full[data-layout='text'] .lib-collection-banner__content { padding: 0 1rem; }

  /* Copy and alignment: desktop, then mobile override. */
  .lib-collection-banner__copy { display: flex; flex-direction: column; align-items: flex-start; text-align: left; max-width: 44rem; min-width: 0; }
  .lib-collection-banner__copy[data-align='center'] { align-items: center; text-align: center; }
  .lib-collection-banner__copy[data-align='right'] { align-items: flex-end; text-align: right; }
  .lib-collection-banner[data-layout='text'] .lib-collection-banner__copy[data-align='center'] { margin-inline: auto; }
  .lib-collection-banner[data-layout='text'] .lib-collection-banner__copy[data-align='right'] { margin-inline-start: auto; }
  @media (max-width: 749px) {
    .lib-collection-banner__copy[data-align-m='left'] { align-items: flex-start; text-align: left; margin-inline: 0; }
    .lib-collection-banner__copy[data-align-m='center'] { align-items: center; text-align: center; margin-inline: auto; }
    .lib-collection-banner__copy[data-align-m='right'] { align-items: flex-end; text-align: right; margin-inline: auto 0; }
  }

  .lib-collection-banner__crumbs ol { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0 0 1rem; padding: 0; list-style: none; font-size: 0.875rem; }
  .lib-collection-banner__crumbs li + li::before { content: '/'; margin-inline-end: 0.25rem; opacity: 0.55; }
  .lib-collection-banner__crumbs a { display: inline-block; padding-block: 0.15rem; color: inherit; text-decoration: underline; text-underline-offset: 0.2em; }
  .lib-collection-banner__crumbs a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 2px; }
  .lib-collection-banner__crumbs [aria-current] { opacity: 0.8; }

  .lib-collection-banner__heading {
    margin: 0;
    font-size: clamp(2rem, 4.4vw, 3.5rem);
    line-height: 1.06;
    letter-spacing: -0.025em;
    text-wrap: balance;
  }
  .lib-collection-banner__heading--small { font-size: clamp(1.6rem, 2.8vw, 2.25rem); }
  .lib-collection-banner__heading--medium { font-size: clamp(1.8rem, 3.4vw, 2.75rem); }
  .lib-collection-banner__heading--xlarge { font-size: clamp(2.5rem, 6vw, 4.75rem); }
  .lib-collection-banner__count {
    margin: 0.85rem 0 0;
    padding: 0.2rem 0.7rem;
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: 999px;
    font-size: 0.8125rem;
    font-weight: 600;
  }
  .lib-collection-banner[data-layout='split'] .lib-collection-banner__count,
  .lib-collection-banner[data-layout='text'] .lib-collection-banner__count { border-color: var(--lib-accent); color: var(--lib-accent); }
  .lib-collection-banner__text { margin-top: 1rem; max-width: 38rem; font-size: 1.0625rem; line-height: 1.6; opacity: 0.85; }
  .lib-collection-banner__text > :first-child { margin-top: 0; }
  .lib-collection-banner__text > :last-child { margin-bottom: 0; }
  .lib-collection-banner__text a { color: inherit; text-underline-offset: 0.2em; }

  @media (prefers-reduced-motion: no-preference) {
    .lib-collection-banner[data-animate] .lib-collection-banner__img { animation: lib-collection-banner-zoom 1.4s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
    .lib-collection-banner[data-animate] .lib-collection-banner__copy { animation: lib-collection-banner-in 0.8s 0.15s ease-out both; }
  }
  @keyframes lib-collection-banner-zoom { from { transform: scale(1.06); } }
  @keyframes lib-collection-banner-in { from { opacity: 0; transform: translateY(10px); } }
{% endstylesheet %}

{% schema %}
{
  "name": "Lib · Collection banner",
  "tag": "section",
  "class": "lib-section",
  "settings": [
    { "type": "header", "content": "Content" },
    {
      "type": "collection",
      "id": "collection",
      "label": "Collection",
      "info": "Leave empty on collection templates to use the page's collection. Pick one to use the banner on other pages."
    },
    {
      "type": "select",
      "id": "heading_tag",
      "label": "Title tag",
      "info": "H1 by default: on a collection page the title is the page's main heading. Use H2 when another section already has the H1.",
      "options": [
        { "value": "h1", "label": "H1" },
        { "value": "h2", "label": "H2" },
        { "value": "h3", "label": "H3" },
        { "value": "p", "label": "Paragraph" }
      ],
      "default": "h1"
    },
    {
      "type": "select",
      "id": "heading_size",
      "label": "Title size",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" },
        { "value": "xlarge", "label": "Extra large" }
      ],
      "default": "large"
    },
    { "type": "checkbox", "id": "show_description", "label": "Show collection description", "default": true },
    { "type": "checkbox", "id": "show_count", "label": "Show product count", "default": true },
    { "type": "text", "id": "count_singular", "label": "Product count word, one", "default": "product" },
    { "type": "text", "id": "count_plural", "label": "Product count word, more than one", "default": "products" },
    { "type": "checkbox", "id": "show_breadcrumb", "label": "Show breadcrumb", "default": false },
    { "type": "text", "id": "breadcrumb_home", "label": "Breadcrumb home link", "default": "Home" },
    { "type": "text", "id": "breadcrumb_label", "label": "Breadcrumb label for screen readers", "default": "Breadcrumb" },
    { "type": "text", "id": "placeholder_title", "label": "Title in the editor preview", "info": "Shown only in the theme editor when no collection is set.", "default": "Collection title" },
    { "type": "text", "id": "placeholder_text", "label": "Description in the editor preview", "default": "The collection's description from Shopify admin appears here." },

    { "type": "header", "content": "Image" },
    { "type": "checkbox", "id": "use_collection_image", "label": "Use the collection's image", "info": "Set in Products > Collections. A desktop image below replaces it.", "default": true },
    { "type": "image_picker", "id": "image", "label": "Desktop image", "info": "Optional." },
    { "type": "image_picker", "id": "image_mobile", "label": "Mobile image", "info": "Optional. Shown below 750px." },
    {
      "type": "select",
      "id": "layout",
      "label": "Layout",
      "info": "Without any image the banner shows text only.",
      "options": [
        { "value": "overlay", "label": "Text over the image" },
        { "value": "split", "label": "Image beside the text" },
        { "value": "text", "label": "Text only" }
      ],
      "default": "overlay"
    },
    {
      "type": "select",
      "id": "height",
      "label": "Banner height",
      "options": [
        { "value": "small", "label": "Small" },
        { "value": "medium", "label": "Medium" },
        { "value": "large", "label": "Large" }
      ],
      "default": "medium"
    },
    { "type": "range", "id": "overlay_opacity", "label": "Image overlay", "info": "Darkens the image so the text stays readable.", "min": 0, "max": 80, "step": 5, "unit": "%", "default": 35 },
    {
      "type": "select",
      "id": "image_position",
      "label": "Image side (beside the text)",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "right", "label": "Right" }
      ],
      "default": "right"
    },
    {
      "type": "select",
      "id": "content_position",
      "label": "Text position over the image on desktop",
      "options": [
        { "value": "top-left", "label": "Top left" },
        { "value": "top-center", "label": "Top center" },
        { "value": "top-right", "label": "Top right" },
        { "value": "middle-left", "label": "Middle left" },
        { "value": "middle-center", "label": "Middle center" },
        { "value": "middle-right", "label": "Middle right" },
        { "value": "bottom-left", "label": "Bottom left" },
        { "value": "bottom-center", "label": "Bottom center" },
        { "value": "bottom-right", "label": "Bottom right" }
      ],
      "default": "bottom-left"
    },
    {
      "type": "select",
      "id": "content_position_mobile",
      "label": "Text position over the image on mobile",
      "options": [
        { "value": "top-left", "label": "Top left" },
        { "value": "top-center", "label": "Top center" },
        { "value": "middle-left", "label": "Middle left" },
        { "value": "middle-center", "label": "Middle center" },
        { "value": "bottom-left", "label": "Bottom left" },
        { "value": "bottom-center", "label": "Bottom center" }
      ],
      "default": "bottom-left"
    },

    { "type": "header", "content": "Layout" },
    {
      "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": "Text alignment on desktop", "default": "left" },
    {
      "type": "select",
      "id": "text_alignment_mobile",
      "label": "Text 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": "#FFFDF9" },
    { "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_overlay_text", "label": "Text over the image", "default": "#FFFFFF" },
    { "type": "color", "id": "color_accent", "label": "Accent (product count)", "default": "#7A5C3E" },

    { "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": 24 },
    { "type": "range", "id": "padding_bottom", "label": "Bottom padding on desktop", "min": 0, "max": 200, "step": 4, "unit": "px", "default": 40 },
    { "type": "range", "id": "padding_top_mobile", "label": "Top padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 16 },
    { "type": "range", "id": "padding_bottom_mobile", "label": "Bottom padding on mobile", "min": 0, "max": 160, "step": 4, "unit": "px", "default": 28 },
    {
      "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": "Slow image zoom and text fade on load", "info": "Always off for visitors who prefer reduced motion.", "default": false }
  ],
  "presets": [
    { "name": "Lib · Collection banner" }
  ]
}
{% endschema %}
```

### snippets/lib-image.liquid

```liquid
{%- comment -%}
  MIT License · (c) 2026 Lintel · https://lintelagency.com/resources/shopify-sections
{%- endcomment -%}
{% doc %}
  Responsive image with optional art direction: a separate mobile image (below 750px),
  each honouring its own focal point from the theme editor. Falls back to a placeholder.

  @param {image} [image] - Desktop image (also used on mobile when no mobile image is set)
  @param {image} [image_mobile] - Mobile image, below 750px
  @param {string} [class] - Class for the img element
  @param {string} [sizes] - sizes attribute for the desktop image (default 100vw)
  @param {boolean} [eager] - Load immediately with high fetch priority (use for the first sections on a page)
  @param {string} [placeholder] - placeholder_svg_tag name when no image is set (default 'lifestyle-1')

  @example
  {% render 'lib-image', image: section.settings.image, image_mobile: section.settings.image_mobile, class: 'lib-hero__img', sizes: '(min-width: 990px) 50vw, 100vw', eager: true %}
{% enddoc %}

{%- liquid
  assign desktop = image
  if desktop == blank
    assign desktop = image_mobile
  endif
  assign img_sizes = sizes | default: '100vw'
  assign img_loading = 'lazy'
  assign img_priority = 'auto'
  if eager
    assign img_loading = 'eager'
    assign img_priority = 'high'
  endif
  assign art = false
  if image != blank and image_mobile != blank
    assign art = true
  endif
-%}

{%- if desktop != blank -%}
  <picture
    class="lib-picture{% if art %} lib-picture--art{% endif %}"
    {% if art %}
      style="--lib-pos-m: {{ image_mobile.presentation.focal_point | default: '50% 50%' }};"
    {% endif %}
  >
    {%- if art -%}
      <source
        media="(max-width: 749px)"
        srcset="
          {{ image_mobile | image_url: width: 375 }} 375w,
          {{ image_mobile | image_url: width: 750 }} 750w,
          {{ image_mobile | image_url: width: 1100 }} 1100w,
          {{ image_mobile | image_url: width: 1500 }} 1500w
        "
        sizes="100vw"
        width="{{ image_mobile.width }}"
        height="{{ image_mobile.height }}"
      >
    {%- endif -%}
    {{
      desktop
      | image_url: width: 2400
      | image_tag:
        class: class,
        loading: img_loading,
        fetchpriority: img_priority,
        sizes: img_sizes,
        widths: '600, 900, 1200, 1600, 2000, 2400'
    }}
  </picture>
{%- else -%}
  {{ placeholder | default: 'lifestyle-1' | placeholder_svg_tag: class }}
{%- endif -%}

{% stylesheet %}
  .lib-picture { display: contents; }
  @media (max-width: 749px) {
    /* image_tag sets the desktop focal point inline; the mobile image needs its own. */
    .lib-picture--art img { object-position: var(--lib-pos-m) !important; }
  }
{% endstylesheet %}
```

## License

MIT License, © 2026 Lintel. Free to use, change and ship in your own store or in client work; keep the license line at the top of each file.
