CSS弹性盒子模型

一直知道css3的flex布局很重要,不过由于我的工作主要是做的PC,且公司要求对IE6、IE7和IE8等浏览器要保证兼容性(主要是本人缺乏钻研精神),所以对flex用得少,这次为了准备面试,需要将这个知识点重新整理。刚好趁着这个时候学习下。不到之处,还请各位见谅。

好,主角登场。

CSS弹性盒子模型( Flexible Box 或者 Flexbox )

先来看看它的定义:弹性布局是指通过调整其内元素的宽高,从而在任何显示设备上实现对可用显示空间最佳填充的能力。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。

简单来说,弹性盒子模型,是为了你的网页可以在不同分辨率设备上自适应展示而生的一种布局方式。

弹性盒子布局主要适用于应用程序的组件及小规模的布局,而(新兴的)栅格布局则针对大规模的布局。这二者都是 CSS 工作组为在不同用户代理、不同书写模式和其他灵活性要求下的网页应用程序有更好的互操作性而做出的更广泛的努力的一部分。

现在,我们来看如何定义一个弹性盒子:

<div id="main">
  <div style="background-color:coral;">A</div>
  <div style="background-color:lightblue;">B</div>
  <div style="background-color:khaki;">C</div>
  <div style="background-color:pink;">D</div>
  <div style="background-color:lightgrey;">E</div>
  <div style="background-color:lightgreen;">F</div>
</div>

如果要将上面的HTML布局改为弹性盒子布局,该怎么办?

很简单!!

只需要设置如下:

#main{
    display: flex
}

或者

#main{
    display: inline-flex
}

区别在于,flex会使弹性容器成为块级元素,而inline-flex会使弹性容器成为单个不可分的行内级元素。

说到这里,有人会问了,弹性容器是什么东东???
大家先来看一张图:


flexbox.png

对比这张图和上面的html代码,大家可以看到:

弹性容器(Flex container):指的就是包含着弹性项目的父元素,即上面的 #main
弹性项目(Flex item):弹性容器的每个子元素都称为弹性项目,弹性容器直接包含的文本将被包覆成匿名弹性单元。即上面的 #main div

大家再仔细观察上面的那张图,图上有个主轴和侧轴,这里又涉及到一个知识点:轴(Axis)

每个弹性框布局都包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(main axis)。垂直于主轴的那根轴称为侧轴(cross axis)

接下来我结合上面的HTML代码为大家讲解下怎么确定主轴和主轴上内容的显示:

使用弹性容器的flex-derection可以确立主轴,这个属性一共有6个值,接下来,我为大家一一展示:

#main{
    display: flex;
    width: 200px;
    flex-direction:row;   //默认值,水平展示
}
屏幕快照 2017-12-27 下午5.23.11.png
#main{
    display: flex;
    width: 200px;
    flex-direction:row-reverse;   //与row相同,但是以相反的顺序
}
屏幕快照 2017-12-27 下午5.24.54.png
#main{
    display: flex;
    width: 200px;
    flex-direction:column;   // 弹性项目将垂直展示
}
屏幕快照 2017-12-27 下午5.26.50.png
#main{
    display: flex;
    width: 200px;
    flex-direction:column-reverse;   // 与 column 相同,但是以相反的顺序。
}
屏幕快照 2017-12-27 下午5.28.47.png

还有两个属性,简单介绍下,就不用举例了:
initial:设置该属性为它的默认值
inherit:从父元素继承该属性

确定了主轴之后,那么在主轴上弹性项目怎么分布??

我们来看一个新的属性:
justify-content: 定义了在当前行上,弹性项目沿主轴如何排布。

#main {
    display: flex;
    width: 400px;
    flex-direction: row;
    justify-content: flex-start;  //默认值,项目位于容器的开头
}
屏幕快照 2017-12-27 下午5.37.16.png
#main{
  display: flex;
  width: 400px;
  flex-direction: row;
  justify-content: flex-end;  // 项目位于容器的结尾
}
屏幕快照 2017-12-27 下午5.39.02.png
#main{
  display: flex;
  width: 400px;
  flex-direction: row;
  justify-content: center;  // 项目位于容器的中间
}
屏幕快照 2017-12-27 下午5.40.26.png
#main{
  display: flex;
  width: 400px;
  flex-direction: row;
  justify-content: space-between;  // 项目位于各行之间留有空白的容器内
}
屏幕快照 2017-12-27 下午5.41.35.png
#main{
  display: flex;
  width: 400px;
  flex-direction: row;
  justify-content: space-around;  // 项目位于各行之前、之间、之后都留有空白的容器内。
}
屏幕快照 2017-12-27 下午5.43.47.png

还有两个属性,简单介绍下,就不用举例了:
initial:设置该属性为它的默认值
inherit:从父元素继承该属性

确定了弹性项目在主轴上是怎么排布的,接下来,再介绍下在侧轴上是怎么排布的:

#main{
  display: flex;
  height: 200px;
  align-items: stretch;  // 默认值,项目被拉伸以适应容器
}
[图片上传中...(屏幕快照 2017-12-27 下午5.50.11.png-f482c0-1514368241951-0)]
#main{
  display: flex;
  height: 200px;
  align-items: center;  // 项目位于容器的中心
}
屏幕快照 2017-12-27 下午5.52.46.png
#main{
  display: flex;
  height: 200px;
  align-items: flex-start;  // 项目位于容器的开头
}
屏幕快照 2017-12-27 下午5.55.34.png
#main{
  display: flex;
  height: 200px;
  align-items: flex-end;  // 项目位于容器的结尾
}
屏幕快照 2017-12-27 下午5.54.09.png
#main{
  display: flex;
  height: 200px;
  align-items: baseline;  // 项目位于容器的基线上
}

还有两个属性,简单介绍下,就不用举例了:
initial:设置该属性为它的默认值
inherit:从父元素继承该属性

如果我只想改变单个弹性项目的对齐方式,该怎么办?

别怕,align-self 属性来也!

align-self:定义了单个弹性项目在侧轴上应当如何对齐,这个定义会覆盖由align-items所确立的默认值。

还是用这个HTML来展示:

<div id="main">
  <div class="a" style="background-color:coral;">A</div>
  <div class="b" style="background-color:lightblue;">B</div>
  <div class="c" style="background-color:khaki;">C</div>
  <div class="d" style="background-color:pink;">D</div>
  <div class="e" style="background-color:lightgrey;">E</div>
  <div class="f" style="background-color:lightgreen;">F</div>
</div>

#main{
 display: flex;
 height: 200px;
 align-items: center;
 background: red;
}

#main div{
  width: 40px;
}

#main .d{
 align-self: auto;  //默认值。元素继承了它的父容器的 align-items 属性。如果没有父容器则为 "stretch"。
}

#main .d{
 align-self: stretch;  //元素被拉伸以适应容器
}
屏幕快照 2017-12-27 下午6.13.00.png
#main .d{
 align-self: center;  //元素位于容器的中心
}
屏幕快照 2017-12-27 下午6.16.04.png
#main .d{
 align-self: flex-start;  //元素位于容器的开头
}
[图片上传中...(屏幕快照 2017-12-27 下午6.16.54.png-16a15-1514369874621-0)]
#main .d{
 align-self: flex-end; 
}

//元素位于容器的结尾
屏幕快照 2017-12-27 下午6.16.54.png
#main .d{
 align-self: baseline;  //元素位于容器的基线上
}

还有两个属性,简单介绍下,就不用举例了:
initial:设置该属性为它的默认值
inherit:从父元素继承该属性

说完了弹性项目的排布,接下来,我们回看最上面那张图,再来说说,怎么确定主轴/侧轴的方向

我们先来看一个属性:
flex-wrap:规定flex容器是单行或者多行,同时横轴的方向决定了新行堆叠的方向。

#main{
  width: 200px;
  height: 200px;
  border: 1px solid #c3c3c3;
  display:flex;
  background: red;
  flex-wrap: nowrap;  // 默认值,规定灵活的项目不拆行或不拆列
}
屏幕快照 2017-12-27 下午6.40.48.png
#main{
  width: 200px;
  height: 200px;
  border: 1px solid #c3c3c3;
  display:flex;
  background: red;
  flex-wrap: wrap;  // 默认值,规定灵活的项目在必要时拆行或拆列
}
屏幕快照 2017-12-27 下午6.43.02.png
#main{
  width: 200px;
  height: 200px;
  border: 1px solid #c3c3c3;
  display:flex;
  background: red;
  flex-wrap: wrap-reverse;  // 规定灵活的项目在必要的时候拆行或拆列,但是以相反的顺序。
}
屏幕快照 2017-12-27 下午6.44.14.png

还有两个属性,简单介绍下,就不用举例了:
initial:设置该属性为它的默认值
inherit:从父元素继承该属性

order: 属性将元素与序号关联起来,以此决定哪些元素先出现

<div id="main">
  <div class="a" style="background-color:coral;">A</div>
  <div class="b" style="background-color:lightblue;">B</div>
  <div class="c" style="background-color:khaki;">C</div>
  <div class="d" style="background-color:pink;">D</div>
  <div class="e" style="background-color:lightgrey;">E</div>
  <div class="f" style="background-color:lightgreen;">F</div>
</div>

.a{
  order: 6;
  -webkit-order: 6;
}
.b{
  order: 5; 
  -webkit-order: 5;
}
.c{
  order: 4; 
  -webkit-order: 4;
}
.d{
  order: 3; 
  -webkit-order: 3;
}
.e{
  order: 2; 
  -webkit-order: 2;
}
.f{
  order: 1; 
  -webkit-order: 1;
}
屏幕快照 2017-12-27 下午6.50.18.png

flex-flow:是 flex-direction 和 flex-wrap 属性的简写,决定弹性项目如何排布。

对于行(Line)中来说,根据flex-wrap属性,弹性项目可以排布在单个行或多个行中。此属性控制侧轴的方向和新行排列的方向

