【问题标题】:Transitions on the CSS height property toggles inconsistentlyCSS 高度属性上的转换不一致地切换
【发布时间】:2020-05-22 23:25:42
【问题描述】:

我有一个垂直导航栏,它显示隐藏内容的下拉容器。使用max-height: 0px 隐藏容器。我有 JS 在 max-height: 5000pxmax-height: 0px 之间转换,具体取决于检查当前值的条件语句。所有这些隐藏的容器都有不同的大小。因此,我必须应用一个大于捕获所有这些用例所需的max-height。但是,这样做会导致transition 属性在从max-height: 5000px 移动到max-height: 0px 时执行不一致(从5000 像素到实际高度的过渡导致延迟)。是否有更好的方法来实现相同的效果,从而实现更自然/一致的过渡?

var dropdown = document.getElementsByClassName("dropdown-btn");
      var i;

      for (i = 0; i < dropdown.length; i++) {
        dropdown[i].addEventListener("click", function() {
          this.classList.toggle("active");
          var dropdownContent = this.nextElementSibling;
          if (dropdownContent.style.maxHeight === "5000px") {
            dropdownContent.style.maxHeight = "0px";
          } else {
            dropdownContent.style.maxHeight = "5000px";
          }
        });
      }
body {
    margin: 0;
    padding: 0;
    font-family: 'Roboto', sans-serif;
    font-weight: 400;
    background-color: #F6F5F8;
  }
  
header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }

  nav {
    display: flex;
    flex-direction: column;
    justify-content: flext-start;
    height: 100%;
    width: 14.5em;
    position: fixed;
    top: 0;
    left: 0;
    background-color: #2C3039;
    overflow-x: hidden;
    padding-top: .75em;
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
    align-items: center;
  }

  #logo-pic {
    height: 2.4em;
    width: 2.4em;
    filter: contrast(100%);
  }

  #logo-font {
    color: #f6f5f8;
    font-family: 'Maven Pro', sans-serif;
    font-size: 25px;
    margin-top: .15em;
    margin-left: .4em;
  }

  .nav-logo-app-container {
    text-decoration: none;
    position: relative;
    display: flex;
  }

  #profile-pic {
    height: 3em;
    width: 3em;
    border-radius: 50%;
    filter: contrast(85%);
    border:3.5px solid white;
  }

  .profile-info {
      padding-top: 2em;
      display: flex;
      justify-content: flex-start;
      align-self: flex-start;
      padding-left: 1em;
  }

  .profile-greeting {
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
      align-items: flex-start;
      color: #cdcad2;
      font-size: 12px;
      padding-left: 1.8em;
      padding-bottom: .3em;
      font-weight: 300;
  }

  #username {
      margin: .75em 0em 0em 0em;
      color: white;
      font-weight: 300;
  }

  .sidebar-menu {
    margin-top: 1em;
    align-self: flex-start;
    width: 100%;
    font-size: 14px;
  }

  #sidebar-head {
    padding-left: 2.1em;
    color: white;
    font-size: 12.5px;
    margin-bottom: .6em;
  }

  .sidebar-menu a, .dropdown-btn {
    text-decoration: none;
    color: #f6f5f8;
    display: block;
    border: none;
    background: none;
    width:100%;
    cursor: pointer;
    outline: none;
    text-align: left;
  }

  .dropdown-btn {
    height: 3em;
    text-align: left;
    padding-left: 1.25em;
    margin-bottom: .5em;
  }

  .fa-chevron-down {
    padding-right: 1em;
  }

  .active {
    border-top: 1px solid #635f5f;
    border-bottom: 1px solid #1d1d1d;
    color: white;
    background-color: #373c46;
  }

  .dropdown-container {
    padding-left: 8px;
    transition: max-height 1s ease-in-out;
    max-height: 0px;
    overflow: hidden;
  }

  .fa-chevron-down {
    float: right;
    font-size: 10px;
    padding-top: .35em;
  }

  .dropdown-btn-icon {
    font-size: 15px;
    display: inline;
    margin-right: 1em;
  }
<nav>
  <a class="nav-logo-app-container" href="/">
    <img id="logo-pic" src="/images/sbux-logo.png"/>
    <div id="logo-font">Test</div>
  </a>
    <div class="profile-info">
      <img id="profile-pic" src="/images/professional_pic.jpg" />
        <div class="profile-greeting">
          <span>Welcome,</span>
          <h3 id="username">John Smith</h3>
        </div>
    </div>
    <div class="sidebar-menu">
        <h3 id="sidebar-head">GENERAL</h3>
        <button class="dropdown-btn">
          <div class="dropdown-btn-icon"><i class="fas fa-home"></i></div>Home<i class="fas fa-chevron-down"></i>
        </button>
        <div class="dropdown-container"><a href="#">Home1</a><a href="#">Home2</a><a href="#">Home3</a></div>
        <button class="dropdown-btn">
          <div class="dropdown-btn-icon"><i class="fas fa-users"></i></div>Sourcing<i class="fas fa-chevron-down"></i>
        </button>
        <div class="dropdown-container"><a href="#">Other1</a><a href="#">Other2</a><a href="#">Other3</a></div>
    </div>
</nav>

【问题讨论】:

  • 嗨有趣,也许是一个更大尺寸的容器?

标签: javascript html css css-transitions


【解决方案1】:

我认为您应该为下拉容器使用真实的max-height 值。最大高度为 5000px 时,当从 5000 转换回 0 时,容器的实际高度(= 大约 50px)将在转换的 99% 处达到,因此 50px 和 0 之间的转换将花费 1/100 秒,它似乎会延迟 99/100 秒..

如果您在 javascript 中将 max-heigth 的值更改为 50px,则从 0 到 50 的整个转换(反之亦然)实际上需要一秒钟 - 转换更加平滑 - 并且返回(50 到 0)的转换将开始立即从 50 开始,而不是在 99% 的秒内没有效果,因为在此期间,在您的示例中,过渡从 5000 运行到 50(= 没有效果,或者仅在达到 50px 时)。

注意:您可能需要根据实际高度为不同的下拉菜单应用不同的值。

注意 2:您写道,您正在通过 JS 进行转换,但实际的转换是由 CSS 完成的 - 通过 JS,您只是更改 CSS 用作转换值的值。

var dropdown = document.getElementsByClassName("dropdown-btn");
      var i;

      for (i = 0; i < dropdown.length; i++) {
        dropdown[i].addEventListener("click", function() {
          this.classList.toggle("active");
          var dropdownContent = this.nextElementSibling;
          if (dropdownContent.style.maxHeight == "50px") {
            dropdownContent.style.maxHeight = "0px";
          } else {
            dropdownContent.style.maxHeight = "50px";
          }
        });
      }
body {
    margin: 0;
    padding: 0;
    font-family: 'Roboto', sans-serif;
    font-weight: 400;
    background-color: #F6F5F8;
  }
  
header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }

  nav {
    display: flex;
    flex-direction: column;
    justify-content: flext-start;
    height: 100%;
    width: 14.5em;
    position: fixed;
    top: 0;
    left: 0;
    background-color: #2C3039;
    overflow-x: hidden;
    padding-top: .75em;
    border-top-right-radius: 4px;
    border-bottom-right-radius: 4px;
    align-items: center;
  }

  #logo-pic {
    height: 2.4em;
    width: 2.4em;
    filter: contrast(100%);
  }

  #logo-font {
    color: #f6f5f8;
    font-family: 'Maven Pro', sans-serif;
    font-size: 25px;
    margin-top: .15em;
    margin-left: .4em;
  }

  .nav-logo-app-container {
    text-decoration: none;
    position: relative;
    display: flex;
  }

  #profile-pic {
    height: 3em;
    width: 3em;
    border-radius: 50%;
    filter: contrast(85%);
    border:3.5px solid white;
  }

  .profile-info {
      padding-top: 2em;
      display: flex;
      justify-content: flex-start;
      align-self: flex-start;
      padding-left: 1em;
  }

  .profile-greeting {
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
      align-items: flex-start;
      color: #cdcad2;
      font-size: 12px;
      padding-left: 1.8em;
      padding-bottom: .3em;
      font-weight: 300;
  }

  #username {
      margin: .75em 0em 0em 0em;
      color: white;
      font-weight: 300;
  }

  .sidebar-menu {
    margin-top: 1em;
    align-self: flex-start;
    width: 100%;
    font-size: 14px;
  }

  #sidebar-head {
    padding-left: 2.1em;
    color: white;
    font-size: 12.5px;
    margin-bottom: .6em;
  }

  .sidebar-menu a, .dropdown-btn {
    text-decoration: none;
    color: #f6f5f8;
    display: block;
    border: none;
    background: none;
    width:100%;
    cursor: pointer;
    outline: none;
    text-align: left;
  }

  .dropdown-btn {
    height: 3em;
    text-align: left;
    padding-left: 1.25em;
    margin-bottom: .5em;
  }

  .fa-chevron-down {
    padding-right: 1em;
  }

  .active {
    border-top: 1px solid #635f5f;
    border-bottom: 1px solid #1d1d1d;
    color: white;
    background-color: #373c46;
  }

  .dropdown-container {
    padding-left: 8px;
    transition: max-height 1s ease-in-out;
    max-height: 0px;
    overflow: hidden;
  }

  .fa-chevron-down {
    float: right;
    font-size: 10px;
    padding-top: .35em;
  }

  .dropdown-btn-icon {
    font-size: 15px;
    display: inline;
    margin-right: 1em;
  }
<nav>
  <a class="nav-logo-app-container" href="/">
    <img id="logo-pic" src="/images/sbux-logo.png"/>
    <div id="logo-font">Test</div>
  </a>
    <div class="profile-info">
      <img id="profile-pic" src="/images/professional_pic.jpg" />
        <div class="profile-greeting">
          <span>Welcome,</span>
          <h3 id="username">John Smith</h3>
        </div>
    </div>
    <div class="sidebar-menu">
        <h3 id="sidebar-head">GENERAL</h3>
        <button class="dropdown-btn">
          <div class="dropdown-btn-icon"><i class="fas fa-home"></i></div>Home<i class="fas fa-chevron-down"></i>
        </button>
        <div class="dropdown-container"><a href="#">Home1</a><a href="#">Home2</a><a href="#">Home3</a></div>
        <button class="dropdown-btn">
          <div class="dropdown-btn-icon"><i class="fas fa-users"></i></div>Sourcing<i class="fas fa-chevron-down"></i>
        </button>
        <div class="dropdown-container"><a href="#">Other1</a><a href="#">Other2</a><a href="#">Other3</a></div>
    </div>
</nav>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2021-12-07
    • 2020-01-11
    相关资源
    最近更新 更多