我正在尝试使自己不使用Bootstrap,但是遇到了一些我无法弄清的事情。
对于响应式顶部导航栏,当我单击汉堡菜单时,我希望它为打开和关闭设置动画(取决于开始时是打开还是关闭)。
我遇到的问题是在导航中使用display: none
杀死任何/所有动画。 .nav-top__nav-list
是动画需要发生的位置,其显示从“无”切换为“块”。我这样做是为了实现可访问性(这意味着除非扩展导航,否则屏幕阅读器不会进入该区域)。我还有另一种方法可以保持隐藏的可访问性,同时仍然可以对导航菜单的打开/关闭进行动画处理吗?
function topNavToggle() {
var topNavList = document.getElementById("topNavList");
var topNavToggle = document.getElementById("topNavToggle");
if (topNavList.className === "nav-top__nav-list") {
topNavList.className += " responsive";
topNavToggle.className += " toggled";
} else {
topNavList.className = "nav-top__nav-list";
topNavToggle.className = "nav-top__toggle-button";
}
}
.nav-top,
.navbar-nav {
grid-column-start: 1;
grid-column-end: 13;
}
.wrapper__1170-max-width {
display: grid;
grid-template-columns: repeat(12, 1fr);
max-width: 1170px;
margin: 0 auto;
padding: 0 1rem;
}
.display-desktop {
display: block;
}
.display-mobile {
display: none;
}
.nav-top {
background: #466a62;
min-height: 40px;
}
.nav-top__header {
grid-column-start: 1;
grid-column-end: 13;
}
.nav-top__header button {
background: none;
border: none;
cursor: pointer;
grid-column-start: 12;
grid-column-end: 13;
grid-row-start: 1;
justify-self: right;
}
.nav-top__header button .bar-1,
.nav-top__header button .bar-2,
.nav-top__header button .bar-3 {
width: 35px;
height: 5px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.nav-top__header button.change {
background: red;
}
.nav-top__header .toggled .bar-1 {
transform: rotate(-45deg) translate(-9px, 6px);
}
.nav-top__header .toggled .bar-2 {
opacity: 0;
}
.nav-top__header .toggled .bar-3 {
transform: rotate(45deg) translate(-8px, -8px);
}
.nav-top__header .nav-brand {
grid-column-start: 1;
grid-column-end: 12;
grid-row-start: 1;
}
.nav-top__nav-list {
grid-column-start: 1;
grid-column-end: 13;
}
.nav-top__nav-list ul {
list-style: none;
margin: 0;
padding: 0;
}
.nav-top__nav-list ul li {
float: left;
}
.nav-top__nav-list ul li a {
color: #FFF;
display: block;
padding: 11px;
text-decoration: none;
}
.nav-top__nav-list ul li a:hover {
background: #FFF;
color: #18453b;
}
@media only screen and (max-width: 992px) {
.display-desktop {
display: none;
}
.display-mobile {
display: block;
}
.nav-top__header {
display: grid;
}
.nav-top__nav-list {
display: none;
}
.nav-top__nav-list.responsive {
display: block;
}
.nav-top__nav-list.responsive ul li {
display: block;
float: none;
}
}
<nav class="nav-top" aria-label="primary">
<div class="wrapper__1170-max-width">
<div class="nav-top__header display-mobile">
<span class="nav-top__brand">Menu</span>
<button type="button" id="topNavToggle" class="nav-top__toggle-button" aria-label="Expand and collapse primary site navigation" data-toggle="collapse" data-target="#topNavList" onclick="topNavToggle()">
<div class="bar-1"></div>
<div class="bar-2"></div>
<div class="bar-3"></div>
</button>
</div>
<div class="nav-top__nav-list" id="topNavList">
<ul>
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 2</a></li>
</ul>
</div>
</div>
</nav>
最佳答案
在CSS中,不能为display
属性设置动画。您可以使用height
或max-height
。使用max-height
的优点是,即使您通过媒体查询在不同屏幕尺寸下更改字体大小,容器也会占据最佳高度。因此,我在CSS过渡中使用了max-height
。我已经更新了您的代码以获得预期的效果。
function topNavToggle() {
var topNavList = document.getElementById("topNavList");
var topNavToggle = document.getElementById("topNavToggle");
var topNavListLi = document.querySelectorAll("#topNavList li");
if (topNavList.className === "nav-top__nav-list") {
topNavList.className += " responsive";
topNavToggle.className += " toggled";
for (let i = 0; i < topNavListLi.length; i++) {
var hiddenAttribute = document.createAttribute("hidden");
//topNavListLi[i].setAttribute('hidden',false);
topNavListLi[i].setAttributeNode(hiddenAttribute);
}
} else {
topNavList.className = "nav-top__nav-list";
topNavToggle.className = "nav-top__toggle-button";
setTimeout(function(){
for (let i = 0; i < topNavListLi.length; i++) {
//topNavListLi[i].setAttribute('hidden',true);
topNavListLi[i].removeAttribute('hidden');
}
},300);
}
}
.nav-top,
.navbar-nav {
grid-column-start: 1;
grid-column-end: 13;
}
.wrapper__1170-max-width {
display: grid;
grid-template-columns: repeat(12, 1fr);
max-width: 1170px;
margin: 0 auto;
padding: 0 1rem;
}
.display-desktop {
display: block;
}
.display-mobile {
display: none;
}
.nav-top {
background: #466a62;
min-height: 40px;
}
.nav-top__header {
grid-column-start: 1;
grid-column-end: 13;
}
.nav-top__header button {
background: none;
border: none;
cursor: pointer;
grid-column-start: 12;
grid-column-end: 13;
grid-row-start: 1;
justify-self: right;
}
.nav-top__header button .bar-1,
.nav-top__header button .bar-2,
.nav-top__header button .bar-3 {
width: 35px;
height: 5px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.nav-top__header button.change {
background: red;
}
.nav-top__header .toggled .bar-1 {
transform: rotate(-45deg) translate(-9px, 6px);
}
.nav-top__header .toggled .bar-2 {
opacity: 0;
}
.nav-top__header .toggled .bar-3 {
transform: rotate(45deg) translate(-8px, -8px);
}
.nav-top__header .nav-brand {
grid-column-start: 1;
grid-column-end: 12;
grid-row-start: 1;
}
.nav-top__nav-list {
grid-column-start: 1;
grid-column-end: 13;
}
.nav-top__nav-list ul {
list-style: none;
margin: 0;
padding: 0;
}
.nav-top__nav-list ul li {
float: left;
}
.nav-top__nav-list ul li a {
color: #FFF;
display: block;
padding: 11px;
text-decoration: none;
}
.nav-top__nav-list ul li a:hover {
background: #FFF;
color: #18453b;
}
@media only screen and (max-width: 992px) {
.display-desktop {
display: none;
}
.display-mobile {
display: block;
}
.nav-top__header {
display: grid;
}
.nav-top__nav-list {
max-height: 0;
overflow: hidden;
transition: max-height .3s ease;
}
.nav-top__nav-list ul li {
float: none;
}
.nav-top__nav-list.responsive {
max-height: 170px;
transition: max-height .3s ease;
}
.nav-top__nav-list.responsive ul li {
display: block;
}
}
<nav class="nav-top" aria-label="primary">
<div class="wrapper__1170-max-width">
<div class="nav-top__header display-mobile">
<span class="nav-top__brand">Menu</span>
<button type="button" id="topNavToggle" class="nav-top__toggle-button" aria-label="Expand and collapse primary site navigation" data-toggle="collapse" data-target="#topNavList" onclick="topNavToggle()">
<div class="bar-1"></div>
<div class="bar-2"></div>
<div class="bar-3"></div>
</button>
</div>
<div class="nav-top__nav-list" id="topNavList">
<ul>
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Page 1</a></li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 2</a></li>
</ul>
</div>
</div>
</nav>
关于javascript - 使用 Vanilla JS/CSS对顶部导航栏的打开/关闭进行动画处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55143252/