How should we resolve percentage margins and padding on grid and flex items?

The CSS Working Group would like your opinion. There is a longstanding issue in both the CSS Grid Layout and Flexbox specifications.

From the CSS Grid specification:

Percentage margins and paddings on grid items can be resolved against either: their own axis (left/right percentages resolve against width, top/bottom resolve against height), or,

the inline axis (left/right/top/bottom percentages all resolve against width) A User Agent must choose one of these two behaviors. Note: This variance sucks, but it accurately captures the current state of the world (no consensus among implementations, and no consensus within the CSSWG). It is the CSSWG’s intention that browsers will converge on one of the behaviors, at which time the spec will be amended to require that. Authors should avoid using percentages in paddings or margins on grid items entirely, as they will get different behavior in different browsers.

The flexbox specification has the same wording.

What is the problem here?

A percentage has to be resolved against something. If you give a grid item a margin-right of 10%, you would probably expect that 10% to be calculated as 10% of the width of the grid area. What happens however if you give the item a margin-bottom of 50%? Do you expect it to resolve to 50% of the total height of the grid area or do you expect it to calculate 50% from the width? The spec allows for both, and browser implementations are split.

You can see the problem in this very simple CodePen. We have three column tracks which are each 120 pixels in width. The margin-right applied to each track resolves to 12 pixels, 10% of 120. In Chrome and Safari the margin-bottom resolves to 60 pixels. 50% of the width of 120 pixels is 60 pixels.

In Firefox and Edge the margin-bottom uses the height of the grid area and so in this case resolves to 150 pixels as I have put a height on the grid and items are stretching. If you remove the height on the grid container you will see how Firefox now completely collapses the container as there is now no height to resolve against. Chrome will keep the container at 60 pixels - that being the margin.