높이 전환 방법 : 0; 높이까지 : 자동; CSS를 사용하십니까?
<ul>CSS 전환을 사용하여 아래 로 슬라이드 를 만들려고합니다 .
는에서 <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>
대신 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 / .
관련된 높이 중 하나가 인 경우 현재 높이에 애니메이션을 적용 할 수 없습니다 auto. 두 개의 명시적인 높이를 설정해야합니다.
내가 항상 사용한 해결책은 먼저 페이드 아웃 한 다음 font-size, padding및 margin값 을 줄이는 것이 었습니다 . 와이프와 똑같이 보이지는 않지만 정적 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>
나는 이것이이 질문에 대한 30 번째 답이라는 것을 알고 있지만, 그만한 가치가 있다고 생각합니다. 이것은 다음 속성을 가진 CSS 전용 솔루션입니다.
- 처음에는 지연이 없으며 전환이 일찍 중단되지 않습니다. 양방향 (확장 및 축소)에서 CSS에 전환 기간을 300ms로 지정하면 전환에 300ms가 걸립니다.
- 실제 높이 (와 달리
transform: scaleY(0))를 전환 하므로 접을 수있는 요소 뒤에 콘텐츠가 있으면 올바른 작업을 수행합니다. - (다른 솔루션 등)이 있지만 있는 매직 넘버 경우 (같은이 "당신의 상자 이제까지 될 것입니다보다 더 높은 길이를 선택")가 심각하지 않은 잘못 인 것을 전제가 종료됩니다. 전환은이 경우에 놀라운 보이지 않을 수 있지만, 이전과 전환 후,이 문제가되지 않습니다 : 확장 된 (에서
height: auto당신이 선택하는 경우) 상태, 전체 내용이 항상 (달리 예를 올바른 높이가max-height밝혀 그 수 너무 낮은). 접힌 상태에서 높이는 0입니다.
데모
다음은 모두 동일한 CSS를 사용하는 세 개의 축소 가능한 요소, 높이가 다른 데모입니다. "스 니펫 실행"을 클릭 한 후 "전체 페이지"를 클릭 할 수 있습니다. JavaScript는 collapsedCSS 클래스 만 토글하며 측정과 관련이 없습니다. (확인란 또는을 사용하여 JavaScript없이이 정확한 데모를 수행 할 수 :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>
어떻게 작동합니까?
실제로 이를 실현하는 데는 두 가지 전환이 있습니다. 그들 중 하나는 margin-bottom0px (확장 상태) -2000px에서 접힌 상태 ( 이 답변 과 유사 )로 전환합니다. 여기서 2000은 첫 번째 매직 넘버입니다. 이는 상자가 이보다 높지 않을 것이라는 가정에 기반한 것입니다 (2000 픽셀은 합리적인 선택 인 것 같습니다).
margin-bottom전환 자체 만 사용하면 두 가지 문제가 있습니다.
- 실제로 2000 픽셀보다 큰 상자가있는 경우 a
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최소 높이 전환 을 위해 실제로 사용하지 않는 이유 입니다. 대신 ::after컨테이너에 height50px에서 0으로 전환 되는 의사 요소가 있습니다. 이것은 a와 동일한 효과를 min-height갖습니다. 현재 의사 요소가 가지고있는 높이 아래로 컨테이너가 줄어들지 않게합니다. 그러나 height, not을 사용 하고 있기 때문에 min-height이제 max-height전환이 끝나면 가상 요소의 실제 높이를 0으로 설정하는 데 사용할 수 있습니다 (지연을 다시 한 번 적용). 최소한 전환 외부에있는 작은 요소도 정확한 높이. 때문에 min-height이다 강한 것보다 max-height우리가 사용 된 경우,이 컨테이너의 작동하지 않을 min-height대신 의사 요소의의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 전환이 없어서 무의미한 연습이된다는 사실을 제외하면 말입니다.
당신은 약간의 비의 미적 지그 리포 크리로 할 수 있습니다. 내 일반적인 접근 방식은 콘텐츠 높이 측정에만 사용되는 스타일이없는 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.
CSS3 전환을 사용하여 높이를 애니메이션하는 시각적 해결 방법은 대신 패딩을 애니메이션하는 것입니다.
완전한 와이프 효과를 얻지는 못하지만 전환 기간과 패딩 값을 가지고 놀면 충분히 가까이 다가 갈 수 있습니다. 높이 / 최대 높이를 명시 적으로 설정하지 않으려면 원하는 항목이어야합니다.
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에서 추출 됨)
내 해결 방법은 멋진 부드러운 애니메이션을 위해 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>
허용되는 답변은 대부분의 경우에 작동하지만 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>
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/
하드 코딩 된 값이 없습니다.
자바 스크립트가 없습니다.
근사치가 없습니다.
트릭은 숨김 및 복제를 사용 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>
Element.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사용 된 높이가 훨씬 빨리이 걸릴 것보다 최대 값에 도달 할 수 있기 때문에, 기반 솔루션을 max-height손에 9999px. 그리고 화면 해상도가 커짐에 따라 픽셀 길이는 9999px입안에 나쁜 맛을 남깁니다. 이 특정 솔루션은 제 생각에 우아한 방식으로 문제를 해결합니다.
마지막으로, CSS의 향후 개정판에서는 작성자가 이러한 종류의 작업을 훨씬 더 우아하게 수행 할 필요가 있기를 희망합니다. "계산 된"값과 "사용 된"및 "해결 된"값의 개념을 다시 검토하고 전환이 계산 된 값에 적용되어야하는지 고려하십시오. width및 height(현재는 약간의 특별한 대우를받는) 전환을 포함한 값 .
이 글을 올릴 때 이미 30 개가 넘는 답변이 있지만 jake 가 이미 받아 들인 답변보다 내 답변이 향상되는 것 같습니다 .
max-height많은 댓글 작성자가 언급했듯이 max-height값을 실제 높이에 매우 가깝게 설정해야하므로 단순히 CSS3 전환을 사용하여 발생하는 문제에 만족하지 않았습니다. 그렇지 않으면 지연이 발생합니다. 해당 문제의 예는 이 JSFiddle 을 참조하십시오 .
이 문제를 해결하기 위해 (JavaScript를 사용하지 않는 동안) transform: translateYCSS 값 을 전환하는 다른 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>
좋아, 그래서 나는 매우 간단한 대답을 생각해 냈다고 생각한다 ... 아니요 max-height, relative위치 지정을 사용 하고 li요소에서 작동하며 순수한 CSS입니다. Firefox 이외의 다른 곳에서는 테스트하지 않았지만 CSS로 판단하면 모든 브라우저에서 작동합니다.
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>
편집 : 업데이트 된 답변을 보려면 아래로 스크롤
하여 드롭 다운 목록을 만들고이 게시물을 보았습니다 ... 많은 다른 답변을했지만 드롭 다운 목록도 공유하기로 결정했습니다 ... 완벽하지는 않지만 적어도 CSS 만 사용합니다. 쓰러지 다! 나는 transform : translateY (y)를 사용하여 목록을보기로 변환했습니다 ... http://jsfiddle.net/BVEpc/4/
테스트에서 더 많은 것을 볼 수 있습니다.
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을위한
Fiddle RTL을 위한 Fiddle
바라건대 누군가가 이것을 미래에 유용하게 사용하기를 바랍니다.
min-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;
}
Flexbox 솔루션
장점 :
- 단순한
- JS 없음
- 부드러운 전환
단점 :
- 요소는 고정 높이 플렉스 컨테이너에 넣어야합니다.
작동 방식은 항상 flex-basis : 콘텐츠가있는 요소에 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>
정말 견고한 솔루션을 생각 해낸 것 같아요
확인! 이 문제가 인터넷만큼 오래되었다는 것을 알고 있지만 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의 변경 사항을 따릅니다. 이로 인해 수동으로 애니메이션을 적용하기 위해 아무것도 설정하거나 자바 스크립트를 사용할 필요가 없습니다. 변경 사항은 자동으로 추적됩니다. 그러나 MutationObserver를 사용하기 때문에 IE11 +에서만 전환됩니다.
바이올린!
@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/
다음은 노드 별 하드 세트 코드 또는 초기화 할 사용자 코드없이 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);
/ * 데모 코드 * /
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);
최대 높이 애니메이션에 대한 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/
이 스레드가 늙어 가고 있다는 것을 알고 있지만 특정 Google 검색에서 높은 순위를 차지하므로 업데이트 할 가치가 있다고 생각합니다.
또한 요소의 자체 높이를 가져 오거나 설정합니다.
var load_height = document.getElementById('target_box').clientHeight;
document.getElementById('target_box').style.height = load_height + 'px';
인라인 스크립트 태그에서 target_box의 닫는 태그 바로 뒤에이 자바 스크립트를 덤프해야합니다.
나는 이것을 할 수 있었다. 나는 .child& .parentdiv가 있습니다. 자식 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 */
}
당신은을 지정합니다 height에 .parent에 px, %같은, 또는 휴가 auto. 이 div는 .child아래로 미끄러질 때 div를 마스킹 합니다.
다음은 방금 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 }
나는 최근에를 전환했습니다 max-height온 li요소가 아닌 포장 ul.
추론은 소규모의 지연이 있다는 것입니다 max-heights대형에 비해 (전혀 경우) 훨씬 눈에 잘 띄지 않는 max-heights, 나는 또한 나의 설정할 수 있습니다 max-height받는 상대적인 값 font-size의 li사용에 의해 오히려 어떤 임의의 큰 수보다를 ems하거나 rems.
내 글꼴 크기가 1rem이면 max-height다음과 같이 설정합니다 3rem(줄 바꿈 된 텍스트를 수용하기 위해). 여기에서 예를 볼 수 있습니다.
http://codepen.io/mindfullsilence/pen/DtzjE
나는 모든 것을 자세히 읽지 않았지만 최근 에이 문제가 발생하여 다음을 수행했습니다.
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에서 % 또는 자동으로의 전환이 작동하지 않습니다. 동일한 측정 단위를 사용해야합니다. 이것은 나를 위해 잘 작동합니다. HTML5를 사용하면 완벽합니다 ....
항상 해결 방법이 있다는 것을 기억하십시오 ...; )
누군가가 유용하다고 생각하기를 바랍니다.
이것은 문제에 대한 "솔루션"이 아니라 더 많은 해결 방법입니다. 텍스트로 작성된 대로만 작동하지만 필요에 따라 다른 요소와 함께 작동하도록 변경할 수 있습니다.
.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를 사용하여 실제 높이를 자동으로 변환하는 것은 현재 가능하지 않지만 콘텐츠를 변환하는 것은 가능하므로 글꼴 크기 전환이 필요합니다.
- 참고-코드 펜에는 자바 스크립트가 있지만 아코디언을 클릭 할 때 CSS 클래스를 추가 / 제거하는 것이 유일한 목적입니다. 이 작업은 숨겨진 라디오 버튼으로 수행 할 수 있지만 저는 그것에 초점을 맞추지 않고 높이 변환에만 집중했습니다.
나는 질문이 JavaScript없이 해결책을 요구한다는 것을 이해합니다. 그러나 관심있는 사람들을 위해 약간의 JS를 사용하는 내 솔루션이 있습니다.
좋아, 기본적으로 높이가 변경되는 요소의 CSS는 height: 0;and when open으로 설정됩니다 height: auto;. 또한 transition: height .25s ease-out;. 하지만 물론 문제는height: auto;
그래서 내가 한 것은 열거 나 닫을 때 높이를 scrollHeight요소 의 속성으로 설정하는 것 입니다. 이 새로운 인라인 스타일은 더 높은 특이성을 가지며 height: auto;및 height: 0;및 전환 실행을 재정의합니다 .
열 때 transitionend한 번만 실행되는 이벤트 리스너를 추가 한 다음 height: auto;필요한 경우 요소의 크기를 조정할 수있는 인라인 스타일 설정을 제거합니다. 하위 메뉴 https://codepen.io/ninjabonsai/가있는 더 복잡한 예제에서 펜 / 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>
제공되는 하드 코딩 된 최대 높이 값이 실제 높이보다 훨씬 크지 않은 경우 Jake의 최대 높이 솔루션이 잘 작동합니다 (그렇지 않으면 바람직하지 않은 지연 및 타이밍 문제가 있기 때문입니다). 반면에 하드 코딩 된 값이 실수로 실제 높이보다 크지 않으면 요소가 완전히 열리지 않습니다.
다음 CSS 전용 솔루션에는 발생하는 대부분의 실제 크기보다 커야하는 하드 코딩 된 크기도 필요합니다. 그러나이 솔루션은 실제 크기가 하드 코딩 된 크기보다 큰 경우에도 작동합니다. 이 경우 전환이 약간 점프 할 수 있지만 부분적으로 보이는 요소를 남기지 않습니다. 따라서이 솔루션은 예를 들어 데이터베이스에서 알 수없는 콘텐츠에도 사용할 수 있습니다. 여기서 콘텐츠가 일반적으로 x 픽셀보다 크지 않지만 예외가 있다는 것을 알고 있습니다.
아이디어는 margin-bottom (또는 약간 다른 애니메이션의 경우 margin-top)에 음수 값을 사용하고 overflow : hidden을 사용하여 콘텐츠 요소를 중간 요소에 배치하는 것입니다. 콘텐츠 요소의 음수 여백은 중간 요소의 높이를 줄입니다.
다음 코드는 margin-bottom에서 -150px에서 0px 로의 전환을 사용합니다. 콘텐츠 요소가 150px 이하인 한 이것만으로도 잘 작동합니다. 또한 중간 요소에 대해 0px에서 100 % 로의 최대 높이 전환을 사용합니다. 마지막으로 콘텐츠 요소가 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>
여백 하단의 값은 음수 여야하며 콘텐츠 요소의 실제 높이에 최대한 가까워 야합니다. (절대 값)이 더 크면 최대 높이 솔루션과 유사한 지연 및 타이밍 문제가 있지만 하드 코딩 된 크기가 실제 크기보다 크지 않은 한 제한 될 수 있습니다. margin-bottom의 절대 값이 실제 높이보다 작 으면 tansition이 약간 점프합니다. 어떤 경우에도 전환 후 콘텐츠 요소는 완전히 표시되거나 완전히 제거됩니다.
자세한 내용은 내 블로그 게시물 http://www.taccgl.org/blog/css_transition_display.html#combined_height를 참조하십시오.
적절한 해결책이없는 것 같습니다. max-height접근 방식은 꽤 좋지만 숨기기 단계에서는 잘 작동하지 않습니다. 콘텐츠의 높이를 알지 못하면 눈에 띄는 지연이 발생합니다.
나는 가장 좋은 방법은 사용하는 것입니다 생각 max-height하지만, 단지 쇼 단계에 . 그리고 숨길 때 애니메이션을 사용하지 마십시오. 대부분의 경우 중요하지 않습니다.
max-height콘텐츠에 맞는지 확인하려면 상당히 큰 값으로 설정해야합니다. transition기간 ( speed = max-height / duration)을 사용하여 애니메이션 속도를 제어 할 수 있습니다 . 속도는 콘텐츠의 크기에 의존하지 않습니다. 전체 콘텐츠를 표시하는 데 걸리는 시간은 크기에 따라 다릅니다.
document.querySelector("button").addEventListener(
"click",
function(){
document.querySelector("div").classList.toggle("hide");
}
)
div {
max-height: 20000px;
transition: max-height 3000ms;
overflow-y: hidden;
}
.hide {
max-height: 0;
transition: none;
}
<button>Toggle</button>
<div class="hide">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.
</div>
'Program Club' 카테고리의 다른 글
| Objective-C 빌드의 중복 기호 오류? (0) | 2020.12.13 |
|---|---|
| LINQ는 느리기 때문에 피해야합니까? (0) | 2020.12.13 |
| Google Keep API가 있습니까? (0) | 2020.12.13 |
| DICTATION_MODE에서 android.speech.SpeechRecognizer 사용시 지연 (0) | 2020.12.13 |
| "꿈을 제어"하기 위해 수업을 사용하는 방법? (0) | 2020.12.13 |
