Skip to content

[css-multicol-2] Initial pass at changes to the model section. #12544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

rachelandrew
Copy link
Contributor

There will be more to do here, and I want to add some images, but here's a first pass at the basics so we at least have lines and rows defined.

I haven't added the stuff about nested multicols here, not sure if it's the right place.

@rachelandrew
Copy link
Contributor Author

@mstensho I couldn't add you as a reviewer for some reason but PTAL at this initial pass on the model section.

and arranged into <dfn lt="multi-column line | multi-col line | multicol line">multicol lines</dfn>.
and arranged into
<dfn lt="multi-column row | multi-col row | multicol row">multicol rows</dfn>.
A multicol row contains at least one <dfn lt="multi-column line | multi-col line | multicol line">multicol line</dfn>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A row may also very well just contain a spanner (and no lines), right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this based on another suggestion.

The <dfn export>column width</dfn> is the length of the column box in the inline direction.
The <dfn export>column height</dfn> is the length of the column box in the block direction.
All column boxes in a line have the same column width,
and all column boxes in a line have the same column height.
All column boxes in a row have the same column width,
Copy link
Contributor

@mstensho mstensho Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Column boxes are inside a line (which is inside a row). Why this change? It's also wrong in some cases, actually, since fragments generated from the same multicol container (when nested inside another fragmentation context) may have different widths or heights. Since each multicol fragment establishes a separate line for its columns (right?), if it has any columns at all, the width and height of column boxes are the same within a line (but not necessarily within a row).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I think this depends on where we see the height as happening.

  • The column-height is 100px.
  • There's a spanner, it is 20px tall.
  • We now have two multicol lines, one above and one below the spanner.
  • If the column-height is what defines the row height, those lines are each 40px tall.

Therefore the height the author cares about is the height of the column, because that defines the height of the row. If you consider a block direction carousel where each row is 100vh, the author needs to set the column-height to 100vh, which defines the row size. The only reason the row would be a different size would be if we had to stretch due to a giant spanner (if we go that way).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming that we have the same amount of content before and after the spanner, then yes, the columns will all have a height of 40px, both before and after the spanner.

<!DOCTYPE html>
<div style="columns:3; column-fill:auto; column-height:100px; line-height:20px;">
  before
  <div style="column-span:all;">spanner</div>
  after<br>after<br>after<br>after<br>after<br>
</div>

There's a multicol container. It has one row that is 100px tall. The row has one line, one spanner, then another line.
The first line is 20px tall, the spanner is 20px tall, the second line is 60px tall. The columns in the first line is 20px tall. The columns in the second line are 60px tall. Therefore all columns in a row do not necessarily have the same column height.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean... maybe we need to more strongly define column boxes vs columns? As it's the column that has the height, depending on how many lines there are multiple column boxes within each column. I think that's where I'm confusing things anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused now. :) Multiple column boxes within each column? In my mental model, there's no distinction between "column" and a "column box". In my example above, there should be one column (or column box) above the spanner (there's just one word there, after all), and two columns (or two column boxes) below the spanner. Are you thinking that the first column box above the spanner and the first column box below the spanner form one column? Or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That won't work for the carousel type use cases. You'd end up with a spanner outside of the "page" which would be weird.

It would be fine for the simplest use case of just making sure people don't need to scroll up and down to read, but if we want an entire screen to be a row AND you had a spanner, you'd then end up with the spanner off the bottom of the screen.

Also it would definitely stop column-span: <integer> ever being a thing.

We need the lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To explain about column-span: <integer> the most likely way (in my mind) to implement that would be in conjunction with page floats. So you'd have a three column multicol container, and an element spanning two columns floated top right. That's a super common magazine type layout and the sort of thing people raise (for example #11474).

That would not work if spanners were this weird thing that existed outside of rows.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do carousel type use cases even want spanners at all, though?

Spanners are taken "out of flow" anyway, and I see no strict reason for them having to belong inside a row. Yes, I think page float is the use case for column-span: <integer>. Anything else (non-floated) would be weird, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be such an unexpected behavior for spanners to do that, to immediately lose the nice "set of pages at x height" because there's a spanner seems bad. I do thing that a carousel type layout using page floats would likely be something people want if we ever go there, because there's some nice (and fairly obvious) patterns you could achieve with that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that makes sense. So I guess we need lines and rows. Sorry for the detour.

And deal with page floats later. :) You seem to want them to be contained by rows? They don't need to live inside multicol, though (in which case there'll be no rows). E.g. when printing. We may want to top/bottom align a page float. When printing with multicol, we might want them to span a certain number of columns. If there's no column wrapping set, there'll still be just one giant row, but we then want the page floats to be aligned with some page edge, since the row is irrelevant in that case.

