1743

我目前正在设计一个 CSS 'mega dropdown' 菜单 - 基本上是一个常规的纯 CSS 下拉菜单,但包含不同类型的内容。

目前,CSS 3 过渡似乎不适用于 'display' 属性,也就是说,您不能进行任何类型的从display: noneto display: block(或任何组合)过渡。

当有人将鼠标悬停在顶级菜单项之一上时,是否有办法让上例中的二级菜单“淡入”?

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

我也尝试过使用高度,但这只是失败了。

我也知道使用 JavaScript 实现这一点很简单,但我想挑战自己只使用 CSS,我想我有点短。

4

36 回答 36

1604

您可以连接两个或更多转换,visibility这一次很方便。

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>

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

更多细节在这篇文章中

于 2011-08-04T14:58:25.047 回答
901

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

我通过<div>绝对定位 s 并将隐藏的设置为来实现效果opacity: 0

如果您甚至将display属性从切换noneblock,则不会发生在其他元素上的转换。

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

  1. 设置height0
  2. 设置opacity0
  3. 将该元素定位在另一个具有overflow: hidden.

可能有更多解决方案,但如果您将元素切换为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;
}
于 2010-07-26T04:20:02.287 回答
343

在撰写本文时,如果您尝试更改display属性,所有主要浏览器都会禁用 CSS 过渡,但 CSS 动画仍然可以正常工作,因此我们可以使用它们作为解决方法。

示例代码(您可以相应地将其应用到您的菜单)演示

将以下 CSS 添加到样式表中:

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}
@keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

然后fadeIn在父悬停时将动画应用于子级(当然还有 set display: block):

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

2019 年更新 - 也支持淡出的方法:

(需要一些 JavaScript 代码)

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

于 2012-02-17T19:25:39.170 回答
123

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

那么,这里发生了什么?

  1. 添加visible类后,两者都heightopacity延迟(0 毫秒)开始动画,但height完成动画需要 0 毫秒(相当于display: block)并opacity需要 600 毫秒。

  2. visible类被移除时,opacity开始动画(0 毫秒延迟,400 毫秒持续时间),高度等待 400 毫秒,然后才立即(0 毫秒)恢复初始值(相当于display: none在动画回调中)。

请注意,这种方法比使用visibility. 在这种情况下,元素仍然占据页面上的空间,并不总是合适的。

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

于 2018-05-26T20:50:24.487 回答
104

我怀疑如果更改则禁用转换的原因display是因为显示实际做了什么。它不会改变任何可以想象的平滑动画的东西。

display: none;visibility: hidden;是两个完全不同的东西。
两者都具有使元素不可见的效果,但visibility: hidden;它仍然在布局中呈现,只是不可见
隐藏元素仍然占用空间,并且仍然内联或作为块或块内联或表格或display元素告诉它渲染的任何内容呈现,并相应地占用空间。
其他元素不会自动移动以占据该空间。隐藏元素只是不会将其实际像素渲染到输出。

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

display不仅仅是另一个视觉属性。
它建立了元素的整个渲染模式,比如它是a block, inline, inline-block, table, table-row, table-cell, list-item, 还是什么的!
它们中的每一个都有非常不同的布局分支,并且没有合理的方法来为它们设置动画或平滑过渡(例如,尝试想象从block到的平滑过渡,inline反之亦然!)。

这就是为什么在显示更改时禁用过渡的原因(即使更改是到或从none-none不仅仅是不可见,它是它自己的元素渲染模式,这意味着根本不渲染!)。

于 2012-06-15T18:55:17.407 回答
57

display不是转换起作用的属性之一。

有关可以应用过渡的 CSS 属性列表,请参阅动画 CSS 属性。参见CSS Values and Units Module Level 4, Combining Values: Interpolation, Addition, and Accumulation了解它们是如何被插值的。

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

我也尝试过使用高度,但这只是失败了。

上次我不得不这样做时,我max-height改用了它,它是一个可动画的属性(虽然它有点小技巧,但它确实有效),但要注意它对于复杂页面或使用低端移动设备的用户可能会非常笨拙设备。

于 2011-09-22T23:24:27.620 回答
42

