diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/button-width.txt b/Tests/LibWeb/Layout/expected/block-and-inline/button-width.txt new file mode 100644 index 00000000000000..3786f1e3e19a84 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/button-width.txt @@ -0,0 +1,29 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x58.9375 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x42.9375 children: not-inline + BlockContainer at (13,10) content-size 190x17.46875 children: not-inline + BlockContainer <(anonymous)> at (13,10) content-size 190x17.46875 flex-container(column) [FFC] children: not-inline + BlockContainer <(anonymous)> at (13,10) content-size 190x17.46875 flex-item [BFC] children: inline + line 0 width: 94.921875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 11, rect: [61,10 94.921875x17.46875] + "200px width" + TextNode <#text> + BlockContainer at (13,31.46875) content-size 324.671875x17.46875 children: not-inline + BlockContainer <(anonymous)> at (13,31.46875) content-size 324.671875x17.46875 flex-container(column) [FFC] children: not-inline + BlockContainer <(anonymous)> at (13,31.46875) content-size 324.671875x17.46875 flex-item [BFC] children: inline + line 0 width: 324.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 39, rect: [13,31.46875 324.671875x17.46875] + "auto width should behave as fit-content" + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x58.9375] + PaintableWithLines (BlockContainer) [8,8 784x42.9375] + PaintableWithLines (BlockContainer \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h index 859c18b115d8c0..f5103f2afcfec0 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.h +++ b/Userland/Libraries/LibWeb/DOM/Node.h @@ -100,6 +100,7 @@ class Node : public EventTarget { virtual bool is_html_table_row_element() const { return false; } virtual bool is_html_table_cell_element() const { return false; } virtual bool is_html_br_element() const { return false; } + virtual bool is_html_button_element() const { return false; } virtual bool is_navigable_container() const { return false; } WebIDL::ExceptionOr> pre_insert(JS::NonnullGCPtr, JS::GCPtr); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.h b/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.h index 028a94d7237223..76173781ffa47b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLButtonElement.h @@ -68,6 +68,8 @@ class HTMLButtonElement final virtual DeprecatedString value() const override; private: + virtual bool is_html_button_element() const override { return true; } + HTMLButtonElement(DOM::Document&, DOM::QualifiedName); // ^DOM::Element @@ -75,3 +77,8 @@ class HTMLButtonElement final }; } + +namespace Web::DOM { +template<> +inline bool Node::fast_is() const { return is_html_button_element(); } +} diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 5235c0833fda24..cd76a95bab8d28 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -366,11 +366,18 @@ ErrorOr TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder:: } } + // https://html.spec.whatwg.org/multipage/rendering.html#button-layout + // If the computed value of 'inline-size' is 'auto', then the used value is the fit-content inline size. + if (dom_node.is_html_button_element() && dom_node.layout_node()->computed_values().width().is_auto()) { + auto& computed_values = verify_cast(*dom_node.layout_node()).mutable_computed_values(); + computed_values.set_width(CSS::Size::make_fit_content()); + } + // https://html.spec.whatwg.org/multipage/rendering.html#button-layout // If the element is an input element, or if it is a button element and its computed value for // 'display' is not 'inline-grid', 'grid', 'inline-flex', or 'flex', then the element's box has // a child anonymous button content box with the following behaviors: - if (is(dom_node) && !display.is_grid_inside() && !display.is_flex_inside()) { + if (dom_node.is_html_button_element() && !display.is_grid_inside() && !display.is_flex_inside()) { auto& parent = *dom_node.layout_node(); // If the box does not overflow in the vertical axis, then it is centered vertically.