我一直在做这个项目,作为网络开发路线图的一部分,我开发了这个带有内部滚动列表的侧边栏。在 Chrome 中,内部列表滚动,但在 Firefox 中,其每个子列表独立滚动。没有额外位的代码如下:
参见Codepen:https://codepen.io/rins6618/pen/yLmJxRy(我似乎无法获取片段)。
<nav class="flex" id="sidebar">
<header>
<button id="project-selector" class="flex">
<div id="project-icon" class="flex">B</div>
<div id="project-name" class="flex">Blank Project</div>
</button>
</div>
<iconify-icon icon="material-symbols:side-navigation" style=" font-size: 2rem;" class="toggle-btn"></iconify-icon>
</header>
<div class="flex" id="scrollable-sidebar">
<ul class="flex listing">
<li>
<h3> Projects</h3>
</li>
<li>
<button class="flex">
<span class="flex">Create new project...</span>
</button>
</li>
<li>
<button class="flex">
<span class="flex">Delete a project...</span>
</button>
</li>
</ul>
<ul class="flex listing">
<li>
<h3>This project</h3>
</li>
<li>
<button class="flex">
<span class="flex">Rename this project...</span>
</button>
</li>
<li>
<button class="flex">
<span class="flex">View notes...</span>
</button>
</li>
<li>
<button class="flex">
<span class="flex">View due dates...</span>
</button>
</li>
<li>
<button class="flex">
<span class="flex">Change project color...</span>
</button>
</li>
</ul>
</div>
<footer>
<ul class="flex listing">
<li>
<button class="flex">
<span class="flex">About</span>
</button>
</li>
<li>
<button class="flex">
<span class="flex">Settings</span>
</button>
</li>
</ul>
</footer>
</nav>
CSS:
* {
box-sizing: border-box;
margin: 0;
}
:root {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
html, body {
height: 100%;
width: 100%;
background-color: #efefef;
}
main {
margin-left: 30rem;
}
li {
list-style: none;
}
#sidebar {
flex-direction: column;
margin: 0.5rem 0.5rem 0 0;
width: 30rem;
height: 100dvh;
padding: 1rem;
position: fixed;
z-index: 2;
top: 0;
left: 0;
background-color: #fff;
overflow-x: hidden;
overflow-y: hidden;
border-radius: 0rem 1rem 0rem 0rem;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
#scrollable-sidebar {
flex: 1;
border-top: 0.25rem solid #eee;
border-bottom: 0.25rem solid #eee;
flex-direction: column;
overflow-y: scroll;
scrollbar-width: none;
-ms-overflow-style: none;
}
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: hidden;
overflow-y: visible;
}
#scrollable-sidebar > *:first-child {
border-top: none;
}
#scrollable-sidebar::-webkit-scrollbar {
display: none;
}
#sidebar header {
transition: background-color .3s;
height: 5rem;
position: relative;
overflow: visible;
}
#sidebar:first-child {
border-top-right-radius: 1rem;
}
#project-selector {
z-index: 3;
background: none;
border: none;
font-size: inherit;
transition: background-color .1s;
transition: box-shadow .05s;
position: relative;
padding: 1rem;
cursor: pointer;
align-items: center;
gap: 1ch;
width: 75%;
border-radius: 0.5rem;
box-shadow: none;
}
#project-selector > * {
pointer-events: none;
}
#project-selector:hover {
background-color: #eee;
}
#project-icon {
margin-right: 1ch;
flex-shrink: 0;
background: rgb(163,163,163);
background: linear-gradient(135deg, rgba(163,163,163,1) 0%, rgba(58,58,58,1) 100%);
border-radius: 5%;
aspect-ratio: 1 / 1;
width: 2rem;
align-items: center;
justify-content: center;
font-weight: 800;
color: #fff;
}
#project-name {
font-size: 1.25rem;
max-width: 18ch;
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
#scrollable-sidebar ul {
min-height: fit-content;
flex-direction: column;
margin: 0 1rem;
border-top: 1px solid #eee;
padding: 1rem;
gap: 1rem;
}
#sidebar li > h3 {
padding: 0.5rem 0 1rem 0;
user-select: none;
}
#sidebar li > button {
cursor: pointer;
width: 100%;
transition: color .3s;
transition: background-color .3s;
color: #444;
border: none;
background-color: transparent;
align-items: center;
padding: 0.75rem;
border-radius: 1rem;
font-size: 1.25rem;
gap: 2ch;
}
#sidebar li > button:hover {
background-color: #eee;
color: #000;
}
#sidebar li > button > span {
text-overflow: ellipsis;
white-space: nowrap;
}
#sidebar > footer > ul {
margin: 0 1rem;
min-height: fit-content;
flex-direction: column;
padding: 1rem;
}
我知道我可以通过一个
<ul>
元素来解决这个问题。这不是重点。我想知道 Chrome 和 Firefox 在这样一个基本规则上不同的背后的为什么。如果我必须阻止两个元素滚动并且我别无选择怎么办?请记住 CSS 规则确保 <ul>
不应该是可滚动的,但 Firefox 仍然使它们可滚动。 (相关CSS规则如下);
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: hidden;
overflow-y: visible;
}
差异:
铬
火狐
StackOverflow 中有一个涉及侧边栏的问题,但与我遇到的问题无关。
差异似乎在于 Firefox 没有正确尊重
min-height: fit-content
。在 Chrome 中,ul 的高度设置为其内容的高度,因此不会溢出,也不需要滚动条。在 Firefox 中,ul 的高度默认会缩小 flex-shrink:1
,因此 ul 比内容短,内容会溢出,Firefox 会适当显示滚动条。
还有
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: hidden;
overflow-y: visible;
}
overflow-x: hidden;
和 overflow-y: visible;
不能混合。因此 overflow-y: visible;
自动转换为 overflow-y: auto;
有几种前进的方式。一是添加
#scrollable-sidebar ul {
flex-shrink: 0;
}
这样 ul 就不会缩小,内容也不会溢出。
另一个是将溢出规则改为
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: clip; /* i.e. use clip, not hidden */
overflow-y: visible;
}
所以 ul 不是滚动容器。