http://www.imooc.com/video/6048 [Flexible boxes更加优雅的Web布局]
https://philipwalton.github.io/solved-by-flexbox/ [Solved by Flexbox]
https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex [MDN-flex]
http://www.w3cplus.com/css3/flexboxgeng-jia-you-ya-de-webbu-ju.html [Flexible boxes更加优雅的Web布局]
http://www.w3cplus.com/css3/normalizing-cross-browser-flexbox-bugs.html [解决Flexbox跨浏览器兼容Bug]
第一个视频来自Jaych Su,提到了当要学习一个新东西的时候,从三个方面来思考:功能,兼容,原理;
看了上面这些,来个总结;
一. flex能做什么?
- Better, Simpler Grid Systems :
flex做网格布局,简直不能再方便。 - Holy Grail Layout:
圣杯布局(三栏),常规做法
<div class="layout__main-wrapper">
<div class="layout__main">主内容栏宽度自适应</div>
</div>
<aside class="layout__aside layout__aside--left">左侧边栏宽度固定</aside>
<aside class="layout__aside layout__aside--right">右侧边栏宽度固定</aside>
<footer class="clear">底部</footer>
<style type="text/css">
.clear {
clear: both;
}
.layout__main-wrapper,.layout__aside {
float: left;
}
.layout__main-wrapper {
width: 100%;
}
.layout__main {
margin: 0 210px;
}
.layout__aside {
width: 200px;
}
.layout__aside--left {
margin-left: -100%;
}
.layout__aside--right {
margin-left: -200px;
}
</style>
这种布局的诀窍是:
1)可以没有layout这一层包裹元素;
2)浮动清除需在外部元素上处理;
3)float和margin属性的设置方向相对统一,基本都是一个方向即可;
4)布局四和布局五实现起来,双飞翼布局还需要借助position:relative才行,相对要复杂一点。
flex示例:
http://codepen.io/GitKou/pen/QEjppZ?editors=1100
(https://philipwalton.github.io/solved-by-flexbox/demos/holy-grail/
3. Input Add-ons:
<div class="InputAddOn">
<input class="InputAddOn-field">
<button class="InputAddOn-item">…</button>
</div>
.InputAddOn {
display: flex;
}
.InputAddOn-field {
flex: 1;
/* field styles */
}
.InputAddOn-item {
/* item styles */
}
4.Media Object https://philipwalton.github.io/solved-by-flexbox/demos/media-object/
5.Sticky Footer http://codepen.io/Rocketpilot/pen/f813cf7854371e211758f98de04a5e00
6.Vertical Centering
.Aligner {
display: flex;
align-items: center;
justify-content: center;
}
上面这些难题,用flex简直不能更简单。但是兼容如何?
二. 兼容
(http://www.w3cplus.com/css3/normalizing-cross-browser-flexbox-bugs.html)
有哪些Bugs呢?
Flexbox规范还没有最终确定,所以自然会有一些最新的草案和浏览器实现滞后现象。本文不打算在背后对任何组织进行指指点点,他们的目的是帮助我们做前端开发的人员管理好浏览器的不一致。
下面列出了我在制作Sticky Footer案例时在各个浏览器是碰到的问题清单:
在IE10~11浏览器中,flex项如果设置了最小高度(min-height)将会忽略它们的父容器的高度(height);
Chrome、Opera和Safari浏览器中flex项目没有最小内容的概念;
IE10~11在flex标准中不允许出现不带单位值的flex-basis
下面将本文讨论的Bug和相应的解决方案,总结到一起:在IE10~11浏览器,min-height不适合于flex容器的子元素flex项目。如果可能的话,使用height来替代min-height。
在Chrome,Opear和Safari浏览器不识别flex项目内容的最小尺寸。可以设置flex-shrink的值为0(而不是默认的1),以避免不必要的收缩。
不使用无单位的flex-basis值,因为在IE10~11中,flex简写被忽略。常使用0%来替代0px。
记住所有的缺陷和解决方法,这是我最后想出的替代解决方案。它可能没有最初那样清爽,但它满足我们所有要求的一个解决方案:它可以在所有浏览器中工作 规范的兼容性,错误是有,但可以继续工作 不使用任何浏览器的特定hack
我在CSS中添加了注释,来解决那些解决方法:
/**
* 1. Avoid the IE 10-11 `min-height` bug.
* 2. Set `flex-shrink` to `0` to prevent Chrome, Opera, and Safari from
* letting these items shrink to smaller than their content's default
* minimum size.
*/
.Site {
display: flex;
flex-direction: column;
height: 100vh; /* 1 */
}
.Site-header,
.Site-footer {
flex-shrink: 0; /* 2 */
}
.Site-content {
flex: 1 0 auto; /* 2 */
}
三. 原理
flex-grow和flex-shrink
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