「不思議ちゃん / くん診断」をGoogle Playで公開

 

クラスに一人はいる不思議ちゃん、不思議くん。自分は普通と思っても、人の評価は違うかも……。

片手間に制作し続けている診断アプリシリーズの一つです。暇つぶしにでも、ぜひ、インストールしてみて下さいね!

hushigi_site_top

【2015.10.13リリース】

CSSで縦中央表示を実現する方法

 

今回はCSS を用いて要素を縦中央に配置する方法をまとめてみます。ここで取り上げる縦中央表示とは、以下のような要素の配置を指します。

スクリーンショット 2015-10-11 5.37.47

黒の要素の中で、y 軸に対して、灰の要素が、中央配置されております。このような配置の利用場面は多岐に渡り、少しでもCSS に触れたことのある人ならば一度成らず、解決を迫られたことのある課題と存じます。

では、縦中央表示を実現するにあたり、主要と思われる4つの方法を以下に挙げてみたいと思います。なお、各名称は、情報整理のために筆者が付けたものです。

  1. マイナスマージン法
  2. インライン法
  3. テーブル法
  4. オートマージン法

これらいずれをとっても、先程の中央表示を実現することが可能です。ただし、利用する条件に応じて、期待通りの結果が得られない場合もあります。従って、各方法がどのような条件下において有効なのかを把握する必要があると言えるでしょう。では、早速詳説に参ります。

1. マイナスマージン法

利用可能な条件は、以下の通りです。

  • 中央表示する対象要素の高さ(height) が決まっている。

コードは以下の通りになります。

HTML は親要素の<div> の中に、小要素の<img> を入れているだけの単純なものです。一方、CSS では、親要素に暫定的にmin-height を与え、適当な高さにしております。親要素に小要素以上の高さがないと、縦中央も糞もございません。ですので、適当な高さを指定しております。さて、この方法を用いる上で重要なのは、

  • 親要素にposition が指定する(ここではrelative )。
  • 小要素にposition: absolute を指定する。
  • 小要素の高さが定まっている(ここでは100px )。
  • 小要素の始点はtop:50% である。
  • 小要素のmargin-top は自身の縦幅半分を引くもの(ここでは50px )を指定する。

という点です。まず、「親要素にposition を指定する」ことが重要なのは、「小要素にposition: absoluteを指定する」というポイントを満たすためです。絶対配置は直近の親(ないし先祖)のうち、position が指定されているもの(デフォルト値のstatic以外が指定されているもの)を基準に位置を決定します。親要素に「君が基準と成れ!」と命令しましょう。さすれば、子は親に準じるという具合です。

小要素は基準となる親が与えられることにより「始点は50% である」というポイントを満たすことが出来ます。この「50% 」というのが、「親の高さの50%」となるからです。さて、margin-top を指定する前の段階では、以下のような実現になります。

スクリーンショット 2015-10-11 6.52.26

y 軸に対する始点が「親要素の50% 」になっていることが分かると思います。さて、ここから縦中央表示の条件を満たすためには、「小要素の高さが定まっている」及び「margin-top は自身の高さの半分を引くものを指定する」とのポイントを満たす必要があります。無論、後者を実現するために前者が満たされねばなりません。と言うのも、自身の高さをマージンの設定に利用するからです。ここで、最初に述べたこの方法を利用可能な条件を再度確認します。

  • 中央表示する対象要素の高さ(height) が決まっている。

つまり、小要素の高さが予め分かっていないと、「margin-top は自身の高さの半分を引くものを指定する」にも、どの値の半分かが不明なのです。従って、小要素が高さ可変の要素(例えば、文の長さが定まらないテキスト等を内包する要素)の場合、この条件を満たすことが出来ず、別の方法を採用しなければなりません(もちろん、javascript 等で制御すればこの方法も可能でしょうが……)。一方、サイズ固定のイメージ要素等ならば、この方法が採用可能となるわけです。ここでは高さ100px の小要素とし、以上の条件を満たしております。