我们确定了弹性容器的主轴与侧轴,弹性项目的宽和高,怎么来确定对应的主轴尺寸和侧轴尺寸???

(1) 可以使用min-height和min-width来确定,这两个的初始值都是0

(2) flex属性是flex-grow、flex-shrink和flex-basis的简写,描述弹性项目的整体伸缩性。

接下来,我们逐一看看这三个新的属性

flex-grow: 用于设置或检索弹性盒的扩展比率

#main{
  width: 500px;
  height: 200px;
  border: 1px solid #c3c3c3;
  display:flex;
  background: red;
}

#main div{
  width: 40px;
}

.a{
  flex-grow: 2;
}
.b{
  flex-grow: 3;
}
.c{
  flex-grow: 1;
}
.d{
  flex-grow: 3;
}
.e{
  flex-grow: 2;
}
.f{
  flex-grow: 1;
}
屏幕快照 2017-12-27 下午7.22.01.png

flex-shrink: 指定了 flex 元素的收缩规则,flex 元素仅在默认宽度之和大于容器时才会发生收缩,其收缩的大小是依据flex-shrink的值

<p>div 总宽度为 500px, flex-basic 为 120px。</p>
<p>A, B, C 设置 flex-shrink:1。 D , E 设置为 flex-shrink:2</p>
<p>D , E 宽度与 A, B, C 不同</p>
<div id="content">
  <div class="box" style="background-color:red;">A</div>
  <div class="box" style="background-color:lightblue;">B</div>
  <div class="box" style="background-color:yellow;">C</div>
  <div class="box1" style="background-color:brown;">D</div>
  <div class="box1" style="background-color:lightgreen;">E</div>
</div>

屏幕快照 2017-12-27 下午7.31.55.png

flex-shrink的默认值为1,如果没有显示定义该属性,将会自动按照默认值1在所有因子相加之后计算比率来进行空间收缩。
本例中A、B、C 显式定义了 flex-shrink 为 1,D、E 定义了 flex-shrink 为 2,所以计算出来总共将剩余空间分成了 7 份,其中 A、B、C 占 1 份,D、E 占 2 份,即1:1:1:2:2
我们可以看到父容器定义为 500px,子项被定义为 120px,子项相加之后即为 600 px,超出父容器 100px。那么超出的 100px 需要被 A、B、C、D、E 消化 通过收缩因子,所以加权综合可得 1001+1001+1001+1002+1002=700px

于是我们可以计算 A、B、C、D、E 将被移除的溢出量是多少:
A 被移除溢出量:(1001/700)100,即约等于14px
B 被移除溢出量:(1001/700)100,即约等于14px
C 被移除溢出量:(1001/700)100,即约等于14px
D 被移除溢出量:(1002/700)100,即约等于28px
E 被移除溢出量:(1002/700)100,即约等于28px
最后A、B、C、D、E的实际宽度分别为:120-14=106px, 120-14=106px, 120-14=106px, 120-28=92px,120-28=92px,此外,这个宽度是包含边框的。**

flex-basis:用于设置或检索弹性盒伸缩基准值。

接下来,说几个弹性盒子的相关属性:
由于弹性盒子使用了不同的布局算法,某些属性用在弹性容器上没有意义:

  • 多栏布局模块的 column-* 属性对弹性项目无效
  • float与clear对弹性项目无效。使用float将使元素的display属性记为block
  • vertical-align对弹性项目的对齐方式无效。

最后,我们来看换一个例子:

​<!DOCTYPE html>
<html lang="en">
  <head>
    <style>

   .flex
   {
      /* 基本样式 */
      width: 350px;
      height: 200px;
      border: 1px solid #555;
      font: 14px Arial;

      /*  建立弹性框 */
      display: -webkit-flex;
      -webkit-flex-direction: row;

      display: flex;
      flex-direction: row;
   }

   .flex > div
   {
      -webkit-flex: 1 1 auto;
      flex: 1 1 auto;

      width: 30px; /* 让过渡表现良好。(从/到"width:auto"的过渡
                      至少在 Gecko 和 Webkit 上是有 bug 的。
                      更多信息参见 http://bugzil.la/731886 ) */

      -webkit-transition: width 0.7s ease-out;
      transition: width 0.7s ease-out;
   }

   /* colors */
   .flex > div:nth-child(1){ background : #009246; }
   .flex > div:nth-child(2){ background : #F1F2F1; }
   .flex > div:nth-child(3){ background : #CE2B37; }

   .flex > div:hover
   {
        width: 200px;
   }
   
   </style>
    
 </head>
 <body>
  <p>Flexbox nuovo</p>
  <div class="flex">
    <div>uno</div>
    <div>due</div>
    <div>tre</div>
  </div>
 </body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • 事实上它是一种新类型的盒子模型,也有书上称作弹性伸缩盒布局。比较新的布局方式:旨在提供一个更加有效的方式来布置,对...
    zh_yang阅读 11,310评论 3 14
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 3,452评论 0 6
  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 4,385评论 0 26
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,722评论 1 92
  • 大昭寺也一票难求了
    冈拉梅朵西行漫记阅读 42评论 0 0