多行文本展开收起是一个很小常见的交互:
这一类布局和交互难点主要有以下几点:
- 位于多行文本右下角的展开收起按钮
- 展开和收起的两种状态的切换
- 当文本不超过指定行数时,不显示展开收起按钮
说实话,之前单独看这个布局时,即使借助javascript也不是一件容易的事情,需要计算文字宽度动态截取文本,vue-clamp这是这么做的,更别说下面的交互和判断逻辑了,不过经过我一番琢磨,其实纯css也能完美实现的,下面来看看如何实现 的吧。
一、位于右下角的展开收起按钮(仅兼容chrome, 无点击效果)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrapper {
display: flex;
margin: 50px auto;
width: 800px;
overflow: hidden;
border-radius: 8px;
padding: 15px;
box-shadow: 20px 20px 60px #bebebe,
-20px -20px 60px #ffffff;
}
.text {
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
text-align: justify;
/* display: flex; */
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
position: relative;
}
.text::before {
content: '';
height: calc(100% - 24px);
float: right;
}
.btn {
float: right;
clear: both;
margin-left: 10px;
font-size: 16px;
padding: 0 8px;
background: #3F51B5;
line-height: 24px;
border-radius: 4px;
color: #fff;
cursor: pointer;
border: 0;
/* margin-top: -30px; */
}
button {
float: right;
clear: both;
margin-left: 10px;
/* margin-top: -30px; */
}
</style>
</head>
<body>
<div class="wrapper">
<div class="text">
<button class="btn">这是一个占位</button>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
</div>
</div>
<div class="wrapper">
<div class="text" style="-webkit-line-clamp: 5;">
<button class="btn">这是一个占位</button>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
</div>
</div>
</body>
</html>
如上执行效果:
2.如上的写法不兼容safair, firefox,完事版如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrapper {
display: flex;
margin: 50px auto;
width: 800px;
overflow: hidden;
border-radius: 8px;
padding: 15px;
box-shadow: 20px 20px 60px #bebebe,
-20px -20px 60px #ffffff;
}
.text {
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
text-align: justify;
/* display: flex; */
/* display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical; */
line-height: 1.5;
max-height: 4.5em;
position: relative;
}
.text::before {
content: '';
height: calc(100% - 26px);
float: right;
}
.btn {
position: relative;
float: right;
clear: both;
margin-left: 20px;
font-size: 16px;
padding: 0 8px;
background: #3F51B5;
line-height: 24px;
border-radius: 4px;
color: #fff;
cursor: pointer;
border: 0;
/* margin-top: -30px; */
}
.btn::before {
content: '...';
position: absolute;
left: -5px;
color: #333;
transform: translateX(-100%)
}
</style>
</head>
<body>
<div class="wrapper">
<div class="text">
<button class="btn">这是一个占位</button>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
</div>
</div>
<div class="wrapper">
<div class="text" style="-webkit-line-clamp: 5;">
<button class="btn">这是一个占位</button>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem
ipsum dolor sit amet,",并且接下来是另外一个和"Floats
Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。
</div>
</div>
</body>
</html>
最全的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrapper {
display: flex;
margin: 50px auto;
width: 800px;
overflow: hidden;
border-radius: 8px;
padding: 15px ;
box-shadow: 20px 20px 60px #bebebe,
-20px -20px 60px #ffffff;
}
.text {
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
text-align: justify;
/* display: flex; */
/* display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical; */
position: relative;
line-height: 1.5;
max-height: 4.5em;
transition: .3s max-height;
}
.text::before {
content: '';
height: calc(100% - 26px);
float: right;
}
.text::after {
content: '';
width: 999vw;
height: 999vw;
position: absolute;
box-shadow: inset calc(100px - 999vw) calc(30px - 999vw) 0 0 #fff;
margin-left: -100px;
}
.btn{
position: relative;
float: right;
clear: both;
margin-left: 20px;
font-size: 16px;
padding: 0 8px;
background: #3F51B5;
line-height: 24px;
border-radius: 4px;
color: #fff;
cursor: pointer;
/* margin-top: -30px; */
}
.btn::after{
content:'展开'
}
.exp{
display: none;
}
.exp:checked+.text{
max-height: 200px;
}
.exp:checked+.text::after{
visibility: hidden;
}
.exp:checked+.text .btn::before{
visibility: hidden;
}
.exp:checked+.text .btn::after{
content:'收起'
}
.btn::before{
content: '...';
position: absolute;
left: -5px;
color: #333;
transform: translateX(-100%)
}
</style>
</head>
<body>
<div class="wrapper">
<input id="exp1" class="exp" type="checkbox">
<div class="text">
<label class="btn" for="exp1"></label>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。
</div>
</div>
<div class="wrapper">
<input id="exp2" class="exp" type="checkbox">
<div class="text">
<label class="btn" for="exp2"></label>
浮动元素是如何定位的
正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。
</div>
</div>
</body>
</html>