Reputation: 6469
This is my current Show More page.
When I click the expand button, the text will be expand or collapse.
I tried to update the css to below, in order to make a fade in out effect for the hided text.
@keyframes open {
from {
line-clamp: 3;
-webkit-line-clamp: 3;
opacity: 0; //new
}
to {
line-clamp: initial;
-webkit-line-clamp: initial;
opacity: 1; //new
}
}
@keyframes close {
from {
line-clamp: initial;
-webkit-line-clamp: initial;
opacity: 1; //new
}
to {
line-clamp: 3;
-webkit-line-clamp: 3;
opacity: 0; //new
}
}
After I added the code, I found that the original text is hided also.
How can I fix it?
App.vue
<template>
<div id="app">
<div :class="{ box, open: showMore }">
<div class="top">
<h1>Show More</h1>
</div>
<p class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum. Curabitur pretium tincidunt lacus. Nulla
gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros
bibendum elit, nec luctus magna felis sollicitudin mauris. Integer in
mauris eu nibh euismod gravida.
</p>
<button @click="handleShowMore()"><i class="arrow"></i></button>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
showMore: false,
};
},
methods: {
handleShowMore() {
this.showMore = !this.showMore;
},
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
/* Box */
.box {
margin: 22px auto;
width: 320px;
padding: 12px 32px 64px;
max-height: 162px;
overflow: hidden;
transition: max-height 0.3s cubic-bezier(0, 1, 0, 1);
}
.box.open {
max-height: 100rem;
transition: max-height 0.3s cubic-bezier(0.9, 0, 0.8, 0.2);
}
/* Text */
@keyframes open {
from {
line-clamp: 3;
-webkit-line-clamp: 3;
/* opacity: 0; */
}
to {
line-clamp: initial;
-webkit-line-clamp: initial;
opacity: 1;
}
}
@keyframes close {
from {
line-clamp: initial;
-webkit-line-clamp: initial;
opacity: 1;
}
to {
line-clamp: 3;
-webkit-line-clamp: 3;
/* opacity: 0; */
}
}
.text {
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
margin: 12px 0;
animation: close 2s linear 0.1s forwards;
}
.open .text {
animation: open 2s linear 0s forwards;
}
/* Irrelavant css... */
.arrow {
border: solid #000;
border-width: 0 2px 2px 0;
display: inline-block;
padding: 4px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
}
.open .arrow {
transform: rotate(-135deg);
-webkit-transform: rotate(-135deg);
margin-top: 5px;
}
button {
background: transparent;
border: 2px solid #000;
height: 32px;
width: 32px;
border-radius: 50%;
outline: none;
cursor: pointer;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
}
</style>
Codesandbox:
https://codesandbox.io/s/amazing-goldwasser-e6l95?file=/src/App.vue
Upvotes: 1
Views: 981
Reputation: 8508
You can't animate the line-clamp
property. But, you can solve this problem:
ref
, mounted()
to get all height of the text and store the
value to data
.max-height: 55px
to the .text
class. Equivalent to
3 lines of text.:style
with a <p>
tag for to toggle the height of the text.data
, for toggle class and bind this the
box
class.handleShowMore()
adding check and when showMore
is falsy, set
setTimeout()
where timeout unit should be equal to css
transition-duration
.<template>
<div id="app">
<div class="box" :class="className">
<div class="top">
<h1>Show More</h1>
</div>
<p
:style="{ maxHeight: showMore ? expandedTextHeight + 'px' : '' }"
class="text"
ref="contentText"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum. Curabitur pretium tincidunt lacus. Nulla
gravida orci a odio. Nullam varius, turpis et commodo pharetra, est eros
bibendum elit, nec luctus magna felis sollicitudin mauris. Integer in
mauris eu nibh euismod gravida.
</p>
<button @click="handleShowMore()"><i class="arrow"></i></button>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data: () => ({
showMore: false,
expandedTextHeight: 0,
className: '',
}),
methods: {
handleShowMore() {
this.showMore = !this.showMore;
if (this.showMore) {
this.className = 'open';
} else {
// After .5s remove class 'open'
setTimeout(() => (this.className = ''), 500);
}
},
},
mounted() {
// get full height
this.expandedTextHeight = this.$refs.contentText.scrollHeight;
},
};
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
/* Box */
.box {
margin: 22px auto;
width: 370px;
padding: 12px 32px 64px;
overflow: hidden;
}
.text {
max-height: 55px; /* Init 3 line height */
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
margin: 12px 0;
position: relative;
line-clamp: 3;
-webkit-line-clamp: 3;
transition: all 0.5s cubic-bezier(0.9, 0, 0.8, 0.2);
}
.open .text {
line-clamp: initial;
-webkit-line-clamp: initial;
transition: all 0.5s cubic-bezier(0.9, 0, 0.8, 0.2);
}
/* Irrelavant css... */
.arrow {
border: solid #000;
border-width: 0 2px 2px 0;
display: inline-block;
padding: 4px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
}
.open .arrow {
transform: rotate(-135deg);
-webkit-transform: rotate(-135deg);
margin-top: 5px;
}
button {
background: transparent;
border: 2px solid #000;
height: 32px;
width: 32px;
border-radius: 50%;
outline: none;
cursor: pointer;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
}
</style>
Upvotes: 1