Józef Podlecki
Józef Podlecki

Reputation: 11283

How to remove vertical overflow of parent element which uses flexbox

I am struggling with one styled element which wraps element that contains list of items.

html structure

<div id="root">
<div class="app"> <!-- Causes overflow - unexpected -->
  <nav class="appTopbar"></nav>
  <main class="page">
    <nav class="pageTopbar"></nav>
    <div class="container">
      <div class="left">
        <nav class="pageTopbar"></nav>
        <div class="list"> <!-- Causes overflow - expected -->
          <div class="item">Item 1</div>
          ...
        </div>
      </div>
      <div class="right"></div>
    </div>
  </main>
</div>
</div>

The problem appears when .list accumulates a lot of items.

.app, .page ,.container, .left elements are using flexbox with blox-axis direction.

display: flex;
flex-direction: column;

and all except .left set height: 100% or height: inherit

One (terrible) workaround would be to append .page with overflow: hidden; and let it go but perhaps there is better way.

Thank you for taking the trouble to help me.

Here's the example html code which causes overflow.

const list = document.querySelector(".list");

                         
let index = 0;

for(let it of new Array(100)) {
  const node = document.createElement("div");         
  const textnode = document.createTextNode(`Element ${index}`); 
  node.appendChild(textnode);
  list.appendChild(node); 
  
  index++;
}
html, body {
  height: 100%;
  margin: 0;
}

#root {
  height: inherit;
}

* {
    box-sizing: border-box;
}

.app {
  display: flex;
  flex-direction: column;
  justify-content: stretch;
  align-items: stretch;
  height: inherit;
}

.appTopbar {
  display: flex;
  align-items: center;
  flex: 0 0 50px;
  
  background: #00308F;
}

.page {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.container {
  flex: 1 1;
  display: flex;
  height: 100%;
}

.left {
  display: flex;
  flex-direction: column;
  flex: 0 1 100px;
  
  background: #7FFFD4;
}

.right {
  flex: 1 1;  
  background: #0066b2;
}

.list {
  padding: 10px;
  overflow-y: auto;
  flex: 1 1;
}
<div id="root">
  <div class="app">
    <nav class="appTopbar"></nav>
    <main class="page">
      <nav class="pageTopbar"></nav>
      <div class="container">
        <div class="left">
          <nav class="pageTopbar"></nav>
          <div class="list"></div>
        </div>
        <div class="right"></div>
      </div>
    </main>
  </div>
</div>

Upvotes: 2

Views: 166

Answers (2)

user16716458
user16716458

Reputation:

  • To remove the scroll bar of the body just as overflow:hidden; to id=root that is
    #root {height: inherit;overflow: hidden;}
    The result is shown in below snippet

const list = document.querySelector(".list");


let index = 0;

for (let it of new Array(100)) {
  const node = document.createElement("div");
  const textnode = document.createTextNode(`Element ${index}`);
  node.appendChild(textnode);
  list.appendChild(node);

  index++;
}
html,
body {
  height: 100%;
  margin: 0;
}

#root {
  height: inherit;
  overflow: hidden;
}

* {
  box-sizing: border-box;
}

.app {
  display: flex;
  flex-direction: column;
  justify-content: stretch;
  align-items: stretch;
  height: inherit;
}

.appTopbar {
  display: flex;
  align-items: center;
  flex: 0 0 50px;
  background: #00308F;
}

.page {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.container {
  flex: 1 1;
  display: flex;
  height: 100%;
}

.left {
  display: flex;
  flex-direction: column;
  flex: 0 1 100px;
  background: #7FFFD4;
}

.right {
  flex: 1 1;
  background: #0066b2;
}

.list {
  padding: 10px;
  overflow-y: auto;
  flex: 1 1;
}
<div id="root">
  <div class="app">
    <nav class="appTopbar"></nav>
    <main class="page">
      <nav class="pageTopbar"></nav>
      <div class="container">
        <div class="left">
          <nav class="pageTopbar"></nav>
          <div class="list"></div>
        </div>
        <div class="right"></div>
      </div>
    </main>
  </div>
</div>

Upvotes: 0

Anton
Anton

Reputation: 8508

If i'm right understood, you need to remove the right side scrollbar. In that case to change the height in the class .page from height:100% to height: calc(100% - 50px) where 50px is your height of the .appTopbar class.

.page {
  display: flex;
  flex-direction: column;
  height: calc(100% - 50px); /* changed */
}

const list = document.querySelector('.list');

let index = 0;

for (let it of new Array(100)) {
  const node = document.createElement('div');
  const textnode = document.createTextNode(`Element ${index}`);
  node.appendChild(textnode);
  list.appendChild(node);

  index++;
}
html,
body {
  height: 100%;
  margin: 0;
}

#root {
  height: inherit;
}

* {
  box-sizing: border-box;
}

.app {
  display: flex;
  flex-direction: column;
  justify-content: stretch;
  align-items: stretch;
  height: inherit;
}

.appTopbar {
  display: flex;
  align-items: center;
  flex: 0 0 50px;
  background: #00308f;
}

.page {
  display: flex;
  flex-direction: column;
  height: calc(100% - 50px);
}

.container {
  flex: 1 1;
  display: flex;
  height: 100%;
}

.left {
  display: flex;
  flex-direction: column;
  flex: 0 1 100px;
  background: #7fffd4;
}

.right {
  flex: 1 1;
  background: #0066b2;
}

.list {
  padding: 10px;
  overflow-y: auto;
  flex: 1 1;
}
<div id="root">
  <div class="app">
    <nav class="appTopbar"></nav>
    <main class="page">
      <nav class="pageTopbar"></nav>
      <div class="container">
        <div class="left">
          <nav class="pageTopbar"></nav>
          <div class="list"></div>
        </div>
        <div class="right"></div>
      </div>
    </main>
  </div>
</div>

Upvotes: 2

Related Questions