メインコンテンツへ移動

flexbox レイアウトの互換性

無料2015-06-08#CSS#弹性盒布局#伸缩盒布局#flex布局#flexbox布局

flex レイアウトの互換性は非常に気まずい話題です。各ハイエンドなデスクトップブラウザとモバイルブラウザは非常に息の合ったように互換性の問題が存在します。本文は互換性の問題を詳細に説明し、一般的に使用される互換性の良い flex レイアウトコードを提供します。

前置き

flex レイアウトは 2009 年から存在していましたが、現在は 2015 年 6 月 8 日です。最新の flex 構文を使用すると、サポート状況が良くないことがわかります。「ハイエンド」ブラウザでも同様で、Chrome、Firefox、Safari、Android、IOS Safari などでサポート状況がそれぞれ異なります

既存のオンラインコードには様々なバージョンがあふれており、Chrome では通常問題なく実行されます。Firefox も概ね良好ですが、Android と IOS Safari では非常に無力に見えます。このような状況が生じた主な理由は歴史的な原因です。2009 年から 2015 年までの間に W3C 仕様が何度も更新され、ブラウザのサポート状況にも差異が生じました

一.W3C の各バージョンの flex

###2009 version

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

###2011 version

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

###2012 version

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

###2014 version

flex 項の z-index に関する規定が追加されました

###2015 W3C Editor's Draft

大きな変更はありません

P.S.2015 年は W3C Editor's Draft であり、草案に過ぎず、まだ修正段階で、ブラウザベンダーの意見を募集していないことに注意してください

二.ブラウザの互換性

flex に関する W3C 仕様:http://dev.w3.org/csswg/css-flexbox-1/

ブラウザの互換性は CanIUse を参照できます:http://caniuse.com/#feat=flexbox

CanIUse のデータに基づいて以下のようにまとめられます:

  • IE10 は 2012 を部分的にサポートし、-ms-プレフィックスが必要です

  • Android4.1/4.2-4.3 は 2009 を部分的にサポートし、-webkit-プレフィックスが必要です

  • Safari7/7.1/8 は 2012 を部分的にサポートし、* -webkit-プレフィックスが必要です*

  • IOS Safari7.0-7.1/8.1-8.3 は 2012 を部分的にサポートし、-webkit-プレフィックスが必要です

したがって、新しいバージョン 2012 を考慮する必要があります:http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/

Android は旧バージョン 2009 を考慮する必要があります:http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/

三.ブラウザ互換の flex 構文

上記の分析は非常に明確です。互換性が必要なターゲットに対応するバージョンの構文を使用すればよいです。以下に一般的なレイアウトコードを示します:

/* 子元素 - 平均分栏 */
.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. */
                              /* 见本文底部评论 @Lawrence */
    -webkit-flex: 1;          /* Chrome */
    -ms-flex: 1;              /* IE 10 */
    flex: 1;                  /* NEW, Spec - Opera 12.1, Firefox 20+ */
}
/* 父元素 - 横向排列(主轴) */
.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 版 */
    -webkit-box-orient: horizontal;
    /* 12 版 */
    -webkit-flex-direction: row;
    -moz-flex-direction: row;
    -ms-flex-direction: row;
    -o-flex-direction: row;
    flex-direction: row;
}
/* 父元素 - 横向换行 */
.flex-hw {
    /* 09 版 */
    /*-webkit-box-lines: multiple;*/
    /* 12 版 */
    -webkit-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    -o-flex-wrap: wrap;
    flex-wrap: wrap;
}
/* 父元素 - 水平居中(主轴是横向才生效) */
.flex-hc {
    /* 09 版 */
    -webkit-box-pack: center;
    /* 12 版 */
    -webkit-justify-content: center;
    -moz-justify-content: center;
    -ms-justify-content: center;
    -o-justify-content: center;
    justify-content: center;
    /* 其它取值如下:
        align-items     主轴原点方向对齐
        flex-end        主轴延伸方向对齐
        space-between   等间距排列,首尾不留白
        space-around    等间距排列,首尾留白
     */
}
/* 父元素 - 纵向排列(主轴) */
.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 版 */
    -webkit-box-orient: vertical;
    /* 12 版 */
    -webkit-flex-direction: column;
    -moz-flex-direction: column;
    -ms-flex-direction: column;
    -o-flex-direction: column;
    flex-direction: column;
}
/* 父元素 - 纵向换行 */
.flex-vw {
    /* 09 版 */
    /*-webkit-box-lines: multiple;*/
    /* 12 版 */
    -webkit-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    -o-flex-wrap: wrap;
    flex-wrap: wrap;
}
/* 父元素 - 竖直居中(主轴是横向才生效) */
.flex-vc {
    /* 09 版 */
    -webkit-box-align: center;
    /* 12 版 */
    -webkit-align-items: center;
    -moz-align-items: center;
    -ms-align-items: center;
    -o-align-items: center;
    align-items: center;
}
/* 子元素 - 显示在从左向右(从上向下)第 1 个位置,用于改变源文档顺序显示 */
.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+ */
}
/* 子元素 - 显示在从左向右(从上向下)第 2 个位置,用于改变源文档顺序显示 */
.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+ */
}

より良い互換性のために、コンテナに flex-h/flex-v を宣言する必要があります。通常の flex ではなく:

/* 父元素-flex 容器 */
.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+ */
}

したがって、Android の互換性が必要な場合(2009 版構文)は flex-h/flex-v を使用してコンテナを宣言し、flex モードを使用します。Android の互換性が必要ない場合(2012 版構文)は flex を使用してコンテナを設定することをお勧めします

注意:上記のコードはすべてのハイエンドブラウザと完全に互換性があるわけではありませんが、他の既存コードよりも互換性は良いです。具体的な互換性テスト結果は Demo を参照してください

四.flex レイアウト Demo

オンラインテスト:Demo

テスト結果:

  • Android4.2.2 は改行をサポートしていません

  • Android4.2.2 では疑似要素の位置の動作が一貫していません

  • IOS Safari 7.1 の動作は Chrome28、Chrome43、Firefox の動作と一致しています

  • より多くのテスト結果については、私にフィードバックしてください。ありがとうございます

注意:テスト結果から、flex レイアウトは疑似要素を要素として扱いスペースを割り当てることがわかります(ドキュメントには疑似要素に position: fixed/absolute; を設定することでこの状況を回避できると記載されているようですが、本文ではまだ検証していません)。しかし、通常は疑似要素には装飾的な役割のみを持たせ、レイアウトに影響を与えないことを望んでいます。これは私たちの期待と一致しません。したがって、flex レイアウトに疑似要素がある場合は特に注意し、できるだけ多くのブラウザ互換性テストを行うか、float レイアウトに切り替えてください

参考資料

コメント

コメントはまだありません

コメントを書く