CSS3 transformのZ軸 時計回転のrotateと縦横回転のXやYを併用する際の注意点

CSS3の新しいプロパティtransformにrotateというのがありますが、このrotateでrotate(90deg)からrotateX(180deg)という順で処理するのとrotateX(180deg)からrotate(90deg)とするので結果が違う理由を検証しました。「rotate」は時計回転、「rotateX」は上下の回転、「rotateY」は左右の回転です。

tarnsform: rotate(90deg)の後にrotateX(180deg)を行うのと、rotateX(180deg)の後にrotate(90deg)を行うのでは、表示される内容が違ったので検証して見ました。

CSS3の新しいプロパティtransformにrotateというのがありますが、「rotate」は時計回転、「rotateX」は上下の回転、「rotateY」は左右の回転です。

元画像

ふなっしー

rotate(90deg);

ふなっしー

rotateX(180deg);

ふなっしー

rotateY(180deg);

ふなっしー

このrotateで時計方向に90度回転した状態で、さらにrotateXやrotateYを追加すると、上下や左右の起点はどちらになるのかが疑問でした。

rotateX(180deg)を例にすると、90度回転される前の元画像の上下を基準に回転するのなら次のようになります。

ふなっしー

そうではなく、rotate(90deg)が適用されて横向きになっている画像の上下を回転するのであれば、次のようになります。

ふなっしー

これは試せばいいだけの話なのでやってみました。

rotateを複数適用するCSSの書き方

rotateを複数適用させたい時は、transformに各rotateを半角スペースで区切って書けば出来ます。

ただ、2015年4月13日時点では、ベンダープレフィックスをつけないと反映されないブラウザもありますので、冗長ですが下のようになります。これはrotate(90deg)で画像を時計回転で90度回して、さらにrotateX(180deg)で180度反転させるという場合です。

.class_name {
	transform: rotate(90deg) rotateX(180deg);

	/* ベンダープレフィックス */
	-moz-transform: rotate(90deg) rotateX(180deg);
	-webkit-transform: rotate(90deg) rotateX(180deg);
	-o-transform: rotate(90deg) rotateX(180deg);
	-ms-transform: rotate(90deg) rotateX(180deg);
}

上のcssを実際に適用したら下の通りになりました。

ふなっしー

結論として、rotateを複数適用してもすべて元の画像を基準にされるという事です。考えてみれば当たり前の話で、もし画像のスタイルシートにheightやwidthが指定してあった場合、横になった時にそれが変わってしまうと困ります。

元の状態が基準であるならrotateとrotateXの順序を入れ替えた、次のどちらも同じ結果になるはずです。

  • transform: rotate(90deg) rotateX(180deg);
  • transform: rotateX(180deg) rotate(90deg);

ところが、このように入れ替えてみると違う表示結果となります。

rotateを複数適用する場合、順序が重要

先ほどの順序を次のように入れ替えてみました。

.class_name {
	transform: rotateX(180deg) rotate(90deg);

	/* ベンダープレフィックス */
	-moz-transform: rotateX(180deg) rotate(90deg);
	-webkit-transform: rotateX(180deg) rotate(90deg);
	-o-transform: rotateX(180deg) rotate(90deg);
	-ms-transform: rotateX(180deg) rotate(90deg);
}

その結果です。

ふなっしー

これは次のように推移しているということでしょうか?

  1. 上下を180度回転
  2. 時計方向に90度回転

そうであれば、時計方向は180度反転した後は逆さまになる、つまり反対側から見た状態という事のようです。

ふなっしー => ふなっしー

X軸 Y軸 Z軸

X軸は横線、Y軸は縦線です

X軸Y軸

rotateXは横線を基準に回転するので、rotateX(180deg)は上下の反転になります。また、rotateYは縦線を基準に回転するのでrotateY(180deg)は左右の反転になります。

rotateX(180deg);

ふなっしー

rotateY(180deg);

ふなっしー

XとYで2次元なのですが、rotateにはもうひとつ3次元の座標Z軸があります。

xyz軸

このZ軸はモニター画面の手前からモニター奥に伸びているイメージです。

rotateXやrotateYで180度回転させた画像は奥から見ているのと同じだという事です。

後ろから見ている状態と同じと考えれば時計回転が逆になるのも納得できます。

通常の状態の時計回りは右回り

時計回転はZ軸で変わる

逆の時計回りは左回り

時計回転はZ軸で変わる

rotateZについて

なのでrotateXやrotateYを処理してから時計回転のrotateを行うのと、時計回転のrotateをやってからrotateXやrotateYを行うのでは結果が違うという事だと思います。

下の画像の場合、rotate(90deg)は赤い矢印方向への回転。rotateX(180deg)は、黄色い線側と青い線側の反転です。

時計回転のrotate(90deg)後にrotateX(180deg)

  1. まずrotate(90deg)で赤い矢印方向へ90度回転
  2. その後rotateX(180deg)で黄色い線側と青い線側が反転

ふなっしー=>ふなっしー=>ふなっしー

rotateX(180deg)後に時計回転のrotate(90deg)

  1. まずrotateX(180deg)で黄色い線側と青い線側が反転
  2. その後rotate(90deg)で赤い矢印方向へ90度回転

ふなっしー=>ふなっしー=>ふなっしー

試しにrotateX(180deg) => rotate(90deg)の順のrotateの値を90degではなくマイナスの-90degにしてみます。

rotateX(180deg) => rotate(-90deg)の順
ふなっしー

rotate(90deg) => rotateX(180deg)の順で処理したのと同じ結果になりました。

まとめ

まとめると次のように言えると思います。

  • CSS3のtransformには複数の処理を書ける。
  • 複数の処理を書く場合は半角スペースで区切る。
  • 複数処理の実行は書いてある順番で行われる。
  • 処理の基準となるX、Y、Zの各軸は処理前の画像の状態と常に同じ
  • ただし、時計回転に関してはZ軸の向きによって見え方が変わるので注意!

画像が枠からはみ出さない、簡易的なスタイルシート

以前「絶対はみ出さない画像!自動でサイズ調節するスタイルシート」という記事を書きました。その通りにすれば、ブラウザのサイズに合わせて、画像サイズを自動調整するようになります。

ですが、根本的にimgタグが、わからない人には役に立ちません。そこで、今回は簡易的な方法で、記事の中の、あるいは、サイドバーの中の画像が、はみ出さないようになるスタイルシートの書き方を説明します。

注:この記事は、説明の都合上、600ピクセル以下の狭い画面サイズでは右側が切れて表示されると思いますが、ご了承ください。

画像が枠からはみ出さない、簡易的なスタイルシート

スタイルシートの最後に、次のように書き加えるだけで、画像が枠からはみ出さなくなります。

img{max-width:100%;height:auto;}

サンプル

今回は、Tomさんが船橋西武百貨店で撮影した、ふなっしーの写真を題材にします。

ふなっしー

上のスタイルシートを適用した状態で、写真を400ピクセルの枠と200ピクセルの枠に入れます。左が400ピクセル、右が200ピクセルです。

400ピクセル

記事本文


ふなっしー

200ピクセル

サイドバー


ふなっしー


左の場合、画像の横幅が400ピクセルに満たない時は、そのままの大きさで、400ピクセル以上の時は、400ピクセルのサイズで表示されます。同じように、右の画像は、元々の横幅が200ピクセルない時は、そのままの大きさで、200ピクセル以上の時だけ、200ピクセルに縮小されて表示されるようになります。

横幅いっぱいではなく、隙間を作りたい場合

上のように、余白がない状態ではなく、隙間を開けたいときには、上に書いたスタイルシートのmax-width:100%;の値を変更します。

例えば、max-width:90%;なら、枠の幅の90パーセントのサイズより画像の幅が大きい時は、枠幅の90パーセントの大きさに縮小された画像が、表示されるようになります。

img{max-width:90%;height:auto;}

400ピクセル

記事本文


ふなっしー

200ピクセル

サイドバー


ふなっしー


隙間を左右均等に割り振りたい時は

