JSFiddle - React, Tailwind, and code Playground

by langdonx

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div ui-view>
  <app>
    <header>
      <div class="d-flex align-items-center bg-dark">
        <div class="flex-grow-1 px-3">L O G O</div>
        <div class="d-none d-sm-block px-3">
          <a href="#" class="text-white">Sign Out</a>
        </div>
        <button class="hamburger d-block d-sm-none"></button>
      </div>
    </header>
    <div class="d-flex flex-row">
      <nav class="d-none d-sm-flex flex-column bg-info">
        <div>Parent 1<div>Child 1-1</div><div>Child 1-2</div><div>Child 1-3</div></div>
        <div>Parent 2<div>Child 2-1</div><div>Child 2-2</div><div>Child 2-3</div></div>
        <div>Parent 3<div>Child 3-1</div><div>Child 3-2</div><div>Child 3-3</div></div>
        <div>Parent 4<div>Child 4-1</div><div>Child 4-2</div><div>Child 4-3</div></div>
        <div>Parent 5<div>Child 5-1</div><div>Child 5-2</div><div>Child 5-3</div></div>
        <div>Parent 6<div>Child 6-1</div><div>Child 6-2</div><div>Child 6-3</div></div>
        <div>Parent 7<div>Child 7-1</div><div>Child 7-2</div><div>Child 7-3</div></div>
        <div class="d-none d-sm-block">expand/collapse</div>
      </nav>
      <main class="d-flex flex-column flex-grow-1">
        <div class="d-flex flex-column h-100">
          <sub-nav class="d-none d-sm-flex flex-row flex-shrink-0 align-items-center pl-3">
            <div class="pr-3">Child 1-1</div>
            <div class="pr-3">Child 1-2</div>
            <div class="pr-3">Child 1-3</div>
            <div class="pr-3">Child 1-4</div>
          </sub-nav>
          
          <!-- good -->
          <div class="d-flex flex-column h-100" style="overflow: auto;">
            <div>
              content here
            </div>
            1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>
            1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>
            1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>
           ...

SCSS

// ideally I wanted the logo size and margins to determine the height of the header,
// but Firefox and Edge (which is WebKit, but equivalent to Chrome v64 from January 28)
// don't seem to handle flexbox as well as modern Chrome (currently v72) and sub nodes
// don't inherit the height correctly (app > div need to have its height explicitly
// set in Firefox and Edge)
$header-height: 50px;

html,
body {
    height: 100vh;
}

body > div[ui-view] {
    height: 100vh;
}

app {
    display: flex;
    flex-direction: column;
    height: 100vh;

    > div {
        max-height: calc(100vh - #{$header-height});
    }
}

header {
    > div {
        height: $header-height;
    }
}

nav {
   overflow-y: auto;
   overflow-x: hidden;

   @media (min-width: 576px) {
     > div > div {
       display: none;
     }
   }
   
   > div:nth-last-child(2) {
     flex-grow: 1;
   }
}

main {
    height: calc(100vh - #{$header-height});
}

sub-nav {
  background: #dfdfdf;
  height: 40px;
}

button.hamburger {
    /* @extend .navbar-toggler */
    padding: .25rem .75rem;
    font-size: 1.25rem;
    line-height: 1;
    background-color: transparent;
    border: 1px solid transparent;
    border-radius: .25rem;
}

button.hamburger:after {
    /* @extend .navbar-toggler-icon */
    display: inline-block;
    width: 1.5em;
    height: 1.5em;
    vertical-align: middle;
    content: "";
    background: no-repeat center center;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='white' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

// classes to add menus in mobile:
.fixed-menu {
    position: fixed;
    right: 0;
    padding: 1em;
    overflow: auto;
    height: calc(100vh - #{$header-height});
}

.animated-menu {
    flex-basis: calc(100vh - 56px);
    overflow: hidden;
    transition: flex-basis...

JavaScript

const navAndContentContainer = document.querySelector('app > div');
const navContainer = navAndContentContainer.querySelector('nav');

let toggled = false;

// bs4 style menu
/* document.querySelector('.hamburger').addEventListener('click', () => {
  console.log('toggling');
  navAndContentContainer.classList.toggle('flex-column');
  navAndContentContainer.classList.toggle('flex-row');
  navContainer.classList.toggle('flex-shrink-0');
  navContainer.classList.toggle('d-flex');
  navContainer.classList.toggle('d-none');
  navContainer.classList.toggle('d-sm-flex');
  navContainer.classList.toggle('animated-menu');
  navContainer.classList.toggle('initial');
  setTimeout(() => {
    navContainer.classList.toggle('initial');
    setTimeout(() => {
      navContainer.classList.toggle('expanded');
    }, 333);
  });
}); */

// mobile menu toggle adam is looking for
document.querySelector('.hamburger').addEventListener('click', () => {
    console.log('toggling');
    navAndContentContainer.classList.toggle('flex-column');
    navContainer.classList.toggle('flex-shrink-0');
    navContainer.classList.toggle('d-flex');
    navContainer.classList.toggle('fixed-menu');
});