-
Notifications
You must be signed in to change notification settings - Fork 669
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
[css-flexbox] Investigate applying align-content to single-line flex containers #3052
Comments
The CSS Working Group just discussed The full IRC log of that discussion<eae> Topic: flexbox<astearns> github: https://github.com//issues/3052 <eae> TabAtkins: Align content for a flexbox, you can do align content on a muiltline flexbox but a single line flexbox does not respond to align content <eae> ...this is beacuse we have a behavior where we stretch the line. Not super happy that we made that choice. <eae> ...the problem is there are cases where there are cases where we'd like to align for single line. specifically for things like baseline alignment. <eae> TabAtkins: By the current definition we can't do anything about it, it is always stretching. We can't add in the fake margin to cause it to align <eae> fantasai: the lines are stretched but the individual items arent, if you want ot baseline align you can't do that. <eae> TabAtkins: only moves the line, not the items. <eae> fantasai: The proposal is to take apply to single line flex containers, would allow more alignment options for flexboxes. Not a good reason it isn't allowed alreayd. Main concern is whether it is web compatible. <eae> TabAtkins: use cases, baseline alignment, no reason why a single line shouldn't be allowed to align but a multi-line does. <eae> florian: A similar use case is when making lines, requires wrapping for alignment to work. Declaring it to wrap has caused it tow rok, I don <eae> 't need wrapping but it isn't causing any problems. What's the problem with having to declare wrap. <eae> TabAtkins: Not consistent with not wanting wrapping. <Chris_Lilley> zakim, remind us in 4 hours to go home <Zakim> ok, Chris_Lilley <eae> cbiesinger: Makes sense but please explain baseline items vs lines <eae> s/baseline/align/ <eae> ??: the idea that long term that people have to know that wrpa is needed isn't ideal./ Better to have something that works for single line. <astearns> s/??/jensimmons <eae> TabAtkins: compat risk is in two cases, single line row of flex containers and non-auto cross size. Shrinking to the sdize of the elements anyway. <cbiesinger> s/baseline items/baseline align items/ <eae> fantasai: If you did self alignment which pushes everyhting to the top and everything is shrink wrapped and the flex container is taller, you then have extra space. <eae> TabAtkins: Auto-height won't have the problem. <fantasai> TabAtkins: Fixed height will <eae> TabAtkins: A column flexbox whos columns are all fixed with would have changed behavior with this proposal <eae> TabAtkins: Those are likely to be rare cases. <eae> fantasai: We probably want to run a use counter on this before committing to it. <eae> florian: Either that or chrome tires it and reports back. <eae> astearns: Preferences? <eae> cbiesinger: I'd rather do a use counter <eae> TabAtkins: I'll open a crbug. <eae> astearns: Collect data and report back? <eae> TabAtkins: Yes <eae> astearns: objections? <eae> astearns: We'll wait on data. <eae> dbaron: Are we going to revisit once we have data? <eae> astearns: yes |
I'm adding a use counter for this at https://crrev.com/c/1354539 |
The CSSWG would like to apply align-content to single-line flexboxes as well: https://lists.w3.org/Archives/Public/www-style/2018Nov/0007.html w3c/csswg-drafts#3052 Add a use counter for that to see if it is web-compatible. TESTED=Manually using chrome://histograms R=eae@chromium.org, tabatkins@google.com Change-Id: I3af67474937c8c589e8235c451b358b839556d1f Reviewed-on: https://chromium-review.googlesource.com/c/1354539 Commit-Queue: Christian Biesinger <cbiesinger@chromium.org> Commit-Queue: Emil A Eklund <eae@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Cr-Commit-Position: refs/heads/master@{#611984}
The CSSWG would like to apply align-content to single-line flexboxes as well: https://lists.w3.org/Archives/Public/www-style/2018Nov/0007.html w3c/csswg-drafts#3052 Add a use counter for that to see if it is web-compatible. TESTED=Manually using chrome://histograms R=eae@chromium.org, tabatkins@google.com Change-Id: I3af67474937c8c589e8235c451b358b839556d1f Reviewed-on: https://chromium-review.googlesource.com/c/1354539 Commit-Queue: Christian Biesinger <cbiesinger@chromium.org> Commit-Queue: Emil A Eklund <eae@chromium.org> Reviewed-by: Emil A Eklund <eae@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#611984} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: c660e93a82fa50208e40a3c825e17985e4770aa5
@cbiesinger Can't quite tell what it's counting, should be single-line non-empty flex containers with |
Hm, actually for a behavior change, it |
Reviewing the use-counter code:
Unless I'm completely mistaken, this is counting the exact wrong thing - it appears to be incrementing the use-counter whenever there's a multi-line flexbox with significant alignment. (start alignment has already bailed out before these lines, as it doesn't have a significant effect.) It looks like it just took the existing early-exit test ( So unfortunately, the use counter data appears to be entirely worthless for our purpose. :( |
I'm working on the data collection code. Question about the new proposed behavior below.
The first bullet point indicates that the below case has a behavior change. The only possible change I can see is that the item will no longer stretch to the flex container's height. But the parenthetical in the second bullet point indicates that such stretching should still occur. So my understanding indicates a contradiction. Could you resolve this contradiction for me? <div style="display: flex; align-content: flex-end; height: 100px;">
<div></div>
</div> |
ping @tabatkins on above question about this proposal's effect on stretching |
The two bullet points are about disjoint sets: the first is about row flex containers, the second is about column flex containers. So only the first bullet applies to your example. ^_^ (And in particular, the reason an auto-sized item will still fill the container in a column flex is because |
Why does this case change behavior? <div style="display: flex; align-content: flex-end; height: 100px;">
<div></div>
</div> Why does the column version NOT change behavior? <div style="display: flex; flex-flow: column; align-content: flex-end; width: 100px;">
<div></div>
</div> |
In the column version, the item is given its available inline size from the flexbox itself, with no regard for the align-content property; it then sizes to that width (as is normal for a In the row version the same thing happens, but the inline axis isn't relevant to us; the block axis ends up being 0px, which means we've got 100px of free space to potentially distribute with align-content. |
@davidsgrogan Did you get a fixed use-counter in for this issue? (or @cbiesinger) |
I have a local WIP patch that's not in yet. I think it's almost done. |
@fantasai, these are the test cases from the data collection patch that's in review in the chromium repo. We wanted Tab to review these cases but looks like he is on vacation this week. Could you take a look? Even if you spot check some, I think that's sufficient. Let me know if you see problems or are curious about other cases.
// Current: item is at top of container.
// Proposed: item is at bottom of container.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter1) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-end; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter1b) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-end; height: 50px; flex-wrap: wrap;">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter2) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: baseline; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter2b) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; height: 50px">
<div style="height:20px; align-self: baseline;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter3) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: initial; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter4) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: stretch; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter5) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-start; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter6) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; height: 50px">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter7) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-end;">
<div style="height:20px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: item gets 50px height.
// Proposed: item gets 0px height and abuts bottom edge of container.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter9) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-end; height: 50px;">
<div></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: item abuts left edge of container.
// Proposed: item abuts right edge of container.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter10) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end;">
<div style="width:20px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter11) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end;">
<div style="width:20px;"></div>
<div></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: items abut left edge of container.
// Proposed: items abut right edge of container.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter12) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end;">
<div style="width:20px;"></div>
<div style="width:20px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter14) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end; width: 200px">
<div style="align-self: flex-end"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end; width: 200px">
<div style="align-self: flex-end; width: 100px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: item at top
// Proposed: item at bottom
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15b) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: end; height: 200px">
<div style="align-self: flex-start; height: 100px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15c) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: end; height: 200px;">
<div style="height: 100px; align-self: self-end;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: item at top
// Proposed: item in center
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15d) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: space-around; height: 200px;">
<div style="height: 100px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15e) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: space-around; height: 200px;">
<div style="height: 100px; align-self: center;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15f) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: space-between; height: 200px;">
<div style="height: 100px;"></div>
</div>
)HTML");
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: first item is on the top
// Proposed: first item is on the bottom
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter15g) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: end; height: 200px;">
<div style="height: 100px; align-self: start"></div>
<div style="height: 100px; align-self: end"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: item is on the right.
// Proposed: item is on the left.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter16) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-start; width: 200px">
<div style="align-self: flex-end; width: 100px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: first item's right edge abuts container's right edge
// second item is horizontally centered
// Proposal: both abut container's right edge
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter17) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end; width: 200px">
<div style="align-self: flex-end; width: 100px;"></div>
<div style="align-self: center; width: 100px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// Current: first item's bottom edge abuts container's bottom edge
// second item is vertically centered
// Proposal: both abut container's bottom edge
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter18) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; align-content: flex-end; height: 200px">
<div style="align-self: flex-end; height: 100px;"></div>
<div style="align-self: center; height: 100px;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
}
// This case has no behavior change but checking the used width of each item is
// too difficult.
TEST_F(NGFlexLayoutAlgorithmTest, UseCounter19) {
SetBodyInnerHTML(R"HTML(
<div style="display: flex; flex-flow: column; align-content: flex-end; width: 20px">
<div style="width:20px;"></div>
<div style="width:100%;"></div>
</div>
)HTML");
EXPECT_TRUE(GetDocument().IsUseCounted(
WebFeature::kFlexboxAlignSingleLineDifference));
} |
David and I reviewed these together today. |
It would be nice to let developers apply align-content to single-line flex containers, as discussed in w3c/csswg-drafts#3052, but there might be compat problems. Change-Id: I98bf1a8e647f2fcb7b45040501c9e8c361282b86 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3159204 Commit-Queue: David Grogan <dgrogan@chromium.org> Reviewed-by: Christian Biesinger <cbiesinger@chromium.org> Cr-Commit-Position: refs/heads/main@{#928536}
This is in recent builds of Chrome 96. A few days of Canary has triggered it 0 times. https://www.chromestatus.com/metrics/feature/timeline/popularity/4057 |
Okay, looking at the data, it appears that the % of pages that would be affected by this has held steady at ~1.2% for the past year. That's substantially over our normal threshold for making a breaking change, so I suggest we close this as Rejected. (Unfortunately.) Agenda+ to confirm. |
It would be nice to let developers apply align-content to single-line flex containers, as discussed in w3c/csswg-drafts#3052, but there might be compat problems. Change-Id: I98bf1a8e647f2fcb7b45040501c9e8c361282b86 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3159204 Commit-Queue: David Grogan <dgrogan@chromium.org> Reviewed-by: Christian Biesinger <cbiesinger@chromium.org> Cr-Commit-Position: refs/heads/main@{#928536} NOKEYCHECK=True GitOrigin-RevId: 4ed75b86d2523363be71d0e3f8bc473d5ddcbf9c
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: [css-flexbox] Investigate applying align-content to single-line flex containers Proposed Resolution: close this as Rejected due to web compat<dael> github: https://github.com//issues/3052#issuecomment-1226112918 <dael> astearns: Proposed resoution is no <dael> fantasai: When flex was released we defined align content only applies to multiline. Aligns the flex lines. COuld apply to single line in which case you could top align a bunch of flex items and then center align the line <dael> fantasai: Seems there are enough web pages expecting it to not have an effect that we could not change based on chrome data. We think we can't fix this and should add to list of mistakes <dael> iank_: I looked last week quickly at use counter. It will overcount potentially. But it's high enough that there are sites taht will rely on this so I'm fine. Could do a sample of sites but it's fine <dael> astearns: If you're worried about overcounting by an oder of magnitude <dael> iank_: Even if it is it's a large number of sites <dael> fantasai: Yeah. I think it's unfortunate but we may have to live with it. Curious to know what's being overcounter and if usecounter could tweak <dael> iank_: Not easily. Would have to run the scenario where not stretching items to container which is not easy. That's how I thin it's overcounting. Would need to layout twice. <dael> iank_: I think way forward to investigate is look at sites and see which flexboxes have this and if they would change <dael> fantasai: Is there a way to get a sample of the list? <dael> iank_: Go to the issue on the chrome status page. Below the graph there will be a list of urls that triggered the counter <dael> fantasai: I'd be down to check the first 20 or something and see <dael> astearns: If you want to do that it would be great. Would you like to keep issue open until you do it? Or resolve? <dael> fantasai: Sure, I'll need something to track. <dael> fantasai: So just load these pages and look at it? <dael> iank_: Yeah, so it will be...it's by origin. What I find when doing this is if you hit the home page and have some JS to query elements more or less the home page will have it. <iank_> https://www.chromestatus.com/metrics/feature/timeline/popularity/4057 <dael> fantasai: If I find most of these don't hit a change we can revisit. If not I'll close out <dael> astearns: Okay, leaving this as is <dael> action fantasai look at effect this https://github.com//issues/3052#issuecomment-1226112918 would have on actual websites |
This was added for: w3c/csswg-drafts#3052 The CSSWG hasn't ended up looking at the resulting data - but likely still not web compatible as >1% of page loads. Change-Id: Ib227bce41aab610d3004ff9ebfb273c69e0faf9a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5867711 Commit-Queue: David Grogan <dgrogan@chromium.org> Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org> Reviewed-by: David Grogan <dgrogan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1356647}
Right now, single-line (flex-wrap:nowrap) flex containers don't pay attention to align-content at all; they always stretch to fill the container.
This has some odd implications; although you can align individual items to each other within the line, you can't start/end/center the line as a whole in a non-wrapping flexbox--for no reason that's apparent to authors, because this is totally possible in wrappable flexbox with one line.
This also makes baseline alignment impossible across flex or grid items when one of them is a single-line row flex container, because you can't add magic margin to the flex line to align the contents appropriately.
Filing this issue to see if Web-compat will allow making non-initial values of 'align-content' take effect on single-line flex containers. This would be a change in behavior for:
The text was updated successfully, but these errors were encountered: