Skip to content

[css-align][css-multicol] 'justify-content' other than 'normal' or 'stretch' should change column count/size rules #1420

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

Closed
dbaron opened this issue May 20, 2017 · 17 comments

Comments

@dbaron
Copy link
Member

dbaron commented May 20, 2017

The sizing specification describes how justify-content applies to multicols. However, this application seems less than ideal given its interaction with the column count and sizing rules in multicol.

In particular, when justify-content is not normal or stretch, I think a non-auto column-width should apply as specified rather than being stretched so that the columns plus the column gaps fill the multicol. It seems pretty awkward not to do this.

I also wonder whether column-fill: auto that doesn't fill all of the columns should cause some of the columns not to be generated, and leave only the filled columns (with their widths calculated as though they were all to be generated) to be justified. I have mixed feelings about this one, though.

@dbaron
Copy link
Member Author

dbaron commented May 20, 2017

Er, the spec already says the thing about non-auto column-width, but for some reason it conditions it to only be when column-count is also non-auto. I don't see why that condition should be there.

(Also, it uses "with" when it should be using "non-auto", given that elements always have computed values of all properties.)

@frivoal
Copy link
Collaborator

frivoal commented May 25, 2017

for some reason it conditions it to only be when column-count is also non-auto. I don't see why that condition should be there.

I don't see it either.

Additionally, it feels like we need to say a bit more about how do the column-gaps interact with the distributed space.
For instance, if you have

article {
  columns: 3 100px;
  column-gap: 10px;
  width: 340px;
  justify-content: space-evenly;
}

which of the following two behaviors does it mean:

  1. (340 - 100 * 3) / 4 = 10px between and around each column
  2. (340 - 100 * 3 - 10 * 2 ) / 4 = 5px before the first column and after the last column and 5+10=15px between the columns?

Behavior 2 is probably the one the spec currently intends (since it does not give enough details to define anything else), but would mean that the author needs to set the column-gap to 0 to get space-evenly and space-around to have their intended effect. In addition to being probably unexpected by authors, this does not have good fallback behavior in browsers that do no support justify-content on multi-col. Also, even in browsers that do support justify-content, if the width of the multicol is "just right", you may end up with no space between the columns at all, which seems pretty bad too.

So I think Behavior 1 would be nicer, but it requires that we give a new meaning to column-gap in these situations. The logical answer would be that becomes a minimum spacing. For space-between, that would be the minimum space between the columns. For left, right, start, end, and presumably center, that would be the exact space between the columns. For space-evenly it would be the minimum size of the even spaces. for space-around it could be the minimum space between the columns, with a minimum of half that space before the first one and after the last one.

In that case, with the space-around and space-evenly values, unless we want to allow columns with a used width smaller than the specified width, we also need to change the formula to get the number of columns. For instance:

article {
  columns: 3 100px;
  column-gap: 10px;
  width: 320px;
  justify-content: space-evenly;
}

has 3 columns if you ignore justify-content or apply behavior 2, but it needs to have 2 columns if you apply behavior 1:
3*100 + 4*10 > 320, so we cannot have 3 columns. Instead we can have 2, with 4 30px spaces around them.

This would mean changing the algo to determine the number of columns. Specifically, this part:
floor((U + column-gap)/(column-width + column-gap)))
would stay as if if justify-content is any value other than space-around or space-evenly, but would be changed to floor((U + 2* column-gap)/(column-width + column-gap))) for space-evenly and to floor((U + 1.5* column-gap)/(column-width + column-gap))) for space-around.

@frivoal frivoal added the Agenda+ label Jun 6, 2017
@frivoal frivoal self-assigned this Jun 6, 2017
@fantasai
Copy link
Collaborator

This just seems like an error in applying https://lists.w3.org/Archives/Public/www-style/2016May/0208.html so taking it off the agenda and marking Needs Edits...

@frivoal
Copy link
Collaborator

frivoal commented Jun 14, 2017

This just seems like an error in applying https://lists.w3.org/Archives/Public/www-style/2016May/0208.html

This seems fair

so taking it off the agenda and marking Needs Edits...

