CSS过渡自动高度不起作用

时间:2012-12-18 17:37:19

标签: css animation css-transitions

我有一个网站,我决定用纯CSS片段替换基于jquery的切换框。当我使用固定高度值进行过渡(CSS的最后几行)时,它运行良好,但是使用auto值,动画丢失,只有高度变化才有效!

有没有办法将它与自动值一起使用?我想使用变量文本而不使用脚本。

.ac-container{
  width: 400px;
  margin: 10px auto 30px auto;
  text-align: left;
}
.ac-container label{
  font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
  padding: 5px 20px;
  position: relative;
  z-index: 20;
  display: block;
  height: 30px;
  cursor: pointer;
  color: #777;
  text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
  line-height: 33px;
  font-size: 19px;
  background: #ffffff;
  background: -moz-linear-gradient(top, #ffffff 1%, #eaeaea 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,#ffffff), color-stop(100%,#eaeaea));
  background: -webkit-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
  background: -o-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
  background: -ms-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
  background: linear-gradient(top, #ffffff 1%,#eaeaea 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eaeaea',GradientType=0 );
  box-shadow: 
    0px 0px 0px 1px rgba(155,155,155,0.3), 
    1px 0px 0px 0px rgba(255,255,255,0.9) inset, 
    0px 2px 2px rgba(0,0,0,0.1);
}
.ac-container label:hover{
  background: #fff;
}
.ac-container input:checked + label,
.ac-container input:checked + label:hover{
  background: #c6e1ec;
  color: #3d7489;
  text-shadow: 0px 1px 1px rgba(255,255,255, 0.6);
  box-shadow: 
    0px 0px 0px 1px rgba(155,155,155,0.3), 
    0px 2px 2px rgba(0,0,0,0.1);
}

.ac-container input{
  display: none;
}
.ac-container section{
  background: rgba(255, 255, 255, 0.5);
  margin-top: -1px;
  overflow: hidden;
  height: 0px;
  position: relative;
  z-index: 10;
  -webkit-transition: height 0.3s ease-in-out, box-shadow 0.6s linear;
  -moz-transition: height 0.3s ease-in-out, box-shadow 0.6s linear;
  -o-transition: height 0.3s ease-in-out, box-shadow 0.6s linear;
  -ms-transition: height 0.3s ease-in-out, box-shadow 0.6s linear;
  transition: height 0.3s ease-in-out, box-shadow 0.6s linear;
}
.ac-container section p{
  font-style: italic;
  color: #777;
  line-height: 23px;
  font-size: 14px;
  padding: 20px;
  text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
}
.ac-container input:checked ~ section{
  -webkit-transition: height 0.5s ease-in-out, box-shadow 0.1s linear;
  -moz-transition: height 0.5s ease-in-out, box-shadow 0.1s linear;
  -o-transition: height 0.5s ease-in-out, box-shadow 0.1s linear;
  -ms-transition: height 0.5s ease-in-out, box-shadow 0.1s linear;
  transition: height 0.5s ease-in-out, box-shadow 0.1s linear;
  box-shadow: 0px 0px 0px 1px rgba(155,155,155,0.3);
}
.ac-container input:checked ~ section.ac-small{
  height: 120px; /*auto*/
}
<div class="ac-container">
  <div>

    <input id="ac-1" name="accordion-1" type="checkbox" />
    <section class="ac-small">
      <p>Some content... </p>
    </section>
    <label for="ac-1">About us</label>

  </div>	

  <div>	
    <input id="ac-2" name="accordion-2" type="checkbox" />
    <section class="ac-small">
      <p>Some content... </p>
    </section>
    <label for="ac-2">About us</label>
  </div>
</div>

5 个答案:

答案 0 :(得分:77)

如果您只是想使用CSS,一种解决方案是转换max-height而不是height,并将其设置为比以往更大的值......

这是DEMO

您需要稍微调整一下转换的速度,但至少这个示例可以让您了解如何完成转换。不要忘记在转换过程中更改属性。从transition: height 0.5s;transition: max-height 0.5s;

希望这有帮助!

.ac-container{
    width: 400px;
    margin: 10px auto 30px auto;
    text-align: left;
}
.ac-container label{
    font-family: 'BebasNeueRegular', 'Arial Narrow', Arial, sans-serif;
    padding: 5px 20px;
    position: relative;
    z-index: 20;
    display: block;
    height: 30px;
    cursor: pointer;
    color: #777;
    text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
    line-height: 33px;
    font-size: 19px;
    background: #ffffff;
    background: -moz-linear-gradient(top, #ffffff 1%, #eaeaea 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,#ffffff), color-stop(100%,#eaeaea));
    background: -webkit-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
    background: -o-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
    background: -ms-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
    background: linear-gradient(top, #ffffff 1%,#eaeaea 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eaeaea',GradientType=0 );
    box-shadow: 
        0px 0px 0px 1px rgba(155,155,155,0.3), 
        1px 0px 0px 0px rgba(255,255,255,0.9) inset, 
        0px 2px 2px rgba(0,0,0,0.1);
}
.ac-container label:hover{
    background: #fff;
}
.ac-container input:checked + label,
.ac-container input:checked + label:hover{
    background: #c6e1ec;
    color: #3d7489;
    text-shadow: 0px 1px 1px rgba(255,255,255, 0.6);
    box-shadow: 
        0px 0px 0px 1px rgba(155,155,155,0.3), 
        0px 2px 2px rgba(0,0,0,0.1);
}

.ac-container input{
    display: none;
}
.ac-container section{
    background: rgba(255, 255, 255, 0.5);
    margin-top: -1px;
    overflow: hidden;
    max-height: 0px;
    position: relative;
    z-index: 10;
    -webkit-transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear;
    -moz-transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear;
    -o-transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear;
    -ms-transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear;
    transition: max-height 0.3s ease-in-out, box-shadow 0.6s linear;
}
.ac-container section p{
    font-style: italic;
    color: #777;
    line-height: 23px;
    font-size: 14px;
    padding: 20px;
    text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
}
.ac-container input:checked ~ section{
    -webkit-transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear;
    -moz-transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear;
    -o-transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear;
    -ms-transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear;
    transition: max-height 0.5s ease-in-out, box-shadow 0.1s linear;
    box-shadow: 0px 0px 0px 1px rgba(155,155,155,0.3);
}
.ac-container input:checked ~ section.ac-small{
    max-height: 500px; /*auto*/
}
<div class="ac-container">
    <div>
        
        <input id="ac-1" name="accordion-1" type="checkbox" />
        <section class="ac-small">
            <p>Some content...Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content... Some content...  </p>
        </section>
        <label for="ac-1">About us</label>
        
    </div>    

<div>    
        <input id="ac-2" name="accordion-2" type="checkbox" />
        <section class="ac-small">
            <p>Some content... </p>
        </section>
        <label for="ac-2">About us</label>
</div>
</div>

答案 1 :(得分:10)

您无法为“自动”维度制作动画(不幸的是)。我通常采用的方法是设置外部DIV的高度,该外部DIV具有单个子项,这是一种仅用于测量内容高度的无样式DIV。

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";
  }
}
#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;
}
<input type="button" onclick="growDiv()" value="grow">
<div id='grow'>
  <div class='measuringWrapper'>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
    <div>
      The contents of my div.
    </div>
  </div>
</div>

答案 2 :(得分:9)

您应该使用scaleY。

ul {
  background-color: #eee;
  transform: scaleY(0);    
  transform-origin: top;
  transition: transform 0.3s ease-in-out;
}    
p:hover ~ ul {
  transform: scaleY(1);
}
<p>Here (scaleY(1))</p>
<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li>Milk</li>
</ul>

或者您可以使用clip 剪切列表。

ul {
  clip: rect(auto, auto, 0, auto);
  position: absolute;
  left: 0;
  margin: 0;
  padding: 0;

  color: white;

  background-color: rgba(0, 0, 0, 0.8);

  transition-delay: 0.29s;
  transition-property: clip;
  transition-duration: 0.5s;
  transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
h3:hover ~ ul,
h3:active ~ ul {
  clip: rect(auto, auto, 10rem, auto);
}
<h3>Hover here</h3>
<ul>
  <li>This</li>
  <li>list</li>
  <li>is</li>
  <li>clipped.</li>
  <li>A clip</li>
  <li>transition</li>
  <li>will</li>
  <li>show it</li>
</ul>
<p>
  Some text...
</p>

答案 3 :(得分:6)

很久以前我遇到了这个问题而且很难克服,但CSS转换不适用于自动值。最后我提出了一个混合解决方案,让css过渡,但用JavaScript改变高度。它会完美地运作。

答案 4 :(得分:1)

auto不适用于可设置动画的属性,请参阅CSS Transitions: 7. Animatable properties。您需要长度(pxem,...)或百分比(13.37%)。

因此,只要auto未添加到列表中,就无法使用仅CSS解决方案。您需要使用JavaScript或特定长度值。