传统的布局方案基于盒状模型,依赖 display属性 + position属性 + float属性。这大部分需要确定出元素的高宽,而且它对于那些特殊布局非常不方便,为了适应不同屏幕的设备,还得用更多的代码做媒体查询。
对于垂直居中也不容易实现。用flex布局刚好可以解决这些问题,flex布局能让容器在适应各种显示设备和屏幕大小时,可改变子元素的高宽以填满可用空间,防止溢出或收缩;可解决大小未知或动态的项目的对齐和分布。
浏览器的兼容性
Firefox | IE | Chrome | Opera | Safari | Android | IOS |
---|---|---|---|---|---|---|
22+ | 10+ | 21+ | 12.1+ | 6.1+ | 4.4+ | 7.1+ |
Flex布局常用属性:
display: flex用于父容器,若是行内元素可用:display: inline-flex
1.容器的属性:
justify-content :定义项目在主轴上的对齐方式
justify-content: flex-start(默认) | flex-end | center | space-between | space-around;align-items :定义项目在交叉轴上的对齐方式
align-items: flex-start | flex-end | center | baseline | stretch(默认);
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。align-content :多根轴线的对齐方式,如果项目只有一根轴线,则该属性不起作用
align-content: flex-start | flex-end | center | space-between | space-around | stretch;flex-direction :决定主轴的方向
flex-direction: row(默认) | row-reverse | column | column-reverse;flex-wrap :如果一条轴线排不下时可换行否
flex-wrap: nowrap(默认) | wrap | wrap-reverse;flex-flow :flex-direction和flex-wrap的合并属性,默认值为row nowrap
flex-flow: [flex-direction] || [flex-wrap];
2.项目的属性:
- order:项目的排列顺序,数值越小越靠前,默认为0,可为负数
- flex-grow :项目放大比例,默认为0,即如果存在剩余空间也不放大。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
- flex-shrink :属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
- flex-basis :属性定义了在分配多余空间之前,项目占据的主轴空间(main
size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。可设置为固定大小(比如350px) - flex :flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
- align-self :允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
align-self: auto | flex-start | flex-end | center | baseline | stretch;
demo
1.垂直居中
- 不知子元素高宽的情况下
- 方法一:用align-items
.parent{
display: flex;
height: 300px;
align-items: center;
}
- 方法二:改变主轴的方向,用justify-content
.parent{
display: flex;
height: 300px;
flex-direction: column;
justify-content: center;
}
知道子元素高宽的情况下,可轻松实现水平垂直居中
.parent{
display: flex;
height: 300px;
background-color: deepskyblue;
}
.child{
width: 100px;
height: 100px;
margin: auto;
}
在不知子元素高宽中的两种方法其实是一个概念,重要的是.parent要有高度。在我的下一遍博客中会详细总结元素居中方法。
2.响应式导航栏
随着屏幕大小的改变自适应的导航,比bootstrap更灵活
html部分:
<ul class="parent">
<li class="child"><a href="#">Home</a></li>
<li class="child"><a href="#">About</a></li>
<li class="child"><a href="#">Products</a></li>
<li class="child"><a href="#">Contact</a></li>
</ul>
CSS部分:
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
.parent{
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
background-color: deepskyblue;
}
.child a{
text-decoration: none;
display: block;
padding: 1em;
color: white;
}
.child a:hover{
background-color: #00b7f5;
}
@media all and (max-width: 800px) {
.parent {
justify-content: space-around;
}
}
@media all and (max-width: 600px) {
.parent {
-webkit-flex-flow: column wrap;
flex-flow: column wrap;
padding: 0;
}
.child a{
text-align: center;
padding: 10px;
border-top: 1px solid rgba(255,255,255,0.3);
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.child:last-child a{
border-bottom: none;
}
}
宽度大于800px的效果图:
宽度介于600px到800px之间的导航条:
宽度小于600px的导航条:
3.响应式页面布局
html部分:
<div class="wrapper">
<header class="header">Header</header>
<article class="main">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</article>
<aside class="aside aside-1">Aside 1</aside>
<aside class="aside aside-2">Aside 2</aside>
<footer class="footer">Footer</footer>
</div>
CSS部分:
*{margin: 0;padding: 0;}
.wrapper {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.header {background: tomato;}
.footer {background: lightgreen;}
.main {text-align: left;background: deepskyblue;}
.aside-1 {background: gold;}
.aside-2 {background: hotpink;}
@media all and (min-width: 600px) {
.aside { flex: 1 auto; }
}
@media all and (min-width: 800px) {
.main { flex: 3 0; }
.aside-1 { order: 1; }
.main { order: 2; }
.aside-2 { order: 3; }
.footer { order: 4; }
}
宽度大于800px的效果图:
宽度介于600px到800px之间的布局图:
宽度小于600px的布局:
搜集资料来源:
CSS TRICKS: A Complete Guide to Flexbox
阮一峰的网络日志 > Flex 布局教程:语法篇
特别感谢!