LibWeb: Support relative lengths in calc color values

Gains us ~40 WPT tests.
This commit is contained in:
Callum Law 2025-06-29 17:18:05 +12:00 committed by Sam Atkins
commit 9ab7c5d08d
Notes: github-actions[bot] 2025-07-04 12:20:09 +00:00
17 changed files with 169 additions and 74 deletions

View file

@ -226,7 +226,7 @@ Color ComputedProperties::color_or_fallback(PropertyID id, Layout::NodeWithStyle
auto const& value = property(id); auto const& value = property(id);
if (!value.has_color()) if (!value.has_color())
return fallback; return fallback;
return value.to_color(node, {}); return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) });
} }
// https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme // https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme
@ -670,7 +670,7 @@ Optional<Color> ComputedProperties::accent_color(Layout::NodeWithStyle const& no
{ {
auto const& value = property(PropertyID::AccentColor); auto const& value = property(PropertyID::AccentColor);
if (value.has_color()) if (value.has_color())
return value.to_color(node, {}); return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) });
return {}; return {};
} }
@ -924,7 +924,7 @@ Color ComputedProperties::caret_color(Layout::NodeWithStyle const& node) const
return node.computed_values().color(); return node.computed_values().color();
if (value.has_color()) if (value.has_color())
return value.to_color(node, {}); return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) });
return InitialValues::caret_color(); return InitialValues::caret_color();
} }
@ -1187,7 +1187,7 @@ Vector<ShadowData> ComputedProperties::shadow(PropertyID property_id, Layout::No
maybe_offset_y.release_value(), maybe_offset_y.release_value(),
maybe_blur_radius.release_value(), maybe_blur_radius.release_value(),
maybe_spread_distance.release_value(), maybe_spread_distance.release_value(),
value.color()->to_color(as<Layout::NodeWithStyle>(layout_node), {}), value.color()->to_color(as<Layout::NodeWithStyle>(layout_node), { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }),
value.placement() value.placement()
}; };
}; };
@ -1807,8 +1807,9 @@ Color ComputedProperties::stop_color() const
value = property(PropertyID::Color); value = property(PropertyID::Color);
} }
if (value->has_color()) { if (value->has_color()) {
// FIXME: This is used by the SVGStopElement, which does not participate in layout, // FIXME: This is used by the SVGStopElement, which does not participate in layout, so we can't pass a layout
// so can't pass a layout node (so can't resolve some colors, e.g. palette ones) // node or CalculationResolutionContext. This means we don't support all valid colors (e.g. palette
// colors, calculated values which depend on length resolution, etc)
return value->to_color({}, {}); return value->to_color({}, {});
} }
return Color::Black; return Color::Black;
@ -1893,8 +1894,8 @@ ScrollbarColorData ComputedProperties::scrollbar_color(Layout::NodeWithStyle con
if (value.is_scrollbar_color()) { if (value.is_scrollbar_color()) {
auto& scrollbar_color_value = value.as_scrollbar_color(); auto& scrollbar_color_value = value.as_scrollbar_color();
auto thumb_color = scrollbar_color_value.thumb_color()->to_color(layout_node, {}); auto thumb_color = scrollbar_color_value.thumb_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) });
auto track_color = scrollbar_color_value.track_color()->to_color(layout_node, {}); auto track_color = scrollbar_color_value.track_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) });
return { thumb_color, track_color }; return { thumb_color, track_color };
} }

View file

@ -659,6 +659,13 @@ RefPtr<CSSStyleValue const> interpolate_box_shadow(DOM::Element& element, Calcul
StyleValueVector result_shadows; StyleValueVector result_shadows;
result_shadows.ensure_capacity(from_shadows.size()); result_shadows.ensure_capacity(from_shadows.size());
Optional<Layout::NodeWithStyle const&> layout_node;
CalculationResolutionContext resolution_context;
if (auto node = element.layout_node()) {
layout_node = *node;
resolution_context.length_resolution_context = Length::ResolutionContext::for_layout_node(*node);
}
for (size_t i = 0; i < from_shadows.size(); i++) { for (size_t i = 0; i < from_shadows.size(); i++) {
auto const& from_shadow = from_shadows[i]->as_shadow(); auto const& from_shadow = from_shadows[i]->as_shadow();
auto const& to_shadow = to_shadows[i]->as_shadow(); auto const& to_shadow = to_shadows[i]->as_shadow();
@ -669,7 +676,7 @@ RefPtr<CSSStyleValue const> interpolate_box_shadow(DOM::Element& element, Calcul
if (!interpolated_offset_x || !interpolated_offset_y || !interpolated_blur_radius || !interpolated_spread_distance) if (!interpolated_offset_x || !interpolated_offset_y || !interpolated_blur_radius || !interpolated_spread_distance)
return {}; return {};
auto result_shadow = ShadowStyleValue::create( auto result_shadow = ShadowStyleValue::create(
CSSColorValue::create_from_color(interpolate_color(from_shadow.color()->to_color({}, {}), to_shadow.color()->to_color({}, {}), delta), ColorSyntax::Modern), CSSColorValue::create_from_color(interpolate_color(from_shadow.color()->to_color(layout_node, resolution_context), to_shadow.color()->to_color(layout_node, resolution_context), delta), ColorSyntax::Modern),
*interpolated_offset_x, *interpolated_offset_x,
*interpolated_offset_y, *interpolated_offset_y,
*interpolated_blur_radius, *interpolated_blur_radius,
@ -781,9 +788,13 @@ static RefPtr<CSSStyleValue const> interpolate_value_impl(DOM::Element& element,
} }
case CSSStyleValue::Type::Color: { case CSSStyleValue::Type::Color: {
Optional<Layout::NodeWithStyle const&> layout_node; Optional<Layout::NodeWithStyle const&> layout_node;
if (auto node = element.layout_node()) CalculationResolutionContext resolution_context {};
if (auto node = element.layout_node()) {
layout_node = *node; layout_node = *node;
return CSSColorValue::create_from_color(interpolate_color(from.to_color(layout_node, {}), to.to_color(layout_node, {}), delta), ColorSyntax::Modern); resolution_context.length_resolution_context = Length::ResolutionContext::for_layout_node(*node);
}
return CSSColorValue::create_from_color(interpolate_color(from.to_color(layout_node, resolution_context), to.to_color(layout_node, resolution_context), delta), ColorSyntax::Modern);
} }
case CSSStyleValue::Type::Edge: { case CSSStyleValue::Type::Edge: {
auto resolved_from = from.as_edge().resolved_value(calculation_context); auto resolved_from = from.as_edge().resolved_value(calculation_context);

View file

@ -5113,6 +5113,7 @@ RefPtr<CSSStyleValue const> Parser::parse_filter_value_list_value(TokenStream<Co
} }
Optional<Color> color = {}; Optional<Color> color = {};
if (maybe_color) if (maybe_color)
// FIXME: We should support colors which require compute-time information (i.e. `em` and `vw` to `px` ratios).
color = maybe_color->to_color({}, {}); color = maybe_color->to_color({}, {});
return if_no_more_tokens_return(FilterOperation::DropShadow { x_offset.value(), y_offset.value(), maybe_radius, color }); return if_no_more_tokens_return(FilterOperation::DropShadow { x_offset.value(), y_offset.value(), maybe_radius, color });

View file

@ -1687,10 +1687,13 @@ void Document::obtain_theme_color()
// 4. If color is not failure, then return color. // 4. If color is not failure, then return color.
if (!css_value.is_null() && css_value->has_color()) { if (!css_value.is_null() && css_value->has_color()) {
Optional<Layout::NodeWithStyle const&> root_node; Optional<Layout::NodeWithStyle const&> root_node;
if (html_element() && html_element()->layout_node()) CSS::CalculationResolutionContext resolution_context;
if (html_element() && html_element()->layout_node()) {
root_node = *html_element()->layout_node(); root_node = *html_element()->layout_node();
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*html_element()->layout_node());
}
theme_color = css_value->to_color(root_node, {}); theme_color = css_value->to_color(root_node, resolution_context);
return TraversalDecision::Break; return TraversalDecision::Break;
} }
} }

View file

@ -1174,7 +1174,8 @@ Optional<String> effective_command_value(GC::Ptr<DOM::Node> node, FlyString cons
if (!background_color.has_value()) if (!background_color.has_value())
return NumericLimits<u8>::max(); return NumericLimits<u8>::max();
VERIFY(is<Layout::NodeWithStyle>(node->layout_node())); VERIFY(is<Layout::NodeWithStyle>(node->layout_node()));
return background_color.value()->to_color(*static_cast<Layout::NodeWithStyle*>(node->layout_node()), {}).alpha(); auto& layout_node = *static_cast<Layout::NodeWithStyle*>(node->layout_node());
return background_color.value()->to_color(layout_node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(layout_node) }).alpha();
}; };
while (resolved_background_alpha() == 0 && node->parent() && is<DOM::Element>(*node->parent())) while (resolved_background_alpha() == 0 && node->parent() && is<DOM::Element>(*node->parent()))
node = node->parent(); node = node->parent();

View file

@ -14,6 +14,7 @@
#include <LibWeb/HTML/Canvas/CanvasState.h> #include <LibWeb/HTML/Canvas/CanvasState.h>
#include <LibWeb/HTML/CanvasGradient.h> #include <LibWeb/HTML/CanvasGradient.h>
#include <LibWeb/HTML/CanvasPattern.h> #include <LibWeb/HTML/CanvasPattern.h>
#include <LibWeb/Layout/Node.h>
namespace Web::HTML { namespace Web::HTML {
@ -31,13 +32,27 @@ public:
// 1. If the given value is a string, then: // 1. If the given value is a string, then:
[&](String const& string) { [&](String const& string) {
// 1. Let context be this's canvas attribute's value, if that is an element; otherwise null. // 1. Let context be this's canvas attribute's value, if that is an element; otherwise null.
HTMLCanvasElement* context = my_canvas_element().visit(
[&](HTMLCanvasElement* canvas_element) -> HTMLCanvasElement* {
return canvas_element;
},
[&](OffscreenCanvas*) -> HTMLCanvasElement* {
return nullptr;
});
// 2. Let parsedValue be the result of parsing the given value with context if non-null. // 2. Let parsedValue be the result of parsing the given value with context if non-null.
// FIXME: Parse a color value // FIXME: Parse a color value
// https://drafts.csswg.org/css-color/#parse-a-css-color-value // https://drafts.csswg.org/css-color/#parse-a-css-color-value
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color); auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
if (style_value && style_value->has_color()) { if (style_value && style_value->has_color()) {
auto parsedValue = style_value->to_color(OptionalNone(), {}); Optional<Layout::NodeWithStyle const&> layout_node;
CSS::CalculationResolutionContext resolution_context {};
if (context && context->layout_node()) {
layout_node = *context->layout_node();
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node());
}
auto parsedValue = style_value->to_color(layout_node, resolution_context);
// 4. Set this's fill style to parsedValue. // 4. Set this's fill style to parsedValue.
my_drawing_state().fill_style = parsedValue; my_drawing_state().fill_style = parsedValue;
@ -70,13 +85,27 @@ public:
// 1. If the given value is a string, then: // 1. If the given value is a string, then:
[&](String const& string) { [&](String const& string) {
// 1. Let context be this's canvas attribute's value, if that is an element; otherwise null. // 1. Let context be this's canvas attribute's value, if that is an element; otherwise null.
HTMLCanvasElement* context = my_canvas_element().visit(
[&](HTMLCanvasElement* canvas_element) -> HTMLCanvasElement* {
return canvas_element;
},
[&](OffscreenCanvas*) -> HTMLCanvasElement* {
return nullptr;
});
// 2. Let parsedValue be the result of parsing the given value with context if non-null. // 2. Let parsedValue be the result of parsing the given value with context if non-null.
// FIXME: Parse a color value // FIXME: Parse a color value
// https://drafts.csswg.org/css-color/#parse-a-css-color-value // https://drafts.csswg.org/css-color/#parse-a-css-color-value
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color); auto style_value = parse_css_value(CSS::Parser::ParsingParams(), string, CSS::PropertyID::Color);
if (style_value && style_value->has_color()) { if (style_value && style_value->has_color()) {
auto parsedValue = style_value->to_color(OptionalNone(), {}); Optional<Layout::NodeWithStyle const&> layout_node;
CSS::CalculationResolutionContext resolution_context {};
if (context && context->layout_node()) {
layout_node = *context->layout_node();
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node());
}
auto parsedValue = style_value->to_color(layout_node, resolution_context);
// 4. Set this's stroke style to parsedValue. // 4. Set this's stroke style to parsedValue.
my_drawing_state().stroke_style = parsedValue; my_drawing_state().stroke_style = parsedValue;
@ -129,6 +158,7 @@ protected:
CanvasFillStrokeStyles() = default; CanvasFillStrokeStyles() = default;
private: private:
Variant<HTMLCanvasElement*, OffscreenCanvas*> my_canvas_element() { return &reinterpret_cast<IncludingClass&>(*this).canvas_element(); }
CanvasState::DrawingState& my_drawing_state() { return reinterpret_cast<IncludingClass&>(*this).drawing_state(); } CanvasState::DrawingState& my_drawing_state() { return reinterpret_cast<IncludingClass&>(*this).drawing_state(); }
CanvasState::DrawingState const& my_drawing_state() const { return reinterpret_cast<IncludingClass const&>(*this).drawing_state(); } CanvasState::DrawingState const& my_drawing_state() const { return reinterpret_cast<IncludingClass const&>(*this).drawing_state(); }
}; };

View file

@ -937,11 +937,20 @@ String CanvasRenderingContext2D::shadow_color() const
void CanvasRenderingContext2D::set_shadow_color(String color) void CanvasRenderingContext2D::set_shadow_color(String color)
{ {
// 1. Let context be this's canvas attribute's value, if that is an element; otherwise null. // 1. Let context be this's canvas attribute's value, if that is an element; otherwise null.
auto& context = canvas_element();
// 2. Let parsedValue be the result of parsing the given value with context if non-null. // 2. Let parsedValue be the result of parsing the given value with context if non-null.
auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color); auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color);
if (style_value && style_value->has_color()) { if (style_value && style_value->has_color()) {
auto parsedValue = style_value->to_color(OptionalNone(), {}); Optional<Layout::NodeWithStyle const&> layout_node;
CSS::CalculationResolutionContext resolution_context;
if (auto node = context.layout_node()) {
layout_node = *node;
resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*node);
}
auto parsedValue = style_value->to_color(layout_node, resolution_context);
// 4. Set this's shadow color to parsedValue. // 4. Set this's shadow color to parsedValue.
drawing_state().shadow_color = parsedValue; drawing_state().shadow_color = parsedValue;

View file

@ -378,9 +378,6 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
} }
computed_values.set_color_scheme(computed_style.color_scheme(preferred_color_scheme, document().supported_color_schemes())); computed_values.set_color_scheme(computed_style.color_scheme(preferred_color_scheme, document().supported_color_schemes()));
// NOTE: color must be set second to ensure currentColor can be resolved in other properties (e.g. background-color).
computed_values.set_color(computed_style.color_or_fallback(CSS::PropertyID::Color, *this, CSS::InitialValues::color()));
// NOTE: We have to be careful that font-related properties get set in the right order. // 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. // m_font is used by Length::to_px() when resolving sizes against this layout node.
// That's why it has to be set before everything else. // That's why it has to be set before everything else.
@ -390,6 +387,10 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
computed_values.set_font_kerning(computed_style.font_kerning()); computed_values.set_font_kerning(computed_style.font_kerning());
computed_values.set_line_height(computed_style.line_height()); computed_values.set_line_height(computed_style.line_height());
// 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, *this, CSS::InitialValues::color()));
computed_values.set_vertical_align(computed_style.vertical_align()); computed_values.set_vertical_align(computed_style.vertical_align());
{ {
@ -796,7 +797,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle); do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle);
if (auto const& outline_color = computed_style.property(CSS::PropertyID::OutlineColor); outline_color.has_color()) if (auto const& outline_color = computed_style.property(CSS::PropertyID::OutlineColor); outline_color.has_color())
computed_values.set_outline_color(outline_color.to_color(*this, {})); computed_values.set_outline_color(outline_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }));
if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length()) if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length())
computed_values.set_outline_offset(outline_offset.as_length().length()); computed_values.set_outline_offset(outline_offset.as_length().length());
computed_values.set_outline_style(computed_style.outline_style()); computed_values.set_outline_style(computed_style.outline_style());
@ -836,16 +837,16 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
auto const& fill = computed_style.property(CSS::PropertyID::Fill); auto const& fill = computed_style.property(CSS::PropertyID::Fill);
if (fill.has_color()) if (fill.has_color())
computed_values.set_fill(fill.to_color(*this, {})); computed_values.set_fill(fill.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }));
else if (fill.is_url()) else if (fill.is_url())
computed_values.set_fill(fill.as_url().url()); computed_values.set_fill(fill.as_url().url());
auto const& stroke = computed_style.property(CSS::PropertyID::Stroke); auto const& stroke = computed_style.property(CSS::PropertyID::Stroke);
if (stroke.has_color()) if (stroke.has_color())
computed_values.set_stroke(stroke.to_color(*this, {})); computed_values.set_stroke(stroke.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }));
else if (stroke.is_url()) else if (stroke.is_url())
computed_values.set_stroke(stroke.as_url().url()); computed_values.set_stroke(stroke.as_url().url());
if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color()) if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color())
computed_values.set_stop_color(stop_color.to_color(*this, {})); computed_values.set_stop_color(stop_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }));
auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth); auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth);
// FIXME: Converting to pixels isn't really correct - values should be in "user units" // FIXME: Converting to pixels isn't really correct - values should be in "user units"
// https://svgwg.org/svg2-draft/coords.html#TermUserUnits // https://svgwg.org/svg2-draft/coords.html#TermUserUnits