I am not so sure about that. The minutes you quoted do not provide an answer to how the column-gaps interact with the distributed space, as I was discussing in my last comment. This is a discussion we still need to have.

@fantasai
Copy link
Collaborator

The obvious answer would be "in the same way as gaps between columns in Grid".

@tabatkins
Copy link
Member

Fixed now. We went with matching Grid's behavior - spacing is added in addition to the gutters, giving Florian's behavior #2. While I agree that this has slightly unfortunate implications with multicol's default column-gap, we think it's more important to have a consistent behavior than to give this a slightly different behavior that's slightly more optimal by default.

Also, even in browsers that do support justify-content, if the width of the multicol is "just right", you may end up with no space between the columns at all, which seems pretty bad too.

Grid has the same behavior, and is solved the same way - you can set up your minimum values with a combination of *-gap and padding on the container, in a ratio that matches the desired distribution, then the distribution spreads out the extra space accordingly.

I also wonder whether column-fill: auto that doesn't fill all of the columns should cause some of the columns not to be generated[...]

This seems to require a distinction between two different stretching behaviors: one where all of the columns are stretched to fill the multi-col, and one where only the filled ones are stretched. We could make a distinction and say that normal and stretch operate on all columns whereas the other values cause the empty columns to be dropped, but that seems a bit weird. In any case, filing as a separate issue: #1565

fantasai added a commit that referenced this issue Jun 26, 2017
…mns, and apply distribution in all cases of non-auto 'column-width'. Fixes #1420.
@frivoal
Copy link
Collaborator

frivoal commented Jun 27, 2017

Fixed now. We went with matching Grid's behavior - spacing is added in addition to the gutters, giving Florian's behavior #2. While I agree that this has slightly unfortunate implications with multicol's default column-gap, we think it's more important to have a consistent behavior than to give this a slightly different behavior that's slightly more optimal by default.

Hmmm. Grid gaps were designed to be the same as grid tracks, except empty, so I expect that behavior on Grid. Column gaps were not, so I do not have the same expectation.

[...] you can set up your minimum values with a combination of *-gap and padding on the container [...]

Yeah, but the default value of column-gap is normal, not a specific length, so to use that approach you can no longer rely on the default value of column-gap.

I don't think I'd necessarily object to the approach you're championing, but I do prefer the alternative, and wish we had a group discussion on this.

There's also an other issue, kind of separate from this one but interacting with it:

When the actual numbers of columns ends up being one, do we still want to apply whatever alignment model justify-content tells us, or do we want to fall back to normal/stretch, to preserve the current behavior of "single column multi-col is indistinguishable form block layout in a BFC"?

Needing to set the padding in proportion of the column gap to achieve space-evenly and space-around would interact poorly with that. You can solve it with media queries, but that requires manual math, whose complexity depends on what your multicol is nested in.

You would not have that issue if gaps worked the way I said, and if we always fell back to normal/stretch when there's a single column.


Anyway, maybe you're right and I am wrong, but I think this would be good to hash out with a white board, and get input from author/author advocates like @jensimmons or @rachelandrew before closing on this.

@frivoal frivoal reopened this Jun 27, 2017
@tabatkins
Copy link
Member

Hmmm. Grid gaps were designed to be the same as grid tracks, except empty, so I expect that behavior on Grid. Column gaps were not, so I do not have the same expectation.

Right, thus the "slightly unfortunate implications" note. I agree it's slightly worse behavior, but when weighed against a strong inconsistency with how gaps work elsewhere, I think it's better for the future for column-gap to be consistent between Multicol and Grid. Special cases make people sad.

Yeah, but the default value of column-gap is normal, not a specific length, so to use that approach you can no longer rely on the default value of column-gap.

