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:
parent
eb85264e44
commit
cf3bb8c129
17 changed files with 256 additions and 75 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in a new issue