0

I noticed something weird when using min-width on a flex grandchild.

I'm trying to create a flex layout consisting of a side-menu and content: [ Side | Content ] However, I want a child of Content to be scrollable. When I add min-width to said element, the flex wraps, making the Content wrap under Side instead of being next to each other.

What I expect to happen is the grandchild gets a horizontal scroll due to parent having overflow: scroll in combination of grandchild min-width > parent's.

What happenes is that the flex content wraps.

What causes this, and how can I keep them on the same row with a scroll on grandchild without it wrapping?

// All JS just for DEMO purposes - not related to question
document.querySelector('button').addEventListener('click', () => {
  const element = document.querySelector('.calendar > div');
  
  element.style.minWidth = element.style.minWidth === 'initial' ? '1000px' : 'initial';
})
.container {
  max-width: 550px;
}

.wrapper {
  display: flex;
  flex-wrap: wrap;
  flex: 1 1 auto;
}

.col {
  flex-basis: 0;
  flex-grow: 1;
  max-width: 100%;
  background: cornflowerblue;
}

nav.col {
  background: salmon;
}

.calendar {
  overflow: auto;
}

/* Breaks wrap */
.calendar > div {
  min-width: 1000px;
}
<!-- START Just for demo -->
<button>Toggle element min-width</button>
<!-- END Just for demo -->

<div class="container">
  <div class="wrapper">
    <nav class="col">
      <ul>
        <li>Some navigation</li>
        <li>Some navigation</li>
        <li>Some navigation</li>
      </ul>
    </nav>

    <div class="col">
      <h1>page title</h1>
      <section class="calendar">
        <div>asdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasd</div>
      </section>
    </div>
  </div>
</div>
Sølve T.
  • 4,159
  • 1
  • 20
  • 31

2 Answers2

1

You can update your code like below:

// All JS just for DEMO purposes - not related to question
document.querySelector('button').addEventListener('click', () => {
  const element = document.querySelector('.calendar > div');
  
  element.style.minWidth = element.style.minWidth === 'initial' ? '1000px' : 'initial';
})
.container {
  max-width: 550px;
}

.wrapper {
  display: flex;
  /*flex-wrap: wrap;  remove */
  flex: 1 1 auto;
}

.col {
  /*flex-basis: 0; remove */
  flex-grow: 1;
  max-width: 100%;
  min-width:0; /* add */
  background: cornflowerblue;
}
.col:nth-child(1) {
  flex-shrink:0; /* disable the shrink for the first one */
}
nav.col {
  background: salmon;
}

.calendar {
  overflow: auto;
}

/* Breaks wrap */
.calendar > div {
  min-width: 1000px;
}
<!-- START Just for demo -->
<button>Toggle element min-width</button>
<!-- END Just for demo -->

<div class="container">
  <div class="wrapper">
    <nav class="col">
      <ul>
        <li>Some navigation</li>
        <li>Some navigation</li>
        <li>Some navigation</li>
      </ul>
    </nav>

    <div class="col">
      <h1>page title</h1>
      <section class="calendar">
        <div>asdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasd</div>
      </section>
    </div>
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Awesome! This is just what I was hoping to achieve. I understand all but the "min-width:0" part. Why does this "magically" fix it? – Sølve T. Sep 15 '21 at 15:29
  • 1
    @SølveTornøe here is a detailed explanation around the min-width: https://stackoverflow.com/a/36247448/8620333 – Temani Afif Sep 15 '21 at 15:30
0

You have set .wrapper to flex-wrap: wrap; so it will wrap around if more space is needed, which is the case when you set the minimum width too high.

Am I missing something or why do you set flex-wrap to wrap if you explicitly do not want it to wrap around?

noviolence
  • 156
  • 1
  • 1
  • 8