noUndeclaredClasses
Summary
Section titled “Summary”- Diagnostic Category:
lint/nursery/noUndeclaredClasses - This rule doesn’t have a fix.
- The default severity of this rule is information.
- This rule belongs to the following domains:
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "noUndeclaredClasses": "error" } } }}Description
Section titled “Description”Reports CSS class names in HTML class attributes that are not defined
in any <style> block or linked stylesheet available to the file.
When an HTML file has <style> blocks or <link rel="stylesheet"> elements,
every class name used in class="..." attributes is checked against the
available class definitions. Classes that are not defined are reported.
Framework style scoping
Section titled “Framework style scoping”Different frameworks scope their embedded styles differently. For the
same file, both locally and globally scoped classes are considered
valid — a scoped <style> block defines classes that are available to
that component’s own template. When traversing parent files (via
upward import traversal), only globally scoped classes are visible:
- HTML
<style>: always global. - Vue
<style>(no attribute): global. - Vue
<style scoped>: local — visible within the same component, not to child components. - Astro
<style>(default): local — visible within the same component, not to child components. - Astro
<style is:global>: global. - Svelte
<style>(default): local — visible within the same component, not to child components. Individual selectors inside:global(...)within a scoped block are still treated as global.
Components
Section titled “Components”Components (custom elements) are excluded from this check, as they may receive class names as props or use scoped styling. A component is identified by:
- Tag names starting with an uppercase letter (e.g.,
MyComponent) - Tag names containing a hyphen (e.g.,
my-component) - Member expressions (e.g.,
Component.Item)
No false positives on unstyled files
Section titled “No false positives on unstyled files”If the file has no style information (no <style> blocks and no linked
stylesheets), this rule does not emit diagnostics to avoid false positives.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”<style>.card { border: 1px solid; }</style><div class="header">Content</div><style>.card { border: 1px solid; }</style><div class="card">Content</div><style>.card { border: 1px solid; }</style><MyComponent class="any-class">Components are not checked</MyComponent>Related links
Section titled “Related links”Summary
Section titled “Summary”- Diagnostic Category:
lint/nursery/noUndeclaredClasses - This rule doesn’t have a fix.
- The default severity of this rule is information.
- This rule belongs to the following domains:
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "noUndeclaredClasses": "error" } } }}Description
Section titled “Description”Reports CSS class names in JSX className or class attributes that are not defined
in any imported CSS file.
When a JSX file imports CSS files, every class name used in className= or class=
attributes is checked against the available class definitions. Classes that are not
defined are reported.
This rule checks string literals, variable references (resolved through the semantic
model), call expressions like clsx(...) / classnames(...), object expression keys,
and array expressions. Dynamic class names that cannot be statically resolved are
silently skipped.
In Astro files, class:list={...} directives and class={...} attribute expressions
are also checked. CSS files imported in the frontmatter (import "./styles.css") are
included in the class resolution.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”import "./styles.css";export default () => <div className="missing" />;import "./styles.css";export default () => <div className="header" />;Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.