View file

@ -586,6 +586,7 @@ Optional<BordersData> borders_data_for_outline(Layout::Node const& layout_node,
if (outline_style == CSS::OutlineStyle::Auto) { if (outline_style == CSS::OutlineStyle::Auto) {
// `auto` lets us do whatever we want for the outline. 2px of the accent colour seems reasonable. // `auto` lets us do whatever we want for the outline. 2px of the accent colour seems reasonable.
line_style = CSS::LineStyle::Solid; line_style = CSS::LineStyle::Solid;
// NOTE: CalculationResolutionContext is not required here as Accentcolor keyword value is guaranteed to not rely on it to resolve.
outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(*static_cast<Layout::NodeWithStyle const*>(&layout_node), {}); outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(*static_cast<Layout::NodeWithStyle const*>(&layout_node), {});
outline_width = 2; outline_width = 2;
} else { } else {

View file

@ -30,7 +30,7 @@ static ColorStopData resolve_color_stop_positions(Layout::NodeWithStyle const& n
resolved_color_stops.ensure_capacity(expanded_size); resolved_color_stops.ensure_capacity(expanded_size);
for (auto& stop : color_stop_list) { for (auto& stop : color_stop_list) {
auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node, {}) }; auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(node) }) };
for (int i = 0; i < color_stop_length(stop); i++) for (int i = 0; i < color_stop_length(stop); i++)
resolved_color_stops.append(resolved_stop); resolved_color_stops.append(resolved_stop);
} }

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 402 tests Found 402 tests
222 Pass 230 Pass
180 Fail 172 Fail
Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (-0.3) should be [rgb(0, 0, 0) 7px 33px 7px 33px] Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (-0.3) should be [rgb(0, 0, 0) 7px 33px 7px 33px]
Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (0) should be [rgb(0, 0, 0) 10px 30px 10px 30px] Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (0) should be [rgb(0, 0, 0) 10px 30px 10px 30px]
Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (0.3) should be [rgb(0, 0, 0) 13px 27px 13px 27px] Pass CSS Transitions: property <box-shadow> from neutral to [20px 20px 20px 20px black] at (0.3) should be [rgb(0, 0, 0) 13px 27px 13px 27px]
@ -200,49 +200,49 @@ Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-
Pass CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px] Pass CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px]
Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px] Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px]
Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px] Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px]
Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px] Pass CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px]
Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px] Fail CSS Transitions: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px]
Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px] Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px]
Pass CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px] Pass CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px]
Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px] Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px]
Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px] Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px]
Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px] Pass CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px]
Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px] Fail CSS Transitions with transition: all: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px]
Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px] Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px]
Pass CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px] Pass CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px]
Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px] Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px]
Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px] Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px]
Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px] Pass CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px]
Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px] Fail CSS Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px]
Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px] Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (-0.3) should be [rgb(0, 0, 0) 24px 16px 0px 9px]
Pass Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px] Pass Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0) should be [rgb(0, 0, 0) 15px 10px 5px 6px]
Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px] Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.3) should be [rgb(0, 38, 0) 6px 4px 11px 3px]
Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px] Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (0.6) should be [rgb(0, 77, 0) -3px -2px 17px 0px]
Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px] Pass Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1) should be [rgb(0, 128, 0) -15px -10px 25px -4px]
Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px] Fail Web Animations: property <box-shadow> from [15px 10px 5px 6px black] to [-15px -10px 25px -4px] at (1.5) should be [rgb(0, 192, 0) -30px -20px 35px -9px]
Pass CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Pass CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px] Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px]
Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px] Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px]
Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px] Pass CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px]
Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px] Fail CSS Transitions: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px]
Pass CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Pass CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px] Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px]
Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px] Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px]
Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px] Pass CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px]
Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px] Fail CSS Transitions with transition: all: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px]
Pass CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Pass CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px] Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px]
Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px] Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px]
Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px] Pass CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px]
Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px] Fail CSS Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px]
Pass Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (-0.3) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Pass Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px] Pass Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0) should be [rgb(0, 0, 0) 10px 10px 10px 10px]
Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px] Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.3) should be [rgb(0, 38, 0) 10px 10px 10px 10px]
Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px] Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (0.6) should be [rgb(0, 77, 0) 10px 10px 10px 10px]
Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px] Pass Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1) should be [rgb(0, 128, 0) 10px 10px 10px 10px]
Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px] Fail Web Animations: property <box-shadow> from [10px 10px 10px 10px black] to [10px 10px 10px 10px currentColor] at (1.5) should be [rgb(0, 192, 0) 10px 10px 10px 10px]
Fail CSS Transitions: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (-0.3) should be [rgba(255, 255, 0, 0.65) 13px 26px 0px 0px, rgb(0, 166, 0) 6.5px 39px 0px 0px inset] Fail CSS Transitions: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (-0.3) should be [rgba(255, 255, 0, 0.65) 13px 26px 0px 0px, rgb(0, 166, 0) 6.5px 39px 0px 0px inset]
Fail CSS Transitions: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (0) should be [rgba(255, 255, 0, 0.5) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 30px 0px 0px inset] Fail CSS Transitions: property <box-shadow> from [10px 20px rgba(255, 255, 0, 0.5), inset 5px 10em #008000] to [none] at (0) should be [rgba(255, 255, 0, 0.5) 10px 20px 0px 0px, rgb(0, 128, 0) 5px 30px 0px 0px inset]

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 3753 tests Found 3753 tests
3735 Pass 3747 Pass
18 Fail 6 Fail
Pass Property color value 'hsl(120 30% 50%)' Pass Property color value 'hsl(120 30% 50%)'
Pass Property color value 'hsl(120 30% 50% / 0.5)' Pass Property color value 'hsl(120 30% 50% / 0.5)'
Pass Property color value 'hsl(120 30% 50% / 50%)' Pass Property color value 'hsl(120 30% 50% / 50%)'
@ -3739,21 +3739,21 @@ Pass Property color value 'hsla(360, 37.5%, 62.5%, 0.2)' [HSL/HSLA value should
Pass Property color value 'hsla(360, 37.5%, 62.5%, 1)' [HSL/HSLA value should parse and round correctly] Pass Property color value 'hsla(360, 37.5%, 62.5%, 1)' [HSL/HSLA value should parse and round correctly]
Pass Property color value 'hsl(360, 37.5%, 75%)' [HSL/HSLA value should parse and round correctly] Pass Property color value 'hsl(360, 37.5%, 75%)' [HSL/HSLA value should parse and round correctly]
Pass Property color value 'hsla(360, 37.5%, 75%, 0)' [HSL/HSLA value should parse and round correctly] Pass Property color value 'hsla(360, 37.5%, 75%, 0)' [HSL/HSLA value should parse and round correctly]
Fail Property color value 'hsl(calc(50deg + (sign(1em - 10px) * 10deg)), 100%, 37.5%, 50%)' Pass Property color value 'hsl(calc(50deg + (sign(1em - 10px) * 10deg)), 100%, 37.5%, 50%)'
Fail Property color value 'hsla(calc(50deg + (sign(1em - 10px) * 10deg)), 100%, 37.5%, 50%)' Pass Property color value 'hsla(calc(50deg + (sign(1em - 10px) * 10deg)), 100%, 37.5%, 50%)'
Fail Property color value 'hsl(calc(50 + (sign(1em - 10px) * 10)), 100%, 37.5%, 50%)' Fail Property color value 'hsl(calc(50 + (sign(1em - 10px) * 10)), 100%, 37.5%, 50%)'
Fail Property color value 'hsla(calc(50 + (sign(1em - 10px) * 10)), 100%, 37.5%, 50%)' Fail Property color value 'hsla(calc(50 + (sign(1em - 10px) * 10)), 100%, 37.5%, 50%)'
Fail Property color value 'hsl(60deg, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsl(60deg, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsla(60deg, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsla(60deg, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsl(60, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsl(60, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsla(60, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsla(60, 100%, 37.5%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsl(calc(50deg + (sign(1em - 10px) * 10deg)) 100% 37.5% / 50%)' Pass Property color value 'hsl(calc(50deg + (sign(1em - 10px) * 10deg)) 100% 37.5% / 50%)'
Fail Property color value 'hsla(calc(50deg + (sign(1em - 10px) * 10deg)) 100% 37.5% / 50%)' Pass Property color value 'hsla(calc(50deg + (sign(1em - 10px) * 10deg)) 100% 37.5% / 50%)'
Fail Property color value 'hsl(calc(50 + (sign(1em - 10px) * 10)) 100 37.5 / 0.5)' Fail Property color value 'hsl(calc(50 + (sign(1em - 10px) * 10)) 100 37.5 / 0.5)'
Fail Property color value 'hsla(calc(50 + (sign(1em - 10px) * 10)) 100 37.5 / 0.5)' Fail Property color value 'hsla(calc(50 + (sign(1em - 10px) * 10)) 100 37.5 / 0.5)'
Fail Property color value 'hsl(60deg 100% 37.5% / calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsl(60deg 100% 37.5% / calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsla(60deg 100% 37.5% / calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hsla(60deg 100% 37.5% / calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hsl(60 100 37.5 / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'hsl(60 100 37.5 / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'hsla(60 100 37.5 / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'hsla(60 100 37.5 / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'hsla(calc(50deg + (sign(2cqw - 10px) * 10deg)), 100%, 37.5%, 51%)' Fail Property color value 'hsla(calc(50deg + (sign(2cqw - 10px) * 10deg)), 100%, 37.5%, 51%)'
Fail Property color value 'hsla(calc(50deg + (sign(2cqw - 10px) * 10deg)), 100%, 37.5%, 52%)' Fail Property color value 'hsla(calc(50deg + (sign(2cqw - 10px) * 10deg)), 100%, 37.5%, 52%)'

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 56 tests Found 56 tests
50 Pass 53 Pass
6 Fail 3 Fail
Pass Property color value 'hwb(120 30% 50%)' Pass Property color value 'hwb(120 30% 50%)'
Pass Property color value 'hwb(120 30% 50% / 0.5)' Pass Property color value 'hwb(120 30% 50% / 0.5)'
Pass Property color value 'hwb(120 30% 50% / 50%)' Pass Property color value 'hwb(120 30% 50% / 50%)'
@ -54,9 +54,9 @@ Pass Property color value 'hwb(90 50% 100%)' [HWB value should parse and round c
Pass Property color value 'hwb(90 50% 50% / 0)' [HWB value should parse and round correctly] Pass Property color value 'hwb(90 50% 50% / 0)' [HWB value should parse and round correctly]
Pass Property color value 'hwb(90 50% 50% / 0.2)' [HWB value should parse and round correctly] Pass Property color value 'hwb(90 50% 50% / 0.2)' [HWB value should parse and round correctly]
Pass Property color value 'hwb(90 50% 50% / 1)' [HWB value should parse and round correctly] Pass Property color value 'hwb(90 50% 50% / 1)' [HWB value should parse and round correctly]
Fail Property color value 'hwb(calc(110deg + (sign(1em - 10px) * 10deg)) 30% 50% / 50%)' Pass Property color value 'hwb(calc(110deg + (sign(1em - 10px) * 10deg)) 30% 50% / 50%)'
Fail Property color value 'hwb(calc(110 + (sign(1em - 10px) * 10)) 30 50 / 0.5)' Fail Property color value 'hwb(calc(110 + (sign(1em - 10px) * 10)) 30 50 / 0.5)'
Fail Property color value 'hwb(120deg 30% 50% / calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'hwb(120deg 30% 50% / calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'hwb(120 30 50 / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'hwb(120 30 50 / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'hwb(calc(110deg + (sign(2cqw - 10px) * 10deg)) 30 50 / 51%)' Fail Property color value 'hwb(calc(110deg + (sign(2cqw - 10px) * 10deg)) 30 50 / 51%)'
Fail Property color value 'hwb(calc(110deg + (sign(2cqw - 10px) * 10deg)) 30 50 / 52%)' Fail Property color value 'hwb(calc(110deg + (sign(2cqw - 10px) * 10deg)) 30 50 / 52%)'

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 99 tests Found 99 tests
79 Pass 97 Pass
20 Fail 2 Fail
Pass Property color value 'rgb(none none none)' Pass Property color value 'rgb(none none none)'
Pass Property color value 'rgb(none none none / none)' Pass Property color value 'rgb(none none none / none)'
Pass Property color value 'rgb(128 none none)' Pass Property color value 'rgb(128 none none)'
@ -83,23 +83,23 @@ Pass Property color value 'rgb(0, 0, calc(0 / 0))' [Blue channel resolves NaN eq
Pass Property color value 'rgba(0, 0, 0, calc(0 / 0))' [Alpha channel resolves NaN equivalent calc statements to zero] Pass Property color value 'rgba(0, 0, 0, calc(0 / 0))' [Alpha channel resolves NaN equivalent calc statements to zero]
Pass Property color value 'rgb(var(--high), 0, 0)' [Variables above 255 get clamped to 255.] Pass Property color value 'rgb(var(--high), 0, 0)' [Variables above 255 get clamped to 255.]
Pass Property color value 'rgb(var(--negative), 64, 128)' [Variables below 0 get clamped to 0.] Pass Property color value 'rgb(var(--negative), 64, 128)' [Variables below 0 get clamped to 0.]
Fail Property color value 'rgb(calc(50% + (sign(1em - 10px) * 10%)), 0%, 0%, 50%)' Pass Property color value 'rgb(calc(50% + (sign(1em - 10px) * 10%)), 0%, 0%, 50%)'
Fail Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)), 0%, 0%, 50%)' Pass Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)), 0%, 0%, 50%)'
Fail Property color value 'rgb(calc(50 + (sign(1em - 10px) * 10)), 0, 0, 0.5)' Pass Property color value 'rgb(calc(50 + (sign(1em - 10px) * 10)), 0, 0, 0.5)'
Fail Property color value 'rgba(calc(50 + (sign(1em - 10px) * 10)), 0, 0, 0.5)' Pass Property color value 'rgba(calc(50 + (sign(1em - 10px) * 10)), 0, 0, 0.5)'
Fail Property color value 'rgb(0%, 0%, 0%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'rgb(0%, 0%, 0%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'rgba(0%, 0%, 0%, calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'rgba(0%, 0%, 0%, calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'rgb(0, 0, 0, calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'rgb(0, 0, 0, calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'rgba(0, 0, 0, calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'rgba(0, 0, 0, calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'rgb(calc(50% + (sign(1em - 10px) * 10%)) 0% 0% / 50%)' Pass Property color value 'rgb(calc(50% + (sign(1em - 10px) * 10%)) 0% 0% / 50%)'
Fail Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)) 0% 0% / 50%)' Pass Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)) 0% 0% / 50%)'
Fail Property color value 'rgb(calc(50 + (sign(1em - 10px) * 10)) 0 0 / 0.5)' Pass Property color value 'rgb(calc(50 + (sign(1em - 10px) * 10)) 0 0 / 0.5)'
Fail Property color value 'rgba(calc(50 + (sign(1em - 10px) * 10)) 0 0 / 0.5)' Pass Property color value 'rgba(calc(50 + (sign(1em - 10px) * 10)) 0 0 / 0.5)'
Fail Property color value 'rgb(0% 0% 0% / calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'rgb(0% 0% 0% / calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'rgba(0% 0% 0% / calc(50% + (sign(1em - 10px) * 10%)))' Pass Property color value 'rgba(0% 0% 0% / calc(50% + (sign(1em - 10px) * 10%)))'
Fail Property color value 'rgb(0 0 0 / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'rgb(0 0 0 / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'rgba(0 0 0 / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'rgba(0 0 0 / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)) 0 0% / 0.5)' Pass Property color value 'rgba(calc(50% + (sign(1em - 10px) * 10%)) 0 0% / 0.5)'
Fail Property color value 'rgba(0% 0 0% / calc(0.75 + (sign(1em - 10px) * 0.1)))' Pass Property color value 'rgba(0% 0 0% / calc(0.75 + (sign(1em - 10px) * 0.1)))'
Fail Property color value 'rgba(calc(50% + (sign(2cqw - 10px) * 10%)), 0%, 0%, 51%)' Fail Property color value 'rgba(calc(50% + (sign(2cqw - 10px) * 10%)), 0%, 0%, 51%)'
Fail Property color value 'rgba(calc(50% + (sign(2cqw - 10px) * 10%)), 0%, 0%, 52%)' Fail Property color value 'rgba(calc(50% + (sign(2cqw - 10px) * 10%)), 0%, 0%, 52%)'

View file

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass currentColor is computed from the canvas element even when element is not rendered

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<title>Canvas test: 2d.fillStyle.parse.current.notrendered</title>
<script src="../../../../../resources/testharness.js"></script>
<script src="../../../../../resources/testharnessreport.js"></script>
<script src="../../../../../html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="../../../../../html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.fillStyle.parse.current.basic</h1>
<p class="desc">currentColor is computed from the canvas element</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<p class="output expectedtext">Expected output:<p><img src="../../../../../images/green-100x50.png" class="output expected" id="expected" alt="">
<ul id="d"></ul>
<script>
var t = async_test("currentColor is computed from the canvas element even when element is not rendered");
_addTest(function(canvas, ctx) {
canvas.setAttribute('style', 'color: #0f0;');
canvas.style.display = 'none';
canvas.offsetTop;
ctx.fillStyle = 'currentColor';
canvas.style.display = 'inline';
ctx.fillRect(0, 0, 100, 50);
_assertPixel(canvas, 50,25, 0,255,0,255);
});
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B