Tengo una barra lateral que contiene 2 paneles. Cuando cambio el tamaño de la ventana verticalmente, quiero que el panel superior cambie de tamaño dinámicamente y que el panel inferior permanezca en un tamaño fijo. Cuando la altura total de la barra lateral es menor que la de ambos paneles, quiero que el panel superior se reduzca más que su contenido y se pueda desplazar.
El comportamiento esperado es el mismo que el de la barra lateral de VS Code.
Actualmente, al cambiar el tamaño, el panel superior "empuja" el panel inferior hacia abajo.
document.addEventListener("DOMContentLoaded", () => { const listItem = document.querySelector(".top-panel .list-item"); for (let i = 0; i < 25; i++) { listItem.parentNode.appendChild(listItem.cloneNode(true)); } }); html, body { margin: 0; } .main { margin-left: 12rem; } .sidebar { position: fixed; top: 0; left: 0; bottom: 0; width: 12rem; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid #454545; } .top-panel { flex-shrink: 1; display: flex; flex-direction: column; } .bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; } .header { background-color: #ababbc; font-weight: 700; } .panel-top .list { flex-shrink: 1; overflow-y: auto; } .panel-bottom .list { flex-shrink: 0; } .list-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } <aside class="sidebar"> <div class="top-panel"> <div class="header">Top panel</div> <div class="list"> <div class="list-item"><span>https://example.com/users/helloworld</span></div> <!-- copied 25 times in the JS --> </div> </div> <div class="bottom-panel"> <div class="header">Bottom panel</div> <div class="list"> <div class="list-item"><span>Lorem</span></div> <div class="list-item"><span>Ipsum</span></div> </div> </div> </aside> <main class="main">Main content</main>Use "Página completa" en el fragmento para ver el comportamiento de cambio de tamaño.
En su panel superior agregue esto:
.top-panel { overflow-y: auto; }Básicamente, debe decirle a ese div cómo comportarse cuando alcanza el nivel más pequeño posible mientras muestra todos sus contenidos.
flex-shrink: 1 ayuda a hacerle saber que el panel superior debe encogerse y que el panel inferior no, pero una vez que se encoge a la altura de sus hijos, debe informarle que puede encogerse más que que. Agregar overflow-y: auto hará eso.
Eso debería solucionarlo :)
Agregar la propiedad overflow-y a la clase del panel superior debería funcionar. Luego, asígnele el valor de automático para que se desplace si el contenido es demasiado grande para la altura del div.
document.addEventListener("DOMContentLoaded", () => { const listItem = document.querySelector(".top-panel .list-item"); for (let i = 0; i < 25; i++) { listItem.parentNode.appendChild(listItem.cloneNode(true)); } }); html, body { margin: 0; } .main { margin-left: 12rem; } .sidebar { position: fixed; top: 0; left: 0; bottom: 0; width: 12rem; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid #454545; } .top-panel { flex-shrink: 1; display: flex; flex-direction: column; overflow-y: auto; } .bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; } .header { background-color: #ababbc; font-weight: 700; } .panel-top .list { flex-shrink: 1; overflow-y: auto; } .panel-bottom .list { flex-shrink: 0; } .list-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } <aside class="sidebar"> <div class="top-panel"> <div class="header">Top panel</div> <div class="list"> <div class="list-item"><span>https://example.com/users/helloworld</span></div> <!-- copied 25 times in the JS --> </div> </div> <div class="bottom-panel"> <div class="header">Bottom panel</div> <div class="list"> <div class="list-item"><span>Lorem</span></div> <div class="list-item"><span>Ipsum</span></div> </div> </div> </aside> <main class="main">Main content</main>Puede agregar overflow-y: auto al panel superior, para mostrar solo la barra de desplazamiento cuando sea necesario.
También puede agregar un tamaño fijo al panel inferior agregando height: 100px por ejemplo. El panel superior se encogerá automáticamente para adaptarse al espacio restante.
document.addEventListener("DOMContentLoaded", () => { const listItem = document.querySelector(".top-panel .list-item"); for (let i = 0; i < 25; i++) { listItem.parentNode.appendChild(listItem.cloneNode(true)); } }); html, body { margin: 0; } .main { margin-left: 12rem; } .sidebar { position: fixed; top: 0; left: 0; bottom: 0; width: 12rem; display: flex; flex-direction: column; justify-content: space-between; border-right: 1px solid #454545; } .top-panel { overflow-y: auto; flex-shrink: 1; display: flex; flex-direction: column; } .bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; } .header { background-color: #ababbc; font-weight: 700; } .panel-top .list { flex-shrink: 1; overflow-y: auto; } .panel-bottom .list { flex-shrink: 0; } .list-item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } <aside class="sidebar"> <div class="top-panel"> <div class="header">Top panel</div> <div class="list"> <div class="list-item"><span>https://example.com/users/helloworld</span></div> <!-- copied 25 times in the JS --> </div> </div> <div class="bottom-panel"> <div class="header">Bottom panel</div> <div class="list"> <div class="list-item"><span>Lorem</span></div> <div class="list-item"><span>Ipsum</span></div> </div> </div> </aside> <main class="main">Main content</main>