Flex很难?一文就足够了
Flexible Box 是什么
布局的传统解决方案,基于盒状模型,依赖 display
属性 + position
属性 + float
属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。所以在2009年,w3c提出了一种可以简洁、快速弹性布局的属性,主要思想是给予容器控制内部元素高度和宽度的能力,这就是今天要说的Flexible Box,弹性布局。
由于浏览器的限制,在写代码之前推荐查询一下兼容模式,了解下目前flex的支持程度,我们可以通过CanIuse这个网站来进行查询,如下图,可以看到,除了对于IE支持一般之外,其他浏览器大多没啥毛病,但为了以防万一,在写代码的时候还是加上-webkit-
这一前缀以防万一。
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
重点!flex一共有两根轴:main axis(主轴)和cross axis(交叉轴),大家一般认为主轴就是水平,交叉轴就是垂直的。但是!这是错误的!请与水平垂直这两个方位的概念区分开,这是一个方位,如果说当年定义的时侯为什么不命名为vertical&horizon??原因就是main axis没有一个固定的方位,所以请不要再通过水平垂直的方位来理解了。那么主轴是怎么区分的呢?其实很简单按照当前flex的方向,是水平排列还是垂直排列。如果是水平排列(row),主轴就是水平的,交叉轴就是垂直的,反之亦然。这是一个很重要的概念。
注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。
属性描述
父容器的属性
flex-direction :该元素决定主轴的方向(即子元素的排列方向) 默认值 :row 适用于 :flex 容器
属性 | 描述 |
---|---|
row | 主轴为水平方向,起点在左端。 |
row-reverse | 主轴为水平方向,起点在右端。 |
column | 主轴为垂直方向,起点在上沿。 |
column-reverse | 主轴为垂直方向,起点在下沿。 |
flex-wrap :设置或检索伸缩盒对象的子元素超出父容器时是否换行 默认值 :nowrap 适用于 :flex 容器
属性 | 描述 |
---|---|
nowrap | 不换行(默认) |
wrap | 换行,第一行在上方 |
wrap-reverse | 换行,第一行在下方 |
PS: flex-flow
属性是 flex-direction
属性和 flex-wrap
属性的简写形式,默认值为 row nowrap
.box {
flex-flow: flex-direction flex-wrap|initial|inherit;
}
justify-content :定义了子元素在主轴上的对齐方式。 默认值 :flex-start 适用于 :flex 容器
属性 | 描述 |
---|---|
flex-start | 左对齐(主轴起点对齐) |
flex-end | 右对齐(主轴终点对齐) |
center | 居中 |
space-between | 两端对齐,项目之间的间隔都相等 |
space-around | 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍 |
align-items :定义了子元素在交叉轴上的对齐方式 默认值 :stretch 适用于 :flex 容器
属性 | 描述 |
---|---|
flex-start | 交叉轴的起点对齐 |
flex-end | 交叉轴的终点对齐 |
center | 交叉轴的中点对齐 |
baseline | 子元素第一行文字的基线对齐,如果子标签内没有内容,将按照每个 div 的底部对齐 |
stretch | 如果项目未设置高度或设为auto,将占满整个容器的高度 |
align-items: stretch 时每个子元素的 height 必须为 auto 否则 height 属性会覆盖 stretch 的效果
如果 div 内没有内容,或者子标签内没有内容,将按照每个 div 的底部对齐
align-content :定义多根轴线的对齐方式,如果子元素只有一根轴线,该属性不起作用 默认值 :stretch 适用于 :多行的弹性盒模型容器
属性 | 描述 |
---|---|
flex-start | 与交叉轴的起点对齐 |
flex-end | 与交叉轴的终点对齐 |
center | 与交叉轴的中点对齐 |
space-between | 与交叉轴两端对齐,轴线之间的间隔平均分布 |
space-around | 每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍 |
stretch | 轴线占满整个交叉轴 |
PS: 在上面的例子 flex-wrap 需设为 wrap, 且数量超出一行, 父容器的高度相对于子容器有多余,才能看到效果
子元素的属性
order :定义子元素的排列顺序,数值越小,排列越靠前 默认值:0 适用于:flex子项和flex容器中的绝对定位子元素
PS:用整数值来定义排列顺序,数值小的排在前面。元素的值可以为负值
flex-grow :定义子元素的放大比例 默认值 :0 适用于 :flex子项
<ul class="flex">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
.flex{display:flex;width:600px;margin:0;padding:0;list-style:none;}
.flex li {text-align:center;height:100px;}
.flex li:nth-child(1){width:200px;background-color:green;}
.flex li:nth-child(2){flex-grow:1;width:50px;background-color:yellow;}
.flex li:nth-child(3){flex-grow:3;width:50px;background-color:red;}
flex-grow的默认值为0,如果没有显示定义该属性,是不会拥有分配剩余空间权利的。
本例中b,c两项都显式的定义了flex-grow,flex容器的剩余空间分成了4份,其中b占1份,c占3分,即1:3
flex容器的剩余空间长度为:600-200-50-50=300px,所以最终a,b,c的长度分别为:
a: 200px
b: 50+(300/4*1)=125px
c: 50+(300/4*3)=275px
flex-shrink :定义子元素的收缩比例(与flex-grow相反) 默认值 :1 适用于 :flex子项
<ul class="flex">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
.flex{display:-webkit-flex;display:flex;width:400px;margin:0;padding:0;list-style:none;}
.flex li{width:200px;}
.flex li:nth-child(1){background:#888;}
.flex li:nth-child(2){background:#ccc;}
.flex li:nth-child(3){-webkit-flex-shrink:3;flex-shrink:3;background:#aaa;}
flex-shrink的默认值为1,如果没有显示定义该属性,将会自动按照默认值1在所有因子相加之后计算比率来进行空间收缩。
本例中c显式的定义了flex-shrink,a,b没有显式定义,但将根据默认值1来计算,可以看到总共将剩余空间分成了5份,其中a占1份,b占1份,c占3分,即1:1:3
我们可以看到父容器定义为400px,子项被定义为200px,相加之后即为600px,超出父容器200px。那么这么超出的200px需要被a,b,c消化
通过收缩因子,所以加权综合可得200*1+200*1+200*3=1000px;
于是我们可以计算a,b,c将被移除的溢出量是多少:
a被移除溢出量:(200*1/1000)*200,即约等于40px
b被移除溢出量:(200*1/1000)*200,即约等于40px
c被移除溢出量:(200*3/1000)*200,即约等于120px
最后a,b,c的实际宽度分别为:200-40=160px, 200-40=160px, 200-120=80px
PS:如果所有项目的 flex-shrink 属性都为 1,当空间不足时,都将等比例缩小。如果一个项目的 flex-shrink 属性为0,其他项目都为 1,则空间不足时,前者不缩小。负值对该属性无效。
flex-basis :设置或检索弹性盒伸缩基准值 默认值 :auto 适用于 :flex子项
flex-basis 控制元素的默认尺寸,然后再由其他 Flexbox 属性控制,可以覆盖 width 属性
flex-basis 可以和 width(主轴为水平状态)或者height(主轴为垂直状态) 属性互换
PS:flex-basis 是通过主轴 (main axis) 来影响元素尺寸的
align-self:允许单个子元素有与其他项目不一样的对齐方式,可覆盖align-items属性 默认值 :auto 适用于 :flex子项
属性 | 描述 |
---|---|
auto | 继承父元素的"align-items"值,如果其没有父元素,等同于"stretch" |
flex-start | 交叉轴的起点对齐 |
flex-end | 交叉轴的终点对齐 |
center | 交叉轴的中点对齐 |
baseline | 第一行文字的基线对齐 |
stretch | 如果项目未设置高度或设为auto,将占满整个容器的高度 |
父元素: align-items:flex-end
a: align-self: flex-end
b: align-self: center
c: align-self: flex-start
d: align-self: baseline; padding: 20px 10px
e: align-self: baseline
f: align-self: stretch
g: align-self: auto
参考
- CSS参考手册
- Flex 布局教程-阮一峰
- Even more about how Flexbox works — explained in big, colorful, animated gifs
- How Flexbox works — explained with big, colorful, animated gifs
Flex很难?一文就足够了的更多相关文章
- Scala很难!
Scala很难! 本文是从 Yes, Virginia, Scala is hard 这篇文章翻译而来. 首先要说的是,我是一个Scala粉丝,我作为一个Scala语言的倡导者差不多有5年历史了.我写 ...
- [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office
打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...
- 转:Eric Lippert:阅读代码真的很难
转自:http://blog.jobbole.com/438/ 相关文章 微软资深软件工程师:阅读代码真的很难(第2篇) 阅读优秀代码是提高开发人员修为的一种捷径 学会阅读源代码 如何阅读大型代码库? ...
- 函数式编程很难,这正是你要学习它的原因 | 外刊IT评论网
函数式编程很难,这正是你要学习它的原因 | 外刊IT评论网 函数式编程很难,这正是你要学习它的原因 156 次分享 新浪微博 腾讯微博 Tweet 人人网 QQ空间 很奇怪不是,很少有人每天都使用函数 ...
- UI培训就业会很难吗
众所周知UI是研究人机交互的学科,他是从互联网发展而来的,单从目前它的应用领域来看,主要应用于软件.互联网.移动智能设备.游戏和虚拟现实影音方面.这些都是新兴的热门方向和活跃领域.目前人才缺口和社会需 ...
- 最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备
在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间.我的标准其实不复杂:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架,我相信其它公司招初级开发时,应该也照着这个标准来面 ...
- No bean named 'xxxxx' is defined异常,已解决,这个坑很难发现,你get了吗
出现No bean named 'xxxxx' is defined异常 没有定义名为xxx的bean 如果你的代码写的都对,根本问题只有一个地方出错了,那就是你的 basePackage=的包名路径 ...
- js混淆加密,通过混淆Js代码让别人(很难)无法还原
js混淆加密,通过混淆Js代码让别人(很难)无法还原 使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密 ...
- 关于UIScrollView有些你很难知晓的崩溃情形
关于UIScrollView有些你很难知晓的崩溃情形 为了实现以下的功能(按钮之间的切换效果): 简短的代码如下: // // RootViewController.m // BUG // // Co ...
随机推荐
- Java开源生鲜电商平台-支付模块的设计与架构(源码可下载)
Java开源生鲜电商平台-支付模块的设计与架构(源码可下载) 开源生鲜电商平台支付目前支持支付宝与微信.针对的是APP端(android or IOS) 1. 数据库表设计. 说明:无论是支付宝还 ...
- Python_eval()
''' eval()用来把任意字符串转化为Python表达式并进行求值 ''' print(eval('3+4')) #计算表达式的值 a=3 b=4 print(eval('a+b')) #这时候要 ...
- ThreadPoolExcuter源码解析(一)
1.ThreadPoolExcuter原理说明 首先我们要知道为什么要使用ThreadPoolExcuter,具体可以看看文档中的说明: 线程池可以解决两个不同问题:由于减少了每个任务的调用开销,在执 ...
- webpack4:连奏中的进化
webpack4在2月底的时候发布,这次webpack4有了一个名字"Legato",也就是"连奏"的意思,寓意webpack在不断进化,而且是无缝(no-ga ...
- PAT1132: Cut Integer
1132. Cut Integer (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Cutting a ...
- Redis的九大应用场景
毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象 ...
- RecyclerView android
RecyclerView是用来替代ListView.GridView的一个牛掰的控件.用起来更灵活,还能实现线性布局(横向.纵向).网格布局.瀑布流等美观的UI. 在使用RecyclerView时候, ...
- 《Redis入门指南》第2版 读书笔记
读第二遍了,感觉和几年前读时的收获不一样了.送上门来当树洞的独自承担一切 Redis以简洁为美Redis通信协议是Redis客户端与Redis之间交流的语言,通信协议规定了命令和返回值的格式.Redi ...
- LaTeX 中图片格式错误情况
Unknown graphics extension: .eps 利用宏包usepackage {graphicx} 是图片和pdflatex一起用时的错误.注:{不是所有的时候,有时候也能通过} 两 ...
- java正则使用方法
import java.util.regex.Matcher;import java.util.regex.Pattern; public class RegexMatches{ public ...