我找到了解决这个问题的更好方法,您可以使用 CSS Animation 并制作令人敬畏的效果来显示项目。

.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)
     }
}
于 2019-12-15T18:15:18.883 回答
37

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

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

演示

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

于 2014-07-29T20:51:31.607 回答
25

根据W3C 工作草案 2013 年 11 月 19 日 display不是动画属性。幸运的是,visibility是动画的。您可以将其转换与不透明度转换(JSFiddle)链接起来:

  • HTML:

    <a href="http://example.com" id="foo">Foo</a>
    <button id="hide-button">Hide</button>
    <button id="show-button">Show</button>
    
  • CSS:

    #foo {
        transition-property: visibility, opacity;
        transition-duration: 0s, 1s;
    }
    
    #foo.hidden {
        opacity: 0;
        visibility: hidden;
        transition-property: opacity, visibility;
        transition-duration: 1s, 0s;
        transition-delay: 0s, 1s;
    }
    
  • 用于测试的 JavaScript:

    var foo = document.getElementById('foo');
    
    document.getElementById('hide-button').onclick = function () {
        foo.className = 'hidden';
    };
    
    document.getElementById('show-button').onclick = function () {
        foo.className = '';
    };
    

请注意,如果您只是使链接透明而不设置visibility: hidden,那么它将保持可点击状态。

于 2014-02-02T14:59:39.173 回答
19

编辑:在此示例中未应用显示无。

@keyframes hide {
  0% {
    display: block;
    opacity: 1;
  }
  99% {
    display: block;
  }
  100% {
    display: none;
    opacity: 0;
  }
}

上面发生的情况是,99% 的动画显示被设置为阻塞,而不透明度逐渐消失。在最后一刻显示属性设置为无。

而最重要的一点是使用animation-fill-mode: forwards保留动画结束后的最后一帧

.hide {
   animation: hide 1s linear;
   animation-fill-mode: forwards;
}

这里有两个例子:https ://jsfiddle.net/qwnz9tqg/3/

于 2015-10-30T05:27:21.257 回答
17

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

它有效,到目前为止!

于 2012-12-14T21:55:24.283 回答
15

我今天遇到了这个问题,position: fixed我正在重用一个模态。我无法保留它display: none然后对其进行动画处理,因为它刚刚出现,并且z-index(负值等)也做了一些奇怪的事情。

我也在使用height: 0to height: 100%,但它只在模态出现时才起作用。这就像你使用left: -100%过的一样。

然后我突然想到有一个简单的答案。瞧:

首先,您的隐藏模式。注意heightis 0,并查看转换中的height声明......它有一个500ms它比我的opacitytransition长。请记住,这会影响向外的淡出过渡:将模式返回到其默认状态。

#modal-overlay {
    background: #999;
    background: rgba(33,33,33,.2);
    display: block;
    overflow: hidden;
    height: 0;
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    z-index: 1;
    -webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
       -moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
            -ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
         -o-transition: height 0s 500ms, opacity 300ms ease-in-out;
        transition: height 0s 500ms, opacity 300ms ease-in-out;
}

其次,您的可见模态。假设您将 a 设置.modal-activebody. 现在height100%,我的过渡也发生了变化。我希望height立即更改,并opacity采取300ms.

.modal-active #modal-overlay {
    height: 100%;
    opacity: 1;
    z-index: 90000;
    -webkit-transition: height 0s, opacity 300ms ease-in-out;
       -moz-transition: height 0s, opacity 300ms ease-in-out;
        -ms-transition: height 0s, opacity 300ms ease-in-out;
         -o-transition: height 0s, opacity 300ms ease-in-out;
            transition: height 0s, opacity 300ms ease-in-out;
}

就是这样,它就像一个魅力。

于 2012-04-19T18:49:30.003 回答
12

