Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material design expandable drawer

I am developing a web application using Material Design Lite.

One of the requirements is this: A sidebar exists such that by default, it will display the icons of the menu items at a smaller width (say 50px). Clicking on the menu (hamburger) icon then expands the drawer to a larger size and shows not only the icons but the text beside them. Here is an example of what I want to achieve:

Default: enter image description here

Expand: enter image description here

Here is my current HTML:

<body>
    <!-- Always shows a header, even in smaller screens. -->
    <div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
        <header class="mdl-layout__header">
            <div class="mdl-layout__header-row">
                <button class="mdl-button mdl-js-button mdl-button--icon">
                    <i class="material-icons">menu</i>
                </button>
                <!-- Add spacer, to align navigation to the right -->
                <div class="mdl-layout-spacer"></div>
                <!-- Navigation. We hide it in small screens. -->
                <button class="mdl-button mdl-js-button mdl-button--icon">
                    <i class="material-icons">apps</i>
                </button>
            </div>
        </header>
        <div class="mdl-layout__drawer">
            <span class="mdl-layout-title"></span>
            <nav class="mdl-navigation">
                <a class="mdl-navigation__link" href="">
                    <i class="material-icons md-dark">account_circle</i>
                    <span>Account</span>
                </a>
                <a class="mdl-navigation__link" href="">
                    <i class="material-icons md-dark">home</i>
                    <span>Home</span>
                </a>
                <a class="mdl-navigation__link" href="">
                    <i class="material-icons md-dark">assignment</i>
                    <span>Reports</span>
                </a>
                <a class="mdl-navigation__link" href="">
                    <i class="material-icons md-dark">input</i>
                    <span>Logout</span>
                </a>
            </nav>
        </div>
        <main class="mdl-layout__content">
            <div class="page-content">
                <!-- Your content goes here -->
                @RenderBody()
            </div>
        </main>
    </div>
</body>

Is there a good/correct way of doing this? I was wondering how this could be done and haven't come up with a good solution.

like image 655
arazzy Avatar asked Oct 23 '25 17:10

arazzy


1 Answers

Have a look at this answer. I think it's a good approach to achieving this effect.

You can then just drop the polyfill in and write in your CSS something like:

.mdl-navigation .material-icons {
    opacity: 0;
    transition: 250ms opacity ease-in-out;
}

.mdl-navigation[min-width~="200px"] .material-icons {
    opacity: 1;
}

If you think a polyfill is too much to add just this functionality I can think of one other way that doesn't use any javascript, but it wouldn't be as flexible with regards to how you animate the showing/hiding should you want to animate it. It involves overlapping the main content area over the drawer. Give me a moment and I'll mock up a demo.

EDIT

Here's what I was thinking as far as a non-js approach (still requires some for the toggling of the is-expanded class): https://jsfiddle.net/damo_s/27u4huzf/2/

.mdl-layout__drawer {
  transform: translateX(0);
  z-index: 1;
  box-shadow: none;
  border-right: 0;

  &.is-expanded {
    + .mdl-layout__header {
      margin-left: 240px!important;

      &:before {
        width: 0;
        left: 200px;
      }
    }

    ~ .mdl-layout__content {
      margin-left: 240px!important;

      &:before {
        width: 0;
        left: 200px;
      }
    }
  }
}

.mdl-layout__header,
.mdl-layout__content {
  margin-left: 55px!important;
}

.mdl-layout__header {
  z-index: 2;

  &:before {
    background: #fff;
    content: '';
    display: block;
    position: absolute;
    width: 15px;
    height: 100%;
    left: 40px;
  }
}

.mdl-layout__header-row {
    padding: 0 16px 0 22px;
}

.mdl-layout__content {
  background: #878787;
}

.mdl-layout__drawer-button {
  display: none;
}

.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover {
    background-color: transparent;
}

On looking at it now, I don't think it's a very good approach (for a number of reasons you might notice playing around with it), but I'll leave it here just in case anyone wishes to improve upon it.

EDIT 2

I modified the previous demo to simplify it and allow for opening/closing animation. I don't know if at this point you'd exactly be doing things the "Material" way but I think it's workable and better anyway than my previous attempt. Demo: https://jsfiddle.net/damo_s/Ln6e4qLt/

.mdl-layout__drawer {
  overflow: hidden;
  width: 55px;
  transform: translateX(0);
  transition: 250ms width ease-in-out;

  .mdl-navigation__link span {
    opacity: 0;
    transition: 250ms opacity ease-in-out;
  }

  + .mdl-layout__header,
  ~ .mdl-layout__content {
    transition: 250ms margin-left ease-in-out;
  }

  &.is-expanded {
    width: 240px;

    .mdl-navigation__link span {
      opacity: 1;
    }

    + .mdl-layout__header,
    ~ .mdl-layout__content{
      margin-left: 240px!important;
    }
  }
}

.mdl-layout__header,
.mdl-layout__content {
  margin-left: 55px!important;
}

.mdl-navigation {
  width: 240px;
}

.mdl-layout__header-row {
  padding: 0 16px 0 22px;
}

.mdl-layout__content {
  background: #878787;
}

.mdl-layout__drawer-button {
  display: none;
}
like image 99
damo-s Avatar answered Oct 26 '25 08:10

damo-s



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!