diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt
index d0a23a150e4..58e01135bf3 100644
--- a/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt
+++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-print-all.txt
@@ -175,7 +175,7 @@ user-select: auto
vertical-align: baseline
visibility: visible
white-space: normal
-width: auto
+width: 784px
word-spacing: normal
word-wrap: normal
x: 0px
diff --git a/Tests/LibWeb/Text/expected/css/getComputedStyle-relative-property-values.txt b/Tests/LibWeb/Text/expected/css/getComputedStyle-relative-property-values.txt
new file mode 100644
index 00000000000..2e92d317382
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/css/getComputedStyle-relative-property-values.txt
@@ -0,0 +1,2 @@
+ height: 4px
+width: 5px
diff --git a/Tests/LibWeb/Text/input/css/getComputedStyle-relative-property-values.html b/Tests/LibWeb/Text/input/css/getComputedStyle-relative-property-values.html
new file mode 100644
index 00000000000..8341b83e247
--- /dev/null
+++ b/Tests/LibWeb/Text/input/css/getComputedStyle-relative-property-values.html
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
index 1e533efce86..ffc8f6cfb12 100644
--- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
+++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp
@@ -196,6 +196,18 @@ static RefPtr style_value_for_shadow(Vector const&
RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout::NodeWithStyle const& layout_node, PropertyID property_id) const
{
+ auto used_value_for_property = [&layout_node](Function&& used_value_getter) -> Optional {
+ auto const& display = layout_node.computed_values().display();
+ if (!display.is_none() && !display.is_contents() && layout_node.paintable()) {
+ if (layout_node.paintable()->is_paintable_box()) {
+ auto const& paintable_box = static_cast(*layout_node.paintable());
+ return used_value_getter(paintable_box);
+ }
+ dbgln("FIXME: Support getting used value for ({})", layout_node.debug_description());
+ }
+ return {};
+ };
+
// A limited number of properties have special rules for producing their "resolved value".
// We also have to manually construct shorthands from their longhands here.
// Everything else uses the computed value.
@@ -269,20 +281,13 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(L
// -> padding-right
// -> padding-top
// -> width
- // -> A resolved value special case property like height defined in another specification
- case PropertyID::Height: {
// If the property applies to the element or pseudo-element and the resolved value of the
// display property is not none or contents, then the resolved value is the used value.
// Otherwise the resolved value is the computed value.
- auto const& display = layout_node.computed_values().display();
- if (!display.is_none() && !display.is_contents() && layout_node.paintable()) {
- if (layout_node.paintable()->is_paintable_box()) {
- auto const& paintable_box = static_cast(*layout_node.paintable());
- auto const used_height = paintable_box.content_height();
- return style_value_for_size(Size::make_px(used_height));
- }
- dbgln("FIXME: Support getting used height for ({})", layout_node.debug_description());
- }
+ case PropertyID::Height: {
+ auto maybe_used_height = used_value_for_property([](auto const& paintable_box) { return paintable_box.content_height(); });
+ if (maybe_used_height.has_value())
+ return style_value_for_size(Size::make_px(maybe_used_height.release_value()));
return style_value_for_size(layout_node.computed_values().height());
}
case PropertyID::MarginBlockEnd:
@@ -317,8 +322,12 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(L
return style_value_for_length_percentage(layout_node.computed_values().padding().right());
case PropertyID::PaddingTop:
return style_value_for_length_percentage(layout_node.computed_values().padding().top());
- case PropertyID::Width:
+ case PropertyID::Width: {
+ auto maybe_used_width = used_value_for_property([](auto const& paintable_box) { return paintable_box.content_width(); });
+ if (maybe_used_width.has_value())
+ return style_value_for_size(Size::make_px(maybe_used_width.release_value()));
return style_value_for_size(layout_node.computed_values().width());
+ }
// -> bottom
// -> left