6. road to mastering CSS

本章の目次

6章では,実際にスタイルシートを構築する上で重要になる概念や,無理の無いシートにするための「考え方」を紹介します。

6.1. 逆説的な導入

6.1.1. CSS1のみによる影付き文字

CSS2では「影付き文字」のための専用プロパティが用意されましたが,Internet Explorer4.0もNetscape navigator4.0もまだこれをサポートしていません。しかし,CSS1の機能のみでも,マイナスの上マージンとテキストインデントを利用すれば,「影付き文字」効果を簡単に作れるのです(図6-1)。

図6-1 影付き文字
【図6-1】――同じ文字列を少しずらして描写すると,文字に影がついたように見えます。

「おう,これは簡単で,しかもカッコイイ! これでこそスタイルシートだ!」

しかし,本当にそうでしょうか。

図6-1のソースコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>text with shadow</TITLE>
<STYLE TYPE="text/css">
    BODY{background: white;}
    H1{
        font: 700 2em sans-serif;
        line-height:1;
    }
    H1 SPAN{
        margin: 0em;
        display: block;
    }
    H1 SPAN.BEHIND{
        color: gray;
    }
    H1 SPAN.FORWARD{
        color: black;
        margin-top: -1.2em;  /* ここがポイントです */
        text-indent: -0.2em;  /* ここがポイントです */
    }
</STYLE>
</HEAD>
<BODY>
<H1>
<SPAN CLASS="BEHIND">文字に影を付ける</SPAN>
<SPAN CLASS="FORWARD">文字に影を付ける</SPAN>
</H1>
<P>少しずらして文字を描写すれば,影がついたような感じになります。</P>
</BODY>
</HTML>

6.1.2. 画像にしなかった利点はあるのか

影付き文字などの効果は,ドロー系の画像作成ソフトウェアを用いればより簡単に,しかも高度に作成できます。また,この結果をペイント系レタッチソフトで加工すれば,水でぬらしたようににじませたり,グラデーション,エンボスなどさまざまな効果を実現できます。それをせずに,わざわざスタイルシートを用いた理由は何でしょう。

「だって,はじめに“画像は望ましくない”っていったじゃないか」

確かに,画像にしてしまうとデータサイズが大きくなりますし,また画像を表示できない人に情報を伝達できません。しかし,それでも画像でしか得られない効果が必要なときは,やはり画像を用いるべきです。スタイルシートは画像の代替になるものではありませんし,そのように利用するのは望ましくありません。

図6-1のHTML文書を,スタイルシートをオフにして表示するとどうなるでしょうか。ソースを見て分かるとおり,

となります。この文書の見出しは「文字に影を付ける文字に影を付ける」でいいのでしょうか?

この問題は,CSS2のサポートを待てば解決するわけではありません。なぜなら,根本にあるのは,「本来スタイルシートで行うべきでないことを強行した」という問題なのです。

このような事態は,1章で挙げたスタイルシートの利点に反するものです。どちらかといえば,「怪しいテクニック」の欠点に近いものです。これは望ましい使い方ではありません。

コラム:どうするべきだったのか

本来の見出しは「文字に影を付ける」のはずです。そうであれば,HTML文書インスタンスには

<H1>文字に影を付ける</H1>

とのみ書かれているべきです。影付き文字として表示したければ,それを画像にし,

<H1><IMG SRC="title.gif" ALT="文字に影を付ける"></H1>

としておくのが良いでしょう。これならば,画像を表示しない人にも内容を伝達できます。

6.1.3. 好ましい「考え方」

スタイルシートはHTML文書の表示結果を調整するものです。しかし,スタイルシートが無いと読めないようなHTML文書を書いてはいけません。では,スタイルシートはどんな形でHTML文書と連携するべきなのでしょう?

筆者のこたえは簡潔です。

2・3章では,HTML文書で構成を明示することを解説しました。その指針にしたがっている限り,作成したHTML文書はスタイルシート無しでも十分文章内容をアピールできています。それなのに,わざわざ図6-1のように文書内容を改ざんしないでください。

スタイルシートは,その文章アピールを補助的にサポートするものであるべきです。「見出しは見出しらしく」「本文は本文らしく」をモットーにスタイルシートを記述していきましょう(補助的といっても,見栄えに関してはHTML文書を支配するものです)。

以降では,スタイルシートを記述するための考え方を,「全体的な調整」「見出しの調整」の順に具体的に紹介します。最後には,使いまわしの効くスタイルシートに関する考察を紹介します。

6.2. 全体的な調整

6.2.1. 「一般 → 例外」という原則を守る

文書のスタイル表現に限らず,多くの表現には「一般」と「例外」が存在します。通常,本文中のほとんどの文は同じスタイルで書かれ,その中の特別な語句,すなわち,見出しや強調語句だけが特別なスタイルで書かれています。

CSSの継承(inheritance)という仕組みを利用すれば,この「一般」と「例外」を的確に表現できます。すなわち,BODY要素に対して一般的なスタイルを指定し,各要素には基本的にその指定を継承させます。そして,例外的に指定したい部分を後から付け足していくのが望ましいでしょう。この考え方は,CSS2の仕様書にも明示されています。

6.2.2. BODY要素(一般本文)への指定

基本的に,本文は「読みやすい」ことが大事です。したがって,太さは太すぎず細すぎず,サイズは大きすぎず小さすぎず,フォントファミリーは奇抜でなく……と,「無難」なものを目指すのが普通だと思われます。一般的には,大体次のような指定になると思います。

/* whitebase.css */ /* 原始段階 */
BODY{
    font: medium serif;  /* weight-400: style-normal: variant-normal */
    text-align: left;
    background: #fff;  /* white */
    color:#000;  /* black */
    line-height: 1.4;  /* 一般に,読みやすいのは1.2〜1.7 */
}
/* 以降の指定はBODYへのものではありませんが,ここにあげておきます。 */
A:link{color:#63f}
A:visited{color:#f0a}
A:active{color:#f00;}

特別に意識すべき点は次のとおりです。

コラム:mediumか,12ptか?

whitebase.cssでは,BODYのfont-sizeをmediumとしました。これには理由があります。

もし,これをfont-size:12ptとした場合,読者はこのシートによる表示サイズを自分の環境に合わせて変更できません。一方,mediumの具体的なサイズは,読者がWWWブラウザの設定を変えることで,読者自身の手で調整できます。

ディスプレイの大きさによっては,12ptは小さすぎるかも大きすぎるかもしれません。したがって,筆者はmediumの指定をお勧めします。

6.2.3. インライン系要素への指定

STRONG要素やA(アンカー)要素といったインライン系要素は,本文の中に埋め込まれる特別な語句に相当します。これらが普通の本文と明確に区別できるのは良いことですが,あまり極端にスタイルを変更しては,かえって本文が読みにくくなります(図6-2)。悪い例としては,次のようなものが挙げられます。

図6-2 STRONG要素への指定の悪い例
【図6-2】――STRONG要素の部分が目立ちすぎて,全体として読みにくくなってしまいました。

挙げ始めるときりがないので二つで止めにしますが,大事なのは「無理の無い程度に変える」ように心がけることです。したがって,ボーダーラインや背景画像などの強烈なものは避けることにし,文字そのものに関するちょっとした調整に止めるほうが良いと思われます。次に挙げるものうち,いくつかを組み合わせて指定すると良いでしょう。

6.6.1で例に取り上げる「ks.css」では,STRONGに図6-3の指定を採用しています。

図6-3 「ks.css」のSTRONG
STRONG{
    color:black;
    background: #faa;
    font-weight: bolder;
}
【図6-3】――STRONG要素は背景色と文字の太さを変更しただけなので,段落全体の体裁が保たれています。

6.2.4. ブロック系要素への指定

自然言語(ふつうの言葉)で考えると,「本文」と「見出し」は別のものです。ところが,HTML4.0ではBODY要素が「本文」であり,その中に「見出し」や「段落」などが「ブロック要素」とひとくくりにされています。

しかし,やはり「見出し」は他のブロック系要素とは異なる特別な役割を持っています。すなわち,「見出し」とは本文の流れの変化を主張するための「道しるべ」であり,それに続く内容を端的に表している「短いまとめの言葉」です。したがって,「見出し」は一目で本文と区別できるほど目立っているべきですし,少々派手すぎても内容把握には支障ありません。つまり,「見出し」に関しては,遠慮せずにどんどんスタイルをいじるべきです。そこで,「見出し」に関しては,独立して6.4節として詳細に取り上げたいと思います。

他のブロック系要素は,「本文」を構成するものです。P要素を「ごく一般の本文」と捕らえるならば,BLOCKQUOTE要素などは「特殊な本文」だといえるでしょう。どちらにせよ基本的に「読むための」ものなので,それなりに抑えた指定であるべきです(ブロック系要素で文字そのものを派手にいじってしまうと,その内部のインライン系要素の表現に困ることになるでしょう)。

なかでも,BLOCKQUOTE要素は位置づけのはっきりした要素です。その内容は「他の書物などからの引用」なのですから,しっかりと「ごく一般の本文」と流れが区別できるべきでしょう。表現するべきは「流れの変化」ですから,文字そのものはあまりいじらずに,ボーダーラインやマージンなど「表示の枠」を中心に調整したほうが良いと思われます。そのためには,次のような指定が考えられます。

6.6.2で例に取り上げる「prince.css」では「マージンを均等に取り,ボーダーを左右のみに」指定し(図6-4),「zappa.css」では「左マージンを大きく取り,さらにボーダーも左だけに」指定しています(図6-5)。

図6-4 「prince.css」のBLOCKQUOTE
BLOCKQUOTE{
    margin: 2em;
    font: italic 1em monospace;
    color: #bbb;
    border-width: 0em thick;
    border-style: solid;
    border-color: #a40;
    padding: 1em 0.5em;;
}
【図6-4】――引用部分は,左右にボーダーが引かれ,また全体に余白が大きめに取られることで目立っています。
図6-5 「zappa.css」のBLOCKQUOTE
BLOCKQUOTE{
    margin:1.5em 1em 1.5em 3em;
    border-width: 0em 0em 0em thick;
    border-style: none none none solid;
    border-color: #969;
    padding: 1em 1em 1em 2em;
}
【図6-5】――引用部分は,左側にボーダーが引かれ,また左側を中心に余白が大きめに取られることで目立っています。

この考え方は,他のブロック系要素でも通用するでしょう。

なお,インライン系要素のときは「これらのうち幾つかを組み合わせて」といいましたが,ブロック系要素の場合は,「これらの全てを総合的に組み合わせて」指定するのが良いでしょう。インライン系要素は「ちょっとした違い」で,ブロック系要素は「はっきりとした違い」でアピールしましょう。

コラム:リストの表示に関して

リストに関する指定は,Netscape NavigatorやInternet Explorerなどの標準の指定(入れ子ごとに左マージンが深くなる)があまりにも絶妙な効果を上げています。われわれは,マージンのサイズを変える程度の変更にとどまるべきでしょう。

6.3. emユニットの活用(相対指定のススメ)

唐突に話の毛色が変わりますが,実際に「全体的な」スタイルシートの構築に入る前に,emユニットに代表される相対指定の重要性に関してお話します。

emユニットを無視すると,とんでもない混乱に陥ることがあります。まずは,emユニットを使わないとどんな難点に突き当たるのかを例示しましょう。

6.3.1. text-indentにおける混乱

例えば,フォントサイズ10ptの要素に対し,一文字分のインデントを期待するという意味で {text-indent: 10pt} と指定したとしましょう。これでは,フォントサイズを変更するたびにインデントの指定も変更しなくては「一文字文のインデント」をキープできません。 {text-indent: 1em} としていれば,難なく「一文字分のインデント」を実現できるのに……!

BODY{
    font-size:10pt;
    text-indent: 1em;
}
/* {text-indent: 10pt}でも一文字分だが,フォントサイズを20ptに変更したら,
10ptは一文字分では無くなってしまう。一方,1emは常に一文字分である。 */

6.3.2. 親子間のfont-sizeにおける混乱

また,BODYのfont-sizeが12ptのとき,H1をその2倍にしたい場合はどのように指定するべきでしょうか? たいていの場合H1の親要素はBODYなので,「 H1{font-size:2em} 」でOKです。関係を明示するために,「 BODY H1{font-size:2em} 」と文脈付きで記述しても構いません。これを「 H1{font-size:24pt} 」などとしてしまうと,BODYのfont-sizeを10ptに変更したときに,あわせてH1の指定まで変更する羽目に陥ります。

6.3.3. 問題の本質と解決の指針

以上で紹介したのは,実は「バランスをキープする上での問題」です。

スタイルシートは個々の要素のスタイルを別々に指定していくものですが,指定が個々で完結しているわけではありません。すなわち,スタイルシートは,各部分の相対的なバランスを考慮しながらくみ上げていくものであり,そのバランスをキープすることが重要課題になるのです。

ところが,各種指定を「絶対値」で指定してしまうと,ある部分を変更したくなった場合,連鎖して(バランスを保つために)別の部分を変更しなければならなくなります。この際にどこか一つでも連鎖変更を怠れば,思わぬところで意図した表示結果ではないものが表示されてしまいます。シートが複雑になればなるほど,「どこを直せばいいのかわからなくなる」ことは必至です。

この混乱を避けるには,「はじめから相対指定でシートをくみ上げていくべき」です。相対指定であれば,ある一個所のサイズを変更したとしても,バランスをキープするためにシート全体を書き直す必要はありません。なぜなら,はじめから「バランス」だけが書かれているのですから。

相対指定のためのサイズ単位としてもっとも柔軟性に富んでいるのがemユニットです。emユニットは,font-sizeプロパティにおいては親要素との相対関係を,その他のプロパティにおいてはその要素のfont-sizeとの相対関係を表現します。emユニットを用いれば,シートの中身が「何文字分のインデントやマージン」というわかりやすい表現になります。シートをわかりやすく記述し,しかも相対性を確保するために,存分にemユニットを活用するべきです(プロパティによっては,パーセント指定が可能なものもあります。パーセントもemユニットと同じように有用です)。

しかし,全てが「相対」では何も表示できません。すなわち,どこかに一つ,基準となる絶対値が必要です。筆者の考えでは,基準絶対値は「BODYに指定するfont-size」で指定するのがもっとも有用です。すなわち,BODYのfont-sizeのみを絶対サイズで記述し,残りのものはすべてemユニットやパーセント指定などの相対指定にしてください。そうすれば,BODYのfont-sizeを変更しただけで,他の部分の表示もバランスを保ったまま(自動的に連鎖して)変更されるのです。

コラム:太さの相対指定

font-sizeには,larger・smallerといった相対指定専用のキーワードが用意されています。しかし,一段階の「大きめ」「小さめ」しか指定できず,emユニットに比べると,表現力が貧弱です。

同様に,太さ(font-weight)にもbolder・lighterといった相対指定専用のキーワードがあります。しかし,やはり一段階の「太め」「細め」しか指定できず,表現力が貧弱です。といっても,emユニットでは太さは指定できないため,相対指定に関してはもう選択肢がありません。そこで,筆者は太さに関してはすべて絶対指定を採用しています。

これは,先に述べた理念と矛盾しています。申し訳ありませんが,目をつぶってください^^; と済ますのも何ですので,言い分け的ではありますが,指針を出しておきます。

bolder・lighterの指定は,インライン系要素への指定には有用だと思います。たとえば,STRONG要素の表示がH1要素中に現れようとP要素中に現れようと,確実に一段階太く・細く表示させることができるからです。

しかし,ブロック系要素の親子関係では,「一段階」の変化よりも急激に変化するほうが望ましい場合が多いでしょう。たとえば,H1要素はBODY要素よりも4段階以上太くなって欲しいと思っても不思議はないでしょう。

このような場合にはfont-sizeにおけるemユニットのようなものが欲しいのですが,CSS1ではそのような単位が用意されていません。そこで,本書はあえて絶対指定で太さを指定しました。

これでどうでしょう^^;

6.4. 見出しの調整

6.4.1. サイズと左マージン

既に述べたとおり,見出しは本文よりも目立っているべきだと考えられます。

さらに,見出しレベル間に違いを持たせることが重要です。レベルの上下が自然に読み取れるよう工夫しておくとより望ましいでしょう。一般に,見出しレベルの変化は,サイズの大小や左マージン量の増減で示されます。

図6-6に見出しを調整したスタイルシート例を提示します。ここでは,どのレベルの見出しにも共通する指定を先に記述しておくと,シート全体が把握しやすくなることをご確認ください。これも「一般 → 例外」という考え方のひとつです。

図6-6 見出しレベルをサイズと左マージンで表現
/* atomic.css */
@import url(whitebase.css);

/* 見出し全般への指定 */
H1, H2, H3, H4, H5, H6{
    font-weight: 700;
    font-family: sans-serif;
    line-height: 1.1;
} /* 以上のスタイルシートは,この章を通じてベースとして利用します。 */
/* standard.css */
@import url(atomic.css);
H1{
    font-weight:900; /* 更に太く */
    font-size:3em;  /* ずば抜けて大きく */
    text-align:right;  /* 右寄せで変化を強調 */
    margin: 1em 0em 0em 30%;
        /* “右寄+左に大きなマージン”は,文字折り返し時に効果が出る */
}
H2{
    text-align:center;  /* 真ん中よせで変化を強調 */
    font-size:2em;  /* 第1レベルよりは小さく,3,4よりは大きく */
}
H3{ font-size: 1.6em}
H4{
    font-size: 1.3em;
    margin-left: 1em; /* レベル3と4の違いは,左マージンで */
}
H5{
    font-size: 1.2em;
    margin-left: 1.3em;
}
H6{
    font-size: 1.1em;
    margin-left: 1.5em;
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<TITLE>ももたろうを考える</TITLE>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="whitebase.css">
<LINK REL="STYLESHEET" TYPE="text/css" HREF="atomic.css">
<LINK REL="STYLESHEET" TYPE="text/css" HREF="standard.css">
</HEAD>
<BODY>
<H1>1.ももたろうを考える</H1>
    <H2>1.1.出発まで</H2>
        <H3>1.1.1.はじまりはじまり</H3>
        <H3>1.1.2.桃太郎の誕生</H3>
    <H2>1.2.鬼が島へ</H2>
        <H3>1.2.1.旅の仲間</H3>
            <H4>1)犬猿の仲</h4>
            <H4>2)サルとキジ</H4>
</BODY>
【図6-6】――
コラム:@importとLINK要素を併記

standard.cssには@importでatomic.cssが取り込まれています。atomic.cssにはwhitebase.cssが取り込まれています。したがって,LINK要素でstandard.cssを指定しただけで,この3つのシートを指定したのと同じ効果が得られます。

しかし,この例ではわざわざ3つのシートへのLINK要素がかかれています。なぜでしょうか?

実は,Netscape Navigator4.0が@import構文をサポートしていないことへの配慮です。作業の手間は増えますが,過渡期にはこのようなテクニックが必要になるものです。

コラム:スタイルシートの分割と再利用

どのスタイルシートでも共通に使いうる土台的な部分は,独立したシートとして保存しておき,各シートから@importして利用すると便利でしょう。また,コンポーネント化の発想に基づいて,見出しだけ・段落だけ・引用ブロックだけのシートを複数用意し,LINK要素でそれらを組み合わせながら新たな効果を編み出していくのも楽しいと思われます。

しかし,筆者は「この場合はシートを分離しておくべきだ」という絶対的な方針をお伝えすることはできません。なぜなら,趣味や目指す指定によって,分離ルールは大きく変化するものだからです。

この章におけるシートの分離・コンポーネント化はあくまでも筆者の趣味によるものですが,もしこれが参考になれば幸いです。

6.4.2. 上下マージン

見出しは,ざっと眺めただけでもすぐに発見できるほど目立っているべきです。効果的に見出しをアピールするには,見出しの上下に大き目のマージンを入れるのが良いでしょう。

ただし,見出しの“上”は前セクションとの境,“下”はその見出しが表わすセクションとの接点です。したがって,上マージンは大きめに,下マージンは小さめにするほうが望ましいでしょう(図6-7)。

図6-7 見出しと本文を上下マージンで差別化
/* standard2.css */
/* 上下マージンを追加 */
@import url(standard.css);
H2{margin: 2.5em 0em}  /* 上下マージン2.5em */
H3{margin: 3em 0em 2em 0em}  /* 上,右,下,左 */
H4{margin: 2.5em 0em 0em 1em}  
H5{margin: 2em 0em 0em 1.3em}
H6{margin: 2em 0em 0em 1.5em}
【図6-7】――

6.4.3. ボーダーライン

見出し上下にボーダーラインを引けば,もっと直接的にセクションの区切りを表現できます。全てのレベルの見出しにボーダーがあってはくどすぎますが,ボーダー付きの見出しを適度に混ぜることは効果的です。

図6-8 話の転換をアピールするボーダー
H2{
    border-width: 1em 0em thin 0em;  /*上,右,下,左*/
    border-style: solid none;  /*上下,左右*/
    padding: 2em 0em 0.5em 2em;
}
【図6-8】――

ボーダー指定と左右マージン・パディングやtext-alignプロパティを適切に組み合わせると,見栄えの「感じ」はかなり変わります。見出しレベルの違いを考慮しながら,いくらか調整してみるとよいでしょう(図6-9)。

図6-9 少々凝ったボーダー例
【図6-9】――
/* 「図6-9 少々凝ったボーダー例」のスタイルシート */
/* fancy.css */
@import url(standard2.css);
BODY{
    background: #ffe; /* 淡い黄色〜クリーム色 */
}
H1{
    margin: 1em 0em 2em 20%;  /* standard.cssより左マージンを減らした */
}
H2{
    text-align: left;  /* standard.cssでcenterにしたのを戻した */
    font-weight: 900;  /* 装飾に負けないように,太く */
    border-width: thick 0em 0em 1.5em;  /* 上と左に太さの違うボーダーを */
    border-style: solid none none solid;
    border-color:#390;
    padding: 0.5em 0.5em 0em 0.5em;
    /* 次のように手っ取り早く指定しないのは何故でしょう?
        border-top: thick solid #390;
        border-left: 1.5em solid #390;
    実は,これらのプロパティをNetscape Navigator4.0がサポートしていないのです。 */
}
H3{
    margin: 2.5em 1em 1.5em 0.5em;  /* 右に隙間…ボーダーが左に寄る */
    border-width: thin 0em 0em 0em;  /* 上だけに細いボーダーを */
    border-style: solid none none none;
    padding: 0.5em 0em 0em 0.5em;
}

6.4.4. 通し番号を装飾(spanning)

1) <SPAN CLASS="NUMBER">〜</SPAN>マークアップ

見出しを更に装飾するために,通し番号(1.1.や1.3.2.)と見出し語句そのものを別のものとして扱ってみましょう。

そのためには,スタイル指定に先立って,HTML文書中にマークアップで「通し番号」要素と「見出し語句」要素を明示する必要があります。これらはHTML本来の要素としては用意されていないため,SPAN要素とCLASS属性を用いてマークアップします。

<H1>
<SPAN CLASS="NUMBER">1.</SPAN>
<SPAN CLASS="MAIN">ももたろうを考える</SPAN>
</H1>
    <HR>
    <H2>
    <SPAN CLASS="NUMBER">1.1.</SPAN>
    <SPAN CLASS="MAIN">出発まで</SPAN>
    </H2>
    <HR>
        <H3>
        <SPAN CLASS="NUMBER">1.1.1.</SPAN>
        <SPAN CLASS="MAIN">はじまりはじまり</SPAN>
        </H3>

2) インラインのまま装飾

