【问题标题】:CSS Transition doesn't work on height propertyCSS 过渡不适用于 height 属性
【发布时间】:2021-10-23 03:11:16
【问题描述】:

所以我在点击时进行菜单交互,如果你想看一下,这是我的代码 sn-p。

let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
let labels = document.querySelector('.labels');
btn.onclick = function() {
  icons.classList.toggle('active');
  labels.classList.toggle('active');
}
body {
  background: #222;
}

.trigger {
  cursor: pointer;
}

nav {
  position: absolute;
  top: 30px;
  right: 30px;
  color: #222;
}

nav ul.icons {
  background: #fff;
  width: 60px;
  height: 60px;
  overflow: hidden;
  border-radius: 60px;
  transition: 1s ease;
}

nav ul.icons:hover {
  height: 100%;
}

nav ul li {
  list-style: none;
}
<html lang="en">

<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>

<body>
  <nav>
    <ul class="icons">
      <li class="trigger">
        <i class="fas fa-bars"></i>
      </li>
      <li><i class="fas fa-home"></i></li>
      <li><i class="fas fa-users"></i></li>
      <li><i class="fas fa-concierge-bell"></i></li>
      <li><i class="fas fa-pen"></i></li>
      <li><i class="fas fa-phone-alt"></i></li>
    </ul>
  </nav>
</body>

</html>

我遇到的问题是,transition 属性不能很好地与 CSS 中的高度一起使用。是否有我没有注意到的问题,是否有快速解决方法?

【问题讨论】:

  • 首先,您的 css 中没有任何 active 类。那你想达到什么目的??
  • @KunalTanwar 说了什么。此外,当您创建 .active 类时,您需要设置准确的 height 值才能使转换生效。
  • @KunalTanwar 单击菜单按钮时将出现活动类,顺便说一下它在javascript中。

标签: javascript html css menu interaction


【解决方案1】:

所以问题是您尝试将高度转换为 100% - 但 CSS 无法立即处理。

快速但有问题的解决方案:
您可以将 :hover 中的高度设置为固定量,例如100 像素。
但是,如果您想在其中添加一个新项目或更改项目的大小,则必须手动调整高度。

我会做什么:
首先,我会稍微重构一下 HTML 并将触发器移出项目列表:

<nav>
    <button class="trigger">
        <i class="fas fa-bars"></i>
    </button>
    <ul class="icons fas-container">
        <li><i class="fas fa-home"></i></li>
        <li><i class="fas fa-users"></i></li>
        <li><i class="fas fa-concierge-bell"></i></li>
        <li><i class="fas fa-pen"></i></li>
        <li><i class="fas fa-phone-alt"></i></li>
    </ul>
</nav>

然后我会调整 .icons 的 CSS:
(移除高度,添加最大高度并调整过渡)

nav ul.icons {
    background: #fff;
    width: 60px;
    overflow: hidden;
    border-radius: 60px;

    max-height: 0;
    transition: max-height 0.2s ease-out;
}

最后,我会让 JavaScript 负责获得正确的最大高度。
悬停时:

let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onmouseover = function () {
    icons.style.maxHeight = icons.scrollHeight + "px";
}
btn.onmouseout = function () {
    icons.style.maxHeight = null;
}

或点击(如果您愿意的话):

let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');

btn.onclick = function() {
    if (icons.style.maxHeight){
        icons.style.maxHeight = null;
    } else {
        icons.style.maxHeight = icons.scrollHeight + "px";
    }
}

这里有一些(可能)有用的链接:

片段:

let btn = document.querySelector('.trigger');
    let icons = document.querySelector('.icons');
    btn.onmouseover = function () {
        icons.style.maxHeight = icons.scrollHeight + "px";
    }
    btn.onmouseout = function () {
        icons.style.maxHeight = null;
    }
body {
        background: #222;
    }

    .trigger {
        cursor: pointer;
    }

    nav {
        position: absolute;
        top: 30px;
        right: 30px;
        color: #222;
    }

    nav ul.icons {
        background: #fff;
        width: 60px;
        overflow: hidden;
        border-radius: 60px;

        max-height: 0;
        transition: max-height 0.2s ease-out;
    }

    nav ul.icons:hover {
        height: 100%;
    }

    nav ul li {
        list-style: none;
    }
<html lang="en">

<head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>

<body>
<nav>
    <button class="trigger">
        <i class="fas fa-bars"></i>
    </button>
    <ul class="icons fas-container">
        <li><i class="fas fa-home"></i></li>
        <li><i class="fas fa-users"></i></li>
        <li><i class="fas fa-concierge-bell"></i></li>
        <li><i class="fas fa-pen"></i></li>
        <li><i class="fas fa-phone-alt"></i></li>
    </ul>
</nav>
</body>

</html>

