提问者:小点点

CSS display属性上的转换


我目前正在设计一个CSS‘超级下拉’菜单-基本上是一个常规的CSS只下拉菜单,但一个包含不同类型的内容。

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

有没有办法让第二层菜单从上面的例子‘淡入’时,有人悬停在一个顶层菜单项?

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

我也试过使用身高,但失败得很惨。

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


共3个答案

匿名用户

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

null

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>

匿名用户

您需要通过其他方法隐藏元素以使其工作。

我通过绝对定位

并将隐藏的一个设置为opacity:0来实现这个效果。

如果您甚至将display属性从none切换到block,则不会发生对其他元素的转换。

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

  1. 高度设置为0
  2. 不透明度设置为0
  3. 将元素定位在具有溢出:隐藏的另一个元素的框架之外。

可能有更多的解决方案,但如果将元素切换到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动画应用于父级悬停时的子级(当然还要设置display:block):

.parent:hover .child {
    display: block;
    -webkit-animation: fadeIn 1s;
    animation: fadeIn 1s;
}

(需要一些JavaScript代码)

null

// 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>