風仙洞

HTML + CSS でブログ風レイアウト

初版:2010/12/15
第2版:2022/08/19
第3版:2023/02/24
全面改定:2025/02/17

目次

はじめに

ブログは HTML の知識なしに始めることができる。また、記事をテーマ別や月別に分類したり、作成したWebページにデザイン的な統一感を持たせたりすること可能である。

こうしたメリットがある反面、予め用意されたテンプレートに満足せずにカスタマイズしようとすると、得体の知れない記号が出てきて急に難しくなってしまう。また、なまじ CSS の知識があると、画像の処理やデザインの自由度に関する不満が高まってしまう。ブログでも CSS をインラインで利用することは可能であり、テンプレートで CSS をカスタマイズできるが、慣れた HTML エディタで入力支援機能を利用した方が楽に書ける。

そこで、私がこのWebサイトで採用している方法を紹介する。なお、これには CSS(cascading style sheet=カスケード・スタイル・シート)の知識が不可欠なので、CSS の知識が全くない方は、CSS の勉強をするか、諦めてブログのシステムでWebページを作って下さい。

4部分2列レイアウトの例

右図(スマホでは上図)は、ブログによく見られるレイアウトである。上下のヘッダー部とフッター部、中段左の主要部、中段右のメニュー部(或いは左右逆)から構成されている。Webページも、同じような構造である。

しかし、XHTML 1.0 の時代までは主要部とメニュー部を横並びに配置するのは意外と困難であった。考え方としては div 要素などを CSS によってスタイル・コンテナとして利用すれば良かったのであるが、主要部とメニュー部が左右に分かれてしまったり、指定した幅にならなかったりした。そのため癇癪を起こして、

  • table 要素をレイアウトのために利用する
  • frameset(XHTML 1.0 では非推奨だがまだ使えた)を利用する

という悪癖に陥ってしまう人も多かった。実際私も 2010 年頃に相当悩み、やっと解決した記念にこのページの初版を書いたという経緯がある。

初版では、div 要素の id 属性として contents(表示する全体)、ヘッダー部、メイン部、サイドバー(メニュー部)、フッター部を指定した。第2版では HTML5 で書いたので、XHTML 1.x には存在しなかった header、main、footer 要素が使えるようになり、メンテナンスが容易になった。(その3つの要素がないと、終了タグの </div> がいくつも連続することになるので、コメント行を挟まないと、ペアを成す開始の <div> を見つけにくかった!)

スケルトンの HTML

今、HTML の最新版である HTML Living Standard に従ってスケルトンの HTML ファイルを記述すると次のようになる。

スケルトンの HTML を作るための Emmet
スケルトンの HTML を作るための Emmet
  • この画像は横スクロール可能
スケルトンの HTML
スケルトンの HTML
  • この画像は横スクロール可能

HTML エディタとして Visual Studio Code を使っている場合、このスケルトンは

  1. [Ctrl]+[N] で新規ファイルを作成
  2. 右下の通知領域の「プレーンテキスト」をクリック
  3. 上部に表示された(プログラミング)言語欄に半角で「h」と入力
  4. 候補が少なくなったところで「HTML」を選択(HTML モードになる)
  5. [!] → [Tab]キー押下(Emmet 省略記法が機能する)
  6. 日本語のページを作成する場合、html 要素の lang 属性の値を「en」(英語)から「ja」(日本語)に変更
    • 上のスクリーンショット2つでは lang 属性の値は既に「ja」になっているが、VS Code の初期状態では lang 属性の値は「en」
    • 「設定」で「emmet variables」をキーとして検索し、項目名「lang」、値「ja」を追加すると最初から「ja」になる)
  7. ヘッダー・セクションの最後に style 要素を追加
  8. ファイルとして保存(全角文字は使わない。拡張子の左は半角英数字と「-」「_」で構成されていること。)

という手順で作成できる。余談だが、このサイト内に HTML/CSS 初心者向けの VS Code 設定例を解説したページがあるので、良ければ見て下さい。

