我有一个块,其中包含悬停时显示的内容。效果的工作方式应该是:
.hoverCard 默认显示基础内容(.hoverCard__showOnHover 中的内容被隐藏)
用户将鼠标悬停在 .hoverCard 上,此时 .hoverCard__showOnHover 显示其内容,并且 .hoverCard__body 向上转换(赋予其“打开”效果)
可以在我的演示中看到上述内容的视觉效果,但我无法让动画完美地工作。
我遇到的问题是:
使用 visibility:hidden、opacity:0 和 height:0 仍然为 .hoverCard__showOnHover 保留空间。这意味着,如果默认情况下,.hoverCard__body 的底部填充量为 40px,而 .hoverCard__showOnHover 的高度为 100px,则无需用户将鼠标悬停在 .hoverCard 上即可看到 140px 的空间
我知道可以防止空间预留的唯一方法是使用 display: none。但是,当我将鼠标悬停在卡片上时,我需要为其提供一个显示属性来展示内容,这会给卡片带来跳跃效果(因为悬停时会引入高度)。除此之外,我的卡片的高度也会增长(我想要内容显示并向上打开的效果,而不是像演示中那样增长 .hoverCard)
为了尝试解决上述问题,我尝试使用 GSAP 逐渐赋予 .hoverCard__showOnHover 高度。但运气不好,因为它仍然存在上述问题
有什么办法可以解决这个问题吗?不一定要使用 GSAP,我只是尝试过 GSAP 来尝试解决上述问题。
const hoverCard = document.querySelector('.hoverCard');
const hoverCardBodyShowOnHover = document.querySelector('.hoverCard__showOnHover');
hoverCard.addEventListener('mouseenter', function() {
gsap.to(hoverCardBodyShowOnHover, { duration: 0.5, display: 'block', height: 'auto', ease: 'power4.out' });
});
hoverCard.addEventListener('mouseleave', function() {
gsap.to(hoverCardBodyShowOnHover, { duration: 0.5, height: 0, ease: 'power4.out', onComplete: function() {
this.targets()[0].style.display = 'none';
}});
});
:root {
--black: #000000;
--white: #ffffff;
--yellow: #FFE775;
}
/* general */
body {
font-family: "Poppins", sans-serif;
background-color: var(--white);
color: var(--black);
}
section {
margin: 100px 0 300px 0;
}
/* card */
.hoverCard {
margin-bottom: 15px;
width: 100%;
border-radius: 8px;
overflow: hidden;
background-color: var(--black);
color: var(--white);
border: 1px solid var(--black);
}
.hoverCard * {
transition: all 0.5s ease;
}
.hoverCard:hover .hoverCard__body {
transform: translateY(-75px);
}
.hoverCard:hover .hoverCard__body .hoverCard__showOnHover {
opacity: 1;
visibility: visible;
display: block;
height: auto;
transform: translateY(75px);
}
.hoverCard__header {
height: 350px;
background-color: var(--yellow);
}
.hoverCard__showOnHover {
display: none;
height: 0;
overflow: hidden;
}
.hoverCard__body {
width: 100%;
padding: 30px 30px 40px 30px;
}
Subheader
This will show on hover 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.
以下是该卡的默认版本的视觉效果(见右卡)以及悬停交互的工作原理(左卡):
注意卡片高度没有增加。相反,主体向上移动(在卡片内)以显示内容。
编辑:
基于 Kooilnc 的回答:
:root {
--black: #000000;
--white: #ffffff;
--yellow: #FFE775;
}
/* general */
body {
background-color: var(--white);
color: var(--black);
}
section {
margin: 100px 0 300px 0;
}
/* card */
.hoverCard {
margin-bottom: 15px;
width: 100%;
border-radius: 8px;
overflow: hidden;
background-color: var(--black);
color: var(--white);
border: 1px solid var(--black);
position: relative; /* added */
}
.hoverCard * {
transition: all 0.5s ease;
}
.hoverCard:hover .hoverCard__body {
transform: translateY(-75px);
}
.hoverCard:hover .hoverCard__body .hoverCard__showOnHover {
/* opacity: 1;
visibility: visible;
display: block;
height: */ auto;
overflow: initial; /* added */
height: auto; /* added */
max-height: 100px; /* added */
transform: translateY(75px);
}
.hoverCard__header {
height: 200px;
background-color: var(--yellow);
}
.hoverCard__showOnHover {
overflow: hidden;
max-height: 0; /* added */
transition: max-height 0.5s ease-in-out; /* added */
overflow: hidden; /* added */
}
.hoverCard__body {
width: 100%;
padding: 30px 30px 40px 30px;
}
Subheader
This will show on hover 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.
另外,我们需要为 max-height: 100px; 定义一个数字吗?如果内容大小未知并且需要动态怎么办?
编辑2
最新方法:
:root{
--white: #FFFFFF;
--black: #000000;
--yellow: #FFE775;
}
section{
padding: 150px 0;
}
.hoverCard {
margin-bottom: 15px;
width: 100%;
border-radius: 8px;
overflow: hidden;
padding-bottom: 180px; // seems I need this to maintain height
background-color: var(--black);
color: var(--white);
border: 1px solid var(--black);
/* only on non touch devices
================================== */
@media (hover: hover) {
* {
transition: all 0.5s ease;
}
&:hover {
.hoverCard__body {
transform: translateY(-75px);
}
.hoverCard__showOnHover {
display: block;
max-height: none;
overflow: visible;
}
}
}
&__showOnHover {
display: none;
max-height: 0;
overflow: hidden;
transition: max-height 0.5s ease-in-out;
}
/* only on touch devices
================================== */
@media (pointer: coarse) {
&__showOnHover {
margin-bottom: 30px;
}
}
/* =============================== */
&__header {
height: 350px;
background-color: var(--yellow);
}
&__body {
position: absolute;
bottom: 0;
width: 100%;
padding: 30px 30px 0px 30px;
color: var(--white);
background-color: var(--black);
&-text {
margin-bottom: 60px;
}
}
}
Subheader
This will show on hover 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.
通过以上内容:
这会导致 .hoverCard__body 上方出现不必要的空格(应仅填充顶部 30px)。
入口动画跳跃(内容刚刚出现,翻译不流畅)
退出动画高度也快速跳下(因为display none属性生效)
技巧是将要显示的文本设置为
max-height: 0和overflow: hide。这是一个最小可重现示例。body { margin: 1rem; font-family: system-ui, sans-serif; } .item { position: relative; overflow: hidden; margin-right: 0.8rem; width: 150px; float: left; border: 1px solid #777; border-radius: 3px; } .item.first { background: url("https://upload.wikimedia.org/wikipedia/commons/d/d0/Queen_Clementia_of_Hungary.jpg") no-repeat top left; background-size: cover; height: 150px; } .collapsible { height: inherit; width: inherit; position: absolute; bottom: 0; } .collapsible .header { background-color: #EEE; color: #000; text-align: center; font-weight: bold; font-size: 0.9rem; cursor: pointer; bottom: 0; width: 100%; position: absolute; opacity: 0.8; } .item .collapsible .collapsibleTxt { max-height: 0; text-align: left; font-size: initial; color: #444; overflow: hidden; padding: 4px; font-weight: normal; transition: max-height 0.5s ease-in-out; } .header:hover .collapsibleTxt { overflow: initial; height: auto; max-height: 100px; }