Flex布局中固定侧边栏,实现内容区横竖滚动的解决方案
基于Flexbox实现固定侧边栏+内容区双向滚动的解决方案
我用CSS Flexbox做了一个侧边栏布局,需求是固定侧边栏位置,同时让主内容区域支持垂直和水平滚动。但目前遇到两个问题:
第一种尝试:父容器设overflow: hidden
此时内容容器设overflow:auto只能实现垂直滚动,水平滚动失效。
对应代码:
body { background-color: lightgrey; } .container { display: flex; height: 100vh; width: 720px; margin: auto; border: 1px black solid; overflow: hidden; } .sidebar { background-color: #f00; border: 1px red solid; flex-basis: 250px; flex-grow: 0; flex-shrink: 0; } .content { display: flex; flex: 1 0 auto; overflow: auto; } .wide-content { width: 800px; background-color: lightpink; overflow: auto; }
<div class="container"> <div class="sidebar"> Sidebar </div> <div class="content"> <div class="wide-content"> <p> "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains." </p> <p> "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains." </p> </div> </div> </div>
第二种尝试:父容器设overflow: auto
此时内容区能支持垂直和水平滚动,但侧边栏会跟着滚动,无法固定位置。
对应代码:
body { background-color: lightgrey; } .container { display: flex; height: 100vh; width: 720px; margin: auto; border: 1px black solid; overflow: auto; } .sidebar { background-color: #f00; border: 1px red solid; flex-basis: 250px; flex-grow: 0; flex-shrink: 0; } .content { display: flex; flex: 1 0 auto; overflow: auto; } .wide-content { width: 800px; background-color: lightpink; overflow: auto; }
<div class="container"> <div class="sidebar"> Sidebar </div> <div class="content"> <div class="wide-content"> <p> "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains." </p> <p> "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains." </p> </div> </div> </div>
可行解决方案
问题根源是内容容器的display: flex——Flex容器默认会限制子元素宽度,导致水平滚动无法触发。只需修改.content的样式,移除display: flex,并添加min-width: 0确保内容区能正常收缩:
.content { flex: 1 0 auto; overflow: auto; min-width: 0; /* 避免内容区撑爆父容器,确保滚动正常触发 */ }
修改后的完整CSS:
body { background-color: lightgrey; } .container { display: flex; height: 100vh; width: 720px; margin: auto; border: 1px black solid; overflow: hidden; /* 父容器隐藏溢出,交给内容区处理滚动 */ } .sidebar { background-color: #f00; border: 1px red solid; flex-basis: 250px; flex-grow: 0; flex-shrink: 0; } .content { flex: 1 0 auto; overflow: auto; min-width: 0; } .wide-content { width: 800px; background-color: lightpink; }
最终效果:
- 侧边栏固定在左侧,不会随滚动移动
- 内容区同时支持垂直和水平滚动
内容的提问来源于stack exchange,提问作者emcee
相关产品推荐
相关产品推荐

