Skip to content

Commit

Permalink
[LayoutNG] Relative offset for OOFs with inline CBs in a multicol
Browse files Browse the repository at this point in the history
Relative offsets should be applied after fragmentation. Since we perform
layout for OOFs once they reach the fragmentation context root (if
applicable), we fail to apply any relative offsets at the correct time
in the case of inline containing blocks. See CL:2851595 for how this
was handled for the non-inline case.

The changes required to accomplish this for inline containing blocks
include:

1. We currently store an accumulated relative offset in
NGContainingBlock inside the OOF node, which is any relative offset from
the containing block to the fragmentation context root. We also need to
store an accumulated relative offset from the inline container to the
containing block in order to properly apply all relative offsets at the
time of fragmentation.

A new struct, NGInlineContainer, was added to the OOF node to hold the
inline container object and the accumulated relative offset to the
containing block.

2. A relative offset was also added to the InlineContainingBlockGeometry
struct so that we have access to the relative offset from #1 when
creating the ContainingBlockInfo for the inline container.

3. The way that relative offsets are applied to inlines, it didn't seem
straightforward to separate the relative offset from the normal
offset, like we had in CL:2851595. Instead, store the relative offset
for the inline and subtract it out from the OOF static position once
it reaches the containing block, and subtract it from the containing
block rect offset when determining the ContainingBlockInfo for the
inline container.

4. Store the total relative offset (from the inline container to the
fragmentation context root) in ContainingBlockInfo. This relative
offset will then be applied after fragmentation is complete for the OOF
as a result of CL:2851595.

Bug: 1079031
Change-Id: I7198fec4c01e05ca54c51b2f215569b75b0b869e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2995308
Commit-Queue: Alison Maher <almaher@microsoft.com>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#902060}
  • Loading branch information
alisonmaher authored and chromium-wpt-export-bot committed Jul 15, 2021
1 parent a1cb55f commit 67a78f5
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 0 deletions.
40 changes: 40 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-058.html
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<title>
Out-of-flow positioned element in multicol with inline containing block - the
relative offset should apply to the OOF descendant after fragmentation.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
column-count: 2;
column-fill: auto;
column-gap: 0px;
height: 100px;
width: 100px;
margin-left: -400px;
margin-top: -400px;
}
.rel {
position: relative;
}
.abs {
position: absolute;
background-color: green;
width: 50px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol">
<div class="rel" style="top: 200px; left: 200px;">
<div class="rel" style="top: 50px; left: 50px;">
<span class="rel" style="top: 50px; left: 100px;">
<span class="rel" style="top: 100px; left: 50px;">
<div style="height: 200px; width: 50px; background: red;"></div>
<div class="abs" style="top: 0px; height: 50px;"></div>
<div class="abs" style="top: 50px; height: 150px;"></div>
</span>
</span>
</div>
</div>
</div>
37 changes: 37 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-059.html
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<title>
Out-of-flow positioned element in multicol - the relative offset should
apply to the OOF descendant after fragmentation.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
column-count: 2;
column-fill: auto;
column-gap: 0px;
height: 100px;
width: 100px;
margin-left: -150px;
margin-top: -150px;
}
.rel {
position: relative;
}
.abs {
position: absolute;
background-color: green;
height: 200px;
width: 50px;
top: 0px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol">
<span class="rel" style="top: 50px; left: 100px;">
<div class="rel" style="top: 100px; left: 50px;">
<div style="height: 200px; width: 50px; background: red;"></div>
<span class="abs"></span>
</div>
</span>
</div>
38 changes: 38 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-060.html
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<title>
Nested out-of-flow positioned element in multicol with inline containing
block - the relative offset should apply to the OOF descendant after
fragmentation.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
column-count: 2;
column-fill: auto;
column-gap: 0px;
height: 100px;
width: 100px;
margin-left: -100px;
margin-top: -50px;
}
.rel {
position: relative;
}
.abs {
position: absolute;
background-color: green;
height: 200px;
width: 50px;
top: 0px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol">
<div class="rel" style="top: 50px; left: 100px;">
<span class="abs">
<div style="height: 200px; width: 50px; background: red;"></div>
<div class="abs"></div>
</span>
</div>
</div>
45 changes: 45 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-061.html
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<title>
Nested out-of-flow positioned element in multicol - the relative offset
should apply to the OOF descendant after fragmentation.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
column-count: 2;
column-fill: auto;
column-gap: 0px;
height: 100px;
width: 100px;
margin-left: -100px;
}
.rel {
position: relative;
}
.oof {
background-color: green;
height: 100px;
width: 50px;
}
#abs {
position: absolute;
top: 100px;
}
#fixed {
position: fixed;
top: 0px;
left: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol">
<div style="transform: translateX(0);">
<div class="rel" style="left: 100px;">
<div style="height: 200px; width: 50px; background: red;"></div>
<span class="oof" id="abs">
<div class="oof" id="fixed"></div>
</span>
</div>
</div>
</div>
45 changes: 45 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-062.html
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<title>
Out-of-flow positioned element in nested multicol with inline containing
block - the relative offset should apply to the OOF descendant after
fragmentation.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
column-count: 2;
column-fill: auto;
column-gap: 0px;
}
#outer {
height: 100px;
width: 100px;
margin-left: -150px;
margin-top: -150px;
}
#inner {
width: 50px;
}
.rel {
position: relative;
}
.abs {
position: absolute;
background-color: green;
width: 25px;
height: 400px;
left: -100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol" id="outer">
<div class="multicol" id="inner">
<div class="rel" style="top: 50px; left: 100px;">
<span class="rel" style="top: 100px; left: 50px;">
<div style="height: 400px; width: 25px; background: red;"></div>
<div class="abs"></div>
</span>
</div>
</div>
</div>
42 changes: 42 additions & 0 deletions css/css-break/out-of-flow-in-multicolumn-063.html
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<title>
Out-of-flow positioned element in multicol with inline containing
block and vertical-rl writing mode.
</title>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
.multicol {
writing-mode: vertical-lr;
direction: rtl;
columns: 2;
column-fill: auto;
height: 100px;
width: 100px;
column-gap: 0px;
margin-top: 66px;
margin-left: -50px;
}
.rel {
position: relative;
inset-block-start: 50px;
inset-inline-start: 50px;
}
.abs {
position: absolute;
inline-size: 50px;
block-size: 200px;
inset-block-start: 0;
inset-inline-start: 0;
background: green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="multicol">
<div>
<span class="rel">
<div style="block-size: 200px; inline-size: 50px; background: red;"></div>
<div class="abs"></div>
</span>
</div>
</div>

0 comments on commit 67a78f5

Please sign in to comment.