表示したい内容は body 要素の内容として記述する。私の流儀では、ページ全体のレイアウトに使用する構造的要素は下の5つである。id 属性の代わりに class 属性を使ったり、div id="sidebar" の div 要素の代わりに aside 要素を使ったりしても良い。

  • 全体: <div id="contents">~</div>(下の4つを括る)
  • ヘッダー部: <header>~</header>
  • メイン部: <main>~</main>
  • サイドバー(メニュー部): <div id="sidebar">~</div>
  • フッター部: <footer>~</footer>

これらの要素とダミーのテキストを使って HTML コードを記述すると次のようになる。

● HTML 例(body の内部)
  • <div id="contents">
  • <header>
    <h1>サイト名サイト名</h1>
  • </header>
  • <main>
    <h2>ページ名ページ名</h2>
    <p>
    • テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
    </p>
  • </main>
  • <div id="sidebar">
    • <ul>
      <li>メニュー1</li>
      <li>メニュー2</li>
      <li>メニュー3</li>
    • </ul>
  • </div>
  • <footer>
    • <address>
      Copyright © 2025 hogehoge. All Rights Reserved.
    • </address>
  • </footer>
  • </div>

この HTML コードと CSS で実現したい仕様は、

  • 全体:幅 1000px
  • ヘッダー部:幅 1000px
  • メイン部(中段左側):幅 700px、高さ 500px 以上
  • サイドバー(中段右側):幅 300px
  • フッター部:幅 1000px、高さ 70px

である。初歩ということでレスポンシブ・デザインは考えず、PC向けの4部分2カラム3段のレイアウトである。また、各部の内容はダミーなので適当である。

ただし、このままでは境界がはっきりしないので、

  • ヘッダー部とフッター部にはベージュ色、サイドバーにはラベンダー色の背景色を付ける
  • メイン部には太さ 1px のボーダーを付ける(その分 700px から差し引く。要素の大きさを内税方式にする「box-sizing: border-box;」を適用しても良い。)
  • 必要に応じて適切な要素、CSS を追加する

ことにする。

旧式:float による2カラム

前章末のままブラウザで閲覧すると、4つの要素が積み重なった1カラムになってしまう。それを変更するのが CSS(Cascading Style Sheets)である。

中段を2カラムとするレイアウトを実現したい場合、HTML5 登場前の XHTML 1.x までは CSS で float という手法を使っていた。

● 追加 HTML
  • ☆A案:div="sidebar" の終了タグと footer の開始タグの間に <br class="both"> を挿入する。
  • ☆B案:main と div="sidebar" を div class="clearfix" で括る。
● float での CSS
  • div#contents {width: 1000px; margin: auto; line-height: 1.7;}
  • main {width: 698px; float: left; border: gray solid 1px; min-height: 500px;}
  • div#sidebar {width: 300px; float: left; background-color: lavender; min-height: 300px;}
  • footer {height: 60px;}
  • header,footer {background-color: beige;}
  • /* 追加 start */
  • h1,h2 {margin: 0; padding: 10px 20px;}
  • p {text-indent: 1em; margin-inline: 10px;}
  • address {margin: 10px; padding-block: 10px;}
  • br.both {clear: both;} /* A案で使用 */
  • .clearfix::after {content: ""; display: block; clear: both;} /* B案で使用 */
  • /* 追加 end */

これらの HTML/CSS コードをブラウザで閲覧すると、次のようになる。

float でのレイアウト例
  • 画像をクリック(タップ)すると拡大

A案「br 要素の clear: both」は昔からある回り込み解除方法である。B案は「clearfix」と呼ばれ、「::after」という擬似要素も使っていて新しい。float した要素を檻の中に閉じ込めるイメージである。

A案、B案の clear: both により回り込み解除は実現できた(回り込み解除をしないと、footer の内容がサイドバーの領域に流入してしまう)。しかし問題が......。

  • サイドバー部の下に空白ができてしまった。
  • フッターの上にも少し隙間ができてしまった。

