fix: treat CSS attribute selectors as case-insensitive for HTML enumerated attributes
#17712
Closing issue
Describe the bug
<script lang="ts">
import { logout } from "./logout.remote";
</script>
<!-- Adding this form element -->
<form {...logout}></form>
<!-- 1. Does not add `svelte-*` class name in build output -->
<form method="GET">
<h1>Hello, World!</h1>
</form>
<style lang="postcss">
/* 2. Disables the following warning: */
/* Unused CSS selector "form[method="get"] :global" */
form[method="get"] :global {
h1 {
color: red;
}
}
</style>
In vite preview, the markup is:
<form method="POST" action="?/remote=" class="svelte-1uha8ag"></form>
<form method="GET"><h1>Hello, World!</h1></form>
- The
h1element is red in dev only (due to lack ofsvelte-*class name) - The unused CSS warning is incorrect (which is why it is red in dev mode)
The case sensitivity of attribute names and values depends on the document language. In HTML, attribute names are case-insensitive, as are spec-defined enumerated values. — source
Reproduction
https://github.com/hyunbinseo/svelte-kit-14963
System Info
System:
OS: Windows 11 10.0.26200
CPU: (8) x64 Intel(R) Core(TM) Ultra 7 258V
Memory: 4.66 GB / 31.48 GB
Binaries:
Node: 24.11.0 - C:\Users\hyunb\AppData\Local\fnm_multishells\25576_1763723570534\node.EXE
Yarn: 1.22.22 - C:\Users\hyunb\AppData\Local\fnm_multishells\25576_1763723570534\yarn.CMD
npm: 11.6.1 - C:\Users\hyunb\AppData\Local\fnm_multishells\25576_1763723570534\npm.CMD
pnpm: 10.23.0 - C:\Users\hyunb\AppData\Local\fnm_multishells\25576_1763723570534\pnpm.CMD
Deno: 2.4.0 - C:\Users\hyunb\.deno\bin\deno.EXE
Browsers:
Chrome: 142.0.7444.164
Edge: Chromium (140.0.3485.54)
Firefox: 145.0.1 - C:\Program Files\Mozilla Firefox\firefox.exe
npmPackages:
@sveltejs/adapter-auto: ^7.0.0 => 7.0.0
@sveltejs/kit: ^2.47.1 => 2.49.0
@sveltejs/vite-plugin-svelte: ^6.2.1 => 6.2.1
svelte: ^5.41.0 => 5.43.14
vite: ^7.1.10 => 7.2.4
Severity
serious, but I can work around it
Additional Information
No response
Pull request
Fixes #17207
CSS attribute selectors for HTML enumerated attributes (like method, type, dir, etc.) are supposed to match case-insensitively per the HTML spec. Browsers handle this correctly — form[method="get"] matches <form method="GET">. But Svelte's CSS pruning was doing a strict case-sensitive comparison, which meant:
- The selector got incorrectly flagged as unused (no
css_unused_selectorwarning was shown when spreads were involved, but the selector was still pruned) - The scoping class wasn't applied to the matching element
- Styles silently disappeared in production builds
The fix adds a set of known HTML attributes with case-insensitive enumerated values (sourced from the HTML spec) and uses it during CSS attribute selector matching. The explicit CSS s flag still overrides this behavior, as expected.
Before
<form method="GET">
<h1>Hello</h1>
</form>
<style>
form[method="get"] h1 { color: red; }
/* ^ incorrectly pruned, <h1> not styled */
</style>
After
The selector correctly matches and styles are applied.
Test plan
- Added
attribute-selector-html-case-insensitiveCSS test coveringform[method]andinput[type]cases - All 179 existing CSS tests pass
- Verified the existing
attribute-selector-case-sensitivetest (usingsflag) still works correctly - Compiler error tests and validator tests all pass
Info
🦋 Changeset detected
Latest commit: f194574
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 1 package
| Name | Type |
|---|---|
| svelte | 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
fix: treat CSS attribute selectors as case-insensitive for HTML enumerated attributes
• Feb 15, 2026, 10:10 AMCSS attribute selectors for HTML enumerated attributes (like `method`, `type`, `dir`, etc.) should match case-insensitively per the HTML spec, matching actual browser behavior. Previously, `form[method="get"]` would not match `<form method="GET">` during CSS pruning, causing the selector to be incorrectly marked as unused and the scoping class to not be applied to the element. Closes #17207
Pro tip: You can prefix GitHub URLs of issues, PRs or discussions with svcl.dev/ to view them on this page! Also try it on a GitHub release ;)