Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-use-generic-font-names-supports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#8845](https://github.com/biomejs/biome/issues/8845): [`useGenericFontNames`](https://biomejs.dev/linter/rules/use-generic-font-names/) no longer reports a false positive when `font` or `font-family` is used inside `@supports` rules for feature detection.
20 changes: 20 additions & 0 deletions crates/biome_css_analyze/src/lint/a11y/use_generic_font_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ declare_lint_rule! {
/// - Property with a keyword value such as `inherit`, `initial`.
/// - The last value being a CSS variable.
/// - `font-family` property in an `@font-face` rule.
/// - `font` or `font-family` property in an `@supports` rule (feature detection).
///
/// ## Examples
///
Expand Down Expand Up @@ -62,6 +63,10 @@ declare_lint_rule! {
/// @font-face { font-family: Gentium; }
/// ```
///
/// ```css
/// @supports (font: -apple-system-body) {}
/// ```
///
pub UseGenericFontNames {
version: "1.8.0",
name: "useGenericFontNames",
Expand All @@ -88,6 +93,12 @@ impl Rule for UseGenericFontNames {
return None;
}

// Ignore `@supports`. The font property inside @supports is used for feature detection,
// not as an actual font-family declaration.
if is_in_supports_at_rule(node) {
return None;
}

let is_font_family = property_name == "font-family";
let is_font = property_name == "font";

Expand Down Expand Up @@ -158,6 +169,15 @@ fn is_in_font_face_at_rule(node: &CssGenericProperty) -> bool {
.is_some_and(|n| matches!(n, AnyCssAtRule::CssFontFaceAtRule(_)))
}

fn is_in_supports_at_rule(node: &CssGenericProperty) -> bool {
node.syntax()
.ancestors()
.find(|n| n.kind() == CssSyntaxKind::CSS_AT_RULE)
.and_then(|n| n.cast::<CssAtRule>())
.and_then(|n| n.rule().ok())
.is_some_and(|n| matches!(n, AnyCssAtRule::CssSupportsAtRule(_)))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

fn is_shorthand_font_property_with_keyword(properties: &CssGenericComponentValueList) -> bool {
properties.into_iter().len() == 1
&& properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ a { font-family: Arial, var(--fallback); }
a { font: 1em "Noto Serif", var(--serif); }
a { font: 14px/1.5 Arial, var(--fallback); }
a { font-family: revert }
a { font-family: revert-layer }
a { font-family: revert-layer }
@supports (font: -apple-system-body) {}
@supports (font-family: -apple-system) {}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ a { font: 1em "Noto Serif", var(--serif); }
a { font: 14px/1.5 Arial, var(--fallback); }
a { font-family: revert }
a { font-family: revert-layer }
@supports (font: -apple-system-body) {}
@supports (font-family: -apple-system) {}
```
Loading