如何在CSS Flexbox中实现带动画的可点击下拉菜单(无需jQuery)
实现下拉展开的动画效果(保持flex布局)

如图所示,我有多个连续的锚点标签,点击其中一个时,下方会显示对应的div,效果如下:
现有代码
HTML
以下是第一个锚点标签的代码,其余标签结构相同。
<div class="category2"> <a href="#" class="items2" id="itemOne"> Elektrikli El Aletleri </a> <div class="subCategory" id="subListOne"> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> <a href="#">Lorem ipsum dolor sit.</a> </div> ... </div>
CSS
.category2 { flex-direction: column; display:none; }
@media screen and (max-width:1220px) { .category2 { display: flex; } .category2 > a { height: 50px; } }
.items2 { border:1px solid white; background-color: black; color: white; display: flex; justify-content: center; align-items: center; border-radius: 20px; font-size:20px; }
.subCategory { flex-direction: column; background-color: darkslategrey; display: none; }
点击ID为itemOne的锚点标签时,会给subCategory添加.active类,从而显示该div:
.active { display:flex }
JS
let itemOne = document.getElementById('itemOne'); let subListOne = document.getElementById('subListOne'); itemOne.addEventListener('click', () => { subListOne.classList.toggle('active'); })
需求与问题
我希望给这个显示事件添加动画效果,让div在数毫秒内滑下展开,同时保持该div的display:flex布局。
我尝试通过height属性实现,修改了subCategory的样式:
.subCategory { flex-direction: column; background-color: darkslategrey; display: flex; height:0px; transition: all 0.7s ease }
并将.active类改为:
.active { height:"auto"; }
但这个方法无效,求可行的解决方案。
解决方案
问题出在height: auto无法触发CSS过渡动画,因为过渡需要明确的数值变化。这里提供两种可行方案:
方案1:使用max-height替代height
利用max-height设置一个足够大的数值(大于内容实际高度),通过切换max-height来实现滑入滑出效果,同时保持flex布局:
.subCategory { flex-direction: column; background-color: darkslategrey; display: flex; max-height: 0; overflow: hidden; /* 隐藏超出部分 */ transition: max-height 0.7s ease; } .subCategory.active { max-height: 1000px; /* 设置一个比内容实际高度大的值 */ }
这个方案不需要修改JS代码,直接沿用原来的classList.toggle('active')逻辑即可。
方案2:JS动态计算内容高度
如果需要更精确的动画(比如不想设置过大的max-height),可以通过JS获取内容的实际高度,再动态设置height值:
.subCategory { flex-direction: column; background-color: darkslategrey; display: flex; height: 0; overflow: hidden; transition: height 0.7s ease; }
修改JS代码:
let itemOne = document.getElementById('itemOne'); let subListOne = document.getElementById('subListOne'); itemOne.addEventListener('click', () => { if (subListOne.classList.contains('active')) { // 收起:设置height为0 subListOne.style.height = '0'; // 动画结束后移除active类(可选,根据需求) setTimeout(() => { subListOne.classList.remove('active'); }, 700); } else { // 展开:先获取内容高度,再设置 subListOne.classList.add('active'); const scrollHeight = subListOne.scrollHeight; subListOne.style.height = scrollHeight + 'px'; } })
注意:如果内容高度可能动态变化(比如加载新内容),需要重新计算高度。
内容的提问来源于stack exchange,提问作者Alim Gölcük
相关产品推荐
相关产品推荐

