How can I transition height: 0; to height: auto; using CSS?
我正在尝试使用CSS转换使
-
向下滑动。
- 开始的时候没有延误,过渡也没有提前停止。在两个方向上(展开和折叠),如果在CSS中指定了300毫秒的转换持续时间,则转换需要300毫秒,周期。
- 它转换了实际高度(与
transform: scaleY(0) 不同),所以如果可折叠元素后面有内容,它就做了正确的事情。 - 虽然(和其他解决方案一样)有一些神奇的数字(比如"选择一个比你的盒子更高的长度"),但如果你的假设最终是错误的,那就不是致命的。在这种情况下,转换看起来可能并不令人惊讶,但在转换前后,这不是问题:在扩展(
height: auto 状态下,整个内容始终具有正确的高度(与选择的max-height 高度过低不同)。在崩溃状态下,高度应该是零。 - 如果你有一个高于2000像素的盒子,那么一个
margin-bottom: -2000px 不会隐藏所有东西——即使在折叠的情况下也会有可见的东西。这是我们稍后要做的一个小修复。 - 如果实际框高1000像素,并且您的转换长度为300毫秒,那么可视转换在大约150毫秒后已经结束(或者在相反的方向上,延迟150毫秒)。
- 从上面看,高度超过2000像素的盒子并没有完全隐藏在折叠状态中,
- 相反的问题是,在非隐藏的情况下,低于50像素高度的框太高了,即使转换没有运行,因为最小高度使它们保持在50像素。
- 从
height: auto 向height: 100% 过渡的论证 - 在添加子项时演示转换
height: auto 。 - 简单的
- 无JS
- 平滑过渡
- 元件需要放在固定高度的柔性容器中。
- 注意-代码笔中有JavaScript,但它的唯一目的是在单击手风琴时添加/删除CSS类。这可以通过隐藏的单选按钮来完成,但我并没有集中于此,只是高度转换。
我们真正想要的是改变身高
高度是子菜单中所有列表项的总和。
我们通常知道列表项的高度,因为我们正在设计它
- 我不太确定什么是
max-height ,因为我正在扩展一个未知长度的文本块。 - 如果我把
max-height 设置得太大,崩溃时会有很大的延迟。
-
从
如果我从
如果不使用javascript,我还能怎么做?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | The only difference between the two snippets of CSS is one has height: 0, the other height: 40. Hover me (height: 0) Some content Some content Some content Some content Some content Some content Hover me (height: 40) Some content Some content Some content Some content Some content Some content |
转换时使用
请参阅Chris约旦在另一个答案中提供的jfiddle演示。
1 2 3 4 5 6 7 8 9 10 11 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | hover me <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> |
你应该用scaley代替。
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <p> Here (scaleY(1)) </p> <ul> <li> Coffee </li> <li> Tea </li> <li> Milk </li> </ul> |
CSS:
1 2 3 4 5 6 7 8 9 10 | 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/dotnetcompenter/phyqc/9/,并将您的jsFiddle更改为使用scaley而不是height,http://jsfiddle.net/dotnetcompenter/7cnfc/206/。
当涉及的一个高度是
我一直使用的解决方案是先淡出,然后缩小
工作示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | hover me <ul id="list"> <li> item </li> <li> item </li> <li> item </li> <li> item </li> <li> item </li> </ul> <p> Another paragraph... </p> |
你可以,用一些非语义的诡计。我通常的方法是设置一个外部分区的高度动画,这个外部分区只有一个子分区,它是一个没有样式的分区,只用于测量内容高度。
1 2 3 4 5 6 7 8 9 | 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"; } } |
1 2 3 4 5 6 7 8 9 10 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <input type="button" onclick="growDiv()" value="grow"> The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. |
我们只想不使用
1 2 3 4 5 6 7 8 | function growDiv() { var growDiv = document.getElementById('grow'); if (growDiv.clientHeight) { growDiv.style.height = 0; } else { growDiv.style.height = 'auto'; } } |
1 2 3 4 5 6 7 8 9 10 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <input type="button" onclick="growDiv()" value="grow"> The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. The contents of my div. |
我的解释是动画运行需要一个明确的高度。当高度(起始高度或结束高度)为
我知道这是30多岁的人对这个问题的回答,但我认为这是值得的,所以我来看看。这是一个仅限于CSS的解决方案,具有以下属性:好的。
演示
这是一个演示,有三个可折叠的元素,高度不同,都使用相同的CSS。单击"运行代码段"后,您可能需要单击"整页"。注意,javascript只切换
1 2 3 4 5 6 | $(function () { $(".toggler").click(function () { $(this).next().toggleClass("collapsed"); $(this).toggleClass("toggled"); // this just rotates the expander arrow }); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | .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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> Something involving a holodeck Send an away team Advanced solutions Separate saucer Send an away team that includes the captain (despite Riker's protest) Ask Worf Something involving Wesley, the 19th century, and a holodeck Ask Q for help Sweet-talk the alien aggressor Re-route power from auxiliary systems Something involving a holodeck Send an away team Advanced solutions Separate saucer Send an away team that includes the captain (despite Riker's protest) Sweet-talk the alien aggressor Re-route power from auxiliary systems Something involving a holodeck Send an away team Advanced solutions Separate saucer Send an away team that includes the captain (despite Riker's protest) Ask Worf Something involving Wesley, the 19th century, and a holodeck Ask Q for help Separate saucer Send an away team that includes the captain (despite Riker's protest) Ask Worf Something involving Wesley, the 19th century, and a holodeck Ask Q for help Sweet-talk the alien aggressor Re-route power from auxiliary systems |
好的。它是如何工作的?
事实上,实现这一点涉及两个转变。其中一个将
单独使用
解决第二个问题就是第二个转换出现的地方,这个转换在概念上针对包装器的最小高度("概念上",因为我们实际上并没有为此使用
这是一个动画,演示了如何将底部边缘过渡与最小高度过渡结合在一起,两者的持续时间相同,从而使我们获得从全高度到零高度的组合过渡,其持续时间相同。好的。
好的。
左栏显示负的下边缘如何向上推动底部,从而降低可见高度。中间的条显示了最小高度如何确保在崩溃的情况下,过渡不会过早结束,而在扩展的情况下,过渡不会延迟开始。右栏显示了这两个选项的组合如何使框在正确的时间内从全高过渡到零高。好的。
在我的演示中,我将50px作为最小高度的上限值。这是第二个魔法数字,它应该比盒子的高度还要低。50px看起来也很合理;看起来你不太可能经常想让一个元素可以折叠,而这个元素一开始甚至不高50像素。好的。
正如您在动画中看到的,所产生的转换是连续的,但它是不可微分的——当最小高度等于由下边缘调整的整个高度时,速度会突然发生变化。这在动画中非常明显,因为它对两个过渡都使用线性计时函数,而且整个过渡非常慢。在实际情况下(我的演示在顶部),转换只需要300毫秒,并且底部边缘转换不是线性的。我在这两种转换中都使用了很多不同的计时功能,而最后使用的那些功能让我觉得它们最适合各种各样的情况。好的。
还有两个问题需要解决:好的。
我们解决了第一个问题,在崩溃的情况下给容器元素一个
第二个问题是我们没有实际使用
在chrome(win、mac、android、ios)、firefox(win、mac、android)、edge、ie11(除了我的演示版中的flexbox布局问题,我不需要调试)和safari(mac、ios)中进行测试。说到flexbox,应该可以在不使用任何flexbox的情况下实现此功能;事实上,我认为在IE7中几乎可以实现所有功能,除了没有CSS转换这一事实之外,这是一个非常没有意义的练习。好的。好啊。
使用CSS3转换设置高度动画的一个视觉解决方案是设置填充动画。
你不会完全得到擦除效果,但是使用过渡持续时间和填充值应该能让你足够接近。如果您不想显式地设置高度/最大高度,这应该是您想要的。
1 2 3 4 5 6 7 8 9 10 11 12 | 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上即兴演奏)
我的解决方法是将最大高度转换为精确的内容高度,以获得平滑的动画效果,然后使用transitionend回调将最大高度设置为9999px,以便内容可以自由调整大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 }); } }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | .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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"> Smooth CSS Transitions Between <wyn>height: 0</wyn> and <wyn>height: auto</wyn> <p> A clever workaround is to use <wyn>max-height</wyn> instead of <wyn>height</wyn>, 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 <wyn>max-height: 1000px</wyn> 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 <wyn>max-height: 9999px</wyn> after the transition for fluid content sizing. </p> <br /> <button id="toggle">Challenge Accepted!</button> |
接受的答案对大多数情况都有效,但是当你的
您仍然可以使用css执行实际的动画,但是您需要使用javascript计算项目的高度,而不是尝试使用
1 2 3 4 5 6 7 | 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'; } } |
1 2 3 4 5 6 | #menu #list { height: 0px; transition: height 0.3s ease; background: #d5d5d5; overflow: hidden; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <input value="Toggle list" type="button" onclick="toggleExpand(document.getElementById('list'));"> <ul id="list"> <!-- Works well with dynamically-sized content. --> <li> item </li> <li> </li> <li> item </li> <li> item </li> <li> item </li> </ul> |
对每种状态使用不同缓和和延迟过渡的
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Hover <ul id="toggled"> <li> One </li> <li> Two </li> <li> Three </li> <ul> |
CSS:
1 2 3 4 5 6 7 8 9 10 | #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/
没有硬编码值。
没有JavaScript。
没有近似值。
诀窍是使用隐藏和复制的
当您能够复制要动画化的元素的DOM时,此方法是合适的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | .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%; } |
1 2 3 4 5 6 7 8 9 10 11 | Hover over the box below: <!-- The actual element that you'd like to animate --> 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 <!-- An exact copy of the element you'd like to animate. --> 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 |
几乎没有提到
因此,对于一个
对于这样一个元素,假设它已经设置了过渡,例如(根据原始问题使用
1 2 3 4 | ul { height: 0; transition: height 1s; /* An example transition. */ } |
我们只需使用css,就可以触发所需的高度动画"扩展",如下所示(这里假设
1 | ul.style.height = ul.scrollHeight +"px"; |
就是这样。如果需要折叠列表,以下两个语句中的任何一个都可以:
1 2 | ul.style.height ="0"; ul.style.removeProperty("height"); |
我的特定用例围绕着一个未知的动画列表,通常是相当长的长度,所以我不习惯于使用一个任意的"足够大"的
最后,这里希望将来对CSS地址的修订能够更加优雅地完成这类工作——重新审视"计算"与"已用"和"已解析"值的概念,并考虑转换是否应应用于计算值,包括与
当我发表这篇文章时,已经有30多个答案了,但是我觉得我的答案比杰克已经接受的答案更好。
我不满意仅仅使用
为了解决这个问题(虽然仍然不使用javascript),我添加了另一个HTML元素,它转换
这意味着使用了
总的好处是,在返回(崩溃)的转换中,用户可以立即看到
解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | Toggle! <p> Content! </p> <p> Content! </p> <p> Content! </p> <p> Content! </p> Toggle! <p> Content! </p> <p> Content! </p> <p> Content! </p> <p> Content! </p> |
好吧,我想我想出了一个非常简单的答案…没有
小提琴:http://jsfiddle.net/n5xfg/2596/
CSS
1 2 3 4 5 6 7 8 9 | .wrap { overflow:hidden; } .inner { margin-top:-100%; -webkit-transition:margin-top 500ms; transition:margin-top 500ms; } .inner.open { margin-top:0px; } |
HTML
1 | Some Cool Content |
编辑:向下滚动查看更新的答案
我正在做一个下拉列表,看到了这篇文章…许多不同的答案,但我决定分享我的下拉列表太…它不是完美的,但至少它将只使用CSS下拉!我一直在使用transform:translatey(y)将列表转换为视图…你可以在测试中看到更多http://jsfiddle.net/bvepc/4/我把DIV放在每个LI后面,因为我的下拉列表是从上而来的,为了正确地显示它们,这是需要的,我的DIV代码是:
1 2 3 4 5 6 | #menu div { transition: 0.5s 1s; z-index:-1; -webkit-transform:translateY(-100%); -webkit-transform-origin: top; } |
悬停是:
1 2 3 4 | #menu > li:hover div { transition: 0.5s; -webkit-transform:translateY(0); } |
因为ul height设置为内容,它可以超越你的身体内容,所以我为ul做了这件事:
1 2 3 4 5 | #menu ul { transition: 0s 1.5s; visibility:hidden; overflow:hidden; } |
和悬停:
1 2 3 4 | #menu > li:hover ul { transition:none; visibility:visible; } |
转换后的第二次是延迟,它将在我的下拉列表被动态关闭后隐藏…希望以后有人能从中受益。
BR/>编辑:我简直不敢相信PPL真的在使用这个原型!此下拉菜单仅用于一个子菜单,仅此而已!!我更新了一个更好的,可以有两个子菜单为LTR和RTL方向与IE8支持。< BR>LTR小提琴
用于RTL的小提琴
希望将来有人会发现这一点有用。
如果还提供最小高度和最大高度,则可以从高度0转换为高度:自动。
1 2 3 4 5 6 7 8 9 10 11 12 13 | div.stretchy{ transition: 1s linear; } div.stretchy.hidden{ height: 0; } div.stretchy.visible{ height: auto; min-height:40px; max-height:400px; } |
我想我想出了一个非常可靠的解决方案
好啊!我知道这个问题和互联网一样古老,但我想我有一个解决方案,我把它变成了一个名为"突变转换"的插件。我的解决方案在DOM发生变化时为被跟踪元素设置
1 | This is an example with mutant-transition |
就是这样!此解决方案使用mutationobserver跟踪DOM中的更改。因此,您不必设置任何内容,也不必使用JavaScript手动设置动画。更改将自动跟踪。但是,因为它使用了mutationobserver,所以只能在IE11+中转换。
小提琴!
flexbox解决方案
赞成的意见:
欺骗:
它的工作方式是始终具有flex基础:在包含内容的元素上自动执行,而改为转换flex grow和flex shrink。
编辑:受Xbox One界面启发改进的JS小提琴。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | * { 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <p> Super Metroid Prime Fusion </p> <p> Resident Evil 2 Remake </p> <p> Yolo The Game </p> <p> Final Fantasy 7 Remake + All Additional DLC + Golden Tophat </p> <p> DerpVille </p> |
JS小提琴
以下是一种从任何起始高度(包括0)到自动(全尺寸和灵活)的转换方法,无需每个节点上的硬设置代码或任何要初始化的用户代码:https://github.com/csuwildcat/transition-auto。这基本上是你想要的圣杯,我相信——>http://codepen.io/csuwldcat/pen/kwsdf。只需将下面的JS文件放入页面,然后只需从要扩展和收缩的节点中添加/删除一个布尔属性-
以下是您作为用户需要做的所有事情,一旦您包含了示例代码下面的代码块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /*** 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! ***/ I have tons of content and I am 0px in height you can't see me... 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!... |
下面是要包含在您的页面中的代码块,在这之后,所有代码块都是肉汁:
把这个JS文件放到你的页面上-一切正常吗?
/*高度代码:自动;转换*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | (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); |
/*演示代码*/
1 2 3 4 5 6 | 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); |
杰克对"最大高度动画"的回答很好,但我发现设置一个大的"最大高度"会导致延迟。
可以将可折叠的内容移动到一个内部分区中,并通过获取内部分区的高度来计算最大高度(通过jquery,它将是outerheight())。
1 2 3 4 5 6 7 8 9 10 | $('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://jsfidle.net/8ncjjxh8/
在@jake的答案上展开,转换将一直延伸到最大高度值,从而产生一个极快的动画-如果您同时设置了两种转换:悬停和关闭,那么您可以更大程度地控制疯狂的速度。
所以li:hover是当鼠标进入状态,然后在非hovered属性上的转换将是鼠标离开。
希望这会有所帮助。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | .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/
我意识到这个线程正在变老,但它在某些谷歌搜索中排名很高,所以我认为它值得更新。
您还可以获取/设置元素自身的高度:
1 2 | var load_height = document.getElementById('target_box').clientHeight; document.getElementById('target_box').style.height = load_height + 'px'; |
您应该在内联脚本标记中的Target_Box结束标记之后立即转储此javascript。
我最近一直在转换
理由是,与大的
如果我的字体大小是
http://codepen.io/mindfullselement/pen/dtzje
这里有一个我刚与jquery结合使用的解决方案。这适用于以下HTML结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <nav id="main-nav"> <ul> <li> Link <ul> <li> Sub Link </li> </ul> </li> </ul> </nav> |
功能:
1 2 3 4 5 6 7 8 9 10 11 | $('#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); }); |
然后,您可以使用click函数设置和删除高度,方法是使用
1 2 3 4 5 6 7 8 9 10 | $('#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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #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 } |
我能做到。我有一个
像这样,伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 | .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 */ } |
您可以在
我没有详细阅读所有内容,但我最近遇到了这个问题,我做了如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } |
这允许您有一个DIV,它首先显示高达200px的内容,悬停时,其大小至少与该DIV的整个内容一样高。DIV不会变为3000px,但3000 px是我施加的限制。确保在non:hover上进行转换,否则可能会得到一些奇怪的渲染。这样,:hover继承自non:hover。
从px到%或到auto的转换不起作用。您需要使用相同的度量单位。这对我来说很好。使用HTML5使其完美……
记住,总有工作在身边…;)
希望有人觉得这个有用
似乎没有合适的解决办法。
我认为最好的方法是使用
1 2 3 4 5 6 | document.querySelector("button").addEventListener( "click", function(){ document.querySelector("div").classList.toggle("hide"); } ) |
1 2 3 4 5 6 7 8 9 10 | div { max-height: 20000px; transition: max-height 3000ms; overflow-y: hidden; } .hide { max-height: 0; transition: none; } |
1 2 | <button>Toggle</button> 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. |
我理解这个问题需要一个没有javascript的解决方案。但是对于那些感兴趣的人来说,这里是我的解决方案,只使用一点JS。
好的,那么元素的css(其高度默认会改变)被设置为
因此,我所做的就是在打开或关闭时将高度设置为元素的
打开时,我添加了一个
当关闭时,我会在下一个事件循环周期后立即使用setTimeout删除内联样式,不会延迟。这意味着
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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)); |
1 2 3 4 5 6 7 8 9 10 | #menu>ul { height: 0; overflow: hidden; background-color: #999; transition: height .25s ease-out; } #menu>ul.open { height: auto; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | hover me <ul> <li> item </li> <li> item </li> <li> item </li> <li> item </li> <li> item </li> </ul> |
这并不是解决问题的"解决方案",而是解决问题的方法。它只能与文本一起工作,但可以根据需要更改为与其他元素一起工作。
1 2 3 4 5 6 7 | .originalContent { font-size:0px; transition:font-size .2s ease-in-out; } .show { /* class to add to content */ font-size:14px; } |
以下是一个例子:http://codepen.io/overthemike/pen/wzjrka
本质上,您将字体大小设置为0,并以足够快的速度将其转换为所需的高度,而不是最大高度或scaley()等。用css将实际高度转换为auto当前是不可能的,但是在is中转换内容,因此字体大小转换。
将高度设置为自动并转换最大高度。
在铬V17上测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | div { position: absolute; width:100%; bottom:0px; left:0px; background:#333; color: #FFF; max-height:100%; /**/ height:auto; /**/ -webkit-transition: all 0.2s ease-in-out; -moz-transition: all 0.2s ease-in-out; -o-transition: all 0.2s ease-in-out; -ms-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } .close { max-height:0%; /**/ } |
如果硬编码提供的最大高度值不大于实际高度(否则会出现不希望出现的延迟和时间问题)。另一方面,如果硬编码值意外为不超过实际高度的元素不会完全打开。
以下仅限CSS的解决方案还需要硬编码的大小应该比实际尺寸大。然而这如果实际大小在某些情况下大于硬编码的大小。在这种情况下,过渡可能会有点跳跃,但它不会留下部分可见的元素。因此,此解决方案也可用于未知内容,例如一个数据库,你只知道它的内容通常不大X像素以上,但也有例外。
我们的想法是用一个负的值作为保证金底部(或保证金顶部稍微不同的动画)并将内容元素放入溢出的中间元素:隐藏。内容的负边缘元素,因此减少中间元素的高度。
以下代码在页边距底部使用从-150px到0px。只要内容元素不是高于150像素。此外,它使用最大高度的过渡中间元素从0px到100%。这最后隐藏了中间元素如果含量元素高于150px。对于最大高度,过渡仅用于延迟其应用关闭时的一秒钟,不会产生平滑的视觉效果(因此,它可以从0px运行到100%。
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | .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:
1 2 3 4 5 6 7 8 | Sample Text Sample Text Sample Text Sample Test of height 150px Sample Text Hover Here |
保证金底部的值应为负值,并尽可能接近可能达到内容元素的实际高度。如果它离开了值)越大,与最大高度解决方案,但只要硬编码的大小并不比实际大小大多少。如果绝对页边距底部的值小于实际高度Tanposition跳了一点。在任何情况下,在过渡之后内容元素要么完全显示,要么完全删除。
有关更多详细信息,请参阅我的博客文章http://www.taccgl.org/blog/css-transition-display.html combined-height
这是我经常解决的问题
http://jsfiddle.net/ipeshev/d1dfr0jz/
尝试将关闭状态的延迟设置为某个负数,并用该值播放一点。你会看到区别的。它几乎可以用来欺骗人眼;)。
它可以在主要浏览器中使用,但对我来说已经足够好了。这很奇怪,但给出了一些结果。
1 2 3 4 5 6 7 8 9 10 | .expandable { max-height: 0px; overflow: hidden; transition: all 1s linear -0.8s; } button:hover ~ .expandable { max-height: 9000px; transition: all 1s ease-in-out; } |
小javascript+scss解决方案
我通常使用一个完全不同的视角和一个(非常)小的javascript。问题是:
所以我的解决方案适用于"普通"子菜单,其中项目名称只有一行。不管怎样,只要多加一点JS,就可以容纳多个行名称。
基本上,我只需要计算子菜单项并相应地应用特定类。然后把球传给CSS。例如:
1 2 3 4 5 6 | var main_menu = $('.main-menu'); var submenus = $('.main-menu').find('.submenu'); submenus.each(function(index,item){ var i = $(item); i.addClass('has-' + i.find('li').length + '-children'); }); |
显然,您可以使用任何类/选择器。现在我们有这样的子菜单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <ul class="submenu has-3-children"> <li> </li> <li> </li> <li> </li> </ul> |
我们的CSS是这样的:
1 2 3 4 5 6 | .submenu{ //your styles [...] height:0; overflow:hidden; transition: all 200ms ease-in-out; //assume Autoprefixer is used } |
我们还将有一些类似这样的SCSS变量(任意示例):
1 2 | $sub_item_height:30px; $sub_item_border:2px; |
此时,假设打开的主菜单项将获得类似"opened"或类似的类(您的implementations….),我们可以这样做:
1 2 3 4 5 6 7 | //use a number of children reasonably high so it won't be overcomed by real buttons .main-menu .opened .submenu{ &.has-1-children{ height: $sub_item_height*1 + $sub_item_border*1; } &.has-2-children{ height: $sub_item_height*2 + $sub_item_border*2; } &.has-3-children{ height: $sub_item_height*3 + $sub_item_border*3; } //and so on.... } |
或者,缩短:
1 2 3 4 5 | .main-menu .opened .submenu{ @for $i from 1 through 12{//12 is totally arbitrary &.has-#{$i}-children { height: $menu_item_height * $i + $menu_item_border * $i; } } } |
在大多数情况下,这将起到作用。希望它有帮助!
这就是我的工作:
1 2 3 4 5 6 7 8 9 10 | .hide{ max-height: 0px; overflow: hidden; transition:max-height .5s ease-in-out; } .show{ max-height: 150px; // adjust as needed transition: max-height .5s ease-in-out; } |
您需要将它们放入所有子组件中,并使用jquery或react状态切换它们,这里是我的示例(使用next.js和样式化组件):https://codesandbox.io/s/ol3kl56q9q
你用下面的东西代替高度怎么样
1 2 3 4 5 6 7 8 9 10 11 12 | #child0 { visibility: hidden; opacity: 0; transition: visibility 0s, opacity 0.5s linear; position: absolute; } #parent0:hover #child0 { visibility: visible; opacity: 1; position: relative; } |
效果也很好。请添加前缀。希望这能帮助别人。
附言:如果你还需要高度0来获得某种黑色魔法,你可以把
查看我关于一个相关问题的帖子。
基本上,从
1 2 3 4 5 6 7 8 9 | function setInfoHeight() { $(window).on('load resize', function() { $('.info').each(function () { var current = $(this); var closed = $(this).height() == 0; current.show().height('auto').attr('h', current.height() ); current.height(closed ? '0' : current.height()); }); }); |
每当页面加载/调整大小时,类为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function moreInformation() { $('.icon-container').click(function() { var info = $(this).closest('.dish-header').next('.info'); // Just the one info var icon = $(this).children('.info-btn'); // Select the logo // Stop any ongoing animation loops. Without this, you could click button 10 // times real fast, and watch an animation of the info showing and closing // for a few seconds after icon.stop(); info.stop(); // Flip icon and hide/show info icon.toggleClass('flip'); // Metnod 1, animation handled by JS // info.slideToggle('slow'); // Method 2, animation handled by CSS, use with setInfoheight function info.toggleClass('active').height(icon.is('.flip') ? info.attr('h') : '0'); }); }; |
这是
1 2 3 4 5 6 7 8 9 10 11 12 | .info { padding: 0 1em; line-height: 1.5em; display: inline-block; overflow: hidden; height: 0px; transition: height 0.6s, padding 0.6s; &.active { border-bottom: $thin-line; padding: 1em; } } |
跨浏览器可能不支持样式。以下是此代码的实时示例:
科德森这是我的解决方案。以前的最大高度和巨大的数字是好的,但对我来说还不够,因为动画在较小的文本量上有问题。我的代码动态地获取内容需要的放置量,并将其放到atribute中。
1 2 3 4 5 6 7 8 9 10 11 12 13 | var unrolled = false; $("#unroll" ).click(function() { if(!unrolled){ $('.block-of-text').css("max-height", $('.whole-content').height() +"px"); unrolled=true; } else{ $('.block-of-text').removeAttr("style"); unrolled=false; } }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .block-of-text{ width:200px; max-height:150px; padding:25px; background:rgba(0,0,255,0.6); transition:0.4s; color:white; display:inline-block; overflow:hidden; } #unroll{ position:absolute; left:280px; background:transparent; color:blue; border:2px solid blue; transition:0.4s; top:20px; } #unroll:hover{ background:blue; color:white; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> YOU CAN PLACE HERE AS MUCH TEXT AS YOU WANT Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a, Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a, Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a, Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a, Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Suspendisse enim turpis, dictum sed, iaculis a, Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. END OF CONTENT, <button id="unroll"> Unroll block </button> |
这个解决方案使用JavaScript,但它非常简单,而且工作得很好。
HTML:
1 2 3 4 5 6 7 8 | <button>Toggle</button> Lorem Ipsum Dolor Sit Amet |
CSS:
1 2 3 4 5 6 7 8 9 10 | .container { overflow: hidden; transition: 0.5s ease; } .container.collapsed { height: 0 !important; } |
Javascript:
1 2 3 4 5 6 7 | $("button").click( function () { var height = $(".content").height(); $(".container").css({height: height}); $(".container").toggleClass("collapsed"); }); |
http://jsfiddle.net/r109uz7m/(包括下面解释的缺点的解决方法):
唯一的缺点是,如果容器中的内容发生更改,则需要刷新容器的大小。在大多数用例中,您可以绕过这个限制(就像在JSfiddle中一样)。
短代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 | .slider ul { overflow: hidden; -webkit-transition: max-height 3.3s ease; } .slider.hide ul { max-height: 0px; } .slider.show ul { max-height: 1000px; } |
我通过将最大高度设置为"无",获取高度,将最大高度重新设置为计算出的高度来实现这一点。为我工作得很好。我在一个手风琴菜单上找到了这个,用
作为切换开关,在 内部扩展 。
JS:
1 2 3 4 5 6 | $('h5').click(function(e) { $(this).parent('div').addClass('temp_expanded'); var getheight = ($(this).parent('div').find('div').height()); $(this).parent('div').removeClass('temp_expanded'); $(this).parent('div').find('div').css('max-height', getheight); }); |
较少:
1 2 3 4 5 6 7 8 9 10 11 12 | div { > div { max-height: 0px; overflow: hidden; .transition(all 0.3s ease-in-out); } &.temp_expanded { > div { max-height: none; } } |
我今天研究这个问题已经有一段时间了,发现了这个解决方案:
使用"最大高度",并根据容器内容物的计算高度动态设置最大高度。
1 2 3 | $(obj).children().each(function(index, element) { InnerHeight += $(this).height(); }); |
要将动画设置为全尺寸:
1 | $(obj).removeClass('collapsed').css('max-height', InnerHeight); |
要将动画设置为较小的大小,请执行以下操作:
1 | $(obj).removeClass('collapsed').css('max-height', MySmallerHeight); |
使用CSS3过渡:最大高度;
这样,你就可以避免从一个高度到另一个高度的浮华动画,也不会有剪辑内容的风险。
我遇到了这个问题,找到了解决办法。
首先,我尝试使用
然后,我的解决方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function toggleBlock(e) { var target = goog.dom.getNextElementSibling(e.target); if (target.style.height && target.style.height !="0px") { //collapsing goog.style.setHeight(target, target.clientHeight); setTimeout(function(){ target.style.height ="0px"; }, 100); } else { //expanding target.style.height ="auto"; //get the actual height var height = target.clientHeight; target.style.height ="0px"; setTimeout(function(){ goog.style.setHeight(target, height); }, 100); setTimeout(function(){ //Set this because I have expanding blocks inside expanding blocks target.style.height="auto"; }, 600); //time is set 100 + transition-duration } } |
SCS:
1 2 3 4 5 6 | div.block { height: 0px; overflow: hidden; @include transition-property(height); @include transition-duration(0.5s); } |
我也用jquery做了这个。在我的例子中,我想看一点其他菜单(10px)。因此,这在没有JavaScript的情况下工作(但也没有转换)。
1 2 3 4 5 6 7 8 9 10 | #menu li ul { list-style: none; height: 10px; overflow: hidden; margin: 0; padding: 0; } #menu li:hover ul { height: 100%; } |
这是我的JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //Save the height set in css (10px) var csshoehe = $("ul li ul").height(); // Open all the menus $("ul li ul").css("height","100%"); //Save each height in data-attribute //then shrink it down again $.each($("ul li ul"), function(){ var hoehe = $(this).height(); $(this).data("hoehe", hoehe); $(this).css("height", csshoehe); }); $("ul li").hover( function(){ var orig = $(this).children("ul").data("hoehe"); $(this).children("ul").stop(true,false).delay(150).animate({"height": orig}); }, function(){ $(this).children("ul").stop(true,false).delay(400).animate({"height": csshoehe}); }); |
希望这能帮助别人:)
这就是我一直使用的。
基本上,我会得到所有子元素的高度,对它们求和,然后设置元素的最大高度,覆盖类(您可以创建自己的类,这样您就可以拥有不同的实例)。
过来看。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | <!doctype html> <html> <head> <style> /* OVERFLOW HIDDEN */ .overflowHidden{ overflow: hidden; } /* HEIGHT */ .transitionHeight{ -webkit-transition: max-height 250ms ease-in-out; -moz-transition: max-height 250ms ease-in-out; -o-transition: max-height 250ms ease-in-out; -ms-transition: max-height 250ms ease-in-out; transition: max-height 250ms ease-in-out; } .heightAnimOff{ height: auto; max-height: 0px; } .heightAnimOn{ height: auto; max-height: 20000px; } </style> <script src="jquery_1.8.3.min.js" type="text/javascript"> <script type="text/javascript"> (function($){ $.toggleAnimHeight = function(alvo, velha, nova){ if ( $(alvo).attr("data-maxHeight") != null ){ }else{ var totalH = 0; $(alvo).children().each(function(){ totalH += $(this).height(); }); $(alvo).attr("data-maxHeight", totalH) $("head").append('<style> .'+nova+'{ max-height: '+totalH+'px; } </style>'); } if ( $(alvo).attr("class").indexOf(nova) == -1 ){ $(alvo).removeClass(velha); $(alvo).addClass(nova); }else { $(alvo).removeClass(nova); $(alvo).addClass(velha); } } }(jQuery)); </head> <body> <button onmousedown="$.toggleAnimHeight( $('#target1'), 'heightAnimOff', 'heightAnimOn' );">Anim Toggle</button> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. In id pretium enim, quis faucibus urna. Phasellus blandit nisl eget quam mollis vulputate. Sed pulvinar eros vitae neque volutpat, vitae suscipit urna viverra. Etiam rhoncus purus vitae tortor pulvinar, sed vulputate arcu convallis. Sed porta, mi consectetur convallis semper, odio mauris iaculis purus, non tempor purus augue pharetra lorem. Integer dictum lacus arcu. Vivamus metus lorem, fermentum ac egestas ac, ornare non neque. Aenean ullamcorper adipiscing ante, et mollis orci feugiat et. </p> <p> Praesent pretium sit amet eros et lacinia. Etiam nec neque ullamcorper, sagittis quam vitae, dictum ipsum. Sed volutpat lorem libero, nec commodo magna posuere rutrum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque id erat odio. Sed faucibus sem eu tortor laoreet pulvinar. Praesent pharetra risus eget metus vulputate, eget condimentum leo consequat. Praesent consequat rutrum convallis. </p> <p> Aenean euismod metus quis libero commodo, tristique cursus odio vestibulum. Donec quis lobortis arcu, eu luctus diam. In eget nisi non mauris commodo elementum. Sed gravida leo consequat, tempus orci eu, facilisis ipsum. Cras interdum sed odio vel tincidunt. Morbi arcu ipsum, ultricies dictum enim quis, varius dignissim massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec semper, magna eu aliquam luctus, leo purus accumsan massa, at auctor dui dolor eu augue. Maecenas ultrices faucibus ante non mattis. </p> <p> Pellentesque ut est tortor. Quisque adipiscing ac nisi vel interdum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut facilisis ante sollicitudin vehicula ornare. Quisque sagittis diam nibh, ac imperdiet nibh pulvinar eu. Integer at ipsum a purus tristique porttitor vitae in ante. Sed arcu neque, lacinia eu dolor nec, pellentesque interdum tortor. Morbi ornare aliquet aliquam. Aenean egestas, erat vel tempus mollis, est eros iaculis enim, quis fringilla purus tortor sollicitudin erat. Donec ultrices elit metus, sed iaculis mi dignissim vulputate. Donec adipiscing imperdiet porttitor. Sed ac lacus adipiscing, sagittis sem quis, tincidunt metus. Curabitur vitae augue a dolor scelerisque lobortis ut a nisi. </p> <p> Quisque sollicitudin diam sit amet dui sollicitudin, ac egestas turpis imperdiet. Nullam id dui at lectus ultrices aliquam. Nam non luctus tortor, vitae elementum elit. Nullam id bibendum orci. Aliquam hendrerit nisi vitae tortor mollis, nec aliquam risus malesuada. In scelerisque nisl arcu, sit amet tincidunt libero consequat pharetra. Quisque aliquam consectetur purus nec sollicitudin. Pellentesque consectetur eleifend tortor in blandit. Pellentesque euismod justo sed lectus congue, ut malesuada diam rhoncus. Nulla id tempor odio. Nulla facilisi. Phasellus lacinia neque in nisi congue aliquet. Aliquam malesuada accumsan mauris eget mattis. Maecenas pellentesque, sem sed ultricies ullamcorper, massa enim consectetur magna, eget sagittis lorem leo vel arcu. Cras ultrices nunc id risus commodo laoreet. Proin nisl nulla, elementum ac libero sed, aliquam mollis massa. </p> </body> </html> |
如果"li">30件,那么包装高度将大于500px。我的回答是:
1 2 3 | ul{width:100%} li{height:0;overflow:hidden;background:#dedede;transition:.2s.4s linear} ul:hover li{height:20px} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <ul> Hover me <li> Juice </li> <li> Tea </li> <li> Milk </li> <li> Coffee </li> </ul> |