从其中一些答案和其他地方的一些建议中得出,以下内容非常适合悬停菜单(特别是我将其与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代替,因为 s不允许使用。悬停值需要大于菜单的可能值。max-heightheight:autotransitionmax-heightheight

于 2013-10-23T15:57:11.580 回答
10

使用CSS Animations淡入淡出:

.item {
     display: none;
}

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

@keyframes fadeIn {
     from {
          opacity: 0;
     }

     to {
          opacity: 1;
     }
}
于 2021-02-15T18:29:53.180 回答
8

我多次遇到过这个问题,现在简单地说:

.block {
  opacity: 1;
  transition: opacity 250ms ease;
}

.block--invisible {
  pointer-events: none;
  opacity: 0;
}

通过添加类block--invisible,整个元素将不可点击,但它后面的所有元素都将是因为pointer-events:none所有主要浏览器都支持它(没有 IE < 11)。

于 2017-08-07T09:22:42.933 回答
7

更改overflow:hiddenoverflow:visible。它工作得更好。我这样使用:

#menu ul li ul {
    background-color:#fe1c1c;
    width:85px;
    height:0px;
    opacity:0;
    box-shadow:1px 3px 10px #000000;
    border-radius:3px;
    z-index:1;
    -webkit-transition:all 0.5s ease;
    -moz-transition:all 0.6s ease;
}

#menu ul li:hover ul  {
    overflow:visible;
    opacity:1;
    height:140px;
}

visible更好,因为overflow:hidden行为完全像 a display:none

于 2012-09-09T14:51:14.150 回答
7

它就像以下一样简单:)

@keyframes fadeout {
    0% { opacity: 1; height: auto; }
    90% { opacity: 0; height: auto; }
    100% { opacity: 0; height: 0;
}
animation: fadeout linear 0.5s 1 normal forwards !important;

让它消失,然后让它消失height 0;。还要确保使用 forwards 以使其保持在最终状态。

于 2019-05-29T18:06:32.533 回答
6

不需要 JavaScript,也不需要极大的最大高度。相反,设置您max-height的文本元素,并使用字体相对单位,例如remor 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

于 2014-05-12T20:18:43.267 回答
6

在编写了 Guillermo 接受的答案后,2012-04-03 的 CSS 过渡规范改变了可见性过渡的行为,现在可以在不使用过渡延迟的情况下以更短的方式解决这个问题:

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

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

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

写下问题“显示器上的转换:属性”的标题,并回应 Rui Marques 和 josh 对已接受答案的评论:

此解决方案适用于与使用 display 或 visibility 属性无关的情况(就像这个问题中的情况一样)。

它不会完全删除元素 as display:none,只是使其不可见,但它仍然停留在文档流中并影响后续元素的位置。

display:none可以使用高度(如其他答案和评论所示)、最大高度或边距顶部/底部来 完成完全删除类似元素的转换,但另请参阅我如何转换高度:0;到高度:自动;使用 CSS?和我的博文 Workarounds for CSS Transitions on the Display and Height Properties

回应 GeorgeMillo 的评论: 需要两个属性和两个转换: opacity 属性用于创建淡入和淡出动画,而 visibility 属性用于避免元素仍然对鼠标事件做出反应。视觉效果的不透明度和可见性需要过渡以延迟隐藏直到淡出完成。

于 2014-08-16T09:45:41.090 回答
6

opacity通过结合position absolute(隐藏时不占用空间),我终于找到了一个解决方案。

.toggle {
  opacity: 0;
  position: absolute;
  transition: opacity 0.8s;
}

.parent:hover .toggle {
  opacity: 1;
  position: static;
}
于 2017-10-16T18:07:01.643 回答
5

你可以让它以你期望的自然方式工作 - 使用显示 - 但你必须限制浏览器才能让它工作,使用 Javascript 或其他人建议的一个花哨的技巧,一个标签内有另一个标签。我不关心内部标签,因为它使 CSS 和尺寸进一步复杂化,所以这里是 Javascript 解决方案:

https://jsfiddle.net/b9chris/hweyecu4/17/

从一个盒子开始,如:

<div id="box" class="hidden">Lorem</div>

一个隐藏的盒子。

div.hidden {
    display: none;
}
#box {
    transition: opacity 1s;
}
    

我们将使用在相关 q/a 中找到的技巧,检查 offsetHeight 以立即限制浏览器:

https://stackoverflow.com/a/16575811/176877

首先,将上述技巧形式化的库:

