diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-vertical-align-middle.txt b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-vertical-align-middle.txt new file mode 100644 index 00000000000..7b39efb7f13 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-vertical-align-middle.txt @@ -0,0 +1,16 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x116 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x100 children: inline + InlineNode + frag 0 from TextNode start: 0, length: 4, rect: [8,49 35.15625x17] baseline: 13.296875 + "foo " + frag 1 from BlockContainer start: 0, length: 0, rect: [43,8 100x100] baseline: 54.296875 + TextNode <#text> + BlockContainer at (43,8) content-size 100x100 inline-block [BFC] children: not-inline + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x116] + PaintableWithLines (BlockContainer) [8,8 784x100] + InlinePaintable (InlineNode) + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer.thing) [43,8 100x100] diff --git a/Tests/LibWeb/Layout/input/block-and-inline/inline-block-vertical-align-middle.html b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-vertical-align-middle.html new file mode 100644 index 00000000000..bf666dd2ee4 --- /dev/null +++ b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-vertical-align-middle.html @@ -0,0 +1,9 @@ +foo \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp index 7e3207db69e..35bfc39f30f 100644 --- a/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -261,25 +261,32 @@ void LineBuilder::update_last_line() CSSPixels new_fragment_y = 0; auto y_value_for_alignment = [&](CSS::VerticalAlign vertical_align) { - CSSPixels effective_box_top = fragment.border_box_top(); + CSSPixels effective_box_top_offset = fragment.border_box_top(); + CSSPixels effective_box_bottom_offset = fragment.border_box_top(); if (fragment.is_atomic_inline()) { auto const& fragment_box_state = m_layout_state.get(static_cast(fragment.layout_node())); - effective_box_top = fragment_box_state.margin_box_top(); + effective_box_top_offset = fragment_box_state.margin_box_top(); + effective_box_bottom_offset = fragment_box_state.margin_box_bottom(); } switch (vertical_align) { case CSS::VerticalAlign::Baseline: - return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top; + return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top_offset; case CSS::VerticalAlign::Top: - return m_current_y + effective_box_top; - case CSS::VerticalAlign::Middle: + return m_current_y + effective_box_top_offset; + case CSS::VerticalAlign::Middle: { + // Align the vertical midpoint of the box with the baseline of the parent box + // plus half the x-height of the parent. + auto const x_height = CSSPixels::nearest_value_for(m_context.containing_block().first_available_font().pixel_metrics().x_height); + return m_current_y + line_box_baseline + ((effective_box_top_offset - effective_box_bottom_offset - x_height - fragment.height()) / 2); + } case CSS::VerticalAlign::Bottom: case CSS::VerticalAlign::Sub: case CSS::VerticalAlign::Super: case CSS::VerticalAlign::TextBottom: case CSS::VerticalAlign::TextTop: // FIXME: These are all 'baseline' - return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top; + return m_current_y + line_box_baseline - fragment.baseline() + effective_box_top_offset; } VERIFY_NOT_REACHED(); };