首页 > 解决方案 > 我可以使用 CSS 进行擦除过渡吗?

问题描述

我有以下示例代码片段(我正在使用 React,但不想在此处发布之前花时间清理实际项目代码):

let menuOpened = false;

document.getElementById('menu-button')
    .addEventListener('click', function() {
      menuOpened = !menuOpened;
      document.getElementById('body').classList.toggle('menu-opened', menuOpened);
      document.getElementById('menu').classList.toggle('menu-opened', menuOpened);
    });
* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

body.menu-opened {
  overflow-y: hidden;
}

body > * {
  width: 100vw;
}

header {
  background-color: #6FC5C2;
  display: flex;
  height: 20vh;
  position: sticky;
  top: 0;
  
  align-items: center;
  justify-content: center;
}

nav {
  background-color: #80CAF1;
  display: flex;
  height: 80vh;
  left: 0;
  opacity: 0;
  padding: 1rem;
  position: fixed;
  top: 20vh;
  transition: all 0.35s ease;
  visibility: hidden;
  z-index: 20;
  
  align-items: center;
  flex-direction: column;
  justify-content: center;
}

nav.menu-opened {
  opacity: 1;
  visibility: visible;
}

a {
  color: black;
  font-weight: bold;
  text-decoration: none;
}

a:not(:last-child) {
  margin-bottom: 0.5rem;
}

main {
  display: flex;
}

aside {
  background-color: #9C9ECF;
  display: flex;
  flex-basis: 25%;
  padding: 3rem 0.5rem;
  text-align: center;
  
  justify-content: center;
}

section {
  background-color: #F8CFD7;
  display: flex;
  flex-basis: 75%;
  padding: 2rem;
  
  align-items: stretch;
  flex-direction: column;
}

article {
  border: ridge #80CAF1;
  border-width: 3px 3px 0 3px;
  display: flex;
  font-size: 0.75rem;
  min-height: 15vh;
  padding: 1rem;
  
  align-items: center;
}

article:last-child {
  border-width: 3px;
}

footer {
  background-color: #016CBA;
  height: 30vh;
}
<body id="body">
  <header>
    <button id="menu-button" type="button">Menu</button>
  </header>
  <nav id="menu">
    <a href="/">Link 1</a>
    <a href="/">Link 2</a>
  </nav>
  <main id="main">
    <aside>Filter Form</aside>
    <section>
      <article>Article A</article>
      <article>Article B</article>
      <article>Article C</article>
      <article>Article D</article>
      <article>Article E</article>
      <article>Article F</article>
      <article>Article G</article>
      <article>Article H</article>
      <article>Article I</article>
    </section>
  </main>
  <footer id="footer"></footer>
</body>

目前,当我单击按钮打开导航菜单时,页面将禁用滚动,菜单将淡入。当我再次单击按钮时,将重新启用滚动,菜单将淡出。

我真正想要的是擦除过渡而不是褪色,如下所示:

在此处输入图像描述

以上图为例,主页面内容为 A,菜单为 B。但是,我希望擦除不是水平的,而是垂直的,即当我打开菜单时,擦除将从上到下,当我关闭菜单时,擦除将从下到上。菜单文本不应移动。我想使用与当前配置相同的转换持续时间和计时功能。

在不使用 JavaScript/React 的情况下这可能吗?

标签: javascripthtmlcsscss-transitions

解决方案


另一个想法使用clip-path

let menuOpened = false;

document.getElementById('menu-button')
    .addEventListener('click', function() {
      menuOpened = !menuOpened;
      document.getElementById('body').classList.toggle('menu-opened', menuOpened);
      document.getElementById('menu').classList.toggle('menu-opened', menuOpened);
    });
* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

body.menu-opened {
  overflow-y: hidden;
}

body > * {
  width: 100vw;
}

header {
  background-color: #6FC5C2;
  display: flex;
  height: 20vh;
  position: sticky;
  top: 0;
  
  align-items: center;
  justify-content: center;
}

nav {
  background-color: #80CAF1;
  display: flex;
  height: 80vh;
  left: 0;
  padding: 1rem;
  position: fixed;
  top: 20vh;
  transition: all 0.8s ease;
  z-index: 20;
  
  align-items: center;
  flex-direction: column;
  justify-content: center;
  clip-path:polygon(0 0,0% 0,-200px 100%,0 100%);
}

nav.menu-opened {
  clip-path:polygon(0 0,calc(100% + 200px) 0,100% 100%,0 100%);
}

a {
  color: black;
  font-weight: bold;
  text-decoration: none;
}

a:not(:last-child) {
  margin-bottom: 0.5rem;
}

main {
  display: flex;
}

aside {
  background-color: #9C9ECF;
  display: flex;
  flex-basis: 25%;
  padding: 3rem 0.5rem;
  text-align: center;
  
  justify-content: center;
}

section {
  background-color: #F8CFD7;
  display: flex;
  flex-basis: 75%;
  padding: 2rem;
  
  align-items: stretch;
  flex-direction: column;
}

article {
  border: ridge #80CAF1;
  border-width: 3px 3px 0 3px;
  display: flex;
  font-size: 0.75rem;
  min-height: 15vh;
  padding: 1rem;
  
  align-items: center;
}

article:last-child {
  border-width: 3px;
}

footer {
  background-color: #016CBA;
  height: 30vh;
}
<body id="body">
  <header>
    <button id="menu-button" type="button">Menu</button>
  </header>
  <nav id="menu">
    <a href="/">Link 1</a>
    <a href="/">Link 2</a>
  </nav>
  <main id="main">
    <aside>Filter Form</aside>
    <section>
      <article>Article A</article>
      <article>Article B</article>
      <article>Article C</article>
      <article>Article D</article>
      <article>Article E</article>
      <article>Article F</article>
      <article>Article G</article>
      <article>Article H</article>
      <article>Article I</article>
    </section>
  </main>
  <footer id="footer"></footer>
</body>


推荐阅读