CSS 2.1 定义了四种布局模式 ― 由一个盒与其兄弟、祖先盒的关系决定其尺寸与位置的算法:
块布局 ― 为了呈现文档而设计出来的布局模式
行内布局 ― 为了呈现文本而设计出来的布局模式
表格布局 ― 为了用格子呈现 2D 数据而设计出来的布局模式
定位布局 ― 为了非常直接地定位元素而设计出来的布局模式,定位元素基本与其他元素毫无关系
Css3中引入引入了新的布局模式:弹性布局,是为了呈现复杂的应用与页面而设计出来的。该模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间,可以很轻松的创建自适应浏览器窗口的流动布局或自适应字体大小的弹性布局。
弹性布局解决的问题:
Flexbox 规范时间表:
Flexbox 规范的相关工作已经进展了3年。不同的浏览器也实现了不同的实验版本。在2012年9月,Flexbox 语法的第三个主要修订版本进入到候选推荐阶段。
浏览器支持: (ie和opera支持情况不好,chrome和firefox和safari支持,适合手机端开发)
关于各浏览器中的写法
2009年的语法,已经过时,是需要加上对应前缀的。
2012年的语法,也将是以后标准的语法,大部分浏览器已经实现了无前缀版本
但UC浏览器不支持12年的写法,所以要想完全使用最新写法,还是不现实。
display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */ display: -moz-box; /* Firefox 17- */ display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */ display: -moz-flex; /* Firefox 18+ */ display: -ms-flexbox; /* IE 10 */ display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */
主轴与侧轴的概念
与常说的 X、Y 轴有点像,不过也有点差异。主轴是伸缩布局流向的那个方向的轴,也就是在横排的时候是水平轴,在竖排的时候是垂直轴
实现弹性布局,需要在父容器和子容器中分别设定以下属性
父容器 |
display:-webkit-box |
设定父容器为box |
子容器 |
-webkit-box-flex: |
如未设定此项,默认不会弹性布局 |
实现例子如下,三个子容器的宽度分别为1:2:3
HTML:
<div class="wrap flxBox"> <div class="bgGray flx1">A</div> <div class="bgPink flx2">B</div> <div class="bgBlue flx3">C</div> </div>
css:
.flxBox{display:-webkit-box;} .flx1{-webkit-box-flex:1.0;box-flex:1.0;} .flx2{-webkit-box-flex:2.0;box-flex:2.0;} .flx3{-webkit-box-flex:3.0;box-flex:3.0;} .wrap{width: 100%; height:100px; font:50px/100px microsoft yahei; text-align:center; line-height:100px; color:#666} .bgGray{background: #ccc;} .bgPink{background: #999;} .bgBlue{ background:#444;}
结果:
属性 | 简介 |
box-orient | 设置或检索弹性盒模型对象的子元素的排列方式。 |
box-pack |
设置或检索弹性盒模型对象的子元素的对齐方式。 |
box-align |
设置或检索弹性盒模型对象的子元素的对齐方式。 |
box-flex |
设置或检索弹性盒模型对象的子元素如何分配其剩余空间。 |
box-flex-group |
设置或检索弹性盒模型对象的子元素的所属组。 |
box-ordinal-group |
设置或检索弹性盒模型对象的子元素的显示顺序。 |
box-direction |
设置或检索弹性盒模型对象的子元素的排列顺序是否反转。 |
box-lines |
设置或检索弹性盒模型对象的子元素是否可以换行显示。 |
box-orient:horizontal | vertical
horizontal:设置弹性盒模型对象的子元素为水平排列 (默认值)
vertical:设置弹性盒模型对象的子元素为纵向排列
.flxBox{display:-webkit-box; -webkit-box-orient:vertical;}
box-pack:start | center | end | justify
start:设置弹性盒模型对象的子元素从开始位置对齐(大部分情况等同于左对齐)
center:设置弹性盒模型对象的子元素居中对齐
end:设置弹性盒模型对象的子元素从结束位置对齐(大部分情况等同于右对齐)
justify:设置或弹性盒模型对象的子元素两端对齐
box-align:start | end | center | baseline | stretch
start:设置弹性盒模型对象的子元素从开始位置对齐
center:设置弹性盒模型对象的子元素居中对齐
end:设置弹性盒模型对象的子元素从结束位置对齐
baseline:设置弹性盒模型对象的子元素基线对齐
stretch:设置弹性盒模型对象的子元素自适应父元素尺寸
box-flex:number 使用浮点数指定对象所分配其父元素剩余空间的比例。
box-flex-group:<integer>
用整数值来定义弹性盒模型对象的子元素所在的组。
动态给数值较大的组分配其内容所需的实际空间(如无内容、padding、border则不占空间)
剩余空间则均分给数值最小的那个组(可能有1个或多个元素)
.box li:nth-child(1) { -webkit-box-flex:1; -webkit-box-flex-group:1; background:#ffb000; } .box li:nth-child(2) { -webkit-box-flex:1; -webkit-box-flex-group:1; background:#ffd900; } .box li:nth-child(3) { -webkit-box-flex:1; -webkit-box-flex-group:2; background:#ff7c00; }
效果
box-ordinal-group:<integer>
用整数值来定义弹性盒模型对象的子元素显示顺序。
.box li:nth-child(1) { -webkit-box-ordinal-group:3; background:#ffb000; } .box li:nth-child(2) { background:#ffd900; } .box li:nth-child(3) { background:#ff7c00; }
效果:
box-direction:normal | reverse
normal:设置弹性盒模型对象的子元素按正常顺序排列
reverse:反转弹性盒模型对象的子元素的排列顺序
#box { -webkit-box-direction:normal; } #box2 { -webkit-box-direction:reverse; }
效果
box-lines:single | multiple
single:弹性盒模型对象的子元素只在一行内显示
multiple:弹性盒模型对象的子元素超出父元素的空间时换行显示
父容器 |
display:flex |
设定父容器为flex |
子容器 |
flex: |
如未设定此项,默认不会弹性布局 |
两个版本对应的属性
09属性 | 12属性 |
简介 |
box-orient | flex-direction | 设置或检索弹性盒模型对象的子元素的排列方式。 |
box-pack |
justify-content |
设置或检索弹性盒模型对象的子元素的对齐方式。 |
box-align |
align-items 和 align-self |
设置或检索弹性盒模型对象的子元素的对齐方式。 |
box-flex |
flex: |
设置或检索弹性盒模型对象的子元素如何分配其剩余空间。 |
box-flex-group |
|
设置或检索弹性盒模型对象的子元素的所属组。 |
box-ordinal-group |
order |
设置或检索弹性盒模型对象的子元素的显示顺序。 |
box-direction |
flex-direction |
设置或检索弹性盒模型对象的子元素的排列顺序是否反转。 |
display:flex弹性盒子实现对比(09年和12年的两个版本)
<div class="wrap1 flexBox"> <div class="bgGray flex1">aaa</div> <div class="bgPink flex2">bbbbbbbbbbbbbbbbbbbb</div> <div class="bgBlue flex3">cccccccc</div> </div> <br/><br/> display:box <div class="wrap flxBox"> <div class="bgGray flx1">aaa</div> <div class="bgPink flx2">bbbbbbbbbbbbbbb</div> <div class="bgBlue flx3">cccccccc</div> </div>
.flexBox{display: flex;} .flex1{-webkit-flex:1.0;flex:1.0;} .flex2{-webkit-flex:2.0;flex:2.0;} .flex3{-webkit-flex:3.0;flex:3.0;} .flxBox{display:-webkit-box;display:box;} .flx1{-webkit-box-flex:1.0;box-flex:1.0;} .flx2{-webkit-box-flex:2.0;box-flex:2.0;} .flx3{-webkit-box-flex:3.0;box-flex:3.0;} .wrap{width: 100%;} .bgGray{background: #ccc;} .bgPink{background: #FF7C7C;} .bgBlue{ background:#BDD5E5;}
1. 父容器不限高度,高度随子容器的内容变化,父容器可设置最小高度
2. Display:flex的效果优于display:box
属性 | 属性值 | 初始值 | 适用于 |
---|---|---|---|
align-content
调准伸缩行在伸缩容器里的对齐方式 多行伸缩容器,单行不起作用 |
flex-start 各行向伸缩容器的起点位置堆叠 flex-end 各行向伸缩容器的结束位置堆叠 center 各行向伸缩容器的中间位置堆叠 space-between 各行在伸缩容器中平均分布 space-around 各行在伸缩容器中平均分布,在两边各有一半的空间 stretch 各行将会伸展以占用剩余的空间 |
stretch | multi-line flex containers |
align-items 可以用来设置伸缩容器中包括匿名伸缩项目的所有项目的对齐方式 |
flex-start 伸缩项目在侧轴起点边的外边距紧靠住该行在侧轴起点的边 flex-end伸缩项目在侧轴终点边的外边距靠住该行在侧轴终点的边。 center 伸缩项目的外边距盒在该行的侧轴上居中放置。 baseline如果伸缩项目的行内轴与侧轴为同一条,则该值与「flex-start」等效 stretch 如果侧轴长度属性的值为「auto」, 则此值会使项目的外边距盒的尺寸在遵照「min/max-width/height」 属性的限制下尽可能接近所在行的尺寸 |
stretch | flex containers |
align-self 用来在单独的伸缩项目上覆写默认的对齐方式。 |
auto flex-start flex-end center baseline stretch |
auto | flex items |
flex-basis 指定伸缩基准值 |
<'width'> 0:分配所以空间 auto:分配多余空间 |
auto | flex items |
flex-direction
属性可以用来设定伸缩容器的主轴的方向 这也决定了配置伸缩项目的方向。 |
row 主轴方向,伸缩项目依次序 row-reverse 主轴方向,伸缩项目反次序 column 侧轴方向,伸缩项目依次序 column-reverse侧轴方向,伸缩项目反次序 |
row | flex containers |
flex-flow
伸缩方向与换行的缩写 |
<‘flex-direction’> <‘flex-wrap’> |
see individual properties | flex containers |
flex-grow 属性可以用来设置扩展比率。负值不合法。 |
<number> | 0 | flex items |
flex-shrink 可以用来设置收缩比率。负值不合法 |
<number> | 1 | flex items |
flex
用来指定可伸缩长度的部件: 扩展比率、收缩比率,以及伸缩基准值。 |
none [ <'flex-grow'> <'flex-shrink'>? <'flex-basis'> ] |
see individual properties | flex items |
flex-wrap
控制伸缩容器是单行还是多行 也决定了侧轴方向 ― 新的一行的堆放方向。 |
nowrap 伸缩容器为单行。 wrap 伸缩容器为多行。 wrap-reverse 多行反转 |
nowrap | flex containers |
justify-content
用于在主轴上对齐伸缩项目 这一行为会在所有可伸缩长度及所有自动边距均被解释后进行 |
flex-start 伸缩项目向一行的起始位置靠齐 flex-end 伸缩项目向一行的结束位置靠齐 center 伸缩项目向一行的中间位置靠齐 space-between 伸缩项目会平均地分布在一行里 space-around伸缩项目会平均地分布在行里,两端保留一半的空间 |
flex-start | flex containers |
order 用来改变伸缩项目的顺序 |
<整数> | 0 | flex items and absolutely-positioned flex container children |
属性演示的例子:
属性演示1
属性演示2
达到的效果:
1.ie10以上的版本兼容boxflex,ff,chrome及手机端浏览器支持
2.水平方向宽度自适应
3.dom中按内容,导航,右边栏顺序加载,但表现上顺序不同,如图:
以下是解决方案:
html结构:
<div class="page-wrap"> <section class="main-content"> <h1>Main Content</h1> <p><strong>I'm first in the source order.</strong></p> <p>The key to victory is discipline, and that means a well made bed. You will practice until you can make your bed in your sleep. Fry, we have a crate to deliver. Hey, guess what you're accessories to.</p> </section> <nav class="main-nav"> <h2>Nav</h2> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Clients</a></li> <li><a href="#">Contact Us</a></li> </ul> </nav> <aside class="main-sidebar"> <h2>Sidebar</h2> <p>I am a rather effortless column of equal height.</p> </aside> </div>
.page-wrap { display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (doesn't work very well) */ display: -ms-flexbox; /* TWEENER - IE 10 */ display: -webkit-flex; /* NEW - Chrome */ display: flex; } .main-content { -webkit-box-ordinal-group: 2; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-ordinal-group: 2; /* OLD - Firefox 19- */ -ms-flex-order: 2; /* TWEENER - IE 10 */ -webkit-order: 2; /* NEW - Chrome */ order: 2; /* NEW, Spec - Opera 12.1, Firefox 20+ */ width: 60%; /* No flex here, other cols take up remaining space */ -moz-box-flex: 1; /* Without this, Firefox 19- expands to widest paragraph, overrides width */ background: white; } .main-nav { -webkit-box-ordinal-group: 1; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-ordinal-group: 1; /* OLD - Firefox 19- */ -ms-flex-order: 1; /* TWEENER - IE 10 */ -webkit-order: 1; /* NEW - Chrome */ order: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */ -webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-flex: 1; /* OLD - Firefox 19- */ width: 20%; /* For old syntax, otherwise collapses. */ -webkit-flex: 1; /* Chrome */ -ms-flex: 1; /* IE 10 */ flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */ background: #ccc; } .main-sidebar { -webkit-box-ordinal-group: 3; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-ordinal-group: 3; /* OLD - Firefox 19- */ -ms-flex-order: 3; /* TWEENER - IE 10 */ -webkit-order: 3; /* NEW - Chrome */ order: 3; /* NEW, Spec - Opera 12.1, Firefox 20+ */ -webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-flex: 1; /* Firefox 19- */ width: 20%; /* For OLD syntax, otherwise collapses. */ -ms-flex: 1; /* TWEENER - IE 10 */ -webkit-flex: 1; /* NEW - Chrome */ flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */ background: #ccc; } @media screen and (max-width:600px) { .main-sidebar{ display: none; } }
可以看出,除了ie10使用了中间的版本
display: -ms-flexbox;
其他写法都是09年和12年的写法。因09年的box-flex不会严格按照设定的比例显示,因而使用百分比会比较稳妥。而支持支持12年版本的浏览器会按设定的flex数值的比例来控制。
最后用媒体查询来控制右侧边栏的显隐。
查看完整代码
以上是全部的弹性盒子模型及解决方案,也可能有遗漏的地方,请多提宝贵意见及补充!
参考资料
http://css-tricks.com/old-flexbox-and-new-flexbox/
http://www.w3.org/html/ig/zh/wiki/Css3-flexbox/zh-hans
http://ued.ctrip.com/blog/wp-content/webkitcss/prop/flex-direction.html