tricks 어떻게 전환 할 수 높이:0; 높이:자동; CSS 사용?




transition 뜻 (24)

CSS 전환을 사용하여 <ul> 슬라이드를 아래로 만들려고합니다.

<ul>height: 0; 에서 시작합니다 height: 0; . 마우스를 올리면 높이가 높이로 설정됩니다 height:auto; . 그러나, 이것은 단순히 나타나기만하고, 천이는 아니며 ,

나는 height: 40px; 에서 그것을하는 경우에 height: 40px; height: auto; , height: 0; 까지 올립니다 height: 0; 갑자기 올바른 높이로 건너 뜁니다.

자바 스크립트를 사용하지 않고 어떻게해야합니까?

#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;
}
The only difference between the two snippets of CSS is one has height: 0, the other height: 40.
<hr>
<div id="parent0">
  <h1>Hover me (height: 0)</h1>
  <div id="child0">Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>
  </div>
</div>
<hr>
<div id="parent40">
  <h1>Hover me (height: 40)</h1>
  <div id="child40">Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>Some content
    <br>
  </div>
</div>


나는 최근에를 전환했습니다 max-heightli요소가 아닌 포장 ul.

추론은 소규모의 지연이 있다는 것입니다 max-heights대형에 비해 (모든 경우)까지 눈에 잘 띄지 않는 max-heights, 나는 또한 나의 설정할 수 있습니다 max-height받는 상대적인 값 font-sizeli사용에 의해 오히려 어떤 임의의 큰 수보다를 ems하거나 rems.

내 글꼴 크기가 있다면 wrapped text를 수용하기 위해 1remmy max-height로 설정할 것입니다 3rem. 여기에서 예제를 볼 수 있습니다.

http://codepen.io/mindfullsilence/pen/DtzjE


최대 높이를 움직이게하는 Jake의 대답은 훌륭하지만 큰 max-height 짜증나는 설정으로 인한 지연을 발견했습니다.

하나는 접을 수있는 내용을 내부 div로 옮기고 내부 div의 높이를 가져 와서 최대 높이를 계산할 수 있습니다 (JQuery를 통해 outerHeight ()가 됨).

$('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://jsfiddle.net/8ncjjxh8/


하이 레벨 중 하나가 auto 일 때 현재는 높이에 애니메이션을 적용 할 수 없으며 두 가지 명시적인 높이를 설정해야합니다.


모든 것을 자세하게 읽지는 못했지만 최근에이 문제가 있었고 다음과 같은 일을했습니다.

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

이렇게하면 처음에는 200px 높이까지의 내용을 보여주고 그 위에 놓인 크기는 div의 전체 내용만큼 높게 나타나는 div를 가질 수 있습니다. Div는 3000px가되지 않지만 3000px는 내가 부과하는 한계입니다. non : hover로 전환해야합니다. 그렇지 않으면 이상한 렌더링이 발생할 수 있습니다. 이런 식으로 : hover는 non : hover에서 상속받습니다.

전환이 % px 또는 auto로 작동하지 않습니다. 동일한 측정 단위를 사용해야합니다. 이것은 나를 위해 잘 작동합니다. HTML5를 사용하면 완벽 해집니다.

항상 주위에 일이 있다는 것을 기억하십시오 ...; )

희망이 누군가는이 유용한 발견


편집 : 스크롤 다운 업데이트 된 답변에
대한 드롭 다운 목록을 만들고 있었고이 게시물을 보았다 ... 많은 다른 답변을하지만, 내 드롭 다운 목록을 공유하기로 결정도 ... 완벽하지는 않지만 적어도 CSS를 사용합니다 쓰러지 다! 나는 transform : translateY (y)를 사용하여리스트를 뷰로 변환했다 ...
테스트에서 더 많은 것을 볼 수있다.
http://jsfiddle.net/BVEpc/4/
나는 모든 li 뒤에 div를 배치했다. 드롭 다운 목록이 올라오고 있으며 적절하게 표시하려면 이것이 필요합니다. 내 div 코드는 다음과 같습니다.

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

호버 :

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

ul 높이가 콘텐츠로 설정되어 있기 때문에 귀하의 신체 내용을 극복 할 수 있습니다. 그 이유는 ul에 대해 이렇게했습니다.

 #menu ul {
    transition: 0s 1.5s;
    visibility:hidden;
    overflow:hidden;
}

