IE10 Flexbox: The 2009 Spec That Still Breaks Modern Layouts
IE10 uses the 2009 Flexbox spec with -ms- prefixes and different property names. Learn how to map modern flex properties to IE10, simulate gaps with negative margins, and verify layouts in an IE10 VM.
13 Sept 2025, 14:12 UTC

The Problem: Modern Flexbox Silently Fails in IE10
You write display: flex with justify-content: center and gap: 1rem. It works in Chrome, Firefox, and Safari—then you test in IE10 and the layout collapses into a single column. No error, no warning, just broken alignment. IE10 implemented the 2009 Flexible Box Layout Module, not the modern spec. The properties you know don't exist; they live behind -ms- prefixes with different names and behaviors.
What the 2009 Spec Actually Changed
The 2009 draft (which IE10 shipped) uses a different mental model. The container property is display: -ms-flexbox, not flex. Direction uses -ms-flex-direction but only supports row and column—no row-reverse or column-reverse. Wrapping is -ms-flex-wrap: wrap, but the shorthand flex-flow does not exist.
Alignment is where it gets painful. Modern justify-content maps to -ms-flex-pack. Modern align-items maps to -ms-flex-align. The values differ too: space-between becomes justify, center stays center, and flex-start becomes start. There is no gap property—spacing requires margins on children, which then demands negative margins on the container to avoid double-spacing at edges.
The Prefix Strategy That Actually Works
Don't mix prefixed and unprefixed properties in the same rule. IE10 parses both and the cascade can create unpredictable results. Instead, write the -ms- block first, then the modern block. Modern browsers ignore -ms-; IE10 ignores the unprefixed properties it doesn't understand. This ordering lets each engine pick the implementation it supports.
.card-grid {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-pack: justify;
justify-content: space-between;
-ms-flex-align: start;
align-items: flex-start;
/* gap not supported in IE10; use child margins */
}
.card-grid > * {
-ms-flex: 0 0 30%;
flex: 0 0 30%;
margin-bottom: 1rem;
}
/* Negative margin on container to offset first/last row margins */
.card-grid {
margin: 0 -0.5rem;
}
.card-grid > * {
margin: 0 0.5rem 1rem;
}
The flex shorthand in IE10 (-ms-flex) accepts only two values: -ms-flex: <flex-grow> <flex-shrink>. The preferred width (basis) must be set separately via -ms-flex-preferred-size or width. In the example above, 0 0 30% sets grow=0, shrink=0, and the 30% is interpreted as preferred size—this works but is undocumented behavior; explicit width: 30% is safer.
Worked Example: Three-Column Card Grid
Requirement: three equal columns, wrapped rows, centered horizontally, 16px gap, no horizontal overflow.
.cards {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-ms-flex-pack: center;
justify-content: center;
margin: 0 -8px; /* half-gap negative margin */
}
.card {
-ms-flex: 0 0 calc(33.333% - 16px);
flex: 0 0 calc(33.333% - 16px);
margin: 0 8px 16px; /* half-gap each side + row gap */
box-sizing: border-box;
}
@media screen and (max-width: 600px) {
.card {
-ms-flex: 0 0 calc(50% - 16px);
flex: 0 0 calc(50% - 16px);
}
}
@media screen and (max-width: 400px) {
.card {
-ms-flex: 0 0 100%;
flex: 0 0 100%;
}
}
Key details: calc() works in IE10. The negative container margin (-8px) cancels the child's horizontal margins on the first and last item of each row. box-sizing: border-box ensures padding/border don't add to the calculated width.
Trade-offs and Known Bugs
- min-height on flex container: IE10 ignores
min-heighton a-ms-flexboxcontainer. Workaround: set a fixedheightor use a wrapper element. - Percentage child widths with padding: Even with
box-sizing: border-box, IE10 sometimes calculates the flex basis before applying padding, causing overflow. - No
align-self: Per-item cross-axis alignment doesn't exist. All children share the container's-ms-flex-alignvalue. - No
order: Source order is the only order. Reordering requires DOM manipulation.
Verify Before You Ship
- Spin up an IE10 VM.
- Load the page and open the F12 developer tools. Check the Computed tab:
displayshould show-ms-flexbox. - Resize the viewport across your breakpoints. Confirm columns reflow without horizontal scroll.
- Inspect a
.cardelement: verify-ms-flexshows0 0 30%(or your calculated basis). - Toggle
-ms-flex-pack: centeroff/on in the Styles pane—items should shift from left-aligned to centered.
Closing Action
Audit your codebase for unprefixed display: flex without an -ms- fallback. Add the prefixed block first, test in IE10, then decide: maintain the dual syntax, serve a separate legacy stylesheet, or drop IE10 support entirely. The 2009 spec isn't coming back—every hour spent debugging it is an hour not spent on modern layout.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.