知らないといつまでたってもHTMLとCSSが理解できない暗黙の仕様4つ
この記事は約13分ぐらいで読めます
あまり言及されない地味なルール
HTMLの仕様は膨大で、私も全部目を通しているわけではないです。日本語訳されたドキュメントなども提供されていますし、読めないわけじゃないんですけど…あの量はなかなか読めませんよね。その為、何か困った時や疑問に思った時に調べてみて、初めて知るルールがあるのもしばしばです。
今回はその中でも、特になあなあになってしまいがちで、最終的には理解しないで済ませてしまうルールをいくつか取り上げてみます。トラブルシューティングややってはいけない例も挙げてみました。ちなみに、下に行くほどマニアックになっていきます。
ベースライン
まずは比較的ぶつかりやすくて、その為わりと知られているルール、ベースライン。
英語圏でないため気付きにくいルール
ベースラインとは文書内に配置されたプレーンテキスト(以下テキスト)の下に仮想的に存在する線です。テキストを打ちこむと、当然のように文字はその線上にキレイに並びます。
しかし、英語の場合は小文字のgやy、j等、このベースラインから下にはみ出すものがあります。通常、文字を打ちこんだ場合このベースラインはデフォルトスタイルシートでvertical-align:baseline
に設定されています。つまり何も考えなくても常にテキストの下にはgやyの為に常に隙間があいているという事になります。
しかし、このプロパティーは別にその行のベースラインそのものを動かすわけではなく、あくまでテキストの行の中での高さをコントロールするものなので、同じ大きさの文字を打つ分にはそのベースラインが狂う事はありません。普通にテキストを打つだけなら問題にはならないのですね。
トラブルシューティング:画像の下に隙間が出来る
問題は画像を配置した場合に起きます。img
要素はエンベッディッド・コンテンツであるとともにフレージング・コンテンツ(HTML5以前で言うインライン要素の様なもの)であるため、基本的にはテキストと同じ扱いにされるのです。
その為、何も考えずに段落内やページ内に画像を配置すると思う様にいきません。
この問題に当たったことがない人は一からコードを書かずに、例えば出回っているreset.cssや社内で既に作られたコードを流用している可能性が高いです。大抵のリセットスタイルシートにはimg{vertical-align:bottom;}
が設定されていますね。
これについては単にimg{display:block;}
としてしまうのも有効です。ベースラインはフレージング・コンテンツにしか存在しないからです(vertical-align
もフレージング・コンテンツかテーブル・モデルのセルにしか指定できない)。
vertical-align
自体について知りたい場合は以下を参照してみてください。
暗黙の段落
更に地味なヤツです。これは過去記事の[HTML5 入門]実用を意識した最小単位からの文書構造チュートリアルでも軽く触れています。
自動的に段落の概念を持たせる
通常テキストは何らかのフロー・コンテンツの中に入れられます。私の場合は気持ち悪いのでテキスト・ノード(やフレージング・コンテンツ)をフレージングでないフロー・コンテンツ(ブロック要素)と同階層には置かないようにしてるんですが、例えばセクションの中や、body
要素直下に置くというパターンも間違いではありません。
これは、フレージング・コンテンツが通常のセクションやセクショニング・ルートの直下に置かれた場合、その直前から暗黙の段落が始まるようになっているからです。
この為、次に明示的に段落が指定されるか、ヘッディング・コンテンツやセクショニング・コンテンツ等のフロー・コンテンツが始まるまではその暗黙の段落が続きます(段落内にはフレージング・コンテンツしか入れられない為)。
これは、込み入ったアウトラインを形成していない限り、特にp
タグで段落を指定した場合とほとんど差がありません。段落にCSSを指定したい場合はちゃんと囲まないといけないですね。
やってはいけない例:暗黙の段落をまたぐ
普通にp
タグを使わずに暗黙的に段落を形成した場合、仮に見た目として段落の終わりを空行で表現したとしても、HTMLの文法的には段落が続いていることになると思います。その後次の段落の前に見出しが配置された場合、または明示的に段落を指定した場合はその時点で暗黙の段落が閉じられます。
タグによるマークアップは原則的に入れ子構造になっていなければならず、互い違いにタグを使うことは出来ません。そしてこの暗黙の段落も明示的にマークアップした時と同じで、仮に閉じタグがあったとすると互い違いになってしまうような記述のしかたは本来出来ないわけです。なので、段落内で始まったフレージング・コンテンツは暗黙であってもその段落内で閉じるのが妥当です。
具体的には、暗黙の段落内で始まったstrong
要素やins
要素などもその暗黙の段落内で閉じたほうが複雑にならずに済む、というようなことです。
暗黙のセクション
段落と同じように、セクションにも暗黙のセクションがあります。暗黙の段落がフレージング・コンテンツの直前から始まるように、暗黙のセクションは見出し(ヘッディング・コンテンツ)の直前から始まります。
見出しのみで文書構造を形成出来る
本来であれば明示的にsection
タグでセクショニングするべきなのですが、そうしなくても見出しのみでアウトラインを暗黙的に形成することは出来ます。
セクションは同じまたはそれより大きいレベルの見出しの直前で閉じられます。小さいレベルの見出しが置かれた場合はセクションの階層が深くなります。
やってはいけない例:文章の結びの段落に見出しをつけない
暗黙のセクションはそれより高いレベル、または同レベルのセクションの直前で閉じられる為、文章的にどういう意味で書いていたとしても適切な見出しをつけていなければ後に続く段落は全てその前のセクションの下の階層に属してしまいます。
これを回避するためにはより上位または同レベルの見出しを配置する必要があります。
そうでない場合は、明示的にsection
タグを使ってセクショニングします。これなら明確ですね。
個人的にはこのために、暗示的なセクショニングを行なっている文書の中で敢えて明示的にセクショニングするパターンもありえるのではないかと思っています。例えばWEBCRE8.jpの場合は実際通常のセクショニングこそ見出しを使って暗示的に行なっていますが、コンテンツ内にsection
要素以外のセクショニング・コンテンツも使っています。
この場合締めの文章は記事の最初の親であるarticle
の直接の子要素である必要があるため、h2
要素で終わりにという見出しをつけています。
セクションについての話題はしつこいほど書いているので理解を深めたい方は以下も読んでみてください。
[HTML5]アウトラインで迷わない! sectionと見出しについて
[HTML5]文を書くのも上手くなる!セクショニングを理解する
[HTML5 入門]コンテンツ・モデルについて勘違いしそうなところ
要素間ホワイトスペース
最後、最も地味なルール。要素間ホワイトスペースとは要素と要素の間にできるスペースです。
テキストとテキストの間に余分な間隔を作らない
通常コーディングにおいては、コードの視認性を高めるためタブ、スペースなどのインデント、改行を使うかと思います。この時、仮に何万個スペースやタブを使おうと、実際のブラウザーのレンダリングには現れることがありません。改行を何回しようと、その分だけスペースが空くことはありませんね。
これは、要素と要素の間にある連続したスペース、タブ、改行タグは全て一つの要素間ホワイトスペースと見なされているからです。通常この仕様はとても便利に働きます。あまり意識することもないのではないでしょうか。
もしwebページ上でコードをHTML上の表記通りに表示させたい場合はpre
要素を使います。
トラブルシューティング:横並びリストの間に余分な間隔が出来る
この仕様がコーディングのトラブルとして表出してくるのは、グローバルメニュー等のような横幅の決まったオブジェクトを横並びにする時ではないでしょうか。余分な間隔を作らないようにしている仕様が、この場合は余分な間隔を作ってしまいます。
リストオブジェクト内のli
要素は基本的にブロック要素扱いであり、横並びになることはありません。これを横並びにしたいときにdisplay:inline;
やdisplay:inline-block;
を使うことがあります。しかし、このままではli
要素同士の間に隙間が出来てしまいます。
前述の説明で、なぜ横並びのリストの間に隙間が出来るかがわかったと思います。これはli
要素をインライン扱いにしたことによってli
要素間に要素間ホワイトスペースができている、というわけです。
これを解決するとしてli
要素を改行せずに記述する、li
要素の間をコメントアウトするなどの対処法がありますが、それらが何故その隙間をなくしてくれるのかも理解出来ますよね。
もちろんこれはdisplay:table-cell;
やfloat
プロパティー等を使っても構わないわけですが。
終わりに
いかがだったでしょうか。これら暗黙の要素はそれをコントロールするプロパティや属性のない単なる仕様なので、キーワードとして学ぶことがないのが特徴です(他のHTMLやCSSで苦戦しがちなFloatの使い方やForm周りなどは特定の要素やプロパティーの問題だったりするので学習しやすい)。
殆どの問題は、先人達が最適解を既に見つけ出していて、こういった些細な仕様のせいで苦しめられることってあまりなくなったかと思います。でも、そのセオリーやフレームワークからひとたび出てしまった場合にこれを知っているかどうかは後々大きな差を生むのではないかと思います。
80%の出来はまでは大抵なんとかなります。ですがプロの仕事にはブラウザ対応、環境対応等の詰めの部分までが求められますよね。限りなく100%の出来に近づけられるよう、細かい仕様も理解していきましょう!私もぺーぺーですが制作者のはしくれとして、皆さんと一緒に頑張っていきたいです★
追記
言葉が足りないなと思った部分を全体的に追記しました。