Frage

Please help me to understand one issue with the flexible box layout model for which I get different results in Firefox and Chrome.

Consider the following HTML fragment:

<body>
    <header>Header</header>
    <footer>Footer</footer>
</body>

styled via

body {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
    flex-direction: column;
}

header {
    max-width: 400px;
    height: 20px;
    background-color: yellow;
    margin: 0 auto;
}

footer {
    width: 400px;
    height: 20px;
    background-color: green;
    margin: 0 auto;
}

The header box has a maximum width constraint of 400px while the footer has a fixed width of 400px. When I try this code in Gecko-based browsers (Firefox 21 and 24 in my case) both header and footer are horizontally centered (as I hoped for by giving them left and right auto margins) but only the footer has a width of 400px while the header's width is just the width of the content even if enough horizontal space was available.

In WebKit/Blink-based browsers (Chrome 25 and 28 in my case) the header and footers are both centered and are both 400px wide (in case there is enough horizontal space), and this is exactly what I want to achieve.

Obviously, either Firefox or Chrome must be wrong. How do you understand the spec: http://www.w3.org/TR/css3-flexbox/? What is the desired behaviour?

If you want to play around, here is a JSFiddle: http://jsfiddle.net/4Rv7K/.

Note that one has to enable the flexible box layout model in the release version of Firefox. It is the setting layout.css.flexbox.enabled. (Without it, one is actually not testing anything about flexboxes.)

P.S.: The bug was in Chromium's engine and has apparently been fixed by now: https://code.google.com/p/chromium/issues/detail?id=242654

War es hilfreich?

Lösung

The Firefox/Gecko behavior is correct.

WebKit is stretching up to 400px (the max-width) due to the header element's default "align-self: stretch" value. However, the spec is clear that "align-self: stretch" is only supposed to stretch if you have no auto margins in the cross axis. Quoting the spec:

If a flex item has ‘align-self: stretch’, [...] and neither of its cross-axis margins are ‘auto’, the used outer cross size is the used cross size of its flex line, clamped according to the item's min and max cross size properties http://www.w3.org/TR/css3-flexbox/#cross-sizing

The exception for "neither of its cross-axis margins are auto" is what Firefox is honoring here and WebKit/Blink appear to be ignoring.

Now, to achieve your desired layout: It looks like you want both stretchiness and centering, and I don't think you can get both of those things simultaneously in the cross axis.

You can get them simultaneously in the main axis of a flex container, though -- so you can fix this by adding a horizontal flex container around the header and the footer.

I've done that here: http://jsfiddle.net/4Rv7K/16/

The relevant code (just with the 'header' for simplicity):

body {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
    flex-direction: column;
}
horizFlex {
    display: -webkit-flex;
    display: flex;
}
header {
    -webkit-flex: 1 0 auto;
    flex: 1 0 auto;
    max-width: 400px;
    height: 20px;
    background-color: yellow;
    margin: 0 auto;
}
[...]
<body><horizFlex><header>Header</header></horizFlex></body>

I think this achieves the layout you're looking for by wrapping the header and footer each in a horizontal flex container. The flex container stretches to the width of its parent (the body), and inside of it we have a single flex item (e.g. the ), which is flexible up to its max-width, and which we center (with auto margins) once it has reached its max-width.

Andere Tipps

For an element that lacks a definite size with auto margins, it looks like the element's fit-content width is supposed to be used as the element's actual width while the remaining space is counted as margin. For Chrome, it appears to be behaving inappropriately only when using flex-direction: column.

http://codepen.io/cimmanon/pen/fuhyF

ul {
  display: -webkit-flex;
  display: flex;
  height: 5em;
  background: yellow;
}

li {
  margin: auto;
  border: 1px solid;
}

ul.column {
  -webkit-flex-direction: column;
  -flex-direction: column;
}

If you look at a list with the above styles, Opera, Firefox, and Chrome agree that the li elements are shrink wrapped when the direction is row. Under the column direction, only Firefox and Opera shrink wrap the li, while Chrome has the li take the full width of the flex container.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top