Topic summary
Goal: implement a Dawn theme section with three buttons (tabs) that switch a larger image and accompanying text.
Key points and latest updates:
- Multiple responders confirm it’s feasible but requires custom coding in a new section (Liquid is Shopify’s templating language; sections are reusable theme components). One asked whether it will go on the homepage or a specific page; OP hasn’t answered yet.
- Code option 1: a tabs-with-image.liquid example (HTML/Liquid + CSS/JS) using ARIA roles (tablist/tab/tabpanel) and keyboard navigation to swap visible panels. Note: the pasted snippet appears truncated/partially broken and would need cleanup to work as-is.
- Code option 2: a hair-clip-recommendation.liquid section with buttons updating title/description/image/review/link dynamically via JavaScript and Theme Editor settings. Note: this snippet also looks incomplete/truncated.
- No built-in Dawn section provides this tabbed switcher; an app-based alternative (Tapita: AI Sections and Blocks) can generate a similar section from a screenshot, with step-by-step workflow provided.
Status: no resolution yet. Next steps could be clarifying placement (home vs. page), fixing/completing one of the shared code snippets, or using the app; collaborators offered to help implement.
wanting to do a section like this in my store how would i go about doing this? has 3 buttons that open into a larger image like the one bellow with text using DAWN theme
Hey @JGBowie,
Creating a section same like the reference requires to do the custom code in your theme file.\
Could you please share your store url and the collab code in the p/m so that I can create the same one for you.
Thanks
Hi @JGBowie
Yes, this is possible with a custom section.
Just confirm — do you want to add this section on a page (like About/Product page), or on the homepage?
Best regards,
Devcoder ![]()
Hi,
Hope this will help
- Add a new section called tabs-with-image.liquid.
Code example
{% comment %}
Section: Tabs with Image
Theme: Dawn (v8+)
Purpose: Show N buttons (tabs). Clicking a button swaps the big image and text below.
File name suggestion: sections/tabs-with-image.liquid
{% endcomment %}
<section id="shopify-section-{{ section.id }}" class="tabs-with-image" data-section-id="{{ section.id }}">
<div class="page-width">
{% if section.settings.heading != blank %}
<h2 class="title h2 center">{{ section.settings.heading }}</h2>
{% endif %}
<div class="tabs-with-image__tabs" role="tablist" aria-label="{{ section.settings.heading | escape }}">
{% for block in section.blocks %}
{%- assign is_active = forloop.first -%}
<button
id="tab-{{ section.id }}-{{ forloop.index }}"
class="tabs-with-image__tab{% if is_active %} is-active{% endif %} button button--secondary"
role="tab"
aria-selected="{% if is_active %}true{% else %}false{% endif %}"
aria-controls="panel-{{ section.id }}-{{ forloop.index }}"
tabindex="{% if is_active %}0{% else %}-1{% endif %}"
data-index="{{ forloop.index0 }}"
{{ block.shopify_attributes }}
>
{{ block.settings.label | escape }}
</button>
{% endfor %}
</div>
<div class="tabs-with-image__panels">
{% for block in section.blocks %}
{%- assign is_active = forloop.first -%}
<div
id="panel-{{ section.id }}-{{ forloop.index }}"
class="tabs-with-image__panel{% if is_active %} is-active{% endif %}"
role="tabpanel"
aria-labelledby="tab-{{ section.id }}-{{ forloop.index }}"
{% unless is_active %}hidden{% endunless %}
>
<div class="tabs-with-image__grid">
<div class="tabs-with-image__media">
{% if block.settings.image != blank %}
{% render 'image',
image: block.settings.image,
widths: '360, 533, 720, 940, 1066, 1440',
sizes: '(min-width: 750px) 50vw, 100vw',
class: 'motion-reduce'
%}
{% else %}
<div class="placeholder">{{ 'image' | placeholder_svg_tag }}</div>
{% endif %}
</div>
<div class="tabs-with-image__content rte">
{% if block.settings.title != blank %}
<h3 class="h3">{{ block.settings.title | escape }}</h3>
{% endif %}
{% if block.settings.text != blank %}
{{ block.settings.text }}
{% endif %}
{% if block.settings.button_label != blank and block.settings.button_link != blank %}
<a href="{{ block.settings.button_link }}" class="button button--primary">{{ block.settings.button_label | escape }}</a>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<style>
.tabs-with-image { padding: var(--spacer, 3rem) 0; }
.tabs-with-image .title { margin-bottom: 1.25rem; }
.tabs-with-image__tabs {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: .75rem;
margin-bottom: 1.25rem;
}
.tabs-with-image__tab {
cursor: pointer;
white-space: nowrap;
}
.tabs-with-image__tab.is-active {
outline: 2px solid currentColor;
}
.tabs-with-image__panels { position: relative; }
.tabs-with-image__panel { width: 100%; }
.tabs-with-image__grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
align-items: center;
}
@media (min-width: 750px) {
.tabs-with-image__grid {
grid-template-columns: 1fr 1fr;
gap: 2rem;
}
}
.tabs-with-image__media img { width: 100%; height: auto; display: block; border-radius: 8px; }
.tabs-with-image__content .button { margin-top: 1rem; }
/* Smooth cross-fade */
.tabs-with-image__panel { transition: opacity .25s ease; }
.tabs-with-image__panel[hidden] { display: none; }
</style>
<script>
(function() {
const root = document.currentScript.closest('[data-section-id]');
const tabs = root.querySelectorAll('.tabs-with-image__tab');
const panels = root.querySelectorAll('.tabs-with-image__panel');
function activate(index, setFocus) {
tabs.forEach((tab, i) => {
const selected = i === index;
tab.classList.toggle('is-active', selected);
tab.setAttribute('aria-selected', selected ? 'true' : 'false');
tab.setAttribute('tabindex', selected ? '0' : '-1');
if (setFocus && selected) tab.focus();
});
panels.forEach((panel, i) => {
if (i === index) {
panel.removeAttribute('hidden');
panel.classList.add('is-active');
panel.style.opacity = 1;
} else {
panel.setAttribute('hidden', '');
panel.classList.remove('is-active');
panel.style.opacity = 0;
}
});
}
tabs.forEach((tab, i) => {
tab.addEventListener('click', () => activate(i, false));
tab.addEventListener('keydown', (e) => {
// Arrow navigation for accessibility
const key = e.key;
if (key === 'ArrowRight' || key === 'ArrowDown') {
e.preventDefault();
activate((i + 1) % tabs.length, true);
} else if (key === 'ArrowLeft' || key === 'ArrowUp') {
e.preventDefault();
activate((i - 1 + tabs.length) % tabs.length, true);
} else if (key === 'Home') {
e.preventDefault();
activate(0, true);
} else if (key === 'End') {
e.preventDefault();
activate(tabs.length - 1, true);
}
});
});
})();
</script>
{% schema %}
{
"name": "Tabs with image",
"tag": "section",
"class": "section",
"settings": [
{ "type": "text", "id": "heading", "label": "Heading", "default": "Explore features" }
],
"blocks": [
{
"type": "tab",
"name": "Tab",
"settings": [
{ "type": "text", "id": "label", "label": "Button label", "default": "Tab" },
{ "type": "image_picker", "id": "image", "label": "Image" },
{ "type": "text", "id": "title", "label": "Title", "default": "Title for this tab" },
{ "type": "richtext", "id": "text", "label": "Text", "default": "<p>Add some supporting details here.</p>" },
{ "type": "text", "id": "button_label", "label": "CTA label", "default": "Learn more" },
{ "type": "url", "id": "button_link", "label": "CTA link" }
]
}
],
"max_blocks": 6,
"presets": [
{
"name": "Tabs with image",
"blocks": [
{ "type": "tab", "settings": { "label": "Tab 1" } },
{ "type": "tab", "settings": { "label": "Tab 2" } },
{ "type": "tab", "settings": { "label": "Tab 3" } }
]
}
]
}
{% endschema %}
</section>
-
Insert the section in the Theme Editor.
-
Create 3 tab blocks: each has a button label, big image, title, and text.
-
Clicking a button swaps the big image and text—just like your example.
Hey @JGBowie , Welcome to shopify community!
You can create a section like this in the Dawn theme by adding a custom section file. I have the code ready - please use this code and add it to your theme under /sections/hair-clip-recommendation.liquid. This code is built with Liquid and fully dynamic, so you can easily change all text, images, and buttons directly from the theme editor. Thanks!
{% comment %}
Hair Clip Recommendation Section
Fully editable via Theme Editor — works in Dawn or any Online Store 2.0 theme.
{% endcomment %}
<section class="hair-clip-section" style="background-color: {{ section.settings.bg_color }}; padding: 40px 20px;">
<div class="container" style="max-width:900px; margin:0 auto;">
<div class="header" style="text-align:center; margin-bottom:40px;">
<h1 style="font-size:32px; color:#8b3a3a; margin-bottom:8px; font-weight:400;">{{ section.settings.title }}</h1>
<p style="font-size:14px; color:#b85c5c; font-style:italic;">{{ section.settings.subtitle }}</p>
</div>
<div class="button-group" style="display:flex; gap:12px; justify-content:center; margin-bottom:40px; flex-wrap:wrap;">
{% for block in section.blocks %}
<button class="hair-button{% if forloop.first %} active{% endif %}" data-index="{{ forloop.index0 }}" style="padding:12px 28px; border:2px solid #8b3a3a; background-color:transparent; color:#8b3a3a; border-radius:25px; cursor:pointer;">
{{ block.settings.button_label }}
</button>
{% endfor %}
</div>
<div class="modal active" id="modal" style="display:grid; grid-template-columns:1fr 1fr; gap:30px; background:#fff; border:3px solid #b85c5c; border-radius:12px; padding:30px;">
<div class="modal-image-section" style="text-align:center;">
<div class="modal-image" style="margin-bottom:16px;">
<img id="clipImage" src="{{ section.blocks[0].settings.image | img_url: '500x' }}" alt="{{ section.blocks[0].settings.button_label }}" style="width:100%; max-width:280px; height:auto; border-radius:8px;">
</div>
<div class="image-label" id="imageLabel" style="font-size:12px; color:#8b3a3a; font-style:italic;">{{ section.blocks[0].settings.image_label }}</div>
</div>
<div class="modal-content">
<div class="modal-subtitle" style="font-size:12px; color:#b85c5c; text-transform:uppercase; margin-bottom:8px;">{{ section.blocks[0].settings.subtitle }}</div>
<h2 class="modal-title" id="productTitle" style="font-size:22px; color:#8b3a3a; margin-bottom:16px;">{{ section.blocks[0].settings.title }}</h2>
<p class="modal-description" id="productDescription" style="font-size:14px; color:#555; line-height:1.6; margin-bottom:20px;">{{ section.blocks[0].settings.description }}</p>
<div class="rating" style="color:#d4a574; margin-bottom:12px;">★★★★★</div>
<p class="review" id="customerReview" style="font-size:13px; color:#666; font-style:italic; margin-bottom:12px;">{{ section.blocks[0].settings.review }}</p>
<p class="reviewer" style="font-size:12px; color:#999; margin-bottom:20px;">{{ section.blocks[0].settings.reviewer }}</p>
<a href="{{ section.blocks[0].settings.button_link }}" class="shop-button" style="background-color:#8b3a3a; color:#fff; padding:12px 24px; border-radius:25px; text-decoration:none;">
{{ section.blocks[0].settings.button_text }}
</a>
</div>
</div>
</div>
</section>
<script>
const clips = {{ section.blocks | json }};
const buttons = document.querySelectorAll('.hair-button');
const titleEl = document.getElementById('productTitle');
const descEl = document.getElementById('productDescription');
const imgEl = document.getElementById('clipImage');
const labelEl = document.getElementById('imageLabel');
const reviewEl = document.getElementById('customerReview');
const reviewerEl = document.querySelector('.reviewer');
const shopBtn = document.querySelector('.shop-button');
buttons.forEach((btn, index) => {
btn.addEventListener('click', () => {
buttons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const block = clips[index];
titleEl.textContent = block.settings.title;
descEl.textContent = block.settings.description;
imgEl.src = block.settings.image;
labelEl.textContent = block.settings.image_label;
reviewEl.textContent = block.settings.review;
reviewerEl.textContent = block.settings.reviewer;
shopBtn.textContent = block.settings.button_text;
shopBtn.href = block.settings.button_link;
});
});
</script>
{% schema %}
{
"name": "Hair Clip Recommendation",
"settings": [
{
"type": "text",
"id": "title",
"label": "Main Title",
"default": "Which clips suit your hair?"
},
{
"type": "text",
"id": "subtitle",
"label": "Subtitle",
"default": "Select your hair length to get matched with the right clips for you."
},
{
"type": "color",
"id": "bg_color",
"label": "Background color",
"default": "#f5f0e8"
}
],
"blocks": [
{
"type": "clip",
"name": "Hair Type Option",
"settings": [
{ "type": "text", "id": "button_label", "label": "Button Label", "default": "Short Hair — At or above shoulder length" },
{ "type": "image_picker", "id": "image", "label": "Product Image" },
{ "type": "text", "id": "image_label", "label": "Image Label", "default": "The Mini Claw" },
{ "type": "text", "id": "subtitle", "label": "Small Subtitle", "default": "We recommend:" },
{ "type": "text", "id": "title", "label": "Product Title", "default": "The Mini Claw & The Small Claw" },
{ "type": "textarea", "id": "description", "label": "Product Description", "default": "Perfect for shorter hair lengths or half-up hairstyles." },
{ "type": "textarea", "id": "review", "label": "Customer Review", "default": "\"I'm loving this hair claw! Great grip and style!\"" },
{ "type": "text", "id": "reviewer", "label": "Reviewer Name", "default": "- Ashley D. | Customer review" },
{ "type": "text", "id": "button_text", "label": "Button Text", "default": "Shop for Short Hair" },
{ "type": "url", "id": "button_link", "label": "Button Link" }
]
}
],
"max_blocks": 3,
"presets": [
{
"name": "Hair Clip Recommendation",
"category": "Custom Sections"
}
]
}
{% endschema %}
Result:
Best Regards,
Rajat
Yes, you can add that section on any where you want, but if you don’t know how to implement the section, you can let me know to help implement as like collaborator member.
Hello @JGBowie,
This is Sophia from Tapita: AI Sections and Blocks.
I supposed that it’s a bit tricky to find a pre-made section that matches the exact layout that you want. Dawn doesn’t include a built-in tabbed content/interactive switcher like this.
If you want to build a section like the example without coding, you can give a shot to our app, AI section builder. It lets you upload a screenshot and auto-generate a section that you can then edit and add to your theme:
Try this app: Tapita: AI Sections and Blocks
How to create it with AI:
-
Open Section AI inside the app.
-
Name your section (e.g., TptAi Tab Accordion).
-
Upload your screenshot (the sample design).
-
Let the AI analyze your layout.
-
Add your prompt or adjust the given prompt from AI if needed, describe:
- Overview
- Design
- Elements
- Interactive Features
- Click Create.
- View & edit the generated section.
- Add it directly to your Dawn theme.
If you need more adjustments, feel free to chat with our support team, they can help fine-tune the section for you.
Hope this helps!


