关于css3:我如何转换高度:0;

How can I transition height: 0; to height: auto; using CSS?

我正在尝试使用CSS转换使

    向下滑动。

      height: 0;开始。悬停时,高度设置为height:auto;。然而,这使得它看起来很简单,而不是过渡,

      如果我从height: 40px;height: auto;,它就会滑到height: 0;,然后突然跳到正确的高度。

      如果不使用javascript,我还能怎么做?

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      #child0 {
        height: 0;
        overflow: hidden;
        background-color: #dedede;
        -moz-transition: height 1s ease;
        -webkit-transition: height 1s ease;
        -o-transition: height 1s ease;
        transition: height 1s ease;
      }
      #parent0:hover #child0 {
        height: auto;
      }
      #child40 {
        height: 40px;
        overflow: hidden;
        background-color: #dedede;
        -moz-transition: height 1s ease;
        -webkit-transition: height 1s ease;
        -o-transition: height 1s ease;
        transition: height 1s ease;
      }
      #parent40:hover #child40 {
        height: auto;
      }
      h1 {
        font-weight: bold;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      The only difference between the two snippets of CSS is one has height: 0, the other height: 40.


        Hover me (height: 0)
        Some content
          Some content
          Some content
          Some content
          Some content
          Some content
         
       



        Hover me (height: 40)
        Some content
          Some content
          Some content
          Some content
          Some content
          Some content


      转换时使用max-height,不使用height。在EDOCX1[4]上设置一个值,使其大于您的框所能得到的值。

      请参阅Chris约旦在另一个答案中提供的jfiddle演示。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      #menu #list {
          max-height: 0;
          transition: max-height 0.15s ease-out;
          overflow: hidden;
          background: #d5d5d5;
      }

      #menu:hover #list {
          max-height: 500px;
          transition: max-height 0.25s ease-in;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
          hover me
          <ul id="list">
              <!-- Create a bunch, or not a bunch, of li's to see the timing. -->
             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

         
      </ul>


      你应该用scaley代替。

      HTML:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      <p>
      Here (scaleY(1))
      </p>

      <ul>

       
      <li>
      Coffee
      </li>

       
      <li>
      Tea
      </li>

       
      <li>
      Milk
      </li>


      </ul>

      CSS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      ul {
          background-color: #eee;
          transform: scaleY(0);    
          transform-origin: top;
          transition: transform 0.26s ease;
      }

      p:hover ~ ul {
          transform: scaleY(1);
      }

      我在jsFiddle上制作了一个以供应商为前缀的上述代码版本,http://jsfiddle.net/dotnetcompenter/phyqc/9/,并将您的jsFiddle更改为使用scaley而不是height,http://jsfiddle.net/dotnetcompenter/7cnfc/206/。


      当涉及的一个高度是auto时,您当前无法在高度上设置动画,必须设置两个明确的高度。


      我一直使用的解决方案是先淡出,然后缩小font-sizepaddingmargin值。它看起来与擦除不同,但它在没有静态heightmax-height的情况下工作。

      工作示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      /* final display */
      #menu #list {
          margin: .5em 1em;
          padding: 1em;
      }

      /* hide */
      #menu:not(:hover) #list {
          font-size: 0;
          margin: 0;
          opacity: 0;
          padding: 0;
          /* fade out, then shrink */
          transition: opacity .25s,
                      font-size .5s .25s,
                      margin .5s .25s,
                      padding .5s .25s;
      }

      /* reveal */
      #menu:hover #list {
          /* unshrink, then fade in */
          transition: font-size .25s,
                      margin .25s,
                      padding .25s,
                      opacity .5s .25s;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
          hover me
          <ul id="list">
             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

         
      </ul>



      <p>
      Another paragraph...
      </p>


      你可以,用一些非语义的诡计。我通常的方法是设置一个外部分区的高度动画,这个外部分区只有一个子分区,它是一个没有样式的分区,只用于测量内容高度。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function growDiv() {
        var growDiv = document.getElementById('grow');
        if (growDiv.clientHeight) {
          growDiv.style.height = 0;
        } else {
          var wrapper = document.querySelector('.measuringWrapper');
          growDiv.style.height = wrapper.clientHeight +"px";
        }
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #grow {
        -moz-transition: height .5s;
        -ms-transition: height .5s;
        -o-transition: height .5s;
        -webkit-transition: height .5s;
        transition: height .5s;
        height: 0;
        overflow: hidden;
        outline: 1px solid red;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      <input type="button" onclick="growDiv()" value="grow">

       
         
            The contents of my div.
         
         
            The contents of my div.
         
         
            The contents of my div.
         
         
            The contents of my div.
         
         
            The contents of my div.
         
         
            The contents of my div.

      我们只想不使用.measuringWrapper,只需将div的高度设置为auto,并设置动画,但这似乎不起作用(高度已设置,但没有动画发生)。

      1
      2
      3
      4
      5
      6
      7
      8
      function growDiv() {
        var growDiv = document.getElementById('grow');
        if (growDiv.clientHeight) {
          growDiv.style.height = 0;
        } else {
          growDiv.style.height = 'auto';
        }
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #grow {
        -moz-transition: height .5s;
        -ms-transition: height .5s;
        -o-transition: height .5s;
        -webkit-transition: height .5s;
        transition: height .5s;
        height: 0;
        overflow: hidden;
        outline: 1px solid red;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <input type="button" onclick="growDiv()" value="grow">

       
          The contents of my div.
       
       
          The contents of my div.
       
       
          The contents of my div.
       
       
          The contents of my div.
       
       
          The contents of my div.
       
       
          The contents of my div.

      我的解释是动画运行需要一个明确的高度。当高度(起始高度或结束高度)为auto时,无法获得高度动画。


      我知道这是30多岁的人对这个问题的回答,但我认为这是值得的,所以我来看看。这是一个仅限于CSS的解决方案,具有以下属性:好的。

      • 开始的时候没有延误,过渡也没有提前停止。在两个方向上(展开和折叠),如果在CSS中指定了300毫秒的转换持续时间,则转换需要300毫秒,周期。
      • 它转换了实际高度(与transform: scaleY(0)不同),所以如果可折叠元素后面有内容,它就做了正确的事情。
      • 虽然(和其他解决方案一样)有一些神奇的数字(比如"选择一个比你的盒子更高的长度"),但如果你的假设最终是错误的,那就不是致命的。在这种情况下,转换看起来可能并不令人惊讶,但在转换前后,这不是问题:在扩展(height: auto状态下,整个内容始终具有正确的高度(与选择的max-height高度过低不同)。在崩溃状态下,高度应该是零。

      演示

      这是一个演示,有三个可折叠的元素,高度不同,都使用相同的CSS。单击"运行代码段"后,您可能需要单击"整页"。注意,javascript只切换collapsedcss类,不涉及度量。(您可以使用复选框或:target在完全不使用任何javascript的情况下进行这个精确的演示)。还要注意,负责转换的CSS部分非常短,HTML只需要一个额外的包装器元素。好的。

      1
      2
      3
      4
      5
      6
      $(function () {
        $(".toggler").click(function () {
          $(this).next().toggleClass("collapsed");
          $(this).toggleClass("toggled"); // this just rotates the expander arrow
        });
      });
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      .collapsible-wrapper {
        display: flex;
        overflow: hidden;
      }
      .collapsible-wrapper:after {
        content: '';
        height: 50px;
        transition: height 0.3s linear, max-height 0s 0.3s linear;
        max-height: 0px;
      }
      .collapsible {
        transition: margin-bottom 0.3s cubic-bezier(0, 0, 0, 1);
        margin-bottom: 0;
        max-height: 1000000px;
      }
      .collapsible-wrapper.collapsed > .collapsible {
        margin-bottom: -2000px;
        transition: margin-bottom 0.3s cubic-bezier(1, 0, 1, 1),
                    visibility 0s 0.3s, max-height 0s 0.3s;
        visibility: hidden;
        max-height: 0;
      }
      .collapsible-wrapper.collapsed:after
      {
        height: 0;
        transition: height 0.3s linear;
        max-height: 50px;
      }

      /* END of the collapsible implementation; the stuff below
         is just styling for this demo */


      #container {
        display: flex;
        align-items: flex-start;
        max-width: 1000px;
        margin: 0 auto;
      }  


      .menu {
        border: 1px solid #ccc;
        box-shadow: 0 1px 3px rgba(0,0,0,0.5);
        margin: 20px;

       
      }

      .menu-item {
        display: block;
        background: linear-gradient(to bottom, #fff 0%,#eee 100%);
        margin: 0;
        padding: 1em;
        line-height: 1.3;
      }
      .collapsible .menu-item {
        border-left: 2px solid #888;
        border-right: 2px solid #888;
        background: linear-gradient(to bottom, #eee 0%,#ddd 100%);
      }
      .menu-item.toggler {
        background: linear-gradient(to bottom, #aaa 0%,#888 100%);
        color: white;
        cursor: pointer;
      }
      .menu-item.toggler:before {
        content: '';
        display: block;
        border-left: 8px solid white;
        border-top: 8px solid transparent;
        border-bottom: 8px solid transparent;
        width: 0;
        height: 0;
        float: right;
        transition: transform 0.3s ease-out;
      }
      .menu-item.toggler.toggled:before {
        transform: rotate(90deg);
      }

      body { font-family: sans-serif; font-size: 14px; }

      *, *:after {
        box-sizing: border-box;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">


       
          Something involving a holodeck
          Send an away team
          Advanced solutions
         
           
              Separate saucer
              Send an away team that includes the captain (despite Riker's protest)
              Ask Worf
              Something involving Wesley, the 19th century, and a holodeck
              Ask Q for help
           
         
          Sweet-talk the alien aggressor
          Re-route power from auxiliary systems
       

       
          Something involving a holodeck
          Send an away team
          Advanced solutions
         
           
              Separate saucer
              Send an away team that includes the captain (despite Riker'
      s protest)
           
         
          Sweet-talk the alien aggressor
          Re-route power from auxiliary systems
       

       
          Something involving a holodeck
          Send an away team
          Advanced solutions
         
           
              Separate saucer
              Send an away team that includes the captain (despite Riker's protest)
              Ask Worf
              Something involving Wesley, the 19th century, and a holodeck
              Ask Q for help
              Separate saucer
              Send an away team that includes the captain (despite Riker'
      s protest)
              Ask Worf
              Something involving Wesley, the 19th century, and a holodeck
              Ask Q for help
           
         
          Sweet-talk the alien aggressor
          Re-route power from auxiliary systems

      好的。它是如何工作的?

      事实上,实现这一点涉及两个转变。其中一个将margin-bottom从0px(扩展状态)转换为-2000px,处于崩溃状态(类似于此答案)。这里的2000是第一个神奇数字,它是基于你的盒子不会比这个高的假设(2000像素似乎是一个合理的选择)。好的。

      单独使用margin-bottom转换有两个问题:好的。

      • 如果你有一个高于2000像素的盒子,那么一个margin-bottom: -2000px不会隐藏所有东西——即使在折叠的情况下也会有可见的东西。这是我们稍后要做的一个小修复。
      • 如果实际框高1000像素,并且您的转换长度为300毫秒,那么可视转换在大约150毫秒后已经结束(或者在相反的方向上,延迟150毫秒)。

      解决第二个问题就是第二个转换出现的地方,这个转换在概念上针对包装器的最小高度("概念上",因为我们实际上并没有为此使用min-height属性;稍后将详细介绍)。好的。

      这是一个动画,演示了如何将底部边缘过渡与最小高度过渡结合在一起,两者的持续时间相同,从而使我们获得从全高度到零高度的组合过渡,其持续时间相同。好的。

      animation as described above好的。

      左栏显示负的下边缘如何向上推动底部,从而降低可见高度。中间的条显示了最小高度如何确保在崩溃的情况下,过渡不会过早结束,而在扩展的情况下,过渡不会延迟开始。右栏显示了这两个选项的组合如何使框在正确的时间内从全高过渡到零高。好的。

      在我的演示中,我将50px作为最小高度的上限值。这是第二个魔法数字,它应该比盒子的高度还要低。50px看起来也很合理;看起来你不太可能经常想让一个元素可以折叠,而这个元素一开始甚至不高50像素。好的。

      正如您在动画中看到的,所产生的转换是连续的,但它是不可微分的——当最小高度等于由下边缘调整的整个高度时,速度会突然发生变化。这在动画中非常明显,因为它对两个过渡都使用线性计时函数,而且整个过渡非常慢。在实际情况下(我的演示在顶部),转换只需要300毫秒,并且底部边缘转换不是线性的。我在这两种转换中都使用了很多不同的计时功能,而最后使用的那些功能让我觉得它们最适合各种各样的情况。好的。

      还有两个问题需要解决:好的。

    • 从上面看,高度超过2000像素的盒子并没有完全隐藏在折叠状态中,
    • 相反的问题是,在非隐藏的情况下,低于50像素高度的框太高了,即使转换没有运行,因为最小高度使它们保持在50像素。
    • 我们解决了第一个问题,在崩溃的情况下给容器元素一个max-height: 0,并使用0s 0.3s转换。这意味着它并不是真正的转换,但是max-height应用时会有延迟;它只在转换结束后才应用。为了使其正确工作,我们还需要为相反的非折叠状态选择一个数字max-height。但与2000像素的情况不同,在这种情况下,选择太大的数字会影响转换的质量,在这种情况下,这真的不重要。所以我们可以选择一个非常高的数字,我们知道任何高度都不会接近这个值。我选了一百万像素。如果你觉得你可能需要支持高度超过一百万像素的内容,那么1)对不起,2)只需添加几个零。好的。

      第二个问题是我们没有实际使用min-height进行最小高度转换的原因。相反,容器中有一个::after伪元素,其中height从50px转换为零。这与min-height的效果相同:它不会让容器收缩到伪元素当前的高度之下。但是因为我们使用的是height,而不是min-height,所以我们现在可以使用max-height(再次延迟应用)在转换结束后将伪元素的实际高度设置为零,确保至少在转换之外,即使是小元素也具有正确的高度。因为min-heightmax-height强,所以如果我们使用容器的min-height而不是伪元素的height的话,这是行不通的。就像前一段中的max-height一样,这个max-height也需要一个值作为转换的另一端。但在这种情况下,我们可以选择50像素。好的。

      在chrome(win、mac、android、ios)、firefox(win、mac、android)、edge、ie11(除了我的演示版中的flexbox布局问题,我不需要调试)和safari(mac、ios)中进行测试。说到flexbox,应该可以在不使用任何flexbox的情况下实现此功能;事实上,我认为在IE7中几乎可以实现所有功能,除了没有CSS转换这一事实之外,这是一个非常没有意义的练习。好的。好啊。


      使用CSS3转换设置高度动画的一个视觉解决方案是设置填充动画。

      你不会完全得到擦除效果,但是使用过渡持续时间和填充值应该能让你足够接近。如果您不想显式地设置高度/最大高度,这应该是您想要的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      div {
          height: 0;
          overflow: hidden;
          padding: 0 18px;
          -webkit-transition: all .5s ease;
             -moz-transition: all .5s ease;
                  transition: all .5s ease;
      }
      div.animated {
          height: auto;
          padding: 24px 18px;
      }

      http://jsfiddle.net/catharsis/n5xfg/17/(在jsfiddle上即兴演奏)


      我的解决方法是将最大高度转换为精确的内容高度,以获得平滑的动画效果,然后使用transitionend回调将最大高度设置为9999px,以便内容可以自由调整大小。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      var content = $('#content');
      content.inner = $('#content .inner'); // inner div needed to get size of content when closed

      // css transition callback
      content.on('transitionEnd webkitTransitionEnd transitionend oTransitionEnd msTransitionEnd', function(e){
          if(content.hasClass('open')){
              content.css('max-height', 9999); // try setting this to 'none'... I dare you!
          }
      });

      $('#toggle').on('click', function(e){
          content.toggleClass('open closed');
          content.contentHeight = content.outerHeight();
         
          if(content.hasClass('closed')){
             
              // disable transitions & set max-height to content height
              content.removeClass('transitions').css('max-height', content.contentHeight);
              setTimeout(function(){
                 
                  // enable & start transition
                  content.addClass('transitions').css({
                      'max-height': 0,
                      'opacity': 0
                  });
                 
              }, 10); // 10ms timeout is the secret ingredient for disabling/enabling transitions
              // chrome only needs 1ms but FF needs ~10ms or it chokes on the first animation for some reason
             
          }else if(content.hasClass('open')){  
             
              content.contentHeight += content.inner.outerHeight(); // if closed, add inner height to content height
              content.css({
                  'max-height': content.contentHeight,
                  'opacity': 1
              });
             
          }
      });
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      .transitions {
          transition: all 0.5s ease-in-out;
          -webkit-transition: all 0.5s ease-in-out;
          -moz-transition: all 0.5s ease-in-out;
      }

      body {
          font-family:Arial;
          line-height: 3ex;
      }
      code {
          display: inline-block;
          background: #fafafa;
          padding: 0 1ex;
      }
      #toggle {
          display:block;
          padding:10px;
          margin:10px auto;
          text-align:center;
          width:30ex;
      }
      #content {
          overflow:hidden;
          margin:10px;
          border:1px solid #666;
          background:#efefef;
          opacity:1;
      }
      #content .inner {
          padding:10px;
          overflow:auto;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">

         
              Smooth CSS Transitions Between <wyn>height: 0</wyn> and <wyn>height: auto</wyn>
              <p>
      A clever workaround is to use <wyn>max-height</wyn> instead of <wyn>height</wyn>, and set it to something bigger than your content. Problem is the browser uses this value to calculate transition duration. So if you set it to <wyn>max-height: 1000px</wyn> but the content is only 100px high, the animation will be 10x too fast.
      </p>
              <p>
      Another option is to measure the content height with JS and transition to that fixed value, but then you have to keep track of the content and manually resize it if it changes.
      </p>
              <p>
      This solution is a hybrid of the two - transition to the measured content height, then set it to <wyn>max-height: 9999px</wyn> after the transition for fluid content sizing.
      </p>
         


      <br />

      <button id="toggle">Challenge Accepted!</button>


      接受的答案对大多数情况都有效,但是当你的div在高度上可以有很大的变化时,它就不能很好地工作了——动画速度不依赖于内容的实际高度,而且它看起来很不稳定。

      您仍然可以使用css执行实际的动画,但是您需要使用javascript计算项目的高度,而不是尝试使用auto。不需要jquery,但是如果您想要兼容性(适用于最新版本的chrome:)的话,可能需要稍微修改一下。

      1
      2
      3
      4
      5
      6
      7
      window.toggleExpand = function(element) {
          if (!element.style.height || element.style.height == '0px') {
              element.style.height = Array.prototype.reduce.call(element.childNodes, function(p, c) {return p + (c.offsetHeight || 0);}, 0) + 'px';
          } else {
              element.style.height = '0px';
          }
      }
      1
      2
      3
      4
      5
      6
      #menu #list {
          height: 0px;
          transition: height 0.3s ease;
          background: #d5d5d5;
          overflow: hidden;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
          <input value="Toggle list" type="button" onclick="toggleExpand(document.getElementById('list'));">
          <ul id="list">
              <!-- Works well with dynamically-sized content. -->
             
      <li>
      item
      </li>

             
      <li>

      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

             
      <li>
      item
      </li>

         
      </ul>


      对每种状态使用不同缓和和延迟过渡的max-height

      HTML:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      Hover
      <ul id="toggled">
         
      <li>
      One
      </li>

         
      <li>
      Two
      </li>

         
      <li>
      Three
      </li>


      <ul>

      CSS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #toggled{
          max-height: 0px;
          transition: max-height .8s cubic-bezier(0, 1, 0, 1) -.1s;
      }

      #trigger:hover + #toggled{
          max-height: 9999px;
          transition-timing-function: cubic-bezier(0.5, 0, 1, 0);
          transition-delay: 0s;
      }

      参见示例:http://jsfiddle.net/0hnjehjc/1/


      没有硬编码值。

      没有JavaScript。

      没有近似值。

      诀窍是使用隐藏和复制的div让浏览器理解100%的含义。

      当您能够复制要动画化的元素的DOM时,此方法是合适的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      .outer {
        border: dashed red 1px;
        position: relative;
      }

      .dummy {
        visibility: hidden;
      }

      .real {
        position: absolute;
        background: yellow;
        height: 0;
        transition: height 0.5s;
        overflow: hidden;
      }

      .outer:hover>.real {
        height: 100%;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      Hover over the box below:

        <!-- The actual element that you'd like to animate -->
       
      unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable
      content unpredictable content unpredictable content unpredictable content
       
        <!-- An exact copy of the element you'
      d like to animate. -->
       
      unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable content unpredictable
      content unpredictable content unpredictable content unpredictable content


      几乎没有提到Element.scrollHeight属性,它在这里很有用,并且仍然可以用于纯CSS转换。属性始终包含元素的"完整"高度,而不管其内容是否以及如何因折叠高度而溢出(例如height: 0)。

      因此,对于一个height: 0元素(有效地完全折叠),它的"正常"或"完全"高度仍然可以通过其scrollHeight值(总是一个像素长度)很容易获得。

      对于这样一个元素,假设它已经设置了过渡,例如(根据原始问题使用ul):

      1
      2
      3
      4
      ul {
          height: 0;
          transition: height 1s; /* An example transition. */
      }

      我们只需使用css,就可以触发所需的高度动画"扩展",如下所示(这里假设ul变量引用列表):

      1
      ul.style.height = ul.scrollHeight +"px";

      就是这样。如果需要折叠列表,以下两个语句中的任何一个都可以:

      1
      2
      ul.style.height ="0";
      ul.style.removeProperty("height");

      我的特定用例围绕着一个未知的动画列表,通常是相当长的长度,所以我不习惯于使用一个任意的"足够大"的heightmax-height规范,并冒着突然需要滚动的截止内容或内容的风险(例如,如果overflow: auto)。此外,基于max-height的解决方案打破了这种宽松和定时,因为使用的高度可能比max-height达到9999px所需的时间要快得多。随着屏幕分辨率的增加,像9999px这样的像素长度在我嘴里留下了一种不好的味道。在我看来,这个特殊的解决方案以优雅的方式解决了这个问题。

      最后,这里希望将来对CSS地址的修订能够更加优雅地完成这类工作——重新审视"计算"与"已用"和"已解析"值的概念,并考虑转换是否应应用于计算值,包括与widthheight的转换(目前,这些转换有点像特殊处理)。


      当我发表这篇文章时,已经有30多个答案了,但是我觉得我的答案比杰克已经接受的答案更好。

      我不满意仅仅使用max-height和css3转换所产生的问题,因为正如许多评论所指出的那样,您必须将max-height值设置得非常接近实际高度,否则您将得到延迟。有关该问题的示例,请参阅此jfiddle。

      为了解决这个问题(虽然仍然不使用javascript),我添加了另一个HTML元素,它转换transform: translateYcss值。

      这意味着使用了max-heighttranslateYmax-height允许元素向下推元素,而translateY提供我们想要的"即时"效果。与max-height的问题仍然存在,但其影响有所减弱。这意味着你可以为你的max-height值设置一个更大的高度,并且不用担心它。

      总的好处是,在返回(崩溃)的转换中,用户可以立即看到translateY动画,因此,max-height需要多长时间并不重要。

      解决方案

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      body {
        font-family: sans-serif;
      }

      .toggle {
        position: relative;
        border: 2px solid #333;
        border-radius: 3px;
        margin: 5px;
        width: 200px;
      }

      .toggle-header {
        margin: 0;
        padding: 10px;
        background-color: #333;
        color: white;
        text-align: center;
        cursor: pointer;
      }

      .toggle-height {
        background-color: tomato;
        overflow: hidden;
        transition: max-height .6s ease;
        max-height: 0;
      }

      .toggle:hover .toggle-height {
        max-height: 1000px;
      }

      .toggle-transform {
        padding: 5px;
        color: white;
        transition: transform .4s ease;
        transform: translateY(-100%);
      }

      .toggle:hover .toggle-transform {
        transform: translateY(0);
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
          Toggle!
       
       
         
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>
         
       



       
          Toggle!
       
       
         
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>
            <p>
      Content!
      </p>


      好吧,我想我想出了一个非常简单的答案…没有max-height,使用relative定位,用于li元素,是纯css。除了火狐,我什么都没有测试过,虽然从CSS来看,它应该可以在所有浏览器上运行。

      小提琴:http://jsfiddle.net/n5xfg/2596/

      CSS

      1
      2
      3
      4
      5
      6
      7
      8
      9
      .wrap { overflow:hidden; }

      .inner {
                  margin-top:-100%;
          -webkit-transition:margin-top 500ms;
                  transition:margin-top 500ms;
      }

      .inner.open { margin-top:0px; }

      HTML

      1
          Some Cool Content


      编辑:向下滚动查看更新的答案
      我正在做一个下拉列表,看到了这篇文章…许多不同的答案,但我决定分享我的下拉列表太…它不是完美的,但至少它将只使用CSS下拉!我一直在使用transform:translatey(y)将列表转换为视图…你可以在测试中看到更多http://jsfiddle.net/bvepc/4/我把DIV放在每个LI后面,因为我的下拉列表是从上而来的,为了正确地显示它们,这是需要的,我的DIV代码是:

      1
      2
      3
      4
      5
      6
      #menu div {
          transition: 0.5s 1s;
          z-index:-1;
          -webkit-transform:translateY(-100%);
          -webkit-transform-origin: top;
      }

      悬停是:

      1
      2
      3
      4
      #menu > li:hover div {
          transition: 0.5s;
          -webkit-transform:translateY(0);
      }

      因为ul height设置为内容,它可以超越你的身体内容,所以我为ul做了这件事:

      1
      2
      3
      4
      5
       #menu ul {
          transition: 0s 1.5s;
          visibility:hidden;
          overflow:hidden;
      }

      和悬停:

      1
      2
      3
      4
      #menu > li:hover ul {
           transition:none;
           visibility:visible;
      }

      转换后的第二次是延迟,它将在我的下拉列表被动态关闭后隐藏…希望以后有人能从中受益。
      BR/>编辑:我简直不敢相信PPL真的在使用这个原型!此下拉菜单仅用于一个子菜单,仅此而已!!我更新了一个更好的,可以有两个子菜单为LTR和RTL方向与IE8支持。< BR>LTR小提琴
      用于RTL的小提琴
      希望将来有人会发现这一点有用。


      如果还提供最小高度和最大高度,则可以从高度0转换为高度:自动。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      div.stretchy{
          transition: 1s linear;
      }

      div.stretchy.hidden{
          height: 0;
      }

      div.stretchy.visible{
          height: auto;
          min-height:40px;
          max-height:400px;
      }


      我想我想出了一个非常可靠的解决方案

      好啊!我知道这个问题和互联网一样古老,但我想我有一个解决方案,我把它变成了一个名为"突变转换"的插件。我的解决方案在DOM发生变化时为被跟踪元素设置style=""属性。最终的结果是,您可以使用良好的OLE CSS进行转换,而不使用黑客补丁或特殊的javascript。唯一需要做的就是使用data-mutant-attributes="X"设置要跟踪的元素。

      1
              This is an example with mutant-transition

      就是这样!此解决方案使用mutationobserver跟踪DOM中的更改。因此,您不必设置任何内容,也不必使用JavaScript手动设置动画。更改将自动跟踪。但是,因为它使用了mutationobserver,所以只能在IE11+中转换。

      小提琴!

      • height: autoheight: 100%过渡的论证
      • 在添加子项时演示转换height: auto


      flexbox解决方案

      赞成的意见:

      • 简单的
      • 无JS
      • 平滑过渡

      欺骗:

      • 元件需要放在固定高度的柔性容器中。

      它的工作方式是始终具有flex基础:在包含内容的元素上自动执行,而改为转换flex grow和flex shrink。

      编辑:受Xbox One界面启发改进的JS小提琴。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        transition: 0.25s;
        font-family: monospace;
      }

      body {
        margin: 10px 0 0 10px;
      }

      .box {
        width: 150px;
        height: 150px;
        margin: 0 2px 10px 0;
        background: #2d333b;
        border: solid 10px #20262e;
        overflow: hidden;
        display: inline-flex;
        flex-direction: column;
      }

      .space {
        flex-basis: 100%;
        flex-grow: 1;
        flex-shrink: 0;    
      }

      p {
        flex-basis: auto;
        flex-grow: 0;
        flex-shrink: 1;
        background: #20262e;
        padding: 10px;
        width: 100%;
        text-align: left;
        color: white;
      }

      .box:hover .space {
        flex-grow: 0;
        flex-shrink: 1;
      }
       
      .box:hover p {
        flex-grow: 1;
        flex-shrink: 0;    
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
        <p>

          Super Metroid Prime Fusion
       
      </p>


       
        <p>

          Resident Evil 2 Remake
       
      </p>


       
        <p>

          Yolo The Game
       
      </p>


       
        <p>

          Final Fantasy 7 Remake + All Additional DLC + Golden Tophat
       
      </p>


       
        <p>

          DerpVille
       
      </p>

      JS小提琴


      以下是一种从任何起始高度(包括0)到自动(全尺寸和灵活)的转换方法,无需每个节点上的硬设置代码或任何要初始化的用户代码:https://github.com/csuwildcat/transition-auto。这基本上是你想要的圣杯,我相信——>http://codepen.io/csuwldcat/pen/kwsdf。只需将下面的JS文件放入页面,然后只需从要扩展和收缩的节点中添加/删除一个布尔属性-reveal=""

      以下是您作为用户需要做的所有事情,一旦您包含了示例代码下面的代码块:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      /*** Nothing out of the ordinary in your styles ***/
      <style>
          div {
              height: 0;
              overflow: hidden;
              transition: height 1s;
          }
      </style>

      /*** Just add and remove one attribute and transition to/from auto! ***/


          I have tons of content and I am 0px in height you can't see me...



           I have tons of content and I am 0px in height you can'
      t see me...
           but now that you added the 'reveal' attribute,
           I magically transitioned to full height!...

      下面是要包含在您的页面中的代码块,在这之后,所有代码块都是肉汁:

      把这个JS文件放到你的页面上-一切正常吗?

      /*高度代码:自动;转换*/

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      (function(doc){

      /* feature detection for browsers that report different values for scrollHeight when an element's overflow is hidden vs visible (Firefox, IE) */
      var test = doc.documentElement.appendChild(doc.createElement('x-reveal-test'));
          test.innerHTML = '-';
          test.style.cssText = 'display: block !important; height: 0px !important; padding: 0px !important; font-size: 0px !important; border-width: 0px !important; line-height: 1px !important; overflow: hidden !important;';
      var scroll = test.scrollHeight || 2;
      doc.documentElement.removeChild(test);

      var loading = true,
          numReg = /^([0-9]*\.?[0-9]*)(.*)/,
          skipFrame = function(fn){
            requestAnimationFrame(function(){
              requestAnimationFrame(fn);
            });
          },
          /* 2 out of 3 uses of this function are purely to work around Chrome's catastrophically busted implementation of auto value CSS transitioning */
          revealFrame = function(el, state, height){
              el.setAttribute('reveal-transition', 'frame');
              el.style.height = height;
              skipFrame(function(){
                  el.setAttribute('reveal-transition', state);
                  el.style.height = '';
              });
          },
          transitionend = function(e){
            var node = e.target;
            if (node.hasAttribute('reveal')) {
              if (node.getAttribute('reveal-transition') == 'running') revealFrame(node, 'complete', '');
            }
            else {
              node.removeAttribute('reveal-transition');
              node.style.height = '';
            }
          },
          animationstart = function(e){
            var node = e.target,
                name = e.animationName;  
            if (name == 'reveal' || name == 'unreveal') {

              if (loading) return revealFrame(node, 'complete', 'auto');

              var style = getComputedStyle(node),
                  offset = (Number(style.paddingTop.match(numReg)[1])) +
                           (Number(style.paddingBottom.match(numReg)[1])) +
                           (Number(style.borderTopWidth.match(numReg)[1])) +
                           (Number(style.borderBottomWidth.match(numReg)[1]));

              if (name == 'reveal'){
                node.setAttribute('reveal-transition', 'running');
                node.style.height = node.scrollHeight - (offset / scroll) + 'px';
              }
              else {
                  if (node.getAttribute('reveal-transition') == 'running') node.style.height = '';
                  else revealFrame(node, 'running', node.scrollHeight - offset + 'px');
              }
            }
          };

      doc.addEventListener('animationstart', animationstart, false);
      doc.addEventListener('MSAnimationStart', animationstart, false);
      doc.addEventListener('webkitAnimationStart', animationstart, false);
      doc.addEventListener('transitionend', transitionend, false);
      doc.addEventListener('MSTransitionEnd', transitionend, false);
      doc.addEventListener('webkitTransitionEnd', transitionend, false);

      /*
          Batshit readyState/DOMContentLoaded code to dance around Webkit/Chrome animation auto-run weirdness on initial page load.
          If they fixed their code, you could just check for if(doc.readyState != 'complete') in animationstart's if(loading) check
      */

      if (document.readyState == 'complete') {
          skipFrame(function(){
              loading = false;
          });
      }
      else document.addEventListener('DOMContentLoaded', function(e){
          skipFrame(function(){
              loading = false;
          });
      }, false);

      /* Styles that allow for 'reveal' attribute triggers */
      var styles = doc.createElement('style'),
          t = 'transition: none; ',
          au = 'animation: reveal 0.001s; ',
          ar = 'animation: unreveal 0.001s; ',
          clip = ' { from { opacity: 0; } to { opacity: 1; } }',
          r = 'keyframes reveal' + clip,
          u = 'keyframes unreveal' + clip;

      styles.textContent = '[reveal] { -ms-'+ au + '-webkit-'+ au +'-moz-'+ au + au +'}' +
          '[reveal-transition="frame"] { -ms-' + t + '-webkit-' + t + '-moz-' + t + t + 'height: auto; }' +
          '[reveal-transition="complete"] { height: auto; }' +
          '[reveal-transition]:not([reveal]) { -webkit-'+ ar +'-moz-'+ ar + ar +'}' +
          '@-ms-' + r + '@-webkit-' + r + '@-moz-' + r + r +
          '@-ms-' + u +'@-webkit-' + u + '@-moz-' + u + u;

      doc.querySelector('head').appendChild(styles);

      })(document);

      /*演示代码*/

      1
      2
      3
      4
      5
      6
          document.addEventListener('click', function(e){
            if (e.target.nodeName == 'BUTTON') {
              var next = e.target.nextElementSibling;
              next.hasAttribute('reveal') ? next.removeAttribute('reveal') : next.setAttribute('reveal', '');
            }
          }, false);


      杰克对"最大高度动画"的回答很好,但我发现设置一个大的"最大高度"会导致延迟。

      可以将可折叠的内容移动到一个内部分区中,并通过获取内部分区的高度来计算最大高度(通过jquery,它将是outerheight())。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      $('button').bind('click', function(e) {
        e.preventDefault();
        w = $('#outer');
        if (w.hasClass('collapsed')) {
          w.css({"max-height": $('#inner').outerHeight() + 'px' });
        } else {
          w.css({"max-height":"0px" });
        }
        w.toggleClass('collapsed');
      });

      这里有一个jsFiddle链接:http://jsFiddle.net/pbatey/duzpt

      下面是一个JSfiddle,它使用了所需的绝对最少的代码量:http://jsfidle.net/8ncjjxh8/


      在@jake的答案上展开,转换将一直延伸到最大高度值,从而产生一个极快的动画-如果您同时设置了两种转换:悬停和关闭,那么您可以更大程度地控制疯狂的速度。

      所以li:hover是当鼠标进入状态,然后在非hovered属性上的转换将是鼠标离开。

      希望这会有所帮助。

      例如:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      .sidemenu li ul {
         max-height: 0px;
         -webkit-transition: all .3s ease;
         -moz-transition: all .3s ease;
         -o-transition: all .3s ease;
         -ms-transition: all .3s ease;
         transition: all .3s ease;
      }
      .sidemenu li:hover ul {
          max-height: 500px;
          -webkit-transition: all 1s ease;
         -moz-transition: all 1s ease;
         -o-transition: all 1s ease;
         -ms-transition: all 1s ease;
         transition: all 1s ease;
      }
      /* Adjust speeds to the possible height of the list */

      这是一把小提琴:http://jsfiddle.net/bukwj/


      我意识到这个线程正在变老,但它在某些谷歌搜索中排名很高,所以我认为它值得更新。

      您还可以获取/设置元素自身的高度:

      1
      2
      var load_height = document.getElementById('target_box').clientHeight;
      document.getElementById('target_box').style.height = load_height + 'px';

      您应该在内联脚本标记中的Target_Box结束标记之后立即转储此javascript。


      我最近一直在转换li元素上的max-height,而不是包装ul

      理由是,与大的max-heights相比,小的max-heights的延迟远不明显(如果有的话),我也可以设置我的max-height值相对于lifont-size而不是使用emsrems来设置一些任意的大数字。

      如果我的字体大小是1rem,我会将max-height设置为类似3rem的值(以适应换行文本)。您可以在这里看到一个示例:

      http://codepen.io/mindfullselement/pen/dtzje


      这里有一个我刚与jquery结合使用的解决方案。这适用于以下HTML结构:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      <nav id="main-nav">
         
      <ul>

             
      <li>

                  Link
                 
      <ul>

                     
      <li>
      Sub Link
      </li>

                 
      </ul>

             
      </li>

         
      </ul>

      </nav>

      功能:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
          $('#main-nav li ul').each(function(){
              $me = $(this);

              //Count the number of li elements in this UL
              var liCount = $me.find('li').size(),
              //Multiply the liCount by the height + the margin on each li
                  ulHeight = liCount * 28;

              //Store height in the data-height attribute in the UL
              $me.attr("data-height", ulHeight);
          });

      然后,您可以使用click函数设置和删除高度,方法是使用css()

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      $('#main-nav li a.main-link').click(function(){
          //Collapse all submenus back to 0
          $('#main-nav li ul').removeAttr('style');

          $(this).parent().addClass('current');

          //Set height on current submenu to it's height
          var $currentUl = $('
      li.current ul'),
              currentUlHeight = $currentUl.attr('
      data-height');
      })

      CSS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      #main-nav li ul {
          height: 0;
          position: relative;
          overflow: hidden;
          opacity: 0;
          filter: alpha(opacity=0);
          -ms-filter:"alpha(opacity=0)";
          -khtml-opacity: 0;
          -moz-opacity: 0;
          -webkit-transition: all .6s ease-in-out;
          -moz-transition: all .6s ease-in-out;
          -o-transition: all .6s ease-in-out;
          -ms-transition: all .6s ease-in-out;
          transition: all .6s ease-in-out;
      }

      #main-nav li.current ul {
          opacity: 1.0;
          filter: alpha(opacity=100);
          -ms-filter:"alpha(opacity=100)";
          -khtml-opacity: 1.0;
          -moz-opacity: 1.0;
      }

      .ie #main-nav li.current ul { height: auto !important }

      #main-nav li { height: 25px; display: block; margin-bottom: 3px }


      我能做到。我有一个.child和一个.parent分区。子分区与absolute位置完全符合父分区的宽度/高度。然后我设置translate属性的动画,将它的Y值向下推至100%。它的动画非常流畅,没有任何问题,也没有任何其他解决方案。

      像这样,伪代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      .parent{ position:relative; overflow:hidden; }
      /** shown state */
      .child {
        position:absolute;top:0;:left:0;right:0;bottom:0;
        height: 100%;
        transition: transform @overlay-animation-duration ease-in-out;
        .translate(0, 0);
      }

      /** Animate to hidden by sliding down: */
      .child.slidedown {
        .translate(0, 100%); /** Translate the element"out" the bottom of it's .scene container"mask" so its hidden */
      }

      您可以在.parent上指定一个height,在px中指定一个%,或者保留为auto。当它滑下时,这个DIV会屏蔽掉.childDIV。


      我没有详细阅读所有内容,但我最近遇到了这个问题,我做了如下操作:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      div.class{
         min-height:1%;
         max-height:200px;
         -webkit-transition: all 0.5s ease;
         -moz-transition: all 0.5s ease;
         -o-transition: all 0.5s ease;
         -webkit-transition: all 0.5s ease;
         transition: all 0.5s ease;
         overflow:hidden;
      }

      div.class:hover{
         min-height:100%;
         max-height:3000px;
      }

      这允许您有一个DIV,它首先显示高达200px的内容,悬停时,其大小至少与该DIV的整个内容一样高。DIV不会变为3000px,但3000 px是我施加的限制。确保在non:hover上进行转换,否则可能会得到一些奇怪的渲染。这样,:hover继承自non:hover。

      从px到%或到auto的转换不起作用。您需要使用相同的度量单位。这对我来说很好。使用HTML5使其完美……

      记住,总有工作在身边…;)

      希望有人觉得这个有用


      似乎没有合适的解决办法。max-height方法相当好,但在隐藏阶段效果不佳-除非您知道内容的高度,否则会有明显的延迟。

      我认为最好的方法是使用max-height,但只用于演出阶段。不要在隐藏时使用任何动画。在大多数情况下,这不应该是至关重要的。

      max-height应该设置为相当大的值,以确保任何内容都适合。动画速度可以使用transition持续时间(speed = max-height / duration)来控制。速度不取决于内容的大小。显示整个内容所需的时间将取决于其大小。

      1
      2
      3
      4
      5
      6
      document.querySelector("button").addEventListener(
       "click",
        function(){
          document.querySelector("div").classList.toggle("hide");
        }
      )
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      div {    
          max-height: 20000px;
          transition: max-height 3000ms;
          overflow-y: hidden;
      }

      .hide {
          max-height: 0;
          transition: none;
      }
      1
      2
      <button>Toggle</button>
      Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne. Lorem ipsum dolor sit amet, ius solet dignissim honestatis ad. Mea quem tibique intellegat te. Insolens deterruisset cum ea. Te omnes percipit consulatu eos. Vix novum primis salutatus no, eam denique sensibus et, his ipsum senserit ne.


      我理解这个问题需要一个没有javascript的解决方案。但是对于那些感兴趣的人来说,这里是我的解决方案,只使用一点JS。

      好的,那么元素的css(其高度默认会改变)被设置为height: 0;,当打开height: auto;时。它也有transition: height .25s ease-out;。但问题当然是,它不会向height: auto;或从height: auto;过渡。

      因此,我所做的就是在打开或关闭时将高度设置为元素的scrollHeight属性。这种新的内联样式将具有更高的特异性,并覆盖height: auto;height: 0;以及转换运行。

      打开时,我添加了一个transitionend事件监听器,它只运行一次,然后删除内联样式,将其设置回height: auto;,这将允许元素在必要时调整大小,就像在这个更复杂的例子中,子菜单为https://codepen.io/ninjabonsai/pen/gzyve。

      当关闭时,我会在下一个事件循环周期后立即使用setTimeout删除内联样式,不会延迟。这意味着height: auto;暂时被覆盖,允许转换回height 0;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      const showHideElement = (element, open) => {
        element.style.height = element.scrollHeight + 'px';
        element.classList.toggle('open', open);

        if (open) {
          element.addEventListener('transitionend', () => {
            element.style.removeProperty('height');
          }, {
            once: true
          });
        } else {
          window.setTimeout(() => {
            element.style.removeProperty('height');
          });
        }
      }

      const menu = document.body.querySelector('#menu');
      const list = document.body.querySelector('#menu > ul')

      menu.addEventListener('mouseenter', () => showHideElement(list, true));
      menu.addEventListener('mouseleave', () => showHideElement(list, false));
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #menu>ul {
        height: 0;
        overflow: hidden;
        background-color: #999;
        transition: height .25s ease-out;
      }

      #menu>ul.open {
        height: auto;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
        hover me
       
      <ul>

         
      <li>
      item
      </li>

         
      <li>
      item
      </li>

         
      <li>
      item
      </li>

         
      <li>
      item
      </li>

         
      <li>
      item
      </li>

       
      </ul>


      这并不是解决问题的"解决方案",而是解决问题的方法。它只能与文本一起工作,但可以根据需要更改为与其他元素一起工作。

      1
      2
      3
      4
      5
      6
      7
      .originalContent {
          font-size:0px;
          transition:font-size .2s ease-in-out;
      }
      .show { /* class to add to content */
          font-size:14px;
      }

      以下是一个例子:http://codepen.io/overthemike/pen/wzjrka

      本质上,您将字体大小设置为0,并以足够快的速度将其转换为所需的高度,而不是最大高度或scaley()等。用css将实际高度转换为auto当前是不可能的,但是在is中转换内容,因此字体大小转换。

      • 注意-代码笔中有JavaScript,但它的唯一目的是在单击手风琴时添加/删除CSS类。这可以通过隐藏的单选按钮来完成,但我并没有集中于此,只是高度转换。

      将高度设置为自动并转换最大高度。

      在铬V17上测试

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      div {
        position: absolute;
        width:100%;
        bottom:0px;
        left:0px;

        background:#333;
        color: #FFF;

        max-height:100%; /**/
        height:auto; /**/

        -webkit-transition: all 0.2s ease-in-out;
        -moz-transition: all 0.2s ease-in-out;
        -o-transition: all 0.2s ease-in-out;
        -ms-transition: all 0.2s ease-in-out;
        transition: all 0.2s ease-in-out;
      }

      .close {
        max-height:0%; /**/
      }


      如果硬编码提供的最大高度值不大于实际高度(否则会出现不希望出现的延迟和时间问题)。另一方面,如果硬编码值意外为不超过实际高度的元素不会完全打开。

      以下仅限CSS的解决方案还需要硬编码的大小应该比实际尺寸大。然而这如果实际大小在某些情况下大于硬编码的大小。在这种情况下,过渡可能会有点跳跃,但它不会留下部分可见的元素。因此,此解决方案也可用于未知内容,例如一个数据库,你只知道它的内容通常不大X像素以上,但也有例外。

      我们的想法是用一个负的值作为保证金底部(或保证金顶部稍微不同的动画)并将内容元素放入溢出的中间元素:隐藏。内容的负边缘元素,因此减少中间元素的高度。

      以下代码在页边距底部使用从-150px到0px。只要内容元素不是高于150像素。此外,它使用最大高度的过渡中间元素从0px到100%。这最后隐藏了中间元素如果含量元素高于150px。对于最大高度,过渡仅用于延迟其应用关闭时的一秒钟,不会产生平滑的视觉效果(因此,它可以从0px运行到100%。

      CSS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      .content {
        transition: margin-bottom 1s ease-in;
        margin-bottom: -150px;
      }
      .outer:hover .middle .content {
        transition: margin-bottom 1s ease-out;
        margin-bottom: 0px
      }
      .middle {
        overflow: hidden;
        transition: max-height .1s ease 1s;
        max-height: 0px
      }
      .outer:hover .middle {
        transition: max-height .1s ease 0s;
        max-height: 100%
      }

      HTML:

      1
      2
      3
      4
      5
      6
      7
      8
            Sample Text
             Sample Text
             Sample Text
            Sample Test of height 150px
            Sample Text
         
       
        Hover Here

      保证金底部的值应为负值,并尽可能接近可能达到内容元素的实际高度。如果它离开了值)越大,与最大高度解决方案,但只要硬编码的大小并不比实际大小大多少。如果绝对页边距底部的值小于实际高度Tanposition跳了一点。在任何情况下,在过渡之后内容元素要么完全显示,要么完全删除。

      有关更多详细信息,请参阅我的博客文章http://www.taccgl.org/blog/css-transition-display.html combined-height


      这是我经常解决的问题

      http://jsfiddle.net/ipeshev/d1dfr0jz/

      尝试将关闭状态的延迟设置为某个负数,并用该值播放一点。你会看到区别的。它几乎可以用来欺骗人眼;)。

      它可以在主要浏览器中使用,但对我来说已经足够好了。这很奇怪,但给出了一些结果。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      .expandable {
          max-height: 0px;
          overflow: hidden;
          transition: all 1s linear -0.8s;
      }

      button:hover ~ .expandable {
          max-height: 9000px;
          transition: all 1s ease-in-out;
      }


      小javascript+scss解决方案

      我通常使用一个完全不同的视角和一个(非常)小的javascript。问题是:

      • 我们真正想要的是改变身高

      • 高度是子菜单中所有列表项的总和。

      • 我们通常知道列表项的高度,因为我们正在设计它

      所以我的解决方案适用于"普通"子菜单,其中项目名称只有一行。不管怎样,只要多加一点JS,就可以容纳多个行名称。

      基本上,我只需要计算子菜单项并相应地应用特定类。然后把球传给CSS。例如:

      1
      2
      3
      4
      5
      6
      var main_menu = $('.main-menu');
      var submenus = $('.main-menu').find('.submenu');
      submenus.each(function(index,item){
         var i = $(item);
         i.addClass('has-' + i.find('li').length + '-children');
      });

      显然,您可以使用任何类/选择器。现在我们有这样的子菜单:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      <ul class="submenu has-3-children">
         
      <li>

      </li>

         
      <li>

      </li>

         
      <li>

      </li>


      </ul>

      我们的CSS是这样的:

      1
      2
      3
      4
      5
      6
      .submenu{
         //your styles [...]
         height:0;
         overflow:hidden;
         transition: all 200ms ease-in-out; //assume Autoprefixer is used
      }

      我们还将有一些类似这样的SCSS变量(任意示例):

      1
      2
      $sub_item_height:30px;
      $sub_item_border:2px;

      此时,假设打开的主菜单项将获得类似"opened"或类似的类(您的implementations….),我们可以这样做:

      1
      2
      3
      4
      5
      6
      7
      //use a number of children reasonably high so it won't be overcomed by real buttons
      .main-menu .opened .submenu{
         &.has-1-children{ height:   $sub_item_height*1  + $sub_item_border*1;  }
         &.has-2-children{ height:   $sub_item_height*2  + $sub_item_border*2;  }
         &.has-3-children{ height:   $sub_item_height*3  + $sub_item_border*3;  }
         //and so on....
      }

      或者,缩短:

      1
      2
      3
      4
      5
      .main-menu .opened .submenu{
         @for $i from 1 through 12{//12 is totally arbitrary
            &.has-#{$i}-children { height: $menu_item_height * $i + $menu_item_border * $i; }
         }
      }

      在大多数情况下,这将起到作用。希望它有帮助!


      这就是我的工作:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
        .hide{
          max-height: 0px;
          overflow: hidden;
          transition:max-height .5s ease-in-out;
        }

        .show{
          max-height: 150px; // adjust as needed
          transition: max-height .5s ease-in-out;
        }

      您需要将它们放入所有子组件中,并使用jquery或react状态切换它们,这里是我的示例(使用next.js和样式化组件):https://codesandbox.io/s/ol3kl56q9q


      你用下面的东西代替高度怎么样

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      #child0 {
        visibility: hidden;
        opacity: 0;
        transition: visibility 0s, opacity 0.5s linear;
        position: absolute;
      }

      #parent0:hover #child0 {
        visibility: visible;
        opacity: 1;
        position: relative;
      }

      效果也很好。请添加前缀。希望这能帮助别人。

      附言:如果你还需要高度0来获得某种黑色魔法,你可以把height: 0;加到#child0上,然后把height: inherit加到#parent0:hover #child0上。同时,您可以单独或只为所有人添加高度过渡。


      查看我关于一个相关问题的帖子。

      基本上,从height: 0px;开始,让它转换到由javascript计算的精确高度。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function setInfoHeight() {
        $(window).on('load resize', function() {
          $('.info').each(function () {
            var current = $(this);
            var closed = $(this).height() == 0;
            current.show().height('auto').attr('h', current.height() );
            current.height(closed ? '0' : current.height());
          });
        });

      每当页面加载/调整大小时,类为info的元素将更新其h属性。然后按钮触发style="height: __"将其设置为之前设置的h值。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      function moreInformation() {
        $('.icon-container').click(function() {
          var info = $(this).closest('.dish-header').next('.info'); // Just the one info
          var icon = $(this).children('.info-btn'); // Select the logo

          // Stop any ongoing animation loops. Without this, you could click button 10
          // times real fast, and watch an animation of the info showing and closing
          // for a few seconds after
          icon.stop();
          info.stop();

          // Flip icon and hide/show info
          icon.toggleClass('flip');

          // Metnod 1, animation handled by JS
          // info.slideToggle('slow');

          // Method 2, animation handled by CSS, use with setInfoheight function
          info.toggleClass('active').height(icon.is('.flip') ? info.attr('h') : '0');

        });
      };

      这是info类的样式。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      .info {
        padding: 0 1em;
        line-height: 1.5em;
        display: inline-block;
        overflow: hidden;
        height: 0px;
        transition: height 0.6s, padding 0.6s;
        &.active {
          border-bottom: $thin-line;
          padding: 1em;
        }
      }

      跨浏览器可能不支持样式。以下是此代码的实时示例:

      科德森


      这是我的解决方案。以前的最大高度和巨大的数字是好的,但对我来说还不够,因为动画在较小的文本量上有问题。我的代码动态地获取内容需要的放置量,并将其放到atribute中。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      var unrolled = false;

      $("#unroll" ).click(function() {
        if(!unrolled){
           $('.block-of-text').css("max-height", $('.whole-content').height() +"px");
           unrolled=true;
        }
        else{
           $('.block-of-text').removeAttr("style");
           unrolled=false;
        }
       
      });
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      .block-of-text{
        width:200px;
        max-height:150px;
        padding:25px;
        background:rgba(0,0,255,0.6);
        transition:0.4s;
        color:white;
        display:inline-block;
        overflow:hidden;
      }
      #unroll{
        position:absolute;
        left:280px;
        background:transparent;
        color:blue;
        border:2px solid blue;
        transition:0.4s;
        top:20px;
      }
      #unroll:hover{
        background:blue;
        color:white;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

       
          YOU CAN PLACE HERE AS MUCH TEXT AS YOU WANT
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a,
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a,
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a,
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a,
         
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a,
          Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. END OF CONTENT,
       


      <button id="unroll">
         Unroll block
      </button>


      这个解决方案使用JavaScript,但它非常简单,而且工作得很好。

      HTML:

      1
      2
      3
      4
      5
      6
      7
      8
      <button>Toggle</button>

       
          Lorem
          Ipsum
          Dolor
          Sit
          Amet

      CSS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      .container
      {
        overflow: hidden;
        transition: 0.5s ease;
      }

      .container.collapsed
      {
        height: 0 !important;
      }

      Javascript:

      1
      2
      3
      4
      5
      6
      7
      $("button").click(
          function ()
          {
              var height = $(".content").height();
              $(".container").css({height: height});
              $(".container").toggleClass("collapsed");
          });

      http://jsfiddle.net/r109uz7m/(包括下面解释的缺点的解决方法):

      唯一的缺点是,如果容器中的内容发生更改,则需要刷新容器的大小。在大多数用例中,您可以绕过这个限制(就像在JSfiddle中一样)。


      短代码示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      .slider ul {
        overflow: hidden;
        -webkit-transition: max-height 3.3s ease;
      }

      .slider.hide ul {
        max-height: 0px;
      }

      .slider.show ul {
        max-height: 1000px;
      }

      我通过将最大高度设置为"无",获取高度,将最大高度重新设置为计算出的高度来实现这一点。为我工作得很好。我在一个手风琴菜单上找到了这个,用

      作为切换开关,在内部扩展

      JS:

      1
      2
      3
      4
      5
      6
      $('h5').click(function(e) {
        $(this).parent('div').addClass('temp_expanded');
        var getheight = ($(this).parent('div').find('div').height());
        $(this).parent('div').removeClass('temp_expanded');
        $(this).parent('div').find('div').css('max-height', getheight);
      });

      较少:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      div {
      > div {
          max-height: 0px;
          overflow: hidden;
          .transition(all 0.3s ease-in-out);
      }

      &.temp_expanded {
          > div {
              max-height: none;
          }
      }


      我今天研究这个问题已经有一段时间了,发现了这个解决方案:

      使用"最大高度",并根据容器内容物的计算高度动态设置最大高度。

      1
      2
      3
      $(obj).children().each(function(index, element) {
         InnerHeight += $(this).height();
      });

      要将动画设置为全尺寸:

      1
      $(obj).removeClass('collapsed').css('max-height', InnerHeight);

      要将动画设置为较小的大小,请执行以下操作:

      1
      $(obj).removeClass('collapsed').css('max-height', MySmallerHeight);

      使用CSS3过渡:最大高度;

      这样,你就可以避免从一个高度到另一个高度的浮华动画,也不会有剪辑内容的风险。


      我遇到了这个问题,找到了解决办法。

      首先,我尝试使用max-height。但有两个问题:

    • 我不太确定什么是max-height,因为我正在扩展一个未知长度的文本块。
    • 如果我把max-height设置得太大,崩溃时会有很大的延迟。
    • 然后,我的解决方法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      function toggleBlock(e) {
          var target = goog.dom.getNextElementSibling(e.target);
          if (target.style.height && target.style.height !="0px") { //collapsing
              goog.style.setHeight(target, target.clientHeight);
              setTimeout(function(){
                  target.style.height ="0px";
              }, 100);
          } else { //expanding
              target.style.height ="auto";
              //get the actual height
              var height = target.clientHeight;
              target.style.height ="0px";
              setTimeout(function(){
                  goog.style.setHeight(target, height);
              }, 100);
              setTimeout(function(){
                  //Set this because I have expanding blocks inside expanding blocks
                  target.style.height="auto";
              }, 600); //time is set 100 + transition-duration
          }
      }

      SCS:

      1
      2
      3
      4
      5
      6
      div.block {
          height: 0px;
          overflow: hidden;
          @include transition-property(height);
          @include transition-duration(0.5s);
      }

      我也用jquery做了这个。在我的例子中,我想看一点其他菜单(10px)。因此,这在没有JavaScript的情况下工作(但也没有转换)。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      #menu li ul {
              list-style: none;
              height: 10px;
              overflow: hidden;
              margin: 0;
              padding: 0;
          }
              #menu li:hover ul {
                  height: 100%;
              }

      这是我的JS:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      //Save the height set in css (10px)
      var csshoehe = $("ul li ul").height();

      // Open all the menus
      $("ul li ul").css("height","100%");

      //Save each height in data-attribute
      //then shrink it down again
      $.each($("ul li ul"), function(){
          var hoehe = $(this).height();
          $(this).data("hoehe", hoehe);
          $(this).css("height", csshoehe);
      });

      $("ul li").hover(
          function(){
              var orig = $(this).children("ul").data("hoehe");
              $(this).children("ul").stop(true,false).delay(150).animate({"height": orig});
      },  function(){
              $(this).children("ul").stop(true,false).delay(400).animate({"height": csshoehe});
      });

      希望这能帮助别人:)


      这就是我一直使用的。

      基本上,我会得到所有子元素的高度,对它们求和,然后设置元素的最大高度,覆盖类(您可以创建自己的类,这样您就可以拥有不同的实例)。

      过来看。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
                                  <!doctype html>
                                  <html>

                                  <head>
                                      <style>
                                          /* OVERFLOW HIDDEN */
                                          .overflowHidden{
                                              overflow: hidden;
                                          }

                                          /* HEIGHT */
                                          .transitionHeight{
                                              -webkit-transition: max-height 250ms ease-in-out;
                                              -moz-transition: max-height 250ms ease-in-out;
                                              -o-transition: max-height 250ms ease-in-out;
                                              -ms-transition: max-height 250ms ease-in-out;
                                              transition: max-height 250ms ease-in-out;
                                          }
                                          .heightAnimOff{
                                              height: auto;
                                              max-height: 0px;
                                          }
                                          .heightAnimOn{
                                              height: auto;
                                              max-height: 20000px;
                                          }

                                      </style>
                                      <script src="jquery_1.8.3.min.js" type="text/javascript">
                                      <script type="text/javascript">
                                          (function($){
                                                  $.toggleAnimHeight = function(alvo, velha, nova){
                                                      if ( $(alvo).attr("data-maxHeight") != null ){
                                                      }else{
                                                          var totalH = 0;
                                                          $(alvo).children().each(function(){
                                                              totalH += $(this).height();
                                                          });
                                                          $(alvo).attr("data-maxHeight", totalH)
                                                          $("head").append('<style> .'+nova+'{ max-height: '+totalH+'px; } </style>');
                                                      }          
                                                      if ( $(alvo).attr("class").indexOf(nova) == -1 ){
                                                          $(alvo).removeClass(velha);
                                                          $(alvo).addClass(nova);
                                                      }else {
                                                          $(alvo).removeClass(nova);
                                                          $(alvo).addClass(velha);
                                                      }
                                                  }
                                          }(jQuery));
                                     
                                  </head>

                                  <body>
                                     
                                          <button onmousedown="$.toggleAnimHeight( $('#target1'), 'heightAnimOff', 'heightAnimOn' );">Anim Toggle</button>
                                         
                                              <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. In id pretium enim, quis faucibus urna. Phasellus blandit nisl eget quam mollis vulputate. Sed pulvinar eros vitae neque volutpat, vitae suscipit urna viverra. Etiam rhoncus purus vitae tortor pulvinar, sed vulputate arcu convallis. Sed porta, mi consectetur convallis semper, odio mauris iaculis purus, non tempor purus augue pharetra lorem. Integer dictum lacus arcu. Vivamus metus lorem, fermentum ac egestas ac, ornare non neque. Aenean ullamcorper adipiscing ante, et mollis orci feugiat et.
      </p>

                                              <p>
      Praesent pretium sit amet eros et lacinia. Etiam nec neque ullamcorper, sagittis quam vitae, dictum ipsum. Sed volutpat lorem libero, nec commodo magna posuere rutrum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque id erat odio. Sed faucibus sem eu tortor laoreet pulvinar. Praesent pharetra risus eget metus vulputate, eget condimentum leo consequat. Praesent consequat rutrum convallis.
      </p>

                                              <p>
      Aenean euismod metus quis libero commodo, tristique cursus odio vestibulum. Donec quis lobortis arcu, eu luctus diam. In eget nisi non mauris commodo elementum. Sed gravida leo consequat, tempus orci eu, facilisis ipsum. Cras interdum sed odio vel tincidunt. Morbi arcu ipsum, ultricies dictum enim quis, varius dignissim massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec semper, magna eu aliquam luctus, leo purus accumsan massa, at auctor dui dolor eu augue. Maecenas ultrices faucibus ante non mattis.
      </p>

                                              <p>
      Pellentesque ut est tortor. Quisque adipiscing ac nisi vel interdum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut facilisis ante sollicitudin vehicula ornare. Quisque sagittis diam nibh, ac imperdiet nibh pulvinar eu. Integer at ipsum a purus tristique porttitor vitae in ante. Sed arcu neque, lacinia eu dolor nec, pellentesque interdum tortor. Morbi ornare aliquet aliquam. Aenean egestas, erat vel tempus mollis, est eros iaculis enim, quis fringilla purus tortor sollicitudin erat. Donec ultrices elit metus, sed iaculis mi dignissim vulputate. Donec adipiscing imperdiet porttitor. Sed ac lacus adipiscing, sagittis sem quis, tincidunt metus. Curabitur vitae augue a dolor scelerisque lobortis ut a nisi.
      </p>

                                              <p>
      Quisque sollicitudin diam sit amet dui sollicitudin, ac egestas turpis imperdiet. Nullam id dui at lectus ultrices aliquam. Nam non luctus tortor, vitae elementum elit. Nullam id bibendum orci. Aliquam hendrerit nisi vitae tortor mollis, nec aliquam risus malesuada. In scelerisque nisl arcu, sit amet tincidunt libero consequat pharetra. Quisque aliquam consectetur purus nec sollicitudin. Pellentesque consectetur eleifend tortor in blandit. Pellentesque euismod justo sed lectus congue, ut malesuada diam rhoncus. Nulla id tempor odio. Nulla facilisi. Phasellus lacinia neque in nisi congue aliquet. Aliquam malesuada accumsan mauris eget mattis. Maecenas pellentesque, sem sed ultricies ullamcorper, massa enim consectetur magna, eget sagittis lorem leo vel arcu. Cras ultrices nunc id risus commodo laoreet. Proin nisl nulla, elementum ac libero sed, aliquam mollis massa.
      </p>
                                         
                                     
                                  </body>

                                  </html>


      如果"li">30件,那么包装高度将大于500px。我的回答是:

      1
      2
      3
      ul{width:100%}
      li{height:0;overflow:hidden;background:#dedede;transition:.2s.4s linear}
      ul:hover li{height:20px}
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      <ul>
      Hover me

      <li>
      Juice
      </li>


      <li>
      Tea
      </li>


      <li>
      Milk
      </li>


      <li>
      Coffee
      </li>


      </ul>