Webflow Video Lightbox Accessibility and Focus Management


Most people using Webflow’s native Lightbox component are unaware of just how inaccessible it is out of the box. If you're striving for WCAG conformance, especially for video or media embeds, the Lightbox element presents several key accessibility failures:
role="dialog" or aria-modal="true" or accessible nametitle (e.g., "Vimeo embed")In this guide, I’ll show you how to fully remediate a Webflow Lightbox, add a screen reader-accessible label, implement focus trapping, and return focus back to the triggering element — all with one clean script.
The native Webflow Lightbox component may look polished, but it fails several WCAG 2.2 success criteria that are critical for screen reader and keyboard accessibility. Here’s what’s broken and why it matters:
role="dialog" and aria-modal="true"aria-label, aria-labelledby, or a visible heading. Without this, screen readers cannot announce what the modal is for.title (e.g., “Vimeo embed”)title to describe the embedded content for screen reader users. A generic title like “Vimeo embed” provides no usable context.✅ Note: Webflow’s lightbox does correctly return focus to the trigger element after closing the modal. Our script preserves this behavior.
You’ll need to embed a small script in your site that:
titlePaste the following code into your Webflow project’s Before </body> tag inside Page Settings or use a global Embed component.
<script defer>
document.addEventListener("DOMContentLoaded", function () {
let lastFocusedElement = null;
const observer = new MutationObserver(() => {
const backdrop = document.querySelector('.w-lightbox-backdrop');
const container = document.querySelector('.w-lightbox-container');
if (backdrop && container) {
requestAnimationFrame(() => {
// Apply ARIA role and label
backdrop.setAttribute('role', 'dialog');
backdrop.setAttribute('aria-modal', 'true');
backdrop.setAttribute('aria-label', 'UNIQUE NAME DESCRIBING CONTENT');
// Fix iframe title
const iframe = container.querySelector('iframe');
if (iframe) {
iframe.title = 'UNIQUE NAME DESCRIBING CONTENT';
}
// Trap focus
trapFocus(container);
// Return focus to trigger
const closeBtn = container.querySelector('.w-lightbox-close');
if (closeBtn && document.activeElement) {
const lastFocused = document.activeElement;
closeBtn.addEventListener('click', () => {
lastFocused.focus();
}, { once: true });
}
});
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: false
});
// Focus trap logic
function trapFocus(container) {
const focusable = container.querySelectorAll(
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), iframe, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
container.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
});
}
});
</script>Step 2: Customize the Accessible LabelReplace 'UNIQUE NAME DESCRIBING CONTENT' with a clear, descriptive phrase that communicates what the video or modal contains.
Examples:
"Crystal Scott’s Introduction Video""Customer Testimonial from Walden Mutual Bank"Webflow adds a default aria-label="open lightbox" to lightbox triggers, which fails to meet WCAG’s requirement for unique, descriptive naming. You need to override this by adding your own accessible label to the trigger element.
Here’s how to do that correctly:
Add attribute role="button" to triggering <a href="#" ...> element to ensure it's role matches it's functionality.Add unique attribute aria-label="..." to replace Webflow’s default and give users a clear purpose.alt="" so it’s ignored by screen readers (your label already explains the purpose).aria-haspopup="dialog" (high-five Webflow)Here’s what to confirm after setup:
Webflow empowers creators, but it doesn’t guarantee accessibility. You’re responsible for making sure every visitor can access the information you provide; including people using keyboards and assistive technologies.
Accessible modals are hard to get right. Modal dialogs are one of the most commonly broken accessibility patterns on the web today. Although they’re visually simple, they often fail to meet even the most basic accessibility requirements. Developers frequently forget to add role="dialog" and aria-modal="true", fail to provide a programmatically accessible name, and overlook the need for proper focus management. This creates major usability issues for people who rely on screen readers or keyboard navigation — including blind users, people with motor impairments, and anyone using assistive technology. When focus is not trapped inside the modal or if the dialog isn’t announced properly, users can become completely disoriented or miss critical information.
Need this implemented across multiple projects? Want to integrate a reusable component or automation via Webflow CMS? That’s where we can help.
Graceful Web Studio specializes in Webflow accessibility and strategy. Contact me at crystal@gracefulwebstudio.com to bring inclusive design to your website or request a quote today.
Tried this yourself? Got stuck?
💬 I’d love to hear your experience after you follow me on LinkedIn.
Tag me, share your progress, or tell your developer friends who need this fix.
Together, we can build a more inclusive web — one accessible lightbox at a time. Happy coding!
We build accessible, conversion-focused Webflow websites for businesses across Yakima and the US. Crystal Scott is a Certified Professional in Web Accessibility (CPWA) with 11+ years of front-end experience.
Our services:
Transparent pricing on every service page. Request a free homepage evaluation or view the portfolio to see the work.
We would love to meet with you face-to-face. Whether virtually or for a coffee. Book a call, and let’s find the right solution for you! We review your site, map goals, and then deliver a clear plan and quote.