単純にSPAN.NUMBERのサイズと色を変えただけでも,見栄えにメリハリが生まれます(図6-10)。

図6-10 通し番号をインラインのまま装飾
/* fancy2.css */
@import url(fancy.css);
SPAN.NUMBER{
    font-size: 1.5em;
    color: #33f;
    font-style: italic;
}
【図6-10】――

3) ブロック化して装飾

SPANは本来インライン表示される要素です。インライン表示である限り,「前後の語句に連続するように表示される」というレイアウトに関する制限から逃れることはできません。

各要素の表示形態はdisplayプロパティによって変更できるのですから,ここでは表示をブロック化し,もうすこし複雑なレイアウトを目指してみましょう。ただし,displayプロパティは,むやみやたらに変更するべきではありません。もし変更する場合は,結果を十分考慮した上で指定してください。

コラム:設計が先,記述が後

スタイルシートを記述するときには,あらかじめ目標イメージを明示し,それを眺めながら必要なプロパティを選び出し,定規などで測りながら値を決定してください。目標を持たずになんとなくプロパティを書き,なんとなく値を記述したところで,好ましい表示結果は得られません。

「分析→設計→実装」とはプログラムを書く際の手順ですが,スタイルシートでも同様です。まず,目標の決定。次に,値の決定。最後に,シートの記述。ただし,「値の決定」には試行錯誤が必要です。

