marginを駆使して複数の画像を同一座標系で扱う
2020/07/11

ここに来て新型コロナウイルスの陽性者数が増え続けていますね。 経済も元に戻りつつあるところだったので心配です。 治療薬も承認されたりしているので、早く収束して欲しいですね。
さて今回は、複数の画像をJavaScriptで動かそうとしたときに結構苦労したので、 メモがてら共有しておきます。
複数の画像の左上を合わせたい
HTMLでもゲームでもそうですが、2Dの座標系は基本的に左上が(0,0)になります。 そのため目標としては以下のように、各画像に座標(0,0)を指定した際に、環境によらず左上で画像を重ねたい、ということになります。

これができれば、少々専門的な言い方になりますが同一座標系で扱うことができ、プログラミングしやすくなります。
文字に合わせて表示される画像

この状態になる理由ですが、デフォルト、すなわち何も設定を変更していない状態で画像を表示すると、それらは文章の中で見やすくなるように下揃えになるからです。 やってみますと、キャラクター

display:block;で独立させる

デフォルトではimgの設定はdisplay:inline;になっています。 これが文字に並んで下揃えの状態ですね。 これをdisplay:block;に変更することで、画像を独立した表示物にできます。 その結果は画像の通り。
…ってこれだとちょっとわかりづらいのでここで一旦色をつけましょう。 各画像は長方形で扱われるのでこんな感じです。 ボールが左上に来たのがわかりますね! あとはキャラクター画像の位置を合わせられれば…。

marginを設定して画像の位置を変更する

キャラクターmarginの変更を試してみる
色々と試せると良いと思うので場所を用意しました。 ここでは初期状態のキャラクターのmargin-leftとmargin-topを10pxとしておきました。 この値は先程までは0pxでしたが、10pにすることで隙間ができているのがわかります。

margin-left:とmargin-top:の右にある、白い枠に囲まれた「10」が入っているところは数値を変更できます。 数値を5とか100とか色々といじって[キャラクターmargin設定]ボタンを押すことで設定が反映されますので、 margin-leftとmargin-topの設定による違いを、色々と体感してみてください。
margin-topにマイナス設定して重なるように上に上げる
気づきましたでしょうか。margin-topを-32(px)に設定すると、ちょうど枠の上の位置に来ます。 余白にマイナスの値を設定できるとかちょっと裏技ですよね(笑) でもこれで、画像の基本位置が左上に揃いました!
キャラクターの設定がボールの大きさに左右される

そこで今後も考えて、ボールのmargin-bottomに-32pxを設定します。 それが最初の画像になりますので再掲します。 なおキャラクターのmargin-topは0に戻しておきます。
保守性を高める工夫を
「いや、キャラクターのmargin-topに-32pxを設定するのも、ボールのmargin-bottomに-32pxを設定するのも大差ないだろう」 という意見もあるかと思います。 しかしこれは大きな違いです。
ボールの設定にボールの大きさを反映するなら、前後にどんな画像があってもその設定を変更する必要がありません。 ちなみにキャラクター画像の方にはキャラクターの縦の大きさのマイナス値をmargin-bottomに設定します。 こうしておけば、それぞれの画像が独立した状態を保てます。
これは将来的に大きな意味を持ちます。
例えばボールの大きさを変えたときに、ボールの設定を変更するのは必要なことです。 しかしボール以外の設定も変更する必要があるとなると、 影響箇所の洗い出しが超大変になります。
変更による影響範囲を小さくしておくことで、保守性が高まり、色々な変更に対応しやすくなります。
まとめ
marginを駆使してプログラミングしやすくする工夫を紹介しました。
保守性を高めることは、長期間の運用を考えると重要なことです。 ことなのですが…それは多人数で作っているときに、 それぞれの担当者が独立して作業ができるという意味においては特に重要です。
つまりですね、ぶっちゃけ個人ブログでそこまでする必要は無いなあと思いつつ、 気になってしまうのはなんというか職業病でしょうね(笑)
補足
・本記事はimgエレメントのpositionはrelative、paddingは0であることを前提にしています。 ・画像内のラスタライズ文字フォントにOpen Font LicenseのNoto Sans Japaneseを使用しております。カテゴリー:メガホンDEポン,CSS
Copyright (C) Logic Lovers Inc.