フッターやサイドバーに背景色を付けなければ気がつかれないだろうが、気になるところではある。それに何よりも、float することにより、サイドバーだけでなくメイン部をもレイアウトの本筋から外すのは釈然としない。

結論としては使いにくいので、ページ全体のレイアウトに float を使うのはやめた方が良い。

推奨:grid による2カラム

ということで、HTML5 以降可能となった grid レイアウト の出番となる。

grid レイアウトでは対象となるブロック要素を枡目に見立て(display: grid;)、縦横それぞれについて、親要素には枡目がいくつあるかを指定し、子要素は何番目から何番目の線を使うかを指定するのが基本。次の線までの場合は2番目の値を省略できる。

● grid レイアウトでの CSS
  • div#contents {width: 1000px; margin: auto; line-height: 1.7; display: grid; grid-template-columns: 698px 300px; grid-template-rows: repeat(3,auto);}
  • header {grid-column: 1 / 3; grid-row: 1;}
  • main {grid-column: 1; grid-row: 2; border: gray solid 1px; min-height: 500px;}
  • div#sidebar {grid-column: 2; grid-row: 2; background-color: lavender;}
  • footer {grid-column: 1 / 3; grid-row: 3;}
  • footer {height: 60px; margin-top: 0;}
  • header,footer {background-color: beige;}
  • /* 追加 start */
  • h1,h2 {margin: 0; padding: 10px 20px;}
  • p {text-indent: 1em; margin-inline: 10px;}
  • address {margin: 10px; padding-top: 5px;}
  • /* 追加 end */
  • 画像をクリック(タップ)すると拡大

grid レイアウトではサイドバーがメイン部に対応して下に伸びてくれる(正確には、「短い方が長い方に追従すして伸びる」)。中段とフッターの間にも隙間ができていない。

なお、上の例は初心者向けなので、grid-template-columns の値を2つとも固定値にした。

しかし、 レスポンシブ・デザインにする時、値には

  • 1fr と固定値の組み合わせにする
  • calc(100vw - 16px) のように calc 関数による計算値を使う
  • max-width プロパティや max 関数、min 関数を使う

方が便利である。

代案:flex による2カラム

乗りかかった船なので、flexbox による2カラムも説明する。

flexbox は基本的にはブロック要素を横並びにする手法である。flex-wrap: wrap; も適用すれば次の段に伸びる。flex-direction プロパティを使えば並ぶ方向を変更できる。grid レイアウト が指定席制なのに対して、flexbox は先着順に着席する感じである。

能書きはこのくらいにして、CSS は次のようになる。

● flexbox での CSS
  • div#contents {width: 1000px; margin: auto; line-height: 1.7; display: flex; flex-wrap: wrap;}
  • header {width: 100%;}
  • main {width: 698px; border: gray solid 1px; min-height: 500px;}
  • div#sidebar {width: 300px; background-color: lavender;}
  • footer {width: 100%;}
  • footer {height: 60px; margin-top: 0;}
  • header,footer {background-color: beige;}
  • /* 追加 start */
  • h1,h2 {margin: 0; padding: 10px 20px;}
  • p {text-indent: 1em; margin-inline: 10px;}
  • address {margin: 10px; padding-top: 5px;}
  • /* 追加 end */

この CSS と HTML で得られる画面は grid レイアウトの場合と同じなので省略する。ただし、縦方向の配置を指定する align-items プロパティの値として取り得るいくつかのオプションを適用すると、float の時のように、サイドバーが縦方向に伸びなくなる。


最後に結論。ページ全体のレイアウトには grid が一番良いだろう。レスポンシブ・デザインには、複数カラム、複数段のレイアウトをメディア・クエリーで1カラムに変形させれば良い。ただし、メニューをどうするかという問題を解決しなくてはならない。。

ページ数がいくつであるかも関係するので、なかなか難問である。横三本線をクリック/タップするとメニューがびょ~んと表示される「ハンバーガー・メニュー」がひとつの解決策であるが、作り方はいくつかある。いつかその問題を採り上げてページにまとめるつもりである。

✨ 関連ページ