在css中,已经习惯使用栅格布局方式进行页面的布局。栅格好处是兼容性好,而且写起来也简单粗暴,也是目前大多的UI框架所使用的布局方式

当然,栅格布局也会存在一定的问题,比如各种各样的浮动很糟心,垂直居中什么的就更不用提了,在移动端的表现也比较差,只能够进行简单的响应式。

css3 新的 flex 布局 方式真的是不容小觑的一个新特性,在第一次接触的时候,觉得很麻烦, 非常不好用,而且经常效果就会出现错误,了解的多了,就会慢慢的发现,是自己用的不对,而不是工具不好用。

而目前很多的移动端UI都是使用了flex的布局方式,移动端的表现也很不错。

一、flex box - 弹性盒子

CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。
引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
----来自w3cschool

我觉得弹性盒子最大的有点就是,能够针对屏幕大小自动的保证元素的恰当表现

而且 flex-box 对于处理空白区域的方式非常赞:

  • 使用 bootstrap 多的都知道它的布局当 col-md-12 放不满的时候,默认left to right排列
  • 而我知道 amazeUI 处理方式,当 col-md-12 放不满的时候,:last-child 自动 float:right;

flex-box 对于空白的处理以及垂直居中的处理非常赞~

自适应中宽度其实并不是最重要的:

  • 如果子盒子的宽度没有撑破 一行的宽度,则会按照设置的 width 显示
  • 如果超过了 一行 的宽度,则默认会对 width 进行调整

比如下面的代码中,给 col-item 设置了宽度,但是在 html 代码中,col-item 总宽度是撑破了 row 的宽度,因此宽度会进行调整。

  • 该调整是默认自动调整的
<style>
    .row{
        width:200px;
        display: flex;
        display:-webkit-flex;
        border:1px solid #cccccc;
    }
    .col-item{
        background: rgba(0,0,0,1);
        width:100px;
        height:50px;
        margin:5px;
    }
</style>
<body>
    <div class="row">
        <div class="col-item"></div>
        <div class="col-item"></div>
        <div class="col-item"></div>
        <div class="col-item"></div>
        <div class="col-item"></div>
    </div>    
</body>

1-1.jpg

二、flex-direction

flex-direct 的作用是 指定子盒子的排列方式

  • row : 默认 从左到右依次排列
  • row-reverse : 从右到左依次排列
  • column : 垂直排列 从上到下
  • column-reverse : 垂直排列 从下到上

一般特殊会用到 column 的排列方式:

同样的,由于flex-box的自动调整的特性,在高度超出row设置的高度的时候,也会自动压缩 子盒子的高度,保证内容都在flex-box中。

 <style>
    .row{
        width:200px;
        height:100px;
        display: flex;
        display:-webkit-flex;
        border:1px solid #cccccc;
        flex-direction:column;
    }
    .col-item{
        background: rgba(0,0,0,1);
        width:100px;
        height:100px; 
        color:#fff;
    }
</style>
<body>
    <div class="row">
        <div class="col-item"><span>AAA</span></div>
        <div class="col-item"><span>BBB</span></div>
        <div class="col-item"><span>CCC</span></div>
        <div class="col-item"><span>DDD</span></div>
        <div class="col-item"><span>EEE</span></div>
    </div>    
</body>

不过需要注意的是,在压缩子盒子的时候,如果由于内容已经超出了一行设置的高度,则会进行溢出。

使用默认的font-size: 导致字体的高度加起来也超出了row的高度,因此子盒子是溢出的:

  • 下图中每个子盒子的高度为21px,这个高度是因为字体的高度导致的

1-2.jpg

使用 font-size:10px ,内容不溢出,则子盒子本身不会溢出row的高度

1-3.jpg

二.2、flex-flow

flex-flowflex-direction flex-wrap的两者简写形式:

  .container{
    display:flex;
    display:-webkit-flex;
    flex-flow:row wrap;
    -webkit-flex-flow:row wrap;
    /* 相当于 flex-direction:row;flex-wrap:wrap; */
}

三、justify-content 内容水平对齐方式

我对 justify-content 的理解就是,子盒子在一行中的对齐方式,而不是排列方式,排列方式由 flex-direction 来控制。

所谓的内容对齐无非就是子盒子在一行中的表现形式,比如间距多少、居中、居左、居右等。

使用 justify-content 能够使我们非常方便的实现水平排列的效果,比如占满一整行、或者整体居中、或者平均分布。

  • flex-start : 默认的 就是从贴着行的开始(左边界)依次向右进行排列
  • flex-end : 和 flex-start 相反,从右边界对齐,依次向左挨着排列

    • 需要注意的是:排列的方式是不变的,ABCDE 的顺序是固定的,不会变成EDCBA,只不过如果有空隙会把空隙放在左边
    • 和 flex-direction 中的 row-reverse 是完全不同的概念
  • center : 居中对齐 所有的子盒子排列好之后,放在中间
  • space-between : 平均分配中间的空隙间隔,但是第一个子盒子和最后一个子盒子是贴在row的左右边界上的
  • space-round : 平均分配中间的空隙, 不过 第一个子盒子和最后一个子盒子不贴在row的左右边界,也要计算空隙。

说明图:

1-4.jpg

图片来自wcschool

四、align-items 内容垂直对齐方式

  • flex-start : 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
    1-5.jpg
  • flex-end : 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
    1-6.jpg
  • center : 弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
    1-7.jpg
  • baseline : 如弹性盒子元素的行内轴与侧轴为同一条,则该值与'flex-start'等效。其它情况下,该值将参与基线对齐。
  • stretch : 如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。

五、flex-wrap 换行

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

六、align-content

align-content 属性用于修改 flex-wrap 属性的行为。类似于 align-items, 但它不是设置弹性子元素的对齐,而是设置各个行的对齐。 --- w3cschool

align-content 很大程度上是为了 flex-wrap 服务的

  • stretch - 默认。各行将会伸展以占用剩余的空间。
    1-11.jpg
  • flex-start - 各行向弹性盒容器的起始位置堆叠。
    1-10.jpg
  • flex-end - 各行向弹性盒容器的结束位置堆叠。
    1-12.jpg
  • center - 各行向弹性盒容器的中间位置堆叠。
    1-13.jpg
  • space-between - 各行在弹性盒容器中平均分布。
    1-14.jpg
  • space-around - 各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。
    1-15.jpg

七、order 顺序

order 是用在 子盒子 上的。

  .box1{order:-1;-webkit-order: -1;}
  .box2{order:1;-webkit-order: -1;}

order越低越往前

八、 使用 flex 进行居中

对盒子使用居中对齐我们会使用 margin:0 auto;
但是无法进行垂直对齐,这是永远的痛苦

flex 布局方式中,能够进行 完美居中,只需要进行 margin:auto;

1-16.jpg

九、align-self

align-self 属性用于设置弹性元素自身在侧轴(纵轴)方向上的对齐方式。

align-self 控制的是内容 也就是子盒子自身的垂直排列方式,和 align-items 不同的就是 align-items 控制的是所有的子元素,而 align-self 控制的是子元素本身

  • auto :如果'align-self'的值为'auto',则其计算值为元素的父元素的'align-items'值,如果其没有父元素,则计算值为'stretch'。
  • flex-start : 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
  • flex-end : 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
  • center : 弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
  • baseline : 如弹性盒子元素的行内轴与侧轴为同一条,则该值与'flex-start'等效。其它情况下,该值将参与基线对齐。
  • stretch : 如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。

1-17.jpg

十、flex 属性

在进行栅格布局的时,以 bootstrap 举例,col-md-* 用来控制每一列在该行中所占的宽度。

而使用flex布局方式,可以直接通过flex属性,来控制每个元素的宽度比例。

flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

  • 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
<style>
    .row{
        width:500px;
        height:200px;
        display: flex;
        display: -webkit-flex;
        color:#fff;
        text-align: center;
    } 
    .col-1{
        -webkit-flex:1;
        flex:1;
        background-color: #000000;
    }
    .col-2{
        -webkit-flex:2;
        flex:2;
        background-color: #666666;
    }
</style>
<body>
    <div class="row"> 
        <div class="col-1"><span>1</span></div>
        <div class="col-2"><span>2</span></div>
        <div class="col-1"><span>1</span></div>
    </div>
</body>

1-18.jpg

十一、非常值得看的两篇文章

阮一峰的两篇: