在本教程中,我们将学习如何在滚动时为标题元素设置动画。首先,我们将构建一个具有三种不同布局的完全响应式顶部导航标题:一种用于小屏幕,一种用于中屏,一种用于大屏幕及以上。
接下来,我们将在一定量的滚动后,在中等屏幕及以上屏幕上平滑地为它的号召性用语按钮设置动画。听起来很有趣,可以加入我的旅程吗?
我们将建造什么
这是相应的Codepen 演示 (查看 大版本 以了解布局的变化):
See the Pen How to Build Fixed Headers With Animated Content on Scroll by Envato Tuts+ (@tutsplus) on CodePen.
让我们开始吧!
1. 从页面标记开始
我们的页面将包含一个标题和两个帮助部分。在标题内,我们将放置一个导航栏。这将包括:
图像标志。
主菜单。它的最后三个项目将仅在小屏幕上可见。
二级菜单。这将出现在大于 767 像素的屏幕上。在较小的屏幕上,其项目将成为主菜单的一部分。
负责切换移动菜单的按钮。这将在高达 1100 像素的屏幕上可见。
这是标记:
<header class="page-header">
<nav>
<a href="">
<img src="IMG_SRC" alt="">
</a>
<ul class="main-menu">
<li>
<a href="">Work</a>
</li>
<li>
<a href="">About</a>
</li>
<li>
<a href="">Clients</a>
</li>
<li>
<a href="">News</a>
</li>
<li>
<a href="">Login</a>
</li>
<li>
<a href="">Pricing</a>
</li>
<li class="btn-wrapper">
<a href="" class="btn">Sign Up</a>
</li>
</ul>
<ul class="secondary-menu">
<li>
<a href="">Login</a>
</li>
<li>
<a href="">Pricing</a>
</li>
<li>
<a href="" class="btn">Sign Up</a>
</li>
</ul>
<button class="toggle-mobile-menu" aria-label="Open Mobile Menu" type="button">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" class="open-menu" aria-hidden="true">...</svg>
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" class="close-menu" aria-hidden="true">...</svg>
</button>
</nav>
</header>
<section class="hero">...</section>
<section class="main-content">...</section>
除了标题之外,我们将创建两个带有虚拟内容的部分来测试滚动效果。为了简单起见,对于这些元素,我们不会讨论它们的样式。
注意#1:为了避免创建重复的内容,我们可以通过 javascript 动态添加它们,而不是通过 html 附加主菜单的最后三个项目。请记住,这些最初是二级菜单的一部分。
注意#2:在本教程中,我不会介绍如何使移动菜单完全可访问。我刚刚使用了aria-label 值将通过 JavaScript 和属性更新的aria-hidden属性。
2. 定义一些基本样式
准备好标记后,我们将定义一些基本的 css 样式。这些将包括Google 字体、一些自定义变量和一些重置规则:
:root {
--white: white;
--deeppurple: #7c2a8a;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
ul {
list-style: none;
}
button {
background: none;
border: none;
outline: none;
cursor: pointer;
}
a {
text-decoration: none;
color: inherit;
}
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.35);
}
::-webkit-scrollbar-thumb {
background: var(--deeppurple);
}
body {
font: 20px/1.5 "Inter", sans-serif;
}
在上面的样式中,为了好玩,我们添加了一些用于自定义默认滚动条样式的样式。
请记住,并非所有浏览器(例如 Firefox 80)都会采用这种新外观。
此外,我们将指定三个辅助类来控制元素的可见性。我们稍后会在通过 javaScript 切换移动菜单时使用它们。他们的名字灵感来自 Bootstrap 4 的类名:
.d-block {
display: block !important;
}
.d-flex {
display: flex !important;
}
.d-none {
display: none !important;
}
请注意,所有内容都包括该 important 属性。作为一般规则,我们应该避免使用此属性,因为它会弄乱样式并使调试变得困难。不过,在我们的示例中,我们将使用它通过 JavaScript 将样式应用于具有不同特定级别的元素。
3. 设置标题样式
要构建标题布局,我们将遵循桌面优先的方法。
大屏幕
在大屏幕(>1100px)上,它的布局应该是这样的:
在此刻:
标题将是具有静态高度的固定定位元素。
导航将是一个弹性容器。它的内容将在横轴上垂直居中,并在主轴上水平分布。
主菜单也将是一个带有垂直居中项目的弹性容器。
默认情况下,二级菜单的最后一项(号召性用语按钮)将在屏幕外显示。要将其推出屏幕,我们将提供其父列表transform: translateX(200px)。数字 200 是通过添加按钮的宽度 (150px) 和二级菜单的列表项之间的间距 (50px) 得出的。
汉堡切换按钮将被隐藏。这还将包含取自CSS.gg的两个图标。
相关样式:
/*CUSTOM VARIABLES HERE*/
.page-header {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
height: 100px;
}
.page-header nav {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
padding: 0 15px;
background: var(--white);
box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.15);
}
.page-header ul {
display: flex;
align-items: center;
}
.page-header .main-menu {
margin-left: 100px;
}
.page-header .main-menu li:nth-last-child(-n + 3) {
display: none;
}
.page-header .secondary-menu {
transform: translateX(200px);
transition: transform 0.3s ease-out;
}
.page-header li:not(:last-child) {
margin-right: 50px;
}
.page-header .btn {
display: inline-block;
width: 150px;
text-align: center;
font-weight: 900;
padding: 12px 6px;
border-radius: 5px;
color: var(--white);
background: var(--deeppurple);
}
.page-header a {
font-size: 18px;
color: var(--deeppurple);
}
.page-header .toggle-mobile-menu {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.page-header .toggle-mobile-menu .close-menu {
display: none;
}
.page-header .toggle-mobile-menu path {
fill: var(--deeppurple);
}
中等屏幕
在中等屏幕(≥768px 和 ≤1100px)上,它的布局应该是这样的:
在此刻:
主菜单将绝对定位并移至标题下方。它也将默认隐藏并在我们单击汉堡包按钮时出现。此外,其项目将平均分配给其父项。
号召性用语按钮仍在屏幕外,但这次我们将提供其父transform: translateX(170px) 项,因为列表项之间的间隙减小到 20 像素。
汉堡切换按钮将变得可见。
相关样式:
/*CUSTOM VARIABLES HERE*/
@media screen and (max-width: 1100px) {
.page-header img {
max-width: 140px;
}
.page-header .main-menu {
display: none;
position: absolute;
top: 100px;
left: 0;
right: 0;
padding: 15px;
margin-left: 0;
text-align: center;
z-index: 1;
background: var(--white);
box-shadow: 0 6px 10px rgba(0, 0, 0, 0.15);
}
.page-header .main-menu li {
flex: 1;
}
.page-header .secondary-menu {
transform: translateX(170px);
}
.page-header li:not(:last-child) {
margin-right: 20px;
}
.page-header .toggle-mobile-menu {
display: block;
}
}
小屏幕
最后,在窄屏(<768px)上,它的布局应该是这样的:
在此刻:
主菜单项将被堆叠。此外,最后三个项目将变得可见。
二级菜单将被隐藏。
滚动不会有任何动画。默认情况下,号召性用语将是可见的、绝对定位的,并且是移动菜单的一部分。
@media screen and (max-width: 767px) {
.page-header {
height: 70px;
}
.page-header .main-menu {
top: 70px;
flex-direction: column;
align-items: start;
}
.page-header .main-menu li {
flex-grow: 0;
}
.page-header .main-menu li + li {
margin-top: 15px;
}
.page-header .main-menu li:nth-last-child(-n + 3) {
display: block;
}
.page-header .secondary-menu {
display: none;
}
.page-header .toggle-mobile-menu {
position: static;
transform: none;
}
.page-header .btn-wrapper {
position: absolute;
top: 0;
right: 15px;
}
.page-header .btn {
width: 120px;
padding: 8px 16px;
}
}
4. 滚动动画
当我们在页面中滚动时,我们将跟踪我们滚动了多少,并且在一定的滚动量下,我们将通过切换show-btn类来平滑地为标题按钮的可见性设置动画。
在我们的示例中,一旦英雄部分消失,按钮就会滑入,反之亦然。
targetScroll 在您的项目中,您可以通过变量轻松更改按钮应显示多少滚动。在这里,您可以传递硬编码值或动态值。
这是所需的 JavaScript 代码:
const pageHeader = document.queryselector(".page-header");
const animatedUl = pageHeader.querySelector(".secondary-menu");
const showBtn = "show-btn";
let targetScroll = window.innerHeight - pageHeader.offsetHeight;
window.addeventListener("scroll", () => {
const scrollY = this.pageYOffset;
if (scrollY > targetScroll) {
animatedUl.classList.add(showBtn);
} else {
animatedUl.classList.remove(showBtn);
}
});
window.addEventListener("resize", () => {
targetScroll = window.innerHeight - pageHeader.offsetHeight;
});
和目标 CSS 类:
.page-header .secondary-menu.show-btn {
transform: none;
}
5. 切换移动菜单
最后,为了让标题完全响应,让我们创建移动菜单的功能。
一旦我们点击汉堡按钮,移动菜单的可见性就会被切换。那时,我们将大量使用辅助类。
以下是相关的 JavaScript 代码:
const pageHeader = document.querySelector(".page-header");
const mainMenu = pageHeader.querySelector(".main-menu");
const openMenu = pageHeader.querySelector(".open-menu");
const closeMenu = pageHeader.querySelector(".close-menu");
const toggleMobileMenu = pageHeader.querySelector(".toggle-mobile-menu");
const dNone = "d-none";
const dBlock = "d-block";
const dFlex = "d-flex";
toggleMobileMenu.addEventListener("click", function () {
mainMenu.classList.toggle(dFlex);
if (!openMenu.classList.contains(dNone)) {
this.setAttribute("aria-label", "Close Mobile Menu");
openMenu.classList.remove(dBlock);
openMenu.classList.add(dNone);
closeMenu.classList.remove(dNone);
closeMenu.classList.add(dBlock);
} else {
this.setAttribute("aria-label", "Open Mobile Menu");
openMenu.classList.remove(dNone);
openMenu.classList.add(dBlock);
closeMenu.classList.remove(dBlock);
closeMenu.classList.add(dNone);
}
});
您已经在 Scroll 上构建了响应式标题动画!
就是这样,伙计们!今天我们讨论了如何在滚动时创建带有动画内容的响应式页眉。正如我们所看到的,只需几个步骤,我们就可以构建这种功能并制作引人注目的页面。
See the Pen How to Build Fixed Headers With Animated Content on Scroll by Envato Tuts+ (@tutsplus) on CodePen.
- 大屏幕
- 中等屏幕
- 小屏幕