CSS3弹性盒子布局

    CSS3中引入的弹性盒子布局已经有一段时间,也经历了几次比较重大的修改,可本人一直都没怎么使用过这种布局,惭愧万分!这几天研究了一下这种布局方式,记录一下学习笔记,以后日后用到时过来查看。

      2016年5月26日,W3C(官网:https://www.w3.org/ )组织发布了CSS3弹性盒子布局最新的CR版本:
网址:https://www.w3.org/TR/2016/CR-css-flexbox-1-20160526/
          或 https://www.w3.org/TR/css-flexbox-1/

名称:CSS Flexible Box Layout Module Level 1 W3C Candidate Recommendation, 26 May 2016

      本想翻译过来认真研究一下这篇文档,但发现可爱的WCM官网已经有一篇早期版本的中文版,参考这篇文档也大致可以看懂了。
网址: https://www.w3.org/html/ig/zh/css-flex-1/
名称:CSS 伸缩盒布局模组 Editor’s Draft, 16 October 2012

      更重要的是,W3C上说:

This document was produced by the CSS Working Group (part of the Style Activity) as a Candidate Recommendation. This document is intended to become a W3C Recommendation. This document will remain a Candidate Recommendation at least until 1 September 2016 in order to ensure the opportunity for wide review. (引用自:https://www.w3.org/TR/css-flexbox-1/)

翻译过来就是说:

本文(指https://www.w3.org/TR/css-flexbox-1/) 的最终目标是要成为W3C的标准。但是至少在2016年9月1日之前,本文还是维持在候选标准(CR)阶段,这是为了确保本文档能被广泛的审查。

      所以,

2016年9月1日,这一天可能是一篇文档成为W3C标准的一天!!!
2016年9月1日,这一天可能是一篇文档成为W3C标准的一天!!!
2016年9月1日,这一天可能是一篇文档成为W3C标准的一天!!!

(重要的事说三遍。当然,本人也会跟踪这一情况)

      由于本人刚开始学习弹性盒子布局,自知无法完成一篇通俗易懂的关于弹性盒子布局应用的文章,故只能通过其他高人的文章来学习,以下三篇是个人感觉写的通俗易懂的良心之作,特推荐给各位看客,本人以下的博客内容也主要引用自此,只是部分内容略作修改,特此说明。

http://www.cnblogs.com/yangjie-space/p/4852251.html
http://www.cnblogs.com/yangjie-space/p/4856109.html
http://www.admin10000.com/document/6200.html

CSS3弹性盒布局是什么

      在 https://www.w3.org/TR/css-flexbox-1/ 中,描述了弹性盒子模型是什么,原文如下:

In the flex layout model, the children of a flex container can be laid out in any direction, and can “flex” their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.

翻译过来就是:

在弹性盒子布局中,弹性容器(flex container)中的子元素可以以任意方向排布,也可以伸缩它们自身的尺寸,或者增大自身尺寸以填满未被使用的空间,或者缩小自身尺寸以避免超出父容器的尺寸范围。子元素横向或纵向对齐方式很容易被修改。嵌套的弹性盒子布局(水平内嵌套垂直,或垂直内嵌套水平),可以用来创建两个维度上的布局。

      总结一下什么是弹性盒子布局,

弹性盒子布局的作用——处理页面布局
弹性盒子布局的优点——根据屏幕尺寸或浏览器窗口尺寸自动调整页面中各局部区域的显示方式
弹性盒子布局的兼容性——请参见如下网址:http://www.css88.com/book/css/properties/flex/index.htm

注:以下内容均摘录自:http://www.admin10000.com/document/6200.html

弹性盒布局中的一些专用术语

弹性容器与弹性子项

      一个flexbox布局是由一个弹性容器(flex container)和弹性子项(flex items)组成,在弹性容器(flex container)中,其所有的子元素都会变成弹性子项(flex items),如下图:
这里写图片描述

主侧轴

这里写图片描述

      main axis:进行布局时作为布局基准的轴,在横向布局时为水平轴,在纵向布局时为垂直轴。
      main-start / main-end:进行布局时的布局起点与布局终点。在横向布局时为容器的左端与右端,在纵向布局时为容器的顶端与底端。
      cross axis:与main axis垂直相交的轴,在横向布局时为垂直轴,在纵向布局时为水平轴。
      cross-start / cross-end:cross axis轴的起点与终点。在横向布局时为容器的顶端与底端,在纵向布局时为容器的左端与右端。

将flex-wrap属性值指定为wrap且进行横向多行布局时,按从cross-start到cross-end方向,即从上往下布局,
将flex-wrap属性值指定为wrap-reverse且进行横向多行布局时,按从cross-end到cross-start方向,即从下往上布局。

justify-content属性——规定子元素在主轴方向的对齐方式

   justify-content属性用于指定如何布局 弹性盒容器中除子元素之外的,在main axis轴方向(横向布局时main axis轴方向为水平方向,纵向布局时main axis轴方向为垂直方向)上的,剩余空白部分。

   当flex-grow属性值不为0时,各子元素在main axis轴方向上自动填满容器,此时justify-content属性值无效。

   可指定justify-content属性值如下所示:
        flex-start:从main-start开始布局所有子元素(默认值)。
        flex-end:从main-end开始布局所有子元素。
        center:居中布局所有子元素。
        space-between:将第一个子元素布局在main-start处,将最后一个子元素布局在main-end处,将空白部分平均分配在所有子元素与子元素之间。
        space-around:将空白部分平均分配在以下几处:main-start与第一个子元素之间、各子元素与子元素之间、最后一个子元素与main-end之间。

    上述各属性值的区别如下图所示(灰色代表空白部分)。

这里写图片描述

align-items属性——规定子元素在侧轴方向的对齐方式

     align-items属性与justify-content属性类似,但是用于指定弹性盒容器中的各子元素在cross axis轴方向(横向布局时cross axis轴方向为垂直方向,纵向布局时cross axis轴方向为水平方向)上的对齐方式。

      可指定属性值如下所示。
         flex-start:从cross-start开始布局所有子元素(默认值)。
         flex-end:从cross-end开始布局所有子元素。
         center:居中布局所有子元素。
         baseline:如果子元素的布局方向与容器的布局方向不一致,则该值的作用等效于flex-start属性值的作用。如果子元素的布局方向与容器的布局方向保持一致,则所有子元素中的内容沿基线对齐。
         stretch:同一行中的所有子元素高度被调整为最大。如果未指定任何子元素高度,则所有子元素高度被调整为最接近容器高度(当考虑元素边框及内边距时,当边框宽度与内边距均为0则等于容器高度)。

          上述各属性值的区别如下图所示(灰色代表空白部分)。

这里写图片描述

align-self属性——单独指定某个子元素在侧轴方向的对齐方式

    align-self属性与align-items属性的区别在于:align-items被指定为容器元素的样式属性,用于指定所有子元素的对齐方式,而align-self属性被指定为某些子元素的样式属性,用于单独指定这些子元素的对齐方式。例如将容器元素的align-items属性值指定为center(居中对齐)后,可以将第一个子元素的align-self属性值指定为flex-start(对齐在cross-start端)。

    可以指定的属性值如下所示(含义同align-items属性的各属性值,此处略):
        auto:继承父元素的align-items属性值
        flex-start
        flex-end
        center
        baseline
        stretch

align-content属性——指定多行在侧轴方向上的对齐方式

    当进行多行布局时,可以使用align-content属性来指定各行对齐方式。该属性与align-items属性的区别在于:align-items属性用于指定子元素的对齐方式,而align-content属性用于指定行对齐方式。

    可以指定的属性值如下所示:
        flex-start:从cross-start开始布局所有行。
        flex-end:从cross-end开始布局所有行。
        center:居中布局所有行。
        space-between:将第一行布局在cross-start处,将最后一行布局在cross-end处,将空白部分平均分配在各行之间。
        space-around:将空白部分平均分配在以下几处:cross-start与第一行之间、各行与行之间、最后一行与cross-end之间。

       
       上述各属性值的区别如下图所示(灰色代表空白部分)。

   这里写图片描述

学习弹性盒子布局的准备工作

      本文将要用到的html文档的emmet结构如下:

div#main>div.content(>section(>h1{section $}+p{文字内容})*4)
            +div.content>section>h1{section 5}
                                +p{文字内容}
                                +(section>h1{section $}+p{文字内容})*3
            +div.content(>section(>h1{section $}+p{文字内容})*4)

      html代码如下:

<div id="main">
        <div class="content">
            <section>
                <h1>section 1</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 2</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 3</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 4</h1>
                <p>文字内容</p>
            </section>
        </div>
        <div class="content">
            <section>
                <h1>section 5</h1>
                <p>文字内容</p>
                <section>
                    <h1>section 6</h1>
                    <p>文字内容</p>
                </section>
                <section>
                    <h1>section 7</h1>
                    <p>文字内容</p>
                </section>
                <section>
                    <h1>section 8</h1>
                    <p>文字内容</p>
                </section>
            </section>
        </div>
        <div class="content">
            <section>
                <h1>section 9</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 10</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 11</h1>
                <p>文字内容</p>
            </section>
            <section>
                <h1>section 12</h1>
                <p>文字内容</p>
            </section>
        </div>
    </div>

      CSS样式如下:

      下文出现的所有样式效果如未做特殊说明,均是在此CSS样式的基础上直接添加新样式而成。

<style>
#main {
    border: 1px dotted #f0f;
    padding: 1em;
}
.content {
    border: 1px dotted #0ff;
    padding: 1em;
}
section {
    border: 1px dotted #f00;
    padding: 1em;
}
</style>

      在浏览器中打开目前为止的示例页面,页面中各元素从上往下纵向排列,如下图所示:
这里写图片描述

display:flex—定义弹性盒子布局

    对需要弹性布局的元素的直接父级容器元素使用display:flex;样式属性即可。

    在CSS Flexible Box模块中,该容器元素中的每一个子元素均被称为“Flex item”,将该容器元素称为“Flex container”。

    弹性盒布局方式与使用float等样式属性进行的布局方式的一个主要区别为,当使用float等样式属性时,需要对容器中每一个元素指定样式属性,当使用弹性盒布局时,只需对容器元素指定样式属性即可。

注:

    可能大家也会看到有写的是display:box/display:flexbox;其实其实他们只是不同时期的规范:

    新规范:2013年最新版本规范的语法 即display:flex/inline-flex;
    中间版本:2011年非官方规范的语法 即display:flexbox/inline-flexbox;
    老规范:2009年规范的语法 即display:box/inline-/box;

      以上述html代码为例,我们首先对所有class=content的div元素使用弹性盒布局,这些div元素的容器元素为id=main的div元素,修改该元素的样式代码如下所示:

#main{
        ...
        display: flex;
        ...
}

      页面效果如下图:
这里写图片描述

flex-direction—设置容器中所有子元素的排列方向

    通过使用flex-direction样式属性,来控制容器中所有子元素的排列方向,可指定值如下所示。

    row:横向排列(默认值)
    row-reverse:横向反向排列
    column:纵向排列
    column-reverse:纵向反向排列

      为id=main的div元素的添加如下样式代码:

#main{
        ...
        display: flex;
        flex-direction: row-reverse;
        ...
    }

      打开页面可见,所有class=content的div元素的排列方式被修改为从容器元素(即id=main的div元素)的右端开始横向反向排列,如下图所示
