如何在 display:none 和 display:block 之间转换?

Posted

技术标签:

【中文标题】如何在 display:none 和 display:block 之间转换?【英文标题】:How do you transition between display:none and display:block? 【发布时间】:2019-08-26 16:16:41 【问题描述】:

我正在尝试延迟移动导航项的出现(最好不使用 JS 来延迟它们的出现),直到导航覆盖完全展开(0.4 秒)。

有两种状态: 1.非覆盖状态:顶部导航左侧有汉堡菜单,右侧有我的名字。 4 个导航链接被隐藏。 2.覆盖状态:汉堡菜单变成一个x,顶部nav过渡覆盖整页,4个nav链接集中出现在nav覆盖上。

我在其他地方读到,如果 display: 发生变化,现代浏览器将忽略任何动画或过渡规范。现在还是这样吗?我该如何克服这个问题并延迟导航项的出现,直到覆盖完全展开?

它似乎在这里工作:https://codepen.io/KingKabir/pen/QyPwgG 但我不确定他们是如何完成它的?

我尝试过使用 visibility: 和 opacity: 但它们并没有完全隐藏非覆盖状态下的 4 个导航元素,因此在非覆盖状态下的导航菜单右侧弄乱了我的名字.

html

  <nav class="nav_container" id="overlay">
    <div class="hamburger" id="hamburger" onclick="mobileMenu()">
      <div class="bar1"></div>
      <div class="bar2"></div>
      <div class="bar3"></div>
    </div>
    <div class="icon_personal_container">
      <a href="../index.html">
        <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon_personal">
          <title>J Logo</title>
          <defs>
            <linearGradient x1="14.6040568%" y1="100%" x2="85.3959432%" y2="0%" id="linearGradient-1">
              <stop stop-color="#12A9FF" offset="0%"></stop>
              <stop stop-color="#FF0096" offset="100%"></stop>
            </linearGradient>
          </defs>
          <g stroke="none" stroke- fill="none" fill-rule="evenodd">
            <circle fill="#333333" cx="12" cy="11.94" r="12"></circle>
            <polygon points="18.57144 7.82616 14.68812 7.82616 12 7.82616 12 5.16 18.57144 5.16"></polygon>
            <path d="M12.0021063,5.16 L17.3805494,5.16 L14.6827527,7.80073139 L14.6827527,13.044557 C14.6827527,16.5810127 13.1030779,18.9 9.57770614,18.9 C8.045129,18.9 6.72924975,18.3030871 5.82008559,17.4140986 C5.81142009,17.4056254 6.46074609,16.7540162 7.76806357,15.459271 C8.20030047,15.9163181 8.81488621,16.2138397 9.57770614,16.2138397 C11.2344382,16.2138397 11.985747,15.1509705 11.985747,13.1218565 L11.985747,5.16 L12.0021063,5.16 Z"
              fill="url(#linearGradient-1)"></path>
          </g>
        </svg>
      </a>
    </div>
    <div class="nav_tab" id="nav_tab_about"><a href="#about" class="nav_tab_hover_effect" onclick="mobileMenu()">About</a></div>
    <div class="nav_tab" id="nav_tab_work"><a href="#work" class="nav_tab_hover_effect" onclick="mobileMenu()">Work</a></div>
    <div class="nav_tab" id="nav_tab_skills"><a href="#skills" class="nav_tab_hover_effect" onclick="mobileMenu()">Skills</a></div>
    <div class="nav_tab" id="nav_tab_contact"><a href="#contact" class="nav_tab_hover_effect" onclick="mobileMenu()">Contact</a></div>
    <div class="blanks"></div>
    <div class="blanks"></div>
    <div id="nav_text">Jordan Tranchina</div>
  </nav>

CSS:

    .nav_container 
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr !important;
    grid-template-rows: auto;
    column-gap: 16px;
    grid-template-areas:
      "nav-far-left nav-left nav-right nav-far-right";
  
  .nav_container.open 
    max-height: 100%;
    height: 200%;
    background-color: #000000;
    display: grid;
    grid-template-rows: auto auto auto auto auto;
    grid-template-areas:
      "nav-far-left nav-left nav-right nav-far-right"
      "second second second second"
      "third third third third"
      "fourth fourth fourth fourth"
      "fifth fifth fifth fifth";
    transition: all 0.4s cubic-bezier(0.455, 0.03, 0.515, 0.955);
  

  .icon_personal_container,.blanks
    display: none;
  
  .nav_tab 
    display: block;
    height: 0;
    width: 0;
    visibility: hidden;
    opacity: 0;
  
  .nav_tab.open
    display: block;
    height: auto;
    font-size: 32px;
    font-weight: 500;
    padding-top: 64px;
    visibility: visible;
    opacity: 1;
    transition: visibility 0s linear;
  

  #nav_tab_about.open
    grid-area: second;
    transition-delay: .10s;
    width: auto;
  
  #nav_tab_work.open 
    grid-area: third;
    transition-delay: .15s;
    width: auto;
  
  #nav_tab_skills.open 
    grid-area: fourth;
    transition-delay: .2s;
    width: auto;
  
  #nav_tab_contact.open 
    grid-area: fifth;
    transition-delay: .25s;
    width: auto;
  

  #nav_text 
    grid-area: 1 / nav-right / 1 / nav-far-right;
  

javascript

function mobileMenu() 
  document.getElementById("hamburger").classList.toggle("active"); // toggling active class
  document.body.classList.toggle("overlay-body"); //toggling overlay state on body
  document.getElementById("overlay").classList.toggle("open"); //toggling overlay state on nav by setting classlist to "open"
  // improve below by grabing by class not by id
  document.getElementById("nav_tab_about").classList.toggle("open");
  document.getElementById("nav_tab_work").classList.toggle("open");
  document.getElementById("nav_tab_skills").classList.toggle("open");
  document.getElementById("nav_tab_contact").classList.toggle("open");

我预计“nav_tab”类的导航元素会在 nav_container 有时间完全展开后出现十分之一秒。

当前结果是“nav_tab”类的导航元素立即出现,在 nav_container 有时间完全展开之前。

【问题讨论】:

display:nonedisplay:block 之间没有过渡,也不会有。在 codepen 中,他们正在为 translateX、translateY、opacity 等设置动画。 明白。谢谢@MrLister!你知道我怎样才能延迟从 display:none 变为 display:block 的元素的出现吗? 要连续更改多个属性,可以使用CSS animation @MrLister 我将使用哪个 css 动画来确保元素在单击汉堡菜单而不是屏幕加载后出现延迟? 【参考方案1】:

如果您将visibilityopacitymax-height 结合使用,您可以实现从可见到隐藏的良好过渡,反之亦然。在隐藏时将元素的max-height 设置为0,在可见时将max-height 设置为Xpx(比您的元素更大),可以防止元素以任何方式与您的布局混淆(正如您在你的问题)。

这是一个简单的例子:

var visible = document.querySelector(".visible");

function hide() 
  visible.classList.add("hidden");


visible.addEventListener("click", hide);
div 
  background-color: blue;
  padding: 40px;
  color: white;
  cursor: pointer;
  transition: all .1s ease;


.visible 
  visibility: visible;
  opacity: 1;
  max-height: 1000px;


.hidden 
  visibility: hidden;
  opacity: 0;
  max-height: 0;
&lt;div class="visible"&gt;Click to hide&lt;/div&gt;

【讨论】:

这部分工作@mmshr,谢谢!即使在将 nav_tab 元素的宽度和高度设置为 0 之后,文本仍然离得太远了。我已经在上面添加了我的粗略修复(绝对定位),但我很想在没有绝对定位的情况下这样做,所以我可以仍然使用 CSS Grid 来定位 nav_text。不使用绝对位置破解的叠加和非叠加状态的图像:imgur.com/a/CKKhFge @JordanTranchina 尝试为您的导航标签设置grid-area,当它们也是.open时。例如:div#nav_tab_about.open grid-area: second; 这成功了!非常感谢!您的说明 + 将 .nav_tab 设置为 width:0 & height:0 并将 #nav_tab_[about,work,skills,contact].open's 设置为 width:auto 完美地完成了这项工作!【参考方案2】:

您可以再向您添加一个参数transition,即“延迟”。延迟是转换的第四个参数,在您的情况下,它可以如下所示:

transition: all 0.4s cubic-bezier(0.455, 0.03, 0.515, 0.955) 2s;

现在这个动画会延迟 2 秒开始。

为了让您更接近您想要实现的目标,我对您的 CSS 做了一些小改动,我将在下面进行描述:

    对于元素 .nav_container.open 替换行:

    max-height: 100%;
    height: 200%;
    

    一行:

    min-height: 100vh;
    

    它会让你的容器至少扩展到窗口的高度。

    对于元素.nav_tab 替换:

    display: none;
    

    与:

    display: block;
    opacity: 0;
    

    这样您就可以隐藏您的链接并避免没有动画来显示它们。

    对于元素.nav_tab.open,删除这两行:

    display: block;
    visibility: visible;
    

    并添加这两行:

    opacity: 1;
    transition: all 0.6s linear 0.4s;
    

    其中 0.6s 是动画持续时间,0.4s 是延迟 - 将其设置为不低于展开 nav_container 的持续时间。

检查结果,让我知道你是否更接近你的目标;)

【讨论】:

我相信这会延迟覆盖扩展的动画,而不是延迟 nav_tab 元素@Joint。对吗? 这取决于您如何使用它,您可以将此延迟添加到您想要的任何过渡中 你能提供javascript代码让我检查你的代码现在是如何工作的吗? 我在帖子中添加了我正在使用的 Javascript。我只在单击汉堡菜单时使用它来更改 nav_tab 和 hamburger 元素上的类 谢谢Joint,我能够让我的代码使用@mmshr 上面的建议。结果我没有尝试解决这个问题,但感谢您提交它的工作!

以上是关于如何在 display:none 和 display:block 之间转换?的主要内容,如果未能解决你的问题,请参考以下文章

easyUI-datagrid属性设置display:none,表头不显示

HTML如何创建二级目录

如何在 display:none 和 display:block 之间转换?

如何设置“style=display:none;”使用 jQuery 的 attr 方法?

读取(但不分配)一个属性:把戏还是没用? [复制]

如何使用 display:none css 属性显示已隐藏的 webkit 滚动条?