2

I followed the example code here to put a dismissible drawer under a top app bar but it doesn't work.

Here is what I tried:

// Note: these styles do not account for any paddings/margins that you may need.
body {
  display: flex;
  height: 100vh;
}

.mdc-drawer-app-content {
  flex: auto;
  overflow: auto;
  position: relative;
}

.main-content {
  overflow: auto;
  height: 100%;
}

.app-bar {
  position: absolute;
}

// only apply this style if below top app bar
.mdc-top-app-bar {
  z-index: 7;
}
<!doctype html>
<html lang="en-US">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Default Page Title</title>
  <link rel="stylesheet" type="text/css" href="drawer.css">

  <!--[if lt IE 9]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Test</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900&display=swap">
  <link rel="stylesheet" href="https://unpkg.com/material-components-web@4.0.0/dist/material-components-web.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  <link rel="stylesheet" href="./drawer.css">

</head>
<header class="mdc-top-app-bar app-bar" id="app-bar">
  <div class="mdc-top-app-bar__row">
    <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
      <button class="mdc-top-app-bar__navigation-icon mdc-icon-button material-icons" href="#">menu</button>
      <span class="mdc-top-app-bar__title">Dismissible Drawer</span>
    </section>
  </div>
</header>
<aside class="mdc-drawer mdc-drawer--dismissible mdc-top-app-bar--fixed-adjust">
  <div class="mdc-drawer__content">
    <div class="mdc-list">
      <a class="mdc-list-item mdc-list-item--activated" href="#" aria-current="page">
        <i class="material-icons mdc-list-item__graphic" aria-hidden="true">inbox</i>
        <span class="mdc-list-item__text">Inbox</span>
      </a>
      <a class="mdc-list-item" href="#">
        <i class="material-icons mdc-list-item__graphic" aria-hidden="true">send</i>
        <span class="mdc-list-item__text">Outgoing</span>
      </a>
      <a class="mdc-list-item" href="#">
        <i class="material-icons mdc-list-item__graphic" aria-hidden="true">drafts</i>
        <span class="mdc-list-item__text">Drafts</span>
      </a>
    </div>
  </div>
</aside>

<div class="mdc-drawer-app-content mdc-top-app-bar--fixed-adjust">
  <main class="main-content" id="main-content">
    App Content
  </main>
</div>

<body>

  <script src="https://unpkg.com/material-components-web@4.0.0/dist/material-components-web.min.js"></script>

  <script>
    // Instantiate MDC Drawer
    const drawerEl = document.querySelector('.mdc-drawer');
    const drawer = new mdc.drawer.MDCDrawer.attachTo(drawerEl);

    // Instantiate MDC Top App Bar (required)
    const topAppBarEl = document.querySelector('.mdc-top-app-bar');
    const topAppBar = new mdc.topAppBar.MDCTopAppBar.attachTo(topAppBarEl);

    topAppBar.setScrollTarget(document.querySelector('.main-content'));
    topAppBar.listen('MDCTopAppBar:nav', () => {
      drawer.open = !drawer.open;
    });
  </script>
</body>

</html>
Thatkookooguy
  • 6,669
  • 1
  • 29
  • 54

2 Answers2

0

In order to have the header on the side of the dismissble drawer, you need the following structure:

// Instantiate MDC Drawer
const drawerEl = document.querySelector('.mdc-drawer');
const drawer = new mdc.drawer.MDCDrawer.attachTo(drawerEl);

// Instantiate MDC Top App Bar (required)
const topAppBarEl = document.querySelector('.mdc-top-app-bar');
const topAppBar = new mdc.topAppBar.MDCTopAppBar.attachTo(topAppBarEl);

topAppBar.setScrollTarget(document.querySelector('.main-content'));
topAppBar.listen('MDCTopAppBar:nav', () => {
  drawer.open = !drawer.open;
});
// Note: these styles do not account for any paddings/margins that you may need.
body {
  display: flex;
  height: 100vh;
}

.mdc-drawer-app-content {
  flex: auto;
  overflow: auto;
  position: relative;
}

.main-content {
  overflow: auto;
  height: 100%;
}

.app-bar {
  position: absolute;
}

// only apply this style if below top app bar
.mdc-top-app-bar {
  z-index: 7;
}
<!-- IMPORTS -->

<link rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<link rel="stylesheet"
      href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900&display=swap">
<link rel="stylesheet"
      href="https://unpkg.com/material-components-web@4.0.0/dist/material-components-web.min.css">
<link rel="stylesheet"
      href="https://fonts.googleapis.com/icon?family=Material+Icons">

<!-- CONTENT -->

<aside class="mdc-drawer mdc-drawer--dismissible">
  <div class="mdc-drawer__content">
    <div class="mdc-list">
      <a class="mdc-list-item mdc-list-item--activated"
         href="#"
         aria-current="page">
        <i class="material-icons mdc-list-item__graphic"
           aria-hidden="true">inbox</i>
        <span class="mdc-list-item__text">Inbox</span>
      </a>
      <a class="mdc-list-item"
         href="#">
        <i class="material-icons mdc-list-item__graphic"
           aria-hidden="true">send</i>
        <span class="mdc-list-item__text">Outgoing</span>
      </a>
      <a class="mdc-list-item"
         href="#">
        <i class="material-icons mdc-list-item__graphic"
           aria-hidden="true">drafts</i>
        <span class="mdc-list-item__text">Drafts</span>
      </a>
    </div>
  </div>
</aside>

<div class="mdc-drawer-app-content">
  <header class="mdc-top-app-bar app-bar"
          id="app-bar">
    <div class="mdc-top-app-bar__row">
      <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
        <button class="mdc-top-app-bar__navigation-icon mdc-icon-button material-icons"
                href="#">menu</button>
        <span class="mdc-top-app-bar__title">Dismissible Drawer</span>
      </section>
    </div>
  </header>
  <main class="main-content"
        id="main-content">
    App Content
  </main>
</div>

<!-- IMPORTS -->
<script src="https://unpkg.com/material-components-web@4.0.0/dist/material-components-web.min.js"></script>

Changes to make this work:

  • First, you don't need the class mdc-top-app-bar--fixed-adjust since we won't need to adjust the items anymore
  • Next, move the header itself into the app content (here, called mdc-drawer-app-content).

I looked at this example's HTML in order to see how they did it themselves

Thatkookooguy
  • 6,669
  • 1
  • 29
  • 54
0

Here is the custom CSS that worked for me. Mine is a permanent drawer, so you may need some JS to apply the changes dynamically if you want the drawer to be dismissible, but it solves the layout issues.

First, the critical bit:

.mdc-drawer {
  position: fixed;
  top: 64px;
}

Since the drawer is now fixed-position, it no longer affects the layout, and the top bar sees it has room to fill the whole width of the page. Pushing the drawer down 64 px keeps it from covering the top bar.

However, this has some side-effects that have to be dealt with. First, most obviously, your main content does the same thing the top bar does--it thinks it has room to fill the whole page, so it gets lost behind the drawer. This is fixable by simply pushing it over:

main {
  margin-left: 255px;
}

Second, you will notice that if you resize the viewport, the drawer doesn't show a scroll bar when it should, and when the scroll bar does appear, it won't go all the way to the bottom. This is because you've pushed the bottom of the drawer down off the page.

To fix this, make the drawer's scrollable content shorter:

.mdc-drawer__content {
  height: calc(100% - 128px);
}

(I would have expected it to be 100% - 64px, but for some reason it needs 128. I haven't figured out why.)

Dausuul
  • 154
  • 7