LibWeb: Distinguish first and last baseline sets in box_baseline()

box_baseline() applied CSS2's bottom margin edge rule for non-visible
overflow to every caller, so flex items with hidden overflow were
baseline-aligned by their margin edge instead of their text. CSS Align
scopes that rule to a box's last baseline set, while flex baseline
alignment and table cells use the first set, which always derives from
content. Parameterize box_baseline() on the requested baseline set and
propagate it through the recursive child lookup.
This commit is contained in:
Jelle Raaijmakers 2026-06-12 14:21:50 +02:00 committed by Jelle Raaijmakers
parent eb85264e44
commit cf3bb8c129
17 changed files with 256 additions and 75 deletions

View file

@ -1702,17 +1702,24 @@ void FlexFormattingContext::resolve_baseline_aligned_items()
if (!flex_line.has_baseline_aligned_items)
continue;
// FIXME: box_baseline() only understands horizontal-tb line box geometry, so baseline-aligning items with
// other writing modes would shift them by physically meaningless amounts. Skip them for now.
auto participates_in_baseline_alignment = [&](FlexItem const& item) {
return alignment_for_item(item.box) == CSS::AlignItems::Baseline
&& item.box.computed_values().writing_mode() == CSS::WritingMode::HorizontalTb;
};
CSSPixels max_baseline = 0;
for (auto& item : flex_line.items) {
if (alignment_for_item(item.box) == CSS::AlignItems::Baseline)
max_baseline = max(max_baseline, box_baseline(item.box));
if (participates_in_baseline_alignment(item))
max_baseline = max(max_baseline, box_baseline(item.box, BaselineSet::First));
}
for (auto& item : flex_line.items) {
if (alignment_for_item(item.box) != CSS::AlignItems::Baseline)
if (!participates_in_baseline_alignment(item))
continue;
auto adjustment = max_baseline - box_baseline(item.box);
auto adjustment = max_baseline - box_baseline(item.box, BaselineSet::First);
if (main_axis_is_horizontal())
item.used_values.set_content_y(item.used_values.offset.y() + adjustment);
else

View file

@ -2540,12 +2540,14 @@ CSSPixelRect FormattingContext::absolute_content_rect(Box const& box) const
return rect;
}
Box const* FormattingContext::box_child_to_derive_baseline_from(Box const& box) const
Box const* FormattingContext::box_child_to_derive_baseline_from(Box const& box, BaselineSet baseline_set) const
{
if (!box.has_children() || box.children_are_inline())
return nullptr;
// Find the last in-flow child that has a baseline (either directly via line boxes, or via its descendants).
for (auto child = box.last_child(); child; child = child->previous_sibling()) {
// Find the first/last in-flow child that has a baseline (either directly via line boxes, or via its descendants).
auto deriving_first_baseline = baseline_set == BaselineSet::First;
for (auto child = deriving_first_baseline ? box.first_child() : box.last_child(); child;
child = deriving_first_baseline ? child->next_sibling() : child->previous_sibling()) {
auto const* child_box = as_if<Box>(*child);
if (!child_box)
continue;
@ -2553,13 +2555,13 @@ Box const* FormattingContext::box_child_to_derive_baseline_from(Box const& box)
continue;
if (!m_state.get(*child_box).line_boxes.is_empty())
return child_box;
if (box_child_to_derive_baseline_from(*child_box))
if (box_child_to_derive_baseline_from(*child_box, baseline_set))
return child_box;
}
return nullptr;
}
CSSPixels FormattingContext::box_baseline(Box const& box) const
CSSPixels FormattingContext::box_baseline(Box const& box, BaselineSet baseline_set) const
{
auto const& box_state = m_state.get(box);
@ -2587,52 +2589,55 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const
}
}
// https://drafts.csswg.org/css-inline-3/#baseline-source
// auto: Specifies last-baseline alignment for inline-block, first-baseline alignment for everything else.
// NB: Callers ask an inline-level box for its last baseline set, since that is what CSS2's inline-block rule below
// describes; inline-level flex and grid containers participate with their first baseline set instead.
auto const& display = box.display();
bool is_flex_or_grid_container = display.is_flex_inside() || display.is_grid_inside();
if (display.is_inline_outside() && is_flex_or_grid_container)
baseline_set = BaselineSet::First;
// https://drafts.csswg.org/css2/#propdef-vertical-align
// The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either
// no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the
// baseline is the bottom margin edge.
// NB: This overflow exception only applies to inline-block, not to inline-flex or inline-grid containers, which
// always derive their baselines from their content per CSS Align and the respective Flexbox/Grid specs.
auto const& display = box.display();
// https://drafts.csswg.org/css-align-3/#baseline-rules
// CSS Align restates this overflow exception as only applying to the last baseline set: "for legacy reasons if its
// baseline-source is auto (the initial value) a block-level or inline-level block container that is a scroll
// container always has a last baseline set, whose baselines all correspond to its block-end margin edge". First
// baseline sets always derive from content; so do flex and grid containers, which are not block containers.
// FIXME: Per CSS Align, a scroll container's content-derived baseline position should be clamped to its border
// edge.
auto const& overflow_x = box.computed_values().overflow_x();
auto const& overflow_y = box.computed_values().overflow_y();
bool has_visible_overflow = overflow_x == CSS::Overflow::Visible && overflow_y == CSS::Overflow::Visible;
bool is_flex_or_grid_container = display.is_flex_inside() || display.is_grid_inside();
bool is_inline_flex_or_grid_container = display.is_inline_outside() && is_flex_or_grid_container;
bool always_derive_from_content = is_flex_or_grid_container || has_visible_overflow;
bool derive_baseline_from_content = baseline_set == BaselineSet::First || is_flex_or_grid_container || has_visible_overflow;
if (always_derive_from_content && !box_state.line_boxes.is_empty()) {
auto const& last_line_box = box_state.line_boxes.last();
auto last_line_box_top = last_line_box.bottom() - last_line_box.block_length();
return box_state.margin_box_top() + last_line_box_top + last_line_box.baseline();
if (derive_baseline_from_content && !box_state.line_boxes.is_empty()) {
auto const& line_box = baseline_set == BaselineSet::First ? box_state.line_boxes.first() : box_state.line_boxes.last();
auto line_box_top = line_box.bottom() - line_box.block_length();
return box_state.margin_box_top() + line_box_top + line_box.baseline();
}
// Derive baseline from block children if the box is flex/grid inside or has visible overflow.
// Derive baseline from block children if this box derives its baseline from its content.
// https://drafts.csswg.org/css-flexbox-1/#flex-baselines
// Otherwise, if the flex container has at least one flex item, the flex container's first/last main-axis baseline
// set is generated from the alignment baseline of the startmost/endmost flex item.
// https://drafts.csswg.org/css-grid-1/#grid-baselines
// Otherwise, the grid container's first (last) baseline set is generated from the alignment baseline of the first
// (last) grid item in row-major grid order.
// FIXME: This does not yet select the spec-defined startmost/endmost flex item, or the first/last grid item in
// row-major grid order.
// AD-HOC: We also derive baseline from children for <input> elements. Per the HTML spec, inputs have
// `overflow: clip !important`, so CSS2 says to use bottom margin edge. However, the internal shadow tree
// baseline should determine the control's baseline for proper alignment with adjacent text.
// https://html.spec.whatwg.org/multipage/rendering.html#form-controls
if (auto const* child_box = box_child_to_derive_baseline_from(box)) {
if (always_derive_from_content || is<HTML::HTMLInputElement>(box.dom_node())) {
if (auto const* child_box = box_child_to_derive_baseline_from(box, baseline_set)) {
if (derive_baseline_from_content || is<HTML::HTMLInputElement>(box.dom_node())) {
auto const& child_box_state = m_state.get(*child_box);
auto child_offset_from_margin_edge = child_box_state.offset.y() - child_box_state.margin_box_top();
// https://drafts.csswg.org/css-flexbox-1/#flex-baselines
// Otherwise, if the flex container has at least one flex item, the flex container's first/last main-axis
// baseline set is generated from the alignment baseline of the startmost/endmost flex item.
// https://drafts.csswg.org/css-grid-1/#grid-baselines
// Otherwise, the grid container's first (last) baseline set is generated from the alignment baseline of the
// first (last) grid item in row-major grid order.
// FIXME: This does not yet select the spec-defined startmost/endmost flex item, or the first/last grid item
// in row-major grid order.
if (is_inline_flex_or_grid_container && !child_box_state.line_boxes.is_empty() && !child_box_state.line_boxes.first().is_empty()) {
auto const& first_line_box = child_box_state.line_boxes.first();
auto first_line_box_top = first_line_box.bottom() - first_line_box.block_length();
auto child_first_line_baseline = child_box_state.margin_box_top() + first_line_box_top + first_line_box.baseline();
return box_state.margin_box_top() + child_offset_from_margin_edge + child_first_line_baseline;
}
return box_state.margin_box_top() + child_offset_from_margin_edge + box_baseline(*child_box);
return box_state.margin_box_top() + child_offset_from_margin_edge + box_baseline(*child_box, baseline_set);
}
}

View file

@ -105,6 +105,12 @@ public:
VERIFY_NOT_REACHED();
}
// https://drafts.csswg.org/css-align-3/#baseline-export
enum class BaselineSet : u8 {
First,
Last,
};
virtual void run(AvailableSpace const&) = 0;
// These functions return the automatic content dimensions of the context's root box.
@ -156,7 +162,7 @@ public:
[[nodiscard]] CSSPixelRect content_box_rect(Box const&) const;
[[nodiscard]] CSSPixelRect content_box_rect(LayoutState::UsedValues const&) const;
[[nodiscard]] CSSPixelRect content_box_rect_in_ancestor_coordinate_space(LayoutState::UsedValues const&, Box const& ancestor_box) const;
[[nodiscard]] CSSPixels box_baseline(Box const&) const;
[[nodiscard]] CSSPixels box_baseline(Box const&, BaselineSet) const;
[[nodiscard]] CSSPixels containing_block_width_for(NodeWithStyleAndBoxModelMetrics const&) const;
[[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
@ -233,7 +239,7 @@ protected:
[[nodiscard]] Optional<CSSPixels> compute_auto_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout) const;
[[nodiscard]] Box const* box_child_to_derive_baseline_from(Box const&) const;
[[nodiscard]] Box const* box_child_to_derive_baseline_from(Box const&, BaselineSet) const;
Type m_type {};
LayoutMode m_layout_mode;

View file

@ -301,7 +301,7 @@ void LineBuilder::update_last_line()
fragment_baseline = CSSPixels::nearest_value_for(font_metrics.ascent) + half_leading;
} else {
auto const& box = as<Layout::Box>(fragment.layout_node());
fragment_baseline = m_context.box_baseline(box);
fragment_baseline = m_context.box_baseline(box, FormattingContext::BaselineSet::Last);
}
// Remember the baseline used for this fragment. This will be used when painting the fragment.

View file

@ -1037,7 +1037,10 @@ void TableFormattingContext::compute_table_height()
independent_formatting_context->parent_context_did_dimension_child_root_box();
}
cell.baseline = box_baseline(cell.box);
// https://drafts.csswg.org/css2/#height-layout
// The baseline of a cell is the baseline of the first in-flow line box in the cell, or the first in-flow
// table-row in the cell, whichever comes first.
cell.baseline = box_baseline(cell.box, BaselineSet::First);
// Implements https://www.w3.org/TR/css-tables-3/#computing-the-table-height
@ -1129,7 +1132,7 @@ void TableFormattingContext::compute_table_height()
independent_formatting_context->parent_context_did_dimension_child_root_box();
}
cell.baseline = box_baseline(cell.box);
cell.baseline = box_baseline(cell.box, BaselineSet::First);
if (!row.is_collapsed) {
row.reference_height = max(row.reference_height, cell_state.border_box_height());

View file

@ -3,7 +3,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 23 0+0+8] children: inline
frag 0 from Box start: 0, length: 0, rect: [8,8 23.671875x23] baseline: 17.5
Box <div.flex> at [8,8] flex-container(row) [0+0+0 23.671875 0+0+0] [0+0+0 23 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
BlockContainer <(anonymous)> at [8,8] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.tall> at [8,8] flex-item [0+0+0 17.828125 0+0+0] [0+0+0 23 0+0+0] [BFC] children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 17.828125x23] baseline: 17.5
@ -15,7 +15,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children
frag 0 from TextNode start: 0, length: 1, rect: [25.828125,16.5 5.84375x12] baseline: 9
"B"
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [8,8] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
@ -23,11 +23,11 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x39]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x23]
PaintableBox (Box<DIV>.flex) [8,8 23.671875x23]
PaintableWithLines (BlockContainer(anonymous)) [8,8 0x0]
PaintableWithLines (BlockContainer<SPAN>.tall) [8,8 17.828125x23]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<SPAN>.short) [25.828125,16.5 5.84375x12]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,8 0x0]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x39] [children: 0] (z-index: auto)

