如何使用CSS flex属性实现可点击主/子按钮响应式效果

实现思路
这个效果完全可以基于CSS Flex布局实现,只需要搭配极少量JS处理点击状态,不需要额外框架:
- 桌面端外层容器设置
display: flex实现横向排列,每个主按钮对应一组子按钮,子按钮默认隐藏,点击主按钮时给对应按钮组添加激活类,展示子按钮 - 移动端通过CSS媒体查询触发,将flex容器的排列方向改为纵向,同时强制所有子按钮默认展开,不需要点击交互
- 按钮展开、切换的过渡效果可以直接用CSS
transition实现,不需要额外动画库
可直接运行的参考代码
HTML结构
<div class="btn-wrapper"> <!-- 第一组按钮 --> <div class="btn-group"> <button class="main-btn">item1</button> <div class="sub-btn-list"> <a href="#" class="sub-btn">子选项1-1</a> <a href="#" class="sub-btn">子选项1-2</a> <a href="#" class="sub-btn">子选项1-3</a> </div> </div> <!-- 第二组按钮 --> <div class="btn-group"> <button class="main-btn">item2</button> <div class="sub-btn-list"> <a href="#" class="sub-btn">子选项2-1</a> <a href="#" class="sub-btn">子选项2-2</a> </div> </div> <!-- 第三组按钮 --> <div class="btn-group"> <button class="main-btn">item3</button> <div class="sub-btn-list"> <a href="#" class="sub-btn">子选项3-1</a> <a href="#" class="sub-btn">子选项3-2</a> <a href="#" class="sub-btn">子选项3-3</a> <a href="#" class="sub-btn">子选项3-4</a> </div> </div> </div>
CSS样式(核心基于Flex实现)
/* 基础重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 2rem; } /* 外层按钮容器:桌面端横向Flex布局 */ .btn-wrapper { display: flex; gap: 1rem; align-items: flex-start; } .btn-group { position: relative; } /* 主按钮样式 */ .main-btn { padding: 0.6rem 1.2rem; border: none; border-radius: 4px; background: #2563eb; color: #fff; cursor: pointer; font-size: 1rem; } .main-btn:hover { background: #1d4ed8; } /* 子按钮容器:默认隐藏,桌面端悬浮在主按钮下方 */ .sub-btn-list { position: absolute; top: 100%; left: 0; margin-top: 0.5rem; display: none; flex-direction: column; gap: 0.5rem; min-width: 120px; } /* 激活状态下显示子按钮 */ .btn-group.active .sub-btn-list { display: flex; } /* 子按钮样式 */ .sub-btn { padding: 0.5rem 1rem; border-radius: 4px; background: #f3f4f6; color: #1f2937; text-decoration: none; font-size: 0.9rem; } .sub-btn:hover { background: #e5e7eb; } /* 移动端适配:视口宽度小于768px时触发 */ @media (max-width: 768px) { .btn-wrapper { flex-direction: column; /* Flex改为纵向排列 */ gap: 0.8rem; } .sub-btn-list { position: static; display: flex !important; /* 强制所有子按钮显示 */ margin-top: 0.5rem; padding-left: 1rem; } }
JS交互(仅处理点击切换状态)
// 获取所有主按钮 const mainBtns = document.querySelectorAll('.main-btn') mainBtns.forEach(btn => { btn.addEventListener('click', () => { const currentGroup = btn.parentElement // 先关闭其他已经展开的按钮组 document.querySelectorAll('.btn-group.active').forEach(group => { if (group !== currentGroup) group.classList.remove('active') }) // 切换当前按钮组的激活状态 currentGroup.classList.toggle('active') }) })
可选优化点
- 如果不想写JS,可以直接用原生
<details>+<summary>标签实现点击展开效果,纯CSS就能完成,只是自定义展开箭头样式需要额外调整 - 可以给
.sub-btn-list加opacity、transform属性配合transition,实现平滑的展开收起动画 - 移动端断点可以根据你的设计需求调整,常见的断点还有640px、1024px
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

