Skip to main content

Flexbox Layout Compatibility

Free2015-06-08#CSS#弹性盒布局#伸缩盒布局#flex布局#flexbox布局

Flex layout compatibility is a very awkward topic. Various high-end desktop browsers and mobile browsers tacitly all have compatibility issues. This article explains compatibility issues in detail and provides commonly used flex layout code with better compatibility.

Written at the Beginning

Flex layout has existed since 2009, and now it's June 8, 2015. Using the latest flex syntax, you'll find support is not good, even on "high-end" browsers. For example, Chrome, Firefox, Safari, Android, and IOS Safari all have varying degrees of support

Existing code on the internet is flooded with various versions. Running in Chrome generally has no problems, Firefox is generally okay too, but Android and IOS Safari appear very powerless. The reason for this situation is mainly historical. From 2009 to 2015, the W3C specification had multiple updates, so browser support also varies

I. Various Versions of W3C Flex

2009 version

Mark: display: box; or a property that is box-{*} (eg. box-pack)

2011 version

Mark: display: flexbox; or the flex() function or flex-pack property

2012 version

Mark: display: flex/inline-flex; and flex-{*} properties

2014 version

Added regulations for flex item z-index

2015 W3C Editor's Draft

No major changes

P.S. Note that 2015 is W3C Editor's Draft, just a draft, still in the revision stage, hasn't solicited opinions from browser vendors yet

II. Browser Compatibility

About flex W3C specification: http://dev.w3.org/csswg/css-flexbox-1/

Browser compatibility can refer to CanIUse: http://caniuse.com/#feat=flexbox

According to CanIUse data, can summarize as follows:

  • IE10 partially supports 2012, needs -ms- prefix

  • Android 4.1/4.2-4.3 partially supports 2009, needs -webkit- prefix

  • Safari 7/7.1/8 partially supports 2012, needs -webkit- prefix

  • IOS Safari 7.0-7.1/8.1-8.3 partially supports 2012, needs -webkit- prefix

So need to consider new version 2012: http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/

And Android needs to consider old version 2009: http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/

III. Browser Compatible Flex Syntax

The analysis above is very clear, just use the corresponding version syntax for the targets that need compatibility. Below provides commonly used layout code:

/* Child elements - evenly distributed columns */
.flex1 {
    -webkit-box-flex: 1;      /* OLD - iOS 6-, Safari 3.1-6 */
    -moz-box-flex: 1;         /* OLD - Firefox 19- */
    /* width: 20%; */         /* For old syntax, otherwise collapses. */
                              /* See comment @Lawrence at bottom of this article */
    -webkit-flex: 1;          /* Chrome */
    -ms-flex: 1;              /* IE 10 */
    flex: 1;                  /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
/* Parent element - horizontal arrangement (main axis) */
.flex-h {
    display: box;              /* OLD - Android 4.4- */
    
    display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
    display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
    display: -ms-flexbox;      /* TWEENER - IE 10 */
    display: -webkit-flex;     /* NEW - Chrome */
    display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */


    /* 09 version */
    -webkit-box-orient: horizontal;
    /* 12 version */
    -webkit-flex-direction: row;
    -moz-flex-direction: row;
    -ms-flex-direction: row;
    -o-flex-direction: row;
    flex-direction: row;
}
/* Parent element - horizontal wrap */
.flex-hw {
    /* 09 version */
    /*-webkit-box-lines: multiple;*/
    /* 12 version */
    -webkit-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    -o-flex-wrap: wrap;
    flex-wrap: wrap;
}
/* Parent element - horizontal center (only works when main axis is horizontal) */
.flex-hc {
    /* 09 version */
    -webkit-box-pack: center;
    /* 12 version */
    -webkit-justify-content: center;
    -moz-justify-content: center;
    -ms-justify-content: center;
    -o-justify-content: center;
    justify-content: center;
    /* Other values as follows:
        align-items     Align towards main axis origin
        flex-end        Align towards main axis end
        space-between   Equal spacing, no whitespace at start/end
        space-around    Equal spacing, whitespace at start/end
     */
}
/* Parent element - vertical arrangement (main axis) */
.flex-v {
    display: box;              /* OLD - Android 4.4- */
    
    display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
    display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
    display: -ms-flexbox;      /* TWEENER - IE 10 */
    display: -webkit-flex;     /* NEW - Chrome */
    display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */


    /* 09 version */
    -webkit-box-orient: vertical;
    /* 12 version */
    -webkit-flex-direction: column;
    -moz-flex-direction: column;
    -ms-flex-direction: column;
    -o-flex-direction: column;
    flex-direction: column;
}
/* Parent element - vertical wrap */
.flex-vw {
    /* 09 version */
    /*-webkit-box-lines: multiple;*/
    /* 12 version */
    -webkit-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    -o-flex-wrap: wrap;
    flex-wrap: wrap;
}
/* Parent element - vertical center (only works when main axis is horizontal) */
.flex-vc {
    /* 09 version */
    -webkit-box-align: center;
    /* 12 version */
    -webkit-align-items: center;
    -moz-align-items: center;
    -ms-align-items: center;
    -o-align-items: center;
    align-items: center;
}
/* Child element - display at 1st position from left to right (top to bottom), used to change source document order display */
.flex-1 {
    -webkit-box-ordinal-group: 1;   /* OLD - iOS 6-, Safari 3.1-6 */
    -moz-box-ordinal-group: 1;      /* OLD - Firefox 19- */
    -ms-flex-order: 1;              /* TWEENER - IE 10 */
    -webkit-order: 1;               /* NEW - Chrome */
    order: 1;                       /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
/* Child element - display at 2nd position from left to right (top to bottom), used to change source document order display */
.flex-2 {
    -webkit-box-ordinal-group: 2;   /* OLD - iOS 6-, Safari 3.1-6 */
    -moz-box-ordinal-group: 2;      /* OLD - Firefox 19- */
    -ms-flex-order: 2;              /* TWEENER - IE 10 */
    -webkit-order: 2;               /* NEW - Chrome */
    order: 2;                       /* NEW, Spec - Opera 12.1, Firefox 20+ */
}

For better compatibility, we need to declare flex-h/flex-v for containers, instead of general flex:

/* Parent element - flex container */
.flex {
    display: box;              /* OLD - Android 4.4- */

    display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
    display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
    display: -ms-flexbox;      /* TWEENER - IE 10 */
    display: -webkit-flex;     /* NEW - Chrome */
    display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */
}

So, recommend using flex-h/flex-v to declare containers using flex mode when needing to兼容 Android (2009 version syntax), and use flex to set containers when not needing to兼容 Android (2012 version syntax)

Note: The code given above is not completely compatible with all high-end browsers, but has better compatibility than any other existing code. Please see Demo for specific compatibility test results

IV. Flex Layout Demo

Online test: Demo

Test results:

  • Android 4.2.2 doesn't support wrapping

  • Android 4.2.2 pseudo-element position performance is inconsistent

  • IOS Safari 7.1 performance is consistent with Chrome 28, Chrome 43, Firefox

  • Please feedback more test results to me, thank you

Note: From test results can discover flex layout treats pseudo-elements as elements to allocate space (documentation seems to mention setting position: fixed/absolute; for pseudo-elements can avoid this situation, this article hasn't verified yet), but we generally hope pseudo-elements only have decorative function, not affecting layout, which is inconsistent with our expectations. So, be especially careful when there are pseudo-elements in flex layout, conduct browser compatibility testing as much as possible, or switch to float layout

Reference Materials

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment