You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-multicol] Overflow in the block direction for continuous media #2923
In multicol 1, overflow in continuous media happens in the inline direction, therefore if we restrict a multicol container by height and the content of that container creates more columns than will fit, new columns are created in the inline direction and we get a horizontal scrollbar. This is, in general, not what web authors want.
Overflow in the Block direction would enable something like the below image, where the additional columns are created below the initial multicol container.
In talking to web authors, there was an interest in this ability. Use cases would be to give the multicol container a height in viewport units in order to know that a reader would not have to scroll up and down to read the content, instead they could read one set of columns, scroll down and read the next. There are examples of people using vertical media queries to check for enough space to display columns such as https://css-tricks.com/guide-responsive-friendly-css-columns/#article-header-id-12
When discussing this, authors immediately jumped to the need/desire to control those overflow columns in some way, perhaps by being able to specify a different number of columns/column width in the overflow. For example having the first set of column boxes render three columns, and the second two.
I have a work-in-progress draft spec to deal with putting additional columns in the block direction (and sizing things properly, so that these extra columns are not only overflow, but actually consume space and don't collide with what's after). I'll share as soon as it is a bit more fleshed out.
When it comes to styling the next row(s) of columns differently, I think this will be solved by continue: fragment and ::nth-fragment](https://drafts.csswg.org/css-overflow-4/#fragment-pseudo-element). That isn't solved yet, but we're making baby steps towards it in css-overflow-3, since line-clamp starts to put in place some of the related machinery.
Reacted by Rachel Andrew, jonjohnjohnson, Ilya Streltsyn, Shane Holloway, Paul Shryock, Michael Puckett, (GalaxyMaster) and John Ozbay
The feature is absolutely needed, but it begs one comment: allowing text to flow in the block direction is equivalent to assigning paged media behavior to continuous media for the purpose of multicols (in paged media, columns must overflow in the "block" direction).
Wouldn't it be both more general and easier to allow CSS to assign paged media behavior to continuous media? This would well support the use of CSS to create interactive presentations (slides) or newspaper like layouts, on screen; and it would immediately solve the multicol issue.
By the way, controlling whether columns have the same specs when moving to the next "page/block" remains an open question.
It's something we intend to look at in Level 2, I'm currently working to get Level 1 back to CR so it isn't something we can focus on right now. What would help would be if someone were willing to pay for the work - neither @frivoal nor myself are specifically paid to work on multicol. So we do it as we have time to do and the time I have I'm using to get the issues in the Level 1 specification sorted.
@rachelandrew Thanks for the quick reply. Okay, I don't think I can afford to pay you 😅but, if it is at all helpful, maybe I can write about it publicly, and moot some ideas for the syntax. I am already exploring some existing ways to control column display based on circumstance, such as using quantity queries: https://codepen.io/heydon/pen/PvXJGv.
Yes - we are always interested in ideas and particularly in use cases for this stuff! Do post a link back here, it can take a while for things to get worked on but we do take the contributions of folk into account when we get to it.
I just stumbled on this peculiarity of the spec, and I want the spec to follow firefox, and historical webkit behaviour: extra content overflows vertically as if columns are balanced, and it respects orphans css prop.
Otherwise, I see no way how to square it with #4689 and spec-compliant column-fill, an min-height behaviour.
How overflow-y: auto can work if columns overflow an y-scrollable container element? Columns will overlow on the right, while y-direction will be occupied by empty space equivalent to height of overflown column?
End user here. I am using multicol for wide displays (e.g. 4K) when a user maximizes their browser window. This is to reduce difficulty in reading extra long lines of text.
I did run into a pecularity with this feature on iPad and I'm not sure if it's a bug or a feature. On the following web page, there is a line chart and a pie chart that just happen to straddle the column break. The page displays correctly at first, and sometimes when I scroll the line chart gets moved to the top of column 2 and the pie chart is displayed on top of the line chart. (not supposed to happen) Here's a screenshot:
Multicol seems to work as expected everywhere else that I have tested, it's just a physical iPad where I am seeing the issue, and only sometimes. I'm wondering if it's the particular webkit that runs on the iPad or some other issue. Environment is Chrome 126.0.6478.153 running on iPadOS 17.5.1.
I've written up some proposed spec changes for the multicol level 2 spec, for block direction overflow, and discussed them with a few folks at Chrome. Posted in this comment for discussion, and I'll add to the agenda. If I can get a resolution on the general approach I'll add this into the level 2 draft (which has a new FPWD) and raise any individual issues that come up separately.
Notes on the approach
I’ve modeled this after flex-wrap as it seems the closest thing we already have.
When we rejigged multicol level 1 I preserved “row” as a name for doing this (rather than use it for the rows of columns created by a spanner) as then we can talk about it in terms familiar to flex and grid. Also, if people want to put a decorative line between rows, that would be the row created by this block fragmentation rather than a spanner (you can already decorate a spanner with borders and so on, if that's the visual effect you want).
I think that creating new rows gives us a nested fragmentation flow that behaves pretty much like what happens in paged media, so a lot of the things we need to spec and implement are roughly the same as what happens when a multicol is paged. For example, column-fill already deals with balancing the last fragment in fragmented contexts. I’ll need to go through the spec and make sure that we talk about paged media and "continuous media where column-wrap is wrap".
Relationship to other work
The carousel work prompted me to write this up, as it will be nice to do block direction carousels (though developers want this functionality anyway as it makes multicol more useful on the web). We’d need to be able to snap to the row fragment as for a column fragment.
The work on gap decorations, as it’s likely that developers will want to have lines between the rows as well as between columns as already mentioned.
Additions and changes to the multicol-2 spec
A new property: column-wrap
The overflow direction in continuous media: the column-wrap property
Name: column-wrap
Value: nowrap | wrap
Initial: nowrap
Applies to: multicol containers
Inherited: no
Percentages: n/a
Computed value: specified keyword
Canonical order: per grammar
Animation type: discrete
The column-wrap property controls the behavior of overflow columns in continuous media.
nowrap: Overflow columns are created in the inline direction.
wrap: Overflow columns create a new multicol row in the block direction.
Example:
body {
column-count:3;
block-size: 10em;
column-wrap: wrap;
}
This would create a set of three columns. If there was more content than would fit in the 10em block-size of these columns, rather than overflowing in the line direction as currently happens, a new row of columns would be created in the block direction, again at a max block-size of 10em.
The column-width, column-count, and column-wrap Shorthand: The columns property
Name: columns
Value: <'column-width'> || <'column-count'> || <'column-wrap'>
Initial: see individual properties
Applies to: see individual properties
Inherited: see individual properties
Percentages: see individual properties
Computed value: see individual properties
Animation type: see individual properties
Canonical order: per grammar
This is a shorthand property for setting column-width, column-count, and column-wrap. Omitted values are set to their initial values.
Adding column-wrap here so that it's possible to set all three at once.
Content and column rules that extend outside column boxes at the edges of the multi-column container are clipped according to the overflow property.
A multicol container can have more columns than it has room for due to:
a declaration that constrains the column height (e.g., using height or max-height). In this case, additional column boxes are created according to the value of column-wrap.
the size of the page. In this case, additional column boxes are moved to the next page(s).
explicit column breaks. In this case, additional column boxes are created according to the value of column-wrap for continuous contexts and additional column boxes are moved to the next fragment(s) for fragmented media.
multicol-2 defines the ::column pseudo-element. I think we'll also want to define ::row if we're scrolling in the block direction and stopping on rows.
There will be other places in the spec (anywhere mentioning paged vs continuous media) that need to refer to the value of column-wrap.
Reacted by Roman Komarov, Raura, Sebastian Zartner, Denis Defreyne, Kevin Babbitt, Morten Stenshorne and berlysia
Yes I think row-gap should apply, I guess the question would be whether it should match column-gap in multicol and normal be 1em, or match other gaps and be 0. I'll raise that as a separate issue, thanks for bringing it up.
I (strongly) agree with the goal of this, but I have different proposal / syntax for getting here.
One thing I am not a fan of in the proposal in #2923 (comment) is how it handles (max-)height / block-size: say you set the height of your multicol to be 10em. Depending on how many rows you get, the actual height might be 20em, or 30em (+ the gap size), and that's weird. What we are constraining is not the height / block-size of the multicol, it's the height / block-size of the rows, so using the height / block-size property seems off to me: that should care about the multicol as a whole, and a separate property should care about the height of the rows. Based on that notion, here's an outline my alternative proposal:
The multi-col container contains at one or more column-row box, which in turn, contain column lines (themselves containing column boxes), as described in multi-col 1.
If there is more than 1 column row box, they stack up in the block axis, separated by a gutter whose size is determined by 'row-gap'.
If 'column-rule' is set, a rule is drawn in the row gaps as well as in the column gaps.
name: column-row-height
value: auto | <length [0,∞]>
initial: auto
Sets available space in the block direction for column boxes, effectively acting as a cap on column box height.
auto: the available space is equal to the min inner height of the multicol container.
When 'column-row-height' has a value other than ''column-row-height/auto'',
[=overflow columns=] are not added in the inline direction.
Instead, additional column rows are created as needed
to host the excess columns.
If you set both column-row-height to a non-auto value and height, your may have some leftover space in your multicol. https://drafts.csswg.org/css-align would tell you how to deal with it. (Details of how that works are interesting, but secondary to the concept as a whole.)
This could also be extended to have a column-row-count property, but I find the use cases less convincing, so I didn't include it.
In a way, there's an implied column-wrap: auto | nowrap | wrap underlying this, where auto is the initial value, which resolves to nowrap if column-row-height is auto, and to wrap if not. I had it in my initial draft, but in practice I don't think there's much use for values other that auto, so I think this should not be exposed, at least in an initial version.
I (strongly) agree with the goal of this, but I have different proposal / syntax for getting here.
One thing I am not a fan of in the proposal in #2923 (comment) is how it handles (max-)height / block-size: say you set the height of your multicol to be 10em. Depending on how many rows you get, the actual height might be 20em, or 30em (+ the gap size), and that's weird. What we are constraining is not the height / block-size of the multicol, it's the height / block-size of the rows, so using the height / block-size property seems off to me: that should care about the multicol as a whole, and a separate property should care about the height of the rows.
I don't think that was how it was meant to be read. The actual multicol height will be 10em, but it will be overflown with any additional rows. Using height / block-size both for sizing the multicol container and its rows does limit the possible uses, indeed. The use case it does support quite conveniently is when the multicol container has scrollable overflow. If it doesn't have scrollable overflow, the overflow will just overlap with subsequent content and look bad.
Based on that notion, here's an outline my alternative proposal:
[...]
name: column-row-height value: auto | <length [0,∞]> initial: auto
Sets available space in the block direction for column boxes, effectively acting as a cap on column box height.
auto: the available space is equal to the min inner height of the multicol container.
When 'column-row-height' has a value other than ''column-row-height/auto'', [=overflow columns=] are not added in the inline direction. Instead, additional column rows are created as needed to host the excess columns.
If you set both column-row-height to a non-auto value and height, your may have some leftover space in your multicol. https://drafts.csswg.org/css-align would tell you how to deal with it. (Details of how that works are interesting, but secondary to the concept as a whole.)
[...]
In a way, there's an implied column-wrap: auto | nowrap | wrap underlying this, where auto is the initial value, which resolves to nowrap if column-row-height is auto, and to wrap if not. I had it in my initial draft, but in practice I don't think there's much use for values other that auto, so I think this should not be exposed, at least in an initial version.
If column-row-height is auto, I really think we want to have a way of controlling where the overflow goes.
<divstyle="overflow:scroll; columns:3; column-fill:auto; height:100px;">
[... lots of text ...]
</div>
This will create additional columns in the inline direction. Back to the original use case, where we don't want to specify a column row size, but want overflowing content to establish additional rows, rather than creating overflowing columns in the inline direction... We want a way of achieving that. I think column-wrap is needed for that.
Quite oppositely of what you're thinking, I'm not sure what the auto value would be used for, but I see strong use cases for the two other values. :)
A column-row-height property would allow for some "interesting" scenarios in nested fragmentation, since this new thing "column rows" isn't the same as what happens when breaking inside a nested block fragmentation context:
I agree with @frivoal that using (max-)height/block-size for this feels weird, especially when you start thinking about stuff like calc-size() and animating the block-size of the columns’ container with interpolate-size: allow-keywords.
And yes, “If it doesn't have scrollable overflow, the overflow will just overlap with subsequent content and look bad.” is something we'd want to avoid, and the case with the overflow is a good one, as I don't think we want the element to have different outer dimensions based on if it is visible or auto, for example.
There is another thing that I would like to throw in. It could be totally to be something for the future level of the spec, but I felt that this is something that also points to using a different property to control the block direction rather than the height/block-size. It is that there might be cases where you'd want each row created this way to be different. If we'd want to control this via something similar to grid-template-rows, where we could define either a static value (as described now), or a pattern that would include repeat(), it could unlock some more interesting layouts.
If we think about the overflow in block direction as “pages” and think about print, then this is not a use case that comes to mind, but when translated to a web page, having dynamic rows can make more sense. Although, maybe at this point we're going closer to regions :) But I wanted to mention this possible extension as something that would be harder to do with just height/block-size.
I think one concern I have with having a separate value for the block size, is that we then end up with situations such as an author wanting overflow in the block direction, setting a height on the multicol, and the row height however there still isn't enough space in the multicol container for all of the rows (due to the height). What happens then?
The dev ergonomics currently are:
Set a height.
Get overflow columns in the inline direction
The future spec (my version)
Set a height
Choose whether to get overflow columns in the inline or block direction, by setting them to wrap.
Multicol is a pretty simple thing, in terms of how it's used. I get that having a separate size for rows might open up a bunch of other possibilities, but are they possibilities that anyone actually needs for multicol? Or are we just making the spec more complex because it might be nice to do that stuff at some point.
That said, I'm not completely against the idea, and we should discuss it, I'm just wary of making something complex for the sake of it. We have more complex layout methods, we could potentially introduce something more like regions to do the more complex fragmented cases ... I'm thinking we probably don't want to morph multicol into something that does bits of regions-like things, but never really fulfils that idea.
The CSS Working Group just discussed [css-multicol] Overflow in the block direction for continuous media, and agreed to the following:
RESOLVED: start specifying column-height
The full IRC log of that discussion
<nicole> rachelandrew: speccing overflow in block direction for multicol
<nicole> rachelandrew: partially becuases of the carousel work, and partially because it can go in different directions. Rachel put proposed spec in the issue as a starting point
<nicole> rachelandrew: modeled after flex
<astearns> proposal: https://github.com//issues/2923#issuecomment-2566448417
<nicole> rachelandrew: modeled after logical container. Instead you could opt to use column wrap
<fantasai> +1 for a row-height property
<astearns> florian's: https://github.com//issues/2923#issuecomment-2620334162
<nicole> rachelandrew: has a different proposal. what should we do, which looks best?
<florian> q+
<astearns> ack florian
<nicole> florian: want to have this ability. multicol having overflow columns in inline dir isnt' what people want most of the time. Having multiple rows of multicol is extremely desirable.
<nicole> florian: constrain height, overflow in block direction rather than inline direction
<kizu> q+
<nicole> florian: are they simply overflowing. Will they clash? Or whether you simply grow the multicol despite the constrained height
<nicole> florian: should the rows add height?
<nicole> florian: proposes a new prop to constrain the height of the row of the multicol. column-height or column-row-height would work well.
<nicole> florian: column-row-height: 10em
<nicole> florian: if you also set the multicol height, you use all the css tools to deal with how to lay them out
<TabAtkins> yup, +1 to column-row-height
<nicole> florian: not sure what short hands should be
<astearns> ack fantasai
<nicole> florian: how to make it work with gap and other properties needs to be worked out
<florian> q+
<nicole> fantasai: doesn't want an overflow model for this feature (in flow content). Don't conflate sizing the box with content inside the box. Prop that sets column height is the right thing to do
<astearns> ack kizu
<TabAtkins> ah yeah, column-height is shorter and just as right
<astearns> q+
<nicole> fantasai: likes column-height
<nicole> roman: wants this feature. Could imagine automatically fragmenting so that each item goes into the overflow container
<astearns> ack florian
<nicole> roman: use case to fit everything in viewport so it paginates properly
<nicole> florian: not incompatible with having a property
<TabAtkins> (i do think it would be nice to have a `column-height: auto` that matches the height of the nearest scroller)
<fantasai> s/use case/but more common is use case of having it in-flow,/
<nicole> florian: if you set it to auto it would go in the block direction otherwise inline
<nicole> florian: row-height instead of column-height because we might want to use column-row-count later, but won't insiste
<rachelandrew> q+
<nicole> fantasai: column-height and column-width as a pair seems better
<nicole> fantasai: authors won't think about columns as explicitly as rows
<florian> q+
<nicole> astearns: florian mentioned overflow in inline dir, but thinks it is the wrong way to talk about it. We are fragmenting in the inline direction or block direction. As you fragment columns now they can overflow in inline direction.
<nicole> astearns: when we add this you will be able to fragment in the block direction
<nicole> astearns: but it also might overflow, to put the content in the new contents
<nicole> florian: agree overflow isn't quite the right word. Neither is fragmentation. Fragmenting the content of the multicol, and deciding where to place them. Whether they overflow depends where you place them and what else is there.
<nicole> florian: rachelandrew proposed column wrap, whatever we call it, they describe where the extra content goes (block or inline direction)
<astearns> ack rachelandrew
<astearns> ack astearns
<astearns> ack florian
<nicole> astearns: doesn't agree with fantasai that ___ will be rare, he thinks authors will want to do it at the outset
<nicole> rachelandrew: what happens if you have set a height on multicol and then you set column height and row height. And then you have too many things to fit in the container. Answer could be that it overflows
<nicole> florian: yes
<astearns> s/___ /choosing how many rows of columns you want/
<florian> q+
<astearns> ack florian
<nicole> rachelandrew: are we bringing in too much extra complexity? Is it getting to be like regions. Not against direction, just concerned about complexity.
<nicole> florian: yes it would overflow, like any content that doesn't fit would
<nicole> florian: doesn't matter how many rows cols you put in there
<nicole> florian: if it is too big, you have other tools to deal with extra space
<TabAtkins> I definitely think tying this explicitly to overflow *is* making it too complex. Just adding more columns to the content seems like the most straightforward way
<nicole> astearns: proposed resolution to start specifying this using column-height
<nicole> rachelandrew: happy with that
<kbabbitt> 👍
<nicole> RESOLVED: start specifying column-height
Reacted by Roman Komarov, Rainer Martinez, Joe, Zoë Bijl, Massimo Artizzu and dai
@frivoal I think we do still need the wrap property as a trigger.
If we give people the ability to use the alignment properties when there is extra space in the container, I can imagine people wanting to use that with inline overflow columns. So to set a column-height, and a container height, keep the inline columns and use the extra space somehow.
If we're going for the column-height version I think we should allow it to work both ways, therefore the switch does need to be something else, probably column-wrap. That seems cleaner to me anyway, and makes it explicit that you want wrapping, rather than the magic happening because you set a column-height.
This also includes my suggestion for keeping column-wrap as the trigger. I have not gone through the entire spec and updated all the places that need changing based on adding block direction overflow, as I'd like to get a resolution on column-wrap first, as that's going to at the very least change how we describe the feature elsewhere.
I raised #11754 to explain why I think we need column-wrap and a secondary issue should we adopt that.
Activity
frivoal commentedon Jul 13, 2018
I have a work-in-progress draft spec to deal with putting additional columns in the block direction (and sizing things properly, so that these extra columns are not only overflow, but actually consume space and don't collide with what's after). I'll share as soon as it is a bit more fleshed out.
When it comes to styling the next row(s) of columns differently, I think this will be solved by
continue: fragmentand::nth-fragment](https://drafts.csswg.org/css-overflow-4/#fragment-pseudo-element). That isn't solved yet, but we're making baby steps towards it in css-overflow-3, sinceline-clampstarts to put in place some of the related machinery.arnt commentedon Jan 12, 2019
For paged media, please make the default height of the multicol container be "to the bottom of the current page".
jr-grenoble commentedon May 11, 2019
The feature is absolutely needed, but it begs one comment: allowing text to flow in the block direction is equivalent to assigning paged media behavior to continuous media for the purpose of multicols (in paged media, columns must overflow in the "block" direction).
Wouldn't it be both more general and easier to allow CSS to assign paged media behavior to continuous media? This would well support the use of CSS to create interactive presentations (slides) or newspaper like layouts, on screen; and it would immediately solve the multicol issue.
By the way, controlling whether columns have the same specs when moving to the next "page/block" remains an open question.
Heydon commentedon Jul 19, 2019
What can I do to help push this along?
rachelandrew commentedon Jul 19, 2019
It's something we intend to look at in Level 2, I'm currently working to get Level 1 back to CR so it isn't something we can focus on right now. What would help would be if someone were willing to pay for the work - neither @frivoal nor myself are specifically paid to work on multicol. So we do it as we have time to do and the time I have I'm using to get the issues in the Level 1 specification sorted.
Heydon commentedon Jul 19, 2019
@rachelandrew Thanks for the quick reply. Okay, I don't think I can afford to pay you 😅but, if it is at all helpful, maybe I can write about it publicly, and moot some ideas for the syntax. I am already exploring some existing ways to control column display based on circumstance, such as using quantity queries: https://codepen.io/heydon/pen/PvXJGv.
rachelandrew commentedon Jul 19, 2019
Yes - we are always interested in ideas and particularly in use cases for this stuff! Do post a link back here, it can take a while for things to get worked on but we do take the contributions of folk into account when we get to it.
Heydon commentedon Jul 22, 2019
@rachelandrew Here's the post: https://every-layout.dev/blog/multi-column-manipulation/
P.S. I tried using a CSS regions polyfill to emulate block overflow, but couldn't get the polyfill itself yo work. I may revisit it.
baybal commentedon Nov 29, 2021
I just stumbled on this peculiarity of the spec, and I want the spec to follow firefox, and historical webkit behaviour: extra content overflows vertically as if columns are balanced, and it respects orphans css prop.
Otherwise, I see no way how to square it with #4689 and spec-compliant column-fill, an min-height behaviour.
How overflow-y: auto can work if columns overflow an y-scrollable container element? Columns will overlow on the right, while y-direction will be occupied by empty space equivalent to height of overflown column?
I cannot fathom what purpose this logic serves.
seannherdy commentedon Aug 5, 2024
End user here. I am using multicol for wide displays (e.g. 4K) when a user maximizes their browser window. This is to reduce difficulty in reading extra long lines of text.
I did run into a pecularity with this feature on iPad and I'm not sure if it's a bug or a feature. On the following web page, there is a line chart and a pie chart that just happen to straddle the column break. The page displays correctly at first, and sometimes when I scroll the line chart gets moved to the top of column 2 and the pie chart is displayed on top of the line chart. (not supposed to happen) Here's a screenshot:
Multicol seems to work as expected everywhere else that I have tested, it's just a physical iPad where I am seeing the issue, and only sometimes. I'm wondering if it's the particular webkit that runs on the iPad or some other issue. Environment is Chrome 126.0.6478.153 running on iPadOS 17.5.1.
rachelandrew commentedon Dec 31, 2024
@seannherdy this seems to be a browser issue rather than related to the issue you have commented on. Perhaps raise a WebKit bug https://webkit.org/reporting-bugs/
rachelandrew commentedon Dec 31, 2024
I've written up some proposed spec changes for the multicol level 2 spec, for block direction overflow, and discussed them with a few folks at Chrome. Posted in this comment for discussion, and I'll add to the agenda. If I can get a resolution on the general approach I'll add this into the level 2 draft (which has a new FPWD) and raise any individual issues that come up separately.
Notes on the approach
Relationship to other work
The carousel work prompted me to write this up, as it will be nice to do block direction carousels (though developers want this functionality anyway as it makes multicol more useful on the web). We’d need to be able to snap to the row fragment as for a column fragment.
The work on gap decorations, as it’s likely that developers will want to have lines between the rows as well as between columns as already mentioned.
Additions and changes to the multicol-2 spec
A new property:
column-wrapThe overflow direction in continuous media: the column-wrap property
Name: column-wrap
Value:
nowrap | wrapInitial: nowrap
Applies to: multicol containers
Inherited: no
Percentages: n/a
Computed value: specified keyword
Canonical order: per grammar
Animation type: discrete
The
column-wrapproperty controls the behavior of overflow columns in continuous media.nowrap: Overflow columns are created in the inline direction.wrap: Overflow columns create a new multicol row in the block direction.Example:
This would create a set of three columns. If there was more content than would fit in the 10em
block-sizeof these columns, rather than overflowing in the line direction as currently happens, a new row of columns would be created in the block direction, again at a max block-size of 10em.Changes to the columns shorthand
The column-width, column-count, and column-wrap Shorthand: The columns property
Name: columns
Value:
<'column-width'> || <'column-count'> || <'column-wrap'>Initial: see individual properties
Applies to: see individual properties
Inherited: see individual properties
Percentages: see individual properties
Computed value: see individual properties
Animation type: see individual properties
Canonical order: per grammar
This is a shorthand property for setting column-width, column-count, and column-wrap. Omitted values are set to their initial values.
Adding
column-wraphere so that it's possible to set all three at once.Changes to section Overflow
Content and column rules that extend outside column boxes at the edges of the multi-column container are clipped according to the overflow property.
A multicol container can have more columns than it has room for due to:
Other changes
::columnpseudo-element. I think we'll also want to define::rowif we're scrolling in the block direction and stopping on rows.column-wrap.1 remaining item
rachelandrew commentedon Jan 17, 2025
Yes I think
row-gapshould apply, I guess the question would be whether it should matchcolumn-gapin multicol and normal be 1em, or match other gaps and be 0. I'll raise that as a separate issue, thanks for bringing it up.rachelandrew commentedon Jan 20, 2025
Issue for
row-gap: normal: #11539mstensho commentedon Jan 20, 2025
Looks good! One thing I don't get is why this would give us a nested fragmentation flow. It's still just one fragmentation context.
frivoal commentedon Jan 29, 2025
I (strongly) agree with the goal of this, but I have different proposal / syntax for getting here.
One thing I am not a fan of in the proposal in #2923 (comment) is how it handles
(max-)height/block-size: say you set the height of your multicol to be 10em. Depending on how many rows you get, the actual height might be 20em, or 30em (+ the gap size), and that's weird. What we are constraining is not theheight/block-sizeof the multicol, it's theheight/block-sizeof the rows, so using theheight/block-sizeproperty seems off to me: that should care about the multicol as a whole, and a separate property should care about the height of the rows. Based on that notion, here's an outline my alternative proposal:The multi-col container contains at one or more column-row box, which in turn, contain column lines (themselves containing column boxes), as described in multi-col 1.
If there is more than 1 column row box, they stack up in the block axis, separated by a gutter whose size is determined by 'row-gap'.
If 'column-rule' is set, a rule is drawn in the row gaps as well as in the column gaps.
Name: columns
Value: <'column-width'> || <'column-count'> [ / <'column-row-height'> ]?
name: column-row-height
value: auto | <length [0,∞]>
initial: auto
Sets available space in the block direction for column boxes, effectively acting as a cap on column box height.
auto: the available space is equal to the min inner height of the multicol container.
When 'column-row-height' has a value other than ''column-row-height/auto'',
[=overflow columns=] are not added in the inline direction.
Instead, additional column rows are created as needed
to host the excess columns.
If you set both
column-row-heightto a non-auto value andheight, your may have some leftover space in your multicol. https://drafts.csswg.org/css-align would tell you how to deal with it. (Details of how that works are interesting, but secondary to the concept as a whole.)example
article {
columns: 3 20em / 80vh;
gap: 1em 2em;
}
Notes:
column-row-countproperty, but I find the use cases less convincing, so I didn't include it.column-wrap: auto | nowrap | wrapunderlying this, where auto is the initial value, which resolves to nowrap if column-row-height is auto, and to wrap if not. I had it in my initial draft, but in practice I don't think there's much use for values other thatauto, so I think this should not be exposed, at least in an initial version.mstensho commentedon Jan 29, 2025
I don't think that was how it was meant to be read. The actual multicol height will be 10em, but it will be overflown with any additional rows. Using
height/block-sizeboth for sizing the multicol container and its rows does limit the possible uses, indeed. The use case it does support quite conveniently is when the multicol container has scrollable overflow. If it doesn't have scrollable overflow, the overflow will just overlap with subsequent content and look bad.[...]
[...]
If
column-row-heightisauto, I really think we want to have a way of controlling where the overflow goes.This will create additional columns in the inline direction. Back to the original use case, where we don't want to specify a column row size, but want overflowing content to establish additional rows, rather than creating overflowing columns in the inline direction... We want a way of achieving that. I think
column-wrapis needed for that.Quite oppositely of what you're thinking, I'm not sure what the
autovalue would be used for, but I see strong use cases for the two other values. :)A
column-row-heightproperty would allow for some "interesting" scenarios in nested fragmentation, since this new thing "column rows" isn't the same as what happens when breaking inside a nested block fragmentation context:Should it look like this?
kizu commentedon Jan 29, 2025
I agree with @frivoal that using
(max-)height/block-sizefor this feels weird, especially when you start thinking about stuff likecalc-size()and animating the block-size of the columns’ container withinterpolate-size: allow-keywords.And yes, “If it doesn't have scrollable overflow, the overflow will just overlap with subsequent content and look bad.” is something we'd want to avoid, and the case with the
overflowis a good one, as I don't think we want the element to have different outer dimensions based on if it isvisibleorauto, for example.There is another thing that I would like to throw in. It could be totally to be something for the future level of the spec, but I felt that this is something that also points to using a different property to control the block direction rather than the
height/block-size. It is that there might be cases where you'd want each row created this way to be different. If we'd want to control this via something similar togrid-template-rows, where we could define either a static value (as described now), or a pattern that would includerepeat(), it could unlock some more interesting layouts.If we think about the overflow in block direction as “pages” and think about print, then this is not a use case that comes to mind, but when translated to a web page, having dynamic rows can make more sense. Although, maybe at this point we're going closer to regions :) But I wanted to mention this possible extension as something that would be harder to do with just
height/block-size.rachelandrew commentedon Jan 30, 2025
I think one concern I have with having a separate value for the block size, is that we then end up with situations such as an author wanting overflow in the block direction, setting a height on the multicol, and the row height however there still isn't enough space in the multicol container for all of the rows (due to the height). What happens then?
The dev ergonomics currently are:
The future spec (my version)
Multicol is a pretty simple thing, in terms of how it's used. I get that having a separate size for rows might open up a bunch of other possibilities, but are they possibilities that anyone actually needs for multicol? Or are we just making the spec more complex because it might be nice to do that stuff at some point.
That said, I'm not completely against the idea, and we should discuss it, I'm just wary of making something complex for the sake of it. We have more complex layout methods, we could potentially introduce something more like regions to do the more complex fragmented cases ... I'm thinking we probably don't want to morph multicol into something that does bits of regions-like things, but never really fulfils that idea.
css-meeting-bot commentedon Jan 30, 2025
The CSS Working Group just discussed
[css-multicol] Overflow in the block direction for continuous media, and agreed to the following:RESOLVED: start specifying column-heightThe full IRC log of that discussion
<nicole> rachelandrew: speccing overflow in block direction for multicol<nicole> rachelandrew: partially becuases of the carousel work, and partially because it can go in different directions. Rachel put proposed spec in the issue as a starting point
<nicole> rachelandrew: modeled after flex
<astearns> proposal: https://github.com//issues/2923#issuecomment-2566448417
<nicole> rachelandrew: modeled after logical container. Instead you could opt to use column wrap
<fantasai> +1 for a row-height property
<astearns> florian's: https://github.com//issues/2923#issuecomment-2620334162
<nicole> rachelandrew: has a different proposal. what should we do, which looks best?
<florian> q+
<astearns> ack florian
<nicole> florian: want to have this ability. multicol having overflow columns in inline dir isnt' what people want most of the time. Having multiple rows of multicol is extremely desirable.
<nicole> florian: constrain height, overflow in block direction rather than inline direction
<kizu> q+
<nicole> florian: are they simply overflowing. Will they clash? Or whether you simply grow the multicol despite the constrained height
<nicole> florian: should the rows add height?
<nicole> florian: proposes a new prop to constrain the height of the row of the multicol. column-height or column-row-height would work well.
<nicole> florian: column-row-height: 10em
<nicole> florian: if you also set the multicol height, you use all the css tools to deal with how to lay them out
<TabAtkins> yup, +1 to column-row-height
<nicole> florian: not sure what short hands should be
<astearns> ack fantasai
<nicole> florian: how to make it work with gap and other properties needs to be worked out
<florian> q+
<nicole> fantasai: doesn't want an overflow model for this feature (in flow content). Don't conflate sizing the box with content inside the box. Prop that sets column height is the right thing to do
<astearns> ack kizu
<TabAtkins> ah yeah, column-height is shorter and just as right
<astearns> q+
<nicole> fantasai: likes column-height
<nicole> roman: wants this feature. Could imagine automatically fragmenting so that each item goes into the overflow container
<astearns> ack florian
<nicole> roman: use case to fit everything in viewport so it paginates properly
<nicole> florian: not incompatible with having a property
<TabAtkins> (i do think it would be nice to have a `column-height: auto` that matches the height of the nearest scroller)
<fantasai> s/use case/but more common is use case of having it in-flow,/
<nicole> florian: if you set it to auto it would go in the block direction otherwise inline
<nicole> florian: row-height instead of column-height because we might want to use column-row-count later, but won't insiste
<rachelandrew> q+
<nicole> fantasai: column-height and column-width as a pair seems better
<nicole> fantasai: authors won't think about columns as explicitly as rows
<florian> q+
<nicole> astearns: florian mentioned overflow in inline dir, but thinks it is the wrong way to talk about it. We are fragmenting in the inline direction or block direction. As you fragment columns now they can overflow in inline direction.
<nicole> astearns: when we add this you will be able to fragment in the block direction
<nicole> astearns: but it also might overflow, to put the content in the new contents
<nicole> florian: agree overflow isn't quite the right word. Neither is fragmentation. Fragmenting the content of the multicol, and deciding where to place them. Whether they overflow depends where you place them and what else is there.
<nicole> florian: rachelandrew proposed column wrap, whatever we call it, they describe where the extra content goes (block or inline direction)
<astearns> ack rachelandrew
<astearns> ack astearns
<astearns> ack florian
<nicole> astearns: doesn't agree with fantasai that ___ will be rare, he thinks authors will want to do it at the outset
<nicole> rachelandrew: what happens if you have set a height on multicol and then you set column height and row height. And then you have too many things to fit in the container. Answer could be that it overflows
<nicole> florian: yes
<astearns> s/___ /choosing how many rows of columns you want/
<florian> q+
<astearns> ack florian
<nicole> rachelandrew: are we bringing in too much extra complexity? Is it getting to be like regions. Not against direction, just concerned about complexity.
<nicole> florian: yes it would overflow, like any content that doesn't fit would
<nicole> florian: doesn't matter how many rows cols you put in there
<nicole> florian: if it is too big, you have other tools to deal with extra space
<TabAtkins> I definitely think tying this explicitly to overflow *is* making it too complex. Just adding more columns to the content seems like the most straightforward way
<nicole> astearns: proposed resolution to start specifying this using column-height
<nicole> rachelandrew: happy with that
<kbabbitt> 👍
<nicole> RESOLVED: start specifying column-height
rachelandrew commentedon Feb 4, 2025
@frivoal I think we do still need the wrap property as a trigger.
If we give people the ability to use the alignment properties when there is extra space in the container, I can imagine people wanting to use that with inline overflow columns. So to set a column-height, and a container height, keep the inline columns and use the extra space somehow.
If we're going for the column-height version I think we should allow it to work both ways, therefore the switch does need to be something else, probably
column-wrap. That seems cleaner to me anyway, and makes it explicit that you want wrapping, rather than the magic happening because you set a column-height.rachelandrew commentedon Feb 20, 2025
I've added an initial draft in 29b1f61
This also includes my suggestion for keeping
column-wrapas the trigger. I have not gone through the entire spec and updated all the places that need changing based on adding block direction overflow, as I'd like to get a resolution oncolumn-wrapfirst, as that's going to at the very least change how we describe the feature elsewhere.I raised #11754 to explain why I think we need
column-wrapand a secondary issue should we adopt that.