我目前正在设计一个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毫秒)恢复初始值(相当于显示:动画回调中无)。

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

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

其他回答

不使用显示,您可以将元素存储在“屏幕外”,直到您需要它,然后将其位置设置为您想要的位置,同时对其进行转换。然而,这带来了一系列其他设计问题,因此您的里程可能会有所不同。

无论如何,您可能不想使用显示,因为您希望屏幕阅读器可以访问内容,而屏幕阅读器在很大程度上试图遵守可见性规则-即,如果它不应该被眼睛看到,它就不会作为内容显示给代理。

不需要JavaScript,也不需要惊人的最大高度。相反,在文本元素上设置最大高度,并使用字体相对单位,例如rem或em。这样,您可以设置比容器更大的最大高度,同时避免菜单关闭时出现延迟或“弹出”:

HTML

<nav>
  <input type="checkbox" />
  <ul>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
    <li>Link 1</li>
  </ul>
</nav>

CSS

nav input + ul li { // Notice I set max-height on li, not ul
   max-height: 0;
}

nav input:checked + ul li {
   max-height: 3rem; // A little bigger to allow for text-wrapping - but not outrageous
}

请参阅此处的示例:http://codepen.io/mindfullsilence/pen/DtzjE

此解决方案具有极好的兼容性,我还没有见过它:

.hidden-element {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity .5s ease-out;
}

.hidden-element.visible {
  position: static;
  z-index: auto;
  pointer-events: auto;
  visibility: visible;
  opacity: 1;
}

说明:它使用了可见性:隐藏技巧(与“显示和动画”在一个步骤中兼容),但它使用了组合位置:绝对;z指数:-1;指针事件:无;以确保隐藏的容器不占用空间并且不响应用户交互。

根据W3C工作草案2013年11月19日,显示器不是可设置动画的属性。幸运的是,可见性是可设置动画的。您可以用不透明度的过渡(JSFiddle)链接其过渡:

HTML格式:<a href=“http://example.com“id=”foo“>foo”</a><button id=“hide button”>隐藏</button><button id=“show button”>显示</button>CSS:#食品{过渡特性:可见性,不透明度;转换持续时间:0s,1s;}#foo.hidden餐厅{不透明度:0;可见性:隐藏;过渡特性:不透明度,可见性;转换持续时间:1s,0s;转换延迟:0s,1s;}用于测试的JavaScript:var foo=文档.getElementById('fo');document.getElementById('hide-button').onclick=函数(){foo.className=“隐藏”;};document.getElementById('show-button').onclick=函数(){foo.className=“”;};

请注意,如果您只是使链接透明,而不设置可见性:隐藏,那么它将保持可单击状态。

您需要通过其他方式隐藏该元素才能使其工作。

我通过绝对定位<div>s并将隐藏的<div>设置为不透明度:0来实现这一效果。

如果您甚至将显示属性从“无”切换为“块”,则不会在其他元素上进行转换。

要解决此问题,请始终允许元素显示为:块,但通过调整以下任何方式隐藏元素:

将高度设置为0。将不透明度设置为0。将元素放置在另一个溢出的元素的框架之外:隐藏。

可能有更多的解决方案,但如果将元素切换为显示:无,则无法执行转换。例如,您可以尝试以下操作:

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;
}