在CSS中,transition属性可以为元素的状态变化添加平滑的过渡效果,非常适合用来制作下拉菜单的展开和收起动画。下拉菜单的核心逻辑是默认隐藏菜单内容,当触发元素被 hover 或者点击时,改变菜单的显示状态,配合transition让状态变化的过程产生动画感。

transition核心属性说明
transition是一个简写属性,包含四个子属性,我们可以单独设置也可以直接使用简写形式:
- transition-property:指定需要添加过渡效果的CSS属性,比如height、opacity、transform等,默认值为all,表示所有可过渡的属性都会生效。
- transition-duration:指定过渡效果的持续时间,单位为秒s或者毫秒ms,比如0.3s表示过渡过程持续0.3秒。
- transition-timing-function:指定过渡的速度曲线,常见值有ease(默认,先快后慢)、linear(匀速)、ease-in(渐入)、ease-out(渐出)等。
- transition-delay:指定过渡效果延迟多久开始,默认值为0s,不需要延迟时可以省略。
简写语法为:transition: property duration timing-function delay;,其中duration是必须设置的属性,其余可以根据需求省略。
下拉菜单基础结构搭建
首先我们需要搭建下拉菜单的HTML结构,通常包含一个触发容器,容器内部有触发按钮和下拉菜单内容:
<div class="dropdown">
<button class="dropdown-btn">菜单触发</button>
<ul class="dropdown-menu">
<li><a href="#">菜单项1</a></li>
<li><a href="#">菜单项2</a></li>
<li><a href="#">菜单项3</a></li>
</ul>
</div>
用transition实现展开收起动画
接下来通过CSS设置默认状态和展开状态,配合transition实现动画效果,这里以hover触发为例:
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.dropdown {
position: relative;
width: 120px;
margin: 50px auto;
}
.dropdown-btn {
width: 100%;
padding: 10px;
background-color: #409eff;
color: #fff;
border: none;
cursor: pointer;
border-radius: 4px;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
width: 100%;
background-color: #fff;
border: 1px solid #e4e7ed;
border-radius: 4px;
list-style: none;
/* 默认隐藏菜单:设置高度为0,溢出隐藏 */
height: 0;
overflow: hidden;
/* 添加过渡效果:对height和opacity属性做0.3秒的缓动过渡 */
transition: height 0.3s ease, opacity 0.3s ease;
opacity: 0;
}
.dropdown-menu li a {
display: block;
padding: 8px 10px;
color: #333;
text-decoration: none;
}
.dropdown-menu li a:hover {
background-color: #f5f7fa;
}
/* hover时展开菜单:设置具体高度,显示菜单内容 */
.dropdown:hover .dropdown-menu {
height: 122px; /* 3个菜单项每个高度40px,加上上下边框2px,总共122px */
opacity: 1;
}
上面的代码中,我们默认将下拉菜单的height设为0,overflow设为hidden,同时设置opacity为0让菜单完全不可见。当鼠标 hover 到触发容器时,将height改为菜单的实际高度,opacity改为1,配合transition属性,height和opacity的变化就会产生平滑的过渡动画。
点击触发的下拉菜单实现
如果需要点击触发下拉菜单,可以结合少量JavaScript切换类名,CSS部分只需要调整状态对应的样式即可:
/* 其余样式和上面一致,仅修改展开状态的逻辑 */
.dropdown-menu {
height: 0;
overflow: hidden;
transition: height 0.3s ease, opacity 0.3s ease;
opacity: 0;
}
/* 展开状态的类名 */
.dropdown-menu.show {
height: 122px;
opacity: 1;
}
对应的JavaScript代码如下:
// 获取触发按钮和下拉菜单
const dropdownBtn = document.querySelector('.dropdown-btn');
const dropdownMenu = document.querySelector('.dropdown-menu');
// 点击按钮切换菜单的显示状态
dropdownBtn.addEventListener('click', function() {
dropdownMenu.classList.toggle('show');
});
// 点击页面其他区域关闭菜单
document.addEventListener('click', function(e) {
// 如果点击的目标不在下拉容器内,就关闭菜单
if (!e.target.closest('.dropdown')) {
dropdownMenu.classList.remove('show');
}
});
常见优化技巧
使用transform替代height过渡
如果下拉菜单的高度不固定,设置具体的height值会比较麻烦,此时可以使用transform的scaleY属性来实现过渡,性能也更好:
.dropdown-menu {
transform: scaleY(0);
transform-origin: top; /* 设置缩放的原点为顶部 */
transition: transform 0.3s ease;
opacity: 0;
/* 不需要设置height和overflow,避免内容溢出问题 */
}
.dropdown:hover .dropdown-menu {
transform: scaleY(1);
opacity: 1;
}
适配移动端点击场景
移动端没有hover事件,建议统一使用点击触发的方式,同时可以给触发按钮添加active状态的样式,提升交互反馈。
避免过渡属性冲突
如果元素同时有多个状态变化,建议明确指定transition-property,避免不需要的属性产生意外的过渡效果,比如只设置transition: opacity 0.3s ease;就只对透明度做过渡。
CSStransition下拉菜单动画前端动画修改时间:2026-07-13 18:03:33