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

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

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

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

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

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


当前回答

我巧妙的JavaScript技巧是将整个场景分成两个不同的函数!

为了准备工作,声明了一个全局变量并定义了一个事件处理程序:

  var tTimeout;
  element.addEventListener("transitionend", afterTransition, true);//firefox
  element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome

然后,当隐藏元素时,我使用类似这样的方法:

function hide(){
  element.style.opacity = 0;
}

function afterTransition(){
  element.style.display = 'none';
}

为了再现元素,我正在执行以下操作:

function show(){
  element.style.display = 'block';
  tTimeout = setTimeout(timeoutShow, 100);
}

function timeoutShow(){
  element.style.opacity = 1;
}

到目前为止,它是有效的!

其他回答

从这些答案和其他地方的一些建议中,以下内容非常适合悬停菜单(我在Bootstrap 3中使用了这一点):

nav .dropdown-menu {
    display: block;
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 500ms, opacity 300ms;
    -webkit-transition: max-height 500ms, opacity 300ms;
}
nav .dropdown:hover .dropdown-menu {
    max-height: 500px;
    opacity: 1;
    transition: max-height 0, opacity 300ms;
    -webkit-transition: max-height 0, opacity 300ms;
}

如果同时指定两个值,也可以使用height代替max height,因为height:auto不允许用于过渡。最大高度的悬停值需要大于菜单的高度。

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

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

我有一个类似的问题,但我找不到答案。后来几次谷歌搜索把我带到了这里。考虑到我没有找到我所希望的简单答案,我偶然发现了一个既优雅又有效的解决方案。

结果表明,可见性CSS属性具有一个值折叠,通常用于表项。然而,如果在任何其他元素上使用,它会有效地将它们渲染为隐藏的,与显示几乎相同:隐藏,但添加了元素不占用任何空间的功能,您仍然可以为有问题的元素设置动画。

下面是一个简单的例子。

函数toggleVisibility(){let exampleElement=document.querySelector('span');if(exampleElement.classList.incontains('visible')){回来}exampleElement.innerHTML='我不会占用空间!';exampleElement.classList.tggle('hidden');exampleElement.classList.tggle('visible');setTimeout(()=>{exampleElement.classList.tggle('visible');exampleElement.classList.tggle('hidden');}, 3000);}#主要的,主要的{显示:柔性;弯曲方向:柱;宽度:300px;文本对齐:居中;}.隐藏{可见性:塌陷;不透明度:0;过渡:可见性2s,不透明度2s线性;}.可见{可见性:可见;不透明度:1;过渡:可见性0.5s,不透明度0.5s线性;}<div id=“main”><button onclick=“toggleVisibility()”>单击我</按钮><span class=“hidden”></span><span>我会被推回去</span></div>

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

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

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

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

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

您也可以使用此选项:

.dropdown {
    height: 0px;
    width: 0px;
    opacity: .0;
    color: white;
}
.dropdown:hover {
    height: 20px;
    width: 50px;
    opacity: 1;
    transition: opacity 200ms;
    /* Safari */
    -webkit-transition: opacity 200ms;
}