Commit 0e8ce769 authored by jfernandez@igalia.com's avatar jfernandez@igalia.com

[CSS Grid Layout] Grid items must set a new formatting context.

According to the spec, "A grid item establishes a new formatting context
for its contents." Hence, margins should not collapse even when they may
be adjoining to its content's margins. It also prevents any 'float' protruding
content on the adjoining grid items.

BUG=430100

Review URL: https://codereview.chromium.org/697653004

git-svn-id: svn://svn.chromium.org/blink/trunk@185214 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a4cadaae
<!DOCTYPE html>
<html>
<head>
<link href="resources/grid.css" rel="stylesheet">
<style>
.cell {
width: 50px;
height: auto;
min-height: 50px
}
.invisibleFont {
color: lime;
}
.floatLeft {
float: left;
}
.clearLeft {
clear: left;
}
.relative {
position: relative;
}
</style>
</head>
<body>
<div>This test checks that grid item sets a new formatting context for its content, preventing any 'float' protruding content on the adjoining grid item ('Float' text shouldn't overflow the first row).</div>
<div>
<div class="cell relative floatLeft firstRowFirstColumn">
<div>Float</div>
<div>Float</div>
<div>Float</div>
<div>Float</div>
</div>
<div class="cell floatLeft firstRowSecondColumn">
<div class="invisibleFont">Float</div>
<div class="invisibleFont">Float</div>
<div class="invisibleFont">Float</div>
<div class="invisibleFont">Float</div>
</div>
<div class="cell floatLeft clearLeft secondRowFirstColumn"></div>
<div class="cell floatLeft secondRowSecondColumn"></div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link href="resources/grid.css" rel="stylesheet">
<style>
.grid {
grid-auto-columns: minmax(50px, max-content);
grid-auto-rows: minmax(50px, max-content);
width: -webkit-fit-content;
}
.floatChild {
float: left;
clear: both;
}
</style>
</style>
</head>
<body>
<div>This test checks that grid item sets a new formatting context for its content, preventing any 'float' protruding content on the adjoining grid item ('Float' text shouldn't overflow the first row).</div>
<div class="grid">
<div class="firstRowFirstColumn">
<div class="floatChild">Float</div>
<div class="floatChild">Float</div>
<div class="floatChild">Float</div>
<div class="floatChild">Float</div>
</div>
<div class="firstRowSecondColumn"></div>
<div class="secondRowFirstColumn"></div>
<div class="secondRowSecondColumn"></div>
</div>
</body>
</html>
<!DOCTYPE html>
<link href="resources/grid.css" rel="stylesheet">
<div>This test checks that grid item's margins do not collapse with its content's margins (single margin in the first row and double between subsequent).</div>
<div style="float: left">
<div ><p margin="20px 0px">XXXXX</p></div>
<div style="float: left; margin:20px 0px;">XXXXX</div>
<div><p style="float: left;" margin="20px 0px">XXXXX</p></div>
</div>
<!DOCTYPE html>
<link href="resources/grid.css" rel="stylesheet">
<div>This test checks that grid item's margins do not collapse with its content's margins (single margin in the first row and double between subsequent).</div>
<div style="display: grid;">
<div><p margin="20px 0px">XXXXX</p></div>
<div style="margin:20px 0px;">XXXXX</div>
<div><p margin="20px 0px">XXXXX</p></div>
</div>
...@@ -1285,7 +1285,7 @@ bool RenderBlock::isSelfCollapsingBlock() const ...@@ -1285,7 +1285,7 @@ bool RenderBlock::isSelfCollapsingBlock() const
// We should be able to give a quick answer if the box is a relayout boundary. // We should be able to give a quick answer if the box is a relayout boundary.
// Being a relayout boundary implies a block formatting context, and also // Being a relayout boundary implies a block formatting context, and also
// our internal layout shouldn't affect our container in any way. // our internal layout shouldn't affect our container in any way.
if (createsBlockFormattingContext()) if (createsNewFormattingContext())
return false; return false;
// Placeholder elements are not laid out until the dimensions of their parent text control are known, so they // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they
...@@ -1543,10 +1543,11 @@ void RenderBlock::addVisualOverflowFromTheme() ...@@ -1543,10 +1543,11 @@ void RenderBlock::addVisualOverflowFromTheme()
addVisualOverflow(inflatedRect); addVisualOverflow(inflatedRect);
} }
bool RenderBlock::createsBlockFormattingContext() const bool RenderBlock::createsNewFormattingContext() const
{ {
return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated() return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated()
|| style()->specifiesColumns() || isRenderFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isDocumentElement() || style()->columnSpan(); || style()->specifiesColumns() || isRenderFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot()
|| isDocumentElement() || style()->columnSpan() || isGridItem();
} }
void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child) void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
......
...@@ -444,7 +444,7 @@ protected: ...@@ -444,7 +444,7 @@ protected:
enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary }; enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const; LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
bool createsBlockFormattingContext() const; bool createsNewFormattingContext() const;
public: public:
LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const; LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
......
...@@ -438,7 +438,7 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & ...@@ -438,7 +438,7 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &
layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge); layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
// Expand our intrinsic height to encompass floats. // Expand our intrinsic height to encompass floats.
if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext()) if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsNewFormattingContext())
setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
...@@ -929,7 +929,7 @@ void RenderBlockFlow::rebuildFloatsFromIntruding() ...@@ -929,7 +929,7 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
RenderBlockFlow* parentBlockFlow = toRenderBlockFlow(parent()); RenderBlockFlow* parentBlockFlow = toRenderBlockFlow(parent());
bool parentHasFloats = false; bool parentHasFloats = false;
RenderObject* prev = previousSibling(); RenderObject* prev = previousSibling();
while (prev && (!prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats() || toRenderBlock(prev)->createsBlockFormattingContext())) { while (prev && (!prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats() || toRenderBlock(prev)->createsNewFormattingContext())) {
if (prev->isFloating()) if (prev->isFloating())
parentHasFloats = true; parentHasFloats = true;
prev = prev->previousSibling(); prev = prev->previousSibling();
...@@ -1078,7 +1078,7 @@ MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin ...@@ -1078,7 +1078,7 @@ MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
{ {
RenderStyle* blockStyle = blockFlow->style(); RenderStyle* blockStyle = blockFlow->style();
ASSERT(blockFlow->isRenderView() || blockFlow->parent()); ASSERT(blockFlow->isRenderView() || blockFlow->parent());
m_canCollapseWithChildren = !blockFlow->createsBlockFormattingContext() && !blockFlow->isRenderFlowThread() && !blockFlow->isRenderView(); m_canCollapseWithChildren = !blockFlow->createsNewFormattingContext() && !blockFlow->isRenderFlowThread() && !blockFlow->isRenderView();
m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle->marginBeforeCollapse() != MSEPARATE; m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle->marginBeforeCollapse() != MSEPARATE;
...@@ -1776,7 +1776,7 @@ void RenderBlockFlow::addOverflowFromFloats() ...@@ -1776,7 +1776,7 @@ void RenderBlockFlow::addOverflowFromFloats()
void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats) void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
{ {
RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats); RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats);
if (!hasColumns() && (recomputeFloats || createsBlockFormattingContext() || hasSelfPaintingLayer())) if (!hasColumns() && (recomputeFloats || createsNewFormattingContext() || hasSelfPaintingLayer()))
addOverflowFromFloats(); addOverflowFromFloats();
} }
...@@ -2476,7 +2476,7 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic ...@@ -2476,7 +2476,7 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
ASSERT(!avoidsFloats()); ASSERT(!avoidsFloats());
// If we create our own block formatting context then our contents don't interact with floats outside it, even those from our parent. // If we create our own block formatting context then our contents don't interact with floats outside it, even those from our parent.
if (createsBlockFormattingContext()) if (createsNewFormattingContext())
return; return;
// If the parent or previous sibling doesn't have any floats to add, don't bother. // If the parent or previous sibling doesn't have any floats to add, don't bother.
...@@ -2513,7 +2513,7 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic ...@@ -2513,7 +2513,7 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
void RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats) void RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats)
{ {
// Prevent floats from being added to the canvas by the root element, e.g., <html>. // Prevent floats from being added to the canvas by the root element, e.g., <html>.
if (!child->containsFloats() || child->isRenderRegion() || child->createsBlockFormattingContext()) if (!child->containsFloats() || child->isRenderRegion() || child->createsNewFormattingContext())
return; return;
LayoutUnit childLogicalTop = child->logicalTop(); LayoutUnit childLogicalTop = child->logicalTop();
......
...@@ -530,6 +530,8 @@ public: ...@@ -530,6 +530,8 @@ public:
bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isDeprecatedFlexibleBox(); } bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isDeprecatedFlexibleBox(); }
bool isFlexItemIncludingDeprecated() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBoxIncludingDeprecated(); } bool isFlexItemIncludingDeprecated() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBoxIncludingDeprecated(); }
bool isGridItem() const { return parent() && parent()->isRenderGrid(); }
virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override; virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override; virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment