ゼロからウェブサイトを作るための勘所

ウェブサイトを作るアルバイトを1年ちょいやったので、そこで必要だった知識をメモ。

はじめに

この記事は、筆者がウェブサイト制作のアルバイトを1年ほど行った結果、ウェブサイトを制作するのに必要だった知識を制作手順ごとにまとめたものである。
制作環境はMac + Google Chrome + Dreamweaver + Photoshop + Illustratorだが、今回はソフトウェアの使い方についてはほとんど解説しない。

今回は「htmlとcssをどのように書けば目的のレイアウトを作れるか」に重点を置いて解説する。

尚、本記事では説明を複雑にしないようにcssはhtmlファイル内のstyleタグに直接記述するが、実際に業務を行う場合はhtmlファイルとcssファイルはしっかりと分けて、要素の定義とデザインは分離して管理することを推奨する。

対象読者

htmlとcssは結構触るが、レイアウトまでは作れないプログラマ寄りの人

ワイヤーフレームを作成する

まず初めに、ウェブサイトの構成を決める。どのようなコンテンツが必要か、コンテンツをどのように配置するか、ウェブサイトのページ数、バックエンド(サーバー、プログラム、データベース)はどんなものが必要か、などを洗い出す。
実際に図に起こしておくと分かり易いが、大まかな構成さえ把握できるなら簡単なメモでも構わない。

デザインデータを作成する

ワイヤーフレームをもとに、Adobe Illustratorを使用してウェブサイトの設計図を作成する。
設計図を作る段階で気を付けることは、「コンテンツの幅の設計」と「キリの良い数値でオブジェクトを作成すること」と「ブラウザサイズを100%としたときのコンテンツの比率計算」である。

コンテンツの幅の設計

コンテンツを表示する幅をまずは決める。この幅は、ブラウザの幅を縮めていったときに、それ以上縮小せず、コンテンツが崩れて表示されないようにするためのものである。この幅は全ページ共通になることが多いので、設計を始める段階で決めておくことが望ましい。
2017年時点では、PC版が横幅1000px(前後)、スマートフォン版が横幅750pxが推奨されている。つまり、PC版のコンテンツ幅を1000px、レスポンシブのブレイクポイント(PC版とスマホのCSSを切り替えるブラウザの横幅)を750pxに設定することが基本となる。

キリの良い数値でオブジェクトを作成する

デザインをコードに落とし込む段階で計算が面倒にならないように、オブジェクト(配置するボックスや画像の幅と高さ)はキリの良い数値にすることが望ましい。キリの良い数値とは、「248.6px」のようなものを「250px」にすることである。

ブラウザサイズを100%としたときのコンテンツの比率計算

横幅いっぱいにコンテンツが広がったり、縦幅いっぱいにコンテンツが広がるデザインの場合、コンテンツの幅や高さをパーセント(%)で記述しなければならないことがある。
そういった場合に、行・列のいずれかの方向に2つ以上のオブジェクトが続く場合、オブジェクトのサイズを「50%:50%」や「30%:70%」のように比率で計算しておく必要がある。

リセットCSSを用意する

コーディングを始める前にリセットCSSを用意する。ユーザーがChrome・FireFox・IEといったブラウザのどれを使ってもこちらが意図した表示を提供するためにはリセットCSSが必要になる。
以下のリセットcssはEric Meyer氏により考案されたもので、現在も広く使用されている。

reset.css

/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre, a,
abbr, acronym, address, big, cite, code, del,
dfn, em, img, ins, kbd, q, s, samp, small, strike,
strong, sub, sup, tt, var, b, u, i, center,
dl, dt, dd, ol, ul, li, fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, figure,
figcaption, footer, header, hgroup, menu, nav,
output, ruby, section, summary, time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

基本形となるhtmlファイルを用意する

以下のhtmlファイルを準備し、ここにhtmlを記述していく。今回はDOCTYPE宣言をxhtmlのtransitionalとする。ファイルの拡張子は.htmlとする。

<!DOCTYPE html PUBLIC "-//w3c//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <link rel="stylesheet" type="text/css" href="reset.css" />
  <link rel="stylesheet" type="text/css" href="style.css" />
  <title>タイトル</title>
</head>
<body>

</body>
</html>

ブラウザと対話しながらコーディングを進める

