Material 设计可扩展抽屉

Material design expandable drawer

我正在使用 Material Design Lite 开发 Web 应用程序。

其中一个要求是:存在侧边栏,默认情况下,它将以较小的宽度(比如 50px)显示菜单项的图标。单击菜单(汉堡包)图标,然后将抽屉扩大到更大的尺寸,不仅显示图标,还显示图标旁边的文本。这是我想要实现的示例:

默认:

展开:

这是我现在的 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>

有没有 good/correct 的方法?一直在想怎么办,还没想出好的办法。

纯粹CSS无法做到这一点。你必须使用 jQuery。像这样

$('#hamburger-button').on('click',function() {
   $('#menu .links').css('display','block');

});

假设您隐藏了 display:none 的链接。

如果你可以 post 在这里你的 css 和 html 代码我可以帮助具体的例子。

看看this answer。我认为这是实现这种效果的好方法。

然后您可以将 polyfill 放入 CSS 中,例如:

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

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

如果您认为 polyfill 太多而无法仅添加此功能,我可以想到另一种不使用任何 javascript 的方式,但就您的方式而言,它不会那么灵活如果您想为其设置动画,请为 showing/hiding 设置动画。它涉及将主要内容区域重叠在抽屉上。给我一点时间,我会模拟一个演示。

编辑

就非 js 方法而言,这是我的想法(仍然需要一些用于切换 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;
}

现在来看,我认为这不是一个很好的方法(出于多种原因您可能会注意到使用它),但我会把它留在这里以防万一有人希望改进在上面。

编辑 2

我修改了之前的演示以简化它并允许 opening/closing 动画。我不知道此时您是否会完全按照 "Material" 方式做事,但我认为它比我之前的尝试更可行且更好。演示: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;
}