前言我也不知道怎么写,那废话就很少说了,反正flex布局不考虑兼容性的话用处仍是挺多的,我的感受也是挺神奇挺好用的。在平时的工做中,flex发挥了很是大的做用,今天就来总结一下吧。css
这里只介绍我经常使用的flex属性,有不足的地方欢迎指正(如下状况默认都是在浏览器的默认属性基础上进行介绍)html
display: flex;
复制代码
这个想必你们都很是熟悉了,我也就很少说了。浏览器
flex-direction: row; // 浏览器默认布局方式,在同一行内进行排列(flex-wrap: nowrap的状况下)
flex-direction: column; // 在同一列内进行排列,相似于常规的一行一行的排列
复制代码
至于row-reverse
和 column-reverse
就不说了,感受应用场景很少。bash
这里就须要认识一下主轴(main axis)和交叉轴(cross axis)。app
简单地说主轴就是排列方向,交叉轴和排列方向相垂直。布局
具体地说:flex-direction: row;
时,主轴是指水平方向,交叉轴是垂直方向。flex-direction: column;
时,主轴是指垂直方向,交叉轴是水平方向。flex
用图来表示的话就是:网站
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
复制代码
align-items: flex-start | flex-end | center | baseline | stretch;
复制代码
flex-wrap: nowrap;(未设置时默认就是nowrap)
,将占满整个容器的高度(row)/宽度(column)交叉轴和主轴不同,可没有什么两端对齐,因此可千万别混淆了。spa
单行时使用 align-items, 多行时使用align-content, 这两种都是使用于display: flex
的元素,而align-self能够单独设置子元素的交叉轴对齐方式。3d
flex-wrap: nowrap | wrap | wrap-reverse;
复制代码
当使用nowrap时,当子元素的宽度之和超过父元素的宽度时并不会换行,而是尽可能压缩自身以保障不超过父元素的宽度,因此有时候你会发现flex内的子元素宽度跟你想象的不同就是这个缘由形成的。
至于宽度究竟是怎么计算的嘛,说来仍是有点复杂的。理论上, 当子元素的宽度之和超过父元素的宽度时,子元素的宽度 = 子元素所设置的宽度 / 子元素之和 父元素的宽度。
假设父元素是100px,子元素A是100px,B是400px,C元素是500px,那么理论上子元素之和为1000px,A = 100 / 1000 * 100 = 10px,B = 400 / 1000 * 100 = 40px, C = 500 / 1000 * 100 = 50px。
固然了,这只是理论上的理想状况。实际上,能不能按照理论分配,还得看子元素内的实际宽度,什么是实际宽度呢?就是它里面的内容所占的宽度,假设A里面的文字有3个,占用了25px,那么它的最终宽度就是25px,而不是所分配的10px,B和C也会相应的减小。
使用wrap的话就不会存在这个问题了,在必定程度上能够替代以前的inline-block和float的布局方式。
flex: 1;
/* 其实就至关于 flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */
复制代码
这个属性的做用就是将剩余宽度按照比例分配给该子元素。经常使用于两栏布局,一侧定宽,另外一侧设置flex: 1;
便可得到剩余宽度。
order: 1; /* 任意正整数 */
复制代码
这个东西但是很神奇的了,不须要改变html的结构,直接改变显示的顺序,好比常见的列表介绍,第一行左图右文字,第二行左文字右图。
还有一种应用场景就是聊天界面了,这个稍后会讲到。
总算是讲完基础部分,接下来终于能够进入今天的正题了。
这个应该是最常遇到的布局方式了吧,主要分为单行居中,多行居中。
其实这里还分为只有一行的元素水平居中和多行中的某一行水平居中两种状况,暂时只介绍第一种状况,下一段再介绍后一种状况。
<div class="flex-center" style="background: red;color: #fff;padding: 20px 0;">
单行水平居中
</div>
复制代码
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
复制代码
排列方向为row的状况设置主轴对齐方式为center便可,没什么好说的。
flex-wrap: wrap
后,
align-content: center
是将全部的子元素组合成一个总体后垂直居中,而
align-content: center
则是将剩余部分的空白平均分配给子元素的上下两侧。
因此这种换行后的多行垂直居中推荐你们使用align-content。
<div class="attr-title">align-content: center</div>
<div class="flex box" style="align-content: center;">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
<div class="attr-title">align-items: center</div>
<div class="flex box" style="align-items: center;">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
复制代码
.flex {
display: flex;
flex-direction: row;
}
.red {
background: red;
width: 50%;
height: 30px;
}
.green {
background: green;
height: 40px;
width: 100%;
}
.blue {
background: blue;
width: 100%;
}
.attr-title {
margin-top: 24px;
margin-bottom: 12px;
}
.box {
border: 5px solid #ccc;
flex-wrap: wrap;
height: 200px;
}
复制代码
代码以下:
<div class="attr-title">flex-direction: column 垂直居中</div>
<div class="flex-center column border">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
复制代码
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.border {
border: 5px solid #ccc;
height: 200px;
}
复制代码
多行垂直居中的话,相比较上面换行的那种,仍是推荐你们使用column这种方式。毕竟代码简洁,更好理解。还有很重要的一点就是能够更灵活的控制子元素在水平方向的对齐方式,在文章的排版中应该会比较常见。
可能有的人会说这种排版使用text-align
也能办到。确实也能够,可是text-align
只能做用于块级元素,而flex布局则没有这个局限性。
<div class="flex column">
<h2 class="title self-center">黑洞的发现</h2>
<div class="flex between">
<div class="author">某网站</div>
<time class="time self-end">发布时间:2019-04-12</time>
</div>
<article class="article">
<p>正文中打撒打撒打撒多撒正文中打撒打撒打撒多撒正文中打撒打撒打撒多撒</p>
</article>
</div>
复制代码
.flex {
display: flex;
flex-direction: row;
}
.column {
flex-direction: column;
}
.between {
justify-content: space-between;
}
.self-center {
align-self: center;
}
.self-end {
align-self: flex-end;
}
.author {
font-size: 14px;
color: #666;
}
.time {
color: #999;
font-size: 12px;
}
.article p {
text-indent: 2em;
line-height: 1.6;
}
复制代码
这个应用场景也挺多的,好比左侧是标题,右侧是更多>>。原理也很简单,就是
.flex {
display: flex;
flex-direction: row;
}
.between {
justify-content: space-between;
}
复制代码
在须要两端对齐的时候,只须要在父元素加上这两个类名就能够了。效果图就不上了,上方文章排版的那个就用到了。
这里只举例最简单的两栏布局,其余的相似,本身推导便可。
在应用flex之后,左侧定宽,右侧flex: 1;
便可得到剩余宽度。
<div class="flex">
<div class="red">red</div>
<div class="green">grren</div>
</div>
复制代码
.flex {
display: flex;
flex-direction: row;
}
.red {
width: 100px;
background: red;
height: 36px;
}
.green {
flex: 1;
background: green;
}
复制代码
不知道你们有没有发现,上图中我只设置了red的高度,可是green的高度竟然和red的一致!平时的布局中不是只有文字的高度吗?
其实这就是上文所说的自动填充高度了,align-items: stretch
会将未主动设置高度的子元素拉伸至与高度最高的子元素相同。align-items的默认值就是stretch,因此若是不须要自动填充高度,你须要设置align-items为flex-start,flex-end,center等其余的值。
有了order之后,就能够在不改变html结构的状况下,经过改变order的数值来改变子元素的显示顺序。
分析一下这个布局,其实也就是两栏布局,而后文字部分垂直居中,前面都介绍过了,因此实现起来是很简单的。
代码以下:
<ul class="list">
<li class="flex item even">
<img src="https://taidaxin.oss-cn-qingdao.aliyuncs.com/1.jpg" alt="" class="img">
<div class="content flex-center column">
<div class="p">介绍</div>
<div class="p">flex布局</div>
</div>
</li>
<li class="flex item odd">
<img src="https://taidaxin.oss-cn-qingdao.aliyuncs.com/1.jpg" alt="" class="img">
<div class="content flex-center column">
<div class="p">介绍</div>
<div class="p">flex布局</div>
</div>
</li>
</ul>
复制代码
.flex {
display: flex;
flex-direction: row;
}
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.list {
padding: 20px;
background: #F5F5F5;
}
.img {
width: 94px;
height: 94px;
}
.item+.item {
margin-top: 20px;
}
.content {
padding-left: 20px;
background: #fff;
font-size: 12px;
flex: 1;
}
.even .img,
.odd .content {
order: 1;
}
.even .content,
.odd .img {
order: 2;
}
复制代码
flex: 1;
,上下两端对齐,靠右对齐,那么能够采用使用column的布局方式,主轴两端对齐,交叉轴对齐于结尾处,表现为justify-content: space-between;align-items: flex-end;
代码以下:
<div class="container">
<div class="card">
<img src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png" alt="" class="card-img">
<div class="card-body flex">
<div class="card-body--left">
<div class="title">标题</div>
<div class="text">发布者:谁知道</div>
<time class="time">栏目:天知道</time>
</div>
<div class="card-body--right flex column between">
<div class="share flex align-center">
<img src="http://uppic.fd.zol-img.com.cn/t_s501x2000/g5/M00/0D/0D/ChMkJ1ibsVeIeZ0QAACr6Uwo-6EAAZzpgMdtPAAAKwB105.jpg" alt="" class="share-icon">
<div class="share-text">分享</div>
</div>
<time class="time">发布时间: 2019-01-02</time>
</div>
</div>
</div>
</div>
复制代码
.flex {
display: flex;
flex-direction: row;
}
.between {
justify-content: space-between;
}
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.container {
background: #F5F5F5;
padding: 32px;
}
.card {
width: 320px;
margin: 20px auto;
}
.card-img {
width: 100%;
}
.card-body {
padding: 20px;
background: #fff;
}
.title {
font-size: 16px;
color: #333;
}
.text {
font-size: 14px;
color: #666;
padding: 8px 0;
}
.card-body--right {
flex: 1;
align-items: flex-end;
}
.time {
font-size: 12px;
color: #999;
}
.share {
align-items: center;
}
.share-icon {
width: 40px;
height: 40px;
}
复制代码
简单的分析一下布局,一个别人发的,一个本身发的,也就靠左和靠右对齐的区别而已。
从正常的布局来看,先是头像,而后是一个三角形的箭头(用border便可),再而后就是对话内容了。 反方向的话,就是控制一下这三个部分的order而已,还有就是外边距的方向也得反一下。
跟以前的东西相比没有什么新鲜的,我就不贴代码了,要否则就太多了,固然了有须要的话能够留言,我能够放在评论区。
平时布局的话,你们仍是要注意多总结,先思考怎么布局更简单,而后再着手写代码,这样能够省下不少时间的。flex在一维布局确实是很强大的,基本上能够解决平时遇到的各类问题。grid在二维布局方面相对而言更好用,都怪这**的兼容性问题,要否则咱们就有更多更好的方式能够选择了。
那么今天就先说到这里吧(虽然大部分都是代码),若是你们还有什么疑问或者指导性建议的话,欢迎评论。