「カード」は2次元?3次元?

「カード」は2次元?3次元?blogtitle_card

こんにちは、マークアップエンヅニアのゆーじろ(仮称)です。

今回は皆さんが今まさしく使っているWEBサイトについて書きます。
といっても全てを書くと膨大になってしまうので、テーマを「WEBサイトの奥行き」に絞ってお話します。
WEBの世界はその歴史も相まって不可思議なものです。

本題に入る前に…

WEBサイトの見栄えはHTMLというもので殆どが出来ています。
HTMLはタグと呼ばれるもので構成されていて、テキストの意味をコンピュータに伝える為の役割をしています。
これがあるおかげで、例えばニュースの更新をチェックするWEBサービスだとか、そういった情報の特定をすることやリッチなデザインを表示することが出来ています。
私の仕事であるマークアップはデザインと情報を切り分けて、WEB上に「再現」させるものです。

ここでタイトルの話をしましょう。
皆さんはカードを3次元だと思いますか?2次元だと思いますか?

正解は本分の中盤に。

HTMLでの奥行き

HTMLには奥行きを再現する際、z-idnexかtransformというもので指定出来ます。
「え、なんで二つあるの?」と思いませんか?

WEBは元々が学術論文を広く公開する為のものでした(更に辿ると軍事マニュアルなどの電子化)
その為なのか、HTMLの世界には長らく「奥行き」という明確な概念がありませんでした。
「表示の優先順位」それがz-index(2次元)の役割です。

ですがインターネットが発展するにつれ、様々な場面で使われることになり、アプリケーションと呼ばれる物も続々と出てくるようになって、z-indexだけではどうにもならなくなりました。
そこで登場したのがtransform(3次元)です。

奥行きの矛盾

transformの登場でHTML(とCSS)だけで3次元の再現が可能になったのは素晴らしい事です。
ただ、z-indexは残ったままです。
二次元の表示優先順位と三次元上の奥行きが混在しているのです。

ということは

はい、ここまでくればなんとなく想像がつくと思いますが、WEBにおいてカードは
「2次元でも再現出来るし、3次元でも再現出来る」ということになります。
具体的には下記のような感じです。

<!DOCTYPE html>
<style type="text/css" media="screen">
	#foo{
		display: block;
		width: 600px;
		height: 800px;
		margin: 0 auto;

		position: relative;

		background-color: #fff;

		-webkit-perspective: 800px;
		-webkit-transform-origin:center top;
	}

	#card{
		display: block;
		width: 300px;
		height: 400px;
		margin: 0 auto;

		position: relative;

		-webkit-transform-style:preserve-3d;
		-webkit-transform-origin:center top;
		-webkit-transform:rotateY(0deg);

		transition-duration:.3s;

		-webkit-animation-name:cardRotate;
		-webkit-animation-delay:0;
		-webkit-animation-duration:4s;
		-webkit-animation-iteration-count:infinite;
		-webkit-animation-timing-function:linear;
	}
	#cardFrontside,
	#cardBackside{
		display: block;
		width: 300px;
		height: 400px;

		position: absolute;
		top: 0;
		left: 0;

		background-color: #f00;

		z-index:1;
		-webkit-transform-origin:center top;
		-webkit-transform:rotateY(0deg)translate3d(0,0,1px);
	}
	#cardBackside{
		background-color: #00F;

		z-index:-1;
		-webkit-transform:rotateY(180deg)translate3d(0,0,1px);
	}

	@-webkit-keyframes cardRotate{
		0%{
			-webkit-transform:rotateY(0deg);
		}
		50%{
			-webkit-transform:rotateY(180deg);
		}
		100%{
			-webkit-transform:rotateY(360deg);
		}
	}
</style>
<div id="foo">
	<div id="card">
		<div id="cardFrontside">
			Frontside
		</div>
		<div id="cardBackside">
			Backside
		</div>
	</div>
</div>

サンプル

ただしz-indexは常に画面の正面を正の整数、背面を負の整数として計算している為
z-indexで行う場合は対角90度になったタイミングで前後を入れ替える必要があります。
これはCSSだけでどうにかするのは不可能なので、javascriptを用いることで対応します。
これは主にandroidOS系の古いバージョンで三次元が使えないため、カードを再現するのに有効ですが、
z-indexのみで行っている場合はPCブラウザなどで見ると明滅します。

サンプルの明滅版

上のサンプルその1のソースのようにtransformでZ軸の指定をしている場合、z-indexの重なり順は無視されます。
これは二つの重複した重なり順と奥行きのどちらかを優先させなければ競合してしまうからです。

二次元でも再現出来るし、三次元でも再現出来る。
ただz-indexの成り立ちと上記のような問題点を鑑みれば、三次元で再現した方が無難と言えるでしょう。

奥行きが無い場合になぜ明滅するのか

先ほどz-indexのみで指定した場合明滅すると書きました。
これは次のような条件下で起きる現象です。

  1. アニメーションさせている
  2. transformでZ軸の指定をしていない

transform指定をせず、ただ単純にアニメーションさせてる場合は明滅しません。
これはz-indexのルールが適用されている為で、z-indexが指定されてない場合は
デフォルト値の0で計算され、「同じ値の場合は後述されている要素の表示が優先される」というルールに基づいています。

ではなぜtransformをつけてZ軸の指定をしないと明滅するのでしょうか。

これはtransformのZ軸の値が同じだった場合に、どちらの要素を優先するのかというルールが無い為です。
三次元の世界で同じ所に別の物が存在する場合、シュレーディンガーの猫のように半分そこにあって半分そこに無い状態になります。
更にz-indexは先ほど上げた通りtransformの指定時は無視され、重複した要素の表示順が曖昧になった為に起きているようです。

まとめ

ここまで来ると一見二次元に思える事も三次元処理する場合は基本的にXYZ軸を考えて指定しなければならない。
ということが解ると思います。
WEBの世界は二次元的な情報を扱うものとして誕生しましたが、より高度な表現を可能にするため三次元的も扱えるようになりました。それはWEBの役割が大きく変化してきている、ということに他なりません。
今後も、もしかしたら四次元も扱えるようになるのかもしれません。

WEBは常に進化しています。まだまだCSSだけでは足りない事が多く存在します。
「面白いな」「え、なにこれ怖い」などと思っていただけたようでしたら幸いです。

最後までご覧頂きありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です