【讨论】:

    【解决方案2】:

    “高度”属性的 CSS 过渡只有在指定两个值(开始和结束)时才起作用。

    您可以通过使用“max-height”而不是“height”来解决这个问题。这样您就可以安全地超过元素在过渡结束时应具有的确切高度。

    let btn = document.querySelector('.trigger');
    let icons = document.querySelector('.icons');
    let labels = document.querySelector('.labels');
    btn.onclick = function() {
      icons.classList.toggle('active');
      labels.classList.toggle('active');
    }
    body {
      background: #222;
    }
    
    .trigger {
      cursor: pointer;
    }
    
    nav {
      position: absolute;
      top: 30px;
      right: 30px;
      color: #222;
    }
    
    nav ul.icons {
      background: #fff;
      width: 60px;
      max-height: 60px;
      overflow: hidden;
      border-radius: 60px;
      transition: max-height 1s ease;
    }
    
    nav ul.icons:hover {
      max-height: 120px;
    }
    
    nav ul li {
      list-style: none;
    }
    <html lang="en">
    
    <head>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    </head>
    
    <body>
      <nav>
        <ul class="icons">
          <li class="trigger">
            <i class="fas fa-bars"></i>
          </li>
          <li><i class="fas fa-home"></i></li>
          <li><i class="fas fa-users"></i></li>
          <li><i class="fas fa-concierge-bell"></i></li>
          <li><i class="fas fa-pen"></i></li>
          <li><i class="fas fa-phone-alt"></i></li>
        </ul>
      </nav>
    </body>
    
    </html>

    如果您设置的最终值与所需值相比太高,唯一的副作用可能是返回转换的延迟太长。

    【讨论】:

      【解决方案3】:

      只是您想要创建的内容的一个非常基本的 sn-p。

      [注意]:过渡非常/有点古怪(不流畅)。但事实就是如此。

      document.querySelector('.menu').addEventListener('click', (e) => {
        document.querySelector('ul.icons').classList.toggle('active');
      });
      * {
        margin: 0;
        padding: 0;
        outline: 0;
        box-sizing: border-box;
      }
      
      .navbar {
        position: relative;
        width: 100%;
        height: 100px;
        display: flex;
        padding: 0 4rem;
        align-items: center;
        justify-content: flex-end;
        background-color: #f7f8f9;
        border-bottom: 1px solid #c1c1c1;
      }
      
      .navbar .menu i {
        cursor: pointer;
        font-size: 2rem;
      }
      
      .navbar .icons {
        opacity: 0;
        list-style: none;
        position: absolute;
        top: calc(100% + 2px);
        right: 3rem;
        display: flex;
        flex-direction: column;
        transition: opacity 250ms ease;
      }
      
      .navbar .icons .icon {
        display: grid;
        padding: 1rem;
        flex-shrink: 0;
        min-width: 30px;
        min-height: 30px;
        border-radius: 50%;
        place-items: center;
        background-color: #f7f8f9;
        border: 1px solid #c1c1c1;
        transition: margin-top 250ms ease;
      }
      
      .navbar .icons .icon:not(:first-of-type) {
        margin-top: 1rem;
      }
      
      .navbar .icons .icon:nth-child(2) {
        margin-top: -62px;
      }
      
      .navbar .icons .icon:nth-child(3) {
        margin-top: -62px;
      }
      
      .navbar .icons .icon:nth-child(4) {
        margin-top: -62px;
      }
      
      .navbar .icons .icon:nth-child(5) {
        margin-top: -62px;
      }
      
      .navbar .icons.active {
        opacity: 1;
      }
      
      .navbar .icons.active .icon {
        margin-top: 1rem;
      }
      
      .navbar .icons.active .icon:nth-child(1) {
        margin-top: 0;
        transition-delay: 250ms;
      }
      
      .navbar .icons.active .icon:nth-child(2) {
        transition-delay: 250ms;
      }
      
      .navbar .icons.active .icon:nth-child(2) {
        transition-delay: 500ms;
      }
      
      .navbar .icons.active .icon:nth-child(3) {
        transition-delay: 750ms;
      }
      
      .navbar .icons.active .icon:nth-child(4) {
        transition-delay: 1s;
      }
      
      .navbar .icons.active .icon:nth-child(5) {
        transition-delay: 1.25s;
      }
      
      .bx {
        font-size: 1.75rem;
      }
      <link href='https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css' rel='stylesheet'>
      
      <nav class="navbar">
        <div class="menu" role="button">
          <i class='bx bx-menu'></i>
        </div>
        <ul class="icons">
          <li class="icon">
            <i class='bx bx-home-alt'></i>
          </li>
          <li class="icon">
            <i class='bx bx-user'></i>
          </li>
          <li class="icon">
            <i class='bx bx-bell'></i>
          </li>
          <li class="icon">
            <i class='bx bx-pen'></i>
          </li>
          <li class="icon">
            <i class='bx bx-phone'></i>
          </li>
        </ul>
      </nav>

      如果有人可以让这个过渡更顺利一点编辑这个答案。

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 1970-01-01
        • 2021-08-07
        • 1970-01-01
        • 2014-10-14
        • 2020-04-30
        • 2020-09-23
        • 1970-01-01
        • 2013-08-28
        相关资源
        最近更新 更多