Home  >  Article  >  Web Front-end  >  H5学习_番外篇_弹性盒模型详解_html/css_WEB-ITnose

H5学习_番外篇_弹性盒模型详解_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-21 08:53:261151browse

弹性盒模型详解


每天都是大晚上的给各位读者老爷写文章,我也是瀑布汗。(⊙﹏⊙)b

近日很多内容都是直接在网上摘录的,具体文章链接全部在文章最底部。

如果涉及到版权问题,请及时联系我,我会尽快做出处理。

今天弄的东西都是老生常谈的问题, 如果你之前读过,就当温习好了,如果没读过,就当学习罢了。

发现自己又墨迹了好长时间,不好意思了。2016年03月23日21:27:25

这里写图片描述

0. 前言

Flexbox 是什么呢?

就 W3C 官方给到的解释是,这是设计来实现更复杂的版面布局。

那我自己对他的定义是,Flexbox 从本质上就是一个 Box-model 的延伸,我们都知道 Box-model 定义了一个元素的盒模型,然而 Flexbox 更进一步的去规范了这些盒模型之间彼此的相对关系。

而不需要去用一些很 cheat 的做法,去 hack 一些本来其实不应该用来做版面布局的属性。

Flexible boxes盒子按照宽和高分出了以下 8 点:

  • 水平的主轴: main axis
  • 垂直的纵轴:cross axis
  • 纵轴的开始位置和边框的交点: cross start
  • 纵轴的结束位置和边框的交点: cross end
  • 主轴的开始位置和边框的交点: main start
  • 主轴的结束位置和边框的交点: main end
  • 单个项目占据主轴的空间距离: main axis
  • 单个项目占据纵轴的空间距离: cross axis

总之,我们的弹性盒模型就是让我们的实现响应式布局更加优雅。

test_2.gif

同时给大家推荐几个网站。

  • 无耻的我,自己占一个坑
  • 18个学习 flexbox 的优质资源
  • Flexbox模拟器
  • FLEXBOX小游戏

    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=6available_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分别为3,2,1.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
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn