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

Open
dbaron opened this Issue May 20, 2017 · 13 comments

Comments

Projects
None yet
5 participants
Contributor

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.

Contributor

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.)

Contributor

frivoal commented May 25, 2017 edited

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 added the Agenda+ label Jun 6, 2017

frivoal self-assigned this Jun 6, 2017

@fantasai fantasai added Needs Edits and removed Agenda+ labels Jun 13, 2017

Contributor

fantasai commented Jun 13, 2017

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...

Contributor

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.

Contributor

fantasai commented Jun 26, 2017

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

Member

tabatkins commented Jun 26, 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.

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

tabatkins closed this Jun 26, 2017

@fantasai fantasai added a commit that referenced this issue Jun 26, 2017

@fantasai fantasai [css-align] Clarify where space goes when distributing multi-col colu…
…mns, and apply distribution in all cases of non-auto 'column-width'. Fixes #1420.
4aa7b02
Contributor

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 reopened this Jun 27, 2017

frivoal added the Agenda+ F2F label Jun 27, 2017

Member

tabatkins commented Jun 27, 2017

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.

Contributor

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.

Member

tabatkins commented Jun 30, 2017

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.)

Contributor

frivoal commented Jul 2, 2017

Contributor

fantasai commented Jul 3, 2017 edited

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.

fantasai added the Agenda+ label Jul 5, 2017

Member

astearns commented Jul 18, 2017

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

astearns removed the Agenda+ label Jul 18, 2017

astearns removed the Agenda+ F2F label Aug 1, 2017

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