さて、最後にマイナスマージンを指定しましょう。マージンは要素の外部に間隔を加えるもの(パディングは内部に加えるもの)であり、マイナスマージンは、「外部の間隔を減らすもの」と捉えて良いでしょう。従って、「margin-top は自身の高さの半分を引いたものである」とのポイントを満たすと、小要素はその外側上部にある間隔を自分の高さの半分だけ減らすことになります。こうして、子要素を親要素の中心の位置まで持ち上げるのです。ここでは50px 持ち上げています。結果は次のようになります。

スクリーンショット 2015-10-11 5.37.47

以上で、マイナスマージン法を用いた縦中央揃えが実現出来ました。

2. インライン法

利用可能な条件は、以下の通りです。

  • 中央表示する対象要素の親要素の高さ(line-height) が決まっている。
  • inline-block に対応するブラウザのみをターゲットとしている。

コードは以下の通りになります。

HTML はマイナスマージン法同様、親要素の<div> の中に、小要素の<img> を入れているだけの単純なものを用意します。また、利用可能な条件「親要素の高さ(line-height) が決まっている」を満たすために、ここでは分かり易く、height:300px と line-height:300px を明示的に指定しております。さて、この方法を用いる上で重要なのは、

  • 小要素にdisplay: inline-block を指定する。
  • 小要素にvertical-align: middle を指定する。

の2点です。インライン法は、vertical-align という命令がinline 要素またはtable-cell 要素に対して有効なものであることを前提としています。従って、他の要素(例えば、block 要素)に対してvertical-alignを指定しても有効にはなりません。この方法を用いる場合は、vertival-align を有効にするために、小要素のdisplay をinline-block としましょう。なお、display: inline では、小要素に高さを指定出来ないので、用途が狭められることになります。この例で小要素として用いている<img>は、元よりinline要素でありますが、高さを持つことの出来る特殊なinline要素です。通常のinline要素にこのような特徴はありませんので要注意です。

以上を満たした場合の実現は次のようになります。

スクリーンショット 2015-10-11 5.37.47

さて、最初に述べた「親要素の高さ(line-height) が決まっている」という利用条件を満たさない場合、つまり、この例において、line-height:300px が親要素に指定されていない場合はどうなるでしょうか。以下が、親要素からline-height:300px の指定を取り除いた場合の実現です。

スクリーンショット 2015-10-12 5.36.04

小要素が親要素の上部に揃ってしまい、一見するとvertical-align:middle が有効になっていないように見えます。しかし、これは、vertical-align が無効になってしまったゆえの挙動ではなく、親要素のline-heightの値が小要素の高さになってしまったゆえの挙動です。それを確認するために、小要素の隣に少し大きめの別の小要素を加えてみましょう。すると、以下のような実現になります。

スクリーンショット 2015-10-12 5.44.39

左側の小さい小要素は、右の少し大きめの要素に対して、中央揃えになっているのが分かると思います。つまり、親要素のline-heightは小要素のうち最大の高さを持つ要素のheightが与えられるということです。小要素として高さの違う複数の要素を使用し、かつ、親要素の高さが可変で構わないような仕様の場合は、line-heightは直接指定する必要はないでしょう。小要素が一つだけ、または、複数の小要素を親要素を基準に中央揃えしたい場合には、line-heightを明示する必要があります。この例に、再びline-height:300px の指定を加えた実現は、以下のようになります。

スクリーンショット 2015-10-12 6.00.16

親要素に対して小要素の中央揃えが成功しました。なお、「inline-block に対応するブラウザのみをターゲットとしている」という利用条件に関し、現在、多くのモダンブラウザがinline-blockに対応しているので、古いブラウザをターゲットとしない場合には問題ないと言えるでしょう。以下より、inline-block対応ブラウザを確認することが出来ます。

http://caniuse.com/#feat=inline-block

追加考察:インライン要素に生まれる隙間

inlineの小要素を横並びにした場合のキャプチャをもう一度見て下さい。要素と要素の間に、隙間が出来ているのが分かると思います。分かり易く、要素を5つほど並べてみると、次のようになります。

スクリーンショット 2015-10-12 6.11.17

