Description
The definition of flex-basis: content
(which also applies for flex-basis: auto
with a main size property of auto
) is not clear:
content
Indicates automatic sizing, based on the flex item’s content.
There is a more detailed definition of "content size" in the section about min-width
/ min-height
which I assume applies (but that's never explicit):
The content size is the min-content size in the main axis, clamped, if it has an aspect ratio, by any definite min and max cross size properties converted through the aspect ratio, and then further clamped by the max main size property if that is definite.
That suggests that aspect ratio / transferred size only affects min/max clamping, and not the basic size calculation.
The min-content
size definition in CSS Sizing doesn't help: it doesn't mention anything about aspect ratios, only about word breaks. However, the Intrinsic Sizes of Replaced Elements section in that spec says that both min and max content should equate to the intrinsic size with no specified size. For an image with an intrinsic aspect ratio but no fixed size (e.g., an SVG with a viewBox
but auto dimensions) this is not well spec'd. Going only by CSS Images' Sizing Algorithm it would be the default 300px×150px, but for SVG (image or inline) in all modern web implementations (for non-flexbox contexts) it is the "fill available" size in the inline direction (i.e., width) and then auto-sized based on aspect ratio in the other dimension (i.e., height).
Current implementations
Given flex-basis: auto
and an auto width and height for items in a single-line flex container with fixed dimensions:
-
Blink (tested in Chrome v 54/stable and 56/Canary)
-
Applies
min-width: auto
/min-height: auto
to<img>
but not to inline<svg>
. -
Does not use transferred size for
flex-basis
at all (neither default based on container size, nor min/max clamping on the container or the item). The aspect ratio is only used when the item itself has an explicitly set cross axis dimension. -
Uses a flex-basis of 0, unless there is a non-zero applied minimum size. With
flex-grow: 0
, elements collapse completely; withflex-grow: 1
, available size is distributed equally. For<img>
with auto minimum size, the minimum size is used as the flex basis for flex grow.
-
-
Gecko (tested in Firefox v 51/Dev Edition):
-
Applies
min-width: auto
/min-height: auto
to<img>
but not to inline<svg>
. -
Does not use transferred size for the default
flex-basis
at all (based on container size), but does use min/max clamping on the cross-size of the item to apply a min/max transferred size to the flex basis. -
Uses a flex-basis of "fill available size" in absence of clamping (aka 100% minus margins, etc). With
flex-shrink: 1
, available size is distributed between all elements equally, regardless offlex-grow
value; withflex-shrink: 0
, each element takes up all available space by itself.
-
-
EdgeHTML (v14)
- Uses the transferred size as both the auto flex-basis and the auto minimum size for both
<img>
and<svg>
.
- Uses the transferred size as both the auto flex-basis and the auto minimum size for both
According to reports, Safari 10 matches Edge in at least some of the demos, but I haven't tested extensively myself.
I'd like to file browser bugs on Chrome and Firefox to follow the Edge/Safari implementation, but I don't think the spec is clear enough to back that up.
Demos on Codepen, from which you can play around with some of the other cases:
-
Flexing Inline SVG versus SVG-as-image, when all flex and sizing properties are default.
-
Flexing Inline SVG and images, with
min-width: 0
andflex-grow:1
-
Flexing Inline SVG and images, with an explicit height and
min-width: 0
. This is the only one where I am getting consistent results across browsers; the explicit height on the graphics successfully triggers all the browsers to calculate a width for both<svg>
and<img>
, and then that is used as the auto flex-basis; amin-width: 0
cancels out the discrepancies between images and inline SVG when it comes to shrinking.