/flexbugs

A community-curated list of flexbox issues and cross-browser workarounds for them.

MIT LicenseMIT

Flexbugs

This repository is a community-curated list of flexbox issues and cross-browser workarounds for them. The goal is that if you're building a website using flexbox and something isn't working as you'd expect, you can find the solution here.

As the spec continues to evolve and vendors nail down their implementations, this repo will be updated with newly discovered issues and remove old issues as they're fixed or become obsolete. If you discover a bug that's not listed here, please report it so everyone else can benefit.

The bugs and their workarounds

  1. Minimum content sizing of flex items not honored
  2. Column flex items set to align-items:center overflow their container
  3. min-height on a flex container won't apply to its flex items
  4. flex shorthand declarations with unitless flex-basis values are ignored
  5. Column flex items don't always preserve intrinsic aspect ratios
  6. The default flex value has changed
  7. flex-basis doesn't account for box-sizing:border-box
  8. flex-basis doesn't support calc()
  9. <button> elements can't be flex containers
  10. align-items: baseline doesn't work with nested flex containers
  11. Min and max size declarations are ignored when wrapping flex items
  12. Inline elements are not treated as flex-items

1. Minimum content sizing of flex items not honored

Demos Browsers affected Tracking bugs
1.1.abug
1.1.bworkaround
1.2.abug
1.2.bworkaround
Chrome
Opera
Safari
Chrome #426898
Firefox #1043520

When flex items are too big to fit inside their container, those items are instructed (by the flex layout algorithm) to shrink, proportionally, according to their flex-shrink property. But contrary to what most browsers allow, they're not supposed to shrink indefinitely. They must always be at least as big as their minimum height or width properties declare, and if no minimum height or width properties are set, their minimum size should be the default minimum size of their content.

According to the current flexbox specification:

By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property.

Workaround

The flexbox spec defines an initial flex-shrink value of 1 but says items should not shrink below their default minimum content size. You can get pretty much this exact same behavior by using a flex-shrink value of 0 instead of the default 1. If your element is already being sized based on its children, and it hasn't set a width, height, or flex-basis value, then setting flex-shrink:0 will render it the same way—but it will avoid this bug.

2. Column flex items set to align-items:center overflow their container

Demos Browsers affected
2.1.abug
2.1.bworkaround
Internet Explorer 10-11 (fixed in Edge)

When using align-items:center on a flex container in the column direction, the contents of flex item, if too big, will overflow their container in IE 10-11.

Workaround

Most of the time, this can be fixed by simply setting max-width:100% on the flex item. If the flex item has a padding or border set, you'll also need to make sure to use box-sizing:border-box to account for that space. If the flex item has a margin, using box-sizing alone will not work, so you may need to use a container element with padding instead.

3. min-height on a flex container won't apply to its flex items

Demos Browsers affected Tracking bugs
3.1.abug
3.1.bworkaround
3.2.abug
3.2.bworkaround
Internet Explorer 10-11 (fixed in Edge) IE #802625

In order for flex items to size and position themselves, they need to know how big their containers are. For example, if a flex item is supposed to be vertically centered, it needs to know how tall its parent is. The same is true when flex items are told to grow to fill the remaining empty space.

In IE 10-11, min-height declarations on flex containers work to size the containers themselves, but their flex item children do not seem to know the size of their parents. They act as if no height has been set at all.

Workaround

By far the most common element to apply min-height to is the body element, and usually you're setting it to 100% (or 100vh). Since the body element will never have any content below it, and since having a vertical scroll bar appear when there's a lot of content on the page is usually the desired behavior, substituting height for min-height will almost always work as shown in demo 3.1.b.

For cases where min-height is required, the workaround is to add a wrapper element around the flex container that is itself a flex container in the column direction. For some reason nested flex containers are not affected by this bug. Demo 3.2.a shows a visual design where min-height is required, and demo 3.2.b shows how this bug can be avoided with a wrapper element.

4. flex shorthand declarations with unitless flex-basis values are ignored