Google Chromeに備え付けられているデベロッパーツールを使用することで効率的にコーディングを進めることができる。WindowsならCtrl + Shift + i、MacならCmd + Opt + iで開く。CSSでハマったときは要素の検証を駆使してブラウザ上でCSSを書いたほうが解決が早い場合が多い。
また、端末ごとに処理を切り分ける場合はユーザーエージェントを変更することで各端末での動きを確認することができたり、Javascriptのデバッグに便利なBreakpointの設定などもできるので開発に役立つ機能はどんどん使っていきたい。

デザインデータをコードに落とし込む

ここまでの準備が終わったら、いよいよコーディングに入る。デザインデータ(Adobe Illustratorのファイル)から画像やオブジェクトの横幅・縦幅を抽出し、htmlとcssに落とし込んでいく。

デザインをコードに落とし込むためのコツは、以下の通りである。

  1. 必要な要素を考える
    • 要素数を考える
    • ブロックレベル要素とインライン要素の違いを意識する
  2. オブジェクトの配置方法を考える
    • margin:0 autoによる中央寄せを覚える
    • ボックスモデルとマージンの相殺を意識する
    • ネガティブマージンによる配置方法を覚える
    • floatプロパティによる左右寄せを覚える
    • clear fixによるfloatの解除方法を覚える
    • positionプロパティによる配置方法を覚える
    • z-indexプロパティによる要素の重なり順の変更方法を覚える
    • box-sizingプロパティでサイズ指定を便利にする

必要な要素を考える

どのような要素があれば目的のデザインが実現できるかを考える。

要素数を考える

例えば、以下のように「画面中央に背景が黒のブロックを配置し、中央に赤いラインが入っていて、その中央に文字が入っている。」というデザインをコードに落とし込む場合を考えてみる。

center-three-div

このデザインを実現するためには3つのブロックレベル要素が必要である。以下のように黒いブロックを作るのに1個、赤いブロックを作るのに1個、文字を入れるブロックを作るのに1個使用する。

<div class="a">
    <div class="b">
        <p class="c">ここが中央</p>
    </div>
</div>

説明を複雑にしたくないので、cssの説明は省くが、ここで重要なのはデザインを実現するために何個の要素が必要かを意識することである。

ブロックレベル要素とインライン要素の違いを意識する

要素は「ブロックレベル要素」と「インライン要素」の2つに大きく分けることができる。

  • ブロックレベル要素
    「かたまりの要素」である。見出し・段落・表など、文書を構成する基本となる要素で、一つのブロックとして認識される。一般的なブラウザでは前後に改行が入る。ブロックレベル要素の中には、ブロックレベル要素とインライン要素の両方を入れることができる。ほとんどのブロックレベル要素は、width、height、margin、paddingなどのプロパティを持つことが出来る。代表的なブロックレベル要素には、div、p、h1~h6、ul、ol、tableなどがある。

  • インライン要素
    「文章の中に埋め込む要素」である。主にブロックレベル要素の内容として用いられる要素で、文章の一部として扱われる。例えば、p要素の中のstrong要素のように、段落のなかの一部を強調するような使われ方をする要素である。一般的なブラウザでは前後に改行が入らず、文章の一部として表示される。インライン要素の中にはブロック要素を入れることができず、インライン要素のみを入れることができる。ほとんどのインライン要素は、width、height、margin、paddingなどのプロパティを持つことが出来ない。代表的なインライン要素には、a、em、span、strongなどがある。

displayプロパティの使い方

displayプロパティを使用することで、ブロックレベル要素とインライン要素を切り替えることができる。
例えば、インライン要素であるspanに対してdisplay:blockを指定するとspanはブロックレベル要素になるので、width、height、margin、paddingなどのプロパティを持つことができるようになる。

記述例

<p>2020年東京オリンピックまで<span style="display:block; height:50px; width:250px; margin-top:10px; font-size:36px; text-align:center; border:solid 1px #000000; line-height:1.4">1000日</span></p>

動作例

2020年東京オリンピックまで1000日

オブジェクトの配置方法を考える

どのような配置方法を使えば目的のデザインが実現できるかを考える。以下より紹介するいくつかのテクニックを押さえておくことで、自由自在な配置をすることが出来るようになる。

margin:0 autoによる中央寄せを覚える

以下のようにブロックレベル要素に対して、margin:0 autoを指定することで中央寄せにすることが出来る。この方法で中央寄せを行う場合、中央寄せにしたい要素が幅と高さを持っている必要がある。

<div style="margin: 0 auto; width:200px; height:200px; background-color:#000000;"></div>

