Accessibility in Webflow
|
This content was generated with the assistance of AI and should be verified against the official Webflow documentation before being relied on in production. This sub-section’s Webflow bibliography lists the reference material consulted while preparing these pages. |
This page describes Webflow accessibility features as they were on 2026-10-28, the date on which its facts were checked against the official documentation. Webflow is a software-as-a-service product and has no version numbers, so what follows is dated rather than versioned, and the Product Changes and Deprecations page tracks later changes. Every feature on this page is available on every plan, including the free Starter site: accessibility is a property of the markup, styles and content you produce, not a paid add-on. Plans are named by tier only on these pages, and Plans, Workspaces, Seats and Roles explains which tier unlocks what.
Accessibility means that people with disabilities can perceive, operate and understand a site. In practice that covers visitors who use a screen reader, who navigate only with a keyboard or a switch device, who zoom the page to 400 percent, who have low vision or colour blindness, who are sensitive to motion, or who simply use a phone in bright sunlight. The international yardstick is the Web Content Accessibility Guidelines (WCAG), published by the W3C, which define testable success criteria at three conformance levels (A, AA and AAA). Most laws and procurement rules refer to level AA. The general theory of accessible HTML, CSS and JavaScript is covered in Web Accessibility; this page is about doing the same work inside Webflow and about the places where the visual builder helps, stays silent or gets in the way.
The running example is Fernbrook Gardens, a fictitious botanical garden. Its site has Home, Visit, Plants, Events, Shop, Garden Journal, About and 404 pages and a password-protected Volunteers area. A botanical garden is a good accessibility case: its content is image-heavy (plant photographs), its visitors include elderly people and families with prams who plan a visit on a phone, its Plants collection is full of colour-coded information, and its marketing pages want animation (the "bloom reveal"). The page walks through the checks the team runs before each release.
What Webflow does for you and what it does not
Webflow generates clean, standards-based HTML, and that is the biggest accessibility feature: a div on the canvas is a
div in the page, a Heading element is a real h1 to h6, and a Link Block is a real a. The platform does not,
however, decide that your page makes sense. Three layers are involved.
| Layer | What Webflow provides | What the builder must still do |
|---|---|---|
Markup |
Real HTML elements, a configurable tag for most containers, custom attributes on any element, ARIA support through those attributes |
Choose the right tag, keep a logical heading order, label every control, hide decorative elements from assistive technology |
Components |
Navbar, Dropdown, Tabs, Slider, Lightbox and Forms ship with keyboard handling and ARIA attributes managed by Webflow’s runtime |
Style the focus states, check the result with a keyboard and a screen reader, and avoid breaking the built-in structure |
Content |
An alt text field on every image, a decorative option, an Audit panel that flags some problems |
Write meaningful alt text and link text, keep contrast high, caption and transcribe media, and write plain language |
No tool can certify a site as conformant. Webflow’s own accessibility checklist says it is based on WCAG 2.1 level AA, mixed with practices its web team follows, and is not exhaustive. Treat the Audit panel, the checklist and automated checkers as ways to find problems, and manual testing as the way to confirm there are none.
Source: Webflow: Accessibility checklist
Who is responsible for what
Accessibility is shared work, and splitting it by role avoids the common failure in which everyone assumes someone else did it.
| Role in the Fernbrook team | Accessibility responsibilities |
|---|---|
Site owner |
Sets the standard (for example WCAG 2.1 or 2.2 AA), budgets for an external audit, publishes an accessibility statement and a contact route for reports |
Designer |
Picks colours with enough contrast, defines visible focus styles in the design system, designs touch targets large enough to hit, plans reduced-motion alternatives for every animation |
Content editor |
Writes alt text, descriptive link text and meaningful headings in the CMS, adds captions and transcripts, avoids text inside images |
Marketer |
Keeps page titles and language correct, checks forms and pop-ups for keyboard use, avoids autoplay and flashing content |
Developer |
Adds ARIA and custom behaviour only where native HTML is not enough, checks third-party scripts and embeds, wires accessibility checks into testing |
Semantic structure
Assistive technology reads the document structure, not the picture. A screen reader user can list all headings, jump
between landmarks (header, nav, main, footer) and list all links. If the structure is flat, those shortcuts
return nothing useful.
Choosing tags in the Settings panel
Most container elements (Div Block, Section, Container, List, Link Block) have a Tag dropdown in the Settings panel of the Element settings. Choosing the tag changes the generated markup and gives the element a role without any ARIA.
| Fernbrook element | Tag to choose | Why |
|---|---|---|
Site header with logo and menu |
|
Exposes a banner landmark when it is not nested inside another sectioning element |
Main menu wrapper (inside the Navbar) |
|
Exposes a navigation landmark |
Page body between header and footer |
|
Exposes the main landmark, one per page, the target of the skip link |
Plant card in a collection list |
|
A self-contained item; its heading names it |
Care-notes sidebar on a plant page |
|
Complementary content |
Footer |
|
Exposes a content-info landmark |
Section with its own heading, such as "Upcoming events" |
|
Becomes a region landmark only when it has an accessible name, so give it one with |
A page needs exactly one main. When Fernbrook’s designers first wrapped the whole page in a Div Block called
page-wrapper, the page had no landmarks at all; changing three tags (header, main, footer) fixed it without
touching a pixel.
Headings
Headings describe the outline. Rules that screen reader users depend on:
-
One
h1per page, naming the page ("Plants", "Plan your visit"). -
Heading levels never skip downwards: an
h2is followed by anh2or anh3, never by anh4. -
Choose the level for meaning, then change the size with a class. The Heading element’s tag and its visual size are independent. Webflow lets you pick
h1toh6in the Settings panel and style any of them with any class. -
Do not use a heading for something that is not one (a decorative tagline or a bold label), and do not use bold text or a Text Block for something that is.
On a collection template page, the plant name is the h1. On a collection list on the Plants page, each card’s plant
name is an h3 under an h2 such as "Browse by bloom month". A frequent mistake is to leave the card headings at the
default h1 copied from the template, which produces a page with thirty h1 elements.
<main id="main">
<h1>Plants</h1>
<section aria-labelledby="bloom-heading">
<h2 id="bloom-heading">Browse by bloom month</h2>
<ul role="list">
<li><article class="plant-card">
<h3 class="plant-card_name">Hellebore</h3>
<p class="plant-card_latin">Helleborus orientalis</p>
</article></li>
</ul>
</section>
</main>
Lists and the list role
A collection list renders as a div with a wrapper and items, not as a list. For a visual grid of cards, give the
Collection List Wrapper nothing and the Collection List the List semantic by choosing the List and List Item tags in
the settings, where the element supports it, or add a role through a custom attribute. See
Collection Lists for how the markup is built. A real list lets a screen reader
announce "list of 24 items", which tells the visitor how much content to expect.
The Audit panel
The Audit panel is Webflow’s built-in checker in the Designer. It scans the page you are editing and lists problems that can hurt accessibility or search ranking before you publish. It is opened from the toolbar on the left of the Designer, and pressing Alt (Option on macOS) together with U expands or collapses every item in the list. The help article describes the panel as covering both accessibility and SEO problems, and sorts issues by severity: a red square marks a critical issue and a yellow triangle marks a moderate one.
What it checks
As of 2026-10-28 the panel runs four checks.
| Check | What it flags | Typical fix |
|---|---|---|
Missing alt text |
Images that have no alt attribute and are not marked decorative |
Write alt text in the image’s settings or mark it decorative |
Non-descriptive link content |
Links whose text says only "click here", "read more" or "learn more", or that have no text |
Rewrite the link text, or add an accessible name |
Skipped heading levels |
A heading that jumps down more than one level, for example an |
Change the tag in the Settings panel, restyle with a class |
Duplicate element IDs |
Two elements on a page with the same |
Rename one, or remove the ID if it is not needed |
Each issue can be selected to highlight the element on the canvas, with step-by-step guidance in the panel, and individual suggestions can be ignored when you have decided they do not apply. The panel was introduced out of beta on 17 November 2021 with those features; older tutorials and lessons list only three checks, so they predate the duplicate ID check.
What it does not check
The Audit panel is a small subset of what accessibility requires. It does not:
-
inspect elements inside components, so issues in a
PlantCardorSiteHeadermust be found by hand on the component’s canvas; the help article warns about this explicitly -
check colour contrast (the colour picker has a contrast checker for text elements, covered below)
-
check keyboard operability, focus order or visible focus
-
judge whether alt text is any good, only whether it exists
-
check form labels, error messages or autocomplete attributes
-
check captions, transcripts, audio control or flashing content
-
check target size, reflow at 400 percent zoom or text spacing overrides
-
read content in a code embed, or third-party scripts' output
A green Audit panel therefore proves very little. Fernbrook treats it as a pre-flight check and then runs the manual checklist at the end of this page.
Using the Audit panel in a release routine
-
Open each template and static page before publishing, not only the home page. Collection template pages are audited with the preview item selected, so choose an item with a long name and an image that has no alt text to expose problems.
-
Fix critical items first.
-
Open each component and repeat the check on its canvas.
-
Ignore a suggestion only with a recorded reason. For Fernbrook, the only ignored item is a duplicate ID on a demo page that is not linked from the site.
-
Publish to the free staging domain (
fernbrook-gardens.webflow.io) and run a browser-based checker and the manual tests before pushing to production. See Publishing and Scheduling.
Images and alt text
Alt text is the text alternative of an image. Webflow exposes it in two places: on each Image element and in the Assets panel, where the same asset can carry a default description reused wherever it is inserted.
Writing alt text
-
Describe the purpose, not the pixels. "Hellebore with nodding, plum-coloured flowers" tells a visitor what the plant looks like; "image1.jpg" and "photo" tell nothing.
-
Keep it short, usually under about 125 characters. Long descriptions belong in the page text.
-
Skip "image of" and "picture of", because screen readers already announce the role.
-
If the image contains text, repeat the text.
-
If the image is a link, describe the destination, not the picture.
Decorative images
Webflow added a Decorative option for images: an image marked decorative is output with an empty alt="", so screen
readers ignore it rather than reading the filename. The option is available in the Assets panel and on each image
instance in the Settings panel, and when it is selected the alt text field is disabled. A decorative image is one that
adds no information: a leaf flourish between sections, a background photograph behind a heading that repeats its
content, an icon next to a label that already says the same.
The difference between the three states is large, and it is the single most common mistake in the field.
| State in Webflow | Generated attribute | What a screen reader does |
|---|---|---|
Alt text written |
|
Reads the text |
Marked decorative |
|
Skips the image |
Neither |
the attribute is missing |
May read the file name, for example "hellebore-img-0042 dot jpg", and the Audit panel flags it |
<!-- Informative image: alt text describes the plant -->
<img src="https://cdn.prod.website-files.com/.../hellebore.webp" loading="lazy"
alt="Hellebore with nodding, plum-coloured flowers" width="800" height="600">
<!-- Decorative flourish: empty alt, ignored by assistive technology -->
<img src="https://cdn.prod.website-files.com/.../leaf-divider.svg" loading="lazy" alt="">
Alt text in the CMS
CMS images deserve special care because editors upload them in bulk. A plain Image field on a collection has a single
file and a file-level alt text; the same photograph reused on several items gets the same description everywhere, which
is rarely right. The Fernbrook Plants collection therefore adds a separate plain-text field called image-alt and
binds the Image element’s alt text to it on the template page. A visitor then hears the editor’s description of
this plant, not a generic one. An empty image-alt falls back to the asset’s default alt text. The
Images and Assets page shows how to bind a field to alt text, and the Audit
panel can see the result only when the item is previewed. The Fernbrook MCP agent, described in
MCP Server and AI Agents, is allowed to propose missing alt text but a
person approves it, because machine-written alt text is often wrong about species.
Links and buttons
-
A link goes somewhere, a button does something. Use a Link Block or Text Link for navigation and a Button element, which renders as an
aby default in Webflow, only for links. For an action that stays on the page (open a dialog, toggle filters), use a real button, which in Webflow means a Div Block with the tag set tobuttonor a Code Embed. -
Link text must make sense out of context. Screen readers list links; ten links that say "Read more" are useless. The Audit panel flags the obvious cases. On Fernbrook’s Journal list, the link text is the post title and the "Read more" label is visual only.
-
Icon-only links need a name. The social icons in the footer are Link Blocks around an SVG; add a custom attribute
aria-labelwith the value "Fernbrook Gardens on Instagram". -
Links that open in a new tab should say so, either in text or in the accessible name.
-
Do not remove the underline from links in running text unless colour contrast to the surrounding text is at least 3 to 1 and another cue appears on focus and hover.
Forms
Forms are where accessibility failures cost the most, because the visitor cannot complete a task. Webflow’s Form elements are listed among the elements with built-in accessibility support, but they only work if labelled.
-
Every input has a visible label (a Label element whose
formatches the input’sid). Webflow connects a Label to the field when it is inserted in the form block. Placeholder text is not a label: it disappears when typing, has low contrast by default and is not reliably announced. -
Group related choices with a fieldset and legend (use a Div Block with the tag set to
fieldsetand a legend inside) for radio buttons such as "Group size". -
Mark required fields with the Required setting, which outputs the
requiredattribute, and say so in text ("required"), not only with a red asterisk. -
Use the right input type (
email,tel,date) so mobile keyboards and autofill work, and addautocompletethrough a custom attribute (autocomplete="email") for personal data fields, which supports WCAG 1.3.5. -
Make errors and success visible and announced. The default success and error messages Webflow shows after submission are plain blocks that appear and disappear; give each a clear text and, using a custom attribute, a
role="alert"on the error block androle="status"on the success block, so screen readers announce them. -
Never rely on colour alone to show an invalid field; add an icon or text.
<form id="group-visit" name="wf-form-Group-Visit" method="get" data-name="Group Visit">
<div>
<label for="visit-name">Your name (required)</label>
<input id="visit-name" name="name" type="text" autocomplete="name" required>
</div>
<div>
<label for="visit-email">Email (required)</label>
<input id="visit-email" name="email" type="email" autocomplete="email" required>
</div>
<fieldset>
<legend>Group size</legend>
<label><input type="radio" name="size" value="10-20"> 10 to 20 people</label>
<label><input type="radio" name="size" value="21-40"> 21 to 40 people</label>
</fieldset>
<input type="submit" value="Send enquiry">
</form>
<div class="w-form-done" role="status">Thank you. We will reply within two working days.</div>
<div class="w-form-fail" role="alert">Something went wrong. Please try again or call us.</div>
Form construction, notifications and spam protection are covered in Forms. The volunteer form with file upload follows the same rules and adds a text description of allowed file types next to the upload control.
ARIA through custom attributes
ARIA (Accessible Rich Internet Applications) is a set of attributes that add roles, states and names to elements when native HTML cannot express them. Webflow has no dedicated ARIA panel; every ARIA attribute is added through custom attributes.
Adding an attribute
-
Select the element on the canvas.
-
Open the Settings panel (the gear tab) and scroll to Custom attributes.
-
Click the plus button and type the Name (
aria-label) and the Value. -
Publish; attributes do not appear in the Designer preview of the element, only in the published HTML and in the browser’s developer tools.
Custom attributes apply to the element, not to a class, so each instance needs its own, and an attribute on a component instance can be exposed as a property when the component’s author makes it editable. See Custom Attributes and JavaScript and Components: Props, Slots and Variants. Attribute values can be bound to CMS fields on a collection page, which is how Fernbrook builds the label "Open hardiness zone 7 map" from a zone name.
The first rule of ARIA
The W3C’s first rule is: if a native HTML element or attribute gives the semantics you need, use it instead of ARIA.
A real button is focusable, activates with Enter and Space and has the right role for free; a Div Block with
role="button" has none of that until you write the JavaScript. Bad ARIA is worse than no ARIA, because it makes
promises the code does not keep.
| Need | Prefer native HTML | Use ARIA only when needed |
|---|---|---|
A control that triggers an action |
A |
|
Name an icon-only link |
Visible text hidden visually |
|
Name a section |
A heading inside the section |
|
Hide a decorative icon |
An empty |
|
Announce a status message |
A real heading or an existing live region |
|
Mark the current page in a menu |
Webflow’s |
|
Common attributes
-
aria-labelgives an accessible name to an element that has no text. It overrides the visible text, so do not use it on elements that already have a good name. -
aria-labelledbynames an element by pointing at theidof another. Because it needs an ID, give the target a unique one and remember that the Audit panel flags duplicates. -
aria-describedbypoints at helper text for a field. -
aria-hidden="true"removes an element from the accessibility tree. Never put it on anything focusable, because the element would still take focus while being invisible to a screen reader. -
aria-expandedandaria-controlsexpose the state of a toggle such as a filter panel. Webflow’s Dropdown and Navbar manage these for you; for a custom disclosure built from a Div Block, you set them and a script updates them. -
aria-liveregions announce content that updates, such as a count of search results. -
role="list"restores list semantics where a CSS reset (includinglist-style: none) causes Safari with VoiceOver to stop announcing a list.
<a class="footer_social" href="https://example.com/fernbrook-gardens" aria-label="Fernbrook Gardens on Instagram">
<svg aria-hidden="true" focusable="false" width="24" height="24" viewBox="0 0 24 24"><!-- icon paths --></svg>
</a>
<button class="filter-toggle" aria-expanded="false" aria-controls="plant-filters">Filter plants</button>
<div id="plant-filters" hidden>...</div>
Webflow’s checklist also advises that decorative elements which are not images be hidden from assistive technology
with an ARIA attribute, which is the aria-hidden pattern above.
Keyboard access and focus
A keyboard user moves through interactive elements with Tab and Shift+Tab, activates links with Enter and buttons with Enter or Space, and uses arrow keys inside composite widgets. Three things must always hold: every control can be reached, the focus is always visible, and the tab order follows the visual order.
Focus states in the Style panel
Webflow’s states menu (the dropdown beside the class name) lets a designer style Hover, Pressed, Focused and, on elements that support it, Focus visible, Focus within and similar states. Each generates CSS pseudo-class rules:
-
Focused generates the
:focusselector. -
Focus visible generates
:focus-visible, which matches when the browser decides a visible indicator is needed (keyboard use, and not usually a mouse click). This is the state to design in most cases. -
Focus within generates
:focus-withinand styles a parent when any descendant has focus, useful for a search box with an icon.
The most important rule is never remove the outline without replacing it. Setting outline: none on a link, button or
form field with no alternative style makes the page unusable by keyboard.
/* Fernbrook design-system focus ring, defined once on a utility class */
.u-focus-ring:focus-visible,
.button:focus-visible,
.nav-link:focus-visible {
outline: 3px solid #1f4f8f;
outline-offset: 3px;
border-radius: 2px;
}
/* Night mode keeps contrast against a dark surface */
.u-theme-night .button:focus-visible {
outline-color: #ffd166;
}
The focus indicator needs a contrast ratio of at least 3 to 1 against the colours next to it (WCAG 1.4.11, non-text
contrast) and, in WCAG 2.2, must not be hidden by sticky content (2.4.11, focus not obscured). Fernbrook’s sticky
header is 72 pixels high, so the page adds scroll-padding-top: 88px to the html element in the site’s custom code
so that a focused anchor target is not hidden behind it.
Built-in components still need focus styles
Webflow’s help article on accessible elements states that its Navbar, Dropdown, Tabs, Slider, Lightbox and Forms provide screen reader and keyboard support without custom code, but that you must add focused-state styles for some of them for them to be fully keyboard accessible. For the Slider, set focused styles on the left arrow, the right arrow and the slider dots; the dot style is written manually, in CSS targeting the dot’s focus state.
Tab order and tabindex
Tab order follows the DOM order, and the DOM order follows the Navigator order. If the visual order is changed with
Flexbox order or CSS Grid placement, focus no longer follows the picture. Fix the order in the Navigator rather
than with positive tabindex values. The only acceptable values are:
-
tabindex="0", which puts a non-interactive element in the tab order, for a scrollable region that has no other way to be reached -
tabindex="-1", which lets script or an anchor move focus to an element without adding it to the tab order, as used on themainelement for a skip link target
A positive tabindex (tabindex="3") overrides the natural order and is almost always a bug.
Skip links
A skip link is the first focusable element on the page. It is visually hidden until it receives focus, and it jumps over the repeated header and menu to the main content. Without it, a keyboard user at Fernbrook has to press Tab about fifteen times on every page to reach the content. Webflow’s checklist lists a "Skip to main" link as a task.
Build it in the Designer:
-
Add a Link Block as the first child of the
body, above the header. Link text "Skip to main content". -
Set its link to the Section option and choose the element with ID
main, or set the link’s URL to#mainin the settings. -
On the
mainelement set the IDmainand, in custom attributes,tabindexwith value-1, so it can take focus when the link is activated. -
Style the link class
.skip-linkso that it is off-screen by default and visible on focus.
.skip-link {
position: absolute;
left: -9999px;
top: 8px;
z-index: 1000;
padding: 8px 16px;
background: #ffffff;
color: #14213d;
}
.skip-link:focus {
left: 8px;
}
Source: Webflow: Accessibility checklist
On a Webflow site built from a component, put the skip link in the SiteHeader component so that every page that uses it
inherits the link. Do not hide the link with display: none or visibility: hidden, because that also removes it from
the tab order.
Colour and contrast
WCAG level AA requires a contrast ratio of at least 4.5 to 1 between normal text and its background, 3 to 1 for large text (about 24 pixels, or 19 pixels bold), and 3 to 1 for user-interface components and graphics such as borders of form fields and icons that convey meaning. Level AAA raises the text requirement to 7 to 1.
Webflow’s colour picker has a built-in contrast checker for text elements, shown when you change the text colour. It compares the text colour with the background of the element and reports whether it passes. Two limits matter. It only works for text, and it can only compare against backgrounds it can read from the styles, so text over a gradient or a photograph is not judged reliably.
Variables and modes
Fernbrook’s brand variable collection has "Day" and "Night" modes. Contrast must be checked in every mode, because the
same variable resolves to different colours. A text variable that passes on the Day mode’s cream background can fail on
the Night mode’s deep green. A practical approach is to define paired variables, such as text-on-surface and
surface, that are always changed together, and to check each pair once per mode. See
Variables and Modes.
| Pair (Fernbrook) | Day mode | Night mode | Requirement |
|---|---|---|---|
Body text on surface |
12.6 to 1 |
11.9 to 1 |
4.5 to 1 passes |
Link text on surface |
7.2 to 1 |
8.1 to 1 |
4.5 to 1 passes |
Focus ring on surface |
7.4 to 1 |
9.3 to 1 |
3 to 1 passes |
Muted caption text on surface |
3.8 to 1 |
4.2 to 1 |
4.5 to 1 fails, darken the muted text variable |
The values are examples from the scenario; compute your own with a contrast checker.
Do not rely on colour alone
The Plants collection has a colour field that holds the flower colour. The plant card shows a colour swatch next to the words "Flower colour: plum". The swatch alone would fail WCAG 1.4.1 (use of colour), since a colour-blind visitor could not read it. The same applies to the "endangered" switch: show an icon and the text "Endangered in the wild", not only a red border.
Source: Webflow: Accessibility checklist
Responsive design and zoom
-
Webflow adds the viewport meta tag automatically; do not disable zooming with
user-scalable=noor a lowmaximum-scalein custom code (WCAG 1.4.4). -
Content must reflow at 320 CSS pixels of width without horizontal scrolling (WCAG 1.4.10), which means flexible widths,
max-widthinstead of fixed widths and wrapping flex rows. Check the Mobile portrait breakpoint and then zoom a desktop browser to 400 percent. See Responsive Design and Breakpoints. -
Use relative units (
rem) for text so that a visitor’s browser font setting is respected. A font size in pixels onhtmloverrides the preference. -
Make touch targets at least 24 by 24 CSS pixels (WCAG 2.5.8 in WCAG 2.2) and ideally 44 by 44 for primary controls.
-
Text must stay readable when the visitor overrides line height, paragraph and letter spacing (WCAG 1.4.12); do not give text containers a fixed height.
Motion and interactions
Animation helps some visitors and harms others: parallax, large movement and pinned scrolling can trigger vestibular disorders, nausea and migraines, and autoplaying movement distracts people with attention difficulties. WCAG 2.2.2 (pause, stop, hide) requires a way to stop moving content that lasts more than five seconds, 2.3.1 limits flashing to three times per second, and 2.3.3 (level AAA) asks for a way to turn off motion triggered by interaction.
Reduced motion in the Interactions panel
Operating systems expose a reduce motion preference, and the browser passes it to the page as the
prefers-reduced-motion media query. Webflow’s interactions panel can act on it through conditional playback:
-
Open the interaction (page trigger, scroll trigger, element trigger) in the Interactions panel.
-
Open the playback settings and add a condition for prefers reduced motion.
-
Choose what to do when the condition is true.
-
No animation turns the interaction off entirely. Use it for decorative effects, such as the Fernbrook staggered fade at page load.
-
Skip to end jumps to the final state without animating. Use it for functional animations such as a menu opening or the bloom reveal, so that the element still appears; with No animation the element would be left in its hidden starting state and the content would never show.
-
-
Test by switching on reduce motion in the device’s accessibility settings and checking the page in the preview.
Large, multi-part and parallax effects are the likeliest to cause problems; simple opacity fades and small movements are often acceptable. The newer GSAP-based interactions are documented in Interactions with GSAP, and the older style in Classic Interactions; the same decision applies in both.
Webflow also changed its smooth scroll setting to honour the visitor’s reduced-motion preference: when the setting is on and a visitor has asked for reduced motion in their operating system or browser, anchor links no longer scroll smoothly.
A CSS safety net
Interactions that animate with CSS transitions or with custom code can be tamed with one media query in the site’s
custom code. The query must include the value: (prefers-reduced-motion: reduce). A bare (prefers-reduced-motion)
matches whenever the browser supports the feature at all, including when the preference is off.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Source: MDN: prefers-reduced-motion
This does not stop Webflow interaction animations, which are driven by the platform’s runtime script. Do not rely on internal runtime calls to switch interactions off; they are not a documented interface and can change. Use conditional playback instead.
Autoplay, video and Lottie
-
Background video and Lottie animations must not autoplay for more than five seconds without a pause control. Give the Fernbrook hero video a visible "Pause" button, built with a Code Embed.
-
Video with speech needs captions, and audio-only content needs a transcript.
-
Avoid anything that flashes more than three times per second.
The Lottie, Spline, Rive and Video page covers the embeds.
Accessible navbars
Webflow’s Navbar is among the elements with built-in accessibility support. The generated menu button has a role and ARIA attributes that Webflow’s runtime updates when the menu opens, and the menu can be dismissed with the keyboard. What the builder still owns:
-
Give the menu button a name. The default button holds only an icon. Webflow sets the label, but check the published markup, and add
aria-label="Menu"if a screen reader announces only "button". -
Style the focus state of the menu button and every nav link.
-
Keep the link text real. Do not replace a nav link’s text with an image.
-
Mark the current page. Webflow adds
aria-current="page"and thew--currentclass to the link that matches the page, so stylew--currentwith more than colour, such as a bottom border. -
Test the mobile menu with the keyboard. Open it with Enter, tab through the links, and close it with Escape.
-
Do not trap focus. The mobile menu overlay should not hide content that the visitor can still tab into.
<nav role="navigation" class="navbar_menu w-nav-menu">
<a href="/visit" class="nav-link w-nav-link">Visit</a>
<a href="/plants" aria-current="page" class="nav-link w-nav-link w--current">Plants</a>
<a href="/events" class="nav-link w-nav-link">Events</a>
</nav>
<div class="navbar_button w-nav-button" role="button" tabindex="0" aria-label="menu" aria-haspopup="menu"
aria-expanded="false" aria-controls="w-nav-overlay-0">
<div class="w-icon-nav-menu"></div>
</div>
The markup above shows the typical structure of a published Webflow navbar; the exact attributes are produced by Webflow’s runtime and can change, so inspect your own published page rather than copying them.
Dropdowns and mega menus
The Webflow Dropdown toggles on click and opens with Enter or Space. Keep dropdown content short, make sure each item is a real link, and do not build a hover-only menu from a Div Block: a menu that opens on hover is unreachable by keyboard and touch (WCAG 1.4.13 additionally requires hover or focus content to be dismissible, hoverable and persistent). A mega menu with many links is better presented as a navigation page.
Accessible sliders
The Webflow Slider element supports keyboard navigation and screen readers without custom code: the arrows and dots are focusable, and the slides are exposed as a group. A slider is still a difficult widget, and several choices make it better or worse.
-
Turn off autoplay unless there is a visible pause control. Autoplaying content that moves for more than five seconds must be stoppable (WCAG 2.2.2). If autoplay is kept, enable the setting that pauses it when the visitor focuses or hovers.
-
Disable looping and fast transitions for people who cannot track the movement, and respect reduced motion.
-
Set focus styles on the left arrow, right arrow and dots, as described earlier.
-
Name the slider with a custom attribute,
aria-label="Featured plants", so a screen reader announces what it is. -
Hide non-visible slides from assistive technology is handled by the runtime, but verify it with a screen reader.
-
Make slide content accessible: every image has alt text, every link has meaningful text, and the headings follow the page outline.
-
Consider not using a slider. A simple grid of cards, such as the Fernbrook Featured plants list, is easier for everyone and is better for mobile.
The Tabs element follows the same pattern as a ready-made tab list with keyboard arrows; style its focus state and keep the tab labels short.
Tables, media and documents
-
Use real table markup for tabular data (a Rich Text table pasted from a spreadsheet loses its header cells, so add a
thand a scope in an embed). -
Provide captions for video and a transcript for audio; the Garden Journal podcast episode has both.
-
PDFs linked from the site, such as the printable map, must be accessible themselves (tagged, with a title and bookmarks), or replaced by an HTML page.
-
Write in plain language, use the
langattribute (Webflow sets the page language from the site’s language setting, and localization sets it per locale; the Localization page shows how a Spanish or German locale changes it), and mark a phrase in another language with alangattribute. -
Give every page a unique, descriptive
title. See SEO and AEO.
Custom code and embeds
Anything you add with a Code Embed or custom code in the head or footer lives outside the Audit panel’s view, so it must be checked by hand. Webflow’s checklist has a section on custom code for this reason.
-
Prefer native elements to scripts that rebuild them: a custom modal written as a
divneeds focus trapping, Escape handling, restore of focus androle="dialog"witharia-modal="true"; the nativedialogelement does most of that for you. -
Third-party widgets (chat, cookie banners, maps) are a frequent source of keyboard traps and low contrast. Test them or choose a vendor with an accessibility conformance report.
-
Overlay products that claim to make a site accessible with one script do not fix the underlying markup, can conflict with assistive technology and do not provide legal protection. Fix the source.
-
A Code Embed that injects content must not remove focus or reorder the DOM visually.
Accessibility in components and the design system
The design system is the cheapest place to get accessibility right once. In Fernbrook:
-
The
SiteHeadercomponent contains the skip link, the navbar and a slot for a banner. Every page inherits a correct structure. -
The
PlantCardcomponent exposes properties for name, image, alt text and zone link; the alt text property is required by convention, so a designer who inserts a card cannot forget it. Its heading level is also a property, set per context (h2on the Plants page,h3inside a zone page). -
The
u-focus-ringutility class carries the focus style, and every interactive class adds it as a combo class. -
A
u-visually-hiddenutility class hides text visually but keeps it for screen readers (clip and 1 pixel size, notdisplay: none), used for the "opens in a new tab" notice. -
Variable collections store only colour pairs that have been checked.
.u-visually-hidden {
position: absolute !important;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}
Source: Webflow: Accessibility checklist
The Audit panel does not look inside components, so open PlantCard and SiteHeader on their own canvases and check
them there. See Building a Design System and
Components: Props, Slots and Variants.
Testing accessibility
Layered testing finds problems that no single tool does. Automated tools find roughly a third of the issues defined by WCAG, mostly the mechanical ones; the rest need a person.
| Method | What it finds |
|---|---|
Audit panel |
Missing alt text, vague link text, skipped headings, duplicate IDs, before publishing |
Browser automated checkers (axe DevTools, Lighthouse, WAVE) |
Contrast failures, missing labels, invalid ARIA, landmark problems on the published page |
Keyboard-only pass |
Unreachable controls, invisible focus, traps, wrong tab order, broken menus |
Screen reader pass (VoiceOver, NVDA, TalkBack) |
Wrong names and roles, missing announcements, reading order |
Zoom and reflow pass |
Content hidden at 200 and 400 percent zoom, horizontal scrolling at 320 pixels |
Reduced-motion pass |
Interactions that still move or leave content hidden |
Real users with disabilities |
Task failures that no checklist predicts |
Automated checks can run in a pipeline as well. A small Playwright test with the axe engine can be run against the staging domain after each publish, which fits the team’s practices in Testing, CI and DevOps.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
const pages = ['/', '/visit', '/plants', '/events', '/garden-journal'];
for (const path of pages) {
test(`no detectable WCAG A/AA violations on ${path}`, async ({ page }) => {
await page.goto(`https://fernbrook-gardens.webflow.io${path}`);
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'])
.analyze();
expect(results.violations).toEqual([]);
});
}
Source: npm: @axe-core/playwright
A WCAG checklist for a Webflow site
The checklist below is organized by the four WCAG principles. It is the list the Fernbrook team works through before launch; the numbers are WCAG success criteria.
Perceivable
| Criterion | Check | Where in Webflow |
|---|---|---|
1.1.1 |
Every informative image has alt text, every decorative image is marked decorative |
Image settings, Assets panel, Audit panel |
1.2.x |
Video has captions, audio has a transcript |
Content and embeds |
1.3.1 |
Landmarks, headings, lists, tables and form labels use real markup |
Settings panel tag dropdown, Navigator |
1.3.5 |
Personal data fields have an |
Custom attributes |
1.4.1 |
Information is not carried by colour alone |
Design system |
1.4.3 and 1.4.11 |
Text contrast 4.5 to 1 (large 3 to 1), interface contrast 3 to 1, in every variable mode |
Colour picker checker, variables |
1.4.4 and 1.4.10 |
Text resizes to 200 percent, content reflows at 320 pixels wide |
Breakpoints, |
1.4.12 |
Text spacing overrides do not clip content |
Auto heights, no fixed heights |
1.4.13 |
Hover and focus content is dismissible, hoverable and persistent |
Dropdowns, tooltips |
Operable
| Criterion | Check | Where in Webflow |
|---|---|---|
2.1.1 and 2.1.2 |
Everything works with a keyboard and there are no traps |
Components, custom code |
2.2.2 |
Moving content can be paused, stopped or hidden |
Slider, video, Lottie |
2.3.1 |
Nothing flashes more than three times per second |
Interactions |
2.4.1 |
A skip link bypasses repeated blocks |
Link Block in |
2.4.2 |
Pages have unique, descriptive titles |
Page settings |
2.4.3 |
Focus order matches the visual order |
Navigator order |
2.4.4 and 2.4.6 |
Link text and headings describe their purpose |
Audit panel, content |
2.4.7 and 2.4.11 |
Focus is visible and not hidden by sticky content |
Focus visible state, |
2.5.8 |
Targets are at least 24 by 24 CSS pixels |
Spacing and padding |
Understandable
| Criterion | Check | Where in Webflow |
|---|---|---|
3.1.1 and 3.1.2 |
Page language is set, and passages in other languages are marked |
Site language, localization |
3.2.x |
Focus or input does not cause an unexpected context change |
Forms, filters |
3.3.1 and 3.3.2 |
Errors are identified in text and fields have labels or instructions |
Forms |
3.3.7 and 3.3.8 |
No repeated data entry; authentication does not require a cognitive test |
Forms, Volunteers area |
Legal and process context
Many jurisdictions require accessible websites: the Web Accessibility Directive and the European Accessibility Act in the European Union, Section 508 and the Americans with Disabilities Act in the United States, and similar laws elsewhere. The details change, and this page is not legal advice. Practical steps that apply everywhere:
-
Publish an accessibility statement with the standard targeted, known gaps and a contact address or form.
-
Keep a record of audits and fixes.
-
Fix reported problems quickly, because response is part of conformance.
-
Build checks into the workflow instead of auditing once at the end: the design system, the Audit panel, an automated pass on staging and a manual pass before each release. The review step fits into Page Branching, Releases and Approvals.
-
Include accessibility in the brief for any agency or freelancer.
Common pitfalls
-
Treating a green Audit panel as conformance. It checks four things and does not look inside components.
-
Missing the difference between no alt and empty alt. Missing alt makes screen readers read a filename;
alt=""makes them skip the image. Use the Decorative option for the second case. -
Removing the focus outline. A global
outline: nonemakes keyboard use impossible. -
Heading levels chosen by size. Choose the level by meaning and size the text with a class.
-
Using a Div Block as a button. It has no keyboard behaviour; use a real button element.
-
Hiding content with
display: noneorvisibility: hiddenwhen you meant "visually hidden". The first removes it for screen readers too. -
Interactions that start with the content hidden. With reduced motion set to No animation, the element can stay invisible forever; use Skip to end for anything that reveals content.
-
Placeholders as labels.
-
Contrast checked only in the default mode. Variable modes change the result.
-
Autoplaying sliders and videos with no pause control.
-
Relying on an overlay widget. It does not fix markup and can add new problems.
-
Alt text inside CMS rich text that is lost on export or in a copy. Check the image settings of images embedded in rich text after an edit.
-
A hover-only dropdown or tooltip. Unreachable by keyboard and touch.
-
Forgetting the staging site is also public. Accessibility testing on
.webflow.iois real, but so is the exposure; use the site password or a robots setting if the draft content should not be indexed.
Corrections to older tutorials
-
"The Audit panel finds all accessibility problems." It runs four checks (missing alt text, non-descriptive link content, skipped heading levels and duplicate IDs). Older material lists three, and none lists checks for contrast, labels or keyboard access.
-
"Alt text is a single field on the image." Images can be marked decorative, which outputs an empty alt, and CMS images need a bound alt text field of their own.
-
"Webflow elements are not accessible, add ARIA to everything." Navbar, Dropdown, Tabs, Slider, Lightbox and Forms provide keyboard and screen reader support, and extra ARIA on top of them can conflict with what the runtime already sets. Style the focus states and test.
-
"Interactions cannot respect reduced motion." The Interactions panel has conditional playback for the reduced-motion preference, with No animation and Skip to end.
-
"Check colour contrast with an outside tool only." The colour picker has a built-in contrast checker for text, though it does not cover images and gradients.
-
"Use a script to destroy interactions for reduced motion." That relies on an internal interface and often uses a media query written without a value, which matches even when the preference is off. Use conditional playback or a correctly written query.