0

I am working on an Angular (8.2.13) + Bootstrap (4.3.1) application able to display different pages, some of which have tabs and some other don't. I am facing various issues related to which part of the screen gets a scrollbar when content becomes larger than the screen.

If possible I would like to find a bootstrap-only solution to this problem (no extra CSS). If not, a solution that adds the least amount of extra CSS possible.

Here is the structure of the page:

  1. Navbar
    • Should always be on the left of the screen (never move when scrolling on the content).
    • Uses the minimum possible width based on its content.
    • Uses the height of its container.
  2. TabBar
    • Should always be at the top of the screen (never move when scrolling on the content).
    • Uses the minimum possible height based on its content.
    • Uses the width of its container.
  3. Content
    • Should scroll vertically when height is higher than its container.
    • Uses all the remaining width and height in its container.

I made a minimal example to reproduce the issue:

Code Example

JSFiddle Exemple

HTML

<div class="d-flex h-100">
  <nav class="navbar flex-column justify-content-start navbar-dark bg-dark h-100 overflow-auto flex-nowrap w-100">
    <div class="navbar-nav">
      <a class="nav-item nav-link pointer">Navbar</a>
    </div>
  </nav>
  <div class="flex-grow-1 d-flex">
    <div class="col overflow-auto p-3">
      <div class="myContainer">
        <ul class="nav nav-tabs">
          <li class="nav-item">
            <a class="nav-link">Tab 1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 3</a>
          </li>
        </ul>
        <div class="tab-content">
          <div class="tab-pane active">
            <div class="flex-item">
              <div class="row h-10">
                <div class="col overflow-auto">
                  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Expected behavior

  • On pages that do not have tabs, vertical scroll should happen when necessary on the right part of the screen (everything but the Navbar should scroll).
  • On pages that do have tabs, vertical scroll should happen when necessary on the container only (Navbar and TabBar should not move).

Observed behavior

  • Scroll works as intended when there is no tabs involved => OK.
  • Scroll applies to the right part of the screen when tabs are there too (meaning the TabBar dissapear when you scroll down) => NOK.

enter image description here

Things I tried that did not work / are not acceptable

  • Setting height: 80vh; (or any other fixed height) on <div class="col overflow-auto"> did work in my application, but it loses the dynamic vertical size on the content and is not bootstrap only (Dynamic vertical size is needed because the TabBar can change height dynamically).
  • According to this topic, setting min-height: 0; on every parent tag of the one supposed to scroll using flex behavior should do the trick. It did not work in my case, plus it is not bootstrap only.

EDIT: Updated bootstrap version in JSFiddle example to match the version used in my application.

Flo
  • 59
  • 5

2 Answers2

0

Try this

body {
  overflow: hidden;
}
.inner {
  overflow-y: scroll;
  height: 100vh;
  padding-bottom: 130px;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>

<div class="d-flex">
  <nav class="navbar flex-column justify-content-start navbar-dark bg-dark overflow-auto flex-nowrap">
    <div class="navbar-nav" style="height: 100vh;">
      <a class="nav-item nav-link pointer">Navbar</a>
    </div>
  </nav>
  <div class="flex-grow-1 d-flex">
    <div class="col overflow-auto p-3">
      <!-- Here the container can be replaced by several others based on elements selected in the Navbar. For simple container the "overflow-auto" of the parent div is required to get the appropriate vertical scroll. Also in my application this "overflow-auto" allows to scroll vertically in this block only, but in this example the scroll is on the whole page (navbar on the left moved when scrolling, but it should be static) -->
      <div class="myContainer">
        <ul class="nav nav-tabs">
          <li class="nav-item">
            <a class="nav-link">Tab 1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 3</a>
          </li>
        </ul>
        <div class="tab-content">
          <div class="tab-pane active">
            <div class="flex-item">
              <div class="row">
                <!-- I wish for vertical scroll to happen on the following col and not at the "myContainer" level. I also want the content of one tab to take all remaining space on screen. So forcing the height on this col with style="height: 85vh" does work, but is not what I am looking for. -->
                <div class="col overflow-auto inner">
                  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
akhtarvahid
  • 9,445
  • 2
  • 26
  • 29
  • So a few things about this solution: 1) The scrollbar is still visible even when it's unused. 2) The bottom of the scrollbar is out of screen. 3) Because of the static "magic value" of `padding-bottom: 130px;`, the full text may not be always visible on screen when scrolling all the way down (especially noticeable if you stretch the window horizontally to the point where the 3 tabs start to stack on top of each other). – Flo Nov 13 '20 at 14:25
0

After discussion with other people we came up with a satisfying solution for this problem:

Code Example

JSFiddle example

HTML

<body style="height: 100vh;">
<div id="app-container" class="d-inline-flex h-100 justify-content-stretch">
  <nav class="navbar justify-content-start navbar-dark bg-dark">
    <div class="navbar-nav">
      <a class="nav-item nav-link pointer">Navbar</a>
    </div>
  </nav>
  <div class="d-flex">
    <div class="col p-3">
      <div class="myContainer h-100 d-flex flex-column">
        <ul class="nav nav-tabs">
          <li class="nav-item">
            <a class="nav-link">Tab 1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link">Tab 3</a>
          </li>
        </ul>
        <div class="tab-content flex-grow-1 overflow-auto">
          <div class="tab-pane active">
            <div class="flex-item">
              <div class="row h-10">
                <div class="col">
                  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</body>
Flo
  • 59
  • 5