Changeset 188582 in webkit


Ignore:
Timestamp:
Aug 18, 2015 10:03:05 AM (9 years ago)
Author:
jfernandez@igalia.com
Message:

[CSS Grid Layout] Do not stretch always grid items with auto width
https://bugs.webkit.org/show_bug.cgi?id=148069

Reviewed by Darin Adler.

Source/WebCore:

We assumed that any grid item with 'auto' width will be stretched
to fill all the available space in its grid area. We assumed this
because grid area acts as item's container.

However, Grid Layout specification states on its Alignment section
that items will be stretched by default, unless either
justify-self or align-self compute to a value other than stretch
or margins are auto. In those cases, grid items will auto-size to
fit their contents.

Tests:
fast/css-grid-layout/grid-align-justify-stretch.html
fast/css-grid-layout/grid-item-auto-margins-and-stretch.html
fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change.html

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::computeLogicalWidthInRegion):

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
(WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.

  • rendering/RenderGrid.h:

LayoutTests:

New Layout tests to verify that grid stretching logic works as expected
when aligning both horizontally and vertically.

  • fast/css-grid-layout/grid-align-justify-stretch-expected.txt: Added.
  • fast/css-grid-layout/grid-align-justify-stretch.html: Added.
  • fast/css-grid-layout/grid-item-auto-margins-and-stretch-expected.txt: Added.
  • fast/css-grid-layout/grid-item-auto-margins-and-stretch.html: Added.
  • fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change-expected.txt: Added.
  • fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change.html: Added.
Location:
trunk
Files:
6 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r188580 r188582  
     12015-08-18  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        [CSS Grid Layout] Do not stretch always grid items with auto width
     4        https://bugs.webkit.org/show_bug.cgi?id=148069
     5
     6        Reviewed by Darin Adler.
     7
     8        New Layout tests to verify that grid stretching logic works as expected
     9        when aligning both horizontally and vertically.
     10
     11        * fast/css-grid-layout/grid-align-justify-stretch-expected.txt: Added.
     12        * fast/css-grid-layout/grid-align-justify-stretch.html: Added.
     13        * fast/css-grid-layout/grid-item-auto-margins-and-stretch-expected.txt: Added.
     14        * fast/css-grid-layout/grid-item-auto-margins-and-stretch.html: Added.
     15        * fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change-expected.txt: Added.
     16        * fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change.html: Added.
     17
    1182015-08-18  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    219
  • trunk/Source/WebCore/ChangeLog

    r188580 r188582  
     12015-08-18  Javier Fernandez  <jfernandez@igalia.com>
     2
     3        [CSS Grid Layout] Do not stretch always grid items with auto width
     4        https://bugs.webkit.org/show_bug.cgi?id=148069
     5
     6        Reviewed by Darin Adler.
     7
     8        We assumed that any grid item with 'auto' width will be stretched
     9        to fill all the available space in its grid area. We assumed this
     10        because grid area acts as item's container.
     11
     12        However, Grid Layout specification states on its Alignment section
     13        that items will be stretched by default, unless either
     14        justify-self or align-self compute to a value other than stretch
     15        or margins are auto. In those cases, grid items will auto-size to
     16        fit their contents.
     17
     18        Tests:
     19        fast/css-grid-layout/grid-align-justify-stretch.html
     20        fast/css-grid-layout/grid-item-auto-margins-and-stretch.html
     21        fast/css-grid-layout/grid-items-should-not-be-stretched-when-height-or-width-or-margin-change.html
     22
     23        * rendering/RenderBox.cpp:
     24        (WebCore::RenderBox::computeLogicalWidthInRegion):
     25        * rendering/RenderGrid.cpp:
     26        (WebCore::RenderGrid::layoutGridItems):
     27        (WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
     28        (WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.
     29        * rendering/RenderGrid.h:
     30
    1312015-08-18  Xabier Rodriguez Calvar  <calvaris@igalia.com>
    232
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r188433 r188582  
    23392339    // FIXME: Account for block-flow in flexible boxes.
    23402340    // https://bugs.webkit.org/show_bug.cgi?id=46418
    2341     if (hasOverrideLogicalContentWidth() && (isRubyRun() || style().borderFit() == BorderFitLines || parent()->isFlexibleBoxIncludingDeprecated())) {
     2341    if (hasOverrideLogicalContentWidth() && (isRubyRun() || style().borderFit() == BorderFitLines || (parent()->isFlexibleBoxIncludingDeprecated() || parent()->isRenderGrid()))) {
    23422342        computedValues.m_extent = overrideLogicalContentWidth() + borderAndPaddingLogicalWidth();
    23432343        return;
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r186682 r188582  
    11911191        // call to avoid unnecessary relayouts. This might imply that child margins, needed to correctly
    11921192        // determine the available space before stretching, are not set yet.
    1193         applyStretchAlignmentToChildIfNeeded(*child, overrideContainingBlockContentLogicalHeight);
     1193        applyStretchAlignmentToChildIfNeeded(*child);
    11941194
    11951195        child->layoutIfNeeded();
     
    12721272}
    12731273
    1274 bool RenderGrid::allowedToStretchLogicalHeightForChild(const RenderBox& child) const
    1275 {
    1276     return child.style().logicalHeight().isAuto() && !child.style().marginBeforeUsing(&style()).isAuto() && !child.style().marginAfterUsing(&style()).isAuto();
    1277 }
    1278 
    12791274// FIXME: This logic is shared by RenderFlexibleBox, so it should be moved to RenderBox.
    12801275bool RenderGrid::needToStretchChildLogicalHeight(const RenderBox& child) const
     
    12981293
    12991294// FIXME: This logic is shared by RenderFlexibleBox, so it should be moved to RenderBox.
    1300 void RenderGrid::applyStretchAlignmentToChildIfNeeded(RenderBox& child, LayoutUnit gridAreaBreadthForChild)
    1301 {
    1302     if (!allowedToStretchLogicalHeightForChild(child) || RenderStyle::resolveAlignment(style(), child.style(), ItemPositionStretch) != ItemPositionStretch) {
    1303         child.clearOverrideLogicalContentHeight();
    1304         return;
    1305     }
    1306 
    1307     bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
    1308     // FIXME: If the child has orthogonal flow, then it already has an override height set, so use it.
    1309     // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
    1310     if (!hasOrthogonalWritingMode) {
    1311         LayoutUnit stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(gridAreaBreadthForChild, child);
    1312         LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight, -1);
    1313 
    1314         // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
    1315         bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight();
    1316         if (childNeedsRelayout || !child.hasOverrideLogicalContentHeight())
     1295void RenderGrid::applyStretchAlignmentToChildIfNeeded(RenderBox& child)
     1296{
     1297    // We clear both width and height override values because we will decide now whether they
     1298    // are allowed or not, evaluating the conditions which might have changed since the old
     1299    // values were set.
     1300    child.clearOverrideSize();
     1301
     1302    auto& gridStyle = style();
     1303    auto& childStyle = child.style();
     1304    bool isHorizontalMode = isHorizontalWritingMode();
     1305    bool hasAutoSizeInRowAxis = isHorizontalMode ? childStyle.width().isAuto() : childStyle.height().isAuto();
     1306    bool allowedToStretchChildAlongRowAxis = hasAutoSizeInRowAxis && !childStyle.marginStartUsing(&gridStyle).isAuto() && !childStyle.marginEndUsing(&gridStyle).isAuto();
     1307    if (!allowedToStretchChildAlongRowAxis || RenderStyle::resolveJustification(gridStyle, childStyle, ItemPositionStretch) != ItemPositionStretch) {
     1308        bool hasAutoMinSizeInRowAxis = isHorizontalMode ? childStyle.minWidth().isAuto() : childStyle.minHeight().isAuto();
     1309        bool canShrinkToFitInRowAxisForChild = !hasAutoMinSizeInRowAxis || child.minPreferredLogicalWidth() <= child.overrideContainingBlockContentLogicalWidth();
     1310        // TODO(lajava): how to handle orthogonality in this case ?.
     1311        // TODO(lajava): grid track sizing and positioning do not support orthogonal modes yet.
     1312        if (hasAutoSizeInRowAxis && canShrinkToFitInRowAxisForChild) {
     1313            LayoutUnit childWidthToFitContent = std::max(std::min(child.maxPreferredLogicalWidth(), child.overrideContainingBlockContentLogicalWidth()  - child.marginLogicalWidth()), child.minPreferredLogicalWidth());
     1314            LayoutUnit desiredLogicalWidth = child.constrainLogicalHeightByMinMax(childWidthToFitContent, -1);
     1315            child.setOverrideLogicalContentWidth(desiredLogicalWidth - child.borderAndPaddingLogicalWidth());
     1316            if (desiredLogicalWidth != child.logicalWidth())
     1317                child.setNeedsLayout();
     1318        }
     1319    }
     1320
     1321    bool hasAutoSizeInColumnAxis = isHorizontalMode ? childStyle.height().isAuto() : childStyle.width().isAuto();
     1322    bool allowedToStretchChildAlongColumnAxis = hasAutoSizeInColumnAxis && !childStyle.marginBeforeUsing(&gridStyle).isAuto() && !childStyle.marginAfterUsing(&gridStyle).isAuto();
     1323    if (allowedToStretchChildAlongColumnAxis && RenderStyle::resolveAlignment(gridStyle, childStyle, ItemPositionStretch) == ItemPositionStretch) {
     1324        // TODO (lajava): If the child has orthogonal flow, then it already has an override height set, so use it.
     1325        // TODO (lajava): grid track sizing and positioning do not support orthogonal modes yet.
     1326        if (child.isHorizontalWritingMode() == isHorizontalMode) {
     1327            LayoutUnit stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(child.overrideContainingBlockContentLogicalHeight(), child);
     1328            LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight, -1);
    13171329            child.setOverrideLogicalContentHeight(desiredLogicalHeight - child.borderAndPaddingLogicalHeight());
    1318         if (childNeedsRelayout) {
    1319             child.setLogicalHeight(0);
    1320             child.setNeedsLayout();
     1330            if (desiredLogicalHeight != child.logicalHeight()) {
     1331                // TODO (lajava): Can avoid laying out here in some cases. See https://webkit.org/b/87905.
     1332                child.setLogicalHeight(0);
     1333                child.setNeedsLayout();
     1334            }
    13211335        }
    13221336    }
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r186682 r188582  
    131131
    132132    virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect) override;
    133     bool allowedToStretchLogicalHeightForChild(const RenderBox&) const;
    134133    bool needToStretchChildLogicalHeight(const RenderBox&) const;
    135134    LayoutUnit marginLogicalHeightForChild(const RenderBox&) const;
    136135    LayoutUnit computeMarginLogicalHeightForChild(const RenderBox&) const;
    137136    LayoutUnit availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox&) const;
    138     void applyStretchAlignmentToChildIfNeeded(RenderBox&, LayoutUnit gridAreaBreadthForChild);
     137    void applyStretchAlignmentToChildIfNeeded(RenderBox&);
    139138    bool hasAutoMarginsInColumnAxis(const RenderBox&) const;
    140139    bool hasAutoMarginsInRowAxis(const RenderBox&) const;
Note: See TracChangeset for help on using the changeset viewer.