我目前正在设计一个 CSS'mega dropdown' 菜单 - 基本上是一个常规的 CSS-only 下拉菜单,但包含不同类型的内容。
目前, 似乎 CSS3 Transitions 不适用于'display' 属性 ,即你不能进行任何类型的从display: none
到display: block
(或任何组合)的转换。
当有人将鼠标悬停在其中一个顶级菜单项上时,是否有人会想到上述示例中的第二层菜单可以 “淡入”?
我知道你可以在visibility:
property 上使用转换,但我想不出有效利用它的方法。
我也尝试过使用身高,但这只是失败了。
我也知道使用 JavaScript 实现这一点是微不足道的,但是我想挑战自己只使用 CSS 而且我认为我有点短。
欢迎所有和任何建议。
您可以连接两个或更多个转换,这次visibility
是最方便的。
div {
border: 1px solid #eee;
}
div > ul {
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
visibility: visible;
opacity: 1;
}
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
(不要忘记transition
属性的供应商前缀)
更多细节在本文中
您需要通过其他方式隐藏元素才能使其生效。
我通过绝对定位两个<div>
并将隐藏的一个设置为opacity: 0
来完成效果opacity: 0
。
如果您甚至将display
属性从none
切换到block
,则不会发生对其他元素的转换。
要解决此问题,请始终允许元素display: block
,但通过调整以下任何方式隐藏元素:
height
设置为0
。 opacity
设置为0
。 overflow: hidden
元素的框架之外。 可能有更多解决方案,但如果您将元素切换为display: none
,则无法执行转换。例如,您可能尝试尝试这样的事情:
div {
display: none;
transition: opacity 1s ease-out;
opacity: 0;
}
div.active {
opacity: 1;
display: block;
}
但是,这是行不通的。根据我的经验,我发现这无所事事。
因此,您将始终需要保持元素display: block
- 但您可以通过执行以下操作来绕过它:
div {
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
overflow: hidden;
}
div.active {
opacity: 1;
height: auto;
}
在本文发表时,如果您尝试更改display
属性,所有主流浏览器都会禁用 CSS 过渡,但 CSS 动画仍然可以正常工作,因此我们可以将它们用作解决方法。
示例代码: - (您可以相应地将它应用于您的菜单) 演示
将以下 CSS 添加到样式表: -
@-webkit-keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
然后将fadeIn
动画应用于父 hover 上的子项: - (当然还设置display: block
)
.parent:hover .child {
display: block;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
}
(有些 JS 需要)
// We need to keep track of faded in elements so we can apply fade out later in CSS
document.addEventListener('animationstart', function (e) {
if (e.animationName === 'fade-in') {
e.target.classList.add('did-fade-in');
}
});
document.addEventListener('animationend', function (e) {
if (e.animationName === 'fade-out') {
e.target.classList.remove('did-fade-in');
}
});
div {
border: 5px solid;
padding: 10px;
}
div:hover {
border-color: red;
}
.parent .child {
display: none;
}
.parent:hover .child {
display: block;
animation: fade-in 1s;
}
.parent:not(:hover) .child.did-fade-in {
display: block;
animation: fade-out 1s;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="parent">
Parent
<div class="child">
Child
</div>
</div>