如果你不是从一个Android转过来写前端的,你不知道安卓程序员对html中弹性布局有多么钟爱。我使用它,最多的场景,是他可以当成安卓布局中LinearLayout + weight的方式,按照比例,使得子元素,按照比例,分配父布局横向和纵向上(其他非使用权重控件占用后剩余的)的空间。
作为最常见的“盒子”元素“div”来说,当你指定了他display:flex
,就意味着,你可以在水平方向上,通过指定子元素flex:n
的形式,使得某个子元素的宽度,占整个父元素宽度的每个子元素n之和的分之n。
例如:父元素宽度360px,他有两个子元素,一个flex:1
另外一个flex:2
,那么,第一个元素的宽度,就是120px,第二个元素宽度是240px。关于flex布局详细使用规则,参见写的比较全面
我一直都是这么用的,然而,在最近的一次实践中,观察到了在弹性盒子嵌套 + 超长文字不折行且省略号展示时,弹性盒子的权重约束被破坏的现象。
文字超长+不折行+省略号展示css:
.single-line-ellipsis{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
当flex没有嵌套时,single-line-ellipsis没有破坏弹性盒子的权重约束:
而当在弹性盒子嵌套,且文字超长时,弹性盒子的约束被破坏殆尽。(嵌套时,两个布局的结构完全一致,只是文字超长时,加了single-line-ellipsis单行)
个人感觉,这更像是内核一个渲染bug,解决办法是,给蓝色文字超长布局的max-length属性设置一个合适的值。
下面是实例代码,感兴趣的可以自己跑一跑,谷歌和火狐都是如此,调试模式是手机时,最为明显。
css
.clean-label {
background-color: burlywood;
display: block;
font-size: 20px;
width: 100%;
color: aqua;
}
.height-appointed {
background-color: chartreuse;
display: block;
font-size: 20px;
width: 100%;
height: 30px;
color: darkorange;
}
.single-line-ellipsis{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.flex-container{
display: flex;
height: 90px;
background-color: aqua;
}
.fragment-left{
flex: 1;
background-color: cadetblue;
margin: 4px;
}
.fragment-right{
display: flex;
flex-direction: column;
flex: 2;
display: flex;
background-color: violet;
margin: 4px;
}
.item-container{
display: flex;
flex: 1;
border: 1px solid black;
}
.item-left{
flex: 1;
background-color: khaki;
margin-right: 4px;
}
.item-right{
flex: 2;
background-color: blue;
}
.block{
display: block;
}
html
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
<title>
Prod
</title>
<link rel="stylesheet" type="text/css" href="./index.css">
<body>
<!-- span 如果没有指定高度,其高度会根据内容多少,自增长;如果指定了高度,但是高度不足以渲染内容,起会over fellow -->
<label class="clean-label">
如果没有指定高度,其高度会根据内容多少,自增长;
</label>
<label class="height-appointed">
如果指定了高度,但是高度不足以渲染内容,起会over fellow
</label>
<label class="clean-label" style="color: blueviolet;background-color: aquamarine;">
Over fellow的部分,会和下面的元素重合。
</label>
<label class="clean-label single-line-ellipsis">
内容超长,不指定高度,但是指定单行,超出部分省略号展示;
</label>
<h2>弹性盒子权重布局</h2>
<h4>弹性盒子非嵌套时</h4>
<label>正常的文字长度</label>
<div class="flex-container" style="height: 30px;">
<div class="fragment-left"></div>
<label class="item-right block" style="color: yellow;margin: 4px;">正常的文字长度</label>
</div>
<label>超长的的文字长度,单行省略,不能破坏布局的约束效果;
如果不加单行省略,则会overflow</label>
<div class="flex-container" style="height: 30px;">
<div class="fragment-left"></div>
<label class="item-right block single-line-ellipsis" style="color: yellow;margin: 4px;">超长的的文字长度,单行省略,不能破坏布局的约束效果;
如果不加单行省略,则会overflow</label>
</div>
<h4>弹性盒子嵌套时</h4>
<label>正常的文字长度</label>
<div class="flex-container">
<div class="fragment-left"></div>
<div class="fragment-right">
<div class="item-container">
<label class="item-left block"></label>
<label class="item-right block" style="color: yellow;">正常文字长度</label>
</div>
<div class="item-container"></div>
<div class="item-container">
<label class="item-left block"></label>
<label class="item-right block" style="color: yellow;"></label>
</div>
</div>
</div>
<label>当文字超长,且加上单行省略时,布局约束效果被破坏</label>
<div class="flex-container">
<div class="fragment-left"></div>
<div class="fragment-right">
<div class="item-container">
<label class="item-left block"></label>
<label class="item-right block" style="color: yellow;">正常文字长度</label>
</div>
<div class="item-container"></div>
<div class="item-container">
<label class="item-left block"></label>
<label class="item-right block single-line-ellipsis" style="color: yellow;">当文字超长,且加上单行省略时,布局约束效果被破坏</label>
</div>
</div>
</div>
</body>
</html>