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

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

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

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

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

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


当前回答

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

.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;指针事件:无;以确保隐藏的容器不占用空间并且不响应用户交互。

其他回答

您可以使用转换事件来实现这一点,因此您为转换构建了两个CSS类,一个保存动画,另一个保存display none状态。你在动画结束后切换它们?在我的例子中,如果我按下一个按钮,我可以再次显示div,并删除这两个类。

尝试下面的代码段。。。

$(文档).ready(函数){//分配转换事件$(“table”).on(“animationend webkitAnimationEnd”,“.visibility_switch_off”,函数(事件){//我们检查这是否是我们想要的动画如果(event.originalEvent.animationName==“col_hide_anim”){//在动画之后,我们分配了这个基本上隐藏元素的新类。$(this).addClass(“动画助手显示无”);}});$(“按钮”).click(函数(事件){$(“table tr.hide col”).tggleClass(函数){//我们以切换方式切换动画类。。。//我们知道在动画结束后//动画助手将不显示额外内容//类,当我们需要删除时//根据切换再次显示元素//状态,所以我们在它们之间建立了关系。if($(this).is(“.animation helper display none”)){//我正在切换,然后已经有了上面的课程//我们希望它显示元素,因此我们删除//两个类。。。返回“visibility_switch_off动画助手显示无”;}其他{//这里我们只想隐藏元素,所以我们//添加动画类,另一个将被添加//稍后是animationend事件。。。返回“visibility_switch_off”;}});});});表th{背景色:灰色;}表td{背景色:白色;填充:5px;}.animation助手显示无{显示:无;}表tr.visibility_switch_off{动画填充模式:向前;动画名称:col_hide_anim;动画持续时间:1s;}@-webkit关键帧col_hide_anim{0%{不透明度:1;}100%{不透明度:0;}}@-moz关键帧col_hide_anim{0%{不透明度:1;}100%{不透明度:0;}}@-o-keyframe col_hide_anim{0%{不透明度:1;}100%{不透明度:0;}}@关键帧col_hide_anim{0%{不透明度:1;}100%{不透明度:0;}}<script src=“https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script><表><theader><tr><th>名称</th>年龄</th><th>国家</th></tr></theader><tbody><tr><td>姓名</td>年龄</td><td>国家/地区</td></tr></tbody></table><button>切换-使用渐变动画隐藏“年龄”列,并在</button>之后不显示

从这些答案和其他地方的一些建议中,以下内容非常适合悬停菜单(我在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不允许用于过渡。最大高度的悬停值需要大于菜单的高度。

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

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

我喜欢这个解决方案,因为它避免了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>

吉列尔莫的回答被接受后,CSS2012-04-03的转换规范改变了可见性转换的行为,现在可以在不使用转换延迟的情况下以更短的方式解决此问题:

.myclass > div {
                   transition:visibility 1s, opacity 1s;
                   visibility:hidden;  opacity:0
               }
.myclass:hover > div
               {   visibility:visible; opacity:1 }

为两个转换指定的运行时间通常应为相同的(尽管稍微长一点的可见性时间不是问题)。

有关运行版本,请参阅我的博客文章CSS Transition Visibility。

W.r.t.问题的标题“显示器上的转换:财产”,并回应Rui Marques和josh对公认答案的评论:

如果显示器或使用visibility属性(这可能是本问题中的情况)。

它不会完全删除显示的元素:无,只是使其不可见,但它仍保留在文档流中,并影响以下元素的位置。

完全删除与显示类似的元素的转换:不能使用高度(如其他答案和注释所示)、最大高度或边距顶部/底部进行转换,但也可以参见如何转换高度:0;至高度:自动;使用CSS?以及我的博客文章《显示器和高度财产上的CSS转换解决方案》。

针对GeorgeMillo的评论:需要财产和两个变换:不透明度属性用于创建淡入淡出动画和可见性属性,以避免元素仍在鼠标上反应事件。需要在不透明度上进行过渡以获得视觉效果可见性以延迟隐藏,直到淡出完成。

我怀疑任何刚开始CSS转换的人都会很快发现,如果你同时修改显示属性(block/none),它们就不起作用了。一个尚未提及的解决方法是,您可以继续使用display:block/none来隐藏/显示元素,但将其不透明度设置为0,这样即使在显示为display:block时,它仍然是不可见的。

然后添加另一个CSS类,例如“on”,将不透明度设置为1,并定义不透明度的转换。正如您可能想象的那样,您必须使用JavaScript将“on”类添加到元素中,但至少您仍在使用CSS进行实际转换。

P.S.如果您发现自己需要同时执行display:block和添加class“on”,请使用setTimeout延迟后者。否则,浏览器只会同时看到这两种情况,并禁用转换。