Recently one of my students had the interesting concept of a menu with a sliding, animated highlight, but was unsure of how to create it in code. After messing around with a few possibilities after class, this is my response.
最近,我的一个学生有了一个有趣的菜单概念,即带有滑动的动画高亮显示,但是不确定如何用代码创建菜单。 下课后弄乱了几种可能性,这是我的回应。
The markup is fairly straightforward:
标记非常简单:
<header id="cylons">
<img src="cylon-centurion.png" alt>
<h1>By Your Command</h1>
<h2>The Cylon Centurion Fansite</h2>
<nav id=cylon-nav>
<a href="#">Base</a>
<a href="#">Codex</a>
<a href="#">Interface</a>
<a href="#">Operations</a>
</nav>
</header>
One particular challenge was making the red highlight, visible on mouseover on each navigation element, both responsive and easily animated. Traditionally, this would be tackled by using JavaScript to read the getComputedStyle
of the navigation elements, inclucing their current position and width, and moving another element behind them to match a changing location and dimension. After playing around with different techniques, I realised that I could solve the problem elegantly by using a background linear gradient with background-position
.
一个特殊的挑战是使红色高亮显示在每个导航元素上的鼠标悬停时都可见,既响应又容易动画。 传统上,这通过将使用JavaScript来读取加以解决getComputedStyle
导航元素,inclucing其当前位置和宽度,并移动另一元件他们后面以匹配变化的位置和尺寸。 在尝试了各种技术之后,我意识到可以通过使用background-position
的背景线性渐变来优雅地解决该问题。
If each of the links takes up an equal amount of space:
如果每个链接占用相等的空间:
#cylons a {
color: currentColor;
text-align: center;
text-decoration: none;
display: inline-block;
width: 20%;
padding: 0 1rem;
font-size: 1.2rem;
}
Then the highlight behind them (created out of a solid linear gradient, meaning that the start and end colors are exactly the same) can use the same horizontal size:
然后,它们后面的突出显示(由实心线性渐变创建,这意味着开始和结束颜色完全相同)可以使用相同的水平尺寸:
#cylonnav {
font-size: 0;
text-align: right;
background-image: linear-gradient(90deg, #f00, #f00);
background-position: 0% 0;
background-size: 20% 100%;
background-repeat: no-repeat;
transition: .5s background-position linear;
}
Note that location as a percentage will not work unless background-size
is also set.
请注意,除非还设置了background-size
否则位置百分比将不起作用 。
百分比混淆 (A Confusion of Percentages)
Testing background-position
by hard-coding changes into the CSS, I realised something a little confusing: the starting location of the gradient is measured from the background's left. This lead to the following script:
通过将更改硬编码到CSS中来测试background-position
,我意识到有些困惑:渐变的起始位置是从背景的左侧开始测量的。 这导致以下脚本:
function woosh(e) {
e.preventDefault();
var index = links.indexOf(e.target);
nav.style.backgroundPosition = (basePercentage * (index + 1)) + "% 0%";
}
var nav = document.getElementById("cylonnav"),
links = Array.prototype.slice.call(nav.getElementsByTagName("a"), 0),
basePercentage = 100 / links.length;
nav.addEventListener("mouseover", woosh, false);
The JavaScript looks at the navigation and uses the number of links found inside it as a percentage multiplier to locate the background. Note that the script looks at mouseover activity on the navigation element in general, then determines which link is actually being hovered over; a far more efficient process than trying to track activity on each link.
JavaScript查看导航,并使用在导航中找到的链接数作为百分比乘数来定位背景。 请注意,该脚本通常查看导航元素上的鼠标悬停活动, 然后确定实际将鼠标悬停在哪个链接上。 这比尝试跟踪每个链接上的活动要有效得多。
You can find the full code for the UI on the associated CodePen demo; the one small issue with this approach is that the movement between any links is always constant in time, making the highlight appear to move twice as fast between “base” and “interface” as it does between “base” and “codex”.
您可以在相关的CodePen演示中找到UI的完整代码; 这种方法的一个小问题是,任何链接之间的移动在时间上始终是恒定的,从而使高亮显示在“基本”和“接口”之间的移动速度是在“基本”和“法典”之间移动的两倍。
翻译自: https://thenewcode.com/624/By-Your-Command-A-Cylon-Inspired-UI