我正在尝试使用CSS转换制作一个<ul>幻灯片。

<ul>开始于高度:0;。悬停时,高度设置为height:auto;。然而,这导致它简单地出现,

如果我从高度做:40px;至高度:自动;,那么它将向上滑动到高度:0;,然后突然跳到正确的高度。

如果不使用JavaScript,我怎么能做到这一点?

#子0{高度:0;溢出:隐藏;背景色:#dedede;-moz过渡:高度1s容易;-webkit过渡:高度1s轻松;-o过渡:高度1s容易;过渡:高度1s;}#parent0:悬停#child0{高度:自动;}#孩子40{高度:40px;溢出:隐藏;背景色:#dedede;-moz过渡:高度1s容易;-webkit过渡:高度1s轻松;-o过渡:高度1s容易;过渡:高度1s;}#parent40:悬停#child40{高度:自动;}h1小时{字号:粗体;}两个CSS片段之间的唯一区别是一个高度为0,另一个高度是40。<小时><div id=“parent0”><h1>将我悬停(高度:0)</h1><div id=“child0”>一些内容<br>一些内容<br>一些内容<br>一些内容<br>一些内容<br>一些内容<br></div></div><小时><div id=“parent40”><h1>将我悬停(高度:40)</h1><div id=“child40”>一些内容<br>一些内容<br>一些内容<br>一些内容<br>一些内容<br>一些内容<br></div></div>


当前回答

我只是为<li>元素设置动画,而不是为整个容器设置动画:

<style>
.menu {
    border: solid;
}
.menu ul li {
    height: 0px;
    transition: height 0.3s;
    overflow: hidden;
}
button:hover ~ .wrapper .menu ul li,
button:focus ~ .wrapper .menu ul li,
.menu:hover ul li {
    height: 20px;
}
</style>


<button>Button</button>
<div class="wrapper">
    <div class="menu">
        <ul>
            <li>menuitem</li>
            <li>menuitem</li>
            <li>menuitem</li>
            <li>menuitem</li>
            <li>menuitem</li>
            <li>menuitem</li>
        </ul>
    </div>
</div>

您可以添加ul:margin 0;高度为0。

其他回答

我想添加一个关于如何扩展/折叠以保持文档流的示例,这个示例适用于使用tailwindcss的React应用程序

export function Collapse({ collapsed = true, children }) {
  return (
    <div className="grid">
      <div className="flex flex-col">
        <div className={`transition-all duration-500 overflow-hidden ${collapsed ? 'basis-0' : 'flex-1'}`}>
          {children}
        </div>
      </div>
    </div>
  );
}

深入阅读:https://stackoverflow.com/a/69871346/9226510

扩展@jake的答案,过渡将一直到最大高度值,从而产生极快的动画效果-如果您同时设置了悬停和关闭两种过渡,则可以进一步控制疯狂的速度。

因此,li:hover是指鼠标进入状态,然后非悬停属性上的转换将是鼠标离开。

希望这会有所帮助。

例如:

.sidemenu li ul {
   max-height: 0px;
   -webkit-transition: all .3s ease;
   -moz-transition: all .3s ease;
   -o-transition: all .3s ease;
   -ms-transition: all .3s ease;
   transition: all .3s ease;
}
.sidemenu li:hover ul {
    max-height: 500px;
    -webkit-transition: all 1s ease;
   -moz-transition: all 1s ease;
   -o-transition: all 1s ease;
   -ms-transition: all 1s ease;
   transition: all 1s ease;
}
/* Adjust speeds to the possible height of the list */

这是一把小提琴:http://jsfiddle.net/BukwJ/

我的解决方法是将最大高度转换为精确的内容高度,以获得流畅的动画效果,然后使用transitionEnd回调将最大高度设置为9999px,以便内容可以自由调整大小。

var content=$('#content');content.inner=$('#content.inter');//关闭时需要获取内容大小的内部div//css转换回调content.on('transitionEnd-webkitTransitionEnd transitiononend oTransitionEnd-msTransitionEnd',函数(e){if(content.hasClass('open')){content.css('max-height',9999);//尝试将此设置为“无”。。。我敢你!}});$('#toggle').on('click',函数(e){content.tggleClass(“打开关闭”);content.contentHeight=content.outerHeight();if(content.hasClass('closed')){//禁用转换&将最大高度设置为内容高度content.removeClass('transitions').css('max-height',content.contentHeight);setTimeout(函数){//启用和启动转换content.addClass('转换').css({'最大高度':0,“不透明度”:0});}, 10); // 10ms超时是禁用/启用转换的秘密因素//chrome只需要1ms,但FF需要约10ms,否则会在第一部动画中因某种原因而窒息}否则如果(content.hasClass('open')){content.contentHeight+=content.inter.outerHeight();//如果已关闭,请将内部高度添加到内容高度内容.css({'max height':content.contentHeight,“不透明度”:1});}});.转换{过渡:所有0.5秒都是缓进缓出;-webkit转换:所有0.5s都易于输入输出;-moz转换:所有0.5s都易于输入输出;}正文{字体系列:Arial;线高:3ex;}代码{显示:内联块;背景:#fafafa;填充:0 1ex;}#切换{显示:块;填充:10px;边距:10px自动;文本对齐:居中;宽度:30ex;}#内容{溢出:隐藏;边距:10px;边框:1px实心#666;背景:#efefef;不透明度:1;}#内容。内部{填充:10px;溢出:自动;}<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>在<code>height:0</code>和<code>high:auto</code>之间平滑CSS转换</h3><p>一个巧妙的解决方法是使用<code>max-height</code>而不是<code>height</code>,并将其设置为比内容更大的值。问题是浏览器使用此值来计算过渡持续时间。因此,如果您将其设置为<code>max-height:1000px</code>,但内容只有100px高,则动画将快10倍</p><p>另一种选择是使用JS测量内容高度,并转换到固定值,但如果内容发生变化,则必须跟踪内容并手动调整其大小</p><p>此解决方案是两种转换的混合,即转换到测量的内容高度,然后在转换后将其设置为<code>最大高度:9999px</code>,以调整流体内容大小</p></div></div><br/><button id=“toggle”>接受挑战</按钮>

当我发布这篇文章时,已经有30多个答案了,但我觉得我的答案比杰克已经接受的答案要好。

我对简单地使用最大高度和CSS3转换产生的问题并不满意,因为正如许多评论人士所指出的,你必须将最大高度值设置得非常接近实际高度,否则会延迟。有关该问题的示例,请参阅此JSFiddle。

为了解决这个问题(虽然仍然不使用JavaScript),我添加了另一个转换转换的HTML元素:translateY CSS值。

这意味着同时使用了max-height和translateY:max-heith允许元素向下推它下面的元素,而translateY提供了我们想要的“即时”效果。最大高度的问题仍然存在,但其影响有所减弱。这意味着你可以为你的最大高度值设置一个更大的高度,而不用担心它。

总的好处是,在转换回(塌陷)时,用户可以立即看到translateY动画,因此最大高度需要多长时间并不重要。

解决方案为Fiddle

正文{字体系列:无衬线;}.切换{位置:相对;边框:2px实心#333;边界半径:3px;边距:5px;宽度:200px;}.切换标题{边距:0;填充:10px;背景色:#333;颜色:白色;文本对齐:居中;光标:指针;}.拨动高度{背景色:番茄;溢出:隐藏;过渡:最大高度。6s轻松;最大高度:0;}.tggle:悬停.tggle高度{最大高度:1000px;}.tggle转换{填充:5px;颜色:白色;转换:转换。4s轻松;变换:translateY(-100%);}.tggle:悬停.tggle变换{变换:translateY(0);}<div class=“toggle”><div class=“toggle header”>切换!</div><div class=“toggle height”><div class=“toggle transform”><p>内容</p><p>内容</p><p>内容</p><p>内容</p></div></div></div><div class=“toggle”><div class=“toggle header”>切换!</div><div class=“toggle height”><div class=“toggle transform”><p>内容</p><p>内容</p><p>内容</p><p>内容</p></div></div></div>

对于每个状态,使用具有不同过渡缓和和延迟的最大高度。

HTML格式:

<a href="#" id="trigger">Hover</a>
<ul id="toggled">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
<ul>

CSS:

#toggled{
    max-height: 0px;
    transition: max-height .8s cubic-bezier(0, 1, 0, 1) -.1s;
}

#trigger:hover + #toggled{
    max-height: 9999px;
    transition-timing-function: cubic-bezier(0.5, 0, 1, 0); 
    transition-delay: 0s;
}

参见示例:http://jsfiddle.net/0hnjehjc/1/