CSS & JS Effect – Hero Banner Swiper
效果
重点
1. 一张图片, 一个 content 定位居中作为一个 slide
2. slider 用了 JavaScript Library – Swiper
3. 当 slide active 的时候做一个 animation 把 content 划出来.
Swiper & Layout
HTML
<div class="swiper"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="../images/hero-banner-1.jpg" /> <h1>Reliable Air Conditioning</h1> <h2>Installation, Services & Repair</h2> <p>100% Satisfaction Guarantee With Everything Thing We Do!</p> <a href="#">Get an Estimate</a> </div> </div> </div>
.swiper > .swiper-wrapper > .swiper-slide 是 swiper 的布局.
内容是 img 和 4 个行 text
效果
在没有任何 CSS 情况下, swiper 的 height 是 hug content.
Set Dimension
.swiper { height: 50vh; img { width: 100%; height: 100%; object-fit: cover; } }
让 swiper 控制高度, 里面的图片 follow
Set Position
<div class="swiper-slide"> <img src="../images/hero-banner-1.jpg" /> <div class="content-container"> <div class="content"> <h1>Reliable Air Conditioning</h1> <h2>Installation, Services & Repair</h2> <p>100% Satisfaction Guarantee With Everything Thing We Do!</p> <a href="#">Get an Estimate</a> </div> </div> </div>
加上 content-container 和 content 把内容 wrap 起来, 然后 CSS 定位 aligh
.swiper { position: relative; .content-container { position: absolute; inset: 0; max-width: 1024px; margin-inline: auto; display: flex; align-items: center; } }
点缀 CSS
.swiper { .content-container { .content { display: flex; flex-direction: column; gap: 1rem; h1 { line-height: 1; letter-spacing: 0; color: #003056; font-size: 4rem; font-weight: 100; } h2 { line-height: 1; color: #003056; font-size: 2.5rem; } a { display: inline-block; padding: 1rem 1.5rem; text-transform: uppercase; background-color: hsl(195, 100%, 43%); color: white; align-self: flex-start; text-decoration: none; border-radius: 4px; } } } }
效果
到这里就有一个型了, 剩下的就是 animation 了.
Animation
放慢来看, 它的 animation 是字从下面划出来. 大概像上面这样.
做 wrapper
要实现这个效果, 首先要把内容藏起来
为每个 text 做一个 wrapper, overflow-y: hidden, 然后让内容 translateY 100%, 内容就完全藏起来了, 待会交出来就可以了.
.wrapper { transition: transform 0.4s 0.2s; transform: translateY(50%); overflow-y: hidden; * { transition: transform 0.4s 0.2s; transform: translateY(100%); } }
wrapper 也设置一个 transition, 这样一起动效果更好哦.
.swiper-slide-active
当 slide active 的时候, swiper 会给一个 swiper-slide-active class, 借助这个 class 就可以设置让内容出现了.
.swiper { .swiper-slide-active .content-container .content .wrapper { transform: initial; * { transform: initial; } } }
完整代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Simple Test (Webpack)</title> </head> <body> <header>Header</header> <main> <section class="hero-banner-section"> <div class="swiper"> <div class="swiper-wrapper"> <div class="swiper-slide"> <img src="../images/hero-banner-1.jpg" /> <div class="content-container"> <div class="content"> <div class="wrapper"> <h1>Reliable Air Conditioning</h1> </div> <div class="wrapper"> <h2>Installation, Services & Repair</h2> </div> <div class="wrapper"> <p>100% Satisfaction Guarantee With Everything Thing We Do!</p> </div> <div class="wrapper"> <a href="#">Get an Estimate</a> </div> </div> </div> </div> <div class="swiper-slide"> <img src="../images/hero-banner-2.jpg" /> <div class="content-container"> <div class="content"> <div class="wrapper"> <h1>Reliable Air Conditioning</h1> </div> <div class="wrapper"> <h2>Installation, Services & Repair</h2> </div> <div class="wrapper"> <p>100% Satisfaction Guarantee With Everything Thing We Do!</p> </div> <div class="wrapper"> <a href="#">Get an Estimate</a> </div> </div> </div> </div> </div> <div class="swiper-button-next"></div> <div class="swiper-button-prev"></div> </div> </section> </main> </body> </html>
CSS Style
* { margin: 0; padding: 0; box-sizing: border-box; } img, svg { display: block; } header { height: 225px; display: flex; justify-content: center; align-items: center; font-size: 32px; background-color: pink; } .swiper { height: 400px; .swiper-slide { img { width: 100%; height: 100%; object-fit: cover; } position: relative; .content-container { position: absolute; inset: 0; max-width: 1024px; margin-inline: auto; display: flex; align-items: center; .content { display: flex; flex-direction: column; gap: 1rem; .wrapper { transition: transform 0.4s 0.2s; transform: translateY(50%); overflow-y: hidden; * { transition: transform 0.4s 0.2s; transform: translateY(100%); } } h1 { line-height: 1; letter-spacing: 0; color: #003056; font-size: 4rem; font-weight: 100; } h2 { line-height: 1; color: #003056; font-size: 2.5rem; } a { display: inline-block; padding: 1rem 1.5rem; text-transform: uppercase; background-color: hsl(195, 100%, 43%); color: white; align-self: flex-start; text-decoration: none; border-radius: 4px; } } } &.swiper-slide-active { .content-container .content .wrapper { transform: initial; * { transform: initial; } } } } }
JavaScript
import './home.scss'; import Swiper, { Navigation } from 'swiper'; import 'swiper/css'; import 'swiper/css/navigation'; new Swiper('.swiper', { modules: [Navigation], navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, });