Correct (but in practice it's 1em, you can just use that).

to preserve the current behavior of "single column multi-col is indistinguishable form block layout in a BFC"?

We already have that behavior - if justify-content is normal or stretch, a 1-column multicol continues to act exactly like Block. If it's anything else it doesn't, but Block doesn't pay attention to justify-content at all, so it's the author breaking the symmetry, not the spec. (Block doesn't have a notion of "content width" separately from "box width" like multicol does.) There's no need to do anything extra-special to try and maintain the linkage past where it makes sense.

@frivoal
Copy link
Collaborator

frivoal commented Jun 28, 2017

We already have that behavior - if justify-content is normal or stretch, a 1-column multicol continues to act exactly like Block.

Except that if you had to add 1em of left and right padding to get space-around to work as intended, when there's only one column it will still technically works like block layout, but has a 1em padding that you wouldn't otherwise have.

@tabatkins
Copy link
Member

Yes? That's exactly what's desired - you use padding/gaps to create the minimum spacing you want, and we assume that doesn't change just because you can only fit one column of content in. (Again, we're explicitly breaking the "acts exactly like Block when single-column" symmetry when you use a non-stretch justify-content.)

@frivoal
Copy link
Collaborator

frivoal commented Jul 2, 2017 via email

@fantasai
Copy link
Collaborator

fantasai commented Jul 3, 2017

Happy to put it on the agenda, but I would object to Grid and Multicol behaving differently with respect to gaps vs. space-between/around/evenly, assuming the same value for the gaps.

@astearns
Copy link
Member

Taking the Agenda+ label off in favor of discussing this at the Paris meeting.

@frivoal
Copy link
Collaborator

frivoal commented Mar 27, 2018

Agenda+F2F again, since we did not discuss this last time.

The right point to start reading this is #1420 (comment) (the part above is resolved).

Restating my position: I believe the behavior proposed by tab&elika is acceptable, but I prefer the one I suggested, and it seems subjective, so I'd like the group's opinion before we're locked by web compat.

@tabatkins
Copy link
Member

tabatkins commented Apr 4, 2018

As far as I can see, your objections are:

  1. In the current spec, you can't robustly set up padding that matches the default column-gap (or half of it); this will be moot once we resolve on [css-align][css-multicol] Make "column-gap: normal" to be 1em in multi-column per spec #2145 and just specify that "normal" is 1em, rather than a UA-defined length.

  2. The default behavior of justify-content: space-around/between on multicol ends up with the space between columns not being the correct ratio with the space on either side, because the space between is 1em + distribution-space; this has a trivial fix (set column-gap: 0) and fixing it in any other way would require special-casing multicol to act differently than every other place where gaps and distribution interact, which seems very bad. @fantasai and I would both strongly object to this.

  3. You might want space on either end of your columns when there are 2+, but not when there is only 1, and the suggestion to "set padding+gaps to the right ratio" will instead always cause space on either end; I don't see why you'd want this. :/

@frivoal
Copy link
Collaborator

frivoal commented Apr 5, 2018

@tabatkins, correct.

1: this is now gone, since we have resolved on #2145

2+3: Your description is correct, that is what my preference is. It is a mild preference, so if you're opposing it with a strong objection, I guess I'll just fold (unless more people come out with stronger preferences / objections).

But, or the sake of the argument, my logic is as follows.

Multi-column typically contain in-flow body text. Without a gap, things would be unreadable, as lines of text across columns would seem connected. You need a way to say how much (at minimum) columns need to be apart when there's more than one of them. For this reason, you generally do not want to set the column-gap to 0. If there's only a single column, there's no need for separation at all, but column-gap doesn't create one, so all is good and you can just pretend there was no multicol at all and that you just got ordinary block layout. Once you do have separations and vertical white space, it is nice to be able to control how it's spread around, and that's where the alignment properties come in. You can use the padding trick to compensate for the column-gap, but then you lose the property of "when there's not much room, it's just block layout without any additional spacing or separation". This concern is not totally absent from grid or flexbox, but unlike multicolumn, grid of flexbox typically do not contain only in-flow body text (and do not contain a continuous flow of text fragmenting across the items), so the need to put some (variable amount of) whitespace around things doesn't necessarily go away when available space limits things to one item per row. Also, visual separation of the items may be achieved in other ways (backgrounds, borders, margins on the items, etc), so unlike multicol, setting the column (or row) gap to 0 is not necessarily a bad idea.

That would work if column-gap was treated as a minimum for the distribution space that only kicks in if there's at least one actual column gap (i.e. at least two columns).

Seems to me that this would more often just do the right thing without having to think about it.

Also, you cannot (easily) roll your own with media queries, and you'd need element queries to do this right, but we don't have those.

That said, while it seems to me that this would (almost?) always be the right thing to do for multi-col, maybe it would also sometimes be the right thing to do for flex-box and grid. Possibly we need to be able to switch between the two behaviors somehow, either with separate values or a separate property. But that does seem overkill.

@css-meeting-bot
Copy link
Member

The Working Group just discussed 'justify-content' other than 'normal' or 'stretch' should change column count/size rules, and agreed to the following resolutions:

  • RESOLVED: alignment and gaps in multicol behave exactly like grid and we will add a note explaining the issues in the issue and how to solve them
The full IRC log of that discussion <dael> Topic: 'justify-content' other than 'normal' or 'stretch' should change column count/size rules
<dael> github: https://github.com//issues/1420
<dael> astearns: We've discussed in the past.
<dael> TabAtkins: As florian says from third to last comment, right place to start reading is the one above.
<fantasai> https://github.com//issues/1420#issuecomment-378751428
<dael> TabAtkins: florian obj to current spec are 3. 1) in current spec you can't robustly fix the ratio of the defualt column gaps
<dael> florian: fixed that
<dael> TabAtkins: 2) default behavior of space between ends up with not the correct ratio because space-between space is added. Trivial fix, if you set column-gap to 0 it works. Solving it precisely would incolve special cases multii col if the column gap and so we'd be against that.
<fantasai> sorry link to comment is https://github.com//issues/1420#issuecomment-303958104
<dael> florian: You should not set the column gap to 0, though, because depending on the space you end up with it might be 0 and it's unreadbale.
<dael> TabAtkins: Then you set padding.
<dael> florian: I'm not completely opposed to your proposal. Setting gap to 0 it can be mushed so you get padding on the edges. Typically multi col has text, though,a nd if you don't have roon you fallback to block which is good. BUt if you're forcing padding for space you keep the padding when you collapse.
<dael> TabAtkins: I disagree. So you want space around. You leave column gap at 1em and padding to 1/2em on either side. I don't see why when you go to 1 colum that you don't want the 1/2em gap. You put it there for a reason and I don't see why it goes away. It goes away in multi col because it has no gaps, UBt you're explicitly putting the gaps.
<dael> TabAtkins: If a single column you want the text flush you'd want that in many columns.
<dael> fantasai: Like if you have 1 column and you split to 2 you don't want padding on common container but you want a gap between the 2.
<dael> fantasai: I'm opposed to different map between multicol and flex.
<fantasai> s/I'm/Regardless, I'm/
<fantasai> s/map/calc/
<dael> rachelandrew: Authors wouldn't use space around if they're not okay with gaps on the outside. If you didn't want that you'd use space between.
<fantasai> s/flex/grid/
<fantasai> s/space between/space-between/
<dael> rachelandrew: I agree we want to be able to maintain the 1em so people don't set column-gap to 0.
<dael> florian: This issue traces back to before we merged the models. Now we have. i'm okay with what you proposed, we jsut never discussed it. It was just added to the spec. If everyone agrees.
<dael> fantasai: Prop: Alignment and gaps in multicol behave exactly like grid.
<dael> astearns: Close no remaining changes.
<dael> TabAtkins: I could go with a note for how it works.
<dael> fantasai: I think people know how to do padding. They figured it would for grid so you'd have to have anot ein both.
<dael> florian: There's many ways to space in grid that don't require figuring this out. I think a note wouldn't hurt. Doesn't have to be multicol specific, but I think it would help more there.
<dael> astearns: I'd prefer the note because it shows we considered this, discussed, and have a solution. as people read they can agree or disagree. WIthout a note it's fairly opaque.
<dael> astearns: Prop: alignment and gaps in multi col behave exactly like grid and we will add a not explaining the issues in the issue and how to solve them
<dael> astearns: Obj?
<dael> RESOLVED: alignment and gaps in multicol behave exactly like grid and we will add a note explaining the issues in the issue and how to solve them

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

No branches or pull requests

6 participants