H1のための指定例

通し番号のサイズを大き目にし左端に配置し,語句は右側に配置してみましょう(図6-11,6-12)。

図6-11 H1の指定の目標
【図6-11】――
図6-12 H1ための分析・設計
【図6-12】――
/* book-h1.css */
@import url(atomic.css);
H1{
    font-size: 1.5em;  /* SPAN.NUMBERの大きさを考えて調整 */
    margin: 1em 0em 1.5em 0em;  /* 上,右,下,左 */
    padding: 1em;
    background: #ffe;
    border-width: 0.5em 0em;  /* 上下,左右 */
    border-style: solid none;
    border-color: #aaf;
    line-height: 1;
}
H1 SPAN{
    display: block;
}
H1 SPAN.NUMBER{
    font-size:3em;
    font-weight:900;
    padding-right: 1em;
    width: 1em;  /* H1の番号は最大でも2文字だと想定し,
                 数字もピリオドも横方向に小さいため,
                 半分の1em程度で十分だろうと考えた */
    float: left;
}
H1 SPAN.MAIN{
    text-align: right;
    padding-top: 1em;
}
H2のための指定例

語句より少し左上に数値を配置してみましょう(図6-13,6-14)。

図6-13 H2の指定の目標
【図6-13】――
図6-14 H2のための分析・設計
【図6-14】――
/* book-h2.css */
@import url(atomic.css);
H2{
    font-size: 1.5em;
    margin: 3em 1em 2em 1em;
    border-width: 0em 0em thin 0em;  /*上,右,下,左*/
    border-style: none none solid none;
}
H2 SPAN{
    display: block;
}
H2 SPAN.NUMBER{
    font-size: 1.5em;
    color: #00f;
    margin: 0em auto 0em 1em; /*右マージンを「残り」に指定*/
    width: 3em;  /* H2の番号は最大でも5文字だと想定し,
                 数字もピリオドも横方向に小さいため,
                 半分程度,すなわち3em程度で十分だろうと考えた*/
    border-width: thin 0em 0em 0.5em;  /*上,右,下,左*/
    border-style: solid none none solid;
    border-color: #aaf;
}
H2 SPAN.MAIN{
    text-align: center;
    margin: -0.5em 0em 0.5em 0em;
}