Demos Browsers affected
3.1.abug
3.1.bworkaround
Internet Explorer 10-11 (fixed in Edge)

Prior to the release of IE 10, the flexbox spec at the time stated that a flexbox item's preferred size required a unit when using the flex shorthand:

If the <preferred-size> is ‘0’, it must be specified with a unit (like ‘0px’) to avoid ambiguity; unitless zero will either be interpreted as as one of the flexibilities, or is a syntax error.

This is no longer true in the spec, but IE 10-11 still treat it as true. If you use the declaration flex: 1 0 0 in one of these browsers, it will be an error and the entire rule (including all the flexibility properties) will be ignored.

Workaround

When using the flex shorthand, always include a unit in the flex-basis portion. For example: 1 0 0%.

Important: using a flex value of something like 1 0 0px can still be a problem because many CSS minifiers will convert 0px to 0. To avoid this, make sure to use 0% instead of 0px since most minifiers won't touch percentage values for other reasons.

5. Column flex items don't always preserve intrinsic aspect ratios

Demos Browsers affected
5.1.abug
5.1.bworkaround
Internet Explorer 10-11 (fixed in Edge)

The March 2014 spec has the following to say about how size determinations are made for flex items:

On a flex item whose overflow is not visible, this [auto] keyword specifies as the minimum size the smaller of: (a) the min-content size, or (b) the computed width/height, if that value is definite.

Demo 5.1.a contains an image whose height is 200 pixels and whose width is 500 pixels. Its container, however, is only 300 pixels wide, so after the image is scaled to fit into that space, its computed height should only be 120 pixels. The text quoted above does not make it clear as to whether the flex item's min-content size should be based the image's actual height or scaled height.

The most recent spec has resolved this ambiguity in favor of using sizes that will preserve an element's intrinsic aspect ratio.

Workaround

You can avoid this problem by adding a container element to house the element with the intrinsic aspect ratio. Since doing this causes the element with the intrinsic aspect ratio to no longer be a flex item, it will be sized normally.

6. The default flex value has changed

Demos Browsers affected
6.1.abug
6.1.bworkaround
Internet Explorer 10 (fixed in 11)

When IE 10 was being developed, the March 2012 spec said the initial value for the flex property was none, which translates to 0 0 auto. The most recent spec sets the initial flex value to the initial values of the individual flexibility properties, which corresponds to initial or 0 1 auto. Notice that this means IE 10 uses a different initial flex-shrink value (technically it was called neg-flex in the spec at the time) than every other browser. Other browsers (including IE 11) use an initial value of 1 rather than 0.

Workaround

If you have to support IE 10, the best solution is to always set an explicit flex-shrink or flex value on all of your flex items. Demo 6.1.a shows how not setting any flexibility properties causes an error.

7. flex-basis doesn't account for box-sizing:border-box

Demos Browsers affected
7.1.abug
7.1.bworkaround
7.1.cworkaround
Internet Explorer 10-11 (fixed in Edge)

An explicit flex-basis value (i.e., any value other than auto) is supposed to act just like width or height. It determines the initial size of a flex item and then the other flexibility properties allow it to grow or shrink accordingly.

IE 10-11 always assume a content box model when using flex-basis to determine a flex item's size, even if that item is set to box-sizing:border-box. Demo 7.1.a shows that an item with a flex-basis value of 100% will overflow its container by the amount of its border plus its padding.

Workaround

There are two ways to work around this bug. The first requires no additional markup, but the second is slightly more flexible:

  1. Instead of setting an explicit flex-basis value, use auto, and then set an explicit width or height. Demo 7.1.b shows this.
  2. Use a wrapper element that contains no border or padding so it works with the content box model. Demo 7.1.c show this.

8. flex-basis doesn't support calc()

Demos Browsers affected
8.1.abug
8.1.bworkaround
Internet Explorer 10-11 (fixed in Edge)
8.2.abug
8.2.bworkaround
Internet Explorer 10 (fixed in 11)

IE 10-11 ignore calc() functions used in flex shorthand declarations. Demo 8.1.a shows flex:0 0 calc(100%/3) not working in IE.

