Fixing Overlap and Layout Bugs in Shopify AI-Generated Sections: A 2026 Debug Walkthrough
A debug guide for the layout bugs Shopify's AI section generator keeps producing: stacking overlaps, sticky-header collisions, and variant grids that won't render.
Devon freelances on Shopify themes, mostly for agencies that overflow work to him. A swimwear brand on Dawn had used Shopify’s Generate with AI button to spin up three new homepage sections, loved them in the theme editor, and pushed live. By morning the merchant was forwarding screenshots. On mobile, the hero copy was sitting on top of the sticky announcement bar. The product grid below it showed “6 variants available” and rendered exactly zero swatches.
Devon’s first instinct was the obvious one. Bump the z-index on the header, raise it again, raise it to 9999. Nothing moved.
That’s the tell. When stacking a bigger number does nothing, the problem isn’t the number. The AI had wrapped the section in a transform to do a subtle entrance animation, and that one property had quietly created a brand new stacking context that no header z-index could ever climb out of. We see this exact pattern on almost every store that ships AI-generated sections without a code review. So here’s the walkthrough we sent Devon, cleaned up.
The three layout bugs Shopify’s AI keeps generating
After auditing a couple dozen of these, the failures cluster into three shapes. Recognizing which one you’re staring at saves you an hour of poking at the wrong property.
The first is the overlap, where section content floats above a sticky header or announcement bar instead of scrolling behind it. A merchant flagged it on a community thread we read as “page content appears above sticky headers instead of behind them,” which is the symptom in one sentence. It’s a stacking-context bug nine times in ten.
The second is the variant grid that knows but won’t show. The block correctly detects the right number of variants, even prints the count, then renders an empty grid. Another merchant described it as the block detecting the right amount of variants but not displaying them. That one’s a data-binding mismatch in the loop.
Then there’s the quiet third one, the mobile snap. The section looks perfect on desktop and at the exact viewport the theme editor previews, then collapses or overflows the moment a real phone hits the 750px Shopify breakpoint. The AI wrote desktop CSS and skipped the responsive half.
Reading the section schema against the rendered HTML
Before you touch CSS, open the generated section file and read two things side by side: the {% schema %} block at the bottom and the actual Liquid markup above it.
The AI generates these somewhat independently, and they drift. You’ll find settings declared in the schema that the markup never references, and hardcoded values in the markup that should have been wired to settings. That drift is the root cause of half the “I can’t edit this in the theme editor” complaints downstream.
Inspect the rendered output in the browser too. Right-click the broken element, inspect, and walk up the DOM tree looking for any ancestor carrying transform, filter, perspective, will-change, or position with a z-index. Any one of those on a parent creates a containing context that traps everything inside it. The browser devtools won’t shout about it, you have to know to look. MDN’s stacking context reference is the page to keep open while you do this.
Once you can see the schema, the markup, and the live DOM at the same time, the bug usually names itself.
Z-index, sticky headers, and the stacking-context trap
Back to Devon’s overlap. The header had z-index: 100. The AI section had z-index: 1. By the numbers the header should win, and yet the section was painting on top.
The reason is that the section’s wrapper carried transform: translateY(0) for an animation. That transform creates a new stacking context, and inside that context the section’s children stack relative to each other, not relative to the header outside it. The header’s z-index of 100 is meaningless because the two elements live in different stacking universes. You cannot raise a number across that boundary.
There are two clean fixes and one hack to avoid.
The structural fix is to remove the unnecessary transform from the wrapper, or move the animation to a child element that doesn’t need to escape the context. If the entrance animation isn’t load-bearing, deleting it is the cleanest path and it speeds up the section too.
The alternative, when you need the transform, is to make sure the sticky header itself lives in a stacking context that’s a sibling or ancestor of the section’s context, with a higher z-index at that shared level. In Dawn that usually means confirming the header group wrapper, not just the inner header, carries the z-index. Raise it where the contexts actually meet.
The hack to avoid is slapping position: relative; z-index: 9999 on random elements until something looks right. It’ll appear fixed on the page you’re testing and break on the next one, because you never addressed which context owns the element. And the next dev who opens the file will have no idea why there’s a 9999 sitting there.
When the product-grid block counts variants but won’t render them
The variant grid bug looks like data is missing. It isn’t. The count is right, remember, so the data is loading fine. The markup is just iterating the wrong object.
A common AI mistake is generating a loop over product.variants to build swatches while binding the swatch markup to product.options_with_values fields, or vice versa. The loop runs the correct number of times, which is why the count is accurate, but each iteration reads a property that doesn’t exist on the object it’s looping, so every swatch renders empty.
{%- for variant in product.variants -%}
<span class="swatch">{{ option.value }}</span>
{%- endfor -%}
There’s the bug in miniature. The loop variable is variant, but the markup reaches for option.value, which is null on every pass. You either fix the reference to variant.title (or the specific option you want), or you restructure to loop over product.options_with_values and read each value inside. Decide which you actually want, color swatches usually want the option values, not every variant permutation, then make the loop and the markup agree.
The deeper lesson is that the AI optimizes for output that compiles, not output that renders what you meant. Liquid will happily print nothing for a null property without throwing an error, so these slip through the generator’s own checks. You have to read the loop.
The Liquid the AI skips that snaps your mobile breakpoints
Shopify’s mobile breakpoint sits at 750px, and the AI generator is weirdly inconsistent about respecting it. It’ll write a polished desktop grid and either omit the mobile media query entirely or write one that targets the wrong breakpoint.
The result is the section that looks flawless in the editor preview, because the editor previews at a desktop-ish width, then overflows its container or stacks wrong the instant a real phone loads it. The merchant sees it before you do, which is the worst order for finding a bug.
The fix is to add the responsive rules the generator left out, scoped to the Shopify breakpoint.
@media screen and (max-width: 749px) {
.ai-section__grid {
grid-template-columns: 1fr;
padding-inline: 1rem;
}
}
Two habits prevent the whole class of bug. Always test the section at 375px, not just the editor preview, before you call it done. And prefer intrinsic layout, grid-template-columns: repeat(auto-fit, minmax(...)), over fixed column counts, so the section degrades gracefully even when the AI forgets the media query. Shopify’s own section and block documentation is worth a skim if you want the breakpoint conventions straight from source.
Adding the settings the AI forgot so merchants can self-serve
Here’s the bug that isn’t a visual bug, but generates the most support tickets. The AI hardcodes padding, colors, heading text, and column counts directly into the markup instead of wiring them to schema settings. The section looks fine. The merchant just can’t change a single thing about it without calling you back.
Every value a merchant might reasonably want to adjust should be a setting. Run the generated section and move the hardcoded values into the schema, then reference them in the markup.
{% schema %}
{
"name": "Featured grid",
"settings": [
{ "type": "range", "id": "padding_top", "label": "Top padding",
"min": 0, "max": 100, "step": 4, "unit": "px", "default": 40 }
]
}
{% endschema %}
Then style="padding-top: {{ section.settings.padding_top }}px" in the markup instead of a baked-in 40px. It’s tedious, and it’s the difference between a section the merchant owns and a section that owns you. Do it once at build time or do it ten times at support time.
A QA pass for every AI section before you publish
Treat anything the generator produces as a junior dev’s first draft, not a finished section. Before it goes live, run the same short pass every time.
Read the schema against the markup and confirm every setting is referenced and every hardcoded value that should be a setting is one. Inspect the live DOM for stray transform, filter, or position on wrappers, and confirm nothing creates an unintended stacking context near a sticky element. Load the page at 375px and 1440px, not just the editor preview, and watch the breakpoint at 749px specifically. Click through every variant on a product block and confirm swatches actually render, not just count. Tab through interactive elements for basic keyboard access, since the AI almost never adds focus states. And check the section renders correctly when it’s empty, because merchants will publish it before adding content.
Six checks, maybe ten minutes. It catches every bug in this post before a customer ever sees it.
What we keep telling clients
The AI section generator is genuinely useful, and it is not a replacement for a dev who reads the output. Those two things are both true, and the agencies that get burned are the ones who treat “Generate with AI” as the last step instead of the first.
What the generator gives you is a fast, decent-looking scaffold. What it doesn’t give you is correct stacking contexts, working variant loops, responsive Liquid, or an editable schema. Those are exactly the things that separate a section that survives contact with a real storefront from one that’s back in your inbox by morning. So the workflow that works is generate fast, then audit hard.
None of these bugs are mysterious once you know the shape. Overlap is a stacking context. Empty grids are a loop binding. Mobile snap is a missing media query. Uneditable sections are a hardcoded value that should’ve been a setting. You’re not debugging AI, you’re debugging the same four CSS and Liquid mistakes, just produced faster than a human would produce them.
Devon shipped the swimwear fixes in an afternoon. He pulled the transform off the hero wrapper, repointed the variant loop, added the 749px media query, and moved six hardcoded values into the schema so the merchant could stop emailing him about padding. The store’s been quiet since. Which, for a freelancer, is the whole point.
Questions we get every week
Why does raising the z-index never fix the overlap?
Because the element is trapped in a stacking context created by a transform, filter, or similar property on a parent. Z-index only orders elements within the same context, so a higher number can’t lift a child out of a context that sits below the header. Remove or relocate the property that created the context, and then z-index behaves the way you expect.
Is it faster to fix the AI section or rewrite it by hand? For a single section with one or two of these bugs, fixing is faster, you keep the scaffold and patch the four usual suspects. We only rewrite from scratch when the schema and markup have drifted badly, maybe one section in five.
Will these bugs show up on themes other than Dawn? Yes. The stacking-context, variant-loop, and breakpoint bugs come from how the generator writes code, not from the host theme. The specific selectors and the breakpoint wrapper names differ between themes, but the patterns and the fixes are the same across any Online Store 2.0 theme.
If your team is shipping AI-generated theme sections and the bug reports are piling up, send us a broken section at monkeyman.agency/contact and we’ll send back the exact stacking-context, loop, and schema fixes we’d make.