From dbdb38db949f3deb3b0aad5335d0c5e8c3bc5fc7 Mon Sep 17 00:00:00 2001 From: Dmitry Dygalo Date: Fri, 23 Jan 2026 11:09:52 +0100 Subject: [PATCH] fix: Inline `!important` styles being overwritten by stylesheet `!important` styles Signed-off-by: Dmitry Dygalo --- CHANGELOG.md | 4 ++++ bindings/c/CHANGELOG.md | 4 ++++ bindings/java/CHANGELOG.md | 4 ++++ bindings/javascript/CHANGELOG.md | 4 ++++ bindings/php/CHANGELOG.md | 4 ++++ bindings/python/CHANGELOG.md | 4 ++++ bindings/ruby/CHANGELOG.md | 4 ++++ css-inline/src/html/serializer.rs | 11 +++++++---- css-inline/tests/test_inlining.rs | 12 ++++++++++++ 9 files changed, 47 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8255685..94e196cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 ### Added diff --git a/bindings/c/CHANGELOG.md b/bindings/c/CHANGELOG.md index fbbd791b..4291b705 100644 --- a/bindings/c/CHANGELOG.md +++ b/bindings/c/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 ### Added diff --git a/bindings/java/CHANGELOG.md b/bindings/java/CHANGELOG.md index 1ddbcb09..f71224fe 100644 --- a/bindings/java/CHANGELOG.md +++ b/bindings/java/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 ### Added diff --git a/bindings/javascript/CHANGELOG.md b/bindings/javascript/CHANGELOG.md index ef7c1f9a..617143c2 100644 --- a/bindings/javascript/CHANGELOG.md +++ b/bindings/javascript/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.1] - 2025-12-29 ### Fixed diff --git a/bindings/php/CHANGELOG.md b/bindings/php/CHANGELOG.md index 55ca7aa4..8f5d05c7 100644 --- a/bindings/php/CHANGELOG.md +++ b/bindings/php/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 - Initial public release diff --git a/bindings/python/CHANGELOG.md b/bindings/python/CHANGELOG.md index 6598f972..b9b1350e 100644 --- a/bindings/python/CHANGELOG.md +++ b/bindings/python/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 ### Added diff --git a/bindings/ruby/CHANGELOG.md b/bindings/ruby/CHANGELOG.md index 06c8b4ae..84f723ff 100644 --- a/bindings/ruby/CHANGELOG.md +++ b/bindings/ruby/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Inline `!important` styles being overwritten by stylesheet `!important` styles. [#637](https://github.com/Stranger6667/css-inline/issues/637) + ## [0.19.0] - 2025-12-29 ### Added diff --git a/css-inline/src/html/serializer.rs b/css-inline/src/html/serializer.rs index c0052773..b421586c 100644 --- a/css-inline/src/html/serializer.rs +++ b/css-inline/src/html/serializer.rs @@ -557,11 +557,14 @@ fn merge_styles( }), ) { // The new rule is `!important` and there's an existing rule with the same name - // In this case, we override the existing rule with the new one + // Only override if the existing inline rule is NOT `!important`. + // Per CSS spec: inline `!important` takes precedence over stylesheet `!important` (Some(value), Some(buffer)) => { - // We keep the rule name and the colon-space suffix - ': ` - buffer.truncate(property.len().saturating_add(STYLE_SEPARATOR.len())); - write_declaration_value(buffer, value)?; + if !buffer.ends_with(b"!important") { + // We keep the rule name and the colon-space suffix - ': ` + buffer.truncate(property.len().saturating_add(STYLE_SEPARATOR.len())); + write_declaration_value(buffer, value)?; + } } // There's no existing rule with the same name, but the new rule is `!important` // In this case, we add the new rule with the `!important` suffix removed diff --git a/css-inline/tests/test_inlining.rs b/css-inline/tests/test_inlining.rs index b0c0c3a1..f1f01a75 100644 --- a/css-inline/tests/test_inlining.rs +++ b/css-inline/tests/test_inlining.rs @@ -291,6 +291,18 @@ fn important_more_specific() { ); } +#[test] +fn important_inline_wins_over_stylesheet_important() { + // Inline `!important` rules should override stylesheet `!important` rules. + // Per CSS spec: "Inline important styles take precedence over all other important author styles" + // See: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/important#inline_styles + assert_inlined!( + style = "h1 { color: blue !important; }", + body = r#"

Big Text

"#, + expected = r#"

Big Text

"# + ); +} + #[test] fn font_family_quoted() { // When property value contains double quotes