厉害了,不用js就能实现文字中间省略号

1,438 阅读4分钟

今天发现一个特别有意思的效果,并进行解析,就是标题的效果

参考链接

如果要实现这个功能,我想很多人第一时间想到的都是用js去计算dom容器和文字之间是否溢出吧?但今天带来一个用css实现的效果,不用自己计算,只需要寥寥几行(bushi)就可以实现让人头疼的文字中间省略号功能。


实现思路

1. 简单实现

在用css实现的时候我们不妨用这个思路想想,设置一个当前显示文字span伪元素的width为50%,浮动到当前span上面,并且设置direction: rtl; 显示右边文字,不就可以很简单的实现这个功能了?让我们试试:

<style>
    .wrap {
        width: 200px;
        border: 1px solid white;
    }
    .test-title {
        display: block;
        overflow: hidden;
        height: 20px;
    }
    .test-title::before {
        content: attr(title);
        width: 50%;
        float: right;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        direction: rtl;
    }
</style>
<body>
    <div class="wrap">
        <span class="test-title" title="这是一行文字文字文字文字文字文字文字文字文字文字文字文字文字">
            这是一行文字文字文字文字文字文字文字文字文字文字文字文字文字
        </span>
    </div>
</body>

Untitled

💡 此处应有图

2. 优化效果

在上面我们已经看到,其实效果我们已经实现了,现在文字中间已经有了省略号了!但是这其中其实有一个弊端不知道大家有没有发现,那就是文本不溢出的情况呢?伪元素是不是会一直显示在上面?这该怎么办?难道我们需要用js监听文本不溢出的情况然后手动隐藏吗?

Untitled

既然是用css来进行实现,那么我们当然不能用这种方式了。这里原作者用了一种很取巧,但也很好玩的一种方法,让我们来看看吧!

既然我们上面实现的是文本溢出的情况,那么当文本不溢出的时候我们直接显示文字不就行了?你可能想说:“这不是废话吗?但我现在不就是不知道怎么判断吗? ”。hhhhh对,那我们就要用css来想想,css该怎么判断呢?我就不卖关子了,让我们想想,我们给文本的容器添加一个固定宽度,那么当文本溢出的时候会发生什么呢?是不是会换行,高度变大呢,那么当我们设置两个文本元素,一个是正常样式,一个是我们上方的溢出样式。等文本不溢出没换行的时候,显示正常样式,当文本溢出高度变大的时候显示溢出样式可以吗?让我们试试吧

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        body {
            background: #333;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
            font-size: 14px;
        }
        .wrap {
            width: 300px;
            background: #333;
            
            /* 设置正常行高,并隐藏溢出画面 */
            height: 2em;
            overflow: hidden;
            line-height: 2;
            position: relative;
            text-align: -webkit-match-parent;
            resize: horizontal;
        }

        .normal-title {
            /* 设置最大高度为双倍行高使其可以换行 */
            display: block;
            max-height: 4em;
        }
        .test-title {
            position: relative;
            top: -4em;
            display: block;
            color: white;
            overflow: hidden;
            height: 2em;
            text-align: justify;
            background: inherit;
            overflow: hidden;
        }
        .test-title::before {
            content: attr(title);
            width: 50%;
            float: right;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            direction: rtl;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <span class="normal-title">这是一行文字文字文字文字文字文字文字文字文字文字文字文字文字</span>
        <span class="test-title" title="这是一行文字文字文字文字文字文字文字文字文字文字文字文字文字">
            这是一行文字文字文字文字文字文字文字文字文字文字文字文字文字
        </span>
    </div>
</body>

</html>

大家都试过了吧?那让我们来讲一下这段代码的实现:

实现方式:简单来说这段代码实现的就是一个覆盖的效果,normal-title元素平常是普通高度(1em),等到换行之后就会变成2em,那么我们的溢出样式test-title怎么实现的覆盖呢?这主要依赖于test-title的top属性,让我们这样子想,当normal-title高度为1em的时候,test-title的top为-2em,那么这时候因为wrap的hidden效果,所以test-title是看不到的。那么当normal-title的高度为2em的时候呢?test-title刚好就会覆盖到normal-title上面,所以我们刚好可以看到test-title的省略号效果。

这就是完整的实现过程和方式,css一些取巧的判断方式总会让我们大开眼界,不断学习,方得始终。