2・3章では,HTML文書からスタイル情報を締め出すことで,単純かつ一般性のある文書になることを解説しました。今後の章では(ようやく^^;),スタイル情報をスタイルシートとして構築する手順を解説します。
4章では,スタイルシート記述の文法的な側面を解説します。ただし,文法の全てを知っていなければスタイルシートを書けないか,といえばそうでもありません。先に6章「road to mastering CSS」を読み,関連する文法だけを抜き読みしても構いません。
なお,CSS2で新しく採用された仕様には「CSS2」である旨を明示します。今のところ,WWWブラウザはCSS2をサポートしていないことにご注意ください。
CSS仕様のスタイルシートの記述は,大変に「定型的」です。すなわち,URLとフォントファミリーの指定を除き,あらかじめ規定されたキーワードを選択したり,数値を記入したりするだけでシートは完成します。
シートの一般様式は「要素名{プロパティ名:指定する値}」です。具体的なプロパティやその値に関しては5章で詳しく解説することにし,4章ではシートそのものを記述するための文法に関して解説します。
まず,スタイルシート記述に用いる文字に関する取り決めは次のとおりです。
専門用語として,「スタイル指定が適用される先」を「セレクタ(Selector)」とよび,「指定するスタイル内容」を「宣言(Declaration)」と呼びます。すると,シートの一般様式は
セレクタ{宣言}
になります。
端的には,セレクタはHTMLの要素そのものです。しかし,実際にはいくらかのバリエーションがあります。そのバリエーションを定めるのが「文法」です。まず,図4-1に正規の文法をいくらか簡略化したものを提示し,以降で各々のバリエーションについて解説していきます。
<セレクタ>(,<セレクタ>)… {<宣言>(;<宣言>)…} /* セレクタはカンマ(,)で区切ることで, 宣言はセミコロン(;)で区切ることで, グルーピングが可能。 */
<プロパティ値> : <値> (!important) | /* 空の宣言も許されている */ /* !importantキーワードは,カスケーディング処理で使われる */
同じセレクタに対する宣言をまとめて記述する際には,宣言をセミコロン(;)でつないでグループ化して用います。また,同じ宣言を複数のセレクタにまとめて記述するには,セレクタをカンマ(,)でつないでグループ化します。
なお,分けて記述してもまとめて記述しても,意味は変わりません。
P{font-weight: 500} /* 太さ500 */ P{text-align: left} CITE{color: red} STRONG{color: red} CITE{font-style: italic}
P{ font-weight: 500; text-align: left; } /* 最後の宣言にはセミコロンは不要ですが, 付けても不正ではありません。*/ CITE, STRONG{color: red} CITE{font-style: italic}
宣言内容が衝突した部分――同じ要素・同じプロパティに複数の指定がなされた場合――は,後になされた宣言のみが有効になります。
P{ text-align: center; color: black; } P{ text-align: left; /* 同じ要素・同じプロパティの宣言が既にある */ }
P{ color: black; } P{ text-align: left; /* もっとも後ろのものが採用される */ }
ただし,!importantキーワードが付けられていた場合,優先順位は変動します。
P{ text-align: center !important; color: black; } P{ text-align: left; /* 同じ要素・同じプロパティの宣言が既にある */ }
P{ color: black; } P{ text-align: center; /* !importantのうち,もっとも後ろのものが採用される */ }
!importantキーワードは,後述のカスケーディング処理でも用いられます。
CSS1では,要素全般への指定だけでなく,HTML文書中でのID属性やCLASS属性の値を特定したスタイル指定が可能です。IDはシャープ(#)で,クラス名はピリオド(.)で指定します(CSS2では「#が取り扱うのは,はHTMLのID属性ではなく,属性値がID機能を持つすべての属性である」と拡張されています。この拡張は,XMLを考慮に入れたものでしょう)。
<要素名>.<クラス名> {<宣言>} <要素名>#<ID> {<宣言>}
BLOCKQUOTE{ /* クラス名を問わずに適用されるスタイル */ font-style:italic; margin: 0.2em 2em; /* 上下マージン0.2em,左右マージン2em */ } BLOCKQUOTE.BEATLES{color: red} /* クラスBEATLESのみの追加スタイル */ BLOCKQUOTE.STONES{color: blue}
CSS2では,CLASS,ID属性に限らず,全ての属性をもちいて対象セレクタを限定できるようになります。
A[HREF]{font-style: italic} /* リンク先を指定したアンカー */ A[NAME]{font-weight: bolder} /* 内部名を指定したアンカー */
H1[ALIGN="CENTER"]{text-align:center;} A[HREF="index.html"]{color: red;} A[rel="NEXT"]{color: blue;}
P[class~=LOVE]{color:red} /* <P CLASS="LOVE"> や <P CLASS="LOVE PEACE SPECIAL"> の場合などで有効 */
BLOCKQUOTE[lang|=fr] { quotes: '≪ ' ' ≫' } /* LANG="fr" や LANG="fr-FR" の場合などに有効 */ BLOCKQUOTE[lang|=ja] { quotes: '「' '」'} /* LANG="ja" や LANG="ja-JP" の場合などに有効 */
CSS2では,一つの要素に複数のクラスが指定されていることを勘案し,クラス名へのアクセスを強化しました。
P.LOVE.PEACE{color:red} /* <P CLASS="LOVE"> では無効だが, <P CLASS="LOVE PEACE SPECIAL"> では有効 */
CSS1では,IDやクラス名だけを指定した宣言(要素名を省略した宣言)を行ったならば,すべての要素に関する指定を行ったことになります。
.<クラス名>{<宣言>} #<ID>{<宣言>}
/* BLOCKQUOTEでもPでも, CLASS="BEATLES" ならば色を変える */ .BEATLES{color: red} /* 要素は問わずに ID="CHAPTER2" に指定 */ #CHAPTER2{color: blue;}
CSS2では,要素名を「*」と書いた場合に,「すべての要素に対する宣言をした」と解釈することに変更されました。なお,上位互換のため,CSS1と同じ記述方法も可能です。
CSS2における「*」は過度に強力な仕組みで,4.2.で説明する「継承」の利点を無視した指定すら可能になります。使用する際には,本当に必要なのかどうかを十分検討してください。
/* 強制的に,すべての要素の色を指定 */ * {color: black; background: white}
普通のスタイル宣言は,指定した要素が文書中のどこに現れても全てに適用されます。すなわち,
STRONG{color: red;}
とさえ記述すれば,STRONG要素がH1中に現われようとP中に現われようと,文脈を問わずに赤色になります。
しかし,「見出しの中のSTRONG要素だけ色を変えたい」ケースもあるでしょう。例えば,H1要素も「color: red」と指定されているため,同じSTRONGでも「H1に含まれる場合だけ」青色にしたいというケースが考えられます(図4-2)。
CSS1では,「対象要素が特定の親要素に含まれた場合にのみ有効になるスタイル」を,「親要素」「子要素」の順に「スペース」で区切って並べたセレクタを用いて指定できます。これを文脈付きセレクタ(Contextual Selector)と呼びます。
親要素 子要素 (孫要素)…{<宣言>}
/* 単純宣言 */ BODY{ color: black; font-size: 10pt; } H1{ color: red; font-size: bolder; text-decoration: underline; } STRONG{ /* 全てのSTRONGに適用されるスタイル */ color: red; font-style: italic; } /* H1に含まれるSTRONGだけに対する“追加の”スタイル */ H1 STRONG{color: blue;}
<H1>私の<STRONG>趣味</STRONG>について</H1> <P>私の趣味は<STRONG>音楽</STRONG>です。</P>
CSS2では,文脈判断がCSS1よりも数段強力になりました。
これは,CSS1における文脈付きセレクタと全く同じものです。4.1.6.では明言しませんでしたが,子孫セレクタにおける「親子関係」は,直接の「子」には限定されません。例えば,「BLOCKQUOTE STRONG」とはBLOCKQUOTE要素に含まれる全てのSTRONG要素に対する指定であり,次のSTRONG要素にも適用されます。
<BLOCKQUOTE> <P>私の趣味は<STRONG>音楽</STRONG>です。</P> </BLOCKQUOTE>
もし,「BLOCKQUOTE STRONG」と「P STRONG」の両方にスタイルを宣言していれば,上記の文脈では両方が同時に有効になります。ただし,衝突する宣言に関しては,より内側の文脈――この場合は「P STRONG」――に対する宣言が優先されます。
BLOCKQUOTE STRONG{ color: black; font-weight: bold; } P STRONG{ color: red; }
{ font-weight: bold; color: red; }
子孫セレクタとは異なり,ある特定の要素が直接の親要素になった場合にだけ有効になる宣言を行いたい場合は,この「子セレクタ」を用います。
親要素 > 子要素 {<宣言>}
DIV.BEATLES > P {font-family: sans-serif;}
<P>もちろん,僕だってBEATLESは嫌いじゃない。<!-- ←ここには適用されない --> <DIV CLASS="BEATLES"> <P>好きなのは,初期のロックもの。ハード・デイズ・ナイトなどには感涙。 しかし,次にリストアップする曲は嫌い。<!-- ←ここには適用される --> <UL> <LI><P>イエスタデイ <!-- ←ここには適用されない --> <LI><P>ヘイ・デュード <!-- ←ここには適用されない --> <LI><P>ロング・アンド・ワインディング・ロード <!-- ←ここには適用されない --> </UL> <P>中期以降でも,やはりサージェント・ペパーズなどは好き。<!-- ←ここには適用される --> </DIV>
親子関係ではなく,文書中の連続関係に注目したのが「隣接セレクタ」です。たとえば,「H1要素直後のH2要素」などに指定したい場合に用います(一般に,見出しが上位の見出しに連続する時と地の文章に続く場合とで,マージンなどを変えるのはもっともです)。
直前要素 + 直後要素 {<宣言>}
H2{margin-top:1em;} H1 + H2{margin-top:0em;}
<H1>すみけんリソース!</H1> <H2>前書き</H2> <!-- ←ここはH1+H2 --> <P>うんぬんかんぬん <H2>目次</H2> <!-- ←ここはただのH2 --> <UL> <LI><P><A HREF="first>うんぬん</A> <LI><P><A HREF="second">かんぬん</A> </UL>
各種文脈の指定は,複数の種類を混ぜることが可能です。その場合でも,指定は単純に前から(あるいは後ろから)順に読み解くだけであり,特別な優先順位は存在しません。
BLOCKQUOTE DIV.BEATLES > P STRONG {color: red} /* (前から読み解くと……) 「『BLOCKQUOTE要素の内部にある,CLASS="BEATLES"を指定されたDIV要素』の, 直接の子要素であるP要素」 の内部にあるSTRONG要素に対して適用される。 */ /* (後ろから読み解くと……) STRONG要素に適用される。 ただし,そのSTRONG要素がP要素の内部にあることと, そのP要素がDIV要素の直下の子要素であることと, そのDIV要素がBLOCKQUOTE要素の内部のもので しかもクラス名として"BEATLES"が指定されていることが条件。*/
WWWにとって有用な情報が,必ずしもHTML文書インスタンスそのものから判断できるとは限りません。例えば,アンカーには「まだ表示したことの無いリンク」「既に表示したことのあるリンク」などの性質の違いがあり,その性質に応じてスタイルを変えることは合理的ですが,その違いはWWWブラウザの履歴情報によって始めて分かるものです。したがって,いくらHTML文書を眺めても判断できません。
このような場合に活用されるのが「疑似(pseudo)クラス」です。「疑似クラス」は,文書中には実在しない性質に着目してスタイルを宣言するための手段です。
CSS1では,上述した「アンカーに対する3つの疑似クラス」のみが用意されています。
疑似クラスへのスタイル宣言は,要素名と疑似クラス名をコロン(:)でつないで記述します。
A:link{color: bule} A:visited{color:lime} A:active{color:red; background: #e88;}
CSS2では,リンク疑似クラスを「:link」と「:visited」の二つに限定し,あらたに「ダイナミック疑似クラス」として「:active」「:hover」「:focus」の3つを導入しました。
疑似クラスを複数用いることによって,「リンク済みでアクティブ」「未リンクでアクティブ」を表現できます。
A:link:active{color:white; background: #555} A:visited:active{color:red; background: #955}
:focusは,HTML4.0で強化されたアクセスキー(キーボードショートカット)設定に対応するもので,フォームやリンクで活用されるでしょう。また,outlineプロパティと:focus疑似クラスを組み合わせることで,イメージマップのうちの選択中の部分に枠を付けるなどの表現も可能になります。
なお,リンク疑似要素はアンカー専用の疑似要素でしたが,ダイナミック疑似要素はすべての要素に適用されます。例えば,「マウスをかざした部分だけ色が変わる目次」などに応用が可能です。
UL.CONTENTS LI:hover{color:black; background:#f8f;}
CSS2で追加された疑似クラスで,言語属性を表現するものです。引用符記号など,言語に依存する表現を使い分けたい時に有用です。(文書の言語属性は,対象となる要素に直接LANG属性が指定されていなくても,親子関係などから判断可能です。この意味で,[lang|=fr]などとは適用範囲が異なります。)
:lang(fr) > Q { quotes: '≪ ' ' ≫' } :lang(ja) > Q { quotes: '「' '」'}
CSS2で追加された疑似クラスで,同列の子要素のうち,文書中の順序が一番始めである要素を表現するものです。
P > STRONG:first-child{ color: red}
<P>いいですか,僕が <STRONG>「オイッス」</STRONG><!-- ←ここには適用される --> といったら,みんなも「オイッス」と応えるのが礼儀です。 また,儀式として,僕は <STRONG>「声が小さい,もう一度!」</STRONG><!-- ←ここには適用されない --> と言い返すので,ここで皆さん笑ってください。
疑似要素も,疑似クラスと同様に,実際には文書中に存在しない要素を操作するものです。あえて性格を要約すれば,書こうと思えば文書中に記述できるが,規則性を持って自動処理することが望ましいもの」が疑似要素に設定されています。
疑似要素へのスタイル宣言も,疑似クラスと同じく,要素名と疑似クラス名をコロン(:)でつないで記述します。
CSS1では,「はじめの文字(:first-letter)」「はじめの一行(:first-line)」のふたつの疑似要素が用意されています。その名のとおり,「はじめの文字」「はじめの一行」だけを異なる見栄えで表示したい場合に利用します(図4-3)。
H1:first-letter{font:2em fantasy}
CSS2で追加された疑似要素で,各要素の前後に,自動的に文字などを挿入したい場合に用います。各疑似要素で表示したい内容は,専用のプロパティ「content」で指定します(7.2.1を参照)。
H1:before{content: "−章−"; font-size: 1.5em; display:block;} BLOCKQUOTE:before{content: open-quote} BLOCKQUOTE:after{content: close-quote} BODY:after{content:"以上,終了。"; margin-top: 5em;}
例えば,一般的な画面(screen)と異なり,文字端末(tty)では文字色・サイズを一定にして表現しなければなりません。このような場合,メディアごとに指定値を切り替える必要があります。CSS2では,メディアを指定してシートを記述するために,@mediaブロックを用意しました。
CSS1には@mediaに相当する仕組みはありませんが,シートの想定メディアはHTMLのLINK要素で指定すればよいため,特に困りません。互換性確保のこともあり,今のところは一つのシートは特定のメディアのみを想定して記述しておき,HTML文書からメディアを指定するほうが得策でしょう。なお,具体的なメディアの特徴およびLINK要素に関しては4.3.5.を参照してください。
@media screen{ H1{ font-size: 3em} H2{ font-size: 2em} } @media screen, tty{ H1{ text-align: right; margin-top: 2em; } H2{ text-align: center; margin-top: 1em; } }
スタイルシートは,基本的にはテキストファイルとして作成・保存されています。各々のシートどうしは独立した存在ですが,あるシートに別のシートを取り込むことも可能です。
CSSによるスタイルシートファイルの拡張子は「.css」としてください。これはコンテントタイプ(MIMEタイプ)指定“text/css”と絡んだ取り決めです。くわしくは,RFC2318を参照してください。
@importキーワードは,既存のスタイルシートファイルの取り込みを宣言します(注:C言語の#includeに似ています。)。WWWブラウザは,受け取ったスタイルシートファイルに@importが書かれていれば,そのシートも同時に読み込みます。
@import "スタイルシートを指すURL"; @import url(スタイルシートを指すURL);
@importで取り込んだ後に独自の宣言を書き込むことで,指定を追加・上書きできます。
@import url(http://www.w3.org/pub/WWW/def-style.css); @import url(my-style.css); STRONG{color: red} /* このシート独自の追加宣言 */
@importを複数指定することも可能ですが,シート独自の追加宣言よりも前に記述する必要があります。なお,@importで取り込んだシート間で宣言が衝突した場合は,単純にもっとも後ろに書かれた宣言のみが有効になります(4.1.4.を参照)。
HTML文書インスタンスは多くの要素の集合です。また,スタイルシートで調整できるプロパティも多岐にわたります。では,全ての要素に全てのプロパティについての指定を行わなければならないのでしょうか?
指定の軽量化と合理化のために,CSSは「継承」という仕組みを提唱しています。継承とは,HTML文書インスタンスの構成に沿って,親要素から子要素へスタイルを伝播させる仕組みです。
具体例を用いて説明しましょう(図4-4,4-5)。
<BODY> <H1>日記<STRONG>1997年11月24日</STRONG></H1> <P>TVで偶然に<STRONG>西行法師</STRONG>の短歌を聞いた。</P> <BLOCKQUOTE> <P>「ねがわくば,桜の元で,春死なん」</P> </BLOCKQUOTE> <P>本当はこの後に下の句が続くのだが,忘れてしまった。 しかし,これだけでも大変見事に「日本人の風情」を表現していると思う。</P> </BODY>
BODY{ color: black; font-size:10pt; } H1{ font-size:15pt; font-family: sans-serif; /* ゴシック系を期待 */ } BLOCKQUOTE{font-style: italic} STRONG{font-weight: bold}
この文脈におけるH1は,まずBODYの宣言を継承し
color: black; font-size: 10pt;
に設定されます。その後,自分への宣言を追加・上書きします。したがって,結果として
color: black; font-size: 15pt; font-family: sans-serif;
を採用します。
図4-5におけるH1に関するスタイル宣言は,「フォントサイズとファミリーの変更は必要だが,色に関してはこだわらない」という考えで記述されています。すると,色は「継承」によって親要素のものが自動的に適用されるのです。すなわち,シート記述者は,必要な要素に対して必要なプロパティのみを宣言するだけで良いのです。
「継承」のこの利点により,スタイルシートは簡潔でわかりやすいものになるでしょう。
次にSTRONG要素を見てみましょう。一口にSTRONG要素といっても,「H1に含まれているSTRONG(1)」と「Pに含まれているSTRONG(2)」とでは,それぞれ継承する親要素が異なるため,最終的に採用するスタイルが異なります。明示するならば次のようになります。
STRONG(1){ color: black; /* H1…BODY */ font-size: 15pt; /* H1 */ font-family: sans-serif; /* H1 */ font-weight: bold; } STRONG(2){ color: black; /* P…BODY */ font-size: 10pt; /* P…BODY */ font-weight: bold; }
各要素の親要素は固定ではなく,HTML文書の文脈によって変ります。この全てのケースを明示してスタイルを調整していくのは大変です。しかし,「継承」によってこれらは自動的に調整されるのです。これも「継承」の利点としてあげて良いでしょう。
H1{ color: black; font-size:15pt; font-family: sans-serif; } BLOCKQUOTE{ color: black; font-size:10pt; font-style: italic; } P{ color: black; font-size:10pt; } H1 STRONG{ color: black; font-size:15pt; font-family: sans-serif; font-weight: bold; } P STRONG{ color: black; font-size:10pt; font-weight: bold; } BLOCKQUOTE P{ color: black; font-size:10pt; font-style: italic; }
もし「継承」の仕組みが存在しなければ,必要となる全ての文脈に関してあらかじめスタイルを宣言するはめに陥ります。しかも,文書が異なれば必要な文脈は変わってしまうため,「特定のHTML文書にしか利用できない」スタイルシートが出来上がるでしょう。このように考えてみると,「継承」はシートの汎用性・再利用性の確保にも役立っています。
さらに,「全ての文脈について,全てのプロパティを宣言している」場合に,H1要素のフォントサイズを変更したくなったとしたら,関連して幾つの宣言を修正することになるでしょう? この例では「H1 STRONG」だけですが,文書が異なれば更に増える可能性があり,修正はだんだんと面倒なものになるでしょう。このように考えると,「継承」はメンテナンスしやすさ――メンテナンス性――の向上にも役立っています。
シート記述者は,「継承」という単純なルールが産み出すさまざまな利点を十分意識する必要があるでしょう。
継承はあくまでもHTML文書インスタンスの入れ子構造にしたがって行われるので,宣言記述の順番を入れ替えても継承処理には何の影響もありません。
P{ color: white; } BODY{ font-size: 12pt; color: red; }
この場合でも,P要素は先にBODY要素から指定を受け継ぎ(BODYは本文の最上位の親要素ですから,常にその指定は継承されます),その後P要素に直接指定された宣言を受け入れます。したがって,Pのcolorプロパティは上書きされてwhiteとなります。
しかし,「後に書かれた方が有効になる」ように注意して書いたほうがわかりやすいのでは無いでしょうか。
BODY{ font-size: 12pt; color: red; } P{ color: white; }
このように書かれていた方が,「PはBODYの子要素であり,BODYの指定を継承する。継承した上で,colorは上書きされる」という関係が理解しやすいと思われます。筆者は,文書型定義における親要素から順に宣言を記述することを奨励します。
継承は大変便利な仕組みですが,全てのプロパティが継承されるわけではありません。なぜなら,継承するべきでないプロパティも存在するからです。継承されるのか否かは,プロパティごとに仕様書で定められています。
例えば,背景画像の指定は継承されません。仮にBODYの背景画像がPに継承されたとすると,Pが現われるたびに背景が書き直され,図4-6に示すような結果になります。どちらかといえば,「背景画像の付け直し」よりも「既に表示されている背景の上に文字を表示する」方が,即ち,背景は継承されないほうが標準的だと考えられます。(CSSのbackground-colorプロパティの初期値はtransparent(透明)になっており,親要素の背景をそのまま表示することが想定されています。)
また,“直前のテキスト”との垂直位置関係(上付き下付き)も継承されません。例えば,図4-7のHTMLコードのSUPの上付き効果をSTRONGが継承してしまえば,結果は「上付きの上付き」すなわち「eの(2のx乗)乗」のように表示されてしまいます。
e<SUP>2<STRONG>x</STRONG></SUP>
CSSの仕様は,HTML文書に対して「WWWブラウザ標準のスタイルシート」「ユーザ(読者)が標準とするスタイルシート」「HTML文書作成者が指定するスタイルシート」の3つのスタイルシートが用意され,この3者の指定を融合させることを想定しています。この3種類のスタイルシートの宣言の融合法,指定が衝突したときの混乱解消法を“カスケーディング”と呼びます。
CSSが想定するカスケーディング処理の基本は,単純で明快です。
CSSでは,各スタイルシートの指定に優先順位をつけています。それを数学の大小記号であらわすと,「WWWブラウザ」<「ユーザ(読者)」<「HTML文書作成者」です。それぞれのスタイルシート間で衝突するプロパティ値が宣言されているときは,優先順位が高い方の指定だけを採用します。宣言が衝突しない場合は,単にそれを採用します。これが,カスケーディング処理の基本です。(全てのカスケーディング処理が終わった後,スタイルの継承が処理されます。それでも指定されていないプロパティがあれば,CSS仕様に定められる初期値が採用されます。)
この処理には以下の利点が挙げられます。
BODY{ line-height: 1em; color: black; }
BODY{ line-height: 1.3em; color: white; background: black; }
BODY{line-height: 1.5em}
BODY{ line-height: 1.5em; /* 作成者の値 */ color: white; /* ユーザ(読者)の値 */ background: black; /* ユーザ(読者)の値 */ } /* そのほかのものは,初期値が採用される */
ただし,スタイル宣言に「!important」キーワードをつけた宣言に関しては,優先順位が変ります。「HTML文書作成者」<「!important付きHTML作成者」<「!important付きユーザ(読者)」となります。(これはCSS2の仕様です。CSS1では,「HTML文書作成者」<「!important付きユーザ(読者)」<「!important付きHTML作成者」となっていました。)
BODY{line-height: 1em}
BODY{ line-height: 1.3em !important; color: black; }
BODY{ line-height: 1.5em; color: red; }
BODY{ line-height: 1.3em; color: red; }
ところで,セレクタの指定にクラスやIDなどが絡んでくると,カスケーディング処理は複雑になります。本書では,このケースに関しての解説は省略します。
これまでのところ,Netscape NavigatorやInternet Explorerの標準的な見栄えでは,行幅に余裕がありません。行幅はスタイルシートによって自在に変更できるのですが,いまだシートを使っていないHTML文書も数多く公開されています。文書作成者がシートを付けてくれるのを待つよりも,自分で「ユーザ(読者)標準スタイルシート」を用意してしまうほうが賢いでしょう。
筆者が使っている「ユーザ(読者)標準スタイルシート」は,次のように簡単なものです。これ以上ごちゃごちゃと指定してしまうと,HTML文書作成者のシートとの兼ね合いが上手く行かなくなってしまうからです。
/* default.css */ BODY{ font-size: 11pt !important; line-height: 1.5; }
なお,Netscape Navigator4.0には,ユーザ(読者)標準シートを設定する機能が無いようです。Internet Explorer4.0には,メニューの「表示→インターネットオプション」で開かれる設定ダイアログの「全般」のなかの「ユーザ補助」に設定項目があります。
スタイルシートとHTML文書の連携に関する取り決めは,CSSの仕様ではなくHTMLの仕様の範疇に入ります。HTML4.0の仕様には,CSSだけでなく,他の仕組みのスタイルシートを包括した「スタイルシートとの連携方法」が記載されています。(2.0,3.2の仕様のHTML文書でも,同様にLINK要素を用いてスタイルシートと連携させられると考えてもよいでしょう。)
HTML4.0は,スタイルシートの連携方式を3つ想定しています。機能的な違いは「いつ有効になるのか」だけです。
LINK要素を用いれば,独立したファイルとして保存されているスタイルシートをその文書と連携させることが可能です。ファイル名はHREF属性で指定します。シートとの連携方式は,REL(Forward Relationship)属性とTITLE属性をもちいて指定します。スタイルシートの種類はTYPE属性で(CSSであれば“text/css”と)指定します。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4,0//EN"> <HTML> <HEAD> <TITLE>HTML4.0(W3C Recommendation 18-Dec-1997)解説</TITLE> <LINK REL="STYLESHEET" TYPE="text/css" HREF="normal.css"> <LINK REL="STYLESHEET" TITLE="fancy" TYPE="text/css" HREF="fancy.css"> <LINK REL="ALTERNATE STYLESHEET" TITLE="compact" TYPE="text/css" HREF="small.css"> <LINK REL="ALTERNATE STYLESHEET" TITLE="compact" TYPE="text/css" HREF="mini.css"> </HEAD>
WWWブラウザは,読み込んだHTML文書にスタイルシートファイルが指定されている場合,そのシートも自動的に読み込みます。そして,連携方式を判断し,適切なシートだけを有効にした上で表示を調整します。
preferred(おすすめ)およびalternate(代替)のスタイルシートには,TITLE属性によってタイトル名が指定されています。ユーザは,その中の特定のタイトル名を指示することによって,有効になるスタイルシートを切り替えることが可能です。
特定のタイトル名が指定された場合,そのタイトル名でないpreferred(おすすめ)スタイルシートは無効になり,そのタイトル名のalternate(代替)スタイルシートは有効になります。なお,persistent(永続)スタイルシートは常に有効です。
<LINK REL="STYLESHEET" TYPE="text/css" HREF="normal.css"> <LINK REL="STYLESHEET" TITLE="fancy" TYPE="text/css" HREF="fancy.css"> <LINK REL="ALTERNATE STYLESHEET" TITLE="compact" TYPE="text/css" HREF="small.css"> <LINK REL="ALTERNATE STYLESHEET" TITLE="compact" TYPE="text/css" HREF="mini.css">
この例の場合,文書読み込み時にはpersistent(ここではnormal.css)とpreferred(ここではfancy.css)の2つのスタイルシートが有効になっています。ユーザの指示により「compact」が選択されれば,prefrredとalternateのうち「compact」のタイトル名を持つスタイルシート(ここではsmall.cssとmini.css)に加えてpersistentが有効になり,他のシートは無効になります。
なお,複数のスタイルシートに同じタイトル名を付けた場合,そのシート群は同時に有効/無効になります。
有効スタイルシートの切り替えをどのような方法で行うのかはWWWブラウザに一任されています。プルダウン・メニューの一覧から選ぶ,別ウィンドウに示されるリストから選ぶなどのバリエーションが考えられます(図4-8)。
どのような方法をとるにせよ,CSS対応を名乗るWWWブラウザは,少なくとも指定されているスタイルシートのタイトル名一覧(ファイル名ではない)をユーザに提示できなければいけません。それにもかかわらず,Netscape Navigator4.0,Internet Explorer4.0はスタイルシート選択機能をサポートしていません。
複数のスタイルシートが有効になっている場合には,シート間で宣言が衝突する可能性があります。衝突した場合には,単純にHEAD要素中での出現順位がもっとも後ろである宣言のみが有効になります(「4.1.4. 宣言が衝突した場合の処理」を参照)。
HTML文書の再生メディアは,必ずしもコンピュータのスクリーン(ページの継ぎ目はなく,表示しきれない部分はスクロールバーによって調整する)であるとは限りません。場合によっては音声出力(スピーチ・シンセサイザー)であったり印刷(ページの物理的な区切りに制約される)であったりしても何の不思議もありません。HTML4.0の仕様書には,表4-1に示すメディアの種類が紹介されています。
値 | 説明 |
---|---|
SCREEN | スクロール可能な(ページの区切り目の無い)コンピュータ画面 |
TTY | テレタイプや端末画面など,固定ピッチ文字によるコンピュータ画面 |
TV | 家庭用TVセットのモニタ |
PROJECTION | 投影機 |
HANDHELD | 小型情報機器(画面サイズや色に制限が多いもの) |
紙,あるいはページ区切りのあるコンピュータ画面 | |
BRAILLE | 点字 |
AURAL | 音声出力(スピーチ・シンセサイザー) |
ALL | 全て |
再生メディアが異なれば,望ましい再生スタイルも異なります。したがって,スタイルシートはメディア別に指定されているべきです。その指定は,HTML文書中に「このメディアの場合はこのシートを用いる」という形態で行います。これは,LINK要素にMEDIA属性を指定することで実現されます。(一つのスタイルシートに複数のメディアを指定する場合は,カンマ(,)で区切って並べます。)
<LINK REL="STYLESHEET" MEDIA="ALL" TYPE="text/css" HREF="normal.css"> <LINK REL="STYLESHEET" MEDIA="AURAL" TYPE="text/css" HREF="normal-vox.css"> <LINK REL="STYLESHEET" TITLE="fancy" MEDIA="SCREEN" TYPE="text/css" HREF="fancy.css"> <LINK REL="STYLESHEET" TITLE="compact" MEDIA="SCREEN, HANDHELD" TYPE="text/css" HREF="small.css"> <LINK REL="ALTERNATE STYLESHEET" TITLE="slow-vox" MEDIA="AURAL" TYPE="text/css" HREF="slow-vox.css">
もし,WWWブラウザが音声出力用に設定されていれば,AURALとALL以外のメディアのスタイルシートは常に無効になるでしょう。この場合はpersistent(永続)としてnormal.cssとnormal-vox.cssが,alternate(代替)として「slow-vox(slow-vox.css)」のみが採用されるでしょう。(Netscape Navigator4.0,Internet Explorer4.0はメディア選択機能をサポートしていません。)
HTML3.2からは,HTML文書内にスタイルシートを直接記述するためのSTYLE要素が用意されています。LINK要素と同様に,TYPE属性,MEDIA属性,TITLE属性を指定できます。
<HEAD> <TITLE>test</TITLE> <STYLE MEDIA="ALL" TYPE="text/css"> BODY{ color: white; background: black; } </STYLE> </HEAD>
HTML3.2以上の仕様を解釈しないWWWブラウザは,STYLE要素の中身を単なるテキストとして表示してしまうかもしれません。W3Cは,それを避けるために,STYLE要素の中身をHTML文書としてコメントアウトするよう提案しています。
<STYLE TYPE="text/css"> <!-- BODY{ font: 400 medium serif; /* 太さ400,サイズ普通,ひげ付き文字 */ text-align: left; } --> </STYLE>
なお,あくまでも「HTML文書としてコメントアウト」ですから, <!--〜--> です。 /*〜*/ だと,「CSSとしてコメントアウト」になり,宣言がすべて無効になります^^;
スタイルシートは一般に独立したファイルとするのですが,STYLE要素を用いればHTML文書内に直接書き込むことも可能です。このふたつはどのように使い分ければ良いのでしょう。
独立したファイルとして作成したスタイルシートは,LINK要素を介して複数のHTML文書から使用できます。しかし,STYLE要素に記述したスタイルシートは,そのHTML文書からしか活用できません。したがって,使いまわしの効くスタイルシートは独立ファイルとし,特定のHTML文書でしか使えないような特殊な指定をしたシートはSTYLE要素に記述するのが賢い使い分けだと考えられます。
HTML4.0からは,BODY要素に含まれる(SCRIPTとPARAMを除く)全ての要素にSTYLE属性があり,属性値としてスタイル宣言を記述できます。この方法は,例外的・局所的なスタイル宣言を追加するために利用できます。
<H3 STYLE="color : red; font-size: 1.5em">3.1.1.HTMLに関して</H3> <H4 STYLE="text-align: center">/HTMLとは/</H4> <P>HTML(hypertext markup langauge)とは,…</P>