LibWeb/CSS: Make accentColor and accentColorText take accent-color value

This commit is contained in:
Vahan Arakelyan 2026-01-26 20:25:41 +04:00 committed by Sam Atkins
parent f280bbdf69
commit d04b74555b
Notes: github-actions[bot] 2026-02-06 10:41:38 +00:00
6 changed files with 59 additions and 6 deletions

View file

@ -144,14 +144,29 @@ Optional<Color> KeywordStyleValue::to_color(ColorResolutionContext color_resolut
PreferredColorScheme scheme = color_resolution_context.color_scheme.value_or(PreferredColorScheme::Light);
// Calculate accent_color_text based on contrast to accent_color
if (keyword() == Keyword::Accentcolortext) {
// min_contrast = 10.2 is a magic number which provides the best accessibility trade-off based on:
// 1. https://webaim.org/resources/contrastchecker/
// 2. Current implementation of luminosity() and contrast_ratio() methods for Color instances
// the baseline colors with the least contrast from black and white are #757575 and #767676
// which score over 4.5 ratio for #fff and #000 accent_color_text values correspondingly
auto constexpr min_contrast = 10.2;
auto system_accent_text = SystemColor::accent_color_text(scheme);
if (color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme)).contrast_ratio(system_accent_text) < min_contrast)
return system_accent_text.inverted();
return system_accent_text;
}
// First, handle <system-color>s, since they don't strictly require a node.
// https://www.w3.org/TR/css-color-4/#css-system-colors
// https://www.w3.org/TR/css-color-4/#deprecated-system-colors
switch (keyword()) {
case Keyword::Accentcolor:
return SystemColor::accent_color(scheme);
case Keyword::Accentcolortext:
return SystemColor::accent_color_text(scheme);
return color_resolution_context.accent_color.value_or(SystemColor::accent_color(scheme));
case Keyword::Buttonborder:
case Keyword::Activeborder:
case Keyword::Inactiveborder:

View file

@ -81,6 +81,7 @@
#include <LibWeb/CSS/StyleValues/UnicodeRangeStyleValue.h>
#include <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h>
#include <LibWeb/CSS/StyleValues/ViewFunctionStyleValue.h>
#include <LibWeb/CSS/SystemColor.h>
#include <LibWeb/HTML/Navigable.h>
#include <LibWeb/Layout/Node.h>
@ -94,7 +95,8 @@ ColorResolutionContext ColorResolutionContext::for_element(DOM::AbstractElement
return {
.color_scheme = color_scheme,
.current_color = element.computed_properties()->color_or_fallback(PropertyID::Color, { color_scheme, CSS::InitialValues::color(), element.document(), calculation_resolution_context }, CSS::InitialValues::color()),
.current_color = element.computed_properties()->color_or_fallback(PropertyID::Color, { color_scheme, CSS::InitialValues::color(), CSS::SystemColor::accent_color(color_scheme), element.document(), calculation_resolution_context }, CSS::InitialValues::color()),
.accent_color = element.computed_properties()->color_or_fallback(PropertyID::AccentColor, { color_scheme, CSS::InitialValues::color(), CSS::SystemColor::accent_color(color_scheme), element.document(), calculation_resolution_context }, CSS::SystemColor::accent_color(color_scheme)),
.document = element.document(),
.calculation_resolution_context = calculation_resolution_context
};
@ -105,6 +107,7 @@ ColorResolutionContext ColorResolutionContext::for_layout_node_with_style(Layout
return {
.color_scheme = layout_node.computed_values().color_scheme(),
.current_color = layout_node.computed_values().color(),
.accent_color = layout_node.computed_values().accent_color(),
.document = layout_node.document(),
.calculation_resolution_context = { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) },
};

View file

@ -103,6 +103,7 @@ namespace Web::CSS {
struct ColorResolutionContext {
Optional<PreferredColorScheme> color_scheme;
Optional<Color> current_color;
Optional<Color> accent_color;
GC::Ptr<DOM::Document const> document;
CalculationResolutionContext calculation_resolution_context;

View file

@ -20,6 +20,7 @@
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
#include <LibWeb/CSS/StyleValues/URLStyleValue.h>
#include <LibWeb/CSS/SystemColor.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Dump.h>
#include <LibWeb/HTML/FormAssociatedElement.h>
@ -580,7 +581,8 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
auto& computed_values = mutable_computed_values();
// NOTE: color-scheme must be set first to ensure system colors can be resolved correctly.
computed_values.set_color_scheme(computed_style.color_scheme(document().page().preferred_color_scheme(), document().supported_color_schemes()));
auto color_scheme = computed_style.color_scheme(document().page().preferred_color_scheme(), document().supported_color_schemes());
computed_values.set_color_scheme(color_scheme);
// NOTE: We have to be careful that font-related properties get set in the right order.
// m_font is used by Length::to_px() when resolving sizes against this layout node.
@ -593,7 +595,8 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
// NOTE: color must be set after color-scheme to ensure currentColor can be resolved in other properties (e.g. background-color).
// NOTE: color must be set after font_size as `CalculatedStyleValue`s can rely on it being set for resolving lengths.
computed_values.set_color(computed_style.color_or_fallback(CSS::PropertyID::Color, CSS::ColorResolutionContext::for_layout_node_with_style(*this), CSS::InitialValues::color()));
// NOTE: Currently there are still discussions about `accentColor` and `currentColor` interactions, so the line below might need changing in the future
computed_values.set_accent_color(computed_style.color_or_fallback(CSS::PropertyID::AccentColor, CSS::ColorResolutionContext::for_layout_node_with_style(*this), CSS::SystemColor::accent_color(color_scheme)));
// NOTE: This color resolution context must be created after we set color above so that currentColor resolves correctly
// FIXME: We should resolve colors to their absolute forms at compute time (i.e. by implementing the relevant absolutized methods)
auto color_resolution_context = CSS::ColorResolutionContext::for_layout_node_with_style(*this);

View file

@ -0,0 +1,2 @@
Before bgColor=rgb(105, 105, 105)
After bgColor=rgb(0, 0, 255)

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<style>
:root {
accent-color: blue;
}
div#accentColorTest {
background-color: #696969;
width: 10px;
height: 10px;
}
</style>
<div id="accentColorTest"></div>
<script src="include.js"></script>
<script>
test(() => {
const divEl = document.getElementById('accentColorTest');
const bgColorBefore = getComputedStyle(divEl)['background-color'];
println(`Before bgColor=${bgColorBefore}`)
divEl.style.backgroundColor = 'accentColor';
const bgColorAfter = getComputedStyle(divEl)['background-color'];
println(`After bgColor=${bgColorAfter}`);
});
</script>