In IE 10, calc() functions don't even work in longhand flex-basis declarations (though this does work in IE 11). Demo 8.2.a shows flex-basis: calc(100%/3) not working in IE 10.

Workaround

Since this bug only affects the flex shorthand declaration in IE 11, an easy workaround (if you only need to support IE 11) is to always specify each flexibility property individually. Demo 8.1.b offers an example of this.

If you need to support IE 10 as well, then you'll need to fall back to setting width or height (depending on the container's flex-direction property). You can do this by setting a flex-basis value of auto, which will instruct the browser to use the element's main size property (i.e., its width or height). Demo 8.2.b offers an example of this.

9. <button> elements can't be flex containers

Demos Browsers affected Tracking bugs
9.1.abug
9.1.bworkaround
Firefox Firefox #984869

Unlike <input> elements of type "button" or "submit", the HTML5 <button> element can contain child nodes. This allows you to put things other than text (e.g. icons) inside of <button> elements without having to resort to using semantically incorrect tags like <div> or <a>. Firefox, however, does not allow the <button> element to be a flex container.

Workaround

The simple solution to this problem is to use a wrapper element inside of the button and apply display:flex to it. The <button> can then be styled as normal.

10. align-items: baseline doesn't work with nested flex containers

Demos Browsers affected Tracking bugs
10.1.abug
10.1.bworkaround
Firefox Firefox #1146442

In Firefox, nested flex containers don't contribute to the baseline that other flex items should align themselves to. Demo 10.1.a shows the line on the left incorrectly aligning itself to the second line of text on the right. It should be aligned to the first line of text, which is the inner flex container.

Workaround

This bug only affects nested containers set to display: flex. If you set the nested container to display: inline-flex it works as expected. Note that when using inline-flex you will probably also need to set the width to 100%.

11. Min and max size declarations are ignored when wrapping flex items

Demos Browsers affected
11.1.abug
11.1.bworkaround
Safari

Safari uses min/max width/height declarations for actually rendering the size of flex items, but it ignores those values when calculating how many items should be on a single line of a multi-line flex container. Instead, it simply uses the item's flex-basis value, or its width if the flex basis is set to auto.

This is problematic when using the flex: 1 shorthand because that sets the flex basis to 0%, and an infinite number of flex items could fit on a single line if the browser thinks their widths are all zero. Demo 11.1.a show an example of this happening.

This is also problematic when creating fluid layouts where you want your flex items to be no bigger than X but no smaller than Y. Since Safari ignores those values when determining how many items fit on a line, that strategy won't work.

Workaround

The only way to avoid this issue is to make sure to set the flex basis to a value that is always going to be between (inclusively) the min and max size declarations. If using either a min or a max size declaration, set the flex basis to whatever that value is, if you're using both a min and a max size declaration, set the flex basis to a value that is somewhere in that range. This sometimes requires using percentage values or media queries to cover all possible scenarios. Demo 11.1.b shows an example of setting the flex basis to the same value as the min width to workaround this bug in Safari.

12. Inline elements are not treated as flex-items

Demos Browsers affected
12.1.abug
12.1.bworkaround
Internet Explorer 10-11 (fixed in Edge)

Inline element, including ::before and ::after pseudo-elements, are not treated as flex items in IE 10. IE 11 fixed this bug with regular inline element, but it still affects the ::before and ::after pseudo-elements.

Workaround

This issue can be avoided by adding a non-inline display value to the items, e.g. block, inline-block, flex, etc. Demo 12.1.b shows an example of this working in IE 10-11.

Acknowledgments

Flexbugs was created as a follow-up to the article Normalizing Cross-Browser Flexbox Bugs. It's maintained by @philwalton and @gregwhitworth. If you have any questions or would like to get involved, please feel free to reach out to either of us on Twitter.

Contributing

If you've discovered a flexbox bug or would like to submit a workaround, please open an issue or submit a pull request. Make sure to submit relevant test cases or screenshots and indicate which browsers are affected.