no horizontal scrolling, no clipped content
When users increase the browser font size to 200 percent, a store must remain fully readable and usable, without content being cut off or requiring sideways scrolling. This article shows in practical terms how rem-based units, reflowing layouts, an unlocked viewport and targeted zoom tests make that reliable in Magento and Hyva stores, without costly special-case fixes.
Table of Contents
- 1. Why 200 percent zoom is a WCAG requirement
- 2. rem and em instead of fixed pixel values
- 3. Reflow: layout without horizontal scrolling
- 4. Avoiding viewport meta zoom locks
- 5. Tailwind CSS and rem-based utility classes
- 6. Navigation and header at high zoom
- 7. Forms, buttons and touch targets under zoom
- 8. Testing zoom behavior systematically
- 9. Common layout breakage compared
- 10. Summary
- 11. FAQ
1. Why 200 percent zoom is a WCAG requirement
Success Criterion 1.4.4 Resize Text in WCAG 2.1 requires that text can be enlarged up to 200 percent without loss of content or functionality. This is not an optional nicety for people with low vision in the narrow sense, it affects a much larger group: older users, people with temporary vision impairment after eye surgery, and anyone working on a small high-resolution laptop display who increases the system font size. Ignoring this requirement excludes not just an edge case but a meaningful share of the target audience of any online store.
Technically, 200 percent zoom means either a browser zoom function (Ctrl and Plus) or an increased base font size at the operating system level, which affects the rem unit in the browser. Both paths must work. In addition, Criterion 1.4.10 Reflow requires that content remain usable without horizontal scrolling at a viewport width of 320 CSS pixels, which corresponds to a 1280 pixel screen at 400 percent zoom, with the exception of elements that must remain two dimensional, such as tables, maps or diagrams. These two criteria together form the technical foundation for everything that follows in this article.
It is important to distinguish browser zoom from operating-system text-size zoom. Browser zoom scales the entire page, including layout and images, proportionally, while pure text size changes in some browsers affect only text and leave container widths unchanged. A robust layout must handle both cases, because users switch between both methods depending on the device.
2. rem and em instead of fixed pixel values
The most common cause of broken zoom behavior is text set in fixed pixel values. A font-size: 16px declaration ignores the default font size configured by the user in the browser entirely, while font-size: 1rem scales relative to the root font size, which is typically 16 pixels but can be set by the user to 20, 24 or more pixels. The effect is not limited to body text: headings, buttons, form fields and icon labels must also scale relatively, otherwise the layout ends up visually inconsistent, with body text growing while navigation and buttons stay fixed.
em and rem differ in their reference point: em refers to the font size of the parent element and compounds when nested, while rem is always calculated relative to the root font size of the html element. For spacing inside a component that should grow proportionally with text size, such as padding inside a button, em is often the right choice. For global sizes such as heading hierarchies and container widths, rem is preferable because it stays predictable regardless of nesting depth.
/* WRONG: fixed pixel values ignore the user's browser font-size setting */
.product-title {
font-size: 24px;
line-height: 32px;
margin-bottom: 16px;
}
.btn-primary {
font-size: 14px;
padding: 8px 16px;
}
/* RIGHT: rem for global sizing, scales with the user's root font-size */
:root {
font-size: 100%; /* respects browser/OS default, usually 16px */
}
.product-title {
font-size: 1.5rem; /* 24px at default, scales with zoom */
line-height: 1.35; /* unitless line-height also scales correctly */
margin-bottom: 1rem;
}
/* em for component-internal spacing that should track the local font-size */
.btn-primary {
font-size: 0.875rem;
padding: 0.6em 1.2em; /* grows proportionally if btn font-size changes */
}
A special case involves images with fixed pixel heights next to icon-text combinations. If an SVG icon with height: 16px sits next to text that grows to 24 pixels via rem, high zoom levels produce a visually unbalanced icon. Icons in such contexts should be scaled using em or 1lh (line-height unit) so they grow with the surrounding text instead of staying rigid.
3. Reflow: layout without horizontal scrolling
Reflow means that page content wraps as the zoom level increases, instead of keeping a fixed width and forcing horizontal scrolling. The most common cause of broken reflow is fixed pixel widths on containers, such as width: 1200px instead of max-width: 75rem. At 200 percent zoom on a 1280 pixel viewport, only about 640 CSS pixels of effective width remain, and a container rigidly set to 1200 pixels then forces horizontal scrolling across the entire page, which is an explicit violation of WCAG 1.4.10.
The solution lies in flexbox and grid layouts with relative units and flex-wrap, or responsive grid templates that automatically switch from multi-column to single-column as the effective viewport width shrinks. CSS Grid with grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)) handles this wrapping without additional media queries, because minmax defines the minimum width in rem and therefore also scales with zoom.
Another common pitfall is long unbroken strings such as product SKUs, long URLs or email addresses inside table cells. Without overflow-wrap: break-word or word-break: break-word, such strings burst out of the cell width and force horizontal scrolling, even when the rest of the layout reflows correctly. This property should be applied project-wide to text containers that render user input or variable-length data.
/* WRONG: fixed pixel container width breaks reflow at 200% zoom */
.page-wrapper {
width: 1200px;
margin: 0 auto;
}
.product-grid {
display: flex;
width: 1200px; /* forces horizontal scroll once effective viewport shrinks */
}
/* RIGHT: max-width in rem plus a reflowing grid */
.page-wrapper {
max-width: 75rem; /* 1200px at default root font-size, but scales with zoom */
margin: 0 auto;
padding-inline: 1rem;
}
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: 1.5rem;
}
/* Prevent long unbreakable strings from forcing horizontal scroll */
.sku, .product-url, .customer-email {
overflow-wrap: break-word;
word-break: break-word;
}
4. Avoiding viewport meta zoom locks
A direct WCAG violation that keeps turning up in older projects is disabling zoom via the viewport meta tag: <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">. The attributes maximum-scale=1.0 and user-scalable=no prevent mobile users from zooming with a pinch gesture, and directly and measurably violate WCAG 1.4.4. This setting was historically chosen to prevent accidental scaling around form inputs, but it is not acceptable from an accessibility standpoint.
The correct viewport tag for a Hyva theme is simply <meta name="viewport" content="width=device-width, initial-scale=1.0">, without maximum-scale and without user-scalable=no. If the base theme includes these restrictions, the corresponding .phtml block should be overridden through layout XML rather than manipulating the meta tag afterward with JavaScript, which can cause race conditions during initial rendering.
5. Tailwind CSS and rem-based utility classes
Tailwind CSS defaults to rem for nearly all sizing utilities, including font sizes (text-sm, text-lg), spacing (p-4, gap-6) and widths (max-w-3xl). That is a structural advantage over hand-written CSS, because developers working in a Hyva theme rarely introduce fixed pixel values by accident as long as they stick to the default utilities. Problems arise once arbitrary values with explicit pixel specifications are used, such as text-[16px] or w-[320px], which bypass the rem base and reproduce the same zoom problems as hand-written CSS.
With Tailwind v4's CSS-first configuration, it is worth enforcing a project-wide rule in code review: arbitrary pixel values for typography and layout widths should generally be avoided and replaced with the predefined scale or rem-based arbitrary values such as text-[1rem]. For icon sizes that should always look visually the same size regardless of zoom, such as status icons in a toolbar with a fixed height, a deliberate pixel value is sometimes justified but should be documented as an explicit exception.
<!-- WRONG: arbitrary pixel values bypass Tailwind's rem-based scale -->
<h3 class="text-[18px] leading-[24px] mb-[12px]">Product details</h3>
<div class="w-[960px] mx-auto">...</div>
<!-- RIGHT: default Tailwind scale, rem-based and zoom-safe -->
<h3 class="text-lg leading-6 mb-3">Product details</h3>
<div class="max-w-5xl mx-auto px-4">...</div>
<!-- Acceptable exception: rem-based arbitrary value when the scale doesn't fit -->
<span class="text-[1.375rem] font-bold">CHF 249.00</span>
6. Navigation and header at high zoom
Sticky headers and mega menus are the components most likely to break at 200 percent zoom, because they are often implemented with a fixed pixel height to avoid layout shift. A header with height: 64px clips the logo, search field or cart icon once text enlargement means the content needs more vertical space than the fixed height allows. The robust alternative is a min-height in rem instead of a rigid height, combined with flex-wrap on the child elements so that the search field and icons can wrap onto a second line when needed.
In mega menus with a horizontal arrangement of many categories, zoom frequently causes menu items to be clipped or overlap. An Alpine.js-driven dropdown menu, as is common in Hyva themes, should not rely on fixed pixel values for max-width when calculating available width, but instead use vw units with a fallback or rem-based widths that respond to actually available space. In practice, it works well to switch the mega menu to a mobile accordion layout automatically once the effective viewport width, measured with a matchMedia query, drops below a threshold, rather than trying to squeeze the desktop layout into less space.
// Alpine.js component: switch mega-menu to accordion layout
// when the *effective* viewport (post-zoom) drops below the desktop breakpoint
document.addEventListener('alpine:init', () => {
Alpine.data('megaMenu', () => ({
isCompact: false,
init() {
const mq = window.matchMedia('(max-width: 64rem)'); // rem-based, zoom-aware
this.isCompact = mq.matches;
mq.addEventListener('change', (e) => {
this.isCompact = e.matches;
});
},
}));
});
7. Forms, buttons and touch targets under zoom
Forms are especially error-prone under zoom testing, because input fields, labels and error messages all grow at once and can easily lose their alignment to one another. A label positioned with position: absolute and a fixed pixel offset above an input frequently overlaps the input text at 200 percent zoom, because label and input do not shift proportionally in relation to each other. The robust solution is a natural document flow with flex flex-col gap-2 instead of absolute positioning, so that the label and field always keep the correct spacing regardless of text size.
Touch targets must be at least 44 by 44 CSS pixels per WCAG 2.5.5, and this requirement must not be undercut under zoom. A button whose height is fixed at height: 32px stays visually small under zoom while the surrounding text grows, resulting in a button that is disproportionate and hard to hit. With min-height: 2.75rem (44 pixels at default size) and padding in em, buttons grow along with zoom and stay comfortably usable at all times. Concretely: instead of <label class="absolute -top-2 left-3"> with a fixed pixel offset, use a simple <div class="flex flex-col gap-2"> with the label and input in natural flow, and instead of class="h-8", use class="min-h-[2.75rem]" on the input field.
8. Testing zoom behavior systematically
Zoom testing belongs in every accessibility audit and can be carried out reproducibly with a few simple steps. In Chrome and Firefox, Ctrl and + or Ctrl and - change the zoom level in 10 percent increments, while Chrome DevTools' command menu (Ctrl Shift P, then "zoom") allows entering 200 percent directly. It is important to test not only at 200 percent, but also at 100, 150 and 400 percent, to see at exactly which level a layout starts to break.
For the reflow test per WCAG 1.4.10, DevTools' responsive mode simulates a viewport width of 320 pixels with 100 percent zoom active at the same time, which matches the effect of 400 percent zoom on a standard screen. Automated tools such as axe DevTools or Lighthouse check contrast and semantic structure, but do not reliably detect broken zoom layouts, which is why a manual visual test by a real person remains indispensable.
The CI pipeline can be extended with an automated baseline check that uses Playwright to set the viewport to 320 by 640 pixels and checks for horizontal scrolling by comparing document.documentElement.scrollWidth against document.documentElement.clientWidth. This does not replace a full manual zoom test, but it catches coarse regressions early, before they reach production.
// Playwright: basic reflow regression check for CI
const { test, expect } = require('@playwright/test');
test('no horizontal scroll at 320px viewport (WCAG 1.4.10 reflow)', async ({ page }) => {
await page.setViewportSize({ width: 320, height: 640 });
await page.goto('https://shop.example.com/product/example-sku');
const hasHorizontalScroll = await page.evaluate(() => {
return document.documentElement.scrollWidth > document.documentElement.clientWidth;
});
expect(hasHorizontalScroll).toBe(false);
});
9. Common layout breakage compared
The following table summarizes the most common failure sources that keep turning up in zoom audits of Magento and Hyva stores, together with the corresponding robust alternative.
| Area | Breaks under zoom | Robust solution | WCAG reference |
|---|---|---|---|
| Font sizes | font-size: 14px |
font-size: 0.875rem |
1.4.4 Resize Text |
| Container width | width: 1200px |
max-width: 75rem |
1.4.10 Reflow |
| Viewport meta | user-scalable=no |
no maximum-scale, no user-scalable | 1.4.4 Resize Text |
| Header height | height: 64px |
min-height: 4rem + flex-wrap |
1.4.10 Reflow |
| Buttons / touch targets | height: 32px |
min-height: 2.75rem |
2.5.5 Target Size |
| Long strings (SKU, URL) | no wrapping, bursts cell | overflow-wrap: break-word |
1.4.10 Reflow |
Notably, almost all of these problems trace back to the same root cause: fixed pixel values in places where relative units would let the layout grow proportionally. A single consistently applied pattern, rem and em instead of px for everything except border widths and a few deliberate exceptions, prevents most of these errors from the start.
Mironsoft
Accessibility, WCAG audits and accessible Magento frontends
Does your store hold up under a 200 percent zoom test?
We audit Magento and Hyva frontends for reflow, rem-based typography and zoom behavior against WCAG 1.4.4 and 1.4.10, and deliver concrete fixes for layout, navigation and forms instead of generic checklists.
Zoom audit
Manual testing at 100, 150, 200 and 400 percent zoom across all core pages
rem refactoring
Replacing fixed pixel values in Tailwind and Hyva templates with rem and em
CI integration
Integrating Playwright reflow checks into the deploy pipeline
10. Summary
Responsive text and zoom support up to 200 percent is not a nicety, it is an explicit WCAG requirement that affects a large and growing group of users. The technical foundation is easy to name, even though consistent implementation takes discipline: rem and em instead of fixed pixel values for text, spacing and container widths, an unmodified viewport meta tag without zoom locks, and flexbox and grid layouts that automatically reflow instead of scrolling horizontally as the effective viewport width shrinks.
Tailwind CSS makes implementation easier, because its default utility scale is already based on rem. The largest remaining source of errors is arbitrary pixel values and hand-written CSS with fixed sizes for headers, buttons and absolutely positioned form labels. Systematic zoom testing at multiple zoom levels, complemented by automated reflow checks in the CI pipeline, catches most regressions before they go live.
Responsive Text and Zoom Support up to 200 Percent, the key points at a glance
WCAG foundation
1.4.4 Resize Text requires 200 percent zoom without loss of function, 1.4.10 Reflow requires no horizontal scrolling at 320 CSS pixels width.
rem instead of px
Define font sizes, spacing and container widths in rem and em so they grow along with the user's zoom.
Viewport meta
Never set maximum-scale or user-scalable=no. Pinch-to-zoom must work on every device.
Testing
Test manually at 100, 150, 200 and 400 percent, and integrate automated Playwright reflow checks into the CI pipeline.