Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Trim collapsed margins at block-start and block-end when specified by…
… margin-trim

https://bugs.webkit.org/show_bug.cgi?id=249781
rdar://103640784

Reviewed by Alan Baradlay.

When collapsed margins at propagated to the block-start or block-end of
a block container and the appropriate margin-trim values are specified,
those margins should also be trimmed.

This can be done by keeping track of whether we are at the block start
or block end of the box as specified by the MarginInfo structure. If
we are currently at the block start of the container, then we should
trim the before margin of the child. If the child is self collapsing,
we should also trim its after margin.

By the time we are in setCollapsedBottomMargin, we are at the block
end of the block container. That means we should be able to trim the
values inside of MarginInfo if margin-trim: block/block-end is
specified.

Here is an example to demonstrate this logic:

container {
    display: block;
    margin-trim: block;
    margin-block-start: 10px;
}
item {
    display: block;
    margin-block-start: 40px;
    width: 50px;
    height: 50px;
    background-color: green;
}
.collapsed {
    margin-block-start: 0px;
    height: 0px;
}
<item style="margin-block-start: 0px;"></item>
<container>
    <item class="collapsed"></item>
    <item></item>
</container>

- The container will begin layout of its block children and will iterate
over them. Each iteration will take in and update a MarginInfo structure
that is used to handle any sort of collapsing. Initially this structure
will just hold the margin information for the container itself.

- RenderBlockFlow::layoutBlockChild will call RenderBlockFlow::collapseMargins
with the child as an argument, and that method will call
RenderBlockFlow::collapseMarginsWithChildInfo to perform the actual
collapsing.

- Since we are at the before side of the block, which is a part of the
MarginInfo state, and block-start trimming is specified, we will then
trim the block-start margin of the child. We will also trim the block-end
margin of the child since it is self-collapsing.

- Once we are done with this item and we are back in RenderBlockFlow::layoutBlockChild
we will check to see if we need to update the MarginInfo state that keeps
track of us being at the before side of the block container. Since
1.) We were at the before side of the block container
2.) The child we just laid out is self collapsing
We will not update our MarginInfo state and we will continue to be at the
before side of the block. This means that this trimming logic will continue
on with the next item in the container. If the first item was not
self collapsing, however, then we would update our MarginInfo state so
that we are no longer at the before side and we would not trim the
block-start margins of the future children.

- After we layout and trim the margins of the second item,
RenderBlockFlow::layoutBlockChildren will call handleAfterSideOfBlock
with the MarginInfo structure that has been modified this whole time.
This should contain any margins that have collapsed through to the
after side of the block.

- Once in RenderBlockFlow::setCollapsedBottomMargin, we will check to
see if block-end margin trimming has been specified. If it has, then
we will use 0 (trimmed) for the margin from MarginInfo that is supposed
to collapse with the container's margin.

* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-collapsed-margins-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-collapsed-margins.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-self-collapsing-item-has-larger-block-end-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-self-collapsing-item-has-larger-block-end.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-self-collapsing-item-has-larger-block-start-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-end-self-collapsing-item-has-larger-block-start.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-collapsed-margins-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-collapsed-margins.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-self-collapsing-item-has-larger-block-end-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-self-collapsing-item-has-larger-block-end.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-self-collapsing-item-larger-block-start-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-box/margin-trim/block-container-block-start-self-collapsing-item-larger-block-start.html: Added.
* Source/WebCore/rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::collapseMarginsWithChildInfo):
(WebCore::RenderBlockFlow::setCollapsedBottomMargin):

Canonical link: https://commits.webkit.org/259734@main
  • Loading branch information
sgill26 authored and Sammy Gill committed Feb 2, 2023
1 parent 00a8569 commit 82ef682
Show file tree
Hide file tree
Showing 13 changed files with 427 additions and 4 deletions.
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-end-collapsed-margins</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<meta name="assert" content="collapsed block-end margins should be trimmed but not affect container margins">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-end-collapsed-margins</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<link rel="match" href="block-container-collapsed-margins-ref.html">
<meta name="assert" content="collapsed block-end margins should be trimmed but not affect container margins">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
margin-block-end: 40px;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<title>margin-trim: block-container-block-end-self-collapsing-item-has-larger-block-end</title>
<meta name="assert" content="self-collapsing margin at block-end has its block-end margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-end-self-collapsing-item-has-larger-block-end</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<link rel="match" href="block-container-collapsed-margins-ref.html">
<meta name="assert" content="self-collapsing margin at block-end has its block-end margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
margin-block-end: 40px;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 100px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-end-self-collapsing-item-has-larger-block-start</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<meta name="assert" content="self-collapsing margin at block-end has its block-start margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-end-self-collapsing-item-has-larger-block-start</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<link rel="match" href="block-container-collapsed-margins-ref.html">
<meta name="assert" content="self-collapsing margin at block-end has its block-end margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
margin-block-end: 40px;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-start: 100px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-start-collapsed-margins</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<meta name="assert" content="collapsed block-start margins should be trimmed but not affect container margins">
<style>
container {
display: block;
margin-trim: block;
margin-block-start: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
</style>
</head>
<body>
<item style="margin-block-start: 0px;"></item>
<container>
<item></item>
</container>
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-start-collapsed-margins</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<link rel="match" href="block-container-collapsed-margins-ref.html">
<meta name="assert" content="second item propagates block-start margin through self collapsing item and gets trimmed">
<style>
container {
display: block;
margin-trim: block;
margin-block-start: 10px;
}
item {
display: block;
margin-block-start: 40px;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-start: 0px;
height: 0px;
}
</style>
</head>
<body>
<item style="margin-block-start: 0px;"></item>
<container>
<item class="collapsed"></item>
<item></item>
</container>
</body>
</html>
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-start-self-collapsing-item-has-larger-block-end</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<meta name="assert" content="self-collapsing margin at block-start has its block-end margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>

</body>
</html>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-start-self-collapsing-item-has-larger-block-end</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<link rel="match" href="block-container-collapsed-margins-ref.html">
<meta name="assert" content="self-collapsing margin at block-start has its block-end margin trimmed which would normally be used in collapsing with container">
<style>
container {
display: block;
margin-trim: block;
margin-block-start: 10px;
}
item {
display: block;
margin-block-start: 40px;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 100px;
height: 0px;
}
</style>
</head>
<body>
<item style="margin-block-start: 0px;"></item>
<container>
<item class="collapsed"></item>
<item></item>
</container>
</body>
</html>
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>margin-trim: block-container-block-start-self-collapsing-item-has-larger-block-start</title>
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-box-4/#margin-trim-block">
<meta name="assert" content="collapsed block-end margins should be trimmed but not affect container margins">
<style>
container {
display: block;
margin-trim: block;
margin-block-end: 10px;
}
item {
display: block;
width: 50px;
height: 50px;
background-color: green;
}
.collapsed {
margin-block-end: 0px;
height: 0px;
}
</style>
</head>
<body>
<container>
<item></item>
<item class="collapsed"></item>
</container>
<item></item>
</body>
</html>

0 comments on commit 82ef682

Please sign in to comment.