CSSだけで数珠つなぎに無限ループするニュースティッカーを作ってみる

お知らせ等の短い文章をテロップのように横スクロールして表示するCSSサンプルです。

普通(?)のニュースティッカーサンプル

表示例

  • ニュースティッカーのテスト1
  • ニュースティッカーのテスト2
  • ニュースティッカーのテスト3
  • ニュースティッカーのテスト4
  • ニュースティッカーのテスト5

HTMLとCSS

<div class="news_ticker1">
	<ul>
		<li>ニュースティッカーのテスト1</li>
		<li>ニュースティッカーのテスト2</li>
		<li>ニュースティッカーのテスト3</li>
		<li>ニュースティッカーのテスト4</li>
		<li>ニュースティッカーのテスト5</li>
	</ul>
</div>
<style>
.news_ticker1 {
	width:300px;
	overflow:hidden;
	white-space:nowrap;
	border:1px solid red;
}
@keyframes hscroll {
	0% { transform:translateX(300px); }
	100% { transform:translateX(-100%); }
}
.news_ticker1 ul {
	display:inline-block;
	margin:0;
	padding:0;
	animation:hscroll 8s linear infinite;
}
.news_ticker1 li {
	display:inline-block;
}
</style>

解説

やってることはけっこう単純で、

  • ニュースティッカーを表示する枠をdivタグ300pxで作成しwhite-space:nowrap;で折り返しを禁止し、overflow:hidden;ではみ出したテキストは隠すように設定する。
  • ul/liをdisplay属性でinline-block化して横並び表示する。
  • CSSアニメーションの設定でX座標+300pxの位置(要するに右側の欄外)から、-100%の位置(左側の欄外)まで移動させる。

というだけの動作です。

ただ、サンプルだと枠が300pxなのでそれほど気にならないかもですが、もっと横長になってくると空白の時間が長くなり、ちょっともったいないなぁ~って気になったんですよね。

数珠つなぎなニュースティッカーサンプル

というわけで、その空白期間を無くした数珠つなぎに表示されるニュースティッカーのサンプルです。

表示例

  • ニュースティッカーのテスト1
  • ニュースティッカーのテスト2
  • ニュースティッカーのテスト3
  • ニュースティッカーのテスト4
  • ニュースティッカーのテスト5
  • ニュースティッカーのテスト1
  • ニュースティッカーのテスト2
  • ニュースティッカーのテスト3
  • ニュースティッカーのテスト4
  • ニュースティッカーのテスト5

「ニュースティッカーのテスト1~5」まで表示された後、すぐに「ニュースティッカーのテスト1」が繋がって表示されていますよね?

HTMLとCSS

<div class="news_ticker2">
	<ul>
		<li>ニュースティッカーのテスト1</li>
		<li>ニュースティッカーのテスト2</li>
		<li>ニュースティッカーのテスト3</li>
		<li>ニュースティッカーのテスト4</li>
		<li>ニュースティッカーのテスト5</li>
	</ul>
	<ul>
		<li>ニュースティッカーのテスト1</li>
		<li>ニュースティッカーのテスト2</li>
		<li>ニュースティッカーのテスト3</li>
		<li>ニュースティッカーのテスト4</li>
		<li>ニュースティッカーのテスト5</li>
	</ul>
</div>
<style>
.news_ticker2 {
	width:300px;
	overflow:hidden;
	white-space:nowrap;
	border:1px solid red;
}
@keyframes hscroll2 {
	0% { transform:translateX(4px); }
	100% { transform:translateX(-100%); }
}
.news_ticker2 ul {
	display:inline-block;
	margin:0;
	padding:0;
	animation:hscroll2 5s linear infinite;
}
.news_ticker2 li {
	display:inline-block;
}
</style>

解説

HTMLタグを見た瞬間にあーなるほどと思われるかもですが、2個並べてるだけです。

どうせこういうニュースティッカーを使う場合はCMSを使ったり、データベースと連動するPHPスクリプト等のサーバーサイドスクリプトを使っているだろうから、同じニュースを2個並べるくらい問題ないかなと思ってこんな実装にしてみました。

そもそも最後の「テスト5」が表示されている最中に「テスト1」をつなげるなんて、HTMLの要素を切って繋げないといけないのでJavaScript使うならともかくCSSだけじゃちょっと無理ですよねー。

JavaScript使うにしても欄外に移動したliタグを切り取って、最後尾につなげ直す…とかちょっと面倒かなぁ…と。ん?そうでもないか…。そのうちやってみようw

まぁそれはともかく、今回はCSSのみで作るのがコンセプトなのでこのまま進めます。

前回からの変更点は

  • ulタグのグループを2つにした
  • @keyframes hscroll2 を-300pxからのスタートではなく、4pxからスタートにした

だけです。

1個目のULタグのアニメーションが終了した瞬間に、2個目のULタグが最初の位置(4px)に登場すればループがずっと繋がっているように見えるんじゃないかな、と思って試してみたら出来ちゃった感じ。

なんで0pxじゃなくて4pxと中途半端なのかというとliタグとliタグの間に4pxほどの空白が出来るからです。

そのため、 0% { transform:translateX(0px); } みたいな書き方をするとループをつなげる際に一瞬カクッとした感じになります。

見たほうがわかりやすいか。

実際0pxにすると↓こんな感じ。

  • ニュースティッカーのテスト1
  • ニュースティッカーのテスト2
  • ニュースティッカーのテスト3
  • ニュースティッカーのテスト4
  • ニュースティッカーのテスト5
  • ニュースティッカーのテスト1
  • ニュースティッカーのテスト2
  • ニュースティッカーのテスト3
  • ニュースティッカーのテスト4
  • ニュースティッカーのテスト5

どうでしょ。テスト5までスクロールした後、一瞬カクついてませんか? もしかしたらブラウザによって微妙に違うかもだけど。

これはinline-blockの特性で、改行があると要素同士の間に空白が入り、アニメーション終了時に空白1個分(4px)のズレが生じるためです。

(inline-block化した)liタグの間に改行を入れなければこんな空白は入らないので、0% { transform:translateX(0px); }という指定で構いません。

まとめ

  • CSSだけでmarqueeタグ(HTML5では廃止)みたいなニュースティッカーを作ってみた。
  • 単純に欄外から欄外へ横スクロールさせると空白期間が気になった。
  • 空白なしでニュースティッカーを数珠つなぎで無限ループさせるよう、ulグループを2つにして繋げてみた。

といったところでしょうか。

単純な仕組みですが、PCとスマホの両対応が求められる昨今、狭い横幅でも情報を詰め込みたい!なんてケースで使えるのではないでしょうか。

adsbygoogle

フォロー