Flexbugs: Auto-sizing images and inline SVG as flex children

Created on 8 Nov 2016  路  5Comments  路  Source: philipwalton/flexbugs

In a single row/column flex container, the child items will stretch to fit the full height/width (cross-axis) and then determine their size in the opposite (flex main axis) direction. However, browsers are currently inconsistent when the flex items are images. Normally, once you set an image's size in one direction, an auto value for the other direction is calculated based on the aspect ratio. But Chrome and Firefox

Images do get a minimum size, in all browsers, based on the aspect ratio. If you don't set min-width or min-height to 0 (or change the overflow settings), they will have a minimum size based on the aspect ratio and the cross axis size. However, Chrome & Firefox do not apply the minimum sizing rule to inline SVG, but Edge & Safari do.

To make things even more confusing, Chrome & Firefox can't even agree on what they do instead: Chrome treats the elements as 0 width/height (if flex-grow is 0, otherwise they grow equally). Firefox treats them as 100% width/height (if flex-shrink is 0, otherwise they shrink equally).

See spec bug https://github.com/w3c/csswg-drafts/issues/694 for more details.

Avoid the issue by:

  • Always making sure image / SVG elements in a flex container have an explicit size in the cross axis (i.e., height for a flex row, width for a flex column).

  • Expressly override the minimum size constraint with min-width: 0 (for row) or min-height: 0 (for column).

Most helpful comment

I have inline svg with no width / height set as a flex item and am experiencing this in Chrome and Safari - svg appears to have 0x0 dimensions.

Setting width / height (or both) through attributes or css properties seems to fix it.

All 5 comments

Is a height attribute sufficient for an explicit cross-axis size?

I have inline svg with no width / height set as a flex item and am experiencing this in Chrome and Safari - svg appears to have 0x0 dimensions.

Setting width / height (or both) through attributes or css properties seems to fix it.

How do you prevent an SVG which has a viewBox, no width/height, and is a flex column item, to expand the width of its (flex) container in Firefox?

Eg.: a site-wide vertical nav bar (an inline flex container) covering the full viewport's height, containing an SVG logo that should fill the available space along the cross-axis, but not extend it.

I tried wrapping the SVG, but it doesn't work. Worse: if the SVG has a cross-axis padding, it will now overflow its container.

Demo: https://codepen.io/creative-wave/pen/zgqXYQ?editors=1000

Edit 1: the demo shows an SVG contained by a flex item, and isn't a flex item itself, to demonstrate another issue related to the overflow created by padding/border (even if box-sizing: border-box is defined), but you can remove this container and it will demonstrate the issue described above.

Edit 2: a fix for the padding issue when it's a child of an inline flex column item (the issue no longer exists when it's an inline flex column item) is max-width: 100% on the svg.

Here鈥檚 a simple reproduction of this issue (I believe) in Safari:

<div style="display: flex; width: 300px;">
  <svg width="800" height="200" style="height: auto; width: 100%;">
    <rect fill="steelblue" width="800" height="200"></rect>
    <text text-anchor="middle" dy="0.35em" x="50%" y="50%">800 x 200</text>
  </svg>
</div>

Screen Shot 2021-03-04 at 12 01 56 PM

Safari shows this as a 300脳200 image, while Chrome scales it down to 300脳75 as expected, preserving the aspect ratio. With a viewBox, you get whitespace around the 300脳75 rect, but the SVG is still 300脳200.

<div style="display: flex; width: 300px;">
  <svg width="800" height="200" viewBox="0 0 800 200" style="height: auto; width: 100%;">
    <rect fill="steelblue" width="800" height="200"></rect>
    <text text-anchor="middle" dy="0.35em" x="50%" y="50%">800 x 200</text>
  </svg>
</div>

Screen Shot 2021-03-04 at 12 02 11 PM

It seems you can workaround this issue by adding Apple鈥檚 nonstandard height: intrinsic constant in addition to height: auto.

Live examples: https://observablehq.com/d/405e33d0a2be5a73

I created this codepen to visualize the differences between browsers, if it can help anyone figure out the issues that still stuck me for hours, 2 years after my previous comment.

Was this page helpful?
0 / 5 - 0 ratings