上の場合、隙間が出来ても、画像は左によっています。それを、バランス良く真ん中に配置したければ、次のようにします。

img{max-width:90%;height:auto;margin:0% 5%}

margin:0% 5%の、最初の0%は、上下の余白、次の5%は、左右の余白です。

左右の余白は、100%から画像の幅のサイズを引いて2で割った数値です。これで、余白が左右に均等に割り振られます。(注:autoでは、うまくいきません)

ただし、そうすると画像の横幅が元々小さくて、はみ出していない画像にも左側に5%の余白がついてしまいます。自分のブログの状況に合わせて対応してください。

400ピクセル

記事本文


ふなっしー

200ピクセル

サイドバー


ふなっしー


アフィリエイトの画像の場合

アフィリエイトの画像の場合、サイズ変更が認められているものと、認められていないものがあります。下のはバリューコマースのものですが、このように明確にサイズ変更が認められているものならいいのですが。

画像のサイズを変更して、トラブルが発生しても、当サイトは一切関知しません。

バリューコマースでは、画像サイズを変更してよいアフィリエイトもある

スマホとPCでレイアウトを切り替える – レスポンシブデザイン

これからのブログはスマートフォンで見やすくする必要がある

最近はスマホアクセスが増加

最近はスマートフォンでのアクセスが増えています。特に一時的なアクセス急増の場合は、Twitterでツイートされたりした時なので、尚更モバイルからのアクセスの割合が増えます。

このキャプチャは実際に、このブログの記事がツイートされた時のアクセスログですが、71%が携帯電話からのアクセスでした。

IE6が消えたと思ったら、スマホなんて面倒なもの作りやがって!と怒っても仕方ありません。頑張って対応したいと思います。

レスポンシブデザイン

先にお断りしておきますが、私はレスポンシブデザインの勉強はまったくしていないので、この記事の内容は自己流です。一般的な流儀に判している可能性もありますことを、ご承知おきください。

最近、こんなコメントを頂きました。

TOMさんのブログをスマホ(iphone)で拝見すると、両サイドがメインの記事の下に来るようになっていますが、裏技でしょうか?
私のブログはそのようにならないのですが・・・

このブログはパソコンで見たときとスマートフォンで見た時はルックスが変わるようにしてあります。下は左がパソコンで見た場合、右がスマホで見た場合の表示のされ方です。ただし、Tomさんはスマホを持っていないので、右はエミュレーションで表示させたものです。実際にスマホで見た時は、もっと崩れていると思います。

PCレイアウト    スマホレイアウト

パソコンの方は、ブラウザのサイズによっても見え方が、変わります。下はヘッダの部分だけを切り取った画像ですが、画面が広い時と、狭い時で横に並ぶ個数が変わっています。

画面が広い時のヘッダ    画面が狭い時のヘッダ

こういう風に状況によってレイアウトが変わるものをレスポンシブデザインと呼ぶそうです。

レスポンシブデザインを実現する方法は、いろいろあると思います。このブログの場合は、主にスタイルシートで作り、スタイルシートだけでやるのが難しいところにJavaScriptを使いました。ただし、何も見ないで作ったので自己流です。一般的な流儀に反しているかもしれません。

3カラムの構造

下は、このブログを書いているファンブログの3カラムスキンの構造です。ファンブログ以外でも、ほぼこれに近い形が多いと思います。

下のスキンは、記事部分が500px(500ピクセル)、左サイドバーが200px、右サイドバーが160pxです。

このブログのスキンは完全オリジナルなので、下のとは違います。

id=”container”

ヘッダ
id=”header”
id=”main”

id=”wrapper”
700px

左サイドバー
id=”sidebarLeft”
200px
記事部分
id=”content”
500px

右サイドバー
id=”sidebarRight”
160px

フッタ
id=”footer”

これをスマホの時だけ、下の構造にします。こうすれば両サイドがメインの記事の下に来ます。下の図は見やすくするために左右に余白がついていますが、この余白をなくせば、スマホの横幅いっぱいで表示されます。

これはスタイルシートを切り替えるだけで実現できます。

id=”container”

ヘッダ
id=”header”
id=”main”

id=”wrapper”

記事部分
id=”content”
左サイドバー
id=”sidebarLeft”
右サイドバー
id=”sidebarRight”
フッタ
id=”footer”

サイドバーを下に落とす

右のサイドバーを下にするには、どうしたらいいでしょうか。それには、パソコンで見る時は700pxあるwrapperの横幅を100%にすればいいです。wrapperの横幅が左右いっぱいに広がれば、右サイドバーは収まりきらないので、下に落ちます。

次に左サイドバーを、記事の下に落とします。これも同じように、記事の部分、idがcontentの部分の横幅を100%に変更します。これで、収まりきらない左サイドバーは記事の下に落ちます。

最後は下に落ちた左右サイドバーの横幅も100%に変更します。そうすれば、スマホで見たときは、上から記事、左サイドバー、右サイドバーの順に横幅いっぱいで表示されます。

つまり、wrapper、content、sidebarLeft、sidebarRightの横幅を、すべて100%にすればいいということです。

ただし、それをやるにはmainの中のHTMLが、下のようになっている必要があります。最初に記事、次に左サイドバー、その次に右サイドバーの順番です。

<div id="main">
	<div id="wrapper">
		<div id="content"></div>
		<div id="sidebarLeft"></div>
	</div>
	<div id="sidebarRight"></div>
</div>

先にある記事が横幅100%になったことで、残りは入りきらずに下に落ちますが、先にサイドバーがあれば、記事が下に落ちます。

どうやってスタイルシートを切り替えるか

スタイルシートを切り替える方法ですが、このブログではbodyタグのidを変更しています。パソコンで見たときにはidなし、スマホで見たときにはidが”sp”となるようにしています。

その実現方法として、JavaScriptを使っています。ユーザーエージェントを見て、スマホブラウザの時に、idをつけるという方法です。ソースコードは下の通りです。

<script type="text/javascript"><!--
(function(){
	if(0<=navigator.userAgent.indexOf('Android')){
		document.body.id='sp';
	}else if(0<=navigator.userAgent.indexOf('iPhone')){
		if(-1==navigator.userAgent.indexOf('iPad')){
			document.body.id='sp';
		}
	}else if(0<=navigator.userAgent.indexOf('iPod')){
		document.body.id='sp';
	}
})();//-->
</script>

このブログで使っているスクリプトから、該当箇所だけ抜き出しました。もし正しく動作しなければご連絡ください。

このスクリプトをコピーして、bodyの開始タグ(<body>)の直後に張り付ければ、スマホの時はidが切り替わるようになります。貼り付ける場所は必ず<body>の直後にしてください。

後は、body#spに対応したスタイルシートを、下のように追加すれば、スマホ用レイアウトで表示されます。

body#sp wrapper,body#sp content,
body#sp sidebarLeft,body#sp sidebarRight{
  width:100%;
}

スマホでだけ表示させたいもの、あるいはスマホでだけ表示させたくないものは、スタイルシートの display で切り替えます。

このブログのヘッダのカテゴリーメニューのように横幅で並ぶ個数を切り替えたいなら、別の記事「横幅に合わせ並ぶ個数を自動調整するスタイルシート」をご覧ください。

画像の大きさを自動調整したいときの参考記事は「絶対はみ出さない画像!自動でサイズ調節するスタイルシート」です。そちらを参考にしてください。


このブログでは、スキンのheadに次のmetaタグを書き込んでいますが、説明は省略します。これを書かなくても、サイドバーを下に落とす目的は達成できます。

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />

マウスが乗った写真を拡大表示する商品レイアウト

ファンブログにアップロードした画像URLの調べ方は「ファンブログでアップロードした画像の場所」に書いてあります。

Amazonなんかでやっている商品レイアウトで小さな写真を並べておいて、どれかにマウスを乗せると、その写真の拡大図を表示するという手法があります。その実現方法です。この下に6つ並んだダースベイダーのどれかにマウスを合わせると、その写真が下に大きく表示されます。






レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113