View file

@ -0,0 +1,77 @@
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children: not-inline
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 136 0+0+0] [BFC] children: not-inline
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 120 0+0+8] children: not-inline
Box <div.row> at [8,8] flex-container(row) [0+0+0 784 0+0+0] [0+0+0 24 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.icon> at [8,8.796875] flex-item [0+0+0 16 0+0+0] [0+0+0 16 0+0+0] [BFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.text> at [24,8] flex-item [0+0+0 64 0+0+0] [0+0+0 24 0+0+0] [BFC] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [24,8 64x24] baseline: 16.796875
"Text"
TextNode <#text> (not painted)
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [8,32] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline
TextNode <#text> (not painted)
Box <div.row> at [8,32] flex-container(row) [0+0+0 784 0+0+0] [0+0+0 48 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.icon> at [8,32.796875] flex-item [0+0+0 16 0+0+0] [0+0+0 16 0+0+0] [BFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.text> at [24,32] flex-item [0+0+0 64 0+0+0] [0+0+0 48 0+0+0] [BFC] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [24,32 64x24] baseline: 16.796875
"Text"
frag 1 from TextNode start: 5, length: 4, rect: [24,56 64x24] baseline: 16.796875
"Text"
TextNode <#text> (not painted)
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [8,80] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline
TextNode <#text> (not painted)
Box <div.row> at [8,80] flex-container(row) [0+0+0 784 0+0+0] [0+0+0 48 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span.icon> at [8,80.796875] flex-item [0+0+0 16 0+0+0] [0+0+0 16 0+0+0] [BFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <div.text> at [24,80] flex-item [0+0+0 64 0+0+0] [0+0+0 48 0+0+0] [BFC] children: not-inline
BlockContainer <p> at [24,80] [0+0+0 64 0+0+0] [0+0+0 24 0+0+0] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [24,80 64x24] baseline: 16.796875
"Text"
TextNode <#text> (not painted)
BlockContainer <p> at [24,104] [0+0+0 64 0+0+0] [0+0+0 24 0+0+0] children: inline
frag 0 from TextNode start: 0, length: 4, rect: [24,104 64x24] baseline: 16.796875
"Text"
TextNode <#text> (not painted)
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [8,128] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline
TextNode <#text> (not painted)
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x136]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x120]
PaintableBox (Box<DIV>.row) [8,8 784x24]
PaintableWithLines (BlockContainer<SPAN>.icon) [8,8.796875 16x16]
PaintableWithLines (BlockContainer<SPAN>.text) [24,8 64x24]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,32 784x0]
PaintableBox (Box<DIV>.row) [8,32 784x48]
PaintableWithLines (BlockContainer<SPAN>.icon) [8,32.796875 16x16]
PaintableWithLines (BlockContainer<SPAN>.text) [24,32 64x48]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,80 784x0]
PaintableBox (Box<DIV>.row) [8,80 784x48]
PaintableWithLines (BlockContainer<SPAN>.icon) [8,80.796875 16x16]
PaintableWithLines (BlockContainer<DIV>.text) [24,80 64x48]
PaintableWithLines (BlockContainer<P>) [24,80 64x24]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<P>) [24,104 64x24]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,128 784x0]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x136] [children: 0] (z-index: auto)

