我目前正在设计一个CSS“巨型下拉菜单”——基本上是一个常规的仅限CSS的下拉菜单,但包含不同类型的内容。

目前,CSS 3转换似乎不适用于“display”属性,也就是说,您不能进行从display:none到display:block(或任何组合)的任何转换。

当有人悬停在一个顶级菜单项上时,上面示例中的第二层菜单是否有办法“淡入”?

我知道你可以在visibility:属性上使用转换,但我想不出一种有效的方法。

我也尝试过使用高度,但那只是失败得很惨。

我也意识到,使用JavaScript实现这一点很简单,但我想挑战一下自己,只使用CSS,我觉得我做得有点短。


当前回答

我们可以使用transition delay属性来代替CSS中不存在的回调。

#selector {
    overflow: hidden;  /* Hide the element content, while height = 0 */
    height: 0;
    opacity: 0;
    transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
    height: auto; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

那么,这里发生了什么?

当添加了可见类时,高度和不透明度都会立即开始动画(0毫秒),尽管高度需要0毫秒才能完成动画(相当于display:block),不透明度需要600毫秒。移除可见类后,不透明度开始动画(0毫秒延迟,400毫秒持续时间),高度等待400毫秒,然后立即(0毫秒)恢复初始值(相当于显示:动画回调中无)。

注意,这种方法比使用可见性的方法要好。在这种情况下,元素仍然占据页面上的空间,并且并不总是合适的。

有关更多示例,请参阅本文。

其他回答

显示不是转换工作的财产之一。

有关可以应用转换的CSS财产的列表,请参阅动画CSS财产。请参阅CSS值和单位模块第4级,组合值:插值、相加和累加,了解如何插值。

9.1中列出了CSS 3。来自CSS的财产(只需关闭警告弹出窗口)

我也尝试过使用高度,但那只是失败得很惨。

上次我不得不这样做时,我使用了max height,这是一个可设置动画的属性(虽然它有点黑客,但确实有效),但要注意,对于复杂的页面或使用低端移动设备的用户来说,它可能非常刺耳。

我怀疑,如果显示发生变化,转换被禁用的原因是因为显示实际的功能。它不会改变任何可以想象的流畅动画。

显示:无;可见性:隐藏;是两件完全不同的事情。两者都具有使元素不可见的效果,但具有可见性:隐藏;它仍然呈现在布局中,但只是不明显。隐藏元素仍然占用空间,并且仍然以内联或块、块内联或表的形式呈现,或者以显示元素告诉的方式呈现,并相应地占用空间。其他元素不会自动移动以占用该空间。隐藏元素只是不将其实际像素渲染到输出。

display:另一方面,没有一个实际上阻止元素完全渲染。它不占用任何布局空间。其他原本占据该元素占用的部分或全部空间的元素现在调整为占据该空间,就好像该元素根本不存在一样。

显示不仅仅是另一种视觉属性。它建立了元素的整个呈现模式,例如它是块、内联、内联块、表、表行、表单元格、列表项还是其他任何元素!每一个都有非常不同的布局影响,并且没有合理的方法来动画化或平滑地转换它们(例如,尝试想象从块到内联的平滑转换,反之亦然!)。

这就是为什么如果显示更改(即使更改为none或从none更改为none-none不仅仅是不可见的,它本身的元素渲染模式意味着根本没有渲染!),则会禁用转换。

我感谢所有的回答。以下是我用于类似目的的内容:过渡与动画。

例子:https://jsfiddle.net/grinevri/tcod87Le/22/

<div class="animation"></div>
<div class="transition"></div>
@keyframes animationTo {
  0% { background-color: rgba(0, 0, 0, 0.1); }
  100% { background-color: rgba(0, 0, 0, 0.5); }
}

@keyframes animationFrom {
  0% { background-color: rgba(0, 0, 0, 0.5); }
  100% { background-color: rgba(0, 0, 0, 0.1); }
}

.animation,
.transition{
  margin: 5px;
  height: 100px;
  width: 100px;
  background-color: rgba(0, 0, 0, 0.1);
}

.animation{
  animation: animationFrom 250ms;
}

.animation:hover{
  background-color: rgba(0, 0, 0, 0.5);
  animation: animationTo 250ms;
}

.transition{
  transition: background-color 250ms;
}

.transition:hover{
  background-color: rgba(0, 0, 0, 0.5);
}

总的来说,我发现最好的解决方案是:使用负上边距而不是显示:无。

对我来说效果很好的解决方案是使用一个负的上边距-边距对动画/转换有效-在转换转换后将菜单从页面顶部移开。对我来说,其中一个问题是,即使在使用可见性隐藏之后,它也会占用空间,下面的解决方案(结合绝对定位)解决了这个问题。这样做(并为语义目的将可见性设置为隐藏)几乎与显示:无一样好。但是,请注意,下面的可见性设置是可选的,实际工作是通过负边距完成的。

我喜欢这个解决方案,因为它避免了JavaScript——你可以看到我使用了一个输入元素(隐藏在汉堡图标下面)来隐藏/取消隐藏从屏幕左侧滑入的菜单。一个小小的烦恼是,必须使用“任意大的数字”作为负裕度,但它已经足够好了。IMHO唯一完全干净的解决方案是转换,以支持显示等功能,其中转换只是等待延迟,然后立即转换,但根据当前的CSS标准规范,这里是我的最佳解决方案:

CSS

#menu {
    /* Hide menu */
    position: absolute;
    overflow: hidden;

    margin: -99999px 0 0 -50px;
    padding: 0;
    visibility: hidden;
    transform-origin: 0% 0%;
    transform: translate(-100%, 0);

    transition: margin 0s 0.5s, padding 0s 0.5s, visibility 0s 0.5s, transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0);
}
#menuToggle input:checked~#menu {
    /* Display menu */
    overflow: unset;

    margin: -80px 0 0 -50px;
    padding: 125px 50px 25px 50px;
    visibility: unset;
    transform: none;

    transition: margin 0s 0s, padding 0s 0s, visibility 0s 0s, transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0);
}

HTML

<div id="menuToggle">
    <input type="checkbox" id="chkBurgerMenu" />
    <span></span><span></span><span></span>
    <ul class="navbar-nav">
        <li><a href="#" class="nav-link"">Home</a></li>
        <li><a href="#" class="nav-link"">Link1</a></li>
        <li><a href="#" class="nav-link"">Link2</a></li>
    </ul>
</div>

使用CSS动画淡入:

.item {
     display: none;
}

.item:hover {
     display: block;
     animation: fadeIn 0.5s;
}

@keyframes fadeIn {
     from {
          opacity: 0;
     }

     to {
          opacity: 1;
     }
}