$.fn.noTrnsn = function () {
    return this.each(function (i, tag) {
        tag.style.transition = 'none';
    });
};
$.fn.resumeTrnsn = function () {
    return this.each(function (i, tag) {
        tag.offsetHeight;    
        tag.style.transition = null;
    });
};

接下来,我们将使用它来显示一个框,并将其淡入:

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden'))
        tag.noTrnsn().removeClass('hidden')
        .css({ opacity: 0 })
        .resumeTrnsn().css({ opacity: 1 });
    else
        tag.css({ opacity: 0 });
});

这会使盒子淡入淡出。所以,.noTrnsn()关闭转换,然后我们删除类,它从hidden翻转到它的默认值,. 然后我们将不透明度设置为 0 以准备淡入。现在我们已经设置好舞台,我们重新打开过渡,使用. 最后,通过将不透明度设置为 1 来开始过渡。displaynoneblock.resumeTrnsn()

如果没有库,对显示的更改和对不透明度的更改都会给我们带来不希望的结果。如果我们简单地删除库调用,我们根本不会得到任何转换。

请注意,上面没有在淡出动画结束时再次将 display 设置为 none。不过我们可以变得更漂亮。让我们用一个从 0 开始淡入并在高度上增长的东西来做。

想要!

https://jsfiddle.net/b9chris/hweyecu4/22/

#box {
    transition: height 1s, opacity 1s;
}

我们现在正在转换高度和不透明度。请注意,我们没有设置高度,这意味着它是默认值,auto. 按照惯例,这不能转换 - 从自动移动到像素值(如 0)将使您没有转换。我们将使用库和另一种库方法来解决这个问题:

$.fn.wait = function (time, fn) {
    if (time)
        this.delay(time);
    if (!fn)
        return this;

    var _this = this;
    return this.queue(function (n) {
        fn.call(_this);
        n();
    });
};

这是一种方便的方法,可以让我们参与 jQuery 现有的 fx/animation 队列,而不需要任何现在在 jQuery 3.x 中排除的动画框架。我不打算解释 jQuery 是如何工作的,但我只想说,jQuery 提供的.queue()管道.stop()可以帮助我们防止动画相互踩踏。

让我们为滑下效果制作动画。

$('#button').on('click', function() {
    var tag = $('#box');
    if (tag.hasClass('hidden')) {
        // Open it
        // Measure it
        tag.stop().noTrnsn().removeClass('hidden').css({
            opacity: 0, height: 'auto'
        });
        var h = tag.height();
        tag.css({ height: 0 }).resumeTrnsn()
        // Animate it
        .css({ opacity: 1, height: h })
        .wait(1000, function() {
            tag.css({ height: 'auto' });
        });
    } else {
        // Close it
        // Measure it
        var h = tag.noTrnsn().height();
        tag.stop().css({ height: h })
        .resumeTrnsn()
        // Animate it
        .css({ opacity: 0, height: 0 })
        .wait(1000, function() {
            tag.addClass('hidden');
        });
    }
});

这段代码首先检查#box它是否是隐藏的,检查它的类。但是它使用wait()库调用完成了更多工作,通过hidden在滑出/淡出动画的末尾添加类,如果它实际上是隐藏的,您希望找到它 - 这是上面更简单的示例无法做到的。这恰好也启用了一遍又一遍地显示/隐藏元素,这是前面示例中的一个错误,因为隐藏的类从未恢复。

您还可以看到在调用 CSS 和类更改之后.noTrnsn()通常会为动画设置舞台,包括进行测量,例如在调用之前测量最终高度#box而不向用户显示的最终高度.resumeTrnsn(),并从完整设置中对其进行动画处理阶段到其目标 CSS 值。

旧答案

https://jsfiddle.net/b9chris/hweyecu4/1/

你可以让它在点击时转换:

function toggleTransition() {
  var el = $("div.box1");

  if (el.length) {
    el[0].className = "box";
    el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
        el[0].className = "box hidden";
    });
  } else {
    el = $("div.box");
    el[0].className = "box";
    el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
        el[0].className = "box box1";
    });
  }

  return el;
}

