0

Skip to content

Art direction, ready for your AI.

Become a member

Nine bugs that break animated websites built with AI, and how to fix them

Each of these reached a build of ours. None of them throws an error, which is why they survive until someone looks at the page.

Author
Nacho Seoane
Date
Reading time
6 min read
Smooth motion curves interrupted by a group of displaced frames, marked with a blue ring

In short

The bugs that survive in animated websites built with AI are the silent ones, because they fail no build and log no error. Nine of them reached our own builds. Three came from Tailwind v4 defaults, two from animations that outlast their job, two from focus and dialogs, and two from phones and autoplay. Accessibility research points the same way. WebAIM found detectable WCAG failures on 95.9% of one million home pages in 2026. Four manual checks cover all nine.

  • Prefix your keyframes, since Tailwind ships spin, ping, pulse and bounce.
  • Use arbitrary breakpoints only, because mixing them cost us 32 px of margin at 1920 pixels.
  • Test hovers and keyboard focus after every entrance animation finishes.
  • Give text masks at least 0.3 em of vertical padding.
  • Review at 375, 768, 1440 and 1920 pixels before you publish.

Why these bugs survive a passing build

These bugs fail no build and log no error, so only someone looking at the page finds them. Accessibility research shows how much that leaves behind. WebAIM’s 2026 analysis (opens in a new tab) detected WCAG failures on 95.9% of one million home pages, with an average of 56.1 errors per page, up 10.1% from 51 in 2025. In a study by AudioEye (opens in a new tab), a vendor of accessibility services, all 15 sites built by five AI tools failed WCAG Level A.

The nine bugs below all reached builds of ours made from a prompt. We fixed each one and added it to the rules we apply on every build.

Three bugs that come from Tailwind v4

Tailwind’s defaults can override what you wrote, through keyframe names, breakpoint order and the media reset. All three look like your own mistake until you read the generated CSS.

1. Your animation plays something else

Symptom: a pulse or spin you wrote behaves strangely, or does not run at all.

Cause: Tailwind ships its own animations (opens in a new tab), with 4 generic keyframe names: spin, ping, pulse and bounce. A @keyframes pulse of yours collides with theirs.

Fix: prefix every keyframe you write, such as @keyframes os-pulse.

2. Margins are wrong at one screen size

Symptom: at 1920 pixels our margins were 32 px instead of the 64 px we had asked for.

Cause: in the CSS that Tailwind v4 generated, sm: came after min-[1600px]:, so the smaller breakpoint won at wide sizes.

Fix: do not mix named and arbitrary breakpoints. Use arbitrary ones everywhere, like min-[640px]: and min-[1600px]:.

3. Large images and videos refuse to overflow

Symptom: a video meant to be larger than its frame, for a parallax or a crop, stops at the container’s width.

Cause: Tailwind’s reset (opens in a new tab) gives images and videos max-width: 100%.

Fix: add max-w-none to any media that should be larger than its container.

Two animations that outlast their job

An animation can keep control of an element after it ends, or clip the text while it runs. Both look fine in the first second, which is when most people stop watching.

4. Hovers stop working after the entrance

Symptom: a card animates in perfectly, and its hover then does nothing.

Cause: an animation with animation-fill-mode: both keeps applying its final values, and those outrank your hover styles.

Fix: remove the animation when it ends, or animate the separate translate and scale properties and leave transform to the hover.

card.addEventListener("animationend", () => {
  card.style.animation = "none";
});

5. Masked headlines lose their descenders

Symptom: the tails of g, j, p and y, and the accents on capitals, are cut off in a headline that animates line by line.

Cause: line reveals clip each line, which is what SplitText’s mask option (opens in a new tab) does with overflow: clip, and a tight line height leaves the letters taller than their box.

Fix: give the mask at least 0.3 em of vertical padding and cancel it with a negative margin. Stack the lines in a flex column, because plain block margins collapse and open up the line spacing. Then start the reveal from further down.

.line-mask {
  overflow: hidden;
  padding-block: 0.3em;
  margin-block: -0.3em;
}
.lines { display: flex; flex-direction: column; }

We animate from yPercent of about 155 for lines and 175 for single letters, so nothing shows above the mask before the reveal starts.

Two focus bugs only a keyboard finds

Focus stays behind when a panel is still hidden, or when a menu does not behave as a dialog. A mouse never reveals either one.

6. The panel opens but focus stays behind

Symptom: a menu or dialog opens, and keyboard users stay on the page behind it.

Cause: the panel fades in with a transition on visibility. When your code calls focus(), the panel is still hidden, so the call does nothing.

