从小红书来做弹性盒和flex文本溢出问题
有个同学在浏览小红书页面的时候看到一个案例觉得很不错,于是就想结合弹性盒的内容做下练习。结果就出现了一个关于flex文本溢出的问题,事后我觉得这个问题还挺有意思的,就想和大家分享分享。
案例
同学在练习的时候,想把右侧的正文部分设置为超出第3行显示为省略号。
问题
以简单的html和css为例
<style>
* {
margin: 0;
padding: 0;
}
.content {
/* 触发弹性盒 */
display: flex;
width: 940px;
height: 198px;
margin: 20px auto;
background-color: #ddd;
}
.left {
width: 310px;
height: 198px;
background: skyblue;
}
.right {
padding: 20px 30px 0 20px;
box-sizing: border-box;
/* 右边的flex取值为auto */
flex: auto;
height: 189px;
}
.right h2{
margin-bottom: 20px;
}
.text {
color: #666;
font-size: 14px;
/*文本内容超出3行之后显示为省略号*/
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:3;
overflow: hidden;
text-overflow: ellipsis;
}
img{
width: 100%;
height: 100%;
}
</style>
<div class="content">
<div class="left">
<img src="../img/logo.png" alt="">
</div>
<div class="right">
<h2>小红书联合中国扶贫基金会、真爱梦想基金会支持河南重建</h2>
<p class="text">
8月20日,小红书公布了向河南灾区捐款的最新进展。其中捐赠给中国扶贫基金会的600万元,用于支持灾后重建修复工作,帮助当地民众的生活早日恢复;向上海真爱梦想公益基金会捐赠的400万元,用于支持河南地区儿童安全及美育教育,助力更多灾区小朋友的梦想成真。目前两家基金会正在积极推动援助项目的落地实施。在河南暴雨灾害发生后,小红书第一时间启动向灾区捐款,根据多方建议,捐款用途重点投向灾后重建。与此同时,小红书紧急上线了多项服务与当地用户需求的站内内容,组织提供紧急救助通道、自救指南、志愿商家等多维度的内容。
</p>
</div>
</div>
<div class="content" style="background: plum">
<div class="left">
正常的盒子width: 310px;height: 198px;
</div>
</div>
上面是一个flex容器,包括着两个项目,左侧项目包含一张图片,已将其宽度设置为100%。右边的项目中我们希望的应该是正常展示,且文本超出3行之后显示省略号。但结果取与我们的想象差距很大。页面展示如下,左侧项目被压缩,且右侧内容出现了拉伸。
那么,我们该如何解决怎么这个问题呢?
解决方法
方法有三,如下
- 右侧盒子设置 flex:1;
- 给右侧盒子设置 width:0;
- 给左侧的盒子设置flex-shrink:0;
方法一 flex:1
第一种,首先看下flex属性
<!-- 缩写 -->
flex: auto;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
<!--默认值为-->
flex: 0 1 auto;
其中
- flex-grow:指的是放大比例
- flex-shrink:指的是缩小比例
- flex-basis:作用于子元素的主轴上的宽度属性,其优先级别高于默认的宽/高。 这个属性决定CSS如何给可伸缩项在容器中分配初始大小.
在本案例中,flex: auto是flex: 1 1 auto的缩写。
flex-basis
定义了该元素的空间大小(the size of that item in terms of the space ) ,flex 容器里除了元素所占的空间以外的富余空间就是可用空间 available space。 该属性的默认值是 auto
。此时,浏览器会检测这个元素是否具有确定的尺寸。如果没有给元素设定尺寸,flex-basis
的值采用元素内容的尺寸。
继续看下面:
.item {
flex: 1;
}
.item {
flex-grow:1;
flex-shrink:1;
flex-basis: 0%;
}
这里的flex:1;等同于flex:1 1 0%;
需要注意的是:flex-basis的值有 content
| <width>
flex-basis: 会检索项目的width 或 height 值作为 flex-basis 的值。如果 width 或 height 值为 auto
,则 flex-basis 设置为 content
,也就是基于 flex 的元素的内容自动调整大小。如果flex-basis
的值为百分数,并且flex容器的尺寸没有被显式设置的话,其flex-basis的值会被解析为content
, 值会根据项目来计算实际尺寸,也就是说flex项目绝对了其主轴初始值。
在本案例中,可以直接设置右侧的flex值为1,使其占容器剩余宽度的所有。
.right {
padding: 20px 30px 0 20px;
box-sizing: border-box;
/* 右边的flex取值为1 */
flex: 1;
height: 189px;
width: 0;
}
方法二 width
第二种,首先看下flex属性
flex: auto;
flex: 0 1 auto;
flex: auto是flex: 1 1 auto的缩写
这里的auto实际上是flex-basis的取值。这里右侧盒子的flex-basis为默认值0,项目总宽度小于容器宽度,计算如下:
项目总宽度310px + 0px = 310px
待分配宽度940px - 310px = 630px
放大比例0 + 1 = 1 , 这是项目的flex-grow之和
每个项目得到自身的grow/总的grow之和比例的剩余空间。
左侧盒子得到0/1 * 630px = 0,最终宽度310px + 0px = 310px
右侧容器得到 1/1 * 630px = 300px,最终宽度630px
将右侧盒子的宽度设置为0,即可解决。
.right {
padding: 20px 30px 0 20px;
box-sizing: border-box;
/* 右边的flex取值为auto */
flex: auto;
height: 189px;
width: 0;
}
方法三 给左侧的盒子设置flex-shrink:0;
从本质上来探究,左侧的盒子之所以被压缩,是因为弹性盒项目的初始属性使然
/*初始条件下*/
flex-grow:0; /*默认不拉伸*/
flex-shink:1; /*默认压缩*/
flex-basis:auto;
也就意味着左侧的内容在容器宽度不够的情况下会被压缩,所以,只需要设置其不压缩即可
.left {
width: 310px;
height: 198px;
background: skyblue;
/* 给左侧的盒子设置flex-shrink:0;不压缩 */
flex-shrink: 0;
}
结尾
弹性盒布局在实际开发过程中用的越来越多,多尝试才能掌握其准确的用法。遇到问题的时候,需要多去探究其基本语法,搞清楚原理,更能够事半功倍。
参考文献
flex 布局的基本概念 :developer.mozilla.org/zh-CN/docs/…
Flex 布局教程:语法篇www.ruanyifeng.com/blog/2015/0…
转载自:https://juejin.cn/post/7135324097352826887