我正在尝试使用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>


当前回答

你可以,用一点非语义的小把戏。我通常的方法是设置外部DIV的高度动画,该外部DIV有一个子级,这是一个仅用于测量内容高度的无样式DIV。

函数growDiv(){var growDiv=文档.getElementById('grow');if(growtDiv.clientHeight){growtDiv.style.height=0;}其他{var wrapper=document.querySelector('.measureingWrapper');growDiv.style.height=wrapper.clientHeight+“px”;}}#成长{-moz过渡:高度.5s;-ms过渡:高度.5s;-o过渡:高度.5s;-webkit过渡:高度.5s;过渡:高度.5s;高度:0;溢出:隐藏;轮廓:1px纯红色;}<input type=“button”onclick=“growDiv()”value=“grow”><div id='grow'><div class='measureingWrapper'><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div></div></div>

人们希望能够省去.metringWrapper,只需将DIV的高度设置为auto并设置动画,但这似乎不起作用(设置了高度,但没有动画发生)。

函数growDiv(){var growDiv=文档.getElementById('grow');if(growtDiv.clientHeight){growtDiv.style.height=0;}其他{growDiv.style.height=“自动”;}}#成长{-moz过渡:高度.5s;-ms过渡:高度.5s;-o过渡:高度.5s;-webkit过渡:高度.5s;过渡:高度.5s;高度:0;溢出:隐藏;轮廓:1px纯红色;}<input type=“button”onclick=“growDiv()”value=“grow”><div id='grow'><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div><div>我部门的内容。</div></div>

我的解释是,动画运行需要明确的高度。当高度(起始高度或结束高度)为自动时,无法获得高度动画。

其他回答

您可以从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;
}

下面是我刚刚与jQuery结合使用的解决方案。这适用于以下HTML结构:

<nav id="main-nav">
    <ul>
        <li>
            <a class="main-link" href="yourlink.html">Link</a>
            <ul>
                <li><a href="yourlink.html">Sub Link</a></li>
            </ul>
        </li>
    </ul>
</nav>

以及功能:

    $('#main-nav li ul').each(function(){
        $me = $(this);

        //Count the number of li elements in this UL
        var liCount = $me.find('li').size(),
        //Multiply the liCount by the height + the margin on each li
            ulHeight = liCount * 28;

        //Store height in the data-height attribute in the UL
        $me.attr("data-height", ulHeight);
    });

然后,您可以使用click函数使用css()设置和删除高度

$('#main-nav li a.main-link').click(function(){
    //Collapse all submenus back to 0
    $('#main-nav li ul').removeAttr('style');

    $(this).parent().addClass('current');

    //Set height on current submenu to it's height
    var $currentUl = $('li.current ul'),
        currentUlHeight = $currentUl.attr('data-height');
})

CSS:

#main-nav li ul { 
    height: 0;
    position: relative;
    overflow: hidden;
    opacity: 0; 
    filter: alpha(opacity=0); 
    -ms-filter: "alpha(opacity=0)";
    -khtml-opacity: 0; 
    -moz-opacity: 0;
    -webkit-transition: all .6s ease-in-out;
    -moz-transition: all .6s ease-in-out;
    -o-transition: all .6s ease-in-out;
    -ms-transition: all .6s ease-in-out;
    transition: all .6s ease-in-out;
}

#main-nav li.current ul {
    opacity: 1.0; 
    filter: alpha(opacity=100); 
    -ms-filter: "alpha(opacity=100)";
    -khtml-opacity: 1.0; 
    -moz-opacity: 1.0;
}

.ie #main-nav li.current ul { height: auto !important }

#main-nav li { height: 25px; display: block; margin-bottom: 3px }

我想添加一个关于如何扩展/折叠以保持文档流的示例,这个示例适用于使用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

我一直使用的解决方案是先淡出,然后缩小字体大小、填充和边距值。它看起来不像擦拭器,但它没有静态高度或最大高度。

工作示例:

/*最终显示器*/#菜单#列表{边距:.5em 1em;填充:1em;}/*隐藏,隐藏*/#menu:not(:hover)#列表{字体大小:0;边距:0;不透明度:0;填充:0;/*淡出,然后收缩*/过渡:不透明度.25s,字体大小.5s.25s,余量.5s.25s,填充.5s.25s;}/*显示*/#菜单:悬停#列表{/*取消闪烁,然后淡入*/过渡:字体大小.25s,边距.25s,填充.25s,不透明度.5s.25s;}<div id=“menu”><b>悬停我</b><ul id=“list”><li>项目</li><li>项目</li><li>项目</li><li>项目</li><li>项目</li></ul></div><p>另一段</p>

仅限CSS的灵活高度解决方案

我偶然发现了一个使用灵活行为的奇怪解决方案。它至少适用于Chrome和Firefox。

首先,高度转换仅在0和100%之间有效,两个数值。由于“auto”不是数值,因此分数在0和“自动”之间不存在增量。100%是灵活的值,因此不需要特定高度。其次,隐藏内容的外部容器和内部容器都必须设置为display:flex with flex direction:column。第三,外部容器必须具有高度属性。仅当所有内容都包含在外部容器中时,将其设置为0才能保持平滑过渡,因为弯曲行为优先于高度。Edit:Json建议使用height:fit内容,这样容器下面的任何内容都会被向下推。

.外部容器{高度:0;显示:flex;flex方向:列;}.内部容器{display:flex;flex direction:column;}.隐藏内容{高度:0;不透明度:0;过渡:高度1s 0.5s进出,不透明度0.5s进出;/*过渡淡出:首先淡出不透明度,然后在延迟等于不透明度持续时间后收缩高度*/}.t触发器:悬停+.内部容器>.隐藏内容{高度:100%;不透明度:1;过渡:高度1s进出,不透明度0.5s 1s进出;/*过渡:首先展开高度,然后在等于高度持续时间的延迟后淡入不透明度*/}<div class=“outer container”><a href=“#”class=“trigger”>悬停以显示内部容器的隐藏内容</a><div class=“内部容器”><div class=“hidden content”>这是隐藏内容。当由悬停触发时,其高度从0过渡到100%,这会将同一容器中的其他内容逐渐向下推</分区><div>在同一个容器中,当隐藏内容的高度从0过渡到100%时,其他内容会逐渐向下推</分区></div></div>

按“运行代码段”按钮查看正在运行的转换。它只是CSS,没有特定的高度。