3

When there is only one row of "flex items", Chrome and Firefox show different results. When there is more than one line(wrap), Chrome and Firefox show the same result!

So why is this happening? Is that a bug, or is there some "default value" or difference that I am missing?

body{
    background-color: teal;
}

.flexContainer{
    background-color: blue;
    border: 1px solid black;
    height: 300px;
}
.flexItem{
    background-color: red;
    border: 1px solid black;
}

.flexContainer{
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start;
}

.flexItem{ 
    flex: 0 1 0; 
}
<div class="flexContainer">
    <div class="flexItem">1111111111111111111</div>
    <div class="flexItem">2222<br/>2222</div>
    <div class="flexItem">3333<br/>3333<br/>3333</div>
    <div class="flexItem">4444444444444444444</div>
</div>
J.L. Yokata
  • 115
  • 2
  • 10
  • because `align-content` it is still a draft . https://drafts.csswg.org/css-flexbox-1/#align-content-property If i understand , for a single line, it should not be applied and chrome would do what expected unless a prefix is needed ... indeed not clear what to expect, but rule is not a candidate either ... – G-Cyrillus Sep 11 '18 at 20:47

1 Answers1

11

Source of the Problem

Here is the source of the problem:

.flexContainer {
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: stretch;
    align-content: flex-start; <-- problem
}

Background

The align-content property controls the cross-axis alignment of flex lines within the flex container. Think of flex lines as the rows or columns (depending on flex-direction) in which flex items live. Put another way, align-content distributes the space between and around flex lines, packing them to the top, bottom, center, etc. (see the full list of values).

Because align-content distributes space between and around flex lines, it can only work on multi-line flex containers. (A single-line extends across the full cross-axis length of the container leaving no free space for align-content to work.)

Obviously, a multi-line container is a container with more than one line (flex items have wrapped). Technically, however, a multi-line container is simply a container with flex-wrap: wrap or flex-wrap: wrap-reverse (regardless of whether flex items have wrapped, or even exist).

Same concept applies to a single-line flex container, which is a container with flex-wrap: nowrap. The align-content property has no effect in nowrap containers, as discussed above.

§ 8.4. Packing Flex Lines: the align-content property

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. Note, this property has no effect on a single-line flex container.

§ 6. Flex Lines

Flex items in a flex container are laid out and aligned within flex lines, hypothetical containers used for grouping and alignment by the layout algorithm. A flex container can be either single-line or multi-line, depending on the flex-wrap property:

  • A single-line flex container (i.e. one with flex-wrap: nowrap) lays out all of its children in a single line, even if that would cause its contents to overflow.

  • A multi-line flex container (i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse) breaks its flex items across multiple lines, similar to how text is broken onto a new line when it gets too wide to fit on the existing line.


The Discrepancy between Chrome and Firefox / Edge

Looking again at your code:

body {
  background-color: teal;
}

.flexContainer {
  background-color: blue;
  border: 1px solid black;
  height: 300px;
}

.flexItem {
  background-color: red;
  border: 1px solid black;
}

.flexContainer {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  align-items: stretch;
  align-content: flex-start;
}

.flexItem {
  flex: 0 1 0;
}
<div class="flexContainer">
  <div class="flexItem">1111111111111111111</div>
  <div class="flexItem">2222<br/>2222</div>
  <div class="flexItem">3333<br/>3333<br/>3333</div>
  <div class="flexItem">4444444444444444444</div>
</div>

Notice three things:

(1) There is no actual wrapping. All four items exist on one line. The flex container has one line.

(2) The flex-wrap property is set to wrap (in the flex-flow shorthand).

(3) The align-content property is set to flex-start.

Let's break this down.

Because there is only a single line in the flex container, Chrome is ignoring align-content. As written in the specification (see above):

The align-content property has no effect on a single-line flex container.

So this is Chrome's interpretation. If there is an actual single line, then ignore align-content.

Switch between wrap and nowrap in Chrome. There's no difference.

On the other hand, because the container is set to flex-wrap: wrap, this technically creates a multi-line flex container, as far as Firefox and Edge are concerned. The actual wrapping or existence of flex items is irrelevant.

As written in the specification (see above):

A multi-line flex container (i.e. one with flex-wrap: wrap or flex-wrap: wrap-reverse) breaks its flex items across multiple lines...

Switch between wrap and nowrap in Firefox and Edge. There's a difference.

So each browser has it's own way of implementing this rendering behavior.


Standards Compliance

In terms of adherence to the specification, I would say that Firefox and Edge are at full compliance. They seem to adhere most closely to the wording in the spec.

However, I wouldn't characterize Chrome's behavior as a "bug". What they've done is more likely an intervention.

An intervention is when a user agent decides to deviate slightly from a standardized behavior in order to provide a greatly enhanced user experience.

Interventions appear to be standard practice at Chrome. Examples:


More Information

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Chrome has zero _flexbox-specific_ interventions. If you have a case where Chrome and Firefox render a flexbox differently and can't find an existing relevant bug, please file a new one at https://crbug.com/new with a minimal reproduction case. – dgrogan Jul 11 '21 at 04:12
  • I wanted to give the Chrome team the benefit of the doubt. There are so many cases (some listed above) where Chrome deviates from the flexbox spec, that I assumed they were interventions. I didn't think they would be all bugs. – Michael Benjamin Jul 11 '21 at 14:25
  • It's still not clear to me why Firefox comes out ahead of Chrome almost all of the time in terms of adherence to the flexbox standard. – Michael Benjamin Jul 11 '21 at 14:26
  • 1
    There are historical reasons that are best discussed IRL. But we're specifically working on cross-browser flex spec adherence this year in conjunction with the Firefox team and some open source contributors who work on Webkit. You can see our progress at https://wpt.fyi/compat2021?feature=css-flexbox – dgrogan Jul 11 '21 at 17:43