Intrinsic Sizing on One Axis

A Collection of Interesting Ideas,

This version:
https://dbaron.github.io/css-intrinsic-sizing-one-axis/
Issue Tracking:
GitHub
Inline In Spec
Editor:
L. David Baron (Mozilla)

Abstract

This is a proposal for changes to concepts defined in [CSS-SIZING-3], [CSS-SIZING-4], [CSS3-MULTICOL], [CSS-FLEXBOX-1], and [CSS-GRID-1] to avoid having intrinsic sizes depend on layout, by instead having intrinsic sizes exist only in the axis (horizontal or vertical) that is not the axis in which the largest units of new content are placed.

1. Introduction

Document layout algorithms historically use one dimension (for Latin script, the width) as an input and the other dimension (for Latin script, the height) as an output. The width is determined from the size of the page, and content is placed within that width until lines wrap, and lines are stacked until they fill the necessary amount of height (possibly broken across pages). This means the heights are a function of the content, but the widths are not.

Some layout concepts also depend on widths that are a function of the content, known as intrinsic widths. Historically CSS layout concepts defined in [CSS21] (such as tables, floats, and absolute positioning) have depended on two such widths, even though the rules for computing them were not defined in [CSS21]. The larger width is conceptually the largest width that an element (and its descendants) can take up without wasting width, and the smaller is the narrowest that the element (and its descendants) can be without causing overflow. These widths could be computed in an entirely separate pass prior to the layout calculations that compute position and size. Some implementations have this assumption built deeply into their architecture, and depend on it for efficient performance. (Note that the notion of whether intrisic width calculations are a fully separate pass is distinct from whether intrinsic width calculations use layout-like algorithms, which is something that implementations differ on. Some implementations (IE, Edge) compute positions in order to perform intrinsic width calculations around floats, but other implementations (WebKit, Gecko, Chromium) do not.)

[CSS-SIZING-3] calls these widths the min-content size and the max-content size, but defines them (contrary to prior practice) as existing in both dimensions. I believe that this was done for various reasons, such as defining behavior for orthogonal flows, and providing particular desired behaviors for various use cases with multicolumn layout and flexbox. The definition of the intrinsic size in one dimension is often defined to depend on layout, which requires performing a full relayout in order to compute the intrinsic size, in order to then do layout at a different size. This both performs work that is unnecessary and is incompatible with the design of existing software.

I believe that these use cases can be addressed in a different way that is both simpler and more efficient. This is by defining the intrinsic sizes to exist only in one axis (the axis that is not the one in which the largest subunits of an element progress), and then defining the sizing algorithms to use intrinsic sizes in a way appropriate to that definition.

2. Axis of largest-unit progression

One interesting question to ask about a layout system is: if I add more content to the end of an element, where is it positioned relative to the content that was already there?

In block layout for English content (i.e., direction is ltr and writing-mode is horizontal-tb), a later block is placed below earlier blocks (a downwards progression). But inline layout for English content is a little bit more complicated: later content is placed to the right of the earlier content (a rightwards progression), except when the later content would overflow the line, then a new line is formed and the new line is placed below the previous lines (a downwards progression). In this inline case, smaller units of content are placed in a rightwards progression, and larger units of content are placed in a downwards progression. Thus the axis of largest-unit progression of CSS inline layout for English is downwards.

The largest-unit progression of other layout systems is defined similarly, as the direction in which the largest units of new content are placed. For example:

3. Defining intrinsic sizes

The current approach in [CSS-SIZING-3] is to define intirinsic sizes (the min-content size and the max-content size) in both dimensions (horizontal and vertical), no matter what layout system and writing-mode are being used.

I propose instead that the intrinsic sizes for a layout primitive instead be defined only in the axis (horizontal or vertical) that is not that layout system’s axis of largest-unit progression.

3.1. Block and Table

Intrinsic sizes of the layout primitives in [CSS21], block and table, are defined as they always have been.

3.2. Multi-column

write

3.3. Flex

write. Note that this can do sensible things in many cases when some dimensions (e.g., height, column-width, column-count) are specified. In the cases where not enough of them are specified to do something useful, it seems likely that the result doesn’t need to be particularly useful anyway.

3.4. Orthogonal layout

Computing an intrinsic size in the presence of orthogonal layout is interesting, although with the definitions above, the relevant cases that are interesting are no longer when the writing-mode of the parent is orthogonal to the writing-mode of the child, but instead now when the axis of largest-unit progression of the parent is orthogonal to the axis of largest-unit progression of the child.

In these cases, the parent needs to define its intrinsic size in a dimension in which the child does not have an intrinsic size.

write (I believe the sizing definitions can be written so the answer here doesn’t matter that much as long as it’s defined)

4. Defining sizing algorithms

write about how the sizing algorithms use the intrinsic sizes, particularly for orthogonal flows, flexbox, and grid

5. Use cases

Need to get a list of use cases that led to the current rules that this proposal is trying to replace, and work through (and refine) the above rules to explain how they also handle those use cases in a reasonable way.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. URL: http://dev.w3.org/csswg/css-display/
[CSS-SIZING-4]
Tab Atkins Jr.; Elika Etemad. CSS Intrinsic & Extrinsic Sizing Module Level 4. ED. URL: https://drafts.csswg.org/css-sizing-4/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. URL: http://dev.w3.org/csswg/css-writing-modes-3/

Informative References

[CSS-FLEXBOX-1]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Flexible Box Layout Module Level 1. URL: https://drafts.csswg.org/css-flexbox/
[CSS-GRID-1]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Grid Layout Module Level 1. URL: https://drafts.csswg.org/css-grid/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS Intrinsic & Extrinsic Sizing Module Level 3. URL: https://drafts.csswg.org/css-sizing
[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2
[CSS3-MULTICOL]
Håkon Wium Lie. CSS Multi-column Layout Module. 12 April 2011. CR. URL: https://www.w3.org/TR/css3-multicol

Issues Index

write
write. Note that this can do sensible things in many cases when some dimensions (e.g., height, column-width, column-count) are specified. In the cases where not enough of them are specified to do something useful, it seems likely that the result doesn’t need to be particularly useful anyway.
write (I believe the sizing definitions can be written so the answer here doesn’t matter that much as long as it’s defined)
write about how the sizing algorithms use the intrinsic sizes, particularly for orthogonal flows, flexbox, and grid
Need to get a list of use cases that led to the current rules that this proposal is trying to replace, and work through (and refine) the above rules to explain how they also handle those use cases in a reasonable way.