diff --git a/Tests/LibWeb/Ref/css-case-insensitive-html-attributes-selector.html b/Tests/LibWeb/Ref/css-case-insensitive-html-attributes-selector.html
new file mode 100644
index 0000000000..c1c0a29911
--- /dev/null
+++ b/Tests/LibWeb/Ref/css-case-insensitive-html-attributes-selector.html
@@ -0,0 +1,12 @@
+
+
+
+
I have a red background
+I don't have a green background
diff --git a/Tests/LibWeb/Ref/reference/css-case-insensitive-html-attributes-selector-ref.html b/Tests/LibWeb/Ref/reference/css-case-insensitive-html-attributes-selector-ref.html
new file mode 100644
index 0000000000..1729f2bb21
--- /dev/null
+++ b/Tests/LibWeb/Ref/reference/css-case-insensitive-html-attributes-selector-ref.html
@@ -0,0 +1,8 @@
+
+
+I have a red background
+I don't have a green background
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
index 43cae50dc9..fd3f1aaa49 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
@@ -75,6 +75,56 @@ public:
[[nodiscard]] LengthOrCalculated parse_as_sizes_attribute();
+ // https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors
+ static constexpr Array case_insensitive_html_attributes = {
+ "accept"sv,
+ "accept-charset"sv,
+ "align"sv,
+ "alink"sv,
+ "axis"sv,
+ "bgcolor"sv,
+ "charset"sv,
+ "checked"sv,
+ "clear"sv,
+ "codetype"sv,
+ "color"sv,
+ "compact"sv,
+ "declare"sv,
+ "defer"sv,
+ "dir"sv,
+ "direction"sv,
+ "disabled"sv,
+ "enctype"sv,
+ "face"sv,
+ "frame"sv,
+ "hreflang"sv,
+ "http-equiv"sv,
+ "lang"sv,
+ "language"sv,
+ "link"sv,
+ "media"sv,
+ "method"sv,
+ "multiple"sv,
+ "nohref"sv,
+ "noresize"sv,
+ "noshade"sv,
+ "nowrap"sv,
+ "readonly"sv,
+ "rel"sv,
+ "rev"sv,
+ "rules"sv,
+ "scope"sv,
+ "scrolling"sv,
+ "selected"sv,
+ "shape"sv,
+ "target"sv,
+ "text"sv,
+ "type"sv,
+ "valign"sv,
+ "valuetype"sv,
+ "vlink"sv,
+ };
+
private:
Parser(ParsingContext const&, Vector);
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp
index 2443fa9e98..5fe7a1cbfe 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp
@@ -226,6 +226,7 @@ Parser::ParseErrorOr Parser::parse_attribute_simple_se
dbgln_if(CSS_PARSER_DEBUG, "Expected qualified-name for attribute name, got: '{}'", attribute_tokens.peek_token().to_debug_string());
return ParseError::SyntaxError;
}
+ auto qualified_name = maybe_qualified_name.release_value();
Selector::SimpleSelector simple_selector {
.type = Selector::SimpleSelector::Type::Attribute,
@@ -236,8 +237,10 @@ Parser::ParseErrorOr Parser::parse_attribute_simple_se
// they are converted to lowercase, so we do that here too. If we want to be
// correct with XML later, we'll need to keep the original case and then do
// a case-insensitive compare later.
- .qualified_name = maybe_qualified_name.release_value(),
- .case_type = Selector::SimpleSelector::Attribute::CaseType::DefaultMatch,
+ .qualified_name = qualified_name,
+ .case_type = case_insensitive_html_attributes.contains_slow(qualified_name.name.lowercase_name)
+ ? Selector::SimpleSelector::Attribute::CaseType::CaseInsensitiveMatch
+ : Selector::SimpleSelector::Attribute::CaseType::DefaultMatch,
}
};