それでは,この二つをあわせたスタイルシートを作成しましょう。

/* book.css */
@import url(book-h1.css);
@import url(book-h2.css);
H3{
    font-size: 1.3em;
    margin: 2em 0em;  /* 上下マージン2em */
}
H4{
    font-size:1.2em;
    margin: 1em 0em 0em 2em;  /* 上マージン1em,下マージン0,左マージン2em */
}
P{
    text-indent:1em;
    line-height: 1.5em;
    margin: 0.5em 0em;  /* 上下,左右 */
}

このbook.cssを使った文書の,Netscape Navigator4.0による表示結果を図6-15に示します。結果を見て分かるとおり,emユニットの処理がおかしいため「期待通り」とは行きませんが,ほぼ願いはかなえられていると言ってよいでしょう。

図6-15 Netscape Navigator4.0でのbook.css
【図6-15】――

一方,book.cssによる文書のInternet Explorer4.0による表示結果を図6-16に示します。テキストに対するフロート指定・width指定などがサポートされていないため望みどおりの結果とはいえませんが,それでも文書構成を伝えることに関してはなんら遜色の無い結果だと言えるでしょう。

図6-16 Internet Explorer4.0でのbook.css
【図6-16】――

6.4.5. 非対応WWWブラウザへの配慮

これまではスタイルシートを用いて文書スタイルを調整することばかり考えてきました。ところで,スタイルシートをオフにして文書を表示してみると,どんな感じになるでしょうか。本書が示した記述方法(HTML文書とスタイルシートの両方)を守っている限り,シート無しでも文書内容の伝達には何の支障もありません。しかし,「見栄え」という意味では,そこはかとなく寂しい表示になるのは仕方ありません。

