使用 CSS 过渡动画最大高度

Posted

技术标签:

【中文标题】使用 CSS 过渡动画最大高度【英文标题】:Animating max-height with CSS transitions 【发布时间】:2013-04-08 09:01:26 【问题描述】:

我想创建一个仅由类名驱动的展开/折叠动画(javascript 用于切换类名)。

我正在上一节课max-height: 4em; overflow: hidden;

还有另一个max-height: 255em;(我也试过none这个值,根本没有动画)

这个动画:transition: max-height 0.50s ease-in-out;

我使用 CSS 过渡在它们之间切换,但浏览器似乎正在为所有这些额外的 em 设置动画,因此它会在折叠效果中产生延迟。

有没有一种方法(本着同样的精神 - 使用 css 类名)没有那种副作用(我可以降低像素数,但这显然有缺点,因为它可能会切断合法性text - 这就是价值大的原因,所以它不会切断合法的长文本,只会切断可笑的长文本)

查看 jsFiddle - http://jsfiddle.net/wCzHV/1/(点击文本容器)

【问题讨论】:

不完美的解决方案:jsfiddle.net/wCzHV/2 这可以接受吗? @Passerby - 可能有负边距,但您的示例似乎不支持具有任意高度或暴露预设数量的行(这些东西在原始文件中都得到支持并且是必不可少的) 这就是为什么我不将其作为答案发布的原因。这个问题已经在 SO 上被问过,我想说在纯 CSS 中实现几乎是不可能的(如果你不想硬编码一些值)。如果你真的需要这样做,请使用 JS。 我担心它可能不可能,这太糟糕了,我讨厌看到它几乎可以工作 【参考方案1】:

如果有人正在阅读本文,我还没有找到解决方案并使用了仅扩展效果(通过将 transition 样式移动到扩展类定义来实现)

【讨论】:

您介意将解决方案发布在 JS Fiddle 或类似文件中吗? 现在是 2016 年,仍然没有解决方案。真可惜。【参考方案2】:

您可以使用jQuery Transit 完成此操作:

$(function () 
    $(".paragraph").click(function () 
        var expanded = $(this).is(".expanded");
        if (expanded) 
        
            $(this).transition( 'max-height': '4em', overflow: 'hidden' , 500, 'in', function () $(this).removeClass("expanded"); );
         
        else 
        
            $(this).transition( 'max-height': $(this).get(0).scrollHeight, overflow: '', 500, 'out', function ()  $(this).addClass("expanded"); );
        
    );
);

您绝对可以根据自己的喜好整理一下,但这应该可以满足您的需求。

JS Fiddle Demo

【讨论】:

谢谢,我知道使用 javascript 的方法,我想要一种方法,只需更改类名即可【参考方案3】:

这是一个老问题,但我只是想出了一个办法,想把它贴在某个地方,这样我就知道在哪里可以找到它,如果我再次需要它:o)

所以我需要一个带有可点击的“sectionHeading”div 的手风琴,可以显示/隐藏相应的“sectionContent”div。部分内容 div 具有可变高度,这会产生问题,因为您无法将高度设置为 100%。我已经看到其他建议使用动画 max-height 的答案,但这意味着有时当您使用的 max-height 大于实际高度时会出现延迟。

这个想法是在加载时使用 jQuery 来查找并明确设置“sectionContent”div 的高度。然后为每个点击处理程序添加一个 css 类 'noHeight' 来切换它:

$(document).ready(function() 
    $('.sectionContent').each(function() 
        var h = $(this).height();
        $(this).height(h).addClass('noHeight');
    );
    $('.sectionHeader').click(function() 
        $(this).next('.sectionContent').toggleClass('noHeight');
    );
);

为了完整起见,相关的css类:

.sectionContent 
    overflow: hidden;
    -webkit-transition: all 0.3s ease-in;
    -moz-transition: all 0.3s ease-in;
    -o-transition: all 0.3s ease-in;
    transition: all 0.3s ease-in;

.noHeight 
        height: 0px !important;

现在高度转换工作没有任何延迟。

【讨论】:

就像一个魅力,虽然我注意到如果窗口的大小调整到足以挤压溢出隐藏容器下方的元素,高度不会正确更新。为了解决这个问题,我将手风琴内容放在另一个没有溢出隐藏的 div 中,在页面加载时设置该 div 的高度,然后在页面上放置一个调整大小的处理程序,以确保手风琴的高度始终与内部 div 匹配。效果很好! 据我所知,此解决方案仅在内容具有固定高度(100px/100em/etc)时有效,但如果内容具有自动、未设置、100% 或任何高度,则不会出现动画像这样【参考方案4】:

修复延迟解决方案:

为元素放置cubic-bezier(0, 1, 0, 1)转换函数。

scss

.text 
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);

  &.full 
    max-height: 1000px;
    transition: max-height 1s ease-in-out;
  

css

.text 
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);


.text.full 
  max-height: 1000px;
  transition: max-height 1s ease-in-out;

【讨论】:

实现纯 CSS 的最佳方式。感谢您的提醒,刚才失去了那条曲线。 有人能解释一下&.full 在这种情况下是什么意思吗? @Jakub &.full 说 - “当类 .full 被添加到类 .text 的元素中时,更新 CSS 如下......”它基本上是 SCSS 方式这样做.text.full ,这就是它在普通 CSS 中的样子。它被称为嵌套,是 Sass/SCSS 的一个特性。 这个答案迫切需要一个解释。它得到了相当多的支持,但它似乎不能正常工作。我看到的唯一效果是收缩过渡只有 0.5 秒,而展开过渡只有 1 秒。 在深入研究之后,我可以肯定地说这不是一个修复,它是一种解决方法,甚至不是一个好的解决方法。唯一发生的事情基本上是动画的持续时间较短,而正在使用的功能基本上是一个极端ease-out。所以基本上,你只是快速收缩了 1000px 的最大高度,最后放慢了速度,所以最后一点看起来有点像普通的ease-in-out。再说一遍:不是修复,而是一种解决方法,而且不是一个好的解决方法。【参考方案5】:

解决方案其实很简单。制作一个包含内容的子 div。父 div 将是展开折叠的那个。

加载时,父 div 将具有最大高度。切换时,您可以通过编写document.querySelector('.expand-collapse-inner').clientHeight; 来检查孩子的高度,并使用javascript 设置最大高度。

在你的 CSS 中,你会有这个

.parent 
transition: max-height 250ms;

【讨论】:

【参考方案6】:

使用 display:flex。这将起作用:

.parent > div 
  display: flex;
  flex-direction: column;
  height: 0px;
  max-height: 0px;
  opacity: 0;
  overflow: hidden;
  transition: all 0.3s;


.parent > div.active 
  opacity: 1; 
  height: 100%;
  max-height: none; /* important for animation */

【讨论】:

对我不起作用

以上是关于使用 CSS 过渡动画最大高度的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS:使用 css 过渡动画 ng-hide / ng-show li 的高度

实现鼠标悬浮内容自动撑开的过渡动画

在子元素中添加/删除类时的 CSS3 过渡动画

如何触发css3过渡动画

css3过渡和动画的区别详解

CSS过渡与动画