flex-basis
Oh My God,CSS flex-basis原来有这么多细节
为了演示方便,避免无谓的干扰,本文所有的尺寸均指水平尺寸,对应CSS均是宽度相关,例如width
/min-width
/max-width
。
以前的我对flex-basis
不屑一顾,以为就是个浮于表面的CSS属性。
最近深入研究后才发现,自己那是朱砂当红土,珍珠当泥丸,钻石当玻璃,檀木当柴火——完全不识货!
在Flex布局中,一个Flex子项的宽度是由元素自身尺寸,flex-basis
设置的基础尺寸,以及外部填充(flex-grow
)或收缩(flex-shrink
)规则3者共同决定的。
本文只要讨论前两者对尺寸的表现影响,如果您对第3者对尺寸影响有兴趣,则可以参考“CSS flex属性深入理解”这篇文章。
直接进入正题。
一、flex-basis与盒模型
flex-basis
的尺寸是作用在content-box
上的,这个和width
属性是一样的。
例如:
.flex-basis {padding: 1em;border: 1em solid deepskyblue;color: deepskyblue;flex-basis: 100px; }
和
.width {padding: 1em;border: 1em solid deepskyblue;color: deepskyblue;width: 100px; }
在外部尺寸够大,内容尺寸够小的情况下,两者的表现是一样的。
如下图示意:
我们可以通过设置box-sizing
属性改变元素的盒模型,例如。
.flex-basis {padding: 1em;border: 1em solid deepskyblue;color: deepskyblue;flex-basis: 100px;box-sizing: border-box;word-break: break-all; }
此时就可以看到内容展示宽度变小了,外部尺寸表现为100px
:
但是,在IE11浏览器下,box-sizing:border-box
是没有任何效果的。
这个细节知识点还是有点用的,在开发内部系统的PC项目上,例如阅文内部系统,兼容Chrome和Firefox是没问题的,但顶不住老板用IE浏览器,因此,需要兼容到window 7 Edge,也就是IE 11,这个时候,就要避免改变Flex子项的box-sizing
属性值,当然,移动端项目可以不用想那么多。
您可以狠狠地点击这里:flex-basic与盒模型样式表现demo
二、深入理解flex-basis和width的关系
大家一定要搞清楚这样一个事实,在Flex布局中,子项设置width是没有直接效果的。
此时一定会有人反驳,我明明设置了width:100px
就有效果啊!
对是有效果,但并不是width
直接生效的,而是flex-basis
的作用。
深入理解flex-basis:auto
flex-basis
的默认值是auto
,表示自动,也就是完全根据子列表项自身尺寸渲染。
自身尺寸渲染优先级如下:
min-width > || max-width > width > Content Size
同时,在Flex布局中,flex-basis优先级是比width高的(可以理解为覆盖)。
所以,flex-basis
和width
同时设置了具体的数值,则width
属性值直接被打入冷宫,在样式表现上完全被忽略。
例如:
<by-zhangxinxu><item-basis-width>项目1</item-basis-width><item-basis-width>项目2</item-basis-width><item-basis-width>项目3</item-basis-width><item-basis-width>项目4</item-basis-width> </by-zhangxinxu>
CSS如下:
by-zhangxinxu {display: flex; } item-basis-width {padding: 1em;border: 1px solid deepskyblue;color: deepskyblue;box-sizing: border-box;width: 200px;flex-basis: 100px; }
结果width:200px
完全是一个盒饭角色,所谓盒饭角色,就是明明参与了这部电视剧,也吃了剧组的盒饭,但是观众完全就没有意识到他的存在。这里的width
属性就是这种性质,代码中确实出现过,但是样式渲染却完全体现不出来。
如下图所示,宽度表现为100px
。
回到主线这里,实际上,flex-basis
值是auto
的时候,width
属性值也是被打入冷宫的,只是,这个时候,由于后宫放权,所以,冷宫也是有影响力的。什么意思呢?
flex-basis:auto
的含义是,子项的基本尺寸根据其自身的尺寸决定。而这个自身尺寸与下面这几个方面有关:
box-sizing
盒模型(这个已经介绍过了);width
/min-width
/max-width
等CSS属性设置;content
内容(min-content最小宽度);
所以下面两段Flex布局中的CSS就不难理解了:
item-width {width: 100px; }
最终尺寸 = 自身尺寸 mix basis尺寸。
此时,自身尺寸为100px
,basis尺寸按照自身尺寸来算(因为此时属性值是auto
),因此最终尺寸是100px
。
item-basis {flex-basis: 100px; }
最终尺寸 = 自身尺寸 mix basis尺寸。
此时,自身尺寸为content内容最小宽度,basis尺寸100px,因此最终尺寸是:如果content内容最小宽度不超过100px
,则最终尺寸是100px
,否则就是内容最小宽度。
记住上面的解释,我们再看下面几个例子,就会豁然开朗了。
案例1:相同表现
一个元素最小宽度超过100像素场景并不多,因此大部分场景下,flex-basis
和width
表现是一致的。
例如下面这个对比案例:
<h4>1. flex-basis:100px</h4> <by-zhangxinxu><item-basis>项目1</item-basis><item-basis>项目2</item-basis><item-basis>项目3</item-basis><item-basis>项目4</item-basis> </by-zhangxinxu> <h4>2. width:100px</h4> <by-zhangxinxu><item-width>项目1</item-width><item-width>项目2</item-width><item-width>项目3</item-width><item-width>项目4</item-width> </by-zhangxinxu>
一个设置width:100px
,一个设置flex-basis:100px
:
item-width {width: 100px; } item-basis {flex-basis: 100px; }
默认都是100px
的展示,例如我的PC电脑显示器下:
由于默认flex-shrink
属性值是1,因此,容器宽度不足时候的弹性收缩效果也是一样的,如下GIF示意:
眼见为实,您可以狠狠地点击这里:flex-basic与width的异同演示demo
案例2:不同表现
什么时候width:100px
和flex-basis:100px
表现不一样呢?就是最小内容宽度较大的时候,例如出现连续英文单词demo_by_zhangxinxu。
还是上面那个demo页面,点击任意某个子项,会改变元素里面的文字内容为demo_by_zhangxinxu。
此时就可以看到两者的差异了,如下图所示:
因为此时content内容最小宽度超过了100px
,于是flex-basis:100px
按照了最小内容宽度显示了;但是width:100px
把元素的尺寸限制得死死的,字符直接溢出容器之外。
要想两者表现一致,可以使用word-break:break-all
使单词断开。
其实,本文一开始的“flex-basic与盒模型样式表现”这个demo就已经展现了flex-basis
和width
属性的区别了。例如第4项设置的flex-basis
值是100px
,同时box-sizing
是border-box
,但是最终表现出来的尺寸却不是100px
,却是个更大的宽度值,如下图所示:
主要是因为这一项里面的内容,'basis:100px'
会当做一个独立的单词,并作为此时flex-basis
默认就有的最小宽度,这个宽度值等同于min-content
的计算尺寸。
我们可以对比一下隔壁width:100px
的效果,可以看到文字内容'width:100px'
直接溢出到了容器之外。
更深入的案例:最小内容宽度、width和flex-basis同时满足
根据上面的分析(不考虑容器尺寸不足或溢出),我们可以得到结论:
width:100px
+flex-basis:auto
= 元素自身100px- content +
flex-basis:100px
= max(content, flex-basis) = 大于等于100px
再加上flex-basis优先级是比width高的结论,我们就可以得到:
- content +
width:100px
+flex-basis:100px
= content +flex-basis:100px
= max(content, flex-basis) = 大于等于100px
事实究竟是不是这样呢?我们看一个实际的例子。
CSS和HTML代码分别如下,还是使用我最爱的深天空蓝:
by-zhangxinxu {display: flex; } item-zxx {padding: 1em;border: 1em solid deepskyblue;color: deepskyblue;box-sizing: border-box; } item-zxx:nth-child(1) {width: 100px; } item-zxx:nth-child(2) {flex-basis:100px; } item-zxx:nth-child(3) {width: 100px;flex-basis: 100px; }
<by-zhangxinxu><item-zxx>我仅设置了width:100px,没有设置了flex-basis:100px。</item-zxx><item-zxx>我没有设置width:100px,但是设置了flex-basis:100px。</item-zxx><item-zxx>我设置了width:100px,同时设置了flex-basis:100px</item-zxx> </by-zhangxinxu>
如果flex-basis
优先级是比width
高,则第3个子项的width:100px
应该是忽略的,也就是项目2和项目3的渲染表现是一样的。
我们把上面的代码在各个浏览器下跑一下,结果发现出现了尴尬的事情:
在Chrome浏览器下,项目3和项目1表现是一样的,也就是width:100px
依然起到了一些作用。
但是,在Firefox浏览器以及IE Edge浏览器下都是符合预期的项目3和项目2表现一样。
如果想亲自确认一下,您可以狠狠的点击这里:flex-basic与width关系深入研究demo
下面问题来了,到底哪个正确哪个错误呢?
按照历史的经验,大概率Chrome浏览器会在N年之后的什么时候修改这个表现,和Firefox等浏览器一致。
至于谁对谁错啊,这个是没有定论的,规范中估计没有对这个细节进行特别详细的描述。
那给我们的启示是什么东西呢?那很简单,flex-basis数值属性值和width数值属性值不要同时使用,就不会遇到浏览器发现差异的问题。说的更极端一点,在Flex布局中,除非万不得已,否则没有使用width
属性的理由,请使用flex-basis
代替。
三、flex-basis还支持关键字属性值
以前以为flex-basis
只支持数值,最近才发现,flex-basis
还支持一大波关键字属性值,包括:
/* 根据flex子项的内容自动调整大小 */ flex-basis: content;/* 内部尺寸关键字 */ flex-basis: fill; flex-basis: max-content; flex-basis: min-content; flex-basis: fit-content;
但是我要提前先泼一波冷水,目前,在Chrome浏览器下,上面任何一个关键字属性值都不支持。这是很罕见的场景。
其中,flex-basis:content
是Edge 12以及Firefox浏览器支持:
max-content
/min-content
关键字目前仅Firefox浏览器支持。
fill
和fit-content
还没有任何浏览器支持。
由于最重要的Chrome浏览器不支持,因此上面几个关键字案例就不demo演示了,直接文字描述下他们的作用吧。
content
尺寸根据内容决定,跟我自己测试,表现和max-content接近。
max-content
最大内容宽度。
min-content
最小内容宽度。
fill
不详
fit-content
不详
四、flex-basis与min-width/max-width
很多前端在Flex布局的时候会使用min-width
或者max-width
限制列表上的最大尺寸和最小尺寸。
实际上很多时候都是没有必要的,活用flex-basis
属性和flex
属性,可以实现类似的效果。
例如我希望一个列表中的每一项最小宽度是100像素,尽可能填满整个容器,请问该如何实现?
无需使用min-width
属性,可以试试下面的CSS代码:
.container {display: flex;flex-wrap: wrap; } .item {flex-basis: 100px;flex-grow: 1; }
您可以狠狠地点击这里:flex-basic代替min/max-width效果实现demo
实现效果如下GIF示意:
如果希望换行的列表也是等宽的,则需要复制N多空标签即可。
五、最后小结一下
本文内容最后的总结一下:
flex-basis
默认作用在content box上,IE11会忽略box-sizing;width
只是flex-basis
为auto时候间接生效,其余时候使用优先级更高的flex-basis
属性值;- flex子项元素尺寸还与元素内容自身尺寸有关,即使设置了
flex-basis
属性值; flex-basis
数值属性值和width
数值属性值不要同时使用;flex-basis
还支持很多关键字属性,只不过目前兼容性不太好;flex-basis
使用得当可以实现类似min-width
/max-width
的效果。
关于Flex子项最终的尺寸也总结一下:是盒模型,元素自身尺寸特性,以及flex属性共同作用的结果。
flex-basis相关推荐
- Flex Basis与Width的区别
最近在学习Flex Box,其中的Flex Box属性中的Flex Basis是关于项目宽度属性设置的,这让许多初学Flex Box的人困惑它与CSS盒子模型Width属性的区别在哪?Google了一 ...
- flexbox_Flexbox中的Flex基础属性
flexbox 弹性基础 (Flex Basis) The flex-basis property defines the size of the flex-item along the main a ...
- 使用 Flex 布局与其他普通布局的简单对比
最近使用 flex 布局来做各种居中真的带来了不少方便,现在来总结一下平时的普通布局是怎样使用 flex 布局来实现一样的效果. 一.左右 1:1 布局 布局: <div class=" ...
- flex布局中 text-overflow:ellipsis 失效
1 问题描述 HTML: <div id="container"><span class="box"><p>box1< ...
- 10分钟理解CSS3 FlexBox
基本介绍 特点 flexbox是一种css display类型,提供一种更简单高效的布局方式: flexbox可以对元素相对于父元素.兄弟元素进行定位.控制尺寸.控制间距: flexbox对响应式有很 ...
- 微信小程序学习笔记(五)
align-content属性在排列中,如果有多行,那么这个属性是设置多行之间的排列方式.可以通过 align-content 属性来确定排列的方式.可以设置以下值. flex-start :从上往下 ...
- -ms-flexbox_Flexbox中width和flex-basis之间的区别
-ms-flexbox by Kyle Gallagher 凯尔·加拉格尔(Kyle Gallagher) Flexbox中width和flex-basis之间的区别 (The difference ...
- flexbox布局_使用Flexbox制作十二列布局
flexbox布局 演示地址 If there's one thing flexbox excels at, it's twelve-column layouts. In a twelve-colum ...
- flex的三个属性grow、shrink、basis
个人理解 flex-grow:0; 默认值为0,容器中项目没有占满时,不分配剩余空间. flex-shrink:1; 默认值为1,容器中项目超出容器大小时,把项目平均压缩到容器内. flex-basi ...
- HTML中布局flex的标签,CSS3---Flex布局--项目属性
前言 今天学习了项目的属性: [内容] 项目属性: ①沿主轴方向上的排列顺序order: 0(默认值) | ②项目的收缩因子flex-shrink: 1(默认值) | ③项目的扩张因子flex-gro ...
最新文章
- windows下常查看端口占用方法总结
- Acer 4750 安装黑苹果_授人以渔的黑苹果安装教程
- Zabbix+shell监控报警任意web
- IntelliJ IDEA配置maven,并创建一个实例作为演示
- leetcode-114. Flatten Binary Tree to Linked List
- python字典速度能比字典高多少_python – 字典访问速度比较与整数键对字符串键...
- ictclas bug修复
- 吴恩达机器学习作业 6.支持向量机
- IT 从业者要如何在国企「活」下去?
- multiprocessing.manager管理的对象需要加锁吗_iOS内存管理布局及管理方案理论篇
- 【基础】算法的时间复杂度分析
- 大气压力换算公式_压力公式换算
- linux脚本显示时间戳,shell下获取时间戳
- linux apache 查看mpm 配置方式,Apache Prefork、Worker和Event三种MPM详解
- 如何自己搭建一个网盘
- 实用网址(永久更新中)
- MySQL无法启动,服务没有报告任何错误
- 制作思维导图的要点总结
- mysql 启动 错误1053:服务没有及时响应启动或者控制请求
- 大学生必须掌握的计算机软件基础
热门文章
- win10默认浏览器总是自动重置为edge浏览器怎么办?
- USB的端点与管道以及设备、配置、接口、端点
- 【React】Props
- 48MW双馈风电机组并网仿真模型 机端由24台2MW双馈风机构成48MW风电场,出口电压690v,经升压变压器及线路阻抗连接至120kv交流电网
- 卷积神经网络的卷积运算,卷积神经网络里的卷积
- Quantile Quantile Plot----QQ图
- Makerbase VESC 第五课 RC PPM遥控测试
- html 更改视频封面,HTML5视频标签 - 如何设置封面背景大小
- Vue.js常用插件
- 程序员编程面试取胜的8个技巧