全ての要素に等間隔に隙間が入っているのが分かると思います。もちろん、マージン等は指定しておらず、先程のHTML に<img>を4つ追加しただけのものです。念のため、以下にそれを示します。

これは、inline要素を横並びにした場合に、HTMLの改行に空白が挿入されるがゆえの挙動です。つまり、改行をなくせば、空白もなくなる理屈となります。例えば、

のように、改行を一切取り除いてしまったり、

のように、改行を一切コメントアウトしてしまえば、次のように、隙間がなくなるわけです。

スクリーンショット 2015-10-12 6.29.16

CSSから制御する方法など、他にも対策は考えられます。以下のTHE HAM MEDIAさんの記事が詳しいです。

http://h2ham.seesaa.net/article/117579108.html

3. テーブル法

利用可能な条件は、以下の通りです。

  • table-cell に対応するブラウザのみをターゲットとしている。

コードは以下の通りになります。

CSS に関して、.parent はインライン法の場合と異なり、横幅を600px と固定値で指定しています。これは.parent のdisplayがtable-cell であるがゆえの実装です。と言うのも、table-cell要素は基本的には<td>と同様の性質を持ち、小要素の幅に応じて自らの横幅を決定するので、何も指定しない場合、小要素の横幅、つまりここでは100px の横幅が適用されます。試しに、.parent のwidth:600px を取り除いてみると、以下のような実現になります。

スクリーンショット 2015-10-12 11.01.54

また、width を100% で指定した場合も同様の結果となります。と言うのも、これはあくまでtable であり、table そのもののサイズがtable-cell の内包する子要素のサイズに従って、大きさを決定するからです。table もtable-cell が持つ要素に従って、ここでは100px となり、table-cell に100% を指定しても、結果は100px のままなのです。仮に、横幅をパーセンテージで指定したい場合は、table-cell 要素を内包する親要素にdisplay:table を指定し、そちらにwidth:100% を加えましょう。さて、この方法を用いる上で重要なのは、

  • 親要素にdisplay:table-cell を指定する。
  • 親要素にvertical-align:middle を指定する。

table-cell はインライン法の時に述べた通りvertical-align が有効なdisplay ですが、table-cell 要素でvertical-align を指定した場合の挙動が、inline要素の時とは少し異るので注意が必要です。inline 要素にvertical-alignを指定した場合、中央揃えが適用されるのは指定された要素そのものでした。しかし、table-cell 要素の場合、指定された要素ではなく、その小要素に中央揃えが適用されるのです。table-cell はtable のwidthやheightを満たすように実現されるがゆえ、自身を中央揃えとするのではなく小要素を中央揃えとする、と解釈出来るかもしれません。

以上を満たした場合の実現は次のようになります。

スクリーンショット 2015-10-11 5.37.47

なお、利用条件の「table-cell に対応するブラウザのみをターゲットとしている」という点に関し、対応ブラウザは以下から確認出来ます。

http://caniuse.com/#feat=css-table

table-cellを用いた方法の注意点は以下の記事が詳しいです。

http://html-five.jp/522/

4. オートマージン法

基本的に利用を制限する条件はありません。つまり、この方法を用いれば、大抵の場合中央揃えが実現するでしょう。

コードは以下の通りになります。

HTML はこれまで同様、親要素の<div> の中に、小要素の<img> を入れているだけのものを用意します。この方法を用いる上で重要なのは、

  • 親要素のpositionを明示する。
  • 小要素のpositionをabsoluteにする。
  • 小要素のtopとbottomに0を指定する。
  • 小要素の上下マージンをautoにする。

の4点です。最初のポイント「親要素のpositionを明示する」というのは、2つ目のポイントにあるように、小要素のposition: absolute を有効にするためです。absoluteが指定された要素は、マイナスマージン法で説明した通り、positionが明示された直近の親要素を基準に、その表示位置を決定します。なお、ここではposition: relative を指定しておりますが、状況に応じabsoluteでもfixedでも構いません。大事なのはstatic(position: static がデフォルト値)以外が明示してあるという点です。二つ目のポイント「小要素のpositionをabsoluteにする」理由は、追加考察の方に述べておりますので、そちらを参考にして下さい。