someTag.click(toggleTransition);

CSS是你猜的:

.hidden {
    display: none;
}
.box {
    width: 100px;
    height: 100px;
    background-color: blue;
    color: yellow;
    font-size: 18px;
    left: 20px;
    top: 20px;
    position: absolute;
    -webkit-transform-origin: 0 50%;
    transform-origin: 0 50%;
    -webkit-transform: scale(.2);
    transform: scale(.2);
    -webkit-transition: transform 2s;
    transition: transform 2s;
}
.box1{
    -webkit-transform: scale(1);
    transform: scale(1);
}

关键是限制显示属性。通过移除隐藏的类,然后等待 50 毫秒,然后通过添加的类开始转换,我们让它出现,然后像我们想要的那样展开,而不是它只是在没有任何动画的情况下闪烁到屏幕上。类似的情况发生在另一个方面,除了我们等到动画结束后再应用隐藏。

注意:我在.animate(maxWidth)这里滥用以避免setTimeout竞争条件。setTimeout当您或其他人在不知情的情况下拾取代码时,会很快引入隐藏的错误。.animate()很容易被杀死.stop()。我只是用它在标准 fx 队列上放置 50 毫秒或 2000 毫秒的延迟,在此基础上构建的其他编码器很容易找到/解决。

于 2016-06-15T18:13:06.080 回答
5

我很感激所有的答案。这是我用于类似目的的内容:过渡与动画。

示例:https ://jsfiddle.net/grinevri/tcod87Le/22/

<div class="animation"></div>
<div class="transition"></div>
@keyframes animationTo {
  0% { background-color: rgba(0, 0, 0, 0.1); }
  100% { background-color: rgba(0, 0, 0, 0.5); }
}

@keyframes animationFrom {
  0% { background-color: rgba(0, 0, 0, 0.5); }
  100% { background-color: rgba(0, 0, 0, 0.1); }
}

.animation,
.transition{
  margin: 5px;
  height: 100px;
  width: 100px;
  background-color: rgba(0, 0, 0, 0.1);
}

.animation{
  animation: animationFrom 250ms;
}

.animation:hover{
  background-color: rgba(0, 0, 0, 0.5);
  animation: animationTo 250ms;
}

.transition{
  transition: background-color 250ms;
}

.transition:hover{
  background-color: rgba(0, 0, 0, 0.5);
}
于 2021-06-22T06:51:41.153 回答
4

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

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

PS 如果您发现自己需要同时执行这两项操作display:block,并添加“on”类,同时使用 setTimeout 推迟后者。否则,浏览器只会同时看到这两种情况并禁用转换。

于 2012-02-25T22:50:52.073 回答
4

在这种情况下不使用关键帧来应用过渡的另一种方法是将元素的宽度设置为零,然后在悬停时取消设置

.className{
  visibility:hidden;
  opacity: 0;
  transition: .2s;
  width:0;
}

.className:hover{
  visibility:visible;
  margin-right: .5rem;
  opacity: 1;
  width:unset;
}
于 2020-10-01T19:33:29.467 回答
3

该问题最简单的通用解决方案是:随意display:none在您的 CSS 中指定,但是您必须使用 JavaScript 将其更改为block(或其他任何内容),然后您还必须向您的元素添加一个类,实际上使用 setTimeout()进行转换。就这样。

IE:

<style>
    #el {
        display: none;
        opacity: 0;
    }
    #el.auto-fade-in {
        opacity: 1;
        transition: all 1s ease-out; /* Future, future, please come sooner! */
        -webkit-transition: all 1s ease-out;
        -moz-transition: all 1s ease-out;
        -o-transition: all 1s ease-out;
    }
</style>

<div id=el>Well, well, well</div>

<script>
    var el = document.getElementById('el');
    el.style.display = 'block';
    setTimeout(function () { el.className = 'auto-fade-in' }, 0);
</script>

这是在最新的理智浏览器中测试的。显然它不应该在 Internet Explorer 9 或更早版本中工作。

于 2012-08-30T20:49:55.780 回答
3

我认为 SalmanPK 有最接近的答案。它确实使用以下 CSS 动画淡入或淡出项目。但是,显示属性的动画并不流畅,只有不透明度。