LEGOとスターウォーズがコラボレーションしたアラームクロック

  • 手足が可動式なのでお気に入りのスタイルで飾れます。
  • 頭の部分を押してアラームストップ&ライト点灯。
  • デスクサイド、ベッドサイドを演出してくれるクロックです。
【メーカー名】LEGO
【品番・型番】9002113

サイズ:(約)前長23cm、幅15cm / 重量:(約)535g
材質:プラスチック / 生産国:中国
スペック:アラーム(スヌーズ機能付き)ライト付き
     単4乾電池×2本使用(付属)
箱・保証書:有り(6ヶ月)
特記事項:実際の商品とは若干異なる場合がございます。
     予めご了承ください。

3,675円(税抜:3,500円)

送料525円(お買い上げ金額合計8,000円以上で送料無料)

レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113  レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113をカートに入れる

ちなみにこれは「カートに入れる」と本当に買うことができます

え!欲しいですか?困ったなぁ。そんなつもりじゃなくて、ただのサンプルなんだけど!いやぁ困った!でも仕方がない。どうしても欲しい方は レゴ (LEGO) スターウォーズ ダースベイダー Star Wars Darth Vader Alarm Clock 目覚まし時計 9002113をカートに入れる をクリックしてお買い上げください。

ソースコード

今回説明するのは、左上のダースベーダーの写真だけのブロックです。その右の「説明文」や「カートに入れる」ボタンがあるブロックと、写真の下の「ストーム・トルーパー」や「Amazon」「楽天」等へのリンクがまとまっているブロック、この2つは説明には含めません。

先にソースだけをまとめて書きます。これをまるごとブログの記事にコピペして、画像URL1から6に表示したい画像のURLを入れるだけでも上のようになります。ただし、編集画面のオプションで改行を有効にしていると動かないと思います。改行を有効にしていても動くソースは記事の最後です。

“マウスが乗った写真を拡大表示する商品レイアウト”の続きを読む

横幅に合わせ並ぶ個数を自動調整するスタイルシート

ファンブログにアップロードした画像URLの調べ方は「ファンブログでアップロードした画像の場所」に書いてあります。

上のキャプチャー画面はブラウザの表示サイズで横に並ぶ数が自動で変わります。意味がわからない方は、試しに今開いているこのページのサイズを色々と変えてみてください。画像が横に2個並んだり、1個だけになったりします。

ブラウザのサイズ変更ボタン

ブラウザのドラッグ

今回のテクニックを駆使した記事が「ゲーマーブログの収益アップにアクセストレードを強く薦める理由」です。リンクをクリックすると別画面で、その記事が表示されますので、見比べながら説明をご覧いただければ、理解が早いかと思います。

floatとwidthで横の個数を自動調整

上のキャプチャー画面は全部、横幅320ピクセルのアフィリエイトです。ブラウザの表示画面が660ピクセル以上あれば、横2個x縦2個の表示、なければ横1個x縦4個で表示します。ソースコードは以下の通りです。

<style type="text/css">
p.capture{
 float:left;
 margin-right:10px;
}
</style>

<p class="capture"><a href="リンクURL" target="_blank"><img src="画像URL" alt="" border="0" /></a></p>
<p class="capture"><a href="リンクURL" target="_blank"><img src="画像URL" alt="" border="0" /></a></p>
<p class="capture"><a href="リンクURL" target="_blank"><img src="画像URL" alt="" border="0" /></a></p>
<p class="capture"><a href="リンクURL" target="_blank"><img src="画像URL" alt="" border="0" /></a></p>
<p style="clear:left;">大きさも色々選べる。</p>

float:leftで画像を左寄せにしています。さらにmargin-right:10pxで画像の右側に10ピクセルの余白を作ります。これで2つ並んでもピッタリとくっついてしまいません。

画像自体が320ピクセルで、右に余白が10ピクセルつくと、合計330ピクセルです。ですから表示領域が660ピクセル以上あれば、横に2個並びます。しかし、足りない時には、横ではなく下に移動します。

最後にclear:leftを絶対に忘れないようにしてください。

“横幅に合わせ並ぶ個数を自動調整するスタイルシート”の続きを読む