Common accessibility issues in Squarespace stores and how to fix them
Squarespace is a popular platform for small and mid-sized e-commerce stores, particularly in fashion, home goods, and specialty retail. Its visual editor makes launching a store fast. But because Squarespace is a closed platform, store owners cannot edit the underlying theme templates the way they can with Shopify or WooCommerce. The result is a set of accessibility issues baked into the platform's own code, some of which can be patched with Code Injection and some of which require Squarespace to fix on their end.
This guide covers the issues that appear most consistently when we scan Squarespace sites. For each one, we explain what the problem is, what the underlying cause is, and what you can realistically do about it.
How customization works in Squarespace
Squarespace gives you three meaningful levers for code-level changes. The first is the Style Editor (Design, then Site Styles in the Squarespace 7 panel), which controls visual properties like fonts and colors. The second is Custom CSS (Design, then Custom CSS), which lets you write CSS rules applied across the site. The third is Code Injection (Settings, then Advanced, then Code Injection), which lets you insert HTML and JavaScript into the global header, the global footer, or individual pages.
For accessibility fixes, Code Injection is the primary tool. You can use footer injection to run JavaScript after the page loads, adding aria attributes or label elements that Squarespace's templates omit. This approach is a patch on top of platform-generated markup, not a clean fix at the source, but it is often the only option available.
1. Icon-only buttons in the site header
Squarespace's built-in navigation header includes icon buttons for cart, search, and account access. In most templates, these are SVG icons inside button elements with no visible text and no aria-label attribute. A screen reader user navigating the header hears "button" repeated for each one, with no way to tell what each button does.
Squarespace generates markup that looks roughly like this:
<!-- Typical Squarespace header icon button -->
<button class="header-actions__icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<!-- cart icon paths -->
</svg>
</button>
The svg has aria-hidden="true", so the icon is correctly hidden from the accessibility tree. But no text alternative replaces it, so the button's accessible name is empty. Axe-core flags this as a button-name violation (WCAG 4.1.2).
The fix via Code Injection (paste into the Footer section so it runs after the DOM is ready):
<script>
document.addEventListener('DOMContentLoaded', function () {
// Map button class fragments to accessible names.
// Inspect your site's HTML to confirm the exact class names.
var labelMap = [
{ selector: '.header-actions__icon--cart', label: 'Open cart' },
{ selector: '.header-actions__icon--search', label: 'Open search' },
{ selector: '.header-actions__icon--account', label: 'Account' },
];
labelMap.forEach(function (entry) {
document.querySelectorAll(entry.selector).forEach(function (btn) {
if (!btn.getAttribute('aria-label')) {
btn.setAttribute('aria-label', entry.label);
}
});
});
});
</script>
2. Images without alt text
Squarespace does not require alt text when you add an image block. If you upload an image and do not set alt text, the image renders with an empty alt attribute or, in some cases, the filename as the alt value. A filename like "IMG_4892.jpg" or "product-hero-final-v3.png" is not useful alt text for anyone, and the filename pattern can generate an image-alt violation on automated scans.
For content images (product photos, editorial images, banners), the fix is to set alt text manually in the image block settings. In the Squarespace editor, click the image block, go to the Design or Content tab, and fill in the alt text field. Every image that conveys information about the product or content needs descriptive alt text. A product image of a blue canvas tote bag should say "Navy canvas tote bag, front view" -- not "Canvas tote" and not the filename.
For purely decorative images (background textures, divider lines, abstract shapes that are visual embellishment only), the alt field should be left empty. An empty alt attribute (alt="") tells assistive technology to skip the image. A filename as alt text does not; the screen reader reads it aloud.
If your Squarespace commerce catalog has a large number of products, this requires going through the media library or each product's settings to verify alt text. There is no bulk-edit path inside Squarespace.
3. Newsletter blocks without form labels
Squarespace's built-in Newsletter block is a common feature on homepage and footer sections. It typically presents a single email input with a placeholder ("Enter your email" or similar) and a submit button. In many implementations, there is no visible label element programmatically associated with the input.
Placeholder text is not a label. When the field is empty, a screen reader may announce "Enter your email, edit text" -- which sounds like useful information. But placeholder text disappears the moment someone begins typing, and it is not consistently read by all screen reader and browser combinations. WCAG success criterion 1.3.1 requires a programmatic association between form inputs and their labels, which placeholder alone does not satisfy.
The Squarespace Form block (a separate component from the Newsletter block) does generate visible labels by default. The Newsletter block is the one that most commonly fails. A fix via Code Injection:
<script>
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.newsletter-form__input').forEach(function (input) {
if (!input.getAttribute('aria-label') && !input.getAttribute('aria-labelledby')) {
input.setAttribute('aria-label', 'Email address');
}
});
});
</script>
This adds an aria-label to any newsletter input that does not already have a label association. The selector (.newsletter-form__input) is representative; verify it against your site's rendered HTML. If your Squarespace version generates a different class, update the selector accordingly.
A more robust fix injects a visually-hidden label element before each input and links it with a for/id pair, which satisfies the requirement more cleanly than aria-label for some screen reader and browser combinations:
<style>
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border: 0;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.newsletter-form__input').forEach(function (input, i) {
var id = 'newsletter-email-' + i;
input.setAttribute('id', id);
var label = document.createElement('label');
label.setAttribute('for', id);
label.className = 'visually-hidden';
label.textContent = 'Email address';
input.parentNode.insertBefore(label, input);
});
});
</script>
4. Gallery lightbox focus management
Squarespace's gallery blocks (Grid, Slideshow, Stacked, and Masonry layouts) can open images in a lightbox overlay when clicked. The lightbox is modal in function: it appears above the page and contains navigation controls and a close button. WCAG success criterion 2.4.3 requires that when a modal opens, keyboard focus moves into it; when the modal closes, focus returns to the element that triggered it.
Squarespace's gallery lightbox does not always satisfy this requirement. Focus may remain on the gallery item that was clicked, leaving keyboard users unable to navigate the lightbox controls without tabbing through the entire page. The close button may not be reachable by keyboard at all, depending on the template version.
This is a platform-level issue in Squarespace's own JavaScript. A Code Injection workaround can partially address it by listening for lightbox open/close events and managing focus explicitly, but this requires identifying the specific DOM events Squarespace fires and the correct container element. The approach varies significantly across Squarespace template families (7.0 and 7.1 templates use different underlying code).
If gallery lightbox accessibility is a priority for your store, the most reliable path is to disable the lightbox (in gallery block settings) and link each image to its own product or detail page instead. This eliminates the modal focus problem entirely and gives each image a permanent URL.
5. Social media icon links in the footer
Squarespace provides built-in social link blocks that render icons for Instagram, Facebook, TikTok, Pinterest, and other platforms. These are almost always SVG icons inside anchor elements with no visible link text and no aria-label. A screen reader user encounters a list of links with no indication of where each one goes.
Axe-core reports these as link-name violations (WCAG 2.4.4). The links are functional -- they navigate to the correct URL -- but they are not labeled in a way that a screen reader user can understand without activating them.
A fix via Code Injection that labels social links by their href destination:
<script>
document.addEventListener('DOMContentLoaded', function () {
var platformNames = {
'instagram.com': 'Instagram',
'facebook.com': 'Facebook',
'tiktok.com': 'TikTok',
'pinterest.com': 'Pinterest',
'twitter.com': 'X (Twitter)',
'x.com': 'X (Twitter)',
'youtube.com': 'YouTube',
'linkedin.com': 'LinkedIn',
};
document.querySelectorAll('.sqs-svg-icon--wrapper a, .social-links a').forEach(function (link) {
if (link.getAttribute('aria-label')) return;
var href = link.getAttribute('href') || '';
for (var domain in platformNames) {
if (href.indexOf(domain) !== -1) {
link.setAttribute('aria-label', platformNames[domain]);
break;
}
}
});
});
</script>
Update the selectors to match your template's rendered markup. You can find the correct selectors by inspecting a social icon link in your browser's DevTools.
6. Skip navigation link
Most Squarespace templates do not include a skip navigation link -- a hidden link at the very top of the page that allows keyboard users to bypass the site header and jump directly to the main content. Without it, a screen reader or keyboard-only user must tab through every navigation item on every page before reaching the content they came to read.
The WCAG 2.4.1 bypass blocks success criterion requires a mechanism for this. A skip link is the standard implementation.
Add this to the Header section of Code Injection:
<style>
.skip-to-main {
position: absolute;
top: -9999px;
left: 0;
z-index: 9999;
padding: 12px 24px;
background: #1c3d5a;
color: #ffffff;
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
text-decoration: none;
}
.skip-to-main:focus {
top: 0;
}
</style>
<a class="skip-to-main" href="#page">Skip to main content</a>
The href value #page targets the main content container that Squarespace generates by default. In some templates this is #canvas or #maincontent. Inspect your site's HTML to confirm the correct id to target. The link is invisible until it receives keyboard focus (via Tab on page load), at which point it appears in the upper-left corner.
What Code Injection fixes and what it cannot fix
The Code Injection approach works for adding missing aria attributes and labels to existing elements. It does not work well for structural problems in the underlying HTML: incorrect heading hierarchy, improper landmark structure, or semantic errors in Squarespace's own components. Those require Squarespace to fix the template output.
Color contrast is another category that Code Injection cannot reliably fix. If your template renders light gray text on a white background at 13px, the only real fix is choosing a higher-contrast color in the Style Editor or switching to a template with better contrast defaults. CSS overrides can force higher contrast values, but they must be applied to every element that fails, which can be a large set on a site with varied content types.
For a complete picture of what your Squarespace store has, automated scanning covers the site systematically across all pages. If you want a scan with specific findings and fix guidance, request a free accessibility scan.