질문자 :Hailwood
CSS 전환을 사용하여 <ul>
슬라이드를 아래로 만들려고 합니다.
<ul>
height: 0;
에서 시작합니다. . 마우스를 올리면 높이가 height:auto;
. 그러나 이로 인해 전환이 아닌 단순히 나타나게 됩니다.
height: 40px;
height: auto;
height: 0;
까지 슬라이드합니다. , 그리고 갑자기 올바른 높이로 점프합니다.
JavaScript를 사용하지 않고 다른 방법으로 이것을 할 수 있습니까?
#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-height
전환하지에 height
. max-height
의 값을 상자가 얻을 수 있는 것보다 더 큰 값으로 설정하십시오.
여기에서 다른 답변 에서 Chris Jordan이 제공한 JSFiddle 데모를 참조하십시오.
#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>
jake대신 scaleY를 사용해야 합니다.
ul { background-color: #eee; transform: scaleY(0); transform-origin: top; transition: transform 0.26s ease; } p:hover ~ ul { transform: scaleY(1); }
<p>Hover This</p> <ul> <li>Coffee</li> <li>Tea</li> <li>Milk</li> </ul>
jsfiddle 에서 위 코드의 벤더 접두사 버전을 만들고 높이 대신 scaleY를 사용하도록 jsfiddle 을 변경했습니다.
편집 어떤 사람들은 어떻게 좋아하지 않아 scaleY
컨텐츠를 변환합니다. 그것이 문제라면 대신 clip
ul { clip: rect(auto, auto, 0, auto); position: absolute; margin: -1rem 0; padding: .5rem; color: white; background-color: rgba(0, 0, 0, 0.8); 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, ul:hover { clip: rect(auto, auto, 10rem, auto); }
<h3>Hover here</h3> <ul> <li>This list</li> <li>is clipped.</li> <li>A clip transition</li> <li>will show it</li> </ul> <p> Some text... </p>
dotnetCarpenterauto
인 경우 현재 높이에 애니메이션을 적용할 수 없으며 두 개의 명시적 높이를 설정해야 합니다.
robertc내가 항상 사용한 솔루션은 먼저 페이드 아웃한 다음 font-size
, padding
및 margin
값을 축소하는 것입니다. 와이프와 같지는 않지만 static height
또는 max-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>
Steven Vachon이것이 이 질문에 대한 30가지 대답이라는 것을 알고 있지만 그만한 가치가 있다고 생각합니다. 이것은 다음 속성을 가진 CSS 전용 솔루션입니다.
- 처음에는 지연이 없고 전환은 일찍 멈추지 않습니다. 양방향(확장 및 축소)에서 CSS에서 전환 지속 시간을 300ms로 지정하면 전환에 300ms가 소요됩니다.
- 실제 높이를 전환하고 있으므로(
transform: scaleY(0)
과 달리) 접을 수 있는 요소 뒤에 내용이 있으면 올바른 작업을 수행합니다. - (다른 솔루션에서와 같이) 마법의 숫자가 있지만 (예: "상자의 길이보다 더 긴 길이를 선택하십시오"), 가정이 틀리면 치명적이지는 않습니다. 전환은이 경우에 놀라운 보이지 않을 수 있지만, 이전과 전환 후,이 문제가되지 않습니다 : 확장 된 (에서
height: auto
) 당신이 선택하면 상태, 전체 내용이 항상 (달리 예를 올바른 높이가 max-height
가 너무 낮음). 그리고 접힌 상태에서 높이는 당연히 0입니다.
데모
다음은 모두 동일한 CSS를 사용하는 서로 다른 높이의 세 가지 접을 수 있는 요소가 있는 데모입니다. "스니펫 실행"을 클릭한 후 "전체 페이지"를 클릭할 수 있습니다. collapsed
CSS 클래스만 토글하며 측정은 필요하지 않습니다. :target
을 사용하여 JavaScript 없이 이 정확한 데모를 수행할 수 있습니다. 또한 전환을 담당하는 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>
어떻게 작동합니까?
실제로 이를 수행하는 데에는 두 가지 전환이 필요합니다. 그 중 하나는 margin-bottom
을 0px(확장 상태)에서 접힌 상태( 이 답변 -2000px
로 전환합니다. 여기에서 2000은 첫 번째 마법의 숫자이며, 상자가 이보다 높지 않을 것이라는 가정에 기반합니다(2000픽셀은 합리적인 선택처럼 보입니다).
margin-bottom
전환을 단독으로 사용하는 것 자체에는 두 가지 문제가 있습니다.
- 실제로 2000픽셀보다 높은 상자가 있는 경우
margin-bottom: -2000px
는 모든 것을 숨기지 않습니다. 접힌 경우에도 보이는 항목이 있을 것입니다. 이것은 나중에 수행할 사소한 수정입니다. - 예를 들어 실제 상자의 높이가 1000픽셀이고 전환 길이가 300ms이면 약 150ms 후에 이미 보이는 전환이 끝난 것입니다(또는 반대 방향에서는 150ms 늦게 시작).
이 두 번째 문제를 해결하는 것은 두 번째 전환이 발생하는 위치이며 이 전환은 개념적으로 래퍼의 최소 높이를 대상으로 합니다("개념적으로"는 이에 대해 min-height
속성을 실제로 사용하지 않기 때문에 나중에 자세히 설명함).
다음은 동일한 기간의 하단 여백 전환과 최소 높이 전환을 결합하여 동일한 기간을 갖는 전체 높이에서 0 높이로 결합된 전환을 제공하는 방법을 보여주는 애니메이션입니다.
왼쪽 막대는 음수 하단 여백이 하단을 위로 밀어서 보이는 높이를 줄이는 방법을 보여줍니다. 중간 막대는 축소의 경우 전환이 일찍 끝나지 않고 확장의 경우 전환이 늦게 시작되지 않도록 최소 높이를 보장하는 방법을 보여줍니다. 오른쪽 막대는 이 둘의 조합으로 상자가 정확한 시간 내에 전체 높이에서 0 높이로 전환되는 방법을 보여줍니다.
내 데모의 경우 최소 높이 값을 50px로 설정했습니다. 이것은 두 번째 마법의 숫자이며 상자의 높이보다 낮아야 합니다. 50px도 합리적으로 보입니다. 처음부터 높이가 50픽셀도 되지 않는 요소를 접을 수 있도록 만드는 경우가 거의 없을 것 같습니다.
애니메이션에서 볼 수 있듯이 결과 전환은 연속적이지만 미분할 수 없습니다. 최소 높이가 하단 여백에 의해 조정된 전체 높이와 동일한 순간 속도에 급격한 변화가 있습니다. 이는 두 전환 모두에 선형 타이밍 기능을 사용하고 전체 전환이 매우 느리기 때문에 애니메이션에서 매우 두드러집니다. 실제 경우(상단의 데모) 전환은 300ms만 걸리고 아래쪽 여백 전환은 선형이 아닙니다. 나는 두 전환 모두에 대해 다양한 타이밍 기능을 가지고 놀았고, 결국 가장 다양한 경우에 가장 잘 작동하는 것처럼 느꼈습니다.
해결해야 할 두 가지 문제가 남아 있습니다.
- 위에서 2000픽셀 이상의 높이의 상자가 접힌 상태에서 완전히 숨겨지지 않은 지점,
- 그리고 반대의 문제는 숨겨지지 않은 경우에 최소 높이가 50픽셀로 유지되기 때문에 전환이 실행되고 있지 않을 때에도 50픽셀 미만의 상자가 너무 높습니다.
max-height: 0
을 제공하여 첫 번째 문제를 해결합니다. 접힌 경우 0s 0.3s
전환입니다. 이것은 실제로 전환이 아니지만 max-height
가 지연과 함께 적용됨을 의미합니다. 전환이 끝난 후에만 적용됩니다. 이것이 올바르게 작동하려면 반대의 접히지 않은 상태에 대한 max-height
그러나 너무 큰 숫자를 선택하면 전환 품질에 영향을 미치는 2000px의 경우와 달리 이 경우에는 실제로 중요하지 않습니다. 그래서 우리는 높이가 이것에 근접하지 않을 것이라는 것을 아는 매우 높은 숫자를 선택할 수 있습니다. 백만 픽셀을 골랐습니다. 백만 픽셀이 넘는 높이의 콘텐츠를 지원해야 한다고 생각되면 1) 죄송합니다. 2) 0을 몇 개 추가하면 됩니다.
두 번째 문제는 우리가 실제로 사용하지 않는 이유입니다 min-height
최소 높이 전환을. 대신 컨테이너에 50px에서 0으로 전환되는 height
::after
의사 요소가 있습니다. min-height
와 같은 효과를 가집니다. 컨테이너가 현재 의사 요소의 높이 아래로 줄어들지 않도록 합니다. min-height
아니라 height
사용하고 있기 때문에 전환이 끝나면 의사 요소의 실제 높이를 0으로 설정하기 max-height
(다시 한 번 지연이 적용됨)를 사용할 수 있습니다. 전환 시 작은 요소라도 올바른 높이를 갖습니다. min-height
가 max-height
보다 강하기 때문에 의사 요소의 height
min-height
를 사용하면 작동하지 않습니다. 이전 단락 max-height
와 마찬가지로 max-height
에도 전환의 반대쪽 끝 값이 필요합니다. 그러나 이 경우에는 50px만 선택할 수 있습니다.
Chrome(Win, Mac, Android, iOS), Firefox(Win, Mac, Android), Edge, IE11(데모에서 디버깅을 방해하지 않은 flexbox 레이아웃 문제 제외) 및 Safari(Mac, iOS)에서 테스트되었습니다. ). flexbox에 대해 말하자면, flexbox를 사용하지 않고도 이 작업을 수행할 수 있어야 합니다. 사실 IE7에서 거의 모든 작업을 수행할 수 있다고 생각합니다. 단, CSS 전환이 없어 무의미한 작업이 된다는 사실을 제외하고는 말이죠.
balpha약간의 의미 없는 지그재그로 할 수 있습니다. 내 일반적인 접근 방식은 콘텐츠 높이 측정에만 사용되는 스타일이 없는 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의 높이를 자동으로 설정하고 애니메이션을 적용할 수 있기를 원하지만 작동하지 않는 것 같습니다(높이는 설정되지만 애니메이션은 발생하지 않음).
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
이면 높이에 대한 애니메이션을 얻을 수 없습니다.
jhurshmanCSS3 전환을 사용하여 높이에 애니메이션을 적용하는 시각적 해결 방법은 대신 패딩에 애니메이션을 적용하는 것입니다.
완전한 지우기 효과를 얻지는 못하지만 전환 지속 시간 및 패딩 값을 가지고 놀면 충분히 가까워질 것입니다. 높이/최대 높이를 명시적으로 설정하고 싶지 않다면 이것이 당신이 찾고 있는 것이어야 합니다.
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 위의 stephband에서 발췌)
Catharsis허용되는 답변은 대부분의 경우에 효과가 있지만 div
높이가 크게 다를 수 있는 경우에는 제대로 작동하지 않습니다. 애니메이션 속도는 콘텐츠의 실제 높이에 의존하지 않고 고르지 않게 보일 수 있습니다.
auto
를 사용하는 대신 JavaScript를 사용하여 항목의 높이를 계산해야 합니다. 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>
Oleg Vaskevich내 해결 방법은 멋진 부드러운 애니메이션을 위해 max-height를 정확한 콘텐츠 높이로 전환한 다음 transitionEnd 콜백을 사용하여 콘텐츠 크기를 자유롭게 조정할 수 있도록 max-height를 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>
AdamElement.prototype.scrollHeight
속성에 대한 언급은 거의 없었으며 여기에서 유용할 수 있고 여전히 순수한 CSS 전환과 함께 사용할 수 있지만 스크립팅 지원이 분명히 필요합니다 . height: 0
)의 결과로 콘텐츠가 오버플로되는지 여부와 방법에 관계없이 항상 요소의 "전체" 높이를 포함합니다.
따라서 height: 0
(효과적으로 완전히 접힌) 요소의 경우 "보통" 또는 "전체" 높이가 여전히 scrollHeight
값(불변 픽셀 길이)을 통해 쉽게 사용할 수 있습니다.
이러한 요소의 경우 예를 들어(원래 질문에 따라 ul
사용) 전환이 이미 설정되어 있다고 가정합니다.
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
9999px
에 도달하는 데 걸리는 것보다 훨씬 빨리 최대값에 도달할 수 있기 때문에 max-height
기반 솔루션에서는 여유 및 타이밍이 깨집니다. 그리고 화면 해상도가 9999px
와 같은 픽셀 길이는 제 입에 나쁜 맛을 남깁니다. 내 생각에 이 특정 솔루션은 문제를 우아한 방식으로 해결합니다.
마지막으로, CSS의 향후 개정이 이러한 종류의 작업을 더욱 우아하게 수행해야 하는 작성자의 요구를 해결하기를 희망합니다. "계산된" 대 "사용된" 및 "해결된" 값의 개념을 다시 살펴보고 전환을 계산된 값에 적용해야 하는지 여부를 고려하십시오. width
와 height
전환을 포함한 값(현재 약간의 특수 처리가 적용됨).
amn각 상태에 대해 다른 전환 완화 및 지연과 함께 max-height
를 사용합니다.
HTML:
<a href="#" id="trigger">Hover</a> <ul id="toggled"> <li>One</li> <li>Two</li> <li>Three</li> <ul>
CSS:
#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/
malihu하드 코딩된 값이 없습니다.
자바스크립트가 없습니다.
근사값이 없습니다.
비결은 숨김 및 복제된 div
를 사용하여 브라우저가 100%의 의미를 이해하도록 하는 것입니다.
이 방법은 애니메이션을 적용하려는 요소의 DOM을 복제할 수 있을 때마다 적합합니다.
.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%; }
Hover over the box below: <div class="outer"> <!-- The actual element that you'd like to animate --> <div class="real"> 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 </div> <!-- An exact copy of the element you'd like to animate. --> <div class="dummy" aria-hidden="true"> 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 </div> </div>
Vivek Maharajh내가 이것을 게시할 때 이미 30개가 넘는 답변이 있지만 제이크가 이미 수락한 답변보다 내 답변이 향상되었다고 생각합니다.
max-height
및 CSS3 전환을 사용하여 발생하는 문제에 만족하지 않았습니다. 많은 댓글 작성자가 언급했듯이 max-height
값을 실제 높이에 매우 가깝게 설정해야 하기 때문에 지연이 발생하기 때문입니다. 해당 문제의 예는 이 JSFiddle 을 참조하십시오.
이 문제를 해결하기 위해(여전히 JavaScript를 사용하지 않음) transform: translateY
CSS 값을 전환하는 다른 HTML 요소를 추가했습니다.
max-height
와 translateY
가 모두 사용된다는 것을 의미합니다 max-height
는 요소가 그 아래에 있는 요소를 밀어내도록 하는 반면, translateY
는 우리가 원하는 "즉각적인" 효과를 제공합니다. max-height
문제는 여전히 존재하지만 그 영향은 줄어듭니다. max-height
값에 대해 훨씬 더 큰 높이를 설정하고 이에 대해 덜 걱정할 수 있습니다.
전반적인 이점은 전환(축소) 시 사용자가 translateY
max-height
가 얼마나 오래 걸리는지는 중요하지 않다는 것입니다.
바이올린으로서의 솔루션
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); }
<div class="toggle"> <div class="toggle-header"> Toggle! </div> <div class="toggle-height"> <div class="toggle-transform"> <p>Content!</p> <p>Content!</p> <p>Content!</p> <p>Content!</p> </div> </div> </div> <div class="toggle"> <div class="toggle-header"> Toggle! </div> <div class="toggle-height"> <div class="toggle-transform"> <p>Content!</p> <p>Content!</p> <p>Content!</p> <p>Content!</p> </div> </div> </div>
Andrew Messier좋아, 그래서 나는 아주 간단한 대답을 생각해 냈다고 생각한다... no max-height
는 relative
위치 지정을 li
요소에서 작동하며 순수 CSS입니다. CSS로 판단하더라도 Firefox 이외의 다른 곳에서는 테스트하지 않았지만 모든 브라우저에서 작동해야 합니다.
바이올린: 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>
VIDesignz편집: 업데이트된 답변을 보려면 아래로 스크롤하십시오.
나는 드롭 다운 목록을 만들고이 게시물을 보았습니다 ... 많은 다른 답변이 있지만 내 드롭 다운 목록도 공유하기로 결정했습니다 ... 완벽하지는 않지만 적어도 드롭 다운에는 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용 바이올린
미래에 누군가가 이것을 유용하게 사용하기를 바랍니다.
Sijavmin-height 및 max-height도 제공하면 height:0에서 height:auto로 전환할 수 있습니다.
div.stretchy{ transition: 1s linear; } div.stretchy.hidden{ height: 0; } div.stretchy.visible{ height: auto; min-height:40px; max-height:400px; }
Stuart Badminton@jake의 답변을 확장하면 전환이 최대 높이 값까지 이동하여 매우 빠른 애니메이션을 생성합니다. 전환을 :hover 및 off 모두에 대해 설정하면 미친 속도를 조금 더 제어할 수 있습니다.
따라서 li:hover는 마우스가 상태에 들어간 다음 호버링되지 않은 속성의 전환이 마우스를 떠날 때입니다.
이것이 도움이 되기를 바랍니다.
예:
.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/
jamie플렉스박스 솔루션
장점:
단점:
- 요소는 고정 높이 플렉스 컨테이너에 넣어야 합니다.
작동 방식은 항상 플렉스 기반을 사용하는 것입니다. 콘텐츠가 있는 요소에는 auto를 사용하고 대신 flex-grow 및 flex-shrink를 전환합니다.
편집: Xbox One 인터페이스에서 영감을 받은 향상된 JS Fiddle.
* { 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 바이올린
Lee Comstock다음은 0을 포함한 모든 시작 높이에서 자동(전체 크기 및 유연성)으로 노드별로 하드 세트 코드 또는 초기화할 사용자 코드를 요구하지 않고 전환하는 방법입니다. https://github.com/csuwildcat /전환 자동 . 이것은 기본적으로 당신이 원하는 것에 대한 성배입니다. --> 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™
/ * 높이 코드: auto; 전환 * /
(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);
/ * 데모용 코드 * /
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);
csuwldcat정말 확실한 해결책을 찾은 것 같아요
좋아요! 나는 이 문제가 인터넷만큼 오래되었다는 것을 알고 있지만 나는 mutation-transition 이라는 플러그인으로 바뀐 해결책이 있다고 생각합니다. 내 솔루션은 DOM이 변경될 때마다 추적된 요소에 대해 style=""
최종 결과는 전환에 좋은 ole CSS를 사용할 수 있고 해킹 수정이나 특수 자바스크립트를 사용하지 않을 수 있다는 것입니다. data-mutant-attributes="X"
사용하여 해당 요소에서 추적하려는 항목을 설정하기만 하면 됩니다.
<div data-mutant-attributes="height"> This is an example with mutant-transition </div>
그거야! 이 솔루션은 MutationObserver 를 사용하여 DOM의 변경 사항을 추적합니다. 이 때문에 수동으로 애니메이션을 만들기 위해 아무것도 설정하거나 자바스크립트를 사용할 필요가 없습니다. 변경 사항은 자동으로 추적됩니다. 그러나 MutationObserver를 사용하기 때문에 IE11+에서만 전환됩니다.
바이올린!
JonTroncoso최대 높이에 애니메이션을 적용하는 Jake의 대답은 훌륭하지만 최대 높이를 크게 설정하여 발생하는 지연이 성가신 것을 발견했습니다.
축소 가능한 콘텐츠를 내부 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/
pbatey한 문장 솔루션: 패딩 전환 사용 . 아코디언과 같은 대부분의 경우에 충분하고 패딩 값이 크지 않은 경우가 많기 때문에 빠르기 때문에 더욱 좋습니다.
애니메이션 프로세스를 개선하려면 패딩 값을 높이면 됩니다.
.parent{ border-top: #999 1px solid;} h1{ margin: .5rem; font-size: 1.3rem} .children { height: 0; overflow: hidden; background-color: #dedede; transition: padding .2s ease-in-out, opacity .2s ease-in-out; padding: 0 .5rem; opacity: 0; } .children::before, .children::after{ content: "";display: block;} .children::before{ margin-top: -2rem;} .children::after{ margin-bottom: -2rem;} .parent:hover .children { height: auto; opacity: 1; padding: 2.5rem .5rem;/* 0.5 + abs(-2), make sure it's less than expected min-height */ }
<div class="parent"> <h1>Hover me</h1> <div class="children">Some content <br>Some content <br>Some content <br>Some content <br>Some content <br>Some content <br> </div> </div> <div class="parent"> <h1>Hover me(long content)</h1> <div class="children">Some content <br>Some content<br>Some content <br>Some content<br>Some content <br>Some content<br>Some content <br>Some content<br>Some content <br>Some content<br>Some content <br> </div> </div> <div class="parent"> <h1>Hover me(short content)</h1> <div class="children">Some content <br>Some content <br>Some content <br> </div> </div>
dallaslu이 스레드가 오래되고 있다는 것을 알고 있지만 특정 Google 검색에서 순위가 높기 때문에 업데이트할 가치가 있다고 생각합니다.
또한 요소의 자체 높이를 가져오거나 설정하기만 하면 됩니다.
var load_height = document.getElementById('target_box').clientHeight; document.getElementById('target_box').style.height = load_height + 'px';
인라인 스크립트 태그에서 target_box의 닫는 태그 바로 뒤에 이 자바스크립트를 덤프해야 합니다.
Charley나는 이것을 할 수 있었다. .child
및 .parent
div가 있습니다. absolute
위치로 부모의 너비/높이에 완벽하게 맞습니다. translate
속성에 애니메이션을 적용하여 Y
값을 100%
. 매우 부드러운 애니메이션, 여기의 다른 솔루션처럼 결함이나 단점이 없습니다.
이와 같은 것, 의사 코드
.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는 아래로 .child
Josh Ribakoff나는 최근에 ul
래핑이 아닌 li
max-height
를 전환했습니다.
추론 작은 대한 지연이다 max-heights
큰 비교 (모두의 경우) 훨씬 덜 눈에 띄는 max-heights
, 및 I 또한 내 설정할 수있는 max-height
받는 상대적인 값 font-size
의 li
어떤 임의보다는 ems
또는 rems
를 사용하여 엄청난 수.
내 글꼴 크기가 1rem
이면 max-height
를 3rem과 같이 3rem
(래핑된 텍스트를 수용하기 위해). 여기에서 예를 볼 수 있습니다.
http://codepen.io/mindfullsilence/pen/DtzjE
mindfullsilence일부 JavaScript로 답변을 게시하고 downvoted 그래서 짜증이 나서 다시 시도하고 CSS만으로 크랙했습니다!
이 솔루션은 몇 가지 '기술'을 사용합니다.
하지만 결과는 CSS만 사용하여 성능이 전환되고 전환을 원활하게 달성하기 위한 단일 전환 기능을 얻을 수 있다는 것입니다. 성배!
물론 단점도 있습니다! 콘텐츠가 잘리는 너비를 제어하는 방법을 알 수 없습니다( overflow:hidden
). padding-bottom 핵 때문에 너비와 높이는 밀접하게 관련되어 있습니다. 하지만 방법이 있을 수 있으므로 다시 돌아올 것입니다.
https://jsfiddle.net/EoghanM/n1rp3zb4/28/
body { padding: 1em; } .trigger { font-weight: bold; } /* .expander is there for float clearing purposes only */ .expander::after { content: ''; display: table; clear: both; } .outer { float: left; /* purpose: shrink to fit content */ border: 1px solid green; overflow: hidden; } .inner { transition: padding-bottom 0.3s ease-in-out; /* or whatever crazy transition function you can come up with! */ padding-bottom: 0%; /* percentage padding is defined in terms of width. The width at this level is equal to the height of the content */ height: 0; /* unfortunately, change of writing mode has other bad effects like orientation of cursor */ writing-mode: vertical-rl; cursor: default; /* don't want the vertical-text (sideways I-beam) */ transform: rotate(-90deg) translateX(-100%); /* undo writing mode */ transform-origin: 0 0; margin: 0; /* left/right margins here will add to height */ } .inner > div { white-space: nowrap; } .expander:hover .inner, /* to keep open when expanded */ .trigger:hover+.expander .inner { padding-bottom: 100%; }
<div class="trigger">HoverMe</div> <div class="expander"> <div class="outer"> <div class="inner"> <div>First Item</div> <div>Content</div> <div>Content</div> <div>Content</div> <div>Long Content can't be wider than outer height unfortunately</div> <div>Last Item</div> </div> </div> </div> <div> after content</div> </div>
EoghanM클립 경로를 사용하여 역방향(축소) 애니메이션을 만들어 이를 수행할 수 있습니다.
#child0 { display: none; } #parent0:hover #child0 { display: block; animation: height-animation; animation-duration: 200ms; animation-timing-function: linear; animation-fill-mode: backwards; animation-iteration-count: 1; animation-delay: 200ms; } @keyframes height-animation { 0% { clip-path: polygon(0% 0%, 100% 0.00%, 100% 0%, 0% 0%); } 100% { clip-path: polygon(0% 0%, 100% 0.00%, 100% 100%, 0% 100%); } }
<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>
Andrii Kovalenko다음은 방금 jQuery와 함께 사용한 솔루션입니다. 이것은 다음 HTML 구조에서 작동합니다.
<nav id="main-nav"> <ul> <li> <a class="main-link" href="yourlink.html">Link</a> <ul> <li><a href="yourlink.html">Sub Link</a></li> </ul> </li> </ul> </nav>
기능:
$('#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); });
css()
사용하여 높이를 설정 및 제거할 수 있습니다.
$('#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:
#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 }
HandiworkNYC.com질문이 JavaScript 없이 솔루션을 요구한다는 것을 이해합니다. 그러나 여기에 관심이 있는 사람들을 위해 약간의 JS를 사용하는 내 솔루션이 있습니다.
좋아, 기본적으로 높이가 변경되는 요소의 CSS는 height: 0;
그리고 높이가 열렸을 때 height: auto;
. 또한 transition: height .25s ease-out;
. 그러나 물론 문제는 높이로 또는 높이에서 전환되지 않는다는 것입니다 height: auto;
그래서 내가 한 일은 열거나 닫을 때 높이를 scrollHeight
속성으로 설정하는 것입니다. 이 새로운 인라인 스타일은 더 높은 특이성을 가지며 두 height: auto;
및 height: 0;
전환이 실행됩니다.
열 때 transitionend
height: auto;
로 설정하는 인라인 스타일을 제거합니다. 하위 메뉴 https://codepen.io/ninjabonsai/pen/GzYyVe가 있는 이 더 복잡한 예에서와 같이 필요한 경우 요소의 크기를 조정할 수 있습니다.
닫을 때 지연 없이 setTimeout을 사용하여 다음 이벤트 루프 주기 직후에 인라인 스타일을 제거합니다. 이것은 높이를 의미합니다 height: auto;
height 0;
다시 전환할 수 있도록 일시적으로 재정의됩니다.
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));
#menu > ul { height: 0; overflow: hidden; background-color: #999; transition: height .25s ease-out; } #menu > ul.open { height: auto; }
<div id="menu"> <a>hover me</a> <ul> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> </ul> </div>
shunryu111나는 모든 것을 자세히 읽지 않았지만 최근에이 문제가 있었고 다음과 같이했습니다.
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는 비 :hover에서 상속됩니다.
px에서 % 또는 auto로의 전환이 작동하지 않습니다. 동일한 측정 단위를 사용해야 합니다.
work.stella84출처 : http:www.stackoverflow.com/questions/3508605/how-can-i-transition-height-0-to-height-auto-using-css