@-webkit-keyframes fadeIn {
    from { opacity: 0; }
      to { opacity: 1; }
}

@-webkit-keyframes fadeOut {
    from { opacity: 1; }
      to { opacity: 0; }
}

如果您想为从显示块移动到不显示的元素设置动画,我看不出目前仅使用 CSS 就可以实现。您必须获取高度并使用 CSS 动画来降低高度。如下例所示,使用 CSS 可以做到这一点,但要知道为元素设置动画所需的确切高度值会很棘手。

jsFiddle 示例

CSS

@-webkit-keyframes pushDown {
  0% {
    height: 10em;
  }
  25% {
    height: 7.5em;
  }
  50% {
    height: 5em;
  }
  75% {
    height: 2.5em;
  }
  100% {
    height: 0em;
  }
}

.push-down {
    -webkit-animation: pushDown 2s forwards linear;
}

JavaScript

var element = document.getElementById("element");

// Push item down
element.className = element.className + " push-down";
于 2015-05-05T04:18:26.363 回答
3

这个方案兼容性很好,我还没见过:

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

解释:它使用了visibility: hidden技巧(与“show-and-animate”在一个步骤中兼容),但它使用组合position: absolute; z-index: -1; pointer-events: none;来确保隐藏容器不占用空间并且不响应用户交互

于 2016-05-04T20:45:29.897 回答
3

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

试试下面的片段...

$(document).ready(function() {
  // Assign transition event
  $("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
    // We check if this is the same animation we want
    if (event.originalEvent.animationName == "col_hide_anim") {
      // After the animation we assign this new class that basically hides the elements.
      $(this).addClass("animation-helper-display-none");
    }

  });

  $("button").click(function(event) {

    $("table tr .hide-col").toggleClass(function() {
      // We switch the animation class in a toggle fashion...
      // and we know in that after the animation end, there
      // is will the animation-helper-display-none extra
      // class, that we nee to remove, when we want to
      // show the elements again, depending on the toggle
      // state, so we create a relation between them.
      if ($(this).is(".animation-helper-display-none")) {
        // I'm toggling and there is already the above class, then
        // what we want it to show the elements , so we remove
        // both classes...
        return "visibility_switch_off animation-helper-display-none";
      }
      else {
        // Here we just want to hide the elements, so we just
        // add the animation class, the other will be added
        // later be the animationend event...
        return "visibility_switch_off";
      }
    });
  });
});
table th {
  background-color: grey;
}

table td {
  background-color: white;
  padding: 5px;
}

.animation-helper-display-none {
  display: none;
}

table tr .visibility_switch_off {
  animation-fill-mode: forwards;
  animation-name: col_hide_anim;
  animation-duration: 1s;
}