@@ -529,15 +532,15 @@ The multi-column model</h2>
hit-test-in-vertical-rl.html
</wpt>

Within each [=multicol line=] in the multi-column container,
Within each [=multicol row=] in the multi-column container,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should remain "line" as well, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed.

@@ -360,11 +360,14 @@ The multi-column model</h2>

The column boxes are ordered
in the [=inline base direction=] of the multicol container
and arranged into <dfn lt="multi-column line | multi-col line | multicol line">multicol lines</dfn>.
and arranged into
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The column boxes are arranged into lines that are inside a row, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure conceptually, because the height of the column (column-height) is what defines the size of the row. It could, however, contain two lines and a spanner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a row contains lines and/or spanners. Lines contain columns. So the column boxes are arranged into lines whose height are confined by the containing row, due to column-height.

So I was thinking that this part looked right the way it was.

The column boxes are ordered in the inline base direction of the multicol container and arranged into multicol lines.

Then explain that a line is contained by a row?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to do this this way round PTAL.

@@ -547,10 +550,17 @@ The multi-column model</h2>
constrained by the page and the content continues in a new line of
column boxes on the next page; a column box never splits across pages.

The same effect occurs when a <i>spanning element</i> divides the
multi-column container: the columns before the spanning element are
If a multi-column container in continuous media is set to wrap,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why just continuous media?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see what the use case is for doing this in paged media, paged media already overflows into new pages. If there's a use case, then great, but this has always been discussed as for continuous media.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So column-wrap only applies in continuous media? It should probably also not apply in nested multicol then (even if media may be continuous in such cases).

Not sure about wording.

If a multi-column container that doesn't participate in a fragmentation context (such as paged media) is set to wrap [...]

?

If we add this limitation, and also do it for column-height, it also means that #11977 doesn't need to be resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding a limitation for nesting is probably ok, I think the only nested multicols I come across are in test cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if we want to avoid this in paged media, we should avoid it for any kind of nested fragmentation - e.g. nested multicol as well.

@rachelandrew
Copy link
Contributor Author

@mstensho thanks for all the discussion, I've updated this some more.

adjacent column boxes are separated by a <dfn noexport>column gap</dfn>,
which may contain a <dfn noexport>column rule</dfn>.
In the block direction, [=column rows=] are separated by a <dfn noexport>column gap</dfn>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

row gap

adjacent column boxes are separated by a <dfn noexport>column gap</dfn>,
which may contain a <dfn noexport>column rule</dfn>.
In the block direction, [=column rows=] are separated by a <dfn noexport>column gap</dfn>,
which may contain a <dfn noexport>column rule</dfn>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

row rule

the height of each column is defined by the 'column-height' property.
If there is more content than will fit in a single row a new multicol row is created
in the block direction, with columns of the size defined by the 'column-height' property.
This row contains at least one multicol line or one spanning element.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true for all rows, and is also mentioned further up.

Copy link
Contributor

@mstensho mstensho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also include wording about disallowing wrapping for fragmented multicols (paged media / nested multicol)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants