CSSのanimationで画像の上に複数のテロップを流す方法
以前、「CSSだけで数珠つなぎに無限ループするニュースティッカーを作ってみる」と題して、右から左にテキストが流れるニュースティッカーを作りましたが、ちょっとこれをテロップのように画像の上に重ねてみたいなと思って、少し改造してみました。
実行例
テロップを流すテスト1
テロップを流すテスト2
テロップを流すテスト3
…うーん、テロップというか、ニコニコ静画のようになってしまったw
HTML部分の解説
<div class="telop">
<img src="[画像ファイル]">
<p>テロップを流すテスト1</p>
<p>テロップを流すテスト2</p>
<p>テロップを流すテスト3</p>
</div>
極シンプルに表示したい画像と表示したいテキストを用意し、クラス名telopで囲っているだけです。
CSS部分の解説
<style>
.telop {
position:relative;
width:600px;
overflow:hidden;
}
.telop img {
width:100%;
}
.telop p {
position:absolute;
bottom:0;
left:100%;
font-size:1.4em;
color:white;
text-shadow:1px 1px 2px black;
white-space:nowrap;
}
.telop p:nth-of-type(1) {
animation:hscroll 6s linear 1s infinite;
bottom:5em;
}
.telop p:nth-of-type(2) {
animation:hscroll 6s linear 2s infinite;
bottom:3em;
}
.telop p:nth-of-type(3) {
animation:hscroll 6s linear 3s infinite;
bottom:1em;
}
@keyframes hscroll {
0% { transform:translateX(0); }
100% { transform:translateX(calc(-100% - 600px)); }
}
</style>
囲んでいるdivタグの中でアニメーションを完結させるため、幅は600px固定にして、overflow:hidden;を指定することで、はみ出たテキストは表示しないようにしています。
テキスト…つまりPタグはtransform:translateX(0);(left:600pxが指定されているので右側の欄外)からスタートして、transform:translateX(calc(-100% + -600px));(左側の欄外)まで移動するためですね。
calcを使っているのは-100%だけだとPタグの幅分しか左に移動しないですし、600pxだけでも画像の幅分しか移動しないためです。Pタグの幅+画像の幅だけ左に移動してくれないと欄外まで出てくれません。
やってることは結局ニュースティッカーと同じなんですけど、複数のテロップを時間差で並べてみたいなぁーと思い、
.telop p:nth-of-type(1) {
animation:hscroll 6s linear 1s infinite;
bottom:5em;
}
.telop p:nth-of-type(2) {
animation:hscroll 6s linear 2s infinite;
bottom:3em;
}
.telop p:nth-of-type(3) {
animation:hscroll 6s linear 3s infinite;
bottom:1em;
}
こんなふうに1秒ごとに遅れて動くようにしています。テロップの位置もbottomでズラす感じで。
…………でも、この実装方法、微妙にイケてないですよねぇ。
流すテロップの数が3つだから大したことないけど、10や20流したくなったら、その分animationプロパティを書くのかって話です。
それなら最初から一つの大きなテキストの塊、例えば↓こんなの。テロップを流すテスト1 テロップを流すテスト2 テロップを流すテスト3
こういう塊を作っておいて、まとめて右から左に流したほうが良いかも知れない。
テロップをひとつの塊とした場合
ということで、テロップをdiv class="text"というひとかたまりにまとめてみました。
テロップのテキストが入れ子になっているのがわかりやすいように、赤枠で囲ってみました。
HTMLとCSSの解説
<div class="telop2">
<img src="[画像ファイル]">
<div class="text">
<div>テロップを流すテスト1
<div>テロップを流すテスト2
<div>テロップを流すテスト3</div>
</div>
</div>
</div>
</div>
<style>
.telop2 {
position:relative;
width:600px;
overflow:hidden;
}
.telop2 img {
width:100%;
}
.telop2 .text {
position:absolute;
bottom:0;
font-size:1.4em;
color:white;
text-shadow:1px 1px 2px black;
white-space:nowrap;
animation:hscroll2 6s linear 0s infinite;
}
.telop2 .text div {
margin-left:8em;
border:1px solid red;
}
@keyframes hscroll2 {
0% { transform:translateX(0); }
100% { transform:translateX(calc(-100% - 600px)); }
}
</style>
短くなったのでHTMLとCSSを全部載せましたが、主な変更点はHTML部分のテキストをPタグからDIVタグに変えて入れ子にした点ですかね。
<p>
テロップを流すテスト1<br>
テロップを流すテスト2<br>
テロップを流すテスト3<br>
</p>
みたいに書いても良かったんですけど、さすがに でインデント調整するのはアレ過ぎるかなぁ、とw
DIVタグで入れ子にしておけばmargin-left:8em;の部分を書き換えるだけで、別行のテキストのインデント幅を変えられるのでこんな実装にしてみました。
なんか入れ子で書くと想像以上にタグが読みづらかったので、ここだけもうちょいなんとかならないかなぁーと悩んでいます。
こう、2つ目以降のPタグだけ徐々に左マージンを増加させていく、みたいな書き方できないかなぁ。
float使って高さを微妙にかぶるように設定して、階段状に配置するのもアリかも知れません。
まとめ
画像の上にテロップのように流れるテキストを複数配置してみたくなったので、以前作った「CSSだけで数珠つなぎに無限ループするニュースティッカーを作ってみる」を流用して、それっぽい仕組みを作ってみました。
なんとなーく実現は出来ましたが、1個目の方法ではテキストが増えるたびにanimation設定を増やすのが面倒だし、2個目の方法ではDIVタグの入れ子が微妙に読みづらいのが難点ですかねー。
CSSはまだまだ勉強中なので、もう少しこのへん綺麗に書けるようになりたいものです。