Skip to content

feat(css_analyze): add an ignore option to noUnknownFunction, noUnknownProperty, noUnknownPseudoClass & noUnknownPseudoElement#8814

Merged
Netail merged 2 commits intobiomejs:nextfrom
Netail:feat/ignore-list
Jan 23, 2026
Merged

feat(css_analyze): add an ignore option to noUnknownFunction, noUnknownProperty, noUnknownPseudoClass & noUnknownPseudoElement#8814
Netail merged 2 commits intobiomejs:nextfrom
Netail:feat/ignore-list

Conversation

@Netail
Copy link
Member

@Netail Netail commented Jan 19, 2026

Summary

Add an ignore list to noUnknownFunction, noUnknownProperty, noUnknownPseudoClass & noUnknownPseudoElement

Closes #7625 & #5554

Test Plan

Add appropriate unit tests

Docs

@changeset-bot
Copy link

changeset-bot bot commented Jan 19, 2026

🦋 Changeset detected

Latest commit: 92bcf47

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major
@biomejs/prettier-compare Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-CSS Language: CSS labels Jan 19, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 19, 2026

Walkthrough

Adds a case-insensitive ignore: Vec<String> option to four CSS lints: noUnknownFunction, noUnknownProperty, noUnknownPseudoClass, and noUnknownPseudoElement. Lint logic now checks the ignore list (via new private helpers; for pseudo-element the helpers/signature were made public) and early-exits to suppress diagnostics when a name matches. Options structs for those rules gained the ignore field with serde skip rules. New tests and .options.json files were added for each rule, plus changesets documenting minor releases.