ところで,この節の例では,見出しをアピールするためにボーダーラインを付加しました。立ち返ってみれば,そのような「区切り線」は,HTMLのHR要素でも表現できます。スタイルシートを適切に用いればHR要素は必要ないのですが,それでもしかし,非対応WWWブラウザのためにHR要素を付け足してみてはいかがでしょうか。

適切にHR要素がマークアップされていれば,スタイルシートをオフにしてもある程度の見やすさ・読みやすさを確保できます。筆者は,仕切り線を想定した部分にはHR要素を記述することをお勧めします(図6-17)。そして,スタイルシート対応WWWブラウザに余分な表示をさせないために,スタイルシート中に

HR { display: none}

と加えておきましょう。

図6-17 スタイルシートオフ時のみHR要素を表示
【図6-17】――
コラム:Transitionalに存在する属性を利用する

スタイルシート非対応WWWブラウザを使っている人のために,HTML4.0-Strictでは破棄されたものの,Transitionalでは残されている幾つかのスタイル規定のための属性を用いるのは悪いことではありません。たとえば,H1〜H6要素やP要素のALIGN属性をtext-alignプロパティの代替にすることは悪いことではありません。

ただし,Transitionalの属性を使う際には,次の2点を守ってください。

すなわち,「BODY要素で色指定をしたから,スタイルシートでは色を指定しなくても良い」「HTMLが用意している属性で指定できない部分だけスタイルシートを使えば良い」などとは考えないでください。そのように考えてしまっては,本末転倒です。Transitionalの意味は,「スタイルシートが普及するまでの過渡的手段」なのですから。

6.5. 「一般性」と「特殊性」のバランス

6.5.1. "DIV.MAIN" = "P + UL + BLOCKQUOTE"

ここでは,特定の文脈を対象にしたスタイル指定を調整する際に必要なテクニックをお伝えします。例として,本文が段落(P要素)・リスト(UL要素,OL要素)・引用ブロック(BLOCKQUOTE要素)によって構成されているケースを用います。

この3者の左マージンを,PとULは見出しに対して3文字分,BLOCKQUOTEはPやULよりさらに2文字分設定するにはどうすればいいでしょうか(図6-18)。

図6-18 複数の要素からなる本文の左マージン目標図
<BODY>
<H1>私のPC</H1>
<P>私のPCの宣伝文句は,かの長島茂雄さんがにこやかに語っていました。</P>
<BLOCKQUOTE>
    <P>「サポート体制で選べば,フローラ。」</P>
</BLOCKQUOTE>
<P>そう,日立のフローラです。</P>
<P>1994年に購入したため,いまやローエンドなスペックです。</P>
<UL>
    <LI>Pentium75MHz
    <LI>RAM48MB(標準は16MB)
    <LI>ハードディスク512MB
</UL>
</BODY>
【図6-18】――

単純に考えれば,各要素に必要なマージンを直接設定すれば実現できます。

P, UL{ margin-left: 3em}
BLOCKQUOTE{ margin-left: 5em}

しかし,これでは「BLOCKQUOTEはPやULよりも2文字多い」という関係が理解しにくくなってしまいます。さらに,P・ULに対するマージンを変更したときには,関係を維持するためにBLOCKQUOTEのマージンも変更する必要があり,大変メンテナンス性が悪いといえます。

これは,文書構成が十分に示されていないために起こる混乱です。マージンは「親要素のマージンにどれだけ追加するか」という形で指定するため,構成が不明確だと指定に不整合が生じやすくなります。「段落・引用ブロック・リストが合わさって狭義の本文になっている」という構成をより明確にするために,DIVブロックを追加しましょう(図6-19)。

図6-19 本文の構造ツリー
<BODY>
<H1>私のPC</H1>
<DIV CLASS="MAIN">
    <P>私のPCの宣伝文句は,かの長島茂雄さん…</P>
    <BLOCKQUOTE>
        <P>「サポート体制で選べば,…」</P>
    </BLOCKQUOTE>
    <P>そう,日立のフローラです。</P>
    <P>1994年に購入したため,いまや…</P>
    <UL>
        <LI>Pentium75MHz
        <LI>RAM48MB(標準は16MB)
        <LI>ハードディスク512MB
    </UL>
