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

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

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

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

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

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


当前回答

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

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

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

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

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

其他回答

您可以连接两个或更多的转换,而可见性是这次方便的地方。

第二部分{边框:1px实心#eee;}div>ul{可见性:隐藏;不透明度:0;过渡:可见性0s,不透明度0.5s线性;}div:悬停>ul{可见性:可见;不透明度:1;}<div><ul><li>项目1</li><li>项目2</li><li>项目3</li></ul></div>

(不要忘记转换属性的供应商前缀。)

更多详情请参阅本文。

您可以简单地使用CSS可见性:hidden/visible而不是display:none/block

div {
    visibility:hidden;
    -webkit-transition: opacity 1s ease-out;
    -moz-transition: opacity 1s ease-out;
    -o-transition: opacity 1s ease-out;
    transition: opacity 1s ease-out;
    opacity: 0;
}

parent:hover > div {
    opacity: 1;
    visibility: visible;
}

现在可以向块特性添加自定义动画。

@keyframes showNav {
  from {opacity: 0;}
  to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
  display: block;
  animation: showNav 250ms ease-in-out both;
}

Demo

在这个演示中,子菜单从display:none变为display:block,并且仍然能够淡入淡出。

我巧妙的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;
}

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

我找到了更好的方法来解决这个问题,你可以使用CSS动画,并为显示项目创造出很棒的效果。

.item {
     display: none;
}

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

@keyframes fade_in_show {
     0% {
          opacity: 0;
          transform: scale(0)
     }

     100% {
          opacity: 1;
          transform: scale(1)
     }
}