やりたいこと
- ヒーローイメージを6秒毎に6枚フェードで切り替え。
- JavaScriptやjQeryは使わずにcssアニメーションで実装。
- フェードイン後は徐々にズームしていく感じ。
ヒーローイメージを6枚用意
本来ならpicture要素を使ったりしますが
今回はシンプルにstyle属性で背景画像6枚を指定します。
<div class="hero">
<div class="hero__bg" style="background-image: url(./);"></div>
<div class="hero__bg" style="background-image: url(./);"></div>
<div class="hero__bg" style="background-image: url(./);"></div>
<div class="hero__bg" style="background-image: url(./);"></div>
<div class="hero__bg" style="background-image: url(./);"></div>
<div class="hero__bg" style="background-image: url(./);"></div>
</div>
スタイルの指定
親ブロックのスタイル
.hero
というblockが基準となるのでposition: relative;
を指定。- スライドの幅や高さを指定。
overflow: hidden;
で、imgがズームした時にはみ出た部分を隠す。
.hero {
height: 100vh;
width: 100%;
position: relative;
overflow: hidden;
}
背景画像の共通スタイル
- 初期値を
opacity: 0;
にして表示を隠す。 position: absolute;
で、スライドの中身を.hero
に合わせて重ねる。animation: anime 36s 0s infinite;
で6枚のスライドを6秒ずつ、36秒間かけてアニメーションし、infiniteによって再生をループ。
.hero__bg {
position: absolute;
z-index:10;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100vh;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
animation: anime 36s 0s infinite;
}
それぞれの背景画像にアニメーションをつける
animation-delay:
で、アニメーションの開始時間を6秒ごとに次の画像が現れるようにずらします。
.hero__bg:nth-of-type(2) {
animation-delay: 6s;
}
.hero__bg:nth-of-type(3) {
animation-delay: 12s;
}
.hero__bg:nth-of-type(4) {
animation-delay: 18s;
}
.hero__bg:nth-of-type(5) {
animation-delay: 24s;
}
.hero__bg:nth-of-type(6) {
animation-delay: 30s;
}
Sassを使ってるのであれば、ループで記述しても良いかと思います。
//for文で記述
.hero__bg {
@for $i from 2 through 6 {
&:nth-of-type(#{$i}) {
animation-delay: ($i - 1) * 6;
}
}
}
@keyframesの指定
opacity: 0;
で表示の変更transform: scale;
でサイズの変更をします。
- 3秒目から、3秒目かけてフェードイン。
36秒間かけてアニメーションするので、3秒は8%、6秒は17%。
- 6秒後に次のスライドが再生されるので、ここからまた3秒目かけてフェードアウト。
この間、1.2倍まで画像はズームされる。
- 6枚目よりも1枚目が上に来るように
z-index
を一つ下げる。
@keyframes anime {
0% {
opacity: 0;
}
8% {
opacity: 1;
}
17% {
opacity: 1;
}
25% {
opacity: 0;
transform: scale(1.2) ;
z-index:9;
}
100% { opacity: 0 }
}
サンプルコード
.hero {
height: 100vh;
width: 100%;
position: relative;
overflow: hidden;
}
.hero__bg {
position: absolute;
z-index:10;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100vh;
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
animation: anime 36s 0s infinite;
}
.hero__bg:nth-of-type(2) {
animation-delay: 6s;
}
.hero__bg:nth-of-type(3) {
animation-delay: 12s;
}
.hero__bg:nth-of-type(4) {
animation-delay: 18s;
}
.hero__bg:nth-of-type(5) {
animation-delay: 24s;
}
.hero__bg:nth-of-type(6) {
animation-delay: 30s;
}
@keyframes anime {
0% {
opacity: 0;
}
8% {
opacity: 1;
}
17% {
opacity: 1;
}
25% {
opacity: 0;
transform: scale(1.2);
z-index: 9;
}
100% {
opacity: 0;
}
}