Possibly related PRs

  • biomejs/biome PR 7745: Adds an identical ignore option and should_ignore helper to skip diagnostics for other unknown CSS constructs (at-rules); strong overlap in approach and helpers.
  • biomejs/biome PR 8403: Modifies no_unknown_property runtime logic to add early-exit behavior; shares file-level control-flow changes related to ignore/skip handling.

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding an ignore option to four specific CSS linting rules.
Description check ✅ Passed The description directly relates to the changeset, mentioning the four rules, linked issues, and test plan.
Linked Issues check ✅ Passed The PR implements an ignore list mechanism across four CSS rules, which directly addresses issue #7625's request for handling Chromium-supported properties like corner-shape without flagging them as unknown.
Out of Scope Changes check ✅ Passed All changes are directly scoped to adding ignore options to the four specified CSS linting rules and their associated tests; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@crates/biome_rule_options/src/no_unknown_function.rs`:
- Around line 6-9: The doc comment on the NoUnknownFunctionOptions::ignore field
incorrectly mentions "at-rule names" — update the comment to refer to unknown
CSS function names (case-insensitive) instead; locate the struct
NoUnknownFunctionOptions and change the documentation above the pub ignore:
Vec<String> field to something like "A list of unknown function names to ignore
(case-insensitive)." and keep the existing serde attribute and field name
unchanged.

In `@crates/biome_rule_options/src/no_unknown_property.rs`:
- Around line 6-9: Update the doc comment on NoUnknownPropertyOptions::ignore to
refer to CSS properties (not at‑rules); change the wording to something like "A
list of unknown CSS property names to ignore (case-insensitive)." Keep the serde
attribute #[serde(skip_serializing_if = "Vec::is_empty")] and the field name
ignore unchanged.

In `@crates/biome_rule_options/src/no_unknown_pseudo_class.rs`:
- Around line 6-9: Update the doc comment on the NoUnknownPseudoClassOptions
struct (and specifically the ignore field) to reference unknown pseudo-class
names instead of at‑rules; keep the existing details (that the list is
case-insensitive and that serde should skip serializing when empty) but correct
the wording to say "unknown pseudo‑class names to ignore (case-insensitive)" so
the documentation matches the option's purpose.

In `@crates/biome_rule_options/src/no_unknown_pseudo_element.rs`:
- Around line 6-10: The doc comment on the NoUnknownPseudoElementOptions struct
incorrectly refers to "at-rule names"; update the comment for the struct field
ignore to accurately describe that it is "A list of unknown pseudo-element names
to ignore (case-insensitive)." Keep the serde attribute and field name ignore
unchanged; only adjust the documentation text to reference pseudo-elements and
preserve the note about case-insensitivity.
🧹 Nitpick comments (1)
crates/biome_css_analyze/src/lint/correctness/no_unknown_property.rs (1)

145-152: Consider using iterator .any() for a more idiomatic approach.

The current implementation works correctly and is consistent with the other should_ignore implementations across the codebase. However, this could be slightly more idiomatic:

♻️ Optional refactor
 fn should_ignore(name: &str, options: &NoUnknownPropertyOptions) -> bool {
-    for ignore_pattern in &options.ignore {
-        if name.eq_ignore_ascii_case(ignore_pattern) {
-            return true;
-        }
-    }
-    false
+    options
+        .ignore
+        .iter()
+        .any(|pattern| name.eq_ignore_ascii_case(pattern))
 }

If you adopt this, you might want to apply it consistently to the other three should_ignore implementations in no_unknown_function.rs, no_unknown_pseudo_class.rs, and no_unknown_pseudo_element.rs as well.

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 19, 2026

CodSpeed Performance Report

Merging this PR will degrade performance by 16.22%

Comparing Netail:feat/ignore-list (92bcf47) with next (375792e)

Summary

❌ 5 (👁 5) regressed benchmarks
✅ 24 untouched benchmarks
⏩ 126 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
👁 css_analyzer[tachyons_11778168428173736564.css] 123.4 ms 141.5 ms -12.76%
👁 css_analyzer[pure_9395922602181450299.css] 17.1 ms 20.4 ms -16.22%
👁 css_analyzer[bulma_5641719244145477318.css] 1.1 s 1.2 s -9.03%
👁 css_analyzer[foundation_11602414662825430680.css] 165.4 ms 192.4 ms -14.02%
👁 css_analyzer[bootstrap_18416142857265205439.css] 478.9 ms 517.2 ms -7.4%

Footnotes

  1. 126 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Netail Netail changed the title feat(css_analyze): ignore list feat(css_analyze): add an ignore option to noUnknownFunction, noUnknownProperty, noUnknownPseudoClass & noUnknownPseudoElement Jan 19, 2026
Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't nursery rules, which means you're adding a feature. So it's a minor.

Also, technically, we should have a changeset for each rule. If they were four PRs, you would create a changeset for each pr

/// It doesn't trigger the rule if the pseudo-element name isn't a vendor prefix or is a pseudo-element
fn should_not_trigger(pseudo_element_name: &str) -> bool {
fn should_not_trigger(pseudo_element_name: &str, options: &NoUnknownPseudoElementOptions) -> bool {
let lowercase = pseudo_element_name.to_ascii_lowercase_cow().to_string();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we allocating a string now?

@Netail
Copy link
Member Author

Netail commented Jan 20, 2026

These aren't nursery rules, which means you're adding a feature. So it's a minor.

Into the next branch?

@ematipico
Copy link
Member

That too :)

@Netail Netail changed the base branch from main to next January 20, 2026 08:53
@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages A-Diagnostic Area: diagnostocis L-HTML Language: HTML and super languages L-Grit Language: GritQL labels Jan 20, 2026
@Netail Netail marked this pull request as draft January 20, 2026 08:55
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.changeset/rich-flowers-hunt.md:
- Line 5: The changeset contains a documentation URL referencing the incorrect
rule slug `no-unknown-selector-pseudo-element`; update that URL and any mention
in this changeset to use the correct kebab-case slug `no-unknown-pseudo-element`
(e.g., change the link to
https://biomejs.dev/linter/rules/no-unknown-pseudo-element) so it matches the
configuration schema, backend, and CHANGELOG references.
🧹 Nitpick comments (1)
crates/biome_css_analyze/src/lint/correctness/no_unknown_pseudo_element.rs (1)

155-162: Consider using iterator style.

A minor stylistic preference - the loop could be simplified:

♻️ Optional refactor using iterators
 fn should_ignore(name: &str, options: &NoUnknownPseudoElementOptions) -> bool {
-    for ignore_pattern in &options.ignore {
-        if name.eq_ignore_ascii_case(ignore_pattern) {
-            return true;
-        }
-    }
-    false
+    options
+        .ignore
+        .iter()
+        .any(|pattern| name.eq_ignore_ascii_case(pattern))
 }

"@biomejs/biome": minor
---

Added `ignore` option to [`noUnknownPseudoElement`](https://biomejs.dev/linter/rules/no-unknown-selector-pseudo-element). If an unknown pseudo-element name matches any of the items provided in `ignore`, a diagnostic won't be emitted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for references to this rule and its URL patterns
echo "=== Searching for noUnknownPseudoElement references ==="
rg -i "noUnknownPseudoElement|no-unknown.*pseudo" --type md --type json --type ts --type js | head -20

echo -e "\n=== Checking changeset files for URL patterns ==="
find .changeset -name "*.md" -type f -exec grep -H "biomejs.dev" {} \; | head -10

echo -e "\n=== Checking if rule slug exists in codebase ==="
rg "no-unknown-pseudo-element|no-unknown-selector-pseudo" --type md --type json | head -10

Repository: biomejs/biome

Length of output: 5955


Fix documentation URL in changeset.

Change no-unknown-selector-pseudo-element to no-unknown-pseudo-element — all current references in the codebase (configuration schema, backend, CHANGELOG) use the correct kebab-case slug without the redundant "selector" prefix.

🤖 Prompt for AI Agents
In @.changeset/rich-flowers-hunt.md at line 5, The changeset contains a
documentation URL referencing the incorrect rule slug
`no-unknown-selector-pseudo-element`; update that URL and any mention in this
changeset to use the correct kebab-case slug `no-unknown-pseudo-element` (e.g.,
change the link to https://biomejs.dev/linter/rules/no-unknown-pseudo-element)
so it matches the configuration schema, backend, and CHANGELOG references.

@Netail Netail marked this pull request as ready for review January 20, 2026 09:09
@github-actions github-actions bot removed the A-Project Area: project label Jan 20, 2026
@github-actions github-actions bot removed A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-HTML Language: HTML and super languages L-Grit Language: GritQL labels Jan 20, 2026
@Netail Netail requested a review from ematipico January 20, 2026 09:24
@Netail Netail removed A-CLI Area: CLI L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages A-Diagnostic Area: diagnostocis labels Jan 20, 2026
@github-actions github-actions bot added the A-Diagnostic Area: diagnostocis label Jan 23, 2026
@ematipico ematipico added this to the Biome v2.4 milestone Jan 23, 2026
Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@Netail Netail merged commit 4d9c676 into biomejs:next Jan 23, 2026
16 of 17 checks passed
@Netail Netail deleted the feat/ignore-list branch January 23, 2026 11:36
@ematipico
Copy link
Member

@Netail you should have acknowledged the benchmarks before merging... Or wait for me 😂

Please double check next time

@Netail
Copy link
Member Author

Netail commented Jan 23, 2026

@Netail you should have acknowledged the benchmarks before merging... Or wait for me 😂

Please double check next time

Ahh sorry, my apologies. Didn't knew that. Thought with the approval you already acknowledged the benchmarks😅

@ematipico
Copy link
Member

@Netail you should have acknowledged the benchmarks before merging... Or wait for me 😂
Please double check next time

Ahh sorry, my apologies. Didn't knew that. Thought with the approval you already acknowledged the benchmarks😅

Well, you still merged a PR with a red workflow :D

@Netail
Copy link
Member Author

Netail commented Jan 23, 2026

@Netail you should have acknowledged the benchmarks before merging... Or wait for me 😂
Please double check next time

Ahh sorry, my apologies. Didn't knew that. Thought with the approval you already acknowledged the benchmarks😅

Well, you still merged a PR with a red workflow :D

Ahh it needs to be approved through a link in the Codespeed comment, thought merging it when it's red will mark it as acknowledged for Codespeed too. That the failing workflow only indicated a lower benchmark

@github-actions github-actions bot mentioned this pull request Feb 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Diagnostic Area: diagnostocis A-Linter Area: linter L-CSS Language: CSS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 Add corner-shape to noUnknownProperty

2 participants