layout: Ensure that <caption>'s support position: relative (#33426)

This change adds support for `position: relative` to table `<caption>`.
In addition to adjusting their position according to inset values, table
captions must also establish containing blocks for descendants that are
absolutely positioned.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Martin Robinson 2024-09-19 14:43:29 +02:00 committed by GitHub
parent eecf5bdea1
commit ef229b9386
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 52 additions and 7 deletions

View file

@ -13,6 +13,7 @@ use style::computed_values::border_collapse::T as BorderCollapse;
use style::computed_values::box_sizing::T as BoxSizing;
use style::computed_values::caption_side::T as CaptionSide;
use style::computed_values::empty_cells::T as EmptyCells;
use style::computed_values::position::T as Position;
use style::computed_values::table_layout::T as TableLayoutMode;
use style::computed_values::visibility::T as Visibility;
use style::logical_geometry::WritingMode;
@ -1642,7 +1643,7 @@ impl<'a> TableLayout<'a> {
style: containing_block.style,
};
let box_fragment = context.layout_in_flow_block_level(
let mut box_fragment = context.layout_in_flow_block_level(
layout_context,
positioning_context
.as_mut()
@ -1651,7 +1652,8 @@ impl<'a> TableLayout<'a> {
None, /* sequential_layout_state */
);
if let Some(positioning_context) = positioning_context.take() {
if let Some(mut positioning_context) = positioning_context.take() {
positioning_context.layout_collected_children(layout_context, &mut box_fragment);
parent_positioning_context.append(positioning_context);
}
@ -1735,11 +1737,19 @@ impl<'a> TableLayout<'a> {
let caption_pbm = caption_fragment
.padding_border_margin()
.to_logical(table_writing_mode);
let caption_relative_offset = match caption_fragment.style.clone_position() {
Position::Relative => {
relative_adjustement(&caption_fragment.style, containing_block_for_children)
},
_ => LogicalVec2::zero(),
};
caption_fragment.content_rect = LogicalRect {
start_corner: LogicalVec2 {
inline: offset_from_wrapper.inline_start + caption_pbm.inline_start,
block: current_block_offset + caption_pbm.block_start,
},
} + caption_relative_offset,
size: caption_fragment
.content_rect
.size

View file

@ -240575,6 +240575,19 @@
{}
]
],
"caption-relative-positioning.html": [
"2be1e86bc077f1293ccc9ea851f23123ae679157",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"col-definite-max-size-001.html": [
"bcd7ca2fd89c26384e26be64dade0e7af0ea4c79",
[

View file

@ -1,2 +0,0 @@
[table-caption-is-containing-block-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[position-relative-table-caption.html]
expected: FAIL

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<title>&lt;caption&gt; elements can be relatively positioned</title>
<meta name="assert" content="The caption is positioned relatively to the table wrapper">
<link rel="help" href="https://drafts.csswg.org/css2/#relative-positioning">
<link rel="match" href="/css/reference/ref-filled-green-100px-square.xht">
<style>
caption {
position: relative;
background: green;
width: 100px;
height: 100px;
margin-left: 200px;
left: -200px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; background: red;">
<table>
<caption></caption>
</table>
</div>
</html>