</DIV>
</BODY>
【図6-19】――

構成に沿って考えると,「見出しに対し3文字分の左マージン」を指定するべき対象はDIV.MAINなのだと思い当たります。PやULはそのマージンを修正せずに用いていますが,BLOCKQUOTEはさらに2文字多いマージンが欲しかったのです。

DIV.MAIN { margin-left: 3em}
DIV.MAIN BLOCKQUOTE{ margin-left: 2em}  /* DIV.MAINよりも2em多い */
/* 仮にDIV.MAINの左マージンを変更したとしても,BLOCKQUOTEとの位置関係は不動 */

このように,構成を明確にすればするほどスタイルシートの内容も明確になり,メンテナンス性も向上します。

6.5.2. 「特定の文書への対応」と「一般性確保」のジレンマ

6.4.1.では「狭義の本文」を「PとBLOCKQUOTEとUL」としましたが,場合によってはPREが入るかもしれませんし,別のDIVが入り込むかもしれません。逆に,BLOCKQUOTEの無い文書もあるでしょう。すなわち,HTML文書の構成は文書型定義で一般的に定義されていますが,その定義は大変に大まかなもので,実際の文書インスタンスの構成は全く特定できないのです。

すると,図6-18のスタイルシートは,この文書にはぴったり適用できまずが,他の文書でもうまく機能するとは限りません。そもそも,わざわざDIV.MAINをマークアップしたHTML文書でなければ図6-18のスタイルシートは活用できないのです。

「ある特定の文書に最適のシート」を追い求めることと「一般性のあるシート」を追い求めることは,基本的に両立できません。

6.5.3. ジレンマと上手に付き合う方法

両立できないものを無理に両立させようと努力するよりも,これらを分けて構築するほうが得策です。以降では,「どのように分けるべきか」について考えていきます。

1) 「一般」と「特殊」を分離する

ところで,「一般性のあるシート」――多くのHTML文書に適用できるシート――とはどのようなものでしょう。端的には,基本的な要素だけへの宣言で構築した(クラス・DIV・SPANに頼らない)シートだと考えられます。本章で紹介したstandard.cssやfancy.cssはこれに当たります。

クラス・DIV・SPANを活用したシートを作る場合は,fancy2.cssのように「一般性のあるシートをimportして,特殊指定を追加する」ように書くのが賢いと思われます。なぜなら,想定した要素が無い場合は単にimportしたもとのシートとして機能するからです。

すなわち,うまくジレンマと付き合うには,「基本的な要素だけへの宣言」と「特殊なクラスや要素への宣言」を別シート(別ファイル)として構築しておくべきだと考えられます。そのようにして作られたシートを必要に応じて組み合わせていけば,常に一般的な効果を期待できます。

2) ごく特殊なものはSTYLE要素に押し込む

ところで,シートが使いまわせるかどうかは,「想定するクラス・DIV・SPANを利用した特殊な要素が,文脈上,親要素になるかどうか」である程度判断できます。

例えば,fancy2.cssやbook.cssのように「期待する特殊な要素が,文脈上,単なる子要素である」場合には,期待する要素が存在しない場合でも,ある程度整合性の取れた表示になります(図6-20)。なぜなら,「その要素が無いこと」の影響が一部にとどまるからです。したがって,このシートは「ある程度使いまわしが効く」と判断できます。

図6-20 book.cssをSPAN指定の無い文書に適用した場合
【図6-20】――

ところが,期待する特殊な要素が親要素となる場合(たとえば図6-19)は上手くいきません。なぜなら,「その要素が無いこと」の影響が別の要素にも波及するからです。

もし,図6-19のように「狭義の本文は,つねにDIV.MAINと指定する」というルールを(自分独自のルールとして)常に守るのであれば,このようなシートも使いまわしが効きます。しかし,そうでないかぎり,そのシートは一回限りしか利用されないでしょう。ということは,特定のHTML文書を対象にしたスタイルシートは,一つのファイルとして保存するのではなく,はじめからHTML文書にSTYLE要素として書き込んでおく(別のHTML文書から利用できないようにする)のが賢いとおもわれます。逆に,使いまわしの効くシートは必ず独立したファイルとして保存しましょう。

どちらにせよ,もっとも重要なのは「一般指定と特殊指定をひとつのシートに混在させないこと」だと言えます。“二兎を追うものは一兎も得ず”です。

6.6. 「一般性のあるシート」の例

standard.cssやfancy.cssはそのままでも十分実用性のあるスタイルシートですが,実は本書の印刷代金との兼ね合いで^^;,白黒でも内容がはっきり伝わるように考慮した結果,色や画像をあまり使っていません。WWWでは色や画像を気軽に使えるため,逆に,このままでは物足りなくなると思われます。

筆者は,atomic.cssに幾つかのボーダー・色指定・背景画を追加したものを自分用の標準スタイルシートとして利用しています。参考までに,それをここで公開します。

6.6.1.「ks.css」

1) 表示結果

図6-21 ks.cssの表示結果
<H1><IMG SRC="moon.gif" ALT="">ひとりごと</H1>
<HR>
<H2>1998年</H2>
<HR>

<H3><IMG SRC="music.gif" ALT="">3/2</H3>
<H4>/o)+&gt;は今でもAMERICAN HEROか?/</H4>
<P>o)+&gt;の出演したマペット・トゥナイトを見た。
音楽は「Starfish and Coffe」と「She gave her angel」の2曲と,
マペット達が歌う「デリリアス」「Let's Go Crazy」だった。</P>
【図6-21】――
図6-22 スタイルシートオフ時の表示結果
【図6-22】――