View file

@ -17,18 +17,18 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children
BlockContainer <(anonymous)> at [0,0] [0+0+0 800 0+0+0] [0+0+0 0 0+0+0] children: inline
TextNode <#text> (not painted)
BlockContainer <div#toolbarContainer> at [1,2] positioned [0+0+1 798 1+0+0] [0+0+2 28 2+0+0] children: inline
frag 0 from Box start: 0, length: 0, rect: [1,2 798x28] baseline: 14
frag 0 from Box start: 0, length: 0, rect: [1,2 798x28] baseline: 27.796875
TextNode <#text> (not painted)
Box <div#toolbarViewer.toolbarHorizontalGroup> at [1,2] flex-container(row) [0+0+0 798 0+0+0] [0+0+0 28 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
BlockContainer <(anonymous)> at [1,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
TextNode <#text> (not painted)
Box <div#toolbarViewerLeft.toolbarHorizontalGroup> at [9,2] flex-container(row) flex-item [8+0+0 240.359375 0+0+0] [0+0+0 28 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
BlockContainer <(anonymous)> at [9,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
TextNode <#text> (not painted)
Box <button#viewsManagerToggleButton.toolbarButton> at [9,2] positioned flex-container(row) flex-item [0+0+0 28 0+0+0] [0+0+0 28 0+0+0] [FFC] children: not-inline
BlockContainer <(anonymous)> at [15,8] flex-item [0+0+0 16 0+0+0] [0+0+0 16 0+0+0] [BFC] children: inline
GeneratedTextNode <(anonymous)> (not painted)
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
BlockContainer <(anonymous)> at [9,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <span> at [31,16] flex-item [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
frag 0 from TextNode start: 0, length: 6, rect: [31,16 56.34375x18] baseline: 13.796875
@ -325,15 +325,15 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children
frag 0 from TextNode start: 0, length: 5, rect: [793,16 46.59375x18] baseline: 13.796875
"Tools"
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [771,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [771,30] [0+0+0 28 0+0+0] [0+0+0 0 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [585,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
BlockContainer <(anonymous)> at [1,2] [0+0+0 0 0+0+0] [0+0+0 0 0+0+0] [BFC] children: inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
TextNode <#text> (not painted)
@ -395,9 +395,12 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0]
PaintableWithLines (BlockContainer<DIV>#toolbarContainer) [0,0 800x32]
PaintableBox (Box<DIV>#toolbarViewer.toolbarHorizontalGroup) [1,2 798x28]
PaintableWithLines (BlockContainer(anonymous)) [1,2 0x0]
PaintableBox (Box<DIV>#toolbarViewerLeft.toolbarHorizontalGroup) [9,2 240.359375x28]
PaintableWithLines (BlockContainer(anonymous)) [9,2 0x0]
PaintableBox (Box<BUTTON>#viewsManagerToggleButton.toolbarButton) [9,2 28x28]
PaintableWithLines (BlockContainer(anonymous)) [15,8 16x16]
PaintableWithLines (BlockContainer(anonymous)) [9,2 0x0]
PaintableWithLines (BlockContainer<SPAN>) [31,16 0x0] overflow: [31,16 56.34375x36]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.toolbarButtonSpacer) [38,15.5 30x1]
@ -491,10 +494,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer(anonymous)) [777,8 16x16]
PaintableWithLines (BlockContainer<SPAN>) [793,16 0x0] overflow: [793,16 46.59375x18]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [771,2 0x0]
PaintableWithLines (BlockContainer(anonymous)) [771,30 28x0]
PaintableWithLines (BlockContainer(anonymous)) [585,2 0x0]
PaintableWithLines (BlockContainer(anonymous)) [1,2 0x0]
PaintableWithLines (BlockContainer(anonymous)) [0,32 800x0]
PaintableWithLines (BlockContainer<DIV>#viewerContainer) [0,32 800x568]
PaintableWithLines (BlockContainer(anonymous)) [0,32 800x0]

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<style>
@font-face {
font-family: Ahem;
src: url("../../Ref/data/fonts/Ahem.ttf");
}
.row {
align-items: baseline;
display: flex;
font: 16px Ahem;
}
.icon {
background: black;
height: 16px;
width: 16px;
}
.text {
line-height: 24px;
overflow: hidden;
}
p {
margin: 0;
}
</style>
<div class="row">
<span class="icon"></span>
<span class="text">Text</span>
</div>
<div class="row">
<span class="icon"></span>
<span class="text" style="width: 64px">Text Text</span>
</div>
<div class="row">
<span class="icon"></span>
<div class="text"><p>Text</p><p>Text</p></div>
</div>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="../../../../../data/fonts/ahem.css">
<style>
.flex {
display: flex;
align-items: baseline;
font: 25px/1 Ahem;
}
</style>
<body>
<div class="flex">
<span>XX</span>
<div><div>YY</div></div>
</div>
</body>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<title>A block with 'overflow: hidden' should produce normal baseline</title>
<link rel="author" title="Koji Ishii" href="kojii@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#flex-baselines">
<link rel="match" href="../../../../expected/wpt-import/css/css-flexbox/reference/align-items-baseline-overflow-non-visible-ref.html">
<link rel="stylesheet" type="text/css" href="../../../../data/fonts/ahem.css">
<style>
.flex {
display: flex;
align-items: baseline;
font: 25px/1 Ahem;
}
.overflow {
overflow: hidden;
height: 2em;
}
</style>
<body>
<!--
CSS2 states that:
The baseline of an 'inline-block' is the baseline of its last line box in
the normal flow, unless it has either no in-flow line boxes or if its
'overflow' property has a computed value other than 'visible', in which case
the baseline is the bottom margin edge.
https://drafts.csswg.org/css2/visudet.html#propdef-vertical-align
This rule should apply only to 'inline-block', and not to normal block.
-->
<div class="flex">
<span>XX</span>
<div><div class="overflow">YY</div></div>
</div>
</body>

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2

View file

@ -2,7 +2,6 @@ Harness status: OK
Found 2 tests
1 Pass
1 Fail
2 Pass
Pass #target > div 1
Fail #target > div 2
Pass #target > div 2