此方案支持IE,firefox,safari,chrome。
效果如下
overview
live demo
完整代码
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.ellipsis {
overflow: hidden;
height: 100px;
line-height: 20px;
background-color: aliceblue;
}
.ellipsis::before {
content: "";
float: left;
width: 2em;
height: 100%;
}
.ellipsis>div {
float: right;
width: 100%;
margin-left: -2em;
line-height: inherit;
}
.ellipsis::after {
content: '...';
display: block;
float: right;
width: 2em;
position: relative;
line-height: inherit;
left: 100%;
transform: translate(0, -100%);
background: inherit;
padding-right: 50px;
margin-left: -50px;
}
</style>
</head>
<body>
<h1>Please change window size to make overflow</h1>
<div class="ellipsis">
<div>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis necessitatibus temporibus rem animi quae
laborum nemo laboriosam fugit eligendi ipsam iure a quidem voluptatem ut iste repellat numquam fugiat
omnis, doloribus earum consequuntur hic vitae accusantium. Nesciunt, quas aliquam labore, consequuntur,
veritatis suscipit amet id dolore numquam magni ea consectetur.
</div>
</div>
</body>
这一段css咋一看很诡异,仔细一瞧看不懂。ellipsis 本身很普通,但是伪元素和子元素的float是为什么?如何实现省略号效果?有兴趣的同学可以往下看,我们一起来解剖一下原理。
原理解剖
先观察float元素在浏览器下的表现,我们引入新的代码并放两个float right 元素:text和token
代码
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.a {
overflow: hidden;
height: 100px;
line-height: 20px;
background-color: aliceblue;
}
.text {
float: right;
background-color: khaki;
}
.token {
float: right;
width: 15px;
height: 15px;
background-color: red;
}
</style>
</head>
<body>
<div class="a">
<div class='text'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis necessitatibus temporibus rem animi quae
laborum nemo laboriosam fugit eligendi ipsam iure a quidem voluptatem ut iste repellat numquam fugiat
omnis, doloribus earum consequuntur hic vitae accusantium. Nesciunt, quas aliquam labore, consequuntur,
veritatis suscipit amet id dolore numquam magni ea consectetur.
</div>
<div class='token'>...</div>
</div>
</body>
效果
1.gif
text 元素撑高时,会把token元素往下挤,直到挤出边界。意料之中,符合直觉,没什么可说的。
如果我在text元素的左边制造一个足以容纳token元素的“缺口”,又会发生什么情况呢?
代码
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.a {
overflow: hidden;
height: 100px;
line-height: 20px;
background-color: aliceblue;
}
.text {
float: right;
background-color: khaki;
width: calc(100% - 15px);
}
.token {
float: right;
width: 15px;
height: 15px;
background-color: red;
}
</style>
</head>
<body>
<div class="a">
<div class='text'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis necessitatibus temporibus rem animi quae
laborum nemo laboriosam fugit eligendi ipsam iure a quidem voluptatem ut iste repellat numquam fugiat
omnis, doloribus earum consequuntur hic vitae accusantium. Nesciunt, quas aliquam labore, consequuntur,
veritatis suscipit amet id dolore numquam magni ea consectetur.
</div>
<div class='token'>...</div>
</div>
</body>
效果
2.png
可以看到,当text左边有缺口并且足够大时,token会被优先放到左边。这也没有什么奇怪的。(耐心点,我没有玩你)
接下来, 是关键的一步
我们在左边放一个占位元素,它会带来一个神奇的效果:当且仅当文本溢出时,制造缺口。
代码
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.a {
overflow: hidden;
height: 100px;
line-height: 20px;
background-color: aliceblue;
}
.place-holder {
float: left;
width: 15px;
height: 100%;
background-color: lawngreen;
}
.text {
float: right;
background-color: khaki;
width: 100%;
margin-left: -15px;
}
.token {
float: right;
width: 15px;
height: 15px;
background-color: red;
}
</style>
</head>
<body>
<div class="a">
<div class='place-holder'></div>
<div class='text'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis necessitatibus temporibus rem animi quae
laborum nemo laboriosam fugit eligendi ipsam iure a quidem voluptatem ut iste repellat numquam fugiat
omnis, doloribus earum consequuntur hic vitae accusantium. Nesciunt, quas aliquam labore, consequuntur,
veritatis suscipit amet id dolore numquam magni ea consectetur.
</div>
<div class='token'></div>
</div>
</body>
效果
3.gif
思维模型图
4.png
当文本溢出时,由于占位元素(高度不变)的存在,父元素左下角会产生一个”缺口“,这时再想想刚才那句废话 当text左边有缺口并且足够大时,token会被优先放到左边
这一点是整个思路的核心!
利用这个现象,再走一步,我们就完成了整个解决方案的关键部分
代码
.token {
...
position: relative;
left: calc(100% - 15px);
transform: translate(0, -100%);
}
新增的定位样式,实现两个效果:
- 文本没有溢出时,token会处于文本的右下角,但是被“left”放到了边界外,不可见
- 文本溢出时,token会处于父元素的左下角,但又被“left”放到了右下角,同时因为transform向上移动了一个身位,就变得可见
现在再回头看那段诡异的代码,头绪就应该被挑起来了。其中有一些为负的margin是为了调整文本的位置,省略号的位置及宽度。
这是一个几乎全浏览器兼容的多行文本溢出的css解决方案,希望你能有所收获。