H5学习弹性盒模型详解

1. 语法

1.1 语法基础概念

任何一个容器都可以指定为Flex布局。

    .box{
      display: flex;
    }

行内元素也可以使用Flex布局。

    .box{
      display: inline-flex;
    }

同时需要注意,在不用的浏览器中,我们还需要在前面加上对应的浏览器前缀。

    .box{
      display: -webkit-flex; /* Safari */
      display: flex;
    }

注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

1.2 容器属性设置

以下6个属性设置在容器上。

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content
1.2.1 flex-direction属性

flex-direction 属性决定主轴的方向(即项目的排列方向)。

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

--
row(默认值)主轴为水平方向,起点在左端。
row-reverse主轴为水平方向,起点在右端。
column主轴为垂直方向,起点在上沿。
column-reverse主轴为垂直方向,起点在下沿。

1.2.2 flex-wrap属性

默认情况下,项目都排在一条线(又称”轴线”)上。

flex-wrap属性定义,如果一条轴线排不下,如何换行。

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

  1. nowrap(默认):不换行。 

  2. wrap:换行,第一行在上方。 

  3. wrap-reverse:换行,第一行在下方。 

1.2.3 flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。

.box {
  flex-flow: <flex-direction> || <flex-wrap>;
}

1.2.4 justify-content属性

justify-content属性定义了项目在主轴上的对齐方式。

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

--
flex-start(默认值)左对齐
flex-end右对齐
center居中
space-between两端对齐,项目之间的间隔都相等。
space-around每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

1.2.5 align-items属性

align-items属性定义项目在交叉轴上如何对齐。

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

--
flex-start交叉轴的起点对齐。
flex-end交叉轴的终点对齐。
center交叉轴的中点对齐。
baseline项目的第一行文字的基线对齐。
stretch(默认值)如果项目未设置高度或设为auto,将占满整个容器的高度。

1.2.6 align-content属性

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

--
flex-start与交叉轴的起点对齐。
flex-end与交叉轴的终点对齐。
center与交叉轴的中点对齐。
space-between与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值)轴线占满整个交叉轴。

1.3 项目的属性

以下6个属性设置在项目上。

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self
1.3.1 order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
  order: <integer>;
}

1.3.2 flex-grow属性

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /* default 0 */
}

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

1.3.3 flex-shrink属性

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

.item {
  flex-shrink: <number>; /* default 1 */
}

http://www.ruanyifeng.com/blogimg/asset/2015/bg2015071015.jpg

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。

如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

负值对该属性无效。

1.3.4 flex-basis属性

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis: <length> | auto; /* default auto */
}

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

补充:

flex-basis:flex-basis可以理解为我们给子元素设置的宽度。

默认值是auto,宽度设置为auto时,盒子的宽度取决你们元素的宽度。

1.3.5 flex属性

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

补充: 
grow和shrink是一对双胞胎,grow表示伸张因子,shrink表示是收缩因子。

grow在flex容器下的子元素的宽度和比容器和小的时候起作用。

grow定义了子元素的宽度增长因子,容器中除去子元素之和剩下的宽度会按照各个子元素的gorw值进行平分加大各个子元素上。

--
计算容器还剩空间available_space(容器还剩的空间)=container_size(容器宽度)-flex_item_total(子元素宽度之和)
计算增长单位grow_unit(增长单位)=available_space/flex_grow_total(子元素增长因子之和)
得到子元素的宽度flex-item-width(子元素计算得到的宽度)=flex-basis+grow-unit*flex-grow

上面例子的计算

container-size=480px;  
flex-item-total=100*3=300px;
flex-grow-total=3+2+1=6
available_space=480-300=180px;  
grow_unit=180/6=30px;  
子元素1的宽度为:

flex_item_width1=100+3*30=190px;
子元素2的宽度为:

flex_item_width1=100+2*30=160px; 
子元素3的宽度为:

flex_item_width1=100+30=130px;    

shrink则是在宽度和比容器宽度大时候,才有用。按照shrink的值减去相应大小得到子元素的值。

公式:

overflow_space(溢出的宽度)

--
计算溢出的宽度overflow-space=flex-item-total(子元素basis宽度之和)-container_width(容器宽度)
得到计算的子元素的宽度item-basis:子元素设置的flex-basis;item-shrink:子元素的flex-shrink;item-shrink-sum:所有子元素flex_shrink的和。flex_item_width(计算的子元素的宽度)=item-basis --(overflow-space*(item-shrink/item-shrink-sum))

    container-width=480px; item-shrink分别为321.item-basis=200px;  overflow-space=120px;  

    则:

    flex_item1_width=200-(120*(3/6))=140px;
    flex_item2_width=200-(120*(2/6))=160px; 
    flex_item3_width=200-(120*(1/6))=180px;  

1.3.6 align-self属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。

默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

2. 实战

2.1 骰子

如果不加说明,本节的HTML模板一律如下。

    <div class="box">
      <span class="item"></span>
    </div>

上面代码中,div元素(代表骰子的一个面)是Flex容器,span元素(代表一个点)是Flex项目。

如果有多个项目,就要添加多个span元素,以此类推。

2.1.1 一个点

首先,只有左上角1个点的情况。Flex布局默认就是首行左对齐,所以一行代码就够了。

.box {
  display: flex;
}

设置项目的对齐方式,就能实现居中对齐和右对齐。

.box {
  display: flex;
  justify-content: center;
}

.box {
  display: flex;
  justify-content: flex-end;
}

设置交叉轴对齐方式,可以垂直移动主轴。

.box {
  display: flex;
  align-items: center;
}

.box {
  display: flex;
  align-items: center;
}

.box {
  display: flex;
  justify-content: center;
  align-items: center;
}

.box {
  display: flex;
  justify-content: center;
  align-items: flex-end;
}

.box {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}

2.1.2 两个点

.box {
  display: flex;
  justify-content: space-between;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
}

.box {
  display: flex;
}

.item:nth-child(2) {
  align-self: center;
}

.box {
  display: flex;
  justify-content: space-between;
}

.item:nth-child(2) {
  align-self: flex-end;
}

2.1.3 三个点

.box {
  display: flex;
}

.item:nth-child(2) {
  align-self: center;
}

.item:nth-child(3) {
  align-self: flex-end;
}

2.1.4 四个点

.box {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-content: space-between;
}


HTML代码如下。

    <div class="box">
      <div class="column">
        <span class="item"></span>
        <span class="item"></span>
      </div>
      <div class="column">
        <span class="item"></span>
        <span class="item"></span>
      </div>
    </div>

CSS代码如下。

    .box {
        display: flex;
        justify-content: space-between;
    }
    .box .column {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }

2.1.5 六个点

.box {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}

.box {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: space-between;
}

HTML代码如下。

    <div class="box">
      <div class="row">
        <span class="item"></span>
        <span class="item"></span>
        <span class="item"></span>
      </div>
      <div class="row">
        <span class="item"></span>
      </div>
      <div class="row">
         <span class="item"></span>
         <span class="item"></span>
      </div>
    </div>


CSS代码如下。

    .box {
      display: flex;
      flex-wrap: wrap;
    }

    .row{
      flex-basis: 100%;
      display:flex;
    }

    .row:nth-child(2){
      justify-content: center;
    }

    .row:nth-child(3){
      justify-content: space-between;
    }


2.1.6 九个点

.box {
  display: flex;
  flex-wrap: wrap;
}

2.2 网格布局

2.2.1 基本网格布局

最简单的网格布局,就是平均分布。

在容器里面平均分配空间,跟上面的骰子布局很像,但是需要设置项目的自动缩放。

HTML代码如下。

    <div class="Grid">
      <div class="Grid-cell">...</div>
      <div class="Grid-cell">...</div>
      <div class="Grid-cell">...</div>
    </div>

CSS代码如下。

    .Grid {
      display: flex;
    }

    .Grid-cell {
      flex: 1;
    }

2.2.2 百分比布局

某个网格的宽度为固定的百分比,其余网格平均分配剩余的空间。

HTML代码如下。

    <div class="Grid">
      <div class="Grid-cell u-1of4">...</div>
      <div class="Grid-cell">...</div>
      <div class="Grid-cell u-1of3">...</div>
    </div>

CSS代码如下。

    .Grid {
      display: flex;
    }

    .Grid-cell {
      flex: 1;
    }

    .Grid-cell.u-full {
      flex: 0 0 100%;
    }

    .Grid-cell.u-1of2 {
      flex: 0 0 50%;
    }

    .Grid-cell.u-1of3 {
      flex: 0 0 33.3333%;
    }

    .Grid-cell.u-1of4 {
      flex: 0 0 25%;
    }


2.3 圣杯布局

圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局。

页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。

其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。

HTML代码如下。

    <body    class="HolyGrail">
      <header>...</header>
      <div class="HolyGrail-body">
        <main class="HolyGrail-content">...</main>
        <nav class="HolyGrail-nav">...</nav>
        <aside class="HolyGrail-ads">...</aside>
      </div>
      <footer>...</footer>
    </body>

CSS代码如下。

    .HolyGrail {
      display: flex;
      min-height: 100vh;
      flex-direction: column;
    }

    header,
    footer {
      flex: 1;
    }

    .HolyGrail-body {
      display: flex;
      flex: 1;
    }

    .HolyGrail-content {
      flex: 1;
    }

    .HolyGrail-nav, .HolyGrail-ads {
      /* 两个边栏的宽度设为12em */
      flex: 0 0 12em;
    }

    .HolyGrail-nav {
      /* 导航放到最左边 */
      order: -1;
    }

如果是小屏幕,躯干的三栏自动变为垂直叠加。

    @media (max-width: 768px) {
      .HolyGrail-body {
        flex-direction: column;
        flex: 1;
      }
      .HolyGrail-nav,
      .HolyGrail-ads,
      .HolyGrail-content {
        flex: auto;
      }
    }

2.4 输入框的布局

我们常常需要在输入框的前方添加提示,后方添加按钮。

HTML代码如下。

    <div class="InputAddOn">
      <span class="InputAddOn-item">...</span>
      <input class="InputAddOn-field">
      <button class="InputAddOn-item">...</button>
    </div>

CSS代码如下。

    .InputAddOn {
      display: flex;
    }

    .InputAddOn-field {
      flex: 1;
    }

2.5 悬挂式布局

有时,主栏的左侧或右侧,需要添加一个图片栏。

HTML代码如下。

    <div class="Media">
      <img class="Media-figure" src="" alt="">
      <p class="Media-body">...</p>
    </div>

CSS代码如下。

    .Media {
      display: flex;
      align-items: flex-start;
    }

    .Media-figure {
      margin-right: 1em;
    }

    .Media-body {
      flex: 1;
    }

2.6 固定的底栏

有时,页面内容太少,无法占满一屏的高度,底栏就会抬高到页面的中间。

这时可以采用Flex布局,让底栏总是出现在页面的底部。

HTML代码如下。

    <body class="Site">
      <header>...</header>
      <main class="Site-content">...</main>
      <footer>...</footer>
    </body>

CSS代码如下。

    .Site {
      display: flex;
      min-height: 100vh;
      flex-direction: column;
    }

    .Site-content {
      flex: 1;
    }

七,流式布局 
每行的项目数固定,会自动分行。

CSS的写法。

    .parent {
      width: 200px;
      height: 150px;
      background-color: black;
      display: flex;
      flex-flow: row wrap;
      align-content: flex-start;
    }

    .child {
      box-sizing: border-box;
      background-color: white;
      flex: 0 0 25%;
      height: 50px;
      border: 1px solid red;
    }

附录

本文摘录网址:

  1. A Complete Guide to Flexbox
  2. Flex 布局教程:实例篇
  3. Flex 布局教程:语法篇
  4. 骰子代码
  5. Flexible boxes更加优雅的Web布局
  6. Flexbox布局
  7. 18个学习 flexbox 的优质资源
  8. CSS Flexbox Please!
  9. FLEXBOX FROGGY

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值