Hai*_*ood 1985 css css-transitions
我正在尝试<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;
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
小智 2594
用于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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
dot*_*ter 287
您应该使用scaleY.
HTML:
<p>Here (scaleY(1))</p>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
CSS:
ul {
background-color: #eee;
transform: scaleY(0);
transform-origin: top;
transition: transform 0.26s ease;
}
p:hover ~ ul {
transform: scaleY(1);
}
Run Code Online (Sandbox Code Playgroud)
我在jsfiddle上创建了上面代码的供应商前缀版本,http://jsfiddle.net/dotnetCarpenter/PhyQc/9/并将你的jsfiddle改为使用scaleY而不是height,http://jsfiddle.net/dotnetCarpenter/ 7cnfc/206 /.
rob*_*rtc 190
当涉及其中一个高度时auto
,您当前无法设置高度动画,您必须设置两个明确的高度.
Ste*_*hon 117
我一直使用的解决方案是第一个淡出,然后收缩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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
bal*_*pha 81
我知道这是这个问题的三十分之一的答案,但我认为这是值得的,所以这里有.这是一个仅支持CSS的解决方案,具有以下属性:
transform: scaleY(0)
),所以如果在可折叠元素之后有内容,它会做正确的事情.height: auto
)状态下,整个内容始终具有正确的高度(不像例如,如果你选择了一个max-height
原来是太低).在崩溃的状态下,高度应该是零.这是一个包含三个可折叠元素的演示,所有元素都具有不同的高度,所有元素都使用相同的CSS.单击"运行代码段"后,您可能需要单击"完整页面".请注意,JavaScript只切换collapsed
CSS类,不涉及测量.(你可以使用复选框完成没有任何JavaScript的精确演示:target
).另请注意,负责转换的CSS部分非常短,而HTML只需要一个额外的包装元素.
$(function () {
$(".toggler").click(function () {
$(this).next().toggleClass("collapsed");
$(this).toggleClass("toggled"); // this just rotates the expander arrow
});
});
Run Code Online (Sandbox Code Playgroud)
.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
实际上有两个转变涉及实现这一点.其中一个margin-bottom
从0px(处于展开状态)转换-2000px
为折叠状态(类似于此答案).这里的2000是第一个神奇的数字,它基于你的盒子不会高于此的假设(2000像素似乎是一个合理的选择).
margin-bottom
单独使用转换本身有两个问题:
margin-bottom: -2000px
将不会隐藏所有内容 - 即使在折叠的情况下也会有可见的东西.这是一个小修复,我们稍后会做.修复第二个问题是第二个转换的位置,这个转换在概念上针对包装器的最小高度("概念上",因为我们实际上并没有使用该min-height
属性;稍后将详细介绍).
这是一个动画,显示了如何将底部边缘过渡与最小高度过渡相结合,两者具有相同的持续时间,为我们提供了从全高度到零高度的组合过渡,具有相同的持续时间.
左侧栏显示负底部边缘如何向下推动底部,降低可见高度.中间栏显示最小高度如何确保在折叠情况下,过渡不会提前结束,并且在扩展的情况下,过渡不会延迟.右侧栏显示两者的组合如何使盒子在正确的时间内从全高度过渡到零高度.
对于我的演示,我已经确定50px作为最小高度值的上限.这是第二个神奇的数字,它应该低于盒子的高度.50px似乎也是合理的; 你似乎不太可能经常想要制作一个折叠的元素,它首先不是50像素高.
正如您在动画中看到的那样,所产生的过渡是连续的,但它是不可微分的 - 当最小高度等于由下边距调整的全高时,速度会突然改变.这在动画中非常明显,因为它对两个过渡使用线性定时功能,并且因为整个过渡非常慢.在实际情况下(我的演示在顶部),转换只需要300毫秒,底部边距转换不是线性的.我已经为这两种转换玩了很多不同的计时功能,而我最终感觉它们最适合各种各样的情况.
还有两个问题需要解决:
我们通过max-height: 0
在折叠的情况下给出容器元素a 来解决第一个问题,并进行0s 0.3s
转换.这意味着它不是真正的过渡,而是max-height
延迟应用; 它只适用于转换结束后.为了使其正常工作,我们还需要max-height
为相反的非折叠状态选择一个数字.但与2000px的情况不同,选择太大的数字会影响转换的质量,在这种情况下,它确实无关紧要.所以我们可以选择一个如此之高的数字,以便我们知道没有任何高度可以接近这一点.我选了一百万像素.如果您觉得可能需要支持高度超过一百万像素的内容,那么1)我很抱歉,2)只需添加几个零.
第二个问题是我们实际上没有min-height
用于最小高度转换的原因.相反,::after
容器中有一个伪元素,其height
从50px转换为零.这与a具有相同的效果min-height
:它不会让容器收缩到伪元素当前所具有的任何高度以下.但是因为我们正在使用height
,而不是min-height
,我们现在可以使用max-height
(再次应用延迟)在转换结束后将伪元素的实际高度设置为零,确保至少在转换之外,即使是小元素也具有正确的高度.因为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过渡这一事实,这使得它成为一个毫无意义的练习.
jhu*_*man 77
你可以用一点点非语义的jiggery-pokery.我通常的方法是为外部DIV的高度设置动画,该外部DIV具有单个子项,这是一种仅用于测量内容高度的无样式DIV.
function growDiv() {
var growDiv = document.getElementById('grow');
if (growDiv.clientHeight) {
growDiv.style.height = 0;
} else {
var wrapper = document.querySelector('.measuringWrapper');
growDiv.style.height = wrapper.clientHeight + "px";
}
}
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
人们希望能够省去.measuringWrapper
并且只是将DIV的高度设置为自动并具有该动画,但这似乎不起作用(高度设置,但没有动画发生).
function growDiv() {
var growDiv = document.getElementById('grow');
if (growDiv.clientHeight) {
growDiv.style.height = 0;
} else {
growDiv.style.height = 'auto';
}
}
Run Code Online (Sandbox Code Playgroud)
#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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
我的解释是动画运行需要一个显式高度.当高度(开始或结束高度)是高度时,您无法获得高度动画auto
.
小智 49
使用CSS3过渡动画高度的可视化解决方法是为填充设置动画.
你没有完全获得完全擦除效果,但是使用transition-duration和padding值可以让你足够接近.如果您不想明确设置height/max-height,那么这应该是您正在寻找的.
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;
}
Run Code Online (Sandbox Code Playgroud)
http://jsfiddle.net/catharsis/n5XfG/17/(在jsFiddle之上翻过stephband)
Ada*_*dam 45
我的解决方法是将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
});
}
});
Run Code Online (Sandbox Code Playgroud)
.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
Mor*_*ori 41
根据MDN Web Docs,auto
值已被有意排除在 CSS 过渡规范之外,因此请height: auto
使用height: 100%
、top
、 或flex
网格和 Flex 布局中的属性来代替 。
.grid-container {
display: grid;
position: absolute;
}
.content {
background: aqua;
height: 0;
overflow: hidden;
transition: 1s;
}
span:hover + .grid-container .content {
height: 100%;
}
Run Code Online (Sandbox Code Playgroud)
<span>Hover over me!</span>
<div class="grid-container">
<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
<p>Rest of the page content...</p>
Run Code Online (Sandbox Code Playgroud)
.grid-container {
display: grid;
position: absolute;
overflow: hidden;
pointer-events: none; /* to enable interaction with elements below the container */
}
.content {
background: aqua;
pointer-events: auto;
position: relative;
top: -100%;
transition: 1s;
}
span:hover + .grid-container .content {
top: 0;
}
Run Code Online (Sandbox Code Playgroud)
<span>Hover over me!</span>
<div class="grid-container">
<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
<p>Rest of the page content...</p>
Run Code Online (Sandbox Code Playgroud)
Ole*_*ich 36
接受的答案适用于大多数情况,但是当你的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';
}
}
Run Code Online (Sandbox Code Playgroud)
#menu #list {
height: 0px;
transition: height 0.3s ease;
background: #d5d5d5;
overflow: hidden;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
mal*_*ihu 28
max-height
对每个州使用不同的转换缓和和延迟.
HTML:
<a href="#" id="trigger">Hover</a>
<ul id="toggled">
<li>One</li>
<li>Two</li>
<li>Three</li>
<ul>
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
参见示例:http://jsfiddle.net/0hnjehjc/1/
Viv*_*ajh 27
没有硬编码值.
没有JavaScript.
没有近似值.
诀窍是使用隐藏和重复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%;
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
amn*_*amn 27
几乎没有提到在Element.scrollHeight
这里有用的属性,仍然可以用于纯CSS过渡.该属性始终包含元素的"完整"高度,无论其内容是否以及如何因折叠高度而溢出(例如height: 0
).
因此,对于height: 0
(有效完全折叠的)元素,其"正常"或"完整"高度仍然可通过其scrollHeight
值(总是像素长度)容易地获得.
对于这样的元素,假设它已经具有类似的转换设置(使用ul
原始问题):
ul {
height: 0;
transition: height 1s; /* An example transition. */
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用CSS来触发所需的动画"高度扩展",使用类似下面的内容(这里假设ul
变量引用列表):
ul.style.height = ul.scrollHeight + "px";
Run Code Online (Sandbox Code Playgroud)
而已.如果您需要折叠列表,则以下两个语句中的任何一个都会执行以下操作:
ul.style.height = "0";
ul.style.removeProperty("height");
Run Code Online (Sandbox Code Playgroud)
我的特定用例围绕着未知且通常相当长的动画列表,因此我不习惯定制任意"足够大" height
或max-height
规范,并冒着截断内容或内容突然需要滚动的内容(overflow: auto
例如,如果) .此外,宽松和时间与破max-height
基于解决方案,因为所使用的高度可达到最大值很多早于它会采取max-height
到达9999px
.随着屏幕分辨率的增长,像素长度就像9999px
在我嘴里留下了不好的味道.在我看来,这个特殊的解决方案以优雅的方式解决了这个问题.
最后,这里希望CSS的未来版本能够更好地解决作者需要更好地完成这些事情 - 重新审视"计算"与"已使用"和"已解决"值的概念,并考虑转换是否应适用于计算值,包括与width
和的转换height
(目前得到一些特殊处理).
Moo*_*oob 23
自从这个问题首次提出以来,浏览器已经发生了很大的变化。您现在可以转换网格轨道大小,并且得到了很好的支持,这意味着可以使用CSS 网格布局来解决此问题
在这里,我将第二个网格项从0fr
(0 小数单位) 转换为1fr
(1 小数单位)。
#parent0 {
display: grid;
grid-template-rows: min-content 0fr;
transition: grid-template-rows 500ms;
}
#child0 {
background-color: #dedede;
overflow: hidden;
}
#parent0:hover{
grid-template-rows: min-content 1fr;
}
Run Code Online (Sandbox Code Playgroud)
<div id="parent0">
<h1>Hover me</h1>
<div id="child0">Some content
<br>Some content
<br>Some content
<br>Some content
<br>Some content
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
And*_*ier 21
正如我发布的那样,已有超过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);
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
Nel*_*zes 19
很多答案,有些比其他更好,大多数使用 JS。我相信我通过两个易于理解的用例解决了这个问题。
\n.demo01 {\n overflow: hidden;\n position: absolute;\n pointer-events: none;\n}\n.demo01__content {\n background: lightgray;\n padding: 1rem;\n pointer-events: all;\n transform: translateY(-100%);\n transition: transform 1s, visibility 1s;\n visibility: hidden;\n}\n:checked ~ .demo01 .demo01__content {\n transform: translateY(0);\n visibility: visible;\n}
Run Code Online (Sandbox Code Playgroud)\r\n<input type="checkbox" /> \xe2\xac\x85\xef\xb8\x8e Toggle\n<div>Something before </div>\n<div class="demo01">\n <div class="demo01__content">\n This content should\xe2\x80\xa6<br />\n toggle! \n </div>\n</div>\n<div>Something after </div>
Run Code Online (Sandbox Code Playgroud)\r\n.demo02 {\n display: grid;\n grid-template-rows: 0fr;\n overflow: hidden;\n transition: grid-template-rows 1s;\n}\n.demo02__content {\n align-self: end;\n min-height: 0;\n background: lightgray;\n transition: visibility 1s;\n visibility: hidden;\n}\n.demo02__padding {\n padding: 1rem;\n}\n:checked ~ .demo02 {\n grid-template-rows: 1fr;\n}\n:checked ~ .demo02 .demo02__content {\n visibility: visible;\n}
Run Code Online (Sandbox Code Playgroud)\r\n<input type="checkbox" /> \xe2\xac\x85\xef\xb8\x8e Toggle\n<div>Something before </div>\n<div class="demo02">\n <div class="demo02__content">\n <div class="demo02__padding">\n This content should\xe2\x80\xa6<br />\n toggle! \n </div>\n </div>\n</div>\n<div>Something after </div>
Run Code Online (Sandbox Code Playgroud)\r\n我写了一篇关于这些技术的博客文章。
\nVID*_*gnz 17
好的,所以我想我想出了一个超级简单的答案......不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; }
Run Code Online (Sandbox Code Playgroud)
HTML
<div class="wrap">
<div class="inner">Some Cool Content</div>
</div>
Run Code Online (Sandbox Code Playgroud)
Sij*_*jav 15
编辑:向下滚动以获取更新的答案
我正在制作一个下拉列表并看到这个帖子...许多不同的答案但我决定分享我的下拉列表,...它不完美但至少它只会使用css落下!我一直在使用transform:translateY(y)将列表转换为视图...
你可以在测试中看到更多
http://jsfiddle.net/BVEpc/4/
我已将div放在每个li后面,因为我的下拉列表来自向上并正确显示它们是必需的,我的div代码是:
#menu div {
transition: 0.5s 1s;
z-index:-1;
-webkit-transform:translateY(-100%);
-webkit-transform-origin: top;
}
Run Code Online (Sandbox Code Playgroud)
并悬停是:
#menu > li:hover div {
transition: 0.5s;
-webkit-transform:translateY(0);
}
Run Code Online (Sandbox Code Playgroud)
并且因为ul高度被设置为它可以覆盖你的身体内容的内容,这就是为什么我这样做为ul:
#menu ul {
transition: 0s 1.5s;
visibility:hidden;
overflow:hidden;
}
Run Code Online (Sandbox Code Playgroud)
并悬停:
#menu > li:hover ul {
transition:none;
visibility:visible;
}
Run Code Online (Sandbox Code Playgroud)
转换后的第二次是延迟,并且在我的下拉列表被关闭后它将被隐藏...
希望以后有人从这个获益.
编辑:我真的不相信人们实际使用这个原型!这个下拉菜单只适用于一个子菜单,这就是全部!! 我已经更新了一个更好的,可以在IE 8支持的情况下为ltr和rtl方向提供两个子菜单.
LTR
Fiddle for RTL的小提琴
希望有人在将来发现它有用.
Stu*_*ton 11
您可以从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;
}
Run Code Online (Sandbox Code Playgroud)
Flexbox解决方案
优点:
缺点:
它的工作方式是始终使用flex-basis:对包含内容的元素执行auto,然后转换flex-grow和flex-shrink.
编辑:改进的JS小提琴灵感来自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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
我想我想出了一个非常可靠的解决方案
好!我知道这个问题与互联网一样古老,但我认为我有一个解决方案,我变成了一个名为突变转换的插件.style=""
每当DOM发生变化时,我的解决方案都会为跟踪元素设置属性.最终结果是你可以使用好的ole CSS进行转换,而不是使用hacky修复程序或特殊的javascript.您唯一需要做的就是使用相关元素设置要跟踪的内容data-mutant-attributes="X"
.
<div data-mutant-attributes="height">
This is an example with mutant-transition
</div>
Run Code Online (Sandbox Code Playgroud)
而已!此解决方案使用MutationObserver来跟踪DOM中的更改.因此,您不需要设置任何内容或使用javascript手动设置动画.自动跟踪更改.但是,因为它使用MutationObserver,所以这只会在IE11 +中进行转换.
小提琴!
我理解这个问题需要一个没有 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));
Run Code Online (Sandbox Code Playgroud)
#menu > ul {
height: 0;
overflow: hidden;
background-color: #999;
transition: height .25s ease-out;
}
#menu > ul.open {
height: auto;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
仅灵活高度 CSS 解决方案
我偶然发现了一个使用弹性行为的奇怪解决方案。它至少可以在 Chrome 和 Firefox 中运行。
首先,高度过渡仅在0到100%(两个数值)之间起作用。由于“auto”不是数值,因此 0 和“auto”之间不存在小数增量。100% 是一个灵活的值,因此不需要特定的高度。
其次,隐藏内容的外容器和内容器都必须设置为display: flex和flex-direction: column。
第三,外容器必须具有高度属性。仅当所有内容都包含在外部容器中时,将其设置为0才能保持平滑过渡,因为伸缩行为优先于高度。编辑:Json建议使用height: fit-content,以便容器下方的任何内容也被下推。
.outer-container { height: 0; display: flex; flex-direction: column; }
.inner-container { display: flex; flex-direction: column; }
.hidden-content {
height: 0;
opacity: 0;
transition: height 1s 0.5s ease-in-out, opacity 0.5s ease-in-out;
/* transition out: first fade out opacity, then shrink height after a delay equal to the opacity duration */
}
.trigger:hover + .inner-container > .hidden-content {
height: 100%;
opacity: 1;
transition: height 1s ease-in-out, opacity 0.5s 1s ease-in-out;
/* transition in: first expand height, then fade in opacity after a delay equal to the height duration */
}
Run Code Online (Sandbox Code Playgroud)
<div class="outer-container">
<a href="#" class="trigger">Hover to Reveal Inner Container's Hidden Content</a>
<div class="inner-container">
<div class="hidden-content">This is hidden content. When triggered by hover, its height transitions from 0 to 100%, which pushes other content in the same container down gradually.</div>
<div>Within the same container, this other content is pushed down gradually as the hidden content's height transitions from 0 to 100%.</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
按“运行代码片段”按钮以查看实际的转换。它只是 CSS,没有具体的高度。
扩展@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 */
Run Code Online (Sandbox Code Playgroud)
这是一个小提琴:http : //jsfiddle.net/BukwJ/
杰克对最大高度动画的答案很棒,但我发现设置一个大的最大高度令人烦恼的延迟.
可以将可折叠内容移动到内部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');
});
Run Code Online (Sandbox Code Playgroud)
这是一个jsfiddle链接:http://jsfiddle.net/pbatey/duZpT
这是一个jsfiddle,需要绝对最少的代码:http://jsfiddle.net/8ncjjxh8/
这是一种从任何起始高度(包括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>
Run Code Online (Sandbox Code Playgroud)
这是包含在您页面中的代码块,之后,它都是肉汁:
将这个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);
Run Code Online (Sandbox Code Playgroud)
/ *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);
Run Code Online (Sandbox Code Playgroud)
一句话解决:使用padding transition。对于大多数情况(例如手风琴)来说已经足够了,甚至更好,因为它很快,因为填充值通常不大。
如果你想让动画过程更好,只需提高 padding 值。
.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 */
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
小智 5
我意识到这个帖子已经老了,但它在某些谷歌搜索中排名很高,所以我认为它值得更新.
您还可以获取/设置元素自己的高度:
var load_height = document.getElementById('target_box').clientHeight;
document.getElementById('target_box').style.height = load_height + 'px';
Run Code Online (Sandbox Code Playgroud)
您应该在内联脚本标记中的target_box的结束标记之后立即转储此Javascript.
我能够做到这一点。我有一个.child
&.parent
div。子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 */
}
Run Code Online (Sandbox Code Playgroud)
您将指定一个height
上.parent
,中px
,%
或休假的auto
。然后,该.child
div向下滑动时会将该div掩盖。
我最近一直在转变max-height
的li
元素,而不是包装ul
。
原因是max-heights
与 large 相比, small 的延迟远不那么明显(如果有的话)max-heights
,我还可以通过使用ormax-height
来设置相对于 thefont-size
的值li
而不是某个任意的大数字。ems
rems
如果我的字体大小是1rem
,我会将我的设置max-height
为类似3rem
(以容纳换行文本)。你可以在这里看到一个例子:
http://codepen.io/mindfullsilence/pen/DtzjE
我用一些 JavaScript 发布了一个答案并被否决了,所以很生气并再次尝试,并且只用 CSS 破解了它!
该解决方案使用了一些“技术”:
padding-bottom:100%
'hack' 其中百分比是根据元素的当前宽度定义的。有关此技术的更多信息。不过,结果是我们只使用 CSS 就可以实现高性能的过渡,并使用单个过渡函数来平滑地实现过渡;圣杯!
当然,也有缺点!我不知道如何控制内容被截断的宽度 ( overflow:hidden
);由于 padding-bottom hack,宽度和高度密切相关。不过可能有办法,所以会回来的。
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%;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
您可以通过使用剪辑路径创建反向(折叠)动画来做到这一点。
#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%);
}
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
line-height
使用、padding
和opacity
的替代纯 CSS 解决方案margin
:
body {
background-color: linen;
}
main {
background-color: white;
}
[id^="toggle_"] ~ .content {
line-height: 0;
opacity: 0;
padding: 0 .5rem;
transition: .2s ease-out;
}
[id^="toggle_"] ~ .content > p {
margin: 0;
transition: .2s ease-out;
}
[id^="toggle_"]:checked ~ .content {
opacity: 1;
padding: .5rem;
line-height: 1.5;
}
[id^="toggle_"]:checked ~ .content p {
margin-bottom: .75rem;
}
[id^="toggle_"] + label {
display: flex;
justify-content: space-between;
padding: 0.5em 1em;
background: lightsteelblue;
border-bottom: 1px solid gray;
cursor: pointer;
}
[id^="toggle_"] + label:before {
content: "Show";
}
[id^="toggle_"]:checked + label:before {
content: "Hide";
}
[id^="toggle_"] + label:after {
content: "\25BC";
}
[id^="toggle_"]:checked + label:after {
content: "\25B2";
}
Run Code Online (Sandbox Code Playgroud)
<main>
<div>
<input type="checkbox" id="toggle_1" hidden>
<label for="toggle_1" hidden></label>
<div class="content">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dolor neque, commodo quis leo ut, auctor tincidunt mauris. Nunc fringilla tincidunt metus, non gravida lorem condimentum non. Duis ornare purus nisl, at porta arcu eleifend eget. Integer lorem ante, porta vulputate dui ut, blandit tempor tellus. Proin facilisis bibendum diam, sit amet rutrum est feugiat ut. Mauris rhoncus convallis arcu in condimentum. Donec volutpat dui eu mollis vulputate. Nunc commodo lobortis nunc at ultrices. Suspendisse in lobortis diam. Suspendisse eget vestibulum ex.
</p>
</div>
</div>
<div>
<input type="checkbox" id="toggle_2" hidden>
<label for="toggle_2" hidden></label>
<div class="content">
<p>
Maecenas laoreet nunc sit amet nulla ultrices auctor. Vivamus sed nisi vitae nibh condimentum pulvinar eu vel lorem. Sed pretium viverra eros ut facilisis. In ut fringilla magna. Sed a tempor libero. Donec sapien libero, lacinia sed aliquet ut, imperdiet finibus tellus. Nunc tellus lectus, rhoncus in posuere quis, tempus sit amet enim. Morbi et erat ac velit fringilla dignissim. Donec commodo, est id accumsan cursus, diam dui hendrerit nisi, vel hendrerit purus dolor ut risus. Phasellus mattis egestas ipsum sed ullamcorper. In diam ligula, rhoncus vel enim et, imperdiet porta justo. Curabitur vulputate hendrerit nisl, et ultricies diam. Maecenas ac leo a diam cursus ornare nec eu quam.
</p>
<p>Sed non vulputate purus, sed consectetur odio. Sed non nibh fringilla, imperdiet odio nec, efficitur ex. Suspendisse ut dignissim enim. Maecenas felis augue, tempor sit amet sem fringilla, accumsan fringilla nibh. Quisque posuere lacus tortor, quis malesuada magna elementum a. Nullam id purus in ante molestie tincidunt. Morbi luctus orci eu egestas dignissim. Sed tincidunt, libero quis scelerisque bibendum, ligula nisi gravida libero, id lacinia nulla leo in elit.
</p>
<p>Aenean aliquam risus id consectetur sagittis. Aliquam aliquam nisl eu augue accumsan, vel maximus lorem viverra. Aliquam ipsum dolor, tempor et justo ac, fermentum mattis dui. Etiam at posuere ligula. Vestibulum tortor metus, viverra vitae mi non, laoreet iaculis purus. Praesent vel semper nibh. Curabitur a congue lacus. In et pellentesque lorem. Morbi posuere felis non diam vulputate, non vulputate ex vehicula. Vivamus ultricies, massa id sagittis consequat, sem mauris tincidunt nunc, eu vehicula augue quam ut mauris.
</p>
</div>
</div>
<div>
<input type="checkbox" id="toggle_3" hidden>
<label for="toggle_3" hidden></label>
<div class="content">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dolor neque, commodo quis leo ut, auctor tincidunt mauris. Nunc fringilla tincidunt metus, non gravida lorem condimentum non. Duis ornare purus nisl, at porta arcu eleifend eget. Integer lorem ante, porta vulputate dui ut, blandit tempor tellus. Proin facilisis bibendum diam, sit amet rutrum est feugiat ut. Mauris rhoncus convallis arcu in condimentum. Donec volutpat dui eu mollis vulputate. Nunc commodo lobortis nunc at ultrices. Suspendisse in lobortis diam. Suspendisse eget vestibulum ex.
</p>
<p>Sed non vulputate purus, sed consectetur odio. Sed non nibh fringilla, imperdiet odio nec, efficitur ex. Suspendisse ut dignissim enim. Maecenas felis augue, tempor sit amet sem fringilla, accumsan fringilla nibh. Quisque posuere lacus tortor, quis malesuada magna elementum a. Nullam id purus in ante molestie tincidunt. Morbi luctus orci eu egestas dignissim. Sed tincidunt, libero quis scelerisque bibendum, ligula nisi gravida libero, id lacinia nulla leo in elit.
</p>
</div>
</div>
</main>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
952098 次 |
最近记录: |