【问题标题】:Can I apply a CSS transition to the overflow property?我可以将 CSS 过渡应用于溢出属性吗?
【发布时间】:2015-03-10 09:22:06
【问题描述】:

当单击div 时,我正在尝试将transition-delay 设置为bodyoverflow 属性,方法是向body 添加一个类,如下所示:

$("div").click(function(){
    $("body").addClass("no_overflow");
});
div{
  background:lime;
  height:2000px;
}
.no_overflow{  
 overflow:hidden;
}
body{  
  overflow:auto;
  transition: overflow 0 2s;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>I'm div</div>

但是,这似乎不起作用(没有延迟)。我在这里做错了吗?

我知道这可以通过使用 setTimeout 函数来实现,但想知道为什么不能使用 css 过渡来实现?是否有可以应用 css 过渡的特定样式属性?

【问题讨论】:

  • 我想到,作为替代方案,您可以转换 height 而不是 overflow 属性以实现大致相同的外观。
  • @TylerH:是的,可以尝试。但是为了做到这一点,必须注意浏览器的高度。此外,当overflowhidden 时,它不会以相同的方式裁剪窗口。无论如何,我最终使用了setTimeout。 ;)

标签: css css-transitions


【解决方案1】:

有许多属性无法转换。 overflow 在其中;渲染引擎不知道如何在“隐藏”和“显示”之间转换,因为它们是二元选项,而不是间隔。这与您无法在 display: none;display: block; 之间转换(例如)的原因相同:没有中间阶段可用作转换。

您可以在 Mozilla Developer Network 上查看可以为 here 制作动画的属性列表。

【讨论】:

  • 据我所知,唯一的例外是visibility,因为您只能拥有visiblehiddencollapse ,意味着没有中间,但它仍然尊重动画步骤;这非常适合动画子菜单。
  • @Smithee 我不确定你在说什么 visibility 属性是唯一的例外。有多个 (n > 1) 属性您可以 转换和多个 (n > 1) 您不能 转换。
【解决方案2】:

overflow 不是 CSS 动画属性。你可以看到完整的动画 CSS 属性列表there

【讨论】:

    【解决方案3】:

    您不能在二进制属性之间转换是有道理的,例如 overflow: hidden;overflow: visible 但如果不是“转换”那么它会非常好(在 js 伪代码中:

    setTimeout("applyOverflowVisible()", transitionTime);
    

    当然,您可以在 JavaScript 中自己执行此操作,但是您会在不同位置之间拆分代码,这会使其他人难以理解。我想使用 React 之类的东西会有所帮助,但即使在那里我也想避免将 css 混入 js 中。

    【讨论】:

      【解决方案4】:

      您可以使用animation 模拟延迟:

      $("div").click(function() {
        $("body").addClass("no_overflow");
      });
      div {
        background: lime;
        height: 2000px;
      }
      
      .no_overflow {
        overflow: hidden;
        /* persist overflow value from animation */
        animation: 7s delay-overflow;
      }
      
      body {
        overflow: auto;
      }
      
      @keyframes delay-overflow {
        from { overflow: auto; }
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div>I'm div</div>

      如果您希望 removeClass 有延迟,则必须将单独的动画应用到 .body,并注意两个动画不要重叠,否则它们会相互抵消。

      【讨论】:

      • 太棒了!我一直在寻找一种方法来隐藏模式容器上的滚动条,直到模式的淡入过渡完成。有点hacky,但这成功了。
      • 就是这样!而不是说“不能通过过渡进行动画处理”,而是显示一个仅适用于 css 的解决方案。
      • 是的,这是唯一正确的答案。它有效!
      【解决方案5】:

      如果有人像我一样正在查看答案,以寻找一种方法来为需要溢出的元素的裁剪设置动画 - 这是对我有用的解决方案:clip-path css property,它是可动画的且用途广泛。

      这是一个很酷的工具,可以用来获得动画的正确开始/结束值:https://bennettfeely.com/clippy/

      【讨论】:

        【解决方案6】:

        Dmitry 的答案应该是唯一被接受的答案,因为它是一个纯 CSS 解决方案,将延迟应用于“非动画”属性。不过值得一提的是,应用动画的 CSS 规则应该在每次需要时都能“触发”。

        例如,下面的代码不起作用:

        @keyframes show-overflow {
          from { overflow: hidden; }
        }
        .hideable, .overlay {
          font-size: 36px;
          height: 50px;
        }
        .hideable {
          transition: height 2s;
          overflow: visible;
          animation: show-overflow 2s;  /* this line should be in separate  "triggerable" CSS rule to work */
        }
        .hideable.hidden {
          height: 0;
          overflow: hidden;
        }
        <button onclick="document.getElementById('hideable').classList.toggle('hidden')">
          Clik HERE to hide/show the text below
        </button>
        <div id='hideable' class='hideable'>
          This is the text to hide and show.  
        </div>
        <div class='overlay'>
          This is overlaying text
        </div>

        但是在将标记的属性移动到单独的 CSS 规则之后,一切都按预期工作:

        @keyframes show-overflow {
          from { overflow: hidden; }
        }
        .hideable, .overlay {
          font-size: 36px;
          height: 50px;
        }
        .hideable {
          transition: height 2s;
          overflow: visible;
        }
        .hideable:not(.hidden) {
          animation: show-overflow 2s;  /* now this works! */
        }
        .hideable.hidden {
          height: 0;
          overflow: hidden;
        }
        <button onclick="document.getElementById('hideable').classList.toggle('hidden')">
          Clik HERE to hide/show the text below
        </button>
        <div id='hideable' class='hideable'>
          This is the text to hide and show.  
        </div>
        <div class='overlay'>
          This is overlaying text
        </div>

        【讨论】:

          猜你喜欢
          • 2014-02-14
          • 2015-03-10
          • 2021-07-26
          • 2017-04-12
          • 1970-01-01
          • 2021-10-23
          • 2021-08-07
          • 1970-01-01
          • 2013-05-19
          相关资源
          最近更新 更多