본문으로 건너뛰기

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 레이아웃으로 전환하십시오

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성