From 6eae92511f1e040bb66d88388b2975359251b3aa Mon Sep 17 00:00:00 2001 From: Callum Law Date: Thu, 28 Aug 2025 02:07:57 +1200 Subject: [PATCH] LibWeb: Store `border-*-width` in computed form in ComputedProperties Gains us 112 new passes since we now interpolate keywords (thick, thin, etc) correctly. Also loses us 4 WPT tests as we longer clamp negative values produced by interpolation from the point of view of getComputedStyle (although the 'used' value is still clamped). --- Libraries/LibWeb/CSS/CSSStyleProperties.cpp | 16 -- Libraries/LibWeb/CSS/ComputedProperties.cpp | 5 + Libraries/LibWeb/CSS/ComputedProperties.h | 1 + Libraries/LibWeb/CSS/StyleComputer.cpp | 53 +++- Libraries/LibWeb/CSS/StyleComputer.h | 2 + Libraries/LibWeb/Layout/Node.cpp | 14 +- Libraries/LibWeb/Layout/Node.h | 3 + .../animations/border-width-interpolation.txt | 236 +++++++++--------- 8 files changed, 183 insertions(+), 147 deletions(-) diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index c23289a7976..4de595b2526 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -790,22 +790,6 @@ RefPtr CSSStyleProperties::style_value_for_computed_property(L // -> Any other property // The resolved value is the computed value. // NOTE: This is handled inside the `default` case. - case PropertyID::BorderBottomWidth: { - auto border_bottom_width = layout_node.computed_values().border_bottom().width; - return LengthStyleValue::create(Length::make_px(border_bottom_width)); - } - case PropertyID::BorderLeftWidth: { - auto border_left_width = layout_node.computed_values().border_left().width; - return LengthStyleValue::create(Length::make_px(border_left_width)); - } - case PropertyID::BorderRightWidth: { - auto border_right_width = layout_node.computed_values().border_right().width; - return LengthStyleValue::create(Length::make_px(border_right_width)); - } - case PropertyID::BorderTopWidth: { - auto border_top_width = layout_node.computed_values().border_top().width; - return LengthStyleValue::create(Length::make_px(border_top_width)); - } case PropertyID::Contain: { auto const& contain = layout_node.computed_values().contain(); if (contain.layout_containment && contain.style_containment && contain.paint_containment) { diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index a25fe809495..d2b465598e4 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -246,6 +246,11 @@ Optional ComputedProperties::length_percentage(PropertyID id) return {}; } +Length ComputedProperties::length(PropertyID property_id) const +{ + return property(property_id).as_length().length(); +} + LengthBox ComputedProperties::length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Length const& default_value) const { LengthBox box; diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index 4963f589642..0799b09dd62 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -78,6 +78,7 @@ public: [[nodiscard]] Variant gap_value(PropertyID) const; LengthPercentage length_percentage_or_fallback(PropertyID, LengthPercentage const& fallback) const; Optional length_percentage(PropertyID) const; + Length length(PropertyID) const; LengthBox length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Length const& default_value) const; Color color_or_fallback(PropertyID, ColorResolutionContext, Color fallback) const; ColorInterpolation color_interpolation() const; diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index f9c0e160401..6819f6cad06 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1173,6 +1173,7 @@ void StyleComputer::collect_animation_into(DOM::Element& element, Optionalpage().client().device_pixels_per_css_pixel() }; // NOTE: This doesn't necessarily return the specified value if we reach into computed_properties but that @@ -2202,7 +2203,8 @@ void StyleComputer::compute_property_values(ComputedProperties& style) const .viewport_rect = viewport_rect(), .font_metrics = font_metrics, .root_font_metrics = m_root_element_font_metrics, - } + }, + .device_pixels_per_css_pixel = m_document->page().client().device_pixels_per_css_pixel() }; // NOTE: This doesn't necessarily return the specified value if we have already computed this property but that @@ -3202,9 +3204,33 @@ void StyleComputer::compute_custom_properties(ComputedProperties&, DOM::Abstract abstract_element.set_custom_properties(move(resolved_custom_properties)); } -NonnullRefPtr StyleComputer::compute_value_of_property(PropertyID property_id, NonnullRefPtr const& specified_value, Function(PropertyID)> const&, PropertyValueComputationContext const&) +static CSSPixels line_width_keyword_to_css_pixels(Keyword keyword) +{ + // https://drafts.csswg.org/css-backgrounds/#typedef-line-width + // The thin, medium, and thick keywords are equivalent to 1px, 3px, and 5px, respectively. + switch (keyword) { + case Keyword::Thin: + return CSSPixels { 1 }; + case Keyword::Medium: + return CSSPixels { 3 }; + case Keyword::Thick: + return CSSPixels { 5 }; + default: + VERIFY_NOT_REACHED(); + } +} + +NonnullRefPtr StyleComputer::compute_value_of_property(PropertyID property_id, NonnullRefPtr const& specified_value, Function(PropertyID)> const& get_property_specified_value, PropertyValueComputationContext const& computation_context) { switch (property_id) { + case PropertyID::BorderBottomWidth: + return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::BorderBottomStyle), computation_context); + case PropertyID::BorderLeftWidth: + return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::BorderLeftStyle), computation_context); + case PropertyID::BorderRightWidth: + return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::BorderRightStyle), computation_context); + case PropertyID::BorderTopWidth: + return compute_border_or_outline_width(specified_value, get_property_specified_value(PropertyID::BorderTopStyle), computation_context); default: // FIXME: We should replace this with a VERIFY_NOT_REACHED() once all properties have their own handling. return specified_value; @@ -3213,6 +3239,29 @@ NonnullRefPtr StyleComputer::compute_value_of_property(Propert VERIFY_NOT_REACHED(); } +NonnullRefPtr StyleComputer::compute_border_or_outline_width(NonnullRefPtr const& specified_value, NonnullRefPtr const& style_specified_value, PropertyValueComputationContext const& computation_context) +{ + // https://drafts.csswg.org/css-backgrounds/#border-width + // absolute length, snapped as a border width; zero if the border style is none or hidden + if (first_is_one_of(style_specified_value->to_keyword(), Keyword::None, Keyword::Hidden)) + return LengthStyleValue::create(Length::make_px(0)); + + auto const absolute_length = [&]() -> CSSPixels { + if (specified_value->is_calculated()) + return specified_value->as_calculated().resolve_length({ .length_resolution_context = computation_context.length_resolution_context })->absolute_length_to_px(); + + if (specified_value->is_length()) + return specified_value->as_length().length().to_px(computation_context.length_resolution_context); + + if (specified_value->is_keyword()) + return line_width_keyword_to_css_pixels(specified_value->to_keyword()); + + VERIFY_NOT_REACHED(); + }(); + + return LengthStyleValue::create(Length::make_px(Layout::NodeWithStyle::snap_a_length_as_a_border_width(computation_context.device_pixels_per_css_pixel, absolute_length))); +} + void StyleComputer::compute_math_depth(ComputedProperties& style, Optional element) const { // https://w3c.github.io/mathml-core/#propdef-math-depth diff --git a/Libraries/LibWeb/CSS/StyleComputer.h b/Libraries/LibWeb/CSS/StyleComputer.h index 6dcb748538c..dd2c32100c9 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Libraries/LibWeb/CSS/StyleComputer.h @@ -198,8 +198,10 @@ public: struct PropertyValueComputationContext { Length::ResolutionContext length_resolution_context; + double device_pixels_per_css_pixel; }; static NonnullRefPtr compute_value_of_property(PropertyID, NonnullRefPtr const& specified_value, Function(PropertyID)> const& get_property_specified_value, PropertyValueComputationContext const&); + static NonnullRefPtr compute_border_or_outline_width(NonnullRefPtr const& specified_value, NonnullRefPtr const& style_specified_value, PropertyValueComputationContext const&); private: virtual void visit_edges(Visitor&) override; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 3258fc74524..a59222a96f5 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -369,7 +369,7 @@ void NodeWithStyle::visit_edges(Visitor& visitor) } // https://www.w3.org/TR/css-values-4/#snap-a-length-as-a-border-width -static CSSPixels snap_a_length_as_a_border_width(double device_pixels_per_css_pixel, CSSPixels length) +CSSPixels NodeWithStyle::snap_a_length_as_a_border_width(double device_pixels_per_css_pixel, CSSPixels length) { // 1. Assert: len is non-negative. VERIFY(length >= 0); @@ -835,16 +835,8 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) border.color = computed_style.color_or_fallback(color_property, CSS::ColorResolutionContext::for_layout_node_with_style(*this), computed_values.color()); border.line_style = computed_style.line_style(style_property); - // https://w3c.github.io/csswg-drafts/css-backgrounds/#border-style - // none - // No border. Color and width are ignored (i.e., the border has width 0). Note this means that the initial value of border-image-width will also resolve to zero. - // hidden - // Same as none, but has different behavior in the border conflict resolution rules for border-collapsed tables [CSS2]. - if (border.line_style == CSS::LineStyle::None || border.line_style == CSS::LineStyle::Hidden) { - border.width = 0; - } else { - border.width = snap_a_length_as_a_border_width(document().page().client().device_pixels_per_css_pixel(), resolve_border_width(width_property)); - } + // FIXME: Interpolation can cause negative values - we clamp here but should instead clamp as part of interpolation + border.width = max(CSSPixels { 0 }, computed_style.length(width_property).absolute_length_to_px()); }; do_border_style(computed_values.border_left(), CSS::PropertyID::BorderLeftWidth, CSS::PropertyID::BorderLeftColor, CSS::PropertyID::BorderLeftStyle); diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index 6fd5fc9f12c..7778b196d6c 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -243,6 +243,9 @@ public: CSS::ImmutableComputedValues const& computed_values() const { return static_cast(*m_computed_values); } CSS::MutableComputedValues& mutable_computed_values() { return static_cast(*m_computed_values); } + // FIXME: Move this to StyleComputer once all users are migrated + static CSSPixels snap_a_length_as_a_border_width(double device_pixels_per_css_pixel, CSSPixels length); + void apply_style(CSS::ComputedProperties const&); Gfx::Font const& first_available_font() const; diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-backgrounds/animations/border-width-interpolation.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-backgrounds/animations/border-width-interpolation.txt index 81a0774fddb..45b8679d7ad 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-backgrounds/animations/border-width-interpolation.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-backgrounds/animations/border-width-interpolation.txt @@ -2,8 +2,8 @@ Harness status: OK Found 256 tests -112 Pass -144 Fail +220 Pass +36 Fail Pass CSS Transitions: property from [20px 40px 60px 80px] to [30px 50px 70px 90px] at (-0.3) should be [17px 37px 57px 77px] Pass CSS Transitions: property from [20px 40px 60px 80px] to [30px 50px 70px 90px] at (0) should be [20px 40px 60px 80px] Pass CSS Transitions: property from [20px 40px 60px 80px] to [30px 50px 70px 90px] at (0.3) should be [23px 43px 63px 83px] @@ -53,210 +53,210 @@ Pass Web Animations: property from neutral to [20px] at (0.6 Pass Web Animations: property from neutral to [20px] at (1) should be [20px] Pass Web Animations: property from neutral to [20px] at (1.5) should be [25px] Fail CSS Transitions: property from [initial] to [23px] at (-0.3) should be [0px] -Fail CSS Transitions: property from [initial] to [23px] at (0) should be [3px] -Fail CSS Transitions: property from [initial] to [23px] at (0.3) should be [9px] -Fail CSS Transitions: property from [initial] to [23px] at (0.6) should be [15px] +Pass CSS Transitions: property from [initial] to [23px] at (0) should be [3px] +Pass CSS Transitions: property from [initial] to [23px] at (0.3) should be [9px] +Pass CSS Transitions: property from [initial] to [23px] at (0.6) should be [15px] Pass CSS Transitions: property from [initial] to [23px] at (1) should be [23px] -Fail CSS Transitions: property from [initial] to [23px] at (1.5) should be [33px] +Pass CSS Transitions: property from [initial] to [23px] at (1.5) should be [33px] Fail CSS Transitions with transition: all: property from [initial] to [23px] at (-0.3) should be [0px] -Fail CSS Transitions with transition: all: property from [initial] to [23px] at (0) should be [3px] -Fail CSS Transitions with transition: all: property from [initial] to [23px] at (0.3) should be [9px] -Fail CSS Transitions with transition: all: property from [initial] to [23px] at (0.6) should be [15px] +Pass CSS Transitions with transition: all: property from [initial] to [23px] at (0) should be [3px] +Pass CSS Transitions with transition: all: property from [initial] to [23px] at (0.3) should be [9px] +Pass CSS Transitions with transition: all: property from [initial] to [23px] at (0.6) should be [15px] Pass CSS Transitions with transition: all: property from [initial] to [23px] at (1) should be [23px] -Fail CSS Transitions with transition: all: property from [initial] to [23px] at (1.5) should be [33px] +Pass CSS Transitions with transition: all: property from [initial] to [23px] at (1.5) should be [33px] Fail CSS Animations: property from [initial] to [23px] at (-0.3) should be [0px] Pass CSS Animations: property from [initial] to [23px] at (0) should be [3px] -Fail CSS Animations: property from [initial] to [23px] at (0.3) should be [9px] -Fail CSS Animations: property from [initial] to [23px] at (0.6) should be [15px] +Pass CSS Animations: property from [initial] to [23px] at (0.3) should be [9px] +Pass CSS Animations: property from [initial] to [23px] at (0.6) should be [15px] Pass CSS Animations: property from [initial] to [23px] at (1) should be [23px] -Fail CSS Animations: property from [initial] to [23px] at (1.5) should be [33px] +Pass CSS Animations: property from [initial] to [23px] at (1.5) should be [33px] Fail Web Animations: property from [initial] to [23px] at (-0.3) should be [0px] Pass Web Animations: property from [initial] to [23px] at (0) should be [3px] -Fail Web Animations: property from [initial] to [23px] at (0.3) should be [9px] -Fail Web Animations: property from [initial] to [23px] at (0.6) should be [15px] +Pass Web Animations: property from [initial] to [23px] at (0.3) should be [9px] +Pass Web Animations: property from [initial] to [23px] at (0.6) should be [15px] Pass Web Animations: property from [initial] to [23px] at (1) should be [23px] -Fail Web Animations: property from [initial] to [23px] at (1.5) should be [33px] +Pass Web Animations: property from [initial] to [23px] at (1.5) should be [33px] Fail CSS Transitions: property from [inherit] to [20px] at (-0.3) should be [0px] -Fail CSS Transitions: property from [inherit] to [20px] at (0) should be [0px] -Fail CSS Transitions: property from [inherit] to [20px] at (0.3) should be [6px] -Fail CSS Transitions: property from [inherit] to [20px] at (0.6) should be [12px] +Pass CSS Transitions: property from [inherit] to [20px] at (0) should be [0px] +Pass CSS Transitions: property from [inherit] to [20px] at (0.3) should be [6px] +Pass CSS Transitions: property from [inherit] to [20px] at (0.6) should be [12px] Pass CSS Transitions: property from [inherit] to [20px] at (1) should be [20px] -Fail CSS Transitions: property from [inherit] to [20px] at (1.5) should be [30px] +Pass CSS Transitions: property from [inherit] to [20px] at (1.5) should be [30px] Fail CSS Transitions with transition: all: property from [inherit] to [20px] at (-0.3) should be [0px] -Fail CSS Transitions with transition: all: property from [inherit] to [20px] at (0) should be [0px] -Fail CSS Transitions with transition: all: property from [inherit] to [20px] at (0.3) should be [6px] -Fail CSS Transitions with transition: all: property from [inherit] to [20px] at (0.6) should be [12px] +Pass CSS Transitions with transition: all: property from [inherit] to [20px] at (0) should be [0px] +Pass CSS Transitions with transition: all: property from [inherit] to [20px] at (0.3) should be [6px] +Pass CSS Transitions with transition: all: property from [inherit] to [20px] at (0.6) should be [12px] Pass CSS Transitions with transition: all: property from [inherit] to [20px] at (1) should be [20px] -Fail CSS Transitions with transition: all: property from [inherit] to [20px] at (1.5) should be [30px] +Pass CSS Transitions with transition: all: property from [inherit] to [20px] at (1.5) should be [30px] Fail CSS Animations: property from [inherit] to [20px] at (-0.3) should be [0px] -Fail CSS Animations: property from [inherit] to [20px] at (0) should be [0px] -Fail CSS Animations: property from [inherit] to [20px] at (0.3) should be [6px] -Fail CSS Animations: property from [inherit] to [20px] at (0.6) should be [12px] +Pass CSS Animations: property from [inherit] to [20px] at (0) should be [0px] +Pass CSS Animations: property from [inherit] to [20px] at (0.3) should be [6px] +Pass CSS Animations: property from [inherit] to [20px] at (0.6) should be [12px] Pass CSS Animations: property from [inherit] to [20px] at (1) should be [20px] -Fail CSS Animations: property from [inherit] to [20px] at (1.5) should be [30px] +Pass CSS Animations: property from [inherit] to [20px] at (1.5) should be [30px] Fail Web Animations: property from [inherit] to [20px] at (-0.3) should be [0px] -Fail Web Animations: property from [inherit] to [20px] at (0) should be [0px] -Fail Web Animations: property from [inherit] to [20px] at (0.3) should be [6px] -Fail Web Animations: property from [inherit] to [20px] at (0.6) should be [12px] +Pass Web Animations: property from [inherit] to [20px] at (0) should be [0px] +Pass Web Animations: property from [inherit] to [20px] at (0.3) should be [6px] +Pass Web Animations: property from [inherit] to [20px] at (0.6) should be [12px] Pass Web Animations: property from [inherit] to [20px] at (1) should be [20px] -Fail Web Animations: property from [inherit] to [20px] at (1.5) should be [30px] +Pass Web Animations: property from [inherit] to [20px] at (1.5) should be [30px] Fail CSS Transitions: property from [unset] to [23px] at (-0.3) should be [0px] -Fail CSS Transitions: property from [unset] to [23px] at (0) should be [3px] -Fail CSS Transitions: property from [unset] to [23px] at (0.3) should be [9px] -Fail CSS Transitions: property from [unset] to [23px] at (0.6) should be [15px] +Pass CSS Transitions: property from [unset] to [23px] at (0) should be [3px] +Pass CSS Transitions: property from [unset] to [23px] at (0.3) should be [9px] +Pass CSS Transitions: property from [unset] to [23px] at (0.6) should be [15px] Pass CSS Transitions: property from [unset] to [23px] at (1) should be [23px] -Fail CSS Transitions: property from [unset] to [23px] at (1.5) should be [33px] +Pass CSS Transitions: property from [unset] to [23px] at (1.5) should be [33px] Fail CSS Transitions with transition: all: property from [unset] to [23px] at (-0.3) should be [0px] -Fail CSS Transitions with transition: all: property from [unset] to [23px] at (0) should be [3px] -Fail CSS Transitions with transition: all: property from [unset] to [23px] at (0.3) should be [9px] -Fail CSS Transitions with transition: all: property from [unset] to [23px] at (0.6) should be [15px] +Pass CSS Transitions with transition: all: property from [unset] to [23px] at (0) should be [3px] +Pass CSS Transitions with transition: all: property from [unset] to [23px] at (0.3) should be [9px] +Pass CSS Transitions with transition: all: property from [unset] to [23px] at (0.6) should be [15px] Pass CSS Transitions with transition: all: property from [unset] to [23px] at (1) should be [23px] -Fail CSS Transitions with transition: all: property from [unset] to [23px] at (1.5) should be [33px] +Pass CSS Transitions with transition: all: property from [unset] to [23px] at (1.5) should be [33px] Fail CSS Animations: property from [unset] to [23px] at (-0.3) should be [0px] Pass CSS Animations: property from [unset] to [23px] at (0) should be [3px] -Fail CSS Animations: property from [unset] to [23px] at (0.3) should be [9px] -Fail CSS Animations: property from [unset] to [23px] at (0.6) should be [15px] +Pass CSS Animations: property from [unset] to [23px] at (0.3) should be [9px] +Pass CSS Animations: property from [unset] to [23px] at (0.6) should be [15px] Pass CSS Animations: property from [unset] to [23px] at (1) should be [23px] -Fail CSS Animations: property from [unset] to [23px] at (1.5) should be [33px] +Pass CSS Animations: property from [unset] to [23px] at (1.5) should be [33px] Fail Web Animations: property from [unset] to [23px] at (-0.3) should be [0px] Pass Web Animations: property from [unset] to [23px] at (0) should be [3px] -Fail Web Animations: property from [unset] to [23px] at (0.3) should be [9px] -Fail Web Animations: property from [unset] to [23px] at (0.6) should be [15px] +Pass Web Animations: property from [unset] to [23px] at (0.3) should be [9px] +Pass Web Animations: property from [unset] to [23px] at (0.6) should be [15px] Pass Web Animations: property from [unset] to [23px] at (1) should be [23px] -Fail Web Animations: property from [unset] to [23px] at (1.5) should be [33px] -Pass CSS Transitions: property from [0px] to [10px] at (-0.3) should be [0px] +Pass Web Animations: property from [unset] to [23px] at (1.5) should be [33px] +Fail CSS Transitions: property from [0px] to [10px] at (-0.3) should be [0px] Pass CSS Transitions: property from [0px] to [10px] at (0) should be [0px] Pass CSS Transitions: property from [0px] to [10px] at (0.3) should be [3px] Pass CSS Transitions: property from [0px] to [10px] at (0.6) should be [6px] Pass CSS Transitions: property from [0px] to [10px] at (1) should be [10px] Pass CSS Transitions: property from [0px] to [10px] at (1.5) should be [15px] -Pass CSS Transitions with transition: all: property from [0px] to [10px] at (-0.3) should be [0px] +Fail CSS Transitions with transition: all: property from [0px] to [10px] at (-0.3) should be [0px] Pass CSS Transitions with transition: all: property from [0px] to [10px] at (0) should be [0px] Pass CSS Transitions with transition: all: property from [0px] to [10px] at (0.3) should be [3px] Pass CSS Transitions with transition: all: property from [0px] to [10px] at (0.6) should be [6px] Pass CSS Transitions with transition: all: property from [0px] to [10px] at (1) should be [10px] Pass CSS Transitions with transition: all: property from [0px] to [10px] at (1.5) should be [15px] -Pass CSS Animations: property from [0px] to [10px] at (-0.3) should be [0px] +Fail CSS Animations: property from [0px] to [10px] at (-0.3) should be [0px] Pass CSS Animations: property from [0px] to [10px] at (0) should be [0px] Pass CSS Animations: property from [0px] to [10px] at (0.3) should be [3px] Pass CSS Animations: property from [0px] to [10px] at (0.6) should be [6px] Pass CSS Animations: property from [0px] to [10px] at (1) should be [10px] Pass CSS Animations: property from [0px] to [10px] at (1.5) should be [15px] -Pass Web Animations: property from [0px] to [10px] at (-0.3) should be [0px] +Fail Web Animations: property from [0px] to [10px] at (-0.3) should be [0px] Pass Web Animations: property from [0px] to [10px] at (0) should be [0px] Pass Web Animations: property from [0px] to [10px] at (0.3) should be [3px] Pass Web Animations: property from [0px] to [10px] at (0.6) should be [6px] Pass Web Animations: property from [0px] to [10px] at (1) should be [10px] Pass Web Animations: property from [0px] to [10px] at (1.5) should be [15px] Fail CSS Transitions: property from [thick] to [15px] at (-2) should be [0px] -Fail CSS Transitions: property from [thick] to [15px] at (-0.3) should be [2px] -Fail CSS Transitions: property from [thick] to [15px] at (0) should be [5px] -Fail CSS Transitions: property from [thick] to [15px] at (0.3) should be [8px] -Fail CSS Transitions: property from [thick] to [15px] at (0.6) should be [11px] +Pass CSS Transitions: property from [thick] to [15px] at (-0.3) should be [2px] +Pass CSS Transitions: property from [thick] to [15px] at (0) should be [5px] +Pass CSS Transitions: property from [thick] to [15px] at (0.3) should be [8px] +Pass CSS Transitions: property from [thick] to [15px] at (0.6) should be [11px] Pass CSS Transitions: property from [thick] to [15px] at (1) should be [15px] -Fail CSS Transitions: property from [thick] to [15px] at (1.5) should be [20px] +Pass CSS Transitions: property from [thick] to [15px] at (1.5) should be [20px] Fail CSS Transitions with transition: all: property from [thick] to [15px] at (-2) should be [0px] -Fail CSS Transitions with transition: all: property from [thick] to [15px] at (-0.3) should be [2px] -Fail CSS Transitions with transition: all: property from [thick] to [15px] at (0) should be [5px] -Fail CSS Transitions with transition: all: property from [thick] to [15px] at (0.3) should be [8px] -Fail CSS Transitions with transition: all: property from [thick] to [15px] at (0.6) should be [11px] +Pass CSS Transitions with transition: all: property from [thick] to [15px] at (-0.3) should be [2px] +Pass CSS Transitions with transition: all: property from [thick] to [15px] at (0) should be [5px] +Pass CSS Transitions with transition: all: property from [thick] to [15px] at (0.3) should be [8px] +Pass CSS Transitions with transition: all: property from [thick] to [15px] at (0.6) should be [11px] Pass CSS Transitions with transition: all: property from [thick] to [15px] at (1) should be [15px] -Fail CSS Transitions with transition: all: property from [thick] to [15px] at (1.5) should be [20px] +Pass CSS Transitions with transition: all: property from [thick] to [15px] at (1.5) should be [20px] Fail CSS Animations: property from [thick] to [15px] at (-2) should be [0px] -Fail CSS Animations: property from [thick] to [15px] at (-0.3) should be [2px] +Pass CSS Animations: property from [thick] to [15px] at (-0.3) should be [2px] Pass CSS Animations: property from [thick] to [15px] at (0) should be [5px] -Fail CSS Animations: property from [thick] to [15px] at (0.3) should be [8px] -Fail CSS Animations: property from [thick] to [15px] at (0.6) should be [11px] +Pass CSS Animations: property from [thick] to [15px] at (0.3) should be [8px] +Pass CSS Animations: property from [thick] to [15px] at (0.6) should be [11px] Pass CSS Animations: property from [thick] to [15px] at (1) should be [15px] -Fail CSS Animations: property from [thick] to [15px] at (1.5) should be [20px] +Pass CSS Animations: property from [thick] to [15px] at (1.5) should be [20px] Fail Web Animations: property from [thick] to [15px] at (-2) should be [0px] -Fail Web Animations: property from [thick] to [15px] at (-0.3) should be [2px] +Pass Web Animations: property from [thick] to [15px] at (-0.3) should be [2px] Pass Web Animations: property from [thick] to [15px] at (0) should be [5px] -Fail Web Animations: property from [thick] to [15px] at (0.3) should be [8px] -Fail Web Animations: property from [thick] to [15px] at (0.6) should be [11px] +Pass Web Animations: property from [thick] to [15px] at (0.3) should be [8px] +Pass Web Animations: property from [thick] to [15px] at (0.6) should be [11px] Pass Web Animations: property from [thick] to [15px] at (1) should be [15px] -Fail Web Animations: property from [thick] to [15px] at (1.5) should be [20px] +Pass Web Animations: property from [thick] to [15px] at (1.5) should be [20px] Fail CSS Transitions: property from [medium] to [13px] at (-2) should be [0px] Fail CSS Transitions: property from [medium] to [13px] at (-0.25) should be [0.5px] -Fail CSS Transitions: property from [medium] to [13px] at (0) should be [3px] -Fail CSS Transitions: property from [medium] to [13px] at (0.3) should be [6px] -Fail CSS Transitions: property from [medium] to [13px] at (0.6) should be [9px] +Pass CSS Transitions: property from [medium] to [13px] at (0) should be [3px] +Pass CSS Transitions: property from [medium] to [13px] at (0.3) should be [6px] +Pass CSS Transitions: property from [medium] to [13px] at (0.6) should be [9px] Pass CSS Transitions: property from [medium] to [13px] at (1) should be [13px] -Fail CSS Transitions: property from [medium] to [13px] at (1.5) should be [18px] +Pass CSS Transitions: property from [medium] to [13px] at (1.5) should be [18px] Fail CSS Transitions with transition: all: property from [medium] to [13px] at (-2) should be [0px] Fail CSS Transitions with transition: all: property from [medium] to [13px] at (-0.25) should be [0.5px] -Fail CSS Transitions with transition: all: property from [medium] to [13px] at (0) should be [3px] -Fail CSS Transitions with transition: all: property from [medium] to [13px] at (0.3) should be [6px] -Fail CSS Transitions with transition: all: property from [medium] to [13px] at (0.6) should be [9px] +Pass CSS Transitions with transition: all: property from [medium] to [13px] at (0) should be [3px] +Pass CSS Transitions with transition: all: property from [medium] to [13px] at (0.3) should be [6px] +Pass CSS Transitions with transition: all: property from [medium] to [13px] at (0.6) should be [9px] Pass CSS Transitions with transition: all: property from [medium] to [13px] at (1) should be [13px] -Fail CSS Transitions with transition: all: property from [medium] to [13px] at (1.5) should be [18px] +Pass CSS Transitions with transition: all: property from [medium] to [13px] at (1.5) should be [18px] Fail CSS Animations: property from [medium] to [13px] at (-2) should be [0px] Fail CSS Animations: property from [medium] to [13px] at (-0.25) should be [0.5px] Pass CSS Animations: property from [medium] to [13px] at (0) should be [3px] -Fail CSS Animations: property from [medium] to [13px] at (0.3) should be [6px] -Fail CSS Animations: property from [medium] to [13px] at (0.6) should be [9px] +Pass CSS Animations: property from [medium] to [13px] at (0.3) should be [6px] +Pass CSS Animations: property from [medium] to [13px] at (0.6) should be [9px] Pass CSS Animations: property from [medium] to [13px] at (1) should be [13px] -Fail CSS Animations: property from [medium] to [13px] at (1.5) should be [18px] +Pass CSS Animations: property from [medium] to [13px] at (1.5) should be [18px] Fail Web Animations: property from [medium] to [13px] at (-2) should be [0px] Fail Web Animations: property from [medium] to [13px] at (-0.25) should be [0.5px] Pass Web Animations: property from [medium] to [13px] at (0) should be [3px] -Fail Web Animations: property from [medium] to [13px] at (0.3) should be [6px] -Fail Web Animations: property from [medium] to [13px] at (0.6) should be [9px] +Pass Web Animations: property from [medium] to [13px] at (0.3) should be [6px] +Pass Web Animations: property from [medium] to [13px] at (0.6) should be [9px] Pass Web Animations: property from [medium] to [13px] at (1) should be [13px] -Fail Web Animations: property from [medium] to [13px] at (1.5) should be [18px] +Pass Web Animations: property from [medium] to [13px] at (1.5) should be [18px] Fail CSS Transitions: property from [thin] to [11px] at (-2) should be [0px] Fail CSS Transitions: property from [thin] to [11px] at (-0.3) should be [0px] -Fail CSS Transitions: property from [thin] to [11px] at (0) should be [1px] -Fail CSS Transitions: property from [thin] to [11px] at (0.3) should be [4px] -Fail CSS Transitions: property from [thin] to [11px] at (0.6) should be [7px] +Pass CSS Transitions: property from [thin] to [11px] at (0) should be [1px] +Pass CSS Transitions: property from [thin] to [11px] at (0.3) should be [4px] +Pass CSS Transitions: property from [thin] to [11px] at (0.6) should be [7px] Pass CSS Transitions: property from [thin] to [11px] at (1) should be [11px] -Fail CSS Transitions: property from [thin] to [11px] at (1.5) should be [16px] +Pass CSS Transitions: property from [thin] to [11px] at (1.5) should be [16px] Fail CSS Transitions with transition: all: property from [thin] to [11px] at (-2) should be [0px] Fail CSS Transitions with transition: all: property from [thin] to [11px] at (-0.3) should be [0px] -Fail CSS Transitions with transition: all: property from [thin] to [11px] at (0) should be [1px] -Fail CSS Transitions with transition: all: property from [thin] to [11px] at (0.3) should be [4px] -Fail CSS Transitions with transition: all: property from [thin] to [11px] at (0.6) should be [7px] +Pass CSS Transitions with transition: all: property from [thin] to [11px] at (0) should be [1px] +Pass CSS Transitions with transition: all: property from [thin] to [11px] at (0.3) should be [4px] +Pass CSS Transitions with transition: all: property from [thin] to [11px] at (0.6) should be [7px] Pass CSS Transitions with transition: all: property from [thin] to [11px] at (1) should be [11px] -Fail CSS Transitions with transition: all: property from [thin] to [11px] at (1.5) should be [16px] +Pass CSS Transitions with transition: all: property from [thin] to [11px] at (1.5) should be [16px] Fail CSS Animations: property from [thin] to [11px] at (-2) should be [0px] Fail CSS Animations: property from [thin] to [11px] at (-0.3) should be [0px] Pass CSS Animations: property from [thin] to [11px] at (0) should be [1px] -Fail CSS Animations: property from [thin] to [11px] at (0.3) should be [4px] -Fail CSS Animations: property from [thin] to [11px] at (0.6) should be [7px] +Pass CSS Animations: property from [thin] to [11px] at (0.3) should be [4px] +Pass CSS Animations: property from [thin] to [11px] at (0.6) should be [7px] Pass CSS Animations: property from [thin] to [11px] at (1) should be [11px] -Fail CSS Animations: property from [thin] to [11px] at (1.5) should be [16px] +Pass CSS Animations: property from [thin] to [11px] at (1.5) should be [16px] Fail Web Animations: property from [thin] to [11px] at (-2) should be [0px] Fail Web Animations: property from [thin] to [11px] at (-0.3) should be [0px] Pass Web Animations: property from [thin] to [11px] at (0) should be [1px] -Fail Web Animations: property from [thin] to [11px] at (0.3) should be [4px] -Fail Web Animations: property from [thin] to [11px] at (0.6) should be [7px] +Pass Web Animations: property from [thin] to [11px] at (0.3) should be [4px] +Pass Web Animations: property from [thin] to [11px] at (0.6) should be [7px] Pass Web Animations: property from [thin] to [11px] at (1) should be [11px] -Fail Web Animations: property from [thin] to [11px] at (1.5) should be [16px] -Fail CSS Transitions: property from [15px] to [thick] at (-2) should be [35px] -Fail CSS Transitions: property from [15px] to [thick] at (-0.3) should be [18px] -Fail CSS Transitions: property from [15px] to [thick] at (0) should be [15px] -Fail CSS Transitions: property from [15px] to [thick] at (0.3) should be [12px] -Fail CSS Transitions: property from [15px] to [thick] at (0.6) should be [9px] +Pass Web Animations: property from [thin] to [11px] at (1.5) should be [16px] +Pass CSS Transitions: property from [15px] to [thick] at (-2) should be [35px] +Pass CSS Transitions: property from [15px] to [thick] at (-0.3) should be [18px] +Pass CSS Transitions: property from [15px] to [thick] at (0) should be [15px] +Pass CSS Transitions: property from [15px] to [thick] at (0.3) should be [12px] +Pass CSS Transitions: property from [15px] to [thick] at (0.6) should be [9px] Pass CSS Transitions: property from [15px] to [thick] at (1) should be [5px] -Fail CSS Transitions: property from [15px] to [thick] at (1.5) should be [0px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (-2) should be [35px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (-0.3) should be [18px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (0) should be [15px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (0.3) should be [12px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (0.6) should be [9px] +Pass CSS Transitions: property from [15px] to [thick] at (1.5) should be [0px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (-2) should be [35px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (-0.3) should be [18px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (0) should be [15px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (0.3) should be [12px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (0.6) should be [9px] Pass CSS Transitions with transition: all: property from [15px] to [thick] at (1) should be [5px] -Fail CSS Transitions with transition: all: property from [15px] to [thick] at (1.5) should be [0px] -Fail CSS Animations: property from [15px] to [thick] at (-2) should be [35px] -Fail CSS Animations: property from [15px] to [thick] at (-0.3) should be [18px] +Pass CSS Transitions with transition: all: property from [15px] to [thick] at (1.5) should be [0px] +Pass CSS Animations: property from [15px] to [thick] at (-2) should be [35px] +Pass CSS Animations: property from [15px] to [thick] at (-0.3) should be [18px] Pass CSS Animations: property from [15px] to [thick] at (0) should be [15px] -Fail CSS Animations: property from [15px] to [thick] at (0.3) should be [12px] -Fail CSS Animations: property from [15px] to [thick] at (0.6) should be [9px] +Pass CSS Animations: property from [15px] to [thick] at (0.3) should be [12px] +Pass CSS Animations: property from [15px] to [thick] at (0.6) should be [9px] Pass CSS Animations: property from [15px] to [thick] at (1) should be [5px] -Fail CSS Animations: property from [15px] to [thick] at (1.5) should be [0px] -Fail Web Animations: property from [15px] to [thick] at (-2) should be [35px] -Fail Web Animations: property from [15px] to [thick] at (-0.3) should be [18px] +Pass CSS Animations: property from [15px] to [thick] at (1.5) should be [0px] +Pass Web Animations: property from [15px] to [thick] at (-2) should be [35px] +Pass Web Animations: property from [15px] to [thick] at (-0.3) should be [18px] Pass Web Animations: property from [15px] to [thick] at (0) should be [15px] -Fail Web Animations: property from [15px] to [thick] at (0.3) should be [12px] -Fail Web Animations: property from [15px] to [thick] at (0.6) should be [9px] +Pass Web Animations: property from [15px] to [thick] at (0.3) should be [12px] +Pass Web Animations: property from [15px] to [thick] at (0.6) should be [9px] Pass Web Animations: property from [15px] to [thick] at (1) should be [5px] -Fail Web Animations: property from [15px] to [thick] at (1.5) should be [0px] \ No newline at end of file +Pass Web Animations: property from [15px] to [thick] at (1.5) should be [0px] \ No newline at end of file