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.