你如何在 display:none 和 display:block 之间转换?
How do you transition between display:none and display:block?
我正在尝试延迟移动导航项目的出现(理想情况下不使用 JS 来延迟它们的出现)直到导航覆盖完全展开 (0.4s)。
有两种状态:
1.非叠加状态:top nav左边是汉堡包菜单,右边是我的名字。 4 个导航链接被隐藏。
2. 叠加状态:汉堡菜单变成一个x,顶部导航过渡到覆盖整个页面,4个导航链接集中出现在导航叠加上。
我在别处读到,如果 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-width="1" 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");
}
我预计 class "nav_tab" 的导航元素会在 nav_container 有时间完全展开后的十分之几秒内出现。
当前结果是 class "nav_tab" 的导航元素在 nav_container 有时间完全展开之前立即出现。
如果您将 visibility
和 opacity
与 max-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;
}
<div class="visible">Click to hide</div>
你可以再给你加一个参数transition
,就是'delay'。延迟是过渡的第四个参数,在你的情况下它可以是这样的:
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;
这将使您的容器至少扩展到 window 的高度。
对于元素 .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。
查看结果,如果您更接近目标,请告诉我 ;)
我正在尝试延迟移动导航项目的出现(理想情况下不使用 JS 来延迟它们的出现)直到导航覆盖完全展开 (0.4s)。
有两种状态: 1.非叠加状态:top nav左边是汉堡包菜单,右边是我的名字。 4 个导航链接被隐藏。 2. 叠加状态:汉堡菜单变成一个x,顶部导航过渡到覆盖整个页面,4个导航链接集中出现在导航叠加上。
我在别处读到,如果 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-width="1" 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");
}
我预计 class "nav_tab" 的导航元素会在 nav_container 有时间完全展开后的十分之几秒内出现。
当前结果是 class "nav_tab" 的导航元素在 nav_container 有时间完全展开之前立即出现。
如果您将 visibility
和 opacity
与 max-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;
}
<div class="visible">Click to hide</div>
你可以再给你加一个参数transition
,就是'delay'。延迟是过渡的第四个参数,在你的情况下它可以是这样的:
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;
这将使您的容器至少扩展到 window 的高度。
对于元素
.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。
查看结果,如果您更接近目标,请告诉我 ;)