多行文本溢出显示省略号 - 纯css解决方案

此方案支持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%);
        }

新增的定位样式,实现两个效果:

  1. 文本没有溢出时,token会处于文本的右下角,但是被“left”放到了边界外,不可见
  2. 文本溢出时,token会处于父元素的左下角,但又被“left”放到了右下角,同时因为transform向上移动了一个身位,就变得可见

现在再回头看那段诡异的代码,头绪就应该被挑起来了。其中有一些为负的margin是为了调整文本的位置,省略号的位置及宽度。

这是一个几乎全浏览器兼容的多行文本溢出的css解决方案,希望你能有所收获。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容