你不知道的css高级应用三种方法——实现多行省略
前言
这是个老掉牙的需求啦,不过仍然有很多人在网上找解决方案,特别是搜索结果排名靠前的那些,都是些只会介绍兼容性不好的使用-webkit-line-clamp
的方案。
如果你看到这篇文章,可能代表你正是从那么多千篇一律的文章中跳转过来的,想找更好地方案的。那恭喜你,没有更好的,只有更合不合适的,当然,前提是我的文章流量够多,能被顶上去你才有机会看到。
这里介绍三种多行文本截断的方法,当然第一种就是你看到想吐的
-webkit-line-clamp
方案,不想看就直接跳到第二种方法开始看啦。
使用-webkit-line-clamp
对多行文本的容器应用如下样式
div {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2;
}
除了-webkit-line-clamp
其他属性固定不变,主要是将对象作为弹性伸缩盒子模型显示,并设置伸缩盒对象的子元素的排列方式。
而-webkit-line-clamp
是用来控制多少行进行省略
优点:
浏览器原生支持的省略行为,样式看起来很舒服
简单方便使用
缺点:
看属性的前缀就知道,这是
webkit
内核的浏览器支持的,兼容性不是广泛。
使用场景
如果你只针对webkit内核浏览器或者移动端(移动端浏览器多数是webkit内核),那么使用该方案是最好的了。
利用绝对定位
这个方案其实很好理解的,首先我们对于一个装内容的容器右边预留一个空间用来放省略号,用padding-right: 1em;
来预留空间,为啥是1em呢,一个省略号差不多就是1em啦,用em单位是为了响应字体大小。
用绝对定位把省略号定位在这个预留的空间右下角。
html
<div class="wrap">内容</div>
css
.wrap3 {
position: relative;
padding-right: 1em;
/*max-height是line-height的几倍,想最多显示多少行就几倍*/
max-height: 3.6em;
line-height: 1.2em;
text-align: justify;
overflow: hidden;
} .wrap3:before {
position: absolute;
right: 0;
bottom: 0;
content: '...';
}
效果(多内容时):
这样的话,省略号永远都会存在的。 所以要解决这个问题,我们用一个跟背景颜色一样的方块遮住省略号,那么关键点就是,怎么知道何时要遮住,何时不遮住呢?
思路: 用于挡住省略号的方块也是绝对定位,靠右定为,right: 0
,但是bottom
值就不要设置了,如果不设置的话,该方块会跟着文本内容的实际高度移动,而不是max-height
的高度。这样的话,当不需要省略时(即不超过max-height
)时,就刚好是bottom: 0
的情况,就会挡住省略号。当要进行省略时(即超过max-height
)就会挡不住省略号了,它自己也会被overflow: hidden
给隐藏掉了。
所以最终方案是:
html
<div class="wrap">内容</div>
css
.wrap {
position: relative;
/*line-height和height要相互配合,显示多少行就省略,就是line-height多少倍数*/
line-height: 1.2em;
max-height: 3.6em;
/*此属性看需求来判断是否设置,因为设置了padding-right,多腾出了点位置,该值一般为padding-right的值的负值*/
/*margin-left: -1em;*/
/*此值写成1em就好,因为省略号大概就是占用1em的空间*/
padding-right: 1em;
text-align: justify;
overflow: hidden;
} .wrap:before {
position: absolute;
right: 0;
bottom: 0;
content: '...';
} .wrap:after {
position: absolute;
right: 0;
/*宽高写死1em就好,因为省略号大概就是占用1em的空间,用来遮挡住省略号,也基本上跟wrap的padding-right一致*/
width: 1em;
/*与wrap的行高实际值保持一致*/
height: 1.2em;
content: '';
/*要跟所在背景颜色一致才能遮挡住省略号后觉得没异样*/
background-color: #fff;
}
效果:
优点
兼容性好,各大浏览器支持
自适应高度,不用写死高度,设定超过多少行才需要进行省略显示
自适应宽度
自适应字体大小,字体大小不会影响到原本的需求,即要求多少行省略就多少行才省略
缺点
文字右边会故意留空一些位置给省略号放置
需要考虑所在的背景颜色,因为after伪类要用背景颜色来遮挡住省略号
利用float布局
这个方案对于基础知识不扎实的童鞋们,可能不太好理解,如果仅是想找个解决方案不想知道原理的话,可以直接去 小结 里看
在说该方案之前,要先理解这么一个现象:
有这么一段html
<div class="wrap">
<div class="left">左浮动</div>
<div class="right1">右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1</div>
<div class="right2">右浮动2</div>
</div>
应用这么一段样式
.wrap {
height: 100px;
}
.left {
float: left;
width: 60px;
height: 100%;
background: pink;
}
.right1 {
float: right;
/*占满wrap除left剩余宽度*/
width: calc(100% - 60px);
background: #95d9f8;
}
.right2 {
float: right;
background: yellow;
}
正常情况下会显示成这样,这也是大家一般所能想象的预期情况:
出现这个正常现象的条件是:
.right1
的高度不超过.left
的高度(即内容少).right2
的宽度少于.right1
的宽度
好了,这个情况大家理解了吧。那么接下来,我们对.right1
的内容增多至超出左浮动的高度,会发生接下来的一幕
右浮动2卡在左下角了。
要问我为什么会这样?额...看来你对float的基础知识不扎实呀,建议夯实一下基础知识,其实我也解释不了,我只知道这是float的一个正常表现。
出现这个现象的条件是:
.right1
的高度超过.left
的高度(即内容多).right2
的宽度少于或等于.left
的宽度
知识转化成需求实现
在理解了上述两个情景后,我们应该怎么利用这些知识来匹配对应的需求呢?
假设右浮动1的文本内容就是我们要进行多行省略的内容,右浮动2的内容就是省略号(...)。这样当内容少时,省略号就是上述的第一个情况,内容多的时候就是第二个情况。
这种动态变化,是不是像“文本少时不省略,文本多时进行省略”这种需求变化呢。在这个基础上,我们要解决的是在第一种情况右浮动2隐藏掉,第二种情况下右浮动2出现在.wrap
的右下角,超出高度的内容隐藏掉。
要解决上述问题,只要使用position: relative;
进行相对定位即可。.wrap
父容器应用overflow: hidden;
。 第一种情况下,定位到父容器外部,就隐藏掉了。而第二种情况,就定位到父容器右下角。
好了,现在该解决方案的焦点,就放在如何准确定位的问题上了(下一小节)。在处理定位问题前,先把目前掌握的情况转化为实际的需求代码:
<!--把左浮动和右浮动2采用伪类元素替换掉实际标签-->
<div class="wrap">
<div class="text">右浮动1</div>
</div>
.wrap {
height: 100px;
/*line-height用来控制最多显示多少行文本*/
line-height: 20px;
overflow: hidden;
}
.wrap:before {
float: left;
/*要大于或等于after元素宽度*/
width: 1.5em;
height: 100%;
content: '';
}
.text {
float: right;
/*用负值的marginLeft来避免由before产生的空白空间*/
/*因为实际需求上你的父容器里不可能左边是一片空白吧*/
margin-left: -1.5em;
/*既然采用了负值marginLeft,那么文本容器宽度就可以100%占满父容器宽度了*/
width: 100%;
}
.wrap:after {
float: right;
/*一般三个点就差不多1em宽,用em作单位能自适应字体大小*/
width: 1em;
content: '...';
}
如果你这时候好奇,为什么.text
都设置了width: 100%;
了,内容多时:after
还是会卡在:before
底下呢?是因为即使.text
设置了margin-left: -1.5em;
,但是实际上并不会影响到原本的文档流情况,原本该是怎样的就是怎样,设置了负值的margin,影响的只是.text
自身的呈现样式。
如何定位
解决定位问题是基于上小节的代码基础上。目前暴露的问题有:
内容少即不需要做省略时,省略号显示出来了
内容多即需要省略时,省略号隐藏了
先解决第二个问题
思路:要把这个:after
向右移动到.wrap
右边,向上移动到最后一行的位置。
用position: relative;
来控制的话,top
值好取,取.wrap
的line-height
实际值一样,取负值就好了。关键是left值,怎么取才能刚好在右下角呈现出来。
如果你能明确知道.text
的宽度的话(如100px),其实设置left: 100px;
即可,但是这样的话只能针对固定宽的情况,不能自适应宽度。要想实现自适应,left的值取百分比就行了,那么到底是百分之多少呢?这是纠结的。索性就取100%吧,会发现会移出到父容器外。
那要刚好出现在右下角的话,省略号的初始位置就必须要在.wrap
的左侧,紧挨着.wrap
,才能left: 100%
后出现在右下角。
现在问题就变成如何让:after
刚好出现在.wrap
的左侧了。 以下代码对于基础不扎实的人,可能有些难理解了(新增部分在注释处):
.wrap:after {
float: right;
/*因为下面设置了margin,所以这里的宽度值大小没有要求*/
width: 1em;
content: '...'; /*这两个属性是设置紧挨着.wrap左侧*/
/*此值要跟自身宽度一样,取负值*/
margin-left: -1em;
/*此值要跟before宽度一样*/
padding-right: 1.5em; /*这是定位省略号的位置*/
position: relative;
left: 100%;
/*与父元素wrap的行高实际值一样,取负值*/
top: -20px;
}
关于设置margin和padding值那里,如果你能理解就最好了,不能理解的话,我尽量解释一下,其实这也真不好说。
首先是应用margin-left: -1em;
的时候,由于:after
的宽度比:before
的要小,所以按照原本的float布局的话,在一行里
粉红色为左浮动,蓝色红色为右浮动,如果红色的宽度不断增大至除粉红色剩余空间,由于一行的空间不够,蓝色会被挤到换行右浮动了。但是如果设置蓝色的margin-left为本身宽度的负值,那么这时候一行的空间还是有位置给它的,就变成了如下这样了
按照上述原理,设置了margin-left: -1em;
后,:after
就变回到父容器的第一行上了,紧挨着父容器左侧。但是我们不能让它回到第一行上呀,所以设置padding-right: 1.5em;
让它实际占的空间变大到第一行容不下它,就变回到原本的卡在:before
下的位置,只是padding值让它移动到左侧了
好了我解释完了,能不能看懂,只能看你的造化了哈哈。
值得留意的是,上面代码里关于width的注释写着“因为下面设置了margin,所以这里的宽度值大小没有要求”,之前都要求小于等于:before
宽度,但是现在由于采用margin-left负值抵消了本身的宽度,所以这个要求转化对padding-right
了,这时是等于
小结
到目前位置,所有问题都解决了。针对上述所有讨论的问题,总结为以下代码(具体优化有注释说明):
css样式
.wrap {
/*需要定高*/
height: 100px;
/*用来设置显示多少行才省略,值一般为wrap的height值/行数求得,但是这个行数会受到字体大小的限制*/
/*字体太大了,设置显示很多行也会很丑,都挤一块了,所以这个实际值,要看具体需求和实践*/
line-height: 25px;
/*加上此属性显示效果更佳,就算部分浏览器不支持也影响不大*/
text-align: justify;
overflow: hidden;
} .wrap:before {
float: left;
/*这个值可以随意设定,不论单位还是什么*/
width: 1em;
height: 100%;
content: '';
} .wrap:after {
float: right;
/*大小随意,设置em单位最好,可随字体大小变化而自适应*/
/*如果要采用以下渐变效果,那么这个值要大于before里的width值效果会比较好点*/
/*值越大,渐变的效果越明显影响的范围越大。*/
width: 2.5em;
/*与父元素wrap的行高实际px值一样*/
height: 25px;
/*此值要跟自身宽度一样,取负值*/
margin-left: -2.5em;
/*此值要跟before宽度一样*/
padding-right: 1em;
content: '...';
text-align: right;
/*这里开始利用在float布局的基础上进行定位移动了*/
position: relative;
/*与父元素wrap的行高实际值一样,取负值*/
top: -25px;
left: 100%;
/*设置渐变效果是为了省略号和内容衔接得自然点,没那么突兀,要注意要跟文字所在的背景的颜色搭配(把white替换成背景色)*/
background: #fff;
background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
} .wrap .text {
float: right;
/*该值要等于wrap:before的width值*/
margin-left: -1em;
width: 100%;
}
html文件:
<div class="wrap">
<span class="text">
示例2: 散发设解决看手机啦开发交
</span>
</div>
效果:
优点
兼容性好,满足不是webkit内核的浏览器都能支持
自适应宽度
缺点
固定高度,不能自适应高度,因此显示多少行还要受字体大小限制
需要为文字包裹一个标签用以设置样式
从读样式代码上来看,理解起来不是很好理解
如果省略号所在元素不用渐变色背景,偶尔会截断得突兀,如果要用渐变色背景,要注意与文字所在的背景下的颜色搭配
总结
其实没有说哪个方案更好,只有合不合适你的方案,叫你去削个水果皮,拿把水果刀就好了,没必要用个大刀。所以,三个方案,总有一款符合你的需求的。
你不知道的css高级应用三种方法——实现多行省略的更多相关文章
- 清楚css浮动的三种方法
第一种:添加新元素,应用clear:both; <div class="clear"></div> css样式:clear:both; 第二种:在浮动元素 ...
- js改变css样式的三种方法
共用代码: <div id="div">this is a div</div> var div=document.getElementById('div') ...
- css 清楚浮动三种方法
我们可以看到这样一个布局: <style> .left{ width: 200px; height: 200px; background-color: #00ee00; float: le ...
- CSS水平居中的三种方法
CSS中经常会用到元素居中,那么今天我为大家分享几种水平居中的方法,下面代码都可以达到同样的居中效果,来不及解释了,快上马(码): 一.margin : 0 auto; <head> &l ...
- HTML页面中插入CSS样式的三种方法
1. 外部样式 当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以通过改变一个文件来改变整个站点的外观.每个页面使用<link>标签链接到样式表. &l ...
- 使用CSS样式的三种方法
一.内联样式 内联样式通过style属性来设置,属性值可以任意的CSS样式. 1 <!DOCTYPE html> 2 <html lang="en"> 3 ...
- CSS围住浮动元素的三种方法
浮动元素脱离了文档流,其父元素看不到它了,因而不会包围它.浮动会“扩散”到下一个清除浮动的元素处.这会引起不想要的页面布局效果. 清除浮动的方法有三种: 1.父元素overflow:hidden 2. ...
- 设置css三种方法的优先级
有的小伙伴问了,如果有一种情况:对于同一个元素我们同时用了三种方法设置css样式,那么哪种方法真正有效呢?在下面代码中就出现了这种情况 1.使用内联式CSS设置“超酷的互联网”文字为粉色. 2.然后使 ...
- CSS实现导航条Tab的三种方法
前面的话 导航条Tab在页面中非常常见,本文说详细介绍CSS实现导航条Tab的三种方法 布局 根据上图所示,先规定几个定义,上图的模块整体叫做导航,由导航标题和导航内容组成.要实现上图所示的布 ...
随机推荐
- 记录:springmvc + mybatis + maven 搭建配置流程
前言:不会配置 spring mvc,不知道为什么那样配置,也不知道从何下手,那么看这里就对了. 在 IDEA 中搭建 maven + springmvc + mybatis: 一.在 IDEA 中首 ...
- JVM类加载器及Java类的生命周期
预定义类加载器(三种): 启动(Bootstrap)类加载器: 是用本地代码实现的类装入器,它负责将<Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar) ...
- HwUI下载地址
下载地址:HwUI.0.0.1.zip
- [js样式效果]具有停顿效果上下滚动方式
一般用于公告的滚动效果 <!DOCTYPE HTML> <html> <head> <meta charset="gb2312" /> ...
- java-接口和抽象类的联系和区别。
接口和抽象类的联系和区别. 一,简单总结 1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象. 2.抽象类要被子类继 ...
- 微信小程序之雪碧图(css script)
今天有朋友问我关于微信小程序中如何在不占用大量网络带宽的情况下快速加载图片,我给他推荐了两种方式 1.雪碧图(css script),有过前端经验的朋友应该都有接触过. 2.懒加载. 由于时间关系我就 ...
- Task15 节点层次笔记
childElementCount : 返回子元素的个数 (不包括文本节点和注释节点) children:返回指定元素的子元素集合,它只返回HTML节点,甚至不返回文本节点,虽然不是标准的DOM属性, ...
- js异步原理与 Promise
一.Javascript的异步原理 javascript 是单线程语言,所以同一时间只执行一个运算.但有些方法是不能瞬间完成或不可预知何时完成的(如网络请求.settimeout等),为了让它们不对后 ...
- Python 3从入门到精通02-python的简单使用
Python 3中的打印语句和字符串使用: Python中的常见数学运算: 这样的简单基础知识,你需要花5分钟就可以了,很基础的东西.
- Linux学习之CentOS(三)----将Cent0S 7的网卡名称eno16777736改为eth0
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...