@-webkit-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-moz-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@-o-keyframes col_hide_anim {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes col_hide_anim {
  0%   {opacity: 1;}
  100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <theader>
    <tr>
      <th>Name</th>
      <th class='hide-col'>Age</th>
      <th>Country</th>
    </tr>
  </theader>
  <tbody>
    <tr>
      <td>Name</td>
      <td class='hide-col'>Age</td>
      <td>Country</td>
    </tr>
  </tbody>
</table>

<button>Switch - Hide Age column with fadeout animation and display none after</button>

于 2017-03-16T13:13:31.403 回答
3

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

事实证明,visibilityCSS 属性有一个collapse通常用于表格项目的值。但是,如果在任何其他元素上使用它,它会有效地将它们呈现为hidden,几乎相同,display: hidden但具有元素不占用任何空间的附加功能,您仍然可以为相关元素设置动画。

下面是一个简单的例子。

function toggleVisibility() {
  let exampleElement = document.querySelector('span');
  if (exampleElement.classList.contains('visible')) {
    return;
  }
  exampleElement.innerHTML = 'I will not take up space!';
  exampleElement.classList.toggle('hidden');
  exampleElement.classList.toggle('visible');
  setTimeout(() => {
    exampleElement.classList.toggle('visible');
    exampleElement.classList.toggle('hidden');
  }, 3000);
}
#main {
  display: flex;
  flex-direction: column;
  width: 300px;
  text-align: center;
}

.hidden {
  visibility: collapse;
  opacity: 0;
  transition: visibility 2s, opacity 2s linear;
}

.visible {
  visibility: visible;
  opacity: 1;
  transition: visibility 0.5s, opacity 0.5s linear;
}
<div id="main">
  <button onclick="toggleVisibility()">Click Me!</button>
  <span class="hidden"></span>
  <span>I will get pushed back up...</span>
</div>

于 2019-04-29T03:13:25.160 回答
2

我启动了一个名为[Toggle Display Animate][1]的开源框架项目。

这个骨架助手将允许您轻松模仿 jQuery 显示/隐藏,但带有输入/输出 CSS 3 过渡动画。

它使用类切换,因此您可以在元素上使用您想要的任何 CSS 方法,除了 display:none|block|table|inline 等,以及可以想到的其他替代用途。

它的主要设计目的是用于元素切换状态,并且它支持还原状态,隐藏对象允许您反向运行关键帧或播放替代动画以隐藏元素。

我正在研究的概念的大部分标记是 CSS,实际使用的 JavaScript 很少。

于 2017-07-15T22:23:07.830 回答
1

您可以将元素“屏幕外”存储到您需要它之前,而不是display使用它,然后将其位置设置到您想要的位置并同时对其进行转换。但是,这会带来许多其他设计问题,因此您的里程可能会有所不同。

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

于 2010-07-25T22:56:28.337 回答
1

如果您使用 jQuery 来设置您的类,这将 100% 有效:

$(document).ready(function() {
  $('button').click(function() {
    var container = $('.container');
    
    if (!container.hasClass('active')) {
      container.addClass('show').outerWidth();
      container.addClass('active');
    }
    else {
      container.removeClass('active').one('transitionend', function() {
        container.removeClass('show');
      });
    }
  });
});
.container {
  display: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.container.show {
  display: flex;
}
 
.container.active {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Toggle</button>

<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

当然,您可以只使用 jQuery.fadeIn().fadeOut()函数,但设置类的好处是,以防您想要转换到显示值以外的显示值block(默认情况下使用.fadeIn()and .fadeOut())。

在这里,我正在过渡到flex具有很好的淡入淡出效果的显示。

于 2018-10-26T10:08:19.127 回答
0

您可以简单地使用 CSS visibility : 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;
}
于 2013-01-23T12:58:36.910 回答
0

你也可以使用这个:

.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;
}
于 2013-07-24T14:28:29.013 回答
0

它可以通过使用过渡定时功能step-endstep-start

例如:https ://jsfiddle.net/y72h8Lky/

$(".run").on("click", function() {
    $(".popup").addClass("show");
});
$(".popup").on("click", function() {
    $(".popup").removeClass("show");
})
.popup {
    opacity: 0;
    display: block;
    position: absolute;
    top: 100%;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1450;
    background-color: rgba(0, 175, 236, 0.6);
    transition: opacity 0.3s ease-out, top 0.3s step-end;
}
.popup.show {
    transition: opacity 0.3s ease-out, top 0.3s step-start;
    opacity: 1;
    top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="popup"></div>
<button class="run" style="font-size: 24px;">Click on me</button>

于 2017-06-02T23:16:30.153 回答
0

在我的情况下,我使用 Jquery 的切换功能来管理显示块/无属性,所以我没有在它上面使用 css,而是切换到了slideToggle,这对我来说是诀窍。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>slideToggle demo</title>
  <style>
  p {
    width: 400px;
  }
  </style>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<button id="toggle-button">Toggle</button>
<button id="slide-toggle-button">Slide Toggle</button>
<p>
  This is the paragraph to end all paragraphs.  You
  should feel <em>lucky</em> to have seen such a paragraph in
  your life.  Congratulations!
</p>
 
<script>
$( "#toggle-button" ).click(function() {
   $( "p" ).toggle();
});
$( "#slide-toggle-button" ).click(function() {
  $( "p" ).slideToggle( "slow" );
});
</script>
 
</body>
</html>

于 2022-02-24T09:18:19.267 回答