这里写图片描述

利用嵌套弹性盒子布局实现两个维度上的布局

      接下来,我们为父级元素和子元素都设置弹性盒子布局,查看一下嵌套弹性盒子布局,首先在id=main的div元素设置弹性盒子布局,代码如下:

#main{
        ...
        display: flex;
        ...
}

      接着,我们对所有class=content的div元素设置弹性盒子布局并指定flex-direction: column-reverse;样式属性,代码如下所示:

.content {
    display: flex;
    flex-direction: column-reverse;
}

      在浏览器中打开示例页面,页面中所有class=content的div元素的所有section子元素的排列方式被修改为纵向反向排列(section子元素中的section孙元素的排列方式不受影响,如section6、7、8),如下图所示。
 这里写图片描述

order—改变容器中各子元素的显示顺序

      使用弹性盒子布局时,可以通过order属性来改变容器中各子元素的显示顺序。可以在每个子元素的样式中加入order属性,该属性使用一个表示序号的整数属性值(可以为负数),浏览器在显示的时候根据该序号从小到大来显示容器中的这些子元素。

      通过将所有class=content的div元素中的第2个section子元素的order属性设置为order:-1,将这些section子元素被优先显示在其他section子元素之前,代码如下所示:

 .content {
        display: flex;
        flex-direction: column;
    }
    .content section:nth-child(2) {
        order: -1;
    }

      在浏览器中打开示例页面,页面中所有class=content的div元素中的第2个section子元素(secton2、10)被显示在其他section子元素之前,如下图所示。