2) 用意した背景画像

スタイルシートはあくまで表示の調整の道具であり,画像の代替になるものではありません。過度な画像埋め込みは望ましくないものの,スタイルシートだけで全ての表現効果を得ようとするのも賢いことではありません。適切に画像を利用しましょう。

図6-23 背景画像
【図6-23】――

3) スタイルシート

@import url(standard2.css);
@import url(ie-back.css);
@import url(ks-back.css);
BODY{
    color: black;
    background: #ffe;
}
H2{
    margin: 2.5em 2em;  /* 上下,左右。左右マージンを追加。 */
    border-width: 0em 0.5em;
    border-style: none solid;
    border-color: #aaf;
    padding: 1em 2em; /* パディングを追加 */
}
H3{
    width: 100%;
    border-width: thin 0em 0em 0em;
    border-style: solid none none none;
    padding: 1em 0em;
}
BLOCKQUOTE{
    margin: 2em;
    border-width: 0.3em 0em ; /* 上下,左右 */
    border-style: dotted none;
    border-color: #f88;
    font-family:monospace;
    padding: 0.8em 1em;
}
/* ie-back.css */
P STRONG{
    color:black;
    background: #faa;
    font-weight: bolder;
}
A:link STRONG{background:#ccf;}
A:visited STRONG{background:#fcc;}
A:active STRONG{background:#f88;}
/* Netscape Navigator4.0はbackground系の処理が中途半端なため,
まったくサポートしていないものよりもマズイ結果を生み出すことがあります。
そこで,Netscape Navigator4.0が@importを解釈できないという不具合を逆に利用し,
別シートとして記述しました。
これならば,既にまっとうに機能するInternet Explorer4.0には支障ありませんし,
後にNetscape NavigatorがCSSを完全サポートしたときにも上手く機能します。
とはいえ,このテクニックは,あくまでも過渡的なものです。*/
LI{margin-bottom:0.5em;}
/* 同様に,これもNetscape Navigator4.0対策です。
同ソフトは,LI要素への指定を「マーカー」への指定であると勘違いし,
おかしな表示結果になります。 */
/* ks-back.css */
H2{background: url(../back2.jpg);}
H3{background: url(../back3.gif) right center repeat-y;}

6.6.2. 「prince.css」

1) 表示例

2) スタイルシート

/* prince.css */
@import url(atomic.css);
@import url(ie-back.css);
@import url(prince-back.css);
BODY{
    background:#646;
    color:#fed;
}
:link{color:#0af}
H1{
    font-size:3em;
}
H2{
    font-size:2em;
    border-width:0em 5em 0em 0.5em;
    border-style: none solid;
    border-color: #a08;
    padding: 2em 0.5em 1em 0.5em;
    margin: 2em 0em 0.5em 0em;
}
H3{
    font-size:1.8em;
    margin: 3em 0.2em 1em 0em;
    color: #99c;
    border-bottom-style: solid;
    border-bottom-width:medium;
    border-color: red;
    padding: 0em 0em 0.3em 0.5em;
}
H4{
    font-size:1.3em;
    margin: 1.5em 0em 0.5em 0.5em;
}
H5{
    font-size:1.1em;
    margin: 0.5em 0em 0.5em 0.5em;
}
.CAUTION{
    margin: 1em 1em 1em 20%;
    border-width: 0em 0.5em 0em 3.5em;
    border-style: none solid;
    border-color:#f22;
    padding: 2em 0.5em 0.5em 1em;;
}
BLOCKQUOTE{
    margin: 2em;
    font: italic 1em monospace;
    color: #bbb;
    border-width: 0em thick;
    border-style: solid;
    border-color: #a40;
    padding: 1em 0.5em;;
}
/*prince-back.css*/
P STRONG{
    color: #404;
    background: #a4a;
}
.SAD{
    color:red;
    background:transparent;
    font: 900 italic 1.2em monospace;
}

6.6.3. 「zappa.css」

1) 表示例

2) スタイルシート

/*zappa.css*/
@import url(ie-back.css);
BODY{
    color:#fed;
    background: #555;
}
:link{color:#0af}
H1{
    font-size:3em;
}
H2{
    font-size:2.4em;
    margin: 1em 2em;
    color: #d9d;
    text-align :center;
}
H3{
    font-size:1.6em;
    border-width: 0em 0em thick 0em;
    border-style: solid;
    border-color: #888;
    padding: 0em 0em 0.5em 0.5em;
    margin: 2.5em 0em 1em 0em;
}
H4{
    font-size: 1.3em;
}
H5{
    font-size: 1.1em;
}
BLOCKQUOTE{
    margin:1.5em 1em 1.5em 3em;
    border-width: 0em 0em 0em thick;
    border-style: none none none solid;
    border-color: #969;
    padding: 1em 1em 1em 2em;
}
H4{margin: 2.5em 0em 0em 1em}  
H5{margin: 2em 0em 0em 1.3em}
H6{margin: 2em 0em 0em 1.5em}

6.7. 終わりに

6章では,スタイルシートを記述するための発想法を紹介しました。本書の指針に従えば,HTML文書にもスタイルシートにも無理の無い形で両者を連携させられるようになります。

スタイルシートは,HTMLと比べて「はじめの一歩」を踏み出すまでに必要となる知識が多いためか,まだあまり利用されていないのが現状です。しかし,スタイルシートは実に魅力的な道具です。ぜひスタイルシートについて学び,活用してみてください。本書の内容が皆様の「はじめの一歩」の手助けになることを願います。

考え方のまとめ

技術面のまとめ(指定決定までの手順)