Fix: switch visibility instantly on opening, and animate only opacity and transform.

7. The phone menu is not a dialog

Symptom: with the menu open, a screen reader or keyboard can still reach the page behind it, and closing the menu drops you at the top.

Cause: the menu was built as a panel that covers the page, with nothing to take the page out of use.

Fix: follow the W3C pattern for modal dialogs (opens in a new tab). Make the background inert (opens in a new tab), move focus into the menu and return it to the button on close.

Two bugs that wait for a phone or a blocked video

A loose error check shows a play button nobody needs, and one missing SVG width zooms out the whole page. Neither appears on a desktop browser with autoplay on.

8. Every video error looks like blocked autoplay

Symptom: the page shows a “tap to play” button on devices where autoplay works fine.

Cause: the code treats any rejection from play() as blocked autoplay. A rejection can also mean the playback was interrupted or the format is unsupported.

Fix: check the name of the error. Only a NotAllowedError (opens in a new tab) means the browser blocked playback.

9. The whole page zooms out on phones

Symptom: on a phone, the whole page appears slightly zoomed out, with a band of space down one side.

Cause: an absolutely positioned <svg> with no width takes its width from the viewBox. In our case that was 1440 px, so it overflowed and the mobile browser zoomed out to fit it.

Fix: give every positioned SVG an explicit width.

If you build with Claude Code, the review steps in our Claude Code guide catch most of these before anyone else sees them.

Four checks that cover all nine

Four manual passes cover all nine bugs, and none of them needs a tool beyond a browser. Run them on every build, because a change to one section can bring a bug back in another.

Check How to run it Bugs covered Count
Four widths Scroll the full page at 375, 768, 1440 and 1920 px 2, 3, 5, 9 4
Pointer pass Watch every animation, then hover everything after it ends 1, 4 2
Keyboard only Tab through the page, opening and closing every panel 6, 7 2
Failed playback Point the video at a missing file: no play button should appear 8 1

Four passes mapped to the bugs in this article. The numbers refer to the sections above.

Then write each rule into the prompt, so the next build starts with it. Our guide to writing a website prompt shows where these rules go, and our comparison of video, WebGL and CSS covers the failures that depend on the technique. The templates in our catalogue are reviewed at these four widths, with keyboard and touch.

Verdict. Passing tests and a clean console prove very little for an animated site. Run the four checks on every build, because none of the nine shows up any other way, and write each rule into your prompt. All 64 of our prompts specify reduced motion, and 53 name inert.

Nacho SeoaneFounder of Orbital Supply

Directs the Orbital Supply catalogue of more than 60 websites. Since October 2026, every new prompt starts from a website that was built and reviewed first.

Questions

Short answers to what usually comes up next.

Why do AI tools keep producing these bugs?

Because nothing tells them something is wrong. These bugs pass the build and leave the console clean, and most appear only in one state, like a hover after an animation or a menu opened from the keyboard. A tool working from your words alone has no reason to look at that state unless your prompt asks for it.

How can I catch these bugs before publishing?

Run four manual passes. Load the page at 375, 768, 1440 and 1920 pixels. Hover everything after the entrance animations end. Use the page with the keyboard alone, opening and closing every panel. Then point the video at a missing file and confirm no play button appears. Those passes cover all nine bugs on this list.

Should I put these fixes in my prompt?

Yes, because a tool will not work them out by itself. Write each one as a rule, such as prefixed keyframes or an inert background behind every open menu. In our catalogue, all 64 prompts specify reduced motion, 53 name inert and 14 name NotAllowedError, and we still check the result by hand.

Are websites built with AI accessible?

Not by default. AudioEye, a company that sells accessibility services, reported that all 15 sites built by five AI tools failed WCAG Level A. Sites in general do poorly too, with 95.9% of one million home pages failing in WebAIM's 2026 analysis. State the requirement in your prompt, then test with a keyboard and a screen reader.

Do these bugs only happen with AI-generated code?

No. Each one is an ordinary front-end bug that people also write by hand, and we list them because they reached builds made from our prompts. The difference with a prompt is that you may never read the code line by line, so looking at the page becomes the main way to find them.

Do automated tests catch these bugs?

Only some of them. A scanner can flag certain missing attributes, and WebAIM counts only failures that can be detected automatically, so the true total runs higher. None of these nine bugs throws an error, so a clean console and passing tests tell you little about them. Keep your tests, and look at the page as well.

Skip the blank page

Start from a finished website.

Each template is a tested prompt with its code, assets and motion.