这里写图片描述

设置元素宽度及高度

      接下来首先介绍如何设置被横向排列的每一个元素的宽度。

使用flex属性使所有子元素的总宽度等于容器宽度

通过将所有class=content的div元素的flex属性值设置为1,使所有class=content的div元素的总宽度等于容器元素,即id=main的div元素的宽度,代码如下所示。
当所有class=content的div元素的flex属性值都被设置为1时,这些div元素的宽度均等。
#main {
            ...
            display: flex;
        }
    .content {
        ...
        flex:1;
    }

      在浏览器中打开示例页面,所有class=content的div元素的宽度自动增长,这些元素的总宽度等于容器元素,即id=main的div元素的宽度,每一个class=content的div元素的宽度均等,如下图所示。
这里写图片描述

      接下来,我们设置第二个样式类名为content的div元素的flex属性值为2,代码如下所示。

#main {
            ...
            display: flex;
        }
    .content {
        ...
        flex:1;
    }
    .content:nth-child(2) {
        flex:2;
    }

      页面效果如下图:
这里写图片描述

      为了更清晰地计算元素宽度,我们取消所有元素的边框设置及内边距设置,修改后的完整样式代码如下所示。

<style>
    #main {
        display: flex;
    }
    .content {
        display: flex;
        flex-direction: column;
        flex:1;
    }
    .content:nth-child(2) {
        flex:2;
    }
    </style>

      在浏览器中打开示例页面如下图所示,第二个class=content的div元素宽度为其他class=content的div元素宽度的两倍,假设这些元素的容器元素,即id=main的div元素的宽度等于600px,则第一个与第三个class=content的div元素宽度的宽度均等于150px,第二个class=content的div元素宽度的宽度等于300px。
这里写图片描述

使用flex-grow属性来指定元素宽度

除了flex可以指定元素宽度,也可以使用flex-grow属性来指定元素宽度,但是该样式属性对于元素宽度的计算方法与flex样式属性对于元素宽度的计算方法有所不同。

      接下来指定所有class=content的div元素的flex-grow样式属性值为1,宽度为150px,指定第二个样式class=content的div元素的flex-grow样式属性值为为3。修改后的完整样式代码如下所示。

<style>
        #main {
            display: flex;
        }
        .content {
            display: flex;
            flex-direction: column;
            width:150px;
            flex-grow:1;
        }
        .content section:nth-child(2) {
            order: -1;
        }
        .content:nth-child(2) {
            flex-grow:3;
        }
    </style>

      在浏览器中打开示例页面,假设这些元素的容器元素,即id属性值为main的div元素的宽度等于600,则第一个与第三个样式类名为content的div元素宽度的宽度均等于180px,第二个样式类名为content的div元素宽度的宽度等于240px。对于每个样式类名为content的div元素宽度的计算步骤如下所示:

    600(容器宽度)-150*3(三个样式类名为content的div元素宽度的总宽度)=150
    150/5(三个样式类名为content的div元素宽度的flex-grow样式属性值的总和=1+1+3=5)=30
    第一个与第三个样式类名为content的div元素宽度的宽度均等于150(其width样式属性值+)+30*1(其flew-grow样式属性值)=180px
    第二个样式类名为content的div元素宽度的宽度等于150(其width样式属性值+)+30*3(其flew-grow样式属性值)=240px

使用flex-shrink属性来指定元素宽度

      使用flex-shrink属性来指定元素宽度,该样式属性与flex-grow样式属性的区别在于:
      当子元素的width样式属性值的总和小于容器元素的宽度值时,必须通过flex-grow样式属性来调整子元素宽度,
      当子元素的width样式属性值的总和大于容器元素的宽度值时,必须通过flex-shrink样式属性来调整子元素宽度。

      接下来指定所有class=content的div元素的flex-shrink样式属性值为1,宽度为250px, 指定第二个class=content的div元素的flex-shrink样式属性值为为3。修改后的完整样式代码如下所示。

<style>
        #main {
            display: flex;
        }
        .content {
            display: flex;
            flex-direction: column;
            width:250px;
            flex-shrink:1;
        }
        .content section:nth-child(2) {
            order: -1;
        }
        .content:nth-child(2) {
            flex-shrink:3;
        }
    </style>

      在浏览器中打开示例页面,假设这些元素的容器元素,即id属性值为main的div元素的宽度等于600,则第一个与第三个样式类名为content的div元素宽度的宽度均等于220px,第二个样式类名为content的div元素宽度的宽度等于160px。对于每个样式类名为content的div元素宽度的计算步骤如下所示:

    250*3(三个样式类名为content的div元素宽度的总宽度)-600(容器宽度)=150
    150/5(三个样式类名为content的div元素宽度的flex-shrink样式属性值的总和=1+1+3=5)=30
    第一个与第三个样式类名为content的div元素宽度的宽度均等于250(其width样式属性值+)-30*1(其flew-shrink样式属性值)=220px
    第二个样式类名为content的div元素宽度的宽度等于250(其width样式属性值+)-30*3(其flew-grow样式属性值)=160px

使用flex-basis属性来指定元素宽度

      在使用flex-grow样式属性或flex-shrink样式属性调整子元素宽度时,也可以使用flex-basis样式属性指定调整前的子元素宽度,该样式属性与width样式属性的作用完全相同。

将flex-grow、flex-shrink以及flex-basis样式属性值合并写入flex样式属性中

      可以将flex-grow、flex-shrink以及flex-basis样式属性值合并写入flex样式属性中,方法如下所示。

    flex:flex-grow样式属性值 flex-shrink样式属性值 flex-basis样式属性值;

      在使用flex样式属性值时,flex-grow、flex-shrink以及flex-basis样式属性值均为可选用样式属性值,当不指定flex-grow、flex-shrink样式属性值时,默认样式属性值均为1,当不指定flex-basis样式属性值时,默认样式属性值为0px。

      修改本示例中的样式代码如下所示:

<style>
    #main {
        display: flex;
    }
    .content {
        display: flex;
        flex-direction: column;
        width:250px;
        flex:250px;
    }
    .content section:nth-child(2) {
        order: -1;
    }
    .content:nth-child(2) {
        flex:1 3 250px;
    }
    </style>

      在浏览器中打开示例页面,假设这些元素的容器元素,即id属性值为main的div元素的宽度等于600,则第一个与第三个样式类名为content的div元素宽度的宽度均等于220px,第二个样式类名为content的div元素宽度的宽度等于160px。

  在子元素为横向排列时,flex、flex-grow、flex-shrink以及flex-basis样式属性均用于指定或调整子元素宽度,
   当子元素为纵向排列时,flex、flex-grow、flex-shrink以及flex-basis样式属性均用于指定或调整子元素高度。

单行布局与多行布局

      可以使用flex-wrap样式属性来指定单行布局或多行布局,可指定样式属性值如下所示:

    nowrap:不换行
    wrap:换行
    wrap-reverse:虽然换行,但是换行方向与使用wrap样式属性值时的换行方向相反

      接下来首先恢复页面内各div元素的边框与内边距(padding)的指定,同时指定所有样式类名为content的div元素的宽度为250px,代码如下所示。

<style>
    #main {
        border: 1px dotted #f0f;
        padding: 1em;
        display: flex;
    }
    .content {
        border: 1px dotted #0ff;
        padding: 1em;
        display: flex;
        flex-direction: column;
        flex:250px;
    }
    section {
        border: 1px dotted #f00;
        padding: 1em;
    }
    .content section:nth-child(2) {
        order: -1;
    }
    </style>

      然后指定容器元素,即id属性值为main的div元素的flex-wrap样式属性值为wrap,以指定允许对所有样式类名为content的div元素进行换行布局,代码如下所示。

#main {
        flex-wrap: wrap;
    }

      在浏览器中打开示例页面,当浏览器窗口宽度不足以容纳三个样式类名为content的div元素时,最右边的样式类名为content的div元素被换行显示,如下图所示。
这里写图片描述

总结

1、要对元素使用弹性盒子布局,只要在其直接父级容器元素上设置display:flex即可
2、以下7个属性是加在flex container上的:
      display:flex/inline-flex;
      flex-direction
      flex-wrap
      flex-flow
      justify-content
      align-items
      align-content
3、这6个属性是加在flex item上的
      order
      flex-grow
      flex-shrink
      flex-basis
      flex
      align-self
4、可以将flex-direction样式属性值与flex-wrap样式属性值合并书写在flex-flow样式属性中。以下两段代码的作用完全相同。

    //使用flex-direction样式属性与flex-wrap样式属性
    .content {
        flex-direction: row;
        flex-wrap: wrap;
    }
    //使用flex-flow样式属性
    .content {
        flex-flow: row wrap;
    }
  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值