• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

如何使用 CSS 和 JavaScript 构建非画布菜单

在本教程中,我们将通过一种简单而有效的方法来使用 htmlcssjavascript 创建画布外菜单。

要初步了解我们将要构建的内容,请查看相关的 CodePen 演示(查看 更大的版本 以获得更好的体验):

See the Pen  Off-Canvas Menu With CSS and a Touch of JavaScript by Envato Tuts+ (@tutsplus)  on CodePen.

信息本教程不会关注如何使画布外菜单可访问或响应,因此这些肯定是有效的后续步骤。

1. 从标记开始

我们的标记由两个包装元素组成:

  • .top-banner元素_

  • .top-nav元素_

这是HTML代码:

<section class="top-banner">
  <div class="top-banner-overlay">
    <!-- content here -->
  </div>
</section>
 
<nav class="top-nav">
  <div class="menu-wrapper">
    <!-- content here -->
  </div>
  <div class="fixed-menu">
    <!-- content here -->
  </div>
</nav>

2. 接下来我们需要一些 CSS

准备好标记后,接下来让我们检查菜单所需的最重要的样式。

信息为了便于阅读,这段 CSS 代码没有经过优化——您会注意到重复的属性,您可能希望在自己的版本中删除这些属性。

顶部横幅元素的样式

该 .top-banner元素如下所示:

如何使用 CSS 和 JavaScript 构建非画布菜单  第1张

关于其样式,我们执行以下操作:

  • 将其宽度设置为等于窗口宽度减去.menu-wrapper元素宽度。

  • 将其高度设置为等于窗口高度。

  • 将其定义为弹性容器。这将强制其覆盖覆盖整个父高度。

  • 使用 flexbox 将叠加层的内容垂直居中。

以下是我们实现所有这些所需的样式: 

.top-banner {
  display: flex;
  width: calc(100% - 150px);
  height: 100vh;
  transform: translateX(150px);
  background: url(IMAGE_PATH) no-repeat center / fixed;
}
 
.top-banner-overlay {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 350px;
  padding: 20px;
  transition: transform .7s;
  color: white;
  background: rgba(0, 0, 0, .7);
}

样式化顶部导航元素

该.top-nav元素如下所示:

如何使用 CSS 和 JavaScript 构建非画布菜单  第2张

在这种情况下,我们将执行以下操作:

  • 将直接子元素指定为覆盖窗口高度的固定定位元素。

  • 使用 flexbox 垂直对齐.fixed-menu元素。

  • 默认隐藏 .menu-wrapper元素。为此,我们不给它一个属性值,例如display: none. 实际上,我们使用该translate()函数将其向左移动 200px。请记住,元素的宽度是 350 像素,因此它的一部分仍在视口内。但是,它是不可见的,因为该元素位于该元素的下方.fixed-menu。

  • 隐藏菜单列表。

看看下面对应的 CSS 样式:

.top-nav .menu-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 350px;
  padding: 20px;
  transform: translateX(-200px);
  transition: transform .7s;
  background: #B1FFE5;
}
 
.top-nav .menu-wrapper .menu {
  opacity: 0;
  transition: opacity .4s;
}
 
.top-nav .fixed-menu {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  width: 150px;
  padding: 20px;
  background: aquamarine;
}

3. 现在一些 JavaScript

此时,我们将使用一些简单的 javaScript 代码来操作画布外菜单的状态。 

让我们描述必要的操作:

  • 单击按钮时.menu-open,菜单应该会出现一个很好的滑入效果,并且覆盖应该同时被推到右侧。可选地,我们可以在这种状态下做更多的事情。::before在我们的示例中,我们为叠加层的伪元素添加了一个盒子阴影, 并使用淡入效果显示菜单列表。

  • 单击按钮时.menu-close,菜单应该会消失,并具有很好的滑出效果,并且覆盖层应该同时向左推。

这是实现此行为的 JavaScript 代码:

const menuOpen = document.queryselector(".top-nav .menu-open");
const menuClose = document.querySelector(".top-nav .menu-close");
const menuWrapper = document.querySelector(".top-nav .menu-wrapper");
const topBannerOverlay = document.querySelector(".top-banner-overlay");
 
function toggleMenu() {
  menuOpen.addeventListener("click", () => {
    menuWrapper.classList.add("is-opened");
    topBannerOverlay.classList.add("is-moved");
  });
   
  menuClose.addEventListener("click", () => {
    menuWrapper.classList.remove("is-opened");
    topBannerOverlay.classList.remove("is-moved");
  });
}
 
toggleMenu();

下面是相关的 CSS 样式:

.top-banner-overlay.is-moved {
  transform: translateX(350px);
}
 
.top-banner-overlay.is-moved::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 100%;
  width: 20px;
  box-shadow: 0 0 10px black;
}
 
.top-nav .menu-wrapper.is-opened {
  transform: translateX(150px);
}
 
.top-nav .menu-wrapper.is-opened .menu {
  opacity: 1;
  transition-delay: .6s;
}

4.浏览器支持

此演示仅适用于桌面浏览器。移动设备将需要不同的页面布局,但这超出了本教程的范围。像往常一样,我们使用 Babel 将 ES6 代码编译成 ES5。

我在测试时遇到的唯一小问题是在叠加动画时发生的文本渲染变化。尽管我尝试了不同 Stack Overflow 线程中提出的各种方法,但我无法找到适用于所有操作系统和浏览器的简单解决方案。因此请记住,当叠加层被动画化时,您可能会看到小的字体渲染问题。

结论

就是这样,伙计们!我们设法用相对简单的代码构建了一个有用的画布外菜单。 


文章目录
  • 1. 从标记开始
  • 2. 接下来我们需要一些 CSS
    • 顶部横幅元素的样式
    • 样式化顶部导航元素
  • 3. 现在一些 JavaScript
  • 4.浏览器支持
  • 结论