ボックスモデルとマージンの相殺を意識する

ボックスモデルとは、主にブロックレベル要素で使用する、width、height、margin、padding、borderなどの構造である。

box_model

※非常に分かりやすい画像なのでこちらから引用させていただいた。

要素と要素の間に空白を取りたい場合、基本的にはmarginを使用することになるが、marginの仕様にはちょっとした落とし穴がある。
親子関係(入れ子)や連続している2つの要素に上下のマージン(margin-topやmargin-bottom)を指定した場合、マージンの相殺が起こってしまう。
これは上下のマージンが隣り合っている場合に先に宣言されている要素に、あとから宣言した要素のマージンが吸収されてしまうという仕様である。

例えば、先の例でも示したが「画面中央に背景が黒のブロックを配置し、中央に赤いラインが入っていて、その中央に文字が入っている。」というデザインを実現したい場合、普通の感覚なら以下のようなコードで実現出来ると思うだろう。

<div style="background-color:#000000; width:300px; height:300px; margin:0 auto;">
    <div style="background-color:#ff0000; width:100%; height:50px; margin-top:125px;">
        <p style="color:#ffffff; text-align:center; line-height:3.2;">ここが中央</p>
    </div>
</div>

しかし、結果は最上位のdivが子要素のdivのmargin-topを吸収してしまうのでレイアウトが崩れてしまう。このマージンの相殺を避けるためには、マージンとマージンを隣合わせにしない必要がある。つまり、paddingを間に挟むことで上下のマージンが相殺されなくなる。

<div style="background-color:#000000; width:300px; height:300px; margin:0 auto; padding-top:1px;">
    <div style="background-color:#ff0000; width:100%; height:50px; margin-top:0px; margin-top:125px;">
      <p style="color:#ffffff;text-align:center;line-height:3.2;">ここが中央</p>
    </div>
</div>

しかし、これだと余分な1px分のpaddingが入ってしまうのが難点である。そこで、これを解決するために、最上位の親のdivのheightとpaddingを上手く計算して調整することで下位のdivがマージンを取っているように見せることが出来る。

<div style="background-color:#000000;width:300px;height:175px;margin:0 auto;padding-top:125px;">
  <div style="background-color:#ff0000;width:100%;height:50px;">
    <p style="color:#ffffff;text-align:center;line-height:3.2;">ここが中央</p>
  </div>
</div>

上記では最上位のdivのheightを300pxから175px、padding-topを125pxに設定している。本来ならば、heightを150px、padding-topを150pxに設定したいところだが、子要素のdivのheightが50px持っているので、padding-topには50pxの半分の25pxを引いた125pxを設定しているというわけだ。

また、同様のレイアウトを実現するために、上記とは違うアプローチとしてネガティブマージンを使用する方法が挙げられる。以下より、この方法について説明する。

ネガティブマージンによる配置方法を覚える

marginプロパティにマイナス値を指定することで、要素の位置を調整することが出来る。
例えば、画像の上に文字を乗せたい場合は、以下のようにmargin-topにマイナス値を設定することで実現することが出来る。

ネガティブマージンの例

<img src="/content/images/2018/03/74211c5c3346a734f2a4759a41eaa6b1-616x400.jpeg" />
<p style="margin-top:-150px; color:#ff0000;">犬っぽいですね!!</p>

また、このネガティブマージンを使用することで先の例で示した「画面中央に背景が黒のブロックを配置し、中央に赤いラインが入っていて、その中央に文字が入っている。」というデザインを実現したい場合、以下のようなコードで実現することができる。

<div style="background-color:#000000;width:300px;height:300px;margin:0 auto;"></div>
<div style="background-color:#ff0000;width:300px;height:50px;margin:-175px auto 0 auto;">
  <p style="color:#ffffff;text-align:center;line-height:3.2;">ここが中央</p>
</div>

上記は黒いボックスの中にあった赤いボックスを外に出し、margin:-175px auto 0 autoと指定することで、ネガティブマージンを利用して黒いボックスの上に赤いボックスを重ねて見せている。

floatプロパティによる回り込み(左右寄せ)を覚える

floatプロパティを使用することで、要素を左右に寄せることが出来る。
以下のようにfloatにleftを指定すると左寄せ、rightを指定すると右寄せになる。

<div style="float:left;">左寄せ</div>
<div style="float:right;">右寄せ</div>

