oxc-project/oxc · warning
Do not use `<{element}>` elements as they can create visual
Error message
Do not use `<{element}>` elements as they can create visual accessibility issues and are deprecated. What it means
This is the `jsx_a11y/no-distracting-elements` rule in oxlint. It fires when a JSX element is one of the configured distracting elements — by default `<marquee>` and `<blink>` (the `DistractingElement` enum plus `default_elements()`). These elements move or flash, which can trigger vestibular disorders and are deprecated in HTML, so the linter bans them.
Source
Thrown at crates/oxc_linter/src/rules/jsx_a11y/no_distracting_elements.rs:17
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::AstNode;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
LintContext,
context::ContextHost,
rule::{DefaultRuleConfig, Rule},
utils::get_element_type,
};
fn no_distracting_elements_diagnostic(span: Span, element: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"Do not use `<{element}>` elements as they can create visual accessibility issues and are deprecated."
))
.with_help(format!(
"Replace the `<{element}>` element with alternative, more accessible ways to achieve your desired visual effects."
))
.with_label(span)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
enum DistractingElement {
Marquee,
Blink,
}
fn default_elements() -> Vec<DistractingElement> {
vec![DistractingElement::Marquee, DistractingElement::Blink]
}View on GitHub (pinned to e1e7af627c)
Solutions
- Replace `<marquee>` with a CSS animation (and pause it for users with `prefers-reduced-motion`).
- Replace `<blink>` with static styled text or a subtle CSS opacity animation, also respecting `prefers-reduced-motion`.
- Restrict or extend the checked set via the rule's `elements` config if needed.
Example fix
// before
<marquee>Breaking news!</marquee>
// after
<div className="ticker" role="marquee-free"><span className="ticker-track">Breaking news!</span></div>
/* CSS: .ticker-track { animation: scroll 12s linear infinite; } @media (prefers-reduced-motion: reduce) { .ticker-track { animation: none; } } */ Defensive patterns
Strategy: validation
Validate before calling
npx oxlint --jsx-a11y/no-distracting-elements src/
Prevention
- Ban <marquee>/<blink> in code review; implement motion with CSS keyframes.
- Always pair animations with @media (prefers-reduced-motion: reduce) { animation: none; }.
- Adjust the rule's elements config if you add other banned tags.
When it happens
Trigger: Any JSX opening element whose resolved element type (via `get_element_type`, so capitalized/DOM-prefixed forms count) is `marquee` or `blink`, or another name listed in the rule's `elements` config option (lowercase serde values: `marquee`, `blink`).
Common situations: Legacy marketing pages with scrolling news tickers (`<marquee>`); old HTML pasted into React components; kitschy attention effects; enabling jsx-a11y strict configs on inherited codebases.
Related errors
- ARIA used where native HTML could suffice.
- Missing `alt` attribute.
- Invalid `alt` value.
- Missing value for `aria-label` attribute.
- Missing value for `aria-labelledby` attribute.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/c93995e19fdc3c4c.
Report an issue: GitHub.