및 마우스를 올리십시오 :

#menu > li:hover ul {
     transition:none;
     visibility:visible;
}

전환 후 두 번째 시간이 지연되고 내 드롭 다운 목록이 애니메이션으로 닫힌 후에 숨겨집니다.
나중에 누군가가이 혜택을 누리 길 바랍니다 .

편집 : 나는 단지 프로토 타입을 사용하여 ppl 실제로 믿을 수 없어! 이 드롭 다운 메뉴는 하나의 하위 메뉴에만 해당되며 그게 전부입니다 !! IE 8 지원으로 ltr 및 rtl 방향 모두에 대해 두 개의 하위 메뉴를 가질 수있는 더 나은 버전을 업데이트했습니다.
LTR에 대한 바이올린
RTL에 대한 바이올린은
희망 누군가가 앞으로이 유용하게 찾을 수 있습니다.


max-height 가 아닌 변형에서 max-height 를 사용하십시오. 그리고 max-height 의 값을 상자보다 큰 값으로 설정하십시오.

Chris Jordan이 제공 한 JSFiddle 데모 에서 다른 answer 참조하십시오.

#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;
}
<div id="menu">
    <a>hover me</a>
    <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>
</div>


이것은 정확하게 문제에 대한 "해결책"은 아니지만 해결 방법에 대한 것입니다. 텍스트로 쓰여진 것으로서 만 작동하지만 필요에 따라 다른 요소로 작업 할 수 있습니다.

.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로 변환하는 것은 현재 가능하지 않지만 그 안에 내용을 변환하는 것은 글꼴 크기 변경입니다.

  • 참고 - codepen에 javascript가 있지만, 목적은 아코디언을 클릭 할 때 CSS 클래스를 추가 / 제거하는 것입니다. 숨겨진 라디오 버튼을 사용하면이 작업을 수행 할 수 있습니다.

나는 정말로 솔리드 한 해결책을 찾았다 고 생각한다.

승인!나는이 문제가 인터넷만큼 오래되었다는 것을 알고 있지만 돌연변이 체 전이 (mutant-transition)라는 플러그인으로 바뀐 해결책이 있다고 생각한다 . 내 솔루션 style=""은 DOM을 변경할 때마다 추적 된 요소 의 속성을 설정합니다 . 최종 결과는 전환에 좋은 OLE CSS를 사용할 수 있으며 해킹 수정 또는 특수 자바 스크립트를 사용하지 않아야한다는 것입니다. 당신이해야 할 유일한 일은 당신이 사용하고자하는 요소에서 추적하고자하는 것을 설정하는 것 data-mutant-attributes="X"입니다.

<div data-mutant-attributes="height">                                                                      
        This is an example with mutant-transition                                                                                                          
    </div>

그게 전부 야! 이 솔루션은 MutationObserver 를 사용 하여 DOM의 변경 사항을 추적합니다. 이 때문에 실제로 아무것도 설정하거나 javascript를 사용하여 수동으로 애니메이션을 적용 할 필요가 없습니다. 변경 사항은 자동으로 추적됩니다. 그러나 MutationObserver를 사용하기 때문에 IE11 +에서만 전환됩니다.

피들 즈!


하드 코딩 된 최대 높이 값이 실제 높이보다 크지 않으면 (그렇지 않으면 바람직하지 않은 지연 및 타이밍 문제가 있기 때문에) Jake의 최대 높이 솔루션이 잘 작동합니다. 반면 하드 코딩 된 값이 실수로 실제 높이보다 크지 않으면 요소가 완전히 열리지 않습니다.

다음의 CSS 전용 솔루션은 발생하는 실제 크기보다 더 커야하는 하드 코드 된 크기가 필요합니다. 그러나이 솔루션은 실제 크기가 하드 코딩 된 크기보다 큰 일부 상황에서도 작동합니다. 이 경우 전환이 조금씩 진행될 수 있지만 부분적으로 보이는 요소가 남지는 않습니다. 따라서이 솔루션은 알 수없는 컨텐트, 예를 들어 데이터베이스에서 컨텐트가 일반적으로 x 픽셀보다 크지 않다는 것을 알고 있지만 예외가있을 때도 사용할 수 있습니다.

아이디어는 margin-bottom (또는 약간 다른 애니메이션의 경우 margin-top)에 음수 값을 사용하고 content 요소를 overflow : hidden이있는 중간 요소에 배치하는 것입니다. content 요소의 음수 여백은 중간 요소의 높이를 줄입니다.

다음 코드에서는 -150px에서 0px까지 margin-bottom의 전환을 사용합니다. 콘텐츠 요소가 150 픽셀보다 크지 않은 경우에만 혼자 작동합니다. 또한 중간 요소의 최대 높이를 0px에서 100 %로 전환합니다. content 요소가 150px보다 높으면 중간 요소를 숨 깁니다. 최대 높이의 경우 전환은 부드러운 시각 효과가 아닌 닫을 때 응용 프로그램을 1 초 지연하기 위해 사용됩니다 (따라서 0px에서 100 %까지 실행할 수 있음).

CSS :

.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 :

<div class="outer">
  <div class="middle">
    <div class="content">
      Sample Text
      <br> Sample Text
      <br> Sample Text
      <div style="height:150px">Sample Test of height 150px</div>
      Sample Text
    </div>
  </div>
  Hover Here
</div>

여백 하단의 값은 음수이고 가능한 한 콘텐츠 요소의 실제 높이에 가깝습니다. 그것 (absoute 값)이 더 크다면, 최대 높이 솔루션과 비슷한 지연 및 타이밍 문제가 있지만, 하드 코딩 된 크기가 실제 크기보다 훨씬 크지 않은 한 제한 될 수 있습니다. margin-bottom의 절대 값이 실제 높이보다 작 으면 tansition이 약간 증가합니다. 어떤 경우에도 전환 후에는 콘텐츠 요소가 완전히 표시되거나 완전히 제거됩니다.

자세한 내용은 내 블로그 게시물 http://www.taccgl.org/blog/css_transition_display.html#combined_height


노드 단위로 하드 코드를 설정하거나 사용자 코드를 초기화하지 않고도 0을 비롯한 시작 높이에서 자동 (전체 크기 및 유연)으로 전환하는 방법은 다음과 같습니다. https://github.com/csuwildcat/transition-auto . 이것은 기본적으로 당신이 원하는 것을위한 성배입니다, 나는 믿습니다 -> http://codepen.io/csuwldcat/pen/kwsdF . 다음 JS 파일을 페이지에 붙여 넣기 만하면 reveal=""확장 및 축소하려는 노드에서 단일 부울 속성을 추가 / 제거 할 수 있습니다.

예제 코드 아래에있는 코드 블록을 포함 시키면 사용자로해야 할 일은 다음과 같습니다.

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

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

<div reveal>
     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!...
</div>

다음은 페이지에 포함 할 코드 블록입니다. 그 후에는 모두 그레이비입니다.

이 JS 파일을 페이지에 드롭하십시오. 모두 Just Works ™

/ * 높이 코드 : 자동; 전환 중 * /

(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);

/ * DEMO 코드 * /

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

최소 높이와 최대 높이를 제공하면 높이 : 0에서 높이 : 자동으로 전환 할 수 있습니다.

div.stretchy{
    transition: 1s linear;
}

div.stretchy.hidden{
    height: 0;
}

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

대신 scaleY를 사용해야합니다.

HTML :

<p>Here (scaleY(1))</p>
<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li>Milk</li>
</ul>

CSS :

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/dotnetCarpenter/PhyQc/9/ 에서 위의 코드의 접두사 버전을 만든 다음 높이 대신 scaleY를 사용하도록 jsfiddle를 변경했습니다. http://jsfiddle.net/dotnetCarpenter/7cnfc/206/ .


Flexbox 솔루션

장점 :

  • 단순한
  • 아니오 JS
  • 부드러운 전이

단점 :

  • 요소는 고정 된 높이의 플렉스 컨테이너에 있어야합니다.

그것이 작동하는 방식은 항상 flex-basis를 갖는 것입니다 : content로 내용을 auto로 바꾸고, flex-grow과 flex-shrink를 전환하십시오.

편집 : 개선 된 JS Fiddle은 Xbox One 인터페이스에서 영감을 얻었습니다.

* {
  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;    
}
<div class="box">
  <div class="space"></div>
  <p>
    Super Metroid Prime Fusion
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Resident Evil 2 Remake
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Yolo The Game
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    Final Fantasy 7 Remake + All Additional DLC + Golden Tophat
  </p>
</div>
<div class="box">
  <div class="space"></div>
  <p>
    DerpVille
  </p>
</div>

JS 피들


비 의미 론적 조그마한 - 위커리를 조금 할 수 있습니다. 내 일반적인 접근 방식은 콘텐츠 높이를 측정하는 데만 사용되는 스타일이없는 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>

하나는 .measuringWrapper DIV의 높이를 auto로 설정하고 애니메이션을 적용 할 수는 있지만 작동하지 않는 것입니다 (높이는 설정되지만 애니메이션은 발생하지 않음).

function growDiv() {
  var growDiv = document.getElementById('grow');
  if (growDiv.clientHeight) {
    growDiv.style.height = 0;
  } else {
    growDiv.style.height = 'auto';
  }
}
#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>
    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>

내 해석은 애니메이션을 실행하려면 명시적인 높이가 필요하다는 것입니다. 높이 (시작 높이 또는 끝 높이)가 auto 때 높이에 애니메이션을 가져올 수 없습니다.


Element.scrollHeight여기서 유용 할 수있는 속성 은 거의 언급되지 않았 으며 여전히 순수 CSS 전환과 함께 사용할 수 있습니다. 이 속성은 축소 된 높이 (예 :)로 인해 콘텐츠의 오버플로 여부와 오버플로 여부에 관계없이 요소의 "전체"높이를 항상 포함합니다 height: 0.

따라서 height: 0(효과적으로 완전히 접힌) 요소의 경우 "정상"또는 "전체"높이가 해당 scrollHeight값 (항상 픽셀 길이)을 통해 쉽게 사용할 수 있습니다 .

그러한 요소의 경우, 이미 ul원래의 질문을 사용하여 eg와 같이 전환이 설정되었다고 가정하십시오 .

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

CSS 만 사용하여 다음과 같은 식으로 원하는 높이의 애니메이션 "확장"을 트리거 할 수 있습니다 (여기서 ul변수는 목록을 나타냄).

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

그게 전부 야. 목록을 축소해야하는 경우 다음 두 문 중 하나가 수행됩니다.

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

내 특정 사례는 알려지지 않았고 종종 상당한 길이의 목록에 애니메이션을 적용하는 데 중점을 두었습니다. 따라서 임의의 "충분히 큰" height또는 max-height사양 에 정착하고 갑자기 스크롤해야하는 컷오프 콘텐츠 나 콘텐츠를 위험에 빠뜨리는 것이 쉽지 않았습니다 ( overflow: auto예 : . 또한, 완화 및 타이밍과 깨진 max-height사용 된 높이가 훨씬 빨리이 걸릴 것보다 최대 값에 도달 할 수 있기 때문에, 기반 솔루션 max-height에 도달하는 9999px. 그리고 화면 해상도가 높아지면서 픽셀 길이는 9999px입안에 좋지 않은 맛을 남깁니다. 이 특별한 해결책은 제 의견으로는 우아한 방식으로 문제를 해결합니다.

마지막으로 CSS 주소 작성자의 향후 수정 사항이 이러한 종류의 일을 훨씬 더 우아하게 처리해야 할 필요가 있음을 알기를 원합니다. "계산 된"vs "사용 된"및 "해결 된"값의 개념을 다시 검토하고 전환을 계산 와 전환을 포함하여 값 widthheight(현재 특별한 치료의 비트를 얻을 수 있음).


나는이 스레드가 오래되었다는 것을 알고 있지만 특정 Google 검색에서 순위가 ​​높기 때문에 업데이트 할 가치가 있다고 판단합니다.

또한 요소의 높이를 가져 오거나 설정합니다.

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

인라인 스크립트 태그에서 target_box의 닫기 태그 바로 뒤에이 자바 스크립트를 덤프해야합니다.


제 해결 방법은 최대 높이를 멋진 부드러운 애니메이션을위한 정확한 콘텐츠 높이로 변환 한 다음 transitionEnd 콜백을 사용하여 최대 높이를 9999px로 설정하여 콘텐츠의 크기를 자유롭게 조정할 수 있도록하는 것입니다.

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
        });
        
    }
});
.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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id="content" class="open">
    <div class="inner">
        <h3>Smooth CSS Transitions Between <code>height: 0</code> and <code>height: auto</code></h3>
        <p>A clever workaround is to use <code>max-height</code> instead of <code>height</code>, 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 <code>max-height: 1000px</code> 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 <code>max-height: 9999px</code> after the transition for fluid content sizing.</p>
    </div>
</div>

<br />

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


높이를 auto로 설정하고 최대 높이를 전환하십시오.

Chrome v17에서 테스트 됨

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%; /**/
}

좋아, 그래서 나는 아주 간단한 대답을 생각해 냈다 ... 아니 max-height, relative포지셔닝을 사용하고 , li요소에 대해 작업하고 , 순수한 CSS이다. CSS 이외에도 Firefox에서 테스트하지는 않았지만 모든 브라우저에서 작동해야합니다.

FIDDLE : http://jsfiddle.net/n5XfG/2596/

CSS

.wrap { overflow:hidden; }

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

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

HTML

<div class="wrap">
    <div class="inner">Some Cool Content</div>
</div>

이것은 내가 이런 식으로 해결 한 규칙적인 문제이다.

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

닫힌 상태의 지연을 몇 가지 음수로 설정하고 값을 조금씩 재생 해 봅니다. 당신은 차이를 볼 수 있습니다. 그것은 인간의 눈에 거의 누워있을 수 있습니다;).

주요 브라우저에서 작동하지만 나에게 충분합니다. 그것은 이상하지만 약간의 결과를줍니다.

.expandable {
    max-height: 0px;
    overflow: hidden;
    transition: all 1s linear -0.8s;
}

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

필자가 항상 사용한 솔루션은 먼저 페이드 아웃 한 다음 font-size , paddingmargin 값을 줄이는 것입니다. 닦아내는 것과 똑같지는 않지만 정적 height max-height height 가 없으면 작동합니다.

실례 :

/* 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;
}
<div id="menu">
    <b>hover me</b>
    <ul id="list">
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>

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


허용 된 답변은 대부분의 경우에 적용되지만 div애니메이션의 속도는 콘텐츠의 실제 높이에 의존하지 않고 고르지 않게 나타날 수 있습니다.

CSS로 실제 애니메이션을 수행 할 수는 있지만 사용하려고하지 않고 JavaScript를 사용하여 항목의 높이를 계산해야합니다 auto. 호환성을 원한다면 조금 수정해야 할 수도 있지만 jQuery는 필요하지 않습니다 (최신 버전의 Chrome에서 작동합니다.).

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';
    }
}
#menu #list {
    height: 0px;
    transition: height 0.3s ease;
    background: #d5d5d5;
    overflow: hidden;
}
<div id="menu">
    <input value="Toggle list" type="button" onclick="toggleExpand(document.getElementById('list'));">
    <ul id="list">
        <!-- Works well with dynamically-sized content. -->
        <li>item</li>
        <li><div style="height: 100px; width: 100px; background: red;"></div></li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>


@ jake의 답변을 확대하면 전환이 최대 높이 값까지 진행되어 극도로 빠른 애니메이션을 생성합니다. 마우스를 올리거나 내리면 전환 속도를 조금만 조절할 수 있습니다.

그러므로 li : 마우스를 올리면 마우스가 상태로 들어간 다음 마우스가 놓여 있지 않은 속성의 전환이 마우스를 놓을 것입니다.

바라기를 이것은 도움이 될 것입니다.

예 :

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


나는 이것이이 질문에 대한 30 가지 대답이지만, 그것이 가치 있다고 생각한다. 그래서 여기에 간다. 이것은 다음 속성을 가진 CSS 전용 솔루션입니다.

  • 처음에는 지연이 없으며 전환이 조기에 중단되지 않습니다. 두 방향 (확장 및 축소)에서 CSS에서 전환 지속 시간을 300ms로 지정하면 전환에는 300ms의 기간이 걸립니다.
  • 이것은 실제 높이를 transform: scaleY(0) ( transform: scaleY(0) 와 달리). 접을 수있는 요소 뒤에 내용이있는 경우 올바른 작업을 수행합니다.
  • (다른 솔루션과 마찬가지로) 마법의 숫자가 있습니다 ( "상자의 길이보다 길게 선택하십시오"와 같이). 가정이 잘못되면 치명적이지는 않습니다. 이 경우 전이가 훌륭하게 보이지 않을 수 있지만 전환 전후에 문제가되지는 않습니다. 확장 된 ( height: auto ) 상태에서 전체 내용의 높이가 항상 같습니다 (예 : max-height 가 너무 낮음). 접은 상태에서 높이는 제로입니다.

데모

다음은 세 가지 접을 수있는 요소가있는 데모입니다. 높이가 모두 다르기 때문에 모두 동일한 CSS를 사용합니다. "run snippet"을 클릭 한 후 "전체 페이지"를 클릭 할 수 있습니다. 자바 스크립트는 collapsed CSS 클래스 만 토글합니다. 측정이 필요 없습니다. (checkbox 또는 :target 을 사용하여 자바 스크립트없이이 정확한 데모를 할 수 있습니다.) 또한 전환을 담당하는 CSS 부분은 매우 짧으며 HTML에는 단 하나의 추가 래퍼 요소 만 필요합니다.

$(function () {
  $(".toggler").click(function () {
    $(this).next().toggleClass("collapsed");
    $(this).toggleClass("toggled"); // this just rotates the expander arrow
  });
});
.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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

  <div class="menu">
    <div class="menu-item">Something involving a holodeck</div>
    <div class="menu-item">Send an away team</div>
    <div class="menu-item toggler">Advanced solutions</div>
    <div class="collapsible-wrapper collapsed">
      <div class="collapsible">
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
        <div class="menu-item">Separate saucer</div>
        <div class="menu-item">Send an away team that includes the captain (despite Riker's protest)</div>
        <div class="menu-item">Ask Worf</div>
        <div class="menu-item">Something involving Wesley, the 19th century, and a holodeck</div>
        <div class="menu-item">Ask Q for help</div>
      </div>
    </div>
    <div class="menu-item">Sweet-talk the alien aggressor</div>
    <div class="menu-item">Re-route power from auxiliary systems</div>
  </div>

</div>

어떻게 작동합니까?

실제로 이러한 일이 일어나기위한 두 가지 전환이 있습니다. 그 중 하나는 접힌 상태에서 0px (확장 된 상태 인 경우)에서 -2000px 까지 margin-bottom 을 전환합니다 ( 이 답변 과 유사). 여기 2000은 첫 번째 마법 수입니다. 상자가 이보다 높지 않을 것이라는 가정에 기반합니다 (2000 픽셀은 합리적인 선택처럼 보입니다).

margin-bottom 전환 만 사용하면 두 가지 문제가 있습니다.

  • 실제로 2000 픽셀보다 큰 상자가있는 경우 margin-bottom: -2000px 이 모든 것을 숨기지 않고 접힌 케이스에서도 보이는 항목이 표시됩니다. 나중에 수행 할 사소한 수정입니다.
  • 실제 상자가 1000 픽셀 높이이고 전환이 300ms 인 경우 가시적 인 전환은 약 150ms 후에 이미 끝났습니다 (또는 반대 방향으로 늦게 150ms가 시작됩니다).

이 두 번째 문제를 해결하는 것은 두 번째 전환이 들어오는 부분입니다.이 전환은 개념적으로 래퍼의 최소 높이를 개념적으로 대상으로합니다 (개념적으로 min-height 속성을 사용하지 않기 때문에 개념적으로 더 자세히 설명합니다).

하단 여백 전환과 최소 높이 전환을 같은 기간 동안 결합하는 방법을 보여주는 애니메이션은 전체 높이에서 0 높이까지 동일한 지속 시간을 갖는 결합 전환을 제공합니다.

왼쪽 막대는 음의 아래쪽 여백이 어떻게 보이지 않는 높이를 줄이는지를 보여줍니다. 중간 막대는 최소 높이가 축소 상황에서 전환이 일찍 끝나지 않는 것을 보여줍니다. 확장하는 경우에는 전환이 늦게 시작되지 않습니다. 오른쪽 막대는 둘의 결합으로 상자가 전체 높이에서 제로 높이로 정확한 시간 내에 전환되는 것을 보여줍니다.

내 데모에서는 상단 최소 높이 값으로 50px로 정했습니다. 이것은 두 번째 매직 넘버이며 상자의 높이보다 낮아야합니다. 50px도 합리적인 것처럼 보입니다. 처음에는 50 픽셀 높이가 아닌 접을 수있는 요소를 만들고 싶지는 않을 것 같습니다.

애니메이션에서 볼 수 있듯이, 결과적인 전환은 연속적이지만, 최소 높이가 하단 여백에 의해 조정 된 전체 높이와 동일한 순간에는 속도가 급격하게 변합니다. 이것은 애니메이션에서 매우 두드러집니다. 왜냐하면 두 전환에 선형 타이밍 기능을 사용하고 전체 전환이 매우 느리기 때문입니다. 실제 사례 (상단의 데모)에서는 전환이 300ms 밖에 걸리지 않으며 하단 여백 전환이 선형이 아닙니다. 두 전환에 대해 서로 다른 많은 타이밍 기능을 가지고 놀았습니다. 가장 다양한 경우에 가장 잘 작동하는 것 같은 느낌이 들었습니다.

해결해야 할 두 가지 문제가 남아 있습니다.

  1. 위에서 2000 픽셀 이상의 상자가 접힌 상태에서 완전히 숨겨지지 않은 지점,
  2. 숨겨진 경우가 아닌 경우, 최소 높이가 50 픽셀로 유지되기 때문에 전환이 실행되지 않아도 높이가 50 픽셀보다 작은 상자는 너무 높습니다.

첫 번째 문제는 컨테이너 요소에 0s 0.3s 전환이있는 접힌 경우 max-height: 0 을 지정하여 해결합니다. 이는 실제로 전환이 아니라 max-height 가 지연과 함께 적용됨을 의미합니다. 전환이 끝나면 적용됩니다. 이 작업을 올바르게 수행하려면 반대쪽, 축소되지 않은 상태의 수치 max-height 를 선택해야합니다. 그러나 너무 큰 숫자를 선택하는 것이 전환의 품질에 영향을주는 2000px 경우와 달리이 경우에는 실제로 중요하지 않습니다. 그래서 우리는 높이가 너무 높아서이 정도까지 올 수없는 숫자를 고를 수 있습니다. 나는 백만 픽셀을 골랐어. 100 만 픽셀보다 큰 높이의 내용을 지원해야한다고 생각되면 1) 미안합니다. 2) 몇 개의 0을 추가하십시오.

두 번째 문제는 실제로 최소 높이 전환에 최소 높이를 사용하지 않는 이유입니다. 대신 컨테이너에 ::after 의사 요소가 있으며 height 가 50px에서 0으로 전환됩니다. 이것은 min-height 와 같은 효과가 있습니다. 의사 요소가 현재 가지고있는 높이 이하로 컨테이너를 축소시키지 않습니다. 그러나 min-height 높이가 아닌 높이를 사용하기 때문에 전환이 끝나면 의사 요소의 실제 높이를 0으로 설정하기 위해 max-height (다시 한 번 지연 적용)를 사용할 수 있습니다. 작은 요소라도 정확한 높이를 갖습니다. min-heightmax-height 보다 stronger 때문에 pseudo-element의 height 대신에 컨테이너의 min-height 를 사용하면 이것이 불가능합니다. 앞 단락의 max-heightmax-height 에도 전환 반대쪽 끝의 값이 필요합니다. 하지만이 경우에는 50 픽셀 만 선택할 수 있습니다.

Chrome (Win, Mac, Android, iOS), Firefox (Win, Mac, Android), Edge, IE11 (디버깅을 신경 쓰지 않았다는 데모에서 Flexbox 레이아웃 문제는 제외) 및 Safari (Mac, iOS ). flexbox에 대해 말하면, flexbox를 사용하지 않고이 작업을 수행 할 수 있어야합니다. 실제로 저는 IE7에서 거의 모든 것을 작동시킬 수 있다고 생각합니다. CSS 전환이 없으므로 다소 무의미한 연습을 할 것입니다.





css-transitions