また、floatの最大の特徴は、floatで右寄せや左寄せになっている連続した2つ以上の要素がある場合、2つ以上の要素の合計の幅が親の要素の幅に収まりきらない場合は、次の行に流れ込むという仕様である。
例えば、8つのブロック(要素)を4列2行にして並べたい場合、子要素の幅を20%、左右のmarginを2.5%にすれば、要素を4つ並べると100%になり、5つ目の要素が幅に収まりきらず自動的に2行目に流れ込むので、4列2行のレイアウトを実現することが出来る。

4列2行の記述例

<ul style="width:500px; height:220px; list-style-type:none;">
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
    <li style="float:left; width:20%; height:100px; margin:5px 2.5%; background-color:#000000;"></li>
</ul>

4列2行にする動作例

clear fixによるfloatの解除方法を覚える

floatによる回り込み(左右寄せ)の解除方法として、最も一般的なのがclear fixと呼ばれる方法である。floatを行っている要素をcfクラスの要素で囲むことでfloatを解除することができる。コーディング中は頻繁に使用するため、common.cssという汎用cssファイルを用意して、そこに記述しておくと良いだろう。

使用方法は以下のようになっている。cfクラスで回り込み(float)を行う要素を囲む。

<div class="cf">
    <div style="float:left;">左寄せ</div>
    <div style="float:right">右寄せ</div>
</div>

common.css側には以下のように記載する。

.cf:after {
    content:"";
    display:block;
    clear:both;
}

positionプロパティによる配置方法を覚える

positionプロパティを使用することで、要素を相対位置、絶対位置、固定位置に配置することができる。

  • position:absoluteを使用することで要素を絶対位置に配置することができる。
    絶対位置を指定するときは、その親要素にposition:relativeを指定することで、その親要素を基準にして位置の調整を行うことができる。ウェブサイト内で絶対位置指定をよく使う箇所は、他の要素との位置的な繋がりが無く独立していたり、ブラウザの幅や高さの変更の影響を受けない要素である。

絶対位置指定の例

<div style="position:relative; width:300px; height:300px; margin:200px; background-color:#000000;">
    <div style="position:absolute; top:10px; left:10px; color:#ffffff;">絶対位置です。</div>
</div>
  • position:fixedを使用することで要素の位置を固定することができる。ブラウザの幅や高さを変えたり、スクロールしたりしても位置が変わらない。

固定位置指定の例

<div style="position:fixed; top:10px; left: 10px;">固定します。</div>
<!-- ※スクロールして確認出来るように縦長のdivを配置 -->
<div style="height:3000px;"></div>

  • position:relativeを使用することで要素を相対位置に配置することができる。
    position:relativeの使いどころとしては、上記で説明したposition:absoluteとの組み合わせや、下記で説明するz-indexとの組み合わせに限られる。

z-indexプロパティによる要素の重なり順の変更方法を覚える

通常は後から記述された要素ほど上に重なって表示されるが、z-indexプロパティを使用することで要素の重なり順を変更することができる。
また、z-indexプロパティを使用するには、positionプロパティの値がrelative、absolute、fixedのいずれかである必要がある。ほとんどの場合はposition: relativeを指定する。

z-indexプロパティの例

<p style="color:#ff0000; margin-top:100px; position: relative; z-index: 100;">上に重なったかな?</p>
<img style="margin-top:-100px; margin-left:-20px;" src="/content/uploads/2014/03/74211c5c3346a734f2a4759a41eaa6b1-300x300.jpeg" />

box-sizingプロパティでサイズ指定を便利にする

box-sizingプロパティにborder-boxを指定することでpaddingとborderを要素の幅と高さに含めることができる。
例えば、300px × 300pxのボックスに1pxの枠線(border)を設定したい場合、このまま設定するだけでは301px × 301pxのボックスになってしまう。かといって、ボックスのサイズを299px × 299pxにしてしまうとぱっと見ただけではボックスのサイズが分からなくなってしまい、計算が非常に面倒になる。
そこで、box-sizingプロパティにborder-boxを指定することで、ボックスのサイズがボーダーを含めたものになるため、扱いが簡単になる。

box-sizingプロパティの例

<div style="width:300px; height:300px; border:solid 1px #000000; box-sizing: border-box;"></div>

参考
Webサイトデザインの横幅サイズ!もう何pxか迷わない! 2017年1月版
ブロックレベル要素とインライン要素
ボックスモデル
position:relativeの使いドコロ