1

I am trying to arrange a layout in which I have a right hand side bar and to the left of it in a main content area I have a list of items of fixed width arranged horizontally.

There are various numbers of these and when they get more than will fit in to the space allowed I want a horizontal scroll bar to appear.

As it happens, each item in this list also contains a header and a list of sub items which could overflow vertically. This too needs a scroll bar.

The following jsbin shows what I am attempting, but fails on the horizontal arrangement. Unfortunately the sidebar gets squashed to a small width before scroll bars appear. Also, it's clearly the whole viewport which gets the horizontal scroll bar as my main heading starts scrolling too.

https://jsbin.com/qametad/edit?html,css,output

How can I get it so the area with class "s" (see jsbin) is the one that horizontally scrolls? (It doesn't have to be "s", I had tried to get "ic" scrolling initially but failed at that so added "s" to try to separate out the flexing and the scrolling).

body {
  fullbleed height: 100vh;
}
.h {
  display: flex;
  flex-direction: row;
  justify-content: center;
  height: 30px;
}
.m {
  display: flex;
  flex-direction: row;
  height: calc(100vh - 50px);
  border: 1px solid green;
}
.ic {
  display: flex;
  flex: 1;
}
.s {
  display: flex;
  flex-direction: row;
  border: 1px solid red;
  width: 100%;
  overflow-x: auto;
}
.i {
  display: flex;
  flex-direction: column;
  width: 150px;
  border: 1px solid rebeccapurple;
  margin: 1px
}
.ih {
  height: 50px;
  self-align: center;
  border: 1px solid orange;
}
.il {
  margin: 1px;
  border: 1px solid black;
  overflow-y: auto;
}
.li {
  height: 60px;
  margin: 3px;
  border: 1px solid lawngreen;
}
.sb {
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 2px;
  border: 1px solid blue;
}
<header class="h">My Heading</header>
<section class="m">
  <div class="ic">
    <div class="s">
      <div class="i">
        <header class="ih">Item Header</header>
        <section class="il">
          <div class="li">A</div>
          <div class="li">B</div>
          <div class="li">C</div>
        </section>
      </div>
      <div class="i">
        <header class="ih">Item Header</header>
        <section class="il">
          <div class="li">A</div>
          <div class="li">B</div>
          <div class="li">C</div>
          <div class="li">C</div>
          <div class="li">C</div>
          <div class="li">C</div>
          <div class="li">C</div>
          <div class="li">C</div>
          <div class="li">C</div>
        </section>
      </div>
      <div class="i">
        <header class="ih">Item Header</header>
        <section class="il">
          <div class="li">A</div>
          <div class="li">B</div>
          <div class="li">C</div>
        </section>
      </div>
      <div class="i">
        <header class="ih">Item Header</header>
        <section class="il">
          <div class="li">A</div>
          <div class="li">B</div>
          <div class="li">C</div>
        </section>
      </div>
      <div class="i">
        <header class="ih">Item Header</header>
        <section class="il">
          <div class="li">A</div>
          <div class="li">B</div>
          <div class="li">C</div>
        </section>
      </div>
    </div>
  </div>
  <section class="sb">
    <div class="sbc">Some Content</div>
  </section </section>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
akc42
  • 4,893
  • 5
  • 41
  • 60

2 Answers2

3

An initial setting of a flex container is flex-shrink: 1 (source).

Hence, your .i elements (the columns) are allowed to shrink when the container gets smaller.

To disable shrinking use flex-shrink: 0.

.i {
  display: flex;
  flex-direction: column;
  width: 150px;
  border: 1px solid rebeccapurple;
  margin: 1px
  flex-shrink: 0; /* NEW */
}

Now the horizontal scrollbar works on your .ic container.

.ic {
  display: flex;
  flex: 1;
  overflow-x: auto;
}

revised demo

More details here: What are the differences between flex-basis and width?

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    thanks - in fact I just tried it on a clone of the jsbin above and I can remove the "s" element now – akc42 Nov 11 '16 at 07:10
1

This should help you.Please check the out put on the fullscreen mode

check the following snippet

.maincontainer{
  display:flex;
  border:1px solid green;
  overflow:auto;
}

.sub-item-1{
  display:flex;
  border:1px solid red;
flex:none;
  width:100%;
  margin:20px;
}

.sub-item-2{
  margin:20px;
  border:1px solid  red;
  flex:1;
  padding:90px;
}
.content{
  border:1px solid gray;
  margin:10px;
  
}
.content-item{
  border:1px solid pink;
  margin:20px;
  height:20px;
  width:20px;
  text-align:center;
  padding:50px;
}
<header class="h">My Heading</header>
<div class="maincontainer">
  <section class=sub-item-1>
         <div class="content">
        <header class="content-header">Item Header</header>
      
          <div class="content-item">A</div>
          <div class="content-item">B</div>
          <div class="content-item">C</div>
        
      </div>
      <div class="content">
        <header class="content-header">Item Header</header>

          <div class="content-item">A</div>
          <div class="content-item">B</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
          <div class="content-item">C</div>
      </div>
      <div class="content">
        <header class="content-header">Item Header</header>

          <div class="content-item">A</div>
          <div class="content-item">B</div>
          <div class="content-item">C</div>
       
      </div>
      <div class="content">
        <header class="content-header">Item Header</header>
   
          <div class="content-item">A</div>
          <div class="content-item">B</div>
          <div class="content-item">C</div>
     
      </div>
      <div class="content">
        <header class="content-header">Item Header</header>
     
          <div class="content-item">A</div>
          <div class="content-item">B</div>
          <div class="content-item">C</div>
   
      </div>
  </section>
  <section class="sub-item-2">
      <div class="sub-item-content">Some Content</div>
    </section
</div>

Hope it helps

Geeky
  • 7,420
  • 2
  • 24
  • 50