さて、3つ目のポイント「小要素のtopとbottomに0を指定する」に関してですが、これはより正確に述べるならば、「小要素のtopとbottomにauto以外を明示する」という旨になります。つまり、topまたはbottomがauto(デフォルト値)のままだと、4つ目のポイント「小要素の上下マージンをautoにする」が無効となってしまうのです。4つ目のポイントを満たすために、ここではtop: 0 及びbottom: 0 をしています。

最後のポイント「小要素の上下マージンをautoにする」という点ですが、これがオートマージン法の肝をなす命令です。上下マージンをautoにすることで、自動的に「上マージン=下マージン」となるようそれぞれの値を計算し、実現されるという次第です。この時、top及びbottomがautoであると、上下マージンの値を0としてしまう仕様のようであり、マージンを有効にするためにも、3つ目のポイント「小要素のtopとbottomに0を指定する」が必要となります。

以上を満たした場合の実現は次のようになります。

スクリーンショット 2015-10-11 5.37.47

追加考察:縦横におけるオートマージンの差異

オートマージン法は、しばしばコラムの横中央表示などで利用される以下のような方法の応用的なものと言えます。

スクリーンショット 2015-10-15 3.25.49

オートマージンを用い横中央を実現する場合、小要素のpositionはabsoluteである必要はなく、特にposition指定がなくとも、「左マージン=右マージン」となるよう値を算出し、表示してくれるようです。一方、縦中央に関して、positionがデフォルト値(static)や、relativeの場合は、上下マージンを0 と算出し表示する仕様のようです。それゆえ、先程のオートマージン法の説明ではabsoluteを指定しておりました。加えて、既述の通り、absoluteやfixedはそれだけでは「上マージン=下マージン」の中央揃えは実現されず、topとbottomに値を指定しなければなりません。top及びbottomがautoの場合、そちらを優先するためか、上下マージンの値は0になってしまうのです(NB : fixedもabsoluteと同様オートマージン法が使えますが、親要素の中央表示ではなく、windowの中央表示となります)。

オートマージン法の利用は易しいですが、幾分理解が難解に思えます。ですので、最後にもう一度プロセスを確認しましょう。①最初に親要素にposition: relativeを指定します。これはabsoluteが指定される小要素に基準を与えるためです。②次に、小要素にposition: absolute を指定します。親要素を基準にし、配置されます。③小要素のtop及びbottomに0を指定します。これは小要素のオートマージンを有効にするためです。④最後に、小要素にmargin auto 0 を指定します。topとbottomがautoでないので、「上マージン=下マージン」の値が適用されます。以上のような流れで、中央揃えが実現されるのがオートマージン法です。

なお、オートマージンの仕様に関しては、以下のWWW WATCHさんの記事が詳しいです。

https://hyper-text.org/archives/2014/08/position_absolute_center_layout.shtml

 

「Chatii On 恋愛トーク」の公開

 

恋バナ専用のチャットサービス「Chatii On 恋愛トーク」を公開致しました。下記リンクからアクセス可能でございます。

http://ren-ai.chatii.jp 「Chatii On 恋愛トーク」

なるべく、手軽に遊べるよう、登録などの面倒な手続きは省きました。ですので、トップページから「会話を始める」をクリックすると、直様チャットが始まる仕様となります。また、「相談役」「聞き手」「とりあえず」と入室時フィルターをかけることで、マッチングの優先順位を変えることも可能になります。本サービスの対象ユーザは、恋する老若男女、全ての方々です。利用規約を守り、楽しくご利用頂ければ、幸いです。

2015年10月10日現在、トップページ及びチャットルームのUIは次のようになっております。

chatii_screen_top

スクリーンショット-2015-10-08-22.42.512

まだまだ生まれたてのサービスですので、日々改善改良に努めて参ります。是非一度……いや、一度と言わず、何度でもお足を運び下さいませ。

図々しくも宣伝させて頂きました。

Chatiiのお知らせ一覧