设置水平菜单的动画(重叠菜单项而不绝对定位它们)



所以客户端需要我实现菜单动画。它最初是由设计师使用InvisionApp创建的。该应用程序只是获取菜单项并将其绝对定位,这在网站上应该不是一个好主意(响应能力等(

我已经用jsfiddle在html/css中复制了具有绝对定位的设计:

ul {
list-style: none;
display: flex;
position: relative;
}
li {
padding: 5px 15px;
position: absolute;
animation-name: menu-fold;
animation-duration: 3s;
animation-iteration-count: infinite;
}
li:nth-child(1) { right: 0; }
li:nth-child(2) { right: 119px; }
li:nth-child(3) { right: 238px; }
li:nth-child(4) { right: 357px; }
li:nth-child(5) { right: 476px; }
@keyframes menu-fold {
from {
opacity: 1;
}

to {
opacity: 0;
right: 0
}
}
<ul>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
</ul>

如何在保持响应能力的同时制作这种动画?

(我知道JavaScript会有一些方法-尽管我还没有尝试过-但如果可能的话,我希望避免使用JavaScript。如果你说只有JS才有可能,我仍然想听听你的建议:p(

//编辑1:我想出了一个快速的jQuery解决方案,但是,我不知道,我仍然想避免它。至少它感觉不是一个好的解决方案:

var lastItemX = $('ul li').last().position().left;
$('ul li').each(function() {
var currentItemX = $(this).position().left;
$(this).css('transform', `translateX(${lastItemX - currentItemX}px)`)
})
html, body {
margin: 0;
padding: 0;
}
ul {
padding: 0;
list-style: none;
display: flex;
position: relative;
}
li {
padding: 5px 15px;
transition: transform 3s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
</ul>

这是一种方法,使用flex,转换width,并使用:hover,其中只有第一个元素可见,直到您悬停在它上面:

.my-list {
list-style: none;
padding: 0;
display: flex;
margin-left: auto;
background: yellow;
width: 20%;
transition: width 0.5s ease;
overflow: hidden
}
.my-list:hover {
width: 100%;
}
.my-list li {
display: none;
flex: auto;
background: orange
}
.my-list li:first-child,
.my-list:hover li {
display: block;
width: 20%;
margin: 5px;
padding: 5px;
}
<div>
<ul class="my-list">
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
</ul>
</div>

设计本身并不是响应能力最好的,任何超过15个字符的菜单项在较小的显示器上都不会很好看,因为没有足够的可用宽度。

JavaScript的一个常见用途是通过一些去抖动/节流机制来防止动画抖动,并且可以通过切换CSS类名将动画本身留给CSS。

这里有一种替代方法,每个项目都占据整个宽度并有一个固定的高度:(JS只切换CSS类(

function myListOpen() {
document.querySelector(".my-list").classList.add("open")
}
function myListClose() {
document.querySelector(".my-list").classList.remove("open")
}
.my-list {
list-style: none;
margin-left: auto;
background: yellow;
padding: 5px;
width: 20%;
overflow: hidden;
transition: width 0.5s ease;
}
.my-list.open {
width: 100%;
}
.my-list li {
background: orange;
margin: 0;
padding: 0;
padding-left: 1em;
height: 0;
line-height: 2em;
transition: height 0.5s ease;
}
.my-list li:first-child,
.my-list.open li {
height: 2em;
visibility: visible;
}
<button type="button" onclick="myListOpen()">open</button>
<button type="button" onclick="myListClose()">close</button>
<hr />
<div>
<ul class="my-list">
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
<li>Menu Item 1</li>
</ul>
</div>

最新更新