03CSS 实现多行文本“展开收起”

前段时间,我分享了一种文本展开收起的方法,并得到了广大朋友的积极反馈。其中,有热心的朋友特别提出一个建议,希望将展开收起的按钮放置在文本末尾。为此,我进行了多次调试与尝试,终于实现了这一功能,并在此与大家分享我的成果。

在着手实现之前,我查阅了百度上众多网友的做法,发现很多人都是通过input的checked属性来控制文本的展开与收起。我也采用了这种方式。

但在此基础上,我特别注重了兼容性的处理。因为有些写法在Chrome浏览器上运行得非常好,但在Firefox浏览器上却会出现样式混乱的问题。因此,我进行了相应的调整和优化,确保在各种主流浏览器上都能呈现出良好的效果。

话不多说,上效果展示

具体实现步骤

1. 先搭建基础页面

html 复制代码
<div class="wrap">
    <input type="checkbox" id="switch" class="input">
    <div class="text">
        <label class="btn" for="switch"></label>
        在清晨的微光中,小镇被一层薄薄的雾气轻轻笼罩,仿佛披上了一层神秘的面纱。
        街道两旁的梧桐树在微风中轻轻摇曳,发出沙沙的声响,像是在诉说着不为人知的故事。
        远处,炊烟袅袅升起,带着家的温馨和生活的气息。偶尔,一阵清脆的鸟鸣划破寂静,
        为这宁静的早晨增添了几分生机。人们开始陆续走出家门,迎接新的一天,
        他们的脸上洋溢着期待和希望,仿佛在告诉世界,这里是一个充满活力和希望的地方。
    </div>
</div>
css 复制代码
*{
    margin: 0;
    padding: 0;
}
.wrap{
    max-width: 750px;
    display: flex;
    padding: 16px;
    border: 1px solid rgba(0,0,0,.2);
    margin: 20px 100px;
    overflow: hidden;
    border-radius: 12px;
    box-shadow: 0 0 10px rgba(0,0,0,.2);
    position: relative;
}
.text {
    line-height: 1.5;
    max-height: 4.5em; // 这里设置的是最大高度3行,超过隐藏
    overflow: hidden;
}

2.利用float属性巧妙地将"展开"和"收起"定位至文本右下角

虽然你们可能会觉得利用float属性方式稍显"土",但不可否认的是,它有独特的价值存在

第一步展开按钮和省略的三个点,运用伪元素即可轻松搞定!这并不难,相信大家都能够轻松驾驭。

css 复制代码
.btn {
    float: right;
    clear: both;
}
.btn::before{
    content: '...';
    position: absolute;
}
.btn::after{
    content:'展开' ;
    padding-left: 15px;
}

第二步要让展开按钮和省略的三个点乖乖待在右下角,确实得动动脑筋想想办法呢

为了给text文本容器添加一个伪元素,让它浮动在右边,我们尝试将高度设置为100%,结果不小心把"展开"文字挤下去了。不过别担心,我们稍微调整了下,给伪元素加了margin-bottom: -24px;,这样"展开"文字就有空间显示啦。看,问题轻松解决!

css 复制代码
.text::before{
    content: '';
    float: right;
    width: 0;
    height: 100%;
    margin-bottom: -24px;
}

margin-bottom:-12px;看一下效果

3.实现文字展开收起切换及高度调整

第一步 点击按钮更换文字

css 复制代码
.input:checked+.text .btn::after{
    content:'收起';
}

第二步将text的max-height的最大高度设置为null,就可以实现基本效果

css 复制代码
.input{
    display: none;
}
.input:checked+.text{
    max-height: none;
}

目前还有个问题要解决,如何在文本不到末尾时隐藏切换按钮,这里就要想点特殊的处理办法

给text添加一个伪元素,在文本后面,并将背景色设置白色,起到遮盖住'展开收起'按钮的作用,需要注意的是,展开后需要把伪元素遮盖层隐藏,并且将省略号置为空,好了这就完成了。

css 复制代码
.text::after {
    content: '';
    width: 100%;
    height: 20px;
    position: absolute;
    transform: translateX(-11px);
    background: #fff;
}

.input:checked+.text::after{
    visibility: hidden;  // 不这样做收起按钮就被遮挡住了,回不去了,哈哈哈哈哈哈
}
.input:checked+.text .btn::before{
    content: '';
}

完整代码如下

xml 复制代码
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .wrap{
            max-width: 750px;
            display: flex;
            padding: 16px;
            border: 1px solid rgba(0,0,0,.2);
            margin: 20px 100px;
            overflow: hidden;
            border-radius: 12px;
            box-shadow: 0 0 10px rgba(0,0,0,.2);
            position: relative;
        }
       
        .text {
            line-height: 1.5;
            max-height: 4.5em;// 这里设置的是最大高度3行,超过隐藏
            overflow: hidden;
        }
        .text::before{
            content: '';
            float: right;
            width: 0;
            height: 100%;
            margin-bottom: -24px;
        }
        .text::after {
            content: '';
            width: 100%;
            height: 100%;
            position: absolute;
            background-color: #fff;
        }
        .btn {
            float: right;
            clear: both;
        }
        .btn::before{
            content: '...';
            position: absolute;
        }
        .btn::after{
            content:'展开' ;
            padding-left: 15px;
        }
        .input{
            display: none;
        }
        .input:checked+.text{
            max-height: none;
        }
        .input:checked+.text .btn::after{
            content:'收起';
        }
        .input:checked+.text::after{
            visibility: hidden;
        }
        .input:checked+.text .btn::before{
            content: '';
        }
    </style>
</head>
<body>
<div class="wrap">
    <input type="checkbox" id="switch" class="input">
    <div class="text">
        <label class="btn" for="switch"></label>
        在清晨的微光中,小镇被一层薄薄的雾气轻轻笼罩,仿佛披上了一层神秘的面纱。
        街道两旁的梧桐树在微风中轻轻摇曳,发出沙沙的声响,像是在诉说着不为人知的故事。
        远处,炊烟袅袅升起,带着家的温馨和生活的气息。偶尔,一阵清脆的鸟鸣划破寂静,
        为这宁静的早晨增添了几分生机。人们开始陆续走出家门,迎接新的一天,
        他们的脸上洋溢着期待和希望,仿佛在告诉世界,这里是一个充满活力和希望的地方。
    </div>
</div>
</body>
</html>

结语

虽然看似是一个微不足道的小功能,但其背后的细节和要点却颇为丰富。

我衷心希望这次的分享能够为大家带来实质性的帮助,同时也非常期待大家能够继续提出宝贵的建议和意见,让我们在共同学习中不断进步。

感谢大家的点赞、收藏与转发,你们的支持与鼓励是我持续前行的最大动力。

相关推荐
mldong3 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排4 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60614 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角5 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!6 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰6 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi7 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen8 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马9 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu9 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss