Writing Flexbox for IE10: Working With the 2012 Spec Without Losing Your Mind
IE10 implements the 2012 Flexbox draft, not the modern spec. Learn the -ms- dialect, its property mappings, its limits, and a strategy for shipping layouts that actually render.
22 May 2026, 20:36 UTC

If you still have to ship a layout that renders correctly in Internet Explorer 10 — an intranet app pinned to an old enterprise image, a kiosk, a legacy embedded browser — the first thing to accept is that IE10 does not speak modern Flexbox. It implements the March 2012 working draft of the spec, which uses different property names, different value keywords, and a different mental model than the justify-content world you know. The good news: the 2012 draft is coherent on its own terms, and once you learn its vocabulary, basic layouts are reliable.
The thesis of this piece is simple: treat IE10 Flexbox as a separate dialect, write it deliberately, and verify it in a real IE10 environment rather than assuming your modern CSS will degrade gracefully. It will not.
The dialect problem: same idea, different words
IE10 requires the -ms- prefix on everything, and several property names changed between the 2012 draft and the final spec. The mappings you will use most:
| Modern spec | IE10 (2012 draft) |
|---|---|
display: flex | display: -ms-flexbox |
flex-direction | -ms-flex-direction |
justify-content | -ms-flex-pack |
align-items | -ms-flex-align |
flex-grow | -ms-flex-positive |
flex-shrink | -ms-flex-negative |
flex: 1 | -ms-flex: 1 |
If you omit the prefix, IE10 silently ignores the declaration. There is no error, no console warning — your items just stack as block elements. That silence is the source of most "Flexbox is broken in IE" bug reports.
A worked example: a centered card row
Here is a horizontal row of cards, centered in the container, with each card growing equally to fill available space. Write the modern rule first, then the IE10 dialect:
.card-row {
display: -ms-flexbox; /* IE10 */
display: flex; /* everyone else */
-ms-flex-pack: center; /* IE10 justify-content */
justify-content: center;
-ms-flex-align: center; /* IE10 align-items */
align-items: center;
}
.card {
-ms-flex: 1; /* grow: 1, shrink: 1, basis: 0 */
flex: 1;
margin-right: 16px; /* no gap property in IE10 */
}
.card:last-child {
margin-right: 0;
}Two things are doing quiet work here. First, the order of the display declarations matters: IE10 reads -ms-flexbox and ignores the unprefixed line it doesn't recognize; modern browsers do the reverse. Second, spacing between items uses margins because IE10 predates the gap property by years — there is no prefixed equivalent to fall back on.
To verify: open the page in a real IE10 instance (a Windows 8 VM or an IE10 virtual machine image is the honest option; IE11's document modes are an approximation, not a guarantee) and check three things: the row is horizontal, the cards are centered as a group, and resizing the window makes the cards grow and shrink proportionally. If the cards stack vertically, the display: -ms-flexbox line was not applied — check for a typo or a later rule overriding it.
Where the 2012 draft bites you
The dialect is workable for single-axis layouts, but it has real limits:
- Wrapping is unreliable.
-ms-flex-wrapexists, but multi-line flex layouts in IE10 frequently misbehave unless children have explicit widths. If your design needs wrapping, a float or inline-block fallback is often less painful than debugging it. - No
gap. Margins on items are the only option, which means:last-child(or an adjacent-sibling selector) cleanup rules everywhere. - Keyword differences. Some alignment values differ between drafts — for example, the 2012 draft uses
start/endwhere the final spec settled onflex-start/flex-endfor-ms-flex-packand-ms-flex-align. Test your specific values rather than translating them mechanically. - The shorthand is your friend. IE10's handling of
flex-basisinside the longhand properties is finicky; the-ms-flexshorthand (grow, shrink, basis in one declaration) is the better-supported path.
A practical strategy
Don't try to write one Flexbox codebase that serves both eras through autoprefixer alone. Autoprefixer with an IE10 target does generate the -ms- dialect, and that covers the common cases — but it cannot fix the wrapping inconsistencies or the missing gap. The reliable approach is:
- Keep IE10 layouts to single-axis, non-wrapping flex rows and columns.
- Use margins for all inter-item spacing.
- Enable autoprefixer with
ie 10in your browserslist so the dialect is generated rather than hand-maintained. - Test in an actual IE10 environment before shipping; rendering differences here are not the kind you can reason about from the spec alone.
IE10's Flexbox is a snapshot of a spec in motion — awkward, incomplete, but functional within its lane. Constrain your designs to what the 2012 draft does well, verify on the real browser, and you can stop treating that old user agent string as a reason to reach for float hacks.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.