CSS3弹性布局

2009年,W3C提出一种崭新的布局方案---弹性盒(Flexbox)布局,使用该模型可以轻松地创建自适应窗口的流动布局,或者自适应字体大小的弹性布局。W3C的弹性盒布局分为旧版本、新版本及混合过渡版本3种不同的设计方案,其中混合过渡版本主要针对IE10进行兼容。目前,CSS3弹性布局多应用于移动端网页布局。

1、旧版本弹性盒

弹性盒是CSS3新增的布局模型,实际上它一直都存在。最开始它作为Mozilla XUL的一个功能,被用来制作程序界面,如Firefox的工具栏。

1.1、启动弹性盒

在旧版本中启动弹性盒模型,只需设置容器的display属性值为box(或inline-box),用法如下所示:

css 复制代码
    display: box;
    display: inline-box;

弹性盒模型由两部分构成:

  • 父容器。
  • 子容器。

父容器通过display:box;或者display: inline-box;启动弹性盒布局功能。

子容器通过box-flex属性定义布局宽度,定义如何对父容器的宽度进行分配。

父容器通过如下属性定义包含容器的显示属性,简单说明如下:

  • box-orient:定义父容器里子容器的排列方式是水平还是垂直。
  • box-direction:定义父容器里子容器的排列顺序。
  • box-align:定义子容器的垂直对齐方式。
  • box-pack:定义子容器的水平对齐方式。

注意:使用旧版本弹性盒模型,需要用到各浏览器的私有属性,Webkit引擎支持-webkit-前缀的私有属性,Mozilla Gecko引擎支持-moz-前缀的私有属性,Presto引擎(包括Opera浏览器等)支持标准属性,IE暂不支持旧版本弹性盒模型。

1.2、设置宽度

在默认情况下,盒子没有弹性,它将尽可能宽地使其内容可见且没有溢出,其大小由width、height、min-height、min-width、max-width或者max-height的属性值决定。

使用box-flex属性可以把默认布局变为盒布局。如果box-flex的属性值为1,则元素变得富有弹性,其大小将按下面的方式计算。

  • 声明的大小(width、height、min-width、min-height、max-width、max-height)。
  • 父容器的大小和所有余下的可利用的内部空间。

如果盒子没有声明大小,那么其大小将完全取决于父容器的大小,即盒子的大小等于父容器的大小乘以其box-flex在所有盒子box-flex总和中的百分比,用公式表示:

bash 复制代码
    盒子的大小 = 父容器的大小 × 盒子的box-flex÷所有盒子的box-flex值的和

【示例】定义左侧边栏的宽度为240px,右侧边栏的宽度为200px,中间内容板块的宽度将由box-flex属性确定。详细代码如下所示:

html 复制代码
    <style type="text/css">
    #container {
        /*定义弹性盒布局样式*/
        display: -moz-box;
        display: -webkit-box;
        display: box;
    }
    #left-sidebar {
        width: 240px;
        padding: 20px;
        background-color: orange;
    }
    #contents {
        /*定义中间列宽度为自适应显示*/
        -moz-box-flex: 1;
        -webkit-box-flex: 1;
        flex: 1;
        padding: 20px;
        background-color: yellow;
    }
    #right-sidebar {
        width: 200px;
        padding: 20px;
        background-color: limegreen;
    }
    #left-sidebar, #contents, #right-sidebar {
        /*定义盒样式*/
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
    }
    </style>
    <div id="container">
        <div id="left-sidebar">
            <h2>宋词精选</h2>
            <ul>
                <li><a href="">卜算子·咏梅</a></li>
                <li><a href=""> 声声慢·寻寻觅觅</a></li>
                <li><a href=""> 雨霖铃·寒蝉凄切</a></li>
                <li><a href="">卜算子·咏梅</a></li>
                <li><a href="">更多</a></li>
            </ul>
        </div>
        <div id="contents">
            <h1>水调歌头·明月几时有</h1>
            <h2>苏轼</h2>
            <p>丙辰中秋,欢饮达旦,大醉,作此篇,兼怀子由。</p>
            <p>明月几时有?把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞
弄清影,何似在人间?</p>
            <p>转朱阁,低绮户,照无眠。不应有恨,何事长向别时圆?人有悲欢离合,月有阴晴圆缺,此事古难全。但愿
人长久,千里共婵娟。</p>
        </div>
        <div id="right-sidebar">
            <h2>词人列表</h2>
            <ul>
                <li><a href="">陆游</a></li>
                <li><a href="">李清照</a></li>
                <li><a href="">苏轼</a></li>
                <li><a href="">柳永</a></li>
            </ul>
        </div>
    </div>

当调整窗口宽度时,中间列的宽度会自适应显示,使整个页面总是满窗口显示。

1.3、设置顺序

使用box-ordinal-group属性可以改变子元素的显示顺序,语法格式如下:

css 复制代码
    box-ordinal-group:<integer>

用整数值定义弹性盒对象的子元素显示顺序,默认值为1。浏览器在显示时,将根据该值从小到大显示这些元素。

【示例】以上节示例为基础,在左栏、中栏、右栏中分别加入一个box-ordinal-group属性,并指定显示的序号,这里将中栏设置为1,右栏设置为2,左栏设置为3,则可以发现三栏显示顺序发生了变化:

css 复制代码
    #left-sidebar {
        -moz-box-ordinal-group: 3;
        -webkit-box-ordinal-group: 3;
        box-ordinal-group: 3;
    }
    #contents {
        -moz-box-ordinal-group: 1;
        -webkit-box-ordinal-group: 1;
        box-ordinal-group: 1;
    }
    #right-sidebar {
        -moz-box-ordinal-group: 2;
        -webkit-box-ordinal-group: 2;
        box-ordinal-group: 2;
    }

1.4、设置方向

使用box-orient属性可以定义元素的排列方向,语法格式如下:

css 复制代码
    box-orient:horizontal | vertical | inline-axis | block-axis

取值简单说明如下:

  • horizontal:设置弹性盒对象的子元素从左到右水平排列。
  • vertical:设置弹性盒对象的子元素从上到下纵向排列。
  • inline-axis:设置弹性盒对象的子元素沿行轴排列。
  • block-axis:设置弹性盒对象的子元素沿块轴排列。

【示例】针对上面示例,在
标签样式中加入box-orient属性,并设定属性值为vertical,即定义内容以垂直方向排列,则代表左侧边栏、中间内容、右侧边栏的3个div元素的排列方向将从水平方向改变为垂直方向:

css 复制代码
    #container {
        /*定义弹性盒布局样式*/
        display: -moz-box;
        display: -webkit-box;
        display: box;
        /*定义从上到下排列显示*/
        -moz-box-orient: vertical;
        -webkit-box-orient: vertical;
        box-orient: vertical;
    }

使用box-direction属性可以让各个子元素反向排序,语法格式如下:

css 复制代码
    box-direction:normal | reverse

取值简单说明如下:

  • normal:设置弹性盒对象的子元素按正常顺序排列。
  • reverse:反转弹性盒对象的子元素的排列顺序。

1.5、设置对齐方式

使用box-pack属性可以设置子元素水平方向的对齐方式,语法格式如下:

css 复制代码
    box-pack:start | center | end | justify

取值简单说明如下:

  • start:设置弹性盒对象的子元素从开始位置对齐,为默认值。
  • center:设置弹性盒对象的子元素居中对齐。
  • end:设置弹性盒对象的子元素从结束位置对齐。
  • justify:设置弹性盒对象的子元素两端对齐。

使用box-align属性可以设置子元素垂直方向的对齐方式,语法格式如下:

css 复制代码
    box-align:start | end | center | baseline | stretch

取值简单说明如下:

  • start:设置弹性盒对象的子元素从开始位置对齐。
  • center:设置弹性盒对象的子元素居中对齐。
  • end:设置弹性盒对象的子元素从结束位置对齐。
  • baseline:设置弹性盒对象的子元素基线对齐。
  • stretch:设置弹性盒对象的子元素自适应父元素尺寸。

【示例】有一个<div class="login">容器,其中包含一个登录表单对象,为了方便练习,本例使用一个<img>标签进行模拟,然后使用box-pack和box-align属性让表单对象在<div class="login">容器的正中央显示。同时,设计<div class="login">容器的高度和宽度都为100%,这样就可以让表单对象在窗口中央位置显示,具体实现代码如下:

html 复制代码
    <style type="text/css">
    /*清除页边距*/
    body { margin: 0; padding: 0;}
    div { position: absolute; }
    .bg {/*设计遮罩层*/
        width: 100%; height: 100%;
        background: #000; opacity: 0.7;
    }
    .login {
        /*满屏显示*/
        width:100%; height:100%;
        /*定义弹性盒布局样式*/
        display: -moz-box;
        display: -webkit-box;
        display: box;
        /*垂直居中显示*/
        -moz-box-align: center;
        -webkit-box-align: center;
        box-align: center;
        /*水平居中显示*/
        -moz-box-pack: center;
        -webkit-box-pack: center;
        box-pack: center;
    }
    </style>
    <div class="web"><img src="images/bg.png" /></div>
    <div class="bg"></div>
    <div class="login"><img src="images/login.png"  /></div>

2、新版本弹性盒

新版本弹性盒模型主要优化了UI布局,既可以简单地使一个元素居中(包括水平和垂直居中),又可以扩大或收缩元素填充容器的可利用空间,还可以改变布局顺序等。

2.1、认识Flexbox系统

Flexbox系统由弹性容器和弹性项目组成。

在弹性容器中,每一个子元素都是一个弹性项目,弹性项目可以是任意数量的,弹性容器外和弹性项目内的一切元素都不受影响。

弹性项目沿着弹性容器内的一个弹性行定位,通常每个弹性容器只有一个弹性行。在默认情况下,弹性行和文本方向一致:从左至右,从上到下。

常规布局是基于块和文本流方向,而Flex布局是基于flex-flow流。如下图所示是W3C规范对Flex布局的解释:

弹性项目是沿着主轴(main axis),从主轴起点(main start)到主轴终点(main end),或者沿着侧轴(cross axis),从侧轴起点(cross start)到侧轴终点(cross end)排列。

  • 主轴(main axis):弹性容器的主轴,弹性项目主要沿着这条轴进行排列布局。注意,它不一定是水平的,这主要取决于内容对齐(justify-content)属性设置。
  • 主轴起点(main start)和主轴终点(main end):弹性项目放置在弹性容器内从主轴起点(main start)向主轴终点(main start)方向。
  • 主轴尺寸(main size):弹性项目在主轴方向的宽度或高度就是主轴的尺寸。弹性项目主要的大小属性要么是宽度属性,要么是高度属性,由哪一个对着主轴方向决定。
  • 侧轴(cross axis):垂直于主轴称为侧轴。它的方向主要取决于主轴方向。
  • 侧轴起点(cross start)和侧轴终点(cross end):弹性行的配置从容器的侧轴起点边开始,往侧轴终点边结束。
  • 侧轴尺寸(cross size):弹性项目在侧轴方向的宽度或高度就是项目的侧轴长度,弹性项目的侧轴长度属性是width或height属性,由哪一个对着侧轴方向决定。

一个弹性项目就是一个弹性容器的子元素,弹性容器中的文本也被视为一个弹性项目。弹性项目中的内容与普通文本流一样。例如,当一个弹性项目被设置为浮动,用户依然可以在这个弹性项目中放置一个浮动元素。

2.2、启动弹性盒

通过设置元素的display属性为flex或inline-flex可以定义一个弹性容器。设置为flex的容器被渲染为一个块级元素,而设置为inline-flex的容器则渲染为一个行内元素。具体语法如下:

css 复制代码
    display: flex | inline-flex;

上面语法定义弹性容器,属性值决定容器是行内显示还是块显示,它的所有子元素将变成flex文档流,被称为弹性项目。

此时,CSS的columns属性在弹性容器上没有效果,同时float、clear和vertical-align属性在弹性项目上也没有效果。

【示例】设计一个弹性容器,其中包含4个弹性项目:

html 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        width: 500px; height: 300px;
        border: solid 1px red;
    }
    .flex-item {
        background-color: blue;
        width: 200px; height: 200px;
        margin: 10px;
    }
    </style>
    <div class="flex-container">
        <div class="flex-item">弹性项目1</div>
        <div class="flex-item">弹性项目2</div>
        <div class="flex-item">弹性项目3</div>
        <div class="flex-item">弹性项目4</div>
    </div>

2.3、设置主轴方向

使用flex-direction属性可以定义主轴方向,它适用于弹性容器。具体语法如下:

css 复制代码
    flex-direction:row | row-reverse | column | column-reverse

取值说明如下:

  • row:主轴与行内轴方向作为默认的书写模式,即横向从左到右排列(左对齐)。
  • column:主轴与块轴方向作为默认的书写模式,即纵向从上往下排列(顶对齐)。
  • column-reverse:对齐方式与column相反。

【示例】在上节示例基础上,设计一个弹性容器,其中包含4个弹性项目,然后定义弹性项目从上往下排列:

css 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        -webkit-flex-direction: column;
        flex-direction: column;
        width: 500px;height: 300px;border: solid 1px red;
    }
    .flex-item {
        background-color: blue;
        width: 200px; height: 200px;
        margin: 10px;
    }
    </style>

2.4、设置行数

flex-wrap定义弹性容器是单行还是多行显示弹性项目,侧轴的方向决定新行堆放的方向。具体语法格式如下:

css 复制代码
    flex-wrap:nowrap | wrap | wrap-reverse

取值说明如下:

  • nowrap:flex容器为单行。该情况下,flex子项可能会溢出容器。
  • wrap:flex容器为多行。该情况下,flex子项溢出的部分会被放置到新行,子项内部会发生断行。
  • wrap-reverse:反转wrap排列。

【示例】在上面示例基础上,设计一个弹性容器,其中包含4个弹性项目,然后定义弹性项目多行排列:

css 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        -webkit-flex-wrap: wrap;
        flex-wrap: wrap;
        width: 500px; height: 300px;border: solid 1px red;
    }
    .flex-item {
        background-color: blue;
        width: 200px; height: 200px;
        margin: 10px;
    }
    </style>

【补充】flex-flow属性是flex-direction和flex-wrap属性的复合属性,适用于弹性容器。该属性可以同时定义弹性容器的主轴和侧轴,其默认值为row nowrap。具体语法如下:

css 复制代码
    flex-flow:<' flex-direction '> || <' flex-wrap '>

取值说明如下:

  • <' flex-direction'>:定义弹性盒子元素的排列方向。
  • <' flex-wrap'>:控制flex容器是单行或者多行。

2.5、设置对齐方式

1、主轴对齐

justify-content定义弹性项目沿着主轴线的对齐方式,该属性适用于弹性容器。具体语法如下:

css 复制代码
    justify-content:flex-start | flex-end | center | space-between | space-around

取值说明如下:

  • flex-star:为默认值,弹性项目向一行的起始位置靠齐。
  • flex-end:弹性项目向一行的结束位置靠齐。
  • center:弹性项目向一行的中间位置靠齐。
  • space-between:弹性项目会平均地分布在行里。第一个弹性项目在一行中最开始的位置,最后一个弹性项目在一行中最终点的位置。

上述取值比较效果如下图所示:

2、侧轴对齐

align-items定义弹性项目在侧轴上的对齐方式,该属性适用于弹性容器。具体语法如下:

css 复制代码
    align-items:flex-start | flex-end | center | baseline | stretch

取值说明如下:

  • flex-start:弹性项目在侧轴起点边的外边距紧靠住该行在侧轴起始的边。
  • flex-end:弹性项目在侧轴终点边的外边距靠住该行在侧轴终点的边。
  • center:弹性项目的外边距盒在该行的侧轴上居中放置。
  • baseline:弹性项目根据它们的基线对齐。
  • stretch:默认值,弹性项目拉伸填充整个弹性容器。此值会使弹性项目的外边距盒的尺寸在遵照min/max-width/height属性的限制下尽可能地接近所在行的尺寸。

上述取值比较效果如下图所示:

3、弹性行对齐

align-content定义弹性行在弹性容器里的对齐方式,该属性适用于弹性容器。类似于弹性项目在主轴上使用justify-content属性,但本属性在只有一行的弹性容器上没有效果。具体语法如下:

css 复制代码
    align-content:flex-start | flex-end | center | space-between | space-around | stretch

取值说明如下:

  • flex-start:各行向弹性容器的起点位置堆叠。
  • flex-end:各行向弹性容器的结束位置堆叠。
  • center:各行向弹性容器的中间位置堆叠。
  • space-between:各行在弹性容器中平均分布。
  • space-around:各行在弹性容器中平均分布,在两边各有一半的空间。
  • stretch:默认值,各行将会伸展以占用剩余的空间。

上述取值比较效果如下图所示:

【示例】以上面示例为基础,定义弹性行在弹性容器中居中显示:

css 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        -webkit-flex-wrap: wrap;
        flex-wrap: wrap;
        -webkit-align-content: center;
        align-content: center;
        width: 500px; height: 300px;border: solid 1px red;
    }
    .flex-item {
        background-color: blue;
        width: 200px; height: 200px;
        margin: 10px;
    }
    </style>

2.6、设置弹性项目

弹性项目都有一个主轴长度(main size)和一个侧轴长度(cross size)。主轴长度是弹性项目在主轴上的尺寸,侧轴长度是弹性项目在侧轴上的尺寸。一个弹性项目的宽或高取决于弹性容器的轴,可能就是它的主轴长度或侧轴长度。

下面属性适用于弹性项目,可以调整弹性项目的行为。

1.显示位置

order属性可以控制弹性项目在弹性容器中的显示顺序,具体语法如下:

css 复制代码
    order: <integer>

<integer>用整数值定义排列顺序,数值小的排在前面,可以为负值。

2.扩展空间

flex-grow可以定义弹性项目的扩展能力,决定弹性容器剩余空间按比例应扩展多少空间。具体语法如下:

css 复制代码
    flex-grow: <number>

其中,<number>用数值定义扩展比率,不允许为负值,默认值为0。

如果所有弹性项目的flex-grow设置为1,那么每个弹性项目将设置为一个大小相等的剩余空间。如果给其中一个弹性项目设置flex-grow为2,那么这个弹性项目所占的剩余空间是其他弹性项目所占剩余空间的2倍。

3.收缩空间

flex-shrink可以定义弹性项目收缩的能力,与flex-grow功能相反。具体语法如下:

css 复制代码
    flex-shrink: <number>

其中,<number>用数值定义收缩比率,不允许为负值,默认值为1。

4.弹性比率

flex-basis可以设置弹性基准值,剩余的空间按比率进行弹性。具体语法如下:

css 复制代码
    flex-basis:<length> | <percentage> | auto | content

取值说明如下:

  • <length>:用长度值定义宽度,不允许为负值。
  • <percentage>:用百分比定义宽度,不允许为负值。
  • auto:无特定宽度值,取决于其他属性值。
  • content:基于内容自动计算宽度。

【补充】flex是flex-grow、flex-shrink和flex-basis 3个属性的复合属性,该属性适用于弹性项目。其中第二个参数(flex-shrink)和第三个参数(flex-basis)是可选参数,默认值为"0 1 auto"。具体语法如下:

css 复制代码
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

5.对齐方式

align-self用来在单独的弹性项目上覆写默认的对齐方式。具体语法如下:

css 复制代码
    align-self:auto | flex-start | flex-end | center | baseline | stretch

其属性值与align-items的属性值相同。

【示例1】以上面示例为基础,定义弹性项目在当前位置向右错移一个位置,其中第一个项目位于第二个项目的位置,第二个项目位于第三个项目的位置,最后一个项目移到第一个项目的位置:

css 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        width: 500px; height: 300px;border: solid 1px red;
    }
    .flex-item { background-color: blue; width: 200px; height: 200px; margin: 10px;}
    .flex-item:nth-child(0){
        -webkit-order: 4;
        order: 4;
    }
    .flex-item:nth-child(1){
        -webkit-order: 1;
        order: 1;
    }
    .flex-item:nth-child(2){
        -webkit-order: 2;
        order: 2;
    }
    .flex-item:nth-child(3){
        -webkit-order: 3;
        order: 3;
    }
    </style>

【示例2】margin: auto;在弹性盒中具有强大的功能,一个auto的margin会合并剩余的空间。它可以把弹性项目挤到其他位置。下面利用margint: auto;定义包含的项目居中显示:

css 复制代码
    <style type="text/css">
    .flex-container {
        display: -webkit-flex;
        display: flex;
        width: 500px; height: 300px; border: solid 1px red;
    }
    .flex-item {
        background-color: blue; width: 200px; height: 200px;
        margin: auto;
    }
    </style>
    <div class="flex-container">
        <div class="flex-item">弹性项目</div>
    </div>
相关推荐
我要洋人死38 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#