CSSのみで雨が降るアニメーションサンプル
ピュアなCSSのみで雨を降らせてみたアニメーションサンプルです。
雨が降るパターンの各アニメーションにanimationプロパティと@keyframes(キーフレーム)を使ったサンプルコードを紹介しています。
追記:雪が降るバージョンもできました。
背景に雨が降るCSSアニメーションサンプル
See the Pen CSS Rain Animation by yochans (@yochans) on CodePen.
<div class="container">
<div class="rains">
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
</div>
<p>雨を降らせてみた。</p>
</div>
.container{
display:flex;
justify-content: center;
align-items: center;
position:relative;
width: 100%;
height:200px;
background:#0c0c33;
overflow: hidden;
}
.container p{
padding:20px;
margin:0;
font-size:40px;
font-weight: bold;
color:#FFF;
}
.rains{
position: absolute;
left:0;
top:0;
width: 100%;
height:100%;
}
/*widthは雨の太さ、heightは長さ*/
.rains span{
position: absolute;
width:1px;
height:180px;
background:#FFF;
opacity:0.4;
}
/*雨の初期位置とアニメーション指定、leftはx座標での基準位置、topは開始位置、アニメーション時間は揺らぎ*/
.rains span:nth-child(1){left:5%; top:-190px; animation: rain-anim 10s infinite;}
.rains span:nth-child(2){left:10%; top:-180px; animation: rain-anim 11s infinite;}
.rains span:nth-child(3){left:15%; top:-170px; animation: rain-anim 8s infinite;}
.rains span:nth-child(4){left:20%; top:-160px; animation: rain-anim 12s infinite;}
.rains span:nth-child(5){left:25%; top:-150px; animation: rain-anim 10s infinite;}
.rains span:nth-child(6){left:30%; top:-150px; animation: rain-anim 11s infinite;}
.rains span:nth-child(7){left:35%; top:-160px; animation: rain-anim 13s infinite;}
.rains span:nth-child(8){left:40%; top:-170px; animation: rain-anim 7s infinite;}
.rains span:nth-child(9){left:45%; top:-180px; animation: rain-anim 9s infinite;}
.rains span:nth-child(10){left:50%; top:-190px; animation: rain-anim 11s infinite;}
.rains span:nth-child(11){left:55%; top:-190px; animation: rain-anim 10s infinite;}
.rains span:nth-child(12){left:60%; top:-180px; animation: rain-anim 6s infinite;}
.rains span:nth-child(13){left:65%; top:-170px; animation: rain-anim 14s infinite;}
.rains span:nth-child(14){left:70%; top:-160px; animation: rain-anim 12s infinite;}
.rains span:nth-child(15){left:75%; top:-150px; animation: rain-anim 10s infinite;}
.rains span:nth-child(16){left:80%; top:-150px; animation: rain-anim 14s infinite;}
.rains span:nth-child(17){left:85%; top:-160px; animation: rain-anim 8s infinite;}
.rains span:nth-child(18){left:90%; top:-170px; animation: rain-anim 9s infinite;}
.rains span:nth-child(19){left:95%; top:-180px; animation: rain-anim 11s infinite;}
.rains span:nth-child(20){left:100%; top:-190px; animation: rain-anim9 13s infinite;}
/*アニメーションキーフレーム
一度落下したら次はキーフレーム1%の間に高さを戻して左右にずらして降らす*/
@keyframes rain-anim {
0% { transform: translate(0px,0px);}
4% { transform: translate(0px,600px);}
5% { transform: translate(200px,0px);}
9% { transform: translate(200px,600px);}
10% { transform: translate(-100px,0px);}
14% { transform: translate(-100px,600px);}
15% { transform: translate(-200px,0px);}
19% { transform: translate(-200px,600px);}
20% { transform: translate(100px,0px);}
24% { transform: translate(100px,600px);}
25% { transform: translate(-150px,0px);}
29% { transform: translate(-150px,600px);}
30% { transform: translate(-80px,0px);}
34% { transform: translate(-80px,600px);}
35% { transform: translate(150px,0px);}
39% { transform: translate(150px,600px);}
40% { transform: translate(-60px,0px);}
44% { transform: translate(-60px,600px);}
45% { transform: translate(90px,0px);}
49% { transform: translate(90px,600px);}
50% { transform: translate(60px,0px);}
54% { transform: translate(60px,600px);}
55% { transform: translate(-60px,0px);}
59% { transform: translate(-60px,600px);}
60% { transform: translate(-40px,0px);}
64% { transform: translate(-40px,600px);}
65% { transform: translate(40px,0px);}
69% { transform: translate(40px,600px);}
70% { transform: translate(-20px,0px);}
74% { transform: translate(-20px,600px);}
75% { transform: translate(-110px,0px);}
79% { transform: translate(-110px,600px);}
80% { transform: translate(20px,0px);}
84% { transform: translate(20px,600px);}
85% { transform: translate(-20px,0px);}
89% { transform: translate(-20px,600px);}
90% { transform: translate(50px,0px);}
99% { transform: translate(50px,600px);}
100% { transform: translate(0px,0px);}
}
ひとつの雨でいくつものパターンを作る為に@keyframesの進行分割区切りが多くなってしまいました。
乱数の使えないピュアCSSですが、見た目上はSCSSやJavaScriptで乱数を使った場合に近づけれたと思います。
写真画像に雨が降るCSSアニメーションサンプル
See the Pen CSS Rain Animation (picture) by yochans (@yochans) on CodePen.
雨が似合いそうな写真・画像を背景にしてみました。
上記のサンプルコードに以下のCSSを追加する事で実装しています。
全コードはcodePenページよりどうぞ。
.container img{
width: 100%;
filter: brightness(0.5);
}
テキストと写真・画像を組み合わせる場合は、pタグのpositionプロパティをabsoluteに変更します。
.container p{
position: absolute;
left: 10px;
top: 10px;
font-size: 32px;
font-weight: bold;
color: #FFF;
}
雨脚も加えた雨降りCSSアニメーションデザインサンプル
See the Pen CSS Rain Animation (& splat) by yochans (@yochans) on CodePen.
雨に加えて、雨脚(?)地面に雨があたる様も追加した雨が降っている感じのCSSデザインです。
HTMLにクラス「splat」を追加しています。
<div class="container">
<img src="https://1-notes.com/images/ishidatami.jpg" border="0" />
<div class="rains">
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
</div>
<div class="splat">
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
<span></span><span></span><span></span><span></span><span></span>
</div>
</div>
雨脚用のCSSとして以下のコードを追加しています。
雨と同じく位置は相対値で指定しているので、ボックスサイズや画像などの要素の大きさに対応しています。
/*splat*/
.splat{
position: absolute;
left:0;
top:0;
width: 100%;
height:100%;
}
.splat span{
position: absolute;
width:100px;
height:30px;
background:#FFF;
border-radius: 50%;
opacity:0;
}
.splat span:nth-child(1){left: 0%; top:30%; animation: splat-anim 5.5s infinite;}
.splat span:nth-child(2){left:10%; top:90%; animation: splat-anim 7.2s infinite;}
.splat span:nth-child(3){left:15%; top:15%; animation: splat-anim 4.3s infinite;}
.splat span:nth-child(4){left:20%; top:20%; animation: splat-anim 5.7s infinite;}
.splat span:nth-child(5){left:25%; top:80%; animation: splat-anim 6.3s infinite;}
.splat span:nth-child(6){left:30%; top:35%; animation: splat-anim 8.5s infinite;}
.splat span:nth-child(7){left:35%; top:70%; animation: splat-anim 7.7s infinite;}
.splat span:nth-child(8){left:40%; top:10%; animation: splat-anim 4.8s infinite;}
.splat span:nth-child(9){left:45%; top:65%; animation: splat-anim 5.3s infinite;}
.splat span:nth-child(10){left:50%; top:55%; animation: splat-anim 3.5s infinite;}
.splat span:nth-child(11){left:55%; top:30%; animation: splat-anim 5.1s infinite;}
.splat span:nth-child(12){left:60%; top:75%; animation: splat-anim 7.1s infinite;}
.splat span:nth-child(13){left:65%; top:15%; animation: splat-anim 4.2s infinite;}
.splat span:nth-child(14){left:70%; top:60%; animation: splat-anim 5.0s infinite;}
.splat span:nth-child(15){left:75%; top:50%; animation: splat-anim 3.0s infinite;}
.splat span:nth-child(16){left:80%; top:10%; animation: splat-anim 6.4s infinite;}
.splat span:nth-child(17){left:85%; top:45%; animation: splat-anim 5.9s infinite;}
.splat span:nth-child(18){left:90%; top:55%; animation: splat-anim 7.0s infinite;}
.splat span:nth-child(19){left:95%; top:25%; animation: splat-anim 4.0s infinite;}
.splat span:nth-child(20){left:100%; top:85%; animation: splat-anim 8.2s infinite;}
@keyframes splat-anim {
0% { opacity:0.0; transform: scale(0);}
10% { opacity:0; transform: scale(0);}
14% { opacity:0.3; transform: scale(0.4);}
15% { opacity:0; transform: scale(0);}
30% { opacity:0; transform: scale(0);}
34% { opacity:0.2; transform: scale(0.8);}
35% { opacity:0; transform: scale(0);}
40% { opacity:0; transform: scale(0);}
44% { opacity:0.2; transform: scale(0.2);}
45% { opacity:0; transform: scale(0);}
50% { opacity:0; transform: scale(0);}
54% { opacity:0.2; transform: scale(0.5);}
55% { opacity:0; transform: scale(0);}
64% { opacity:0; transform: scale(0);}
70% { opacity:0.1; transform: scale(1.0);}
71% { opacity:0; transform: scale(0);}
100% { opacity:0; transform: scale(0);}
}
横殴りの雨バージョン
コメントにてフジカワ様より質問を頂いた横殴りの雨バージョンです。
See the Pen CSS Rain Animation (& splat) 2 by yochans (@yochans) on CodePen.
簡単に実装できそうな方法で、雨脚の部分にtransform: rotate()を追加して角度を調節してみました。(単位は角度)
CSSの変更部分は.rainsの一行みとなります。
.rains{
position: absolute;
left:0;
top:0;
width: 100%;
height:100%;
transform: rotate(20deg);
}
記事作成時に横殴りの雨という発想に辿り着けませんでしたが、横殴りの雨の方が雰囲気出で良いですね、コメントありがとうございました。
ディスカッション
質問させてください。
このコードをベースに雨を斜めに(横殴りの雨を表現)するにはどうしたらいいでしょうか?
コメントありがとうございます。
横殴りの雨について記事に追加させて頂きました。
ありがとうございます。
今後も参考にさせていただきます。
【WEB制作】雨っぽくしたくてあれこれ
ちょっと前から回天狼というサイトの運営を始めました。7/10くらいに公開したばかりですが、ちょこちょこ更新していく予定なのでもしご興味あれば覗いていただけると嬉しいです。ひ…