I have this project I've been working on as part of a roadmap to web development, and I developed this sidebar that has an inner scrolling list. In Chrome, the inner list scrolls, but in Firefox, each of its children scrolls independently. The code, without extra bits is the following:
See Codepen: https://codepen.io/rins6618/pen/yLmJxRy (I cannot seem to get snippets).
<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;
}
I know I can solve this by having one <ul>
element. This is not the point. I want to know the why behind the fact that Chrome and Firefox are different on such a basic rule. What if I had to keep two elements from scrolling and I had no other choice? Keep in mind the CSS rules make sure the <ul>
shouldn't be scrollable, yet Firefox still makes them scrollable. (relevant CSS rule below);
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: hidden;
overflow-y: visible;
}
Differences:
Chrome
Firefox
There was a question involving sidebars in StackOverflow, but not pertinent to what I am having trouble with.
The difference appears to be that Firefox is not respecting min-height: fit-content
correctly. In Chrome, the ul's height is set to that of its content, so there's no overflow and no need for scrollbars. In Firefox, the ul's height is shrunk by the default flex-shrink:1
, so the ul's are shorter than their content, the content overflows and Firefox accordingly shows the scrollbars.
Also with
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: hidden;
overflow-y: visible;
}
overflow-x: hidden;
and overflow-y: visible;
don't mix. Consequently the overflow-y: visible;
is automatically converted to overflow-y: auto;
A couple of ways forward. One is to add
#scrollable-sidebar ul {
flex-shrink: 0;
}
so that the ul's aren't shrunk and their content doesn't overflow.
Another is to change the overflow rules to
#scrollable-sidebar > * {
padding: 0 1rem;
overflow-x: clip; /* i.e. use clip, not hidden */
overflow-y: visible;
}
so the ul's are not scroll containers.