総評ですが,CSS2で追加された新たな側面は,全般に扱いの難しい,どちらかといえばプロフェッショナル向けのものばかりです。もっとも,CSS1が一般的なプロパティを網羅しており,CSS2はそれの上位互換として足りなかった部分を追加したのですから,その狙いが高度になっているのは当然でしょう。
CSS2で追加された印刷時の考慮,音声再生の考慮によって,HTML文書はWWWのみならず広範囲に有効な文書フォーマットになるでしょう。とはいえ,私見ですが,通常はCSS1相当のプロパティだけ覚えていれば十分だと思います。
CSS2の勧告は,1998年5月12日,『スタイルシートWebデザイン』(同8月10日に初版第1刷発行)の執筆途中に出されました。著者のすみ氏自身,DTP最中にCSS2が勧告に進化したために慌てて対応
した,と述べていらっしゃるとおり,本書におけるCSS2に関する解説には,CSS1に関するそれの充実ぶりと比べると,今日の目から見て熟しきっていない部分があるように思われます。
そこで,CSS2での追加プロパティを中心に解説しているこの第7章の編集に当たっては,他の章に比べてより突っ込んだ改変を行うことにしました。具体的には以下のとおりです。
スクロール可能なメディアで,文書が実際に表示されている部分を指す概念です。
ある要素から見て,その要素の祖先に当たる要素の中でもっとも近いブロック要素を指す概念です。マージンやパディングの計算で利用されます。
containing blockに対する訳語として,底本では「コンテナブロック」が採られていましたが,編者の判断で「包含ブロック」を採用しました。以下の本文では特に断りなく「包含ブロック」に改めています。
なお,編者による補足として,包含ブロックの例を以下に示しておきます。
<BLOCKQUOTE> <P>....<STRONG>....<Q>....</Q>....</STRONG>....</P> </BLOCKQUOTE>
上の例で,STRONG要素およびQ要素の包含ブロックはP要素です。また,P要素の包含ブロックはBLOCKQUOTE要素です。「要素Eの包含ブロック」という言い方は「要素Eを包含しているブロック」という意味なので注意してください(「要素Eに包含されたブロック」という意味ではありません)。
なお,厳密には,ここでいうブロック要素というのは,CSS2で言うブロック要素であり,HTMLにおけるブロック要素とは必ずしも一致しません。大まかには,後述するdisplayプロパティに変更を加えない限りは,HTMLのブロック要素はCSS2のそれと一致する,と考えてよいでしょう(上の説明は,HTMLのブロック要素がCSS2としてもブロック要素であることを前提にした説明ですのでご注意ください。また,以下の本文の記述も,基本的には同様の前提に立った上での記述であると思われます)。
あるブロック要素の内容がインライン要素とブロック要素の並列であるときに,そのインライン要素を便宜上,「匿名のブロック要素」として扱います。以下に具体例を示します。
HTML3.2および4.0Transitionalでは,ブロックを含みうる要素(DIV・BLOCKQUOTE・BODYなど)の子要素は「(%inline;|%block;)*」であり,図7-1のような記述も許されます。
<BODY> 事前に<A HREF="maegaki.html">前書き</A>を読んでください。 <H1>第1章:プリンスとの出会い</H1> それは,岡村靖幸との出会いから始まる。 <P>岡村靖幸は… </BODY>
この記述では,BODY要素はH1要素,P要素という二つのブロック要素と「事前に……読んでください。」「それは,……始まる。」という二つの文字列(インライン要素扱い)を直接の内容として含んでいます。この場合,正真正銘のブロック要素だけでなく,インラインの文字列の方も,実際にはブロックレベルのように(長方形の形に)整形されると考えられます。そこで,CSS2においては,処理を分かりやすくするために,このような言わばブロックもどきを,明示されていない即ち「匿名の」ブロック要素として扱うことになっています。
つまり,ある要素の内容がブロック要素とインライン要素との混ぜこぜであった場合には,その内容を強制的にブロック要素だけの状態にしてしまうのです。
ちなみに,図7-1のような記述は図7-2のようにしたほうが望ましいと言えます。
<BODY> <P>事前に<A HREF="maegaki.html">前書き</A>を読んでください。 <H1>第1章:プリンスとの出会い</H1> <P>それは,岡村靖幸との出会いから始まる。 <P>岡村靖幸は… </BODY>
図7-2では,BODY要素の内容はすべて初めからブロック要素なので,匿名ブロックはありません。
その要素の表示位置を決める際の基準となるものを決定するプロパティです。各キーワードの意味は表7-1のとおりです。
キーワード | 解説 |
---|---|
static | 通常の位置に表示する。この値が指定された場合,後述するtop,right,bottom,leftの各プロパティは適用されない。 |
relative | staticで表示されるべき位置(つまり通常の表示位置)を基準として,top,right,bottom,leftの各プロパティによるオフセットで表示位置を決定する。 |
absolute | 通常の表示位置とは無関係に,包含ブロックからの距離をtop,right,bottom,leftの各プロパティで指定されることによって,表示位置を決定する。 |
fixed | absoluteと同様の方法で位置を決定したあと,それを何かに固定する。連続メディア(スクロールメディア)の場合は,viewportに固定され,スクロールに流されずに常に表示されるようになる。ページメディアでは,ページに固定される。 |
仕様書では各指定に関する細かい事例を取り上げて解説していますが,本書ではそこまでは踏み込みません。
要素の表示位置を調整するために利用します。指定する値は,オフセット値すなわち移動量です。何に対するオフセット値であるのかは,positionプロパティの値で決定されます。
底本では,positionプロパティより先にオフセットプロパティが紹介されていましたが,順序を入れ替えました。
なお,オフセットプロパティの値の意味について補足しておきます。例えば,topプロパティの値は,当該要素の上辺を基準となる上辺からどの程度下に移動させるかを決定します。
表示が重なった場合の「背後に移動」「前面に移動」の順序付けを指定します。数値が小さいほど背後に表示されます。
国際化対処の一環で,記述の流れが「左→右(left to right: ltr)」であるか「右→左(right to left: rtl)」であるかを指定します。
CSS2仕様書11.1を端的にまとめると,次のような場合には,表示すべき内容が表示枠(画面,ページ,あるいは指定した表示枠)からはみ出してしまう可能性があります。
overviewプロパティは,はみ出してしまった部分の処理方法を指定するプロパティです(表7-2)。
キーワード | 解説 |
---|---|
visible | 枠をはみ出してでも表示する |
hidden | 見えない部分はそのまま隠す |
scroll | 枠は崩さずに,スクロールバーなどを用いることで見えるようにする。ただし印刷などの場合はvisibleと同じ |
visible以外の指定では,clipプロパティで表示すべき領域の形状を指定します。しかし,CSS2の段階ではまだ十分な検討が済んでいないようですので,ここでは省略します。
要素を表示するか否かを指定します。
「display: none」では要素を存在しないものと処理しますが,「visibility: hidden」では「要素は存在するが表示しない」ことになります。具体的には,「visibility: hidden」では,その要素を表示するために必要なだけの空白が表示されます。「visibility: collapse」は,表の列・列グループ・行・行グループに対してのみ有効な値で,該当部分の表示を隠した後に,その部分の余白が詰められます。
この指定を「:hover」疑似クラスなどと組み合わせると,ちょっとしたトリッキーな効果を得られます。ただし,やりすぎにはご注意を!
DIV.HIDE A{visibility: hidden} DIV.HIDE A:hover{visibility: visible} <DIV CLASS="HIDE"> <P>あなたを <A HREF="http://www.asahi-net.or.jp/~jy3k-sm/i_net/books.html">アヤシイ世界</A> に案内します。 </DIV>
:before疑似要素と:after疑似要素(4.1.9 (3)を参照)の具体的な内容を指定するプロパティです。任意の文字列,画像やサウンド(を指すURL),カウンタ,引用符,およびその組み合わせが指定可能です。なお,引用符とカウンタについては後述します。
@media aural{ H1:before{ content: url(chime.au); } } H1:before{ display: inline; content: url(good.gif); } STRONG:before,STRONG:after{content : "*"} BLOCKQUOTE:before{content:"(引用開始)"} BLOCKQUOTE:after{content:"(引用終了)"} Q:before{content: open-quote} Q:after{content: close-quote}
attr(X)は,HTML文書における属性値をcontentとして表示させるためのキーワードです。その要素が指定された属性を持っていない場合は,空の文字列が返されるため実際には何も表示されません。「A:before {content: "[" attr(REL) "]"}」であれば,図7-3のように表示されます。
<STYLE TYPE="text/css"> A:before {content: "[" attr(REL) "]"} </STYLE> <P>目次 <UL> <LI><A HREF="1.html" REL="NEXT">第1章:プリンスとの出会い</A> <LI><A HREF="2.html">第2章:情報を追い求めて</A> …… <LI><A HREF="appendex.html" REL="APPENDIX">索引</A> </UL>
目次 ・[NEXT]第1章:プリンスとの出会い ・[]第2章:情報を追い求めて …… ・[APPENDIX]索引
CSS1ではBR要素を表現するプロパティは用意されませんでした。このことは改題として残されていたのですが,ついにCSS2で実現できるようになりました。
BR:before { content: "\A"}
文字列の\はエスケープシーケンス用のメタキャラで,\Aは改行文字なのです!
……な,なんだかインチキ臭いんですが,ともかくこれで実現可能です。
contentプロパティの引用符指定に呼応する引用符を指定します。「<開く> <閉じる>」のセットでのみ指定できます。複数の引用符を指定すると,引用ネストの深さに応じた引用符を設定したことになります。
quotes: "{" "}" "[" "]" "(" ")"; /* {……[……(……)……]……} */
なお,5章で紹介した:lang疑似クラスを用いれば,言語の違いを考慮した指定が可能です。
Q:lang(en) { quotes: '"' '"' "'" "'" } /* English */ Q:lang(ja) { quotes: "「" "」" '“' '”' } /* Japanese */
余談ですが,必ずしも伝統的な引用符を用いる必要はありません。
BLOCKQUOTE{quotes: "(引用開始)" "(引用終了)" }
文書記述者は,「カウンタ名」を記述することでその名前のカウンタを利用できるようになります。プログラミングにおける変数宣言のようなものはなく,以降の例のように「カウンタ名」を利用し始めるだけで,自動的に対応するカウンタが作成されます。カウント制御はカウンタ名ごとに独立して行われます。なお,カウンタはいくつでも作成できます。
カウンタ値を表示するには,contentプロパティの値として「counter(<カウンタ名>)」を指定します。
H1:before{ content: counter(chapter-num) "章:"; }
ただし,これだけではカウンタの値が決定されません。「カウントアップ」と「値のリセット」には次のプロパティを用います。
このプロパティが指定されていると,その要素が現れるたびに,記述したカウンタが指定した値だけ増減します。カウントアップ値を省略した場合は,「1」が指定されます(つまり,その要素が現れるたびにカウンタは1ずつ増えることになります)。
このプロパティが指定されていると,その要素が現れるたびに,指定したカウンタの値が指定値にリセットされます。リセット値を省略した場合は,「0」にリセットされます。
「chapter-num」と「section-num」の二つのカウンタを利用してみましょう(CSS2仕様書12.5を改定)。
H1:before { display: inline; counter-increment: chapter-num; /* カウンタ「chapter-num」に1を加算 */ content: counter(chapter-num) "章:"; counter-reset: section-num; /* カウンタ「section-num」を0にリセット */ } H2:before { display: inline; counter-increment: section-num; /* カウンタ「section-num」に1を加算 */ content: counter(chapter-num) "." counter(section-num) ":"; } <H1>はじめに</H1> <H2>Frank Zappaとは</H2> <H2>そのアルバムの数</H2> <H1>ZAPPAアルバム全紹介</H1> <H2>Freak Out!</H2> <H2>Absolutely Free</H2>
1章:はじめに 1.1:Frank Zappaとは 1.2:そのアルバムの数 2章:ZAPPAアルバム全紹介 2.1:Freak Out! 2.2:Absolutely Free
カウンタ値の表示,カウントアップ,リセットの仕組みが独立しているため,「カウントアップだけして表示しない」「表示だけしてカウントアップしない」という指定も自由自在です。必要に応じてお試しください。
カウンタを利用するのは,見出しやリストに通し番号を付与する時が大部分だと思われます。例では見出しのみを取り上げましたが,OL要素のカウントアップも上記の説明と同じようにして記述可能です。
ところで,リストのネスト時の処理はどうなるのでしょう。構造化プログラミングなどを経験していない人には分かりにくいところだとは思いますが,「リストにおけるカウンタのスコープは,リストのネスト状況に合わせてネストします」というのが答えです(次の例ソースは,CSS2仕様書12.5.1を改定したものです)。
OL {counter-reset: item} LI:before { content: counter(item) ". "; counter-increment: item } <P>好きな食べ物 <OL> <LI>麺 <OL> <LI>うどん <LI>スパゲッティ </OL> <LI>肉 <OL> <LI>鶏肉 <LI>牛豚合挽 </OL> </OL>
好きな食べ物 1. 麺 1. うどん 2. スパゲッティ 2. 肉 1. 鶏肉 2. 牛豚合挽
数値ではなく,lower-romanやkatakanaでカウントアップしたい場合は,contentプロパティの値として「counter(<カウンタ名<, <list-style-type>)」を指定します(カンマ区切りです)。
CSS2の段階では,ごく基本的な印刷制御プロパティが用意されただけで,数多くのネタが「今後の課題」になっています。以下のような指定はCSS2ではできません。
なお,ページメディアといっても印刷とは限らないのですが,一般には「印刷」だと受け止めても支障はないでしょう。
ページそのもののサイズなどを指定するために,セレクタ「@page」を導入します。「@page」にはサイズとマージンが存在しますが,ボーダーやパディングは今後の課題になっています。各プロパティのパーセント指定は,紙のサイズを指定するsizeプロパティからの相対記述になります。なお,emユニットは使えません。また,ページへの指定は継承の計算に組み入れません。
特に印刷時の左右ページを指定する場合には「@page:left」「@page:right」疑似クラスを使用します。更に,「最初のページ」として「@page:first」が用意されています。
@page { size: 8.5in 11in; margin: 2cm } @page:left { margin: 2cm 2cm 2cm 3cm } /* 上,右,下,左 */ @page:right { margin: 2cm 3cm 2cm 2cm }
紙面サイズを指定します。<絶対サイズ>以外は,すべて相対指定です(表7-3)。
キーワード | 解説 |
---|---|
portrait | 現在の紙サイズで,縦置き |
landscape | 現在の紙サイズで,横置き |
auto | 現在の設定のまま |
紙サイズの指定によっては,文書内容がページに収まらない可能性があります。仕様書には,こういう場合にWWWブラウザが行うべき処理までが書かれています。
それでも駄目であれば,はみ出した部分は印刷されないことになります。
更に余談ですが,紙サイズよりもページ設定サイズが極端に小さい場合は,WWWブラウザは自動的に「真ん中寄せ」などの処理をするだろう,とも書かれています。
組版で言うところの「トンボ」です(表7-4,図7-4)。なお,その形状,サイズなどはWWWブラウザに一任されています。
キーワード | 解説 |
---|---|
crop | 裁ち切り位置を指定するトンボ |
cross | 複数の紙を重ねる時の位置決めスポットを指定するトンボ |
その要素の「始め」「終わり」で改ページするかしないかを指定します(表7-5)。
キーワード | 解説 |
---|---|
auto | WWWブラウザに一任 |
always | 常に改ページする |
avoid | 改ページを避ける |
left | 1あるいは2ページ分改ページして,左ページへ |
right | 1あるいは2ページ分改ページして,右ページへ |
出版における慣例では,横書きでは「大見出しによる大扉」を必ず右ページ(縦書きでは必ず左ページ)に配置し,中見出しでは優先的に改ページします。
「page-break-inside: avoid」では,指定した要素の最中にページ区切りが来る場合に,無理にそのページに押し込むか,全体を次ページに送り込みます。しかし,どうしても上手く処理できないケースも存在しますのであしからず。
「orphans(孤児)」とは,組版用語で「前ページに残す行」のことです。また,「widows(やもめ)」とは,「次ページに送る行」です。各プロパティには,それぞれの泣き別れの「最小値」を指定します。
WWWブラウザは,page-break系プロパティの指示に従って改ページ処理をした後,この指定を参考にページ送りを調整します。すなわち,orphansやwidowsが指定値以下のブロックが存在する場合には,要素全体を次のページに送り込むなどの処理をします。
仕様書には更に細かい処理の指針が提示されているのですが,それらはWWWブラウザへの指示であるために,ここでは省略します。
図表などの表現のために,印刷途中でページの縦横を変更したり,サイズを変更したいことがあります。そのために,名前付き「@page」を用意し,文章中でページを切り替えられるようになっています。
名前付きページは「@page <ページ名>」(空白区切り)で記述します。各要素をどの@pageで印刷するのかは,pageプロパティで指定します。
@page{size: portrait} @page land{size: landscape} TABLE {page: land; page-break-before: right}
これは特にプロフェッショナル向けだと思われますので,詳細はCSS2仕様書に譲り,ここでは考え方を簡単にまとめるだけにとどめます。また,そもそも筆者の不明のため,詳しく解説できない部分も存在します。申し訳ありません。
CSS2では,記述者が念頭においているフォントの各種特徴をスタイルシート中に書き込むためのセクション「@font-face{}」を定義しました。この情報をもとに,WWWブラウザは「各種特徴が似たフォントを探す」「似たフォントを修正して作る」「フォントをダウンロードする」といった対処が可能になります。
@font-face { font-family: "Robson Celtic"; src: url(http://site/fonts/rob-celt) } H1 { font-family: "Robson Celtic", serif }
CSS2仕様書15.3.1の例を引用して,WWWブラウザの処理を紹介します。先のシートの場合,H1には「Robson Celtic」というフォントファミリーが指定されています。CSS2対応のWWWブラウザは,このフォントがシステムに存在しない場合,対応する@font-face記述を探します。この例では,発見した@font-faceにはソースファイルのURLしか記述されていないため,WWWブラウザはキャッシュからそのファイルを探すか,フォントのダウンロードを試みます。それらによるデータの入手に失敗したら,系統名であるserifに適するフォントをシステム内部から選択し,表示します。
@font-faceの内部に記述するのは,プロパティではなく記述子(descriptors)と呼ばれるものです。すなわち,記述子を用いて,フォントの性質を記述するのです。
@font-face{ font-family:"ゴジック"; font-weight: 100, 200, 300, 400, 500; src: local("中ゴジック"); } @font-face{ font-family:"ゴジック"; font-weight: 600, 700, 800, 900; src: local("極太ゴジック"); }
想定するフォントファイルのソースを指定します。具体的な記述方法は以下のとおりです。
記述したURLのフォントデータのフォーマット(形式)を指定します。想定されているフォーマット名は表7-6のとおりです。
キーワード | 説明 | 拡張子 |
---|---|---|
"truedoc-pfr" | TrueDoc™ Portable Font Resource | .pfr |
"embedded-opentype" | Embedded OpenType | .eot |
"type-1" | PostScript™ Type 1 | .pfb, .pfa |
"truetype" | TrueType | .ttf |
"opentype" | OpenType, including TrueType Open | .ttf |
"truetype-gx" | TrueType with GX extensions | |
"speedo" | Speedo | |
"intellifont" | Intellifont |
ローカルフォントをフルネームで書いたもの,と説明されています。
src: url(http://foo/bar) src: local("BT Century 751 No. 2 Semi Bold Italic") src: url(../fonts/bar) format("truedoc-pfr") src: url(http://cgi-bin/bar?stuff) format("opentype", "intellifont")
仕様書では独立した区分になっていますが,次の記述子もいっしょに紹介します。
フォント名 | 値 |
---|---|
Intellifont | 250 |
Type 1 | 1000 |
TrueType,TrueType GX,OpenType | 2048 |
他にも「baseline」「centerline」「mathline」「topline」という記述子があり,それぞれ名前が示すとおりの特徴を記述します。といっても,筆者不明のため,具体的にどんな値がどのような意味になるのかは不明です。
仕様書にあるTABLE関連の記述の多くはWWWブラウザの処理方法(WWWブラウザベンダ向け)ですので,これもある程度省略しながら話を進めます。
CSS2が想定するのは必ずしもHTML4.0文書とは限りませんが,TABLEモデルはHTML4.0を基本にしています。XMLなどで文書型定義を自作する方は,表7-8の位置づけを参考にしてスタイルシートを記述してください。
CSS2でのdisplayプロパティの値 | 対応するHTMLの要素 |
---|---|
table | TABLE |
inline-table | TABLE(display:inline) |
table-row | TR |
table-row-group | TBODY |
table-header-group | THEAD |
table-footer-group | TFOOT |
table-column | COL |
table-column-group | COLGROUP |
table-cell | TD, TH |
table-caption | CAPTION |
HTMLのTABLEモデルは,行(row)を基本にしています。そのため,スタイルの細かい調整は行(あるいはセル)単位で行います。列(COL要素,COLGROUP要素)に指定できるプロパティは,次のものに限定されています。
CAPTION(テーブルの見出し)の表示位置を決定します。
テーブルのレイアウト方法の指定で,autoであれば表示幅にあわせて動的に決定され,fixedであれば表示幅に関わらず一定サイズで決定されます。処理はfixedの方が速く,またWWWブラウザへの負担が少ないでしょう。しかし,読み手の自由度の面ではautoの方が優れています。
仕様書にはauto時の処理アルゴリズムの指針が書かれていますが,本書では省略します。
TABLEでは,「セルそのもののサイズ」よりも「セルの内容を表示するために必要なサイズ」が小さいことがほとんどです。そのような場合は,自動的にパディングを生成することでつじつまを合わせます。
table-cellにおけるvertical-alignは,セルに内容をレンダリングするときの垂直位置そろえの指定として機能します(図7-5)。値として,「baseline」「top」「bottom」「middle」のみが許されます。baselineは「最初の一行のフォントのbaseline」,残りはセルそのものの「上端」「中央」「下端」を意味します。
text-alignの節(5.5.1)で言及したように,「text-align: "."」などとすることで小数点そろえを指示できます。
TABLEのボーダー処理方法を決定します。それぞれの値に応じて,以下の各項で説明するように処理されます。
「border-collapse: separate」の場合,セルの一つ一つが独立したボーダーを持つものとして処理されます。すなわち,隣接するボーダーの間には,更なる隙間が存在することになります(図7-6)。
セルのボーダー同士の間隔を設定します。セルにボーダーが無い場合には,セルとセルの間隔になります(これとは別に,marginやpaddingも有効ですのでご注意ください)。
空セルのボーダーを表示するかしないかを指定します(図7-6を参照)。これも分離ボーダーモデルのみのプロパティです。
empty-cellsプロパティが適用されるのはTD要素やTH要素ですが,シートとしてはTABLE要素にempty-cellsプロパティを記述しても構いません。TABLE要素にはempty-cellsプロパティは適用されませんが,このプロパティは継承されるため,一括してTD要素やTH要素にempty-cellsプロパティを記述したのと同じ効果が得られます。
TABLE.HAVEEMPTY{empty-cells: hide} /* HAVEEMPTYクラスのTABLEは,空セルのボーダーは表示しない */
同じような効果は,LI要素ではなくUL要素にlist-style系プロパティを指定しても得られます。ちょっとした視点の違いですが,構造を整理するのに役立つ発想だと思われます。
「border-collapse: collapse」の場合,隣接するセルのボーダーは独立したものではなく,融合したものとして処理されます。正しくは,隣接するボーダーは同じ中心線をもって描かれ,後ろのセルのボーダーが前のセルのボーダーの上に描かれていきます。すなわち,隣接するボーダー同士は重なります(図7-7)。なお,border-spacingプロパティは無効になります。
ところで,「ボーダーなし」と指定されたセルと「ボーダーあり」と指定されたセルが隣接する場合,隣接部分のボーダーをどのように処理するべきでしょうか。separateモデルでは各々のボーダーは別の位置に描かれますので,どちらの指定も尊重できます。しかし,collapseモデルではボーダーを重ねがきするため,一方を尊重すれば他方の指定を守れないことになります。
この矛盾を処理するために,CSS2ではborder-styleプロパティのキーワードに「hidden」を導入しました。すなわち,「none」は「弱い“なし”」,「hidden」は「強い“無し”」なのです(表7-9,図7-8)。
指定 | 解説 |
---|---|
boorder-style: none | 隣接部分のborder-styleがnoneかhiddenの場合だけ非表示になります。 |
border-style: hidden | 隣接するセルのborder-styleに関わらず,隣接部分もろとも非表示になります。 |
TABLE{ border: solid medium; } TH{ border-style: solid hidden; border-width: medium; } TD{ border-style: none hidden; }
TABLE要素には四方にボーダーが指定されているが,TH,TDともに左右がhiddenであるため,左右のボーダーは消えている。TDの上下はnoneであるが,最初のTD(Johnの行)の上ボーダーはTHによって,最後のTD(Georgeの行)の下ボーダーはTABLEによって,それぞれ表示されている。
マウス(ポインティングデバイス)を用いるシステム専用のプロパティで,表示された要素の上にカーソル(マウスポインタ)をあわせた時に表示するべきカーソルの形状を指定します。
指定内容は,0個以上のURL(カーソルファイルを指すもの。その後には必ずカンマが必要)と,ひとつのキーワード(必須)です。複数のURLを指定した場合は,前から順に読み込みを試み,最初に成功したものを表示します。ひとつも読み込めなかった場合は,最後の「キーワード」に対応するシステムカーソルを表示します。
CSS2の仕様書は,カーソルファイルの形式を特定していません。CSS2仕様書の18.1の例では,URLに指定するカーソルの拡張子は「.cur」「.csr」でした。
P { cursor : url("mything.cur"), url("second.csr"), text; }
しかし,GIFファイルなどが利用されるのではないか,と筆者は考えています。あくまでも私見ですが。
CSS2が考える「アウトライン(縁取り)」は,ボタンなどのフォーム部品や画像(イメージマップ時は,各部分)の回りに表示される縁取り線です。「ボーダー(枠)」と異なり,アウトラインの形状は対象物の形状と同じ形をしています。すなわち,対象物が丸ければアウトラインも丸いのです(ボーダーの形状は,要素内容の表示に必要な“四角”に固定されています)。あくまで縁取り線ですので,ボーダーのような「上下左右」の概念はありません。
「アウトライン」が威力を発揮するのは,「:focus」などのダイナミック疑似要素との連携時でしょう。普段はアウトラインを表示せず,「マウスをかざした」「選択された」などのアクションに応じてアウトラインを表示するようにすれば,ユーザは「自分が何をしているのか」を明確に意識できます。このような指定は,特にイメージマップで有効でしょう。なお,この処理を考慮してか,アウトラインの表示/非表示はレイアウトに影響を及ぼさないとされています。
なお,ボーダーを描いている場合,アウトラインはボーダーの外側に描かれます。
アウトライン系のプロパティは,ほぼボーダー系のプロパティと同じです。ひとつだけ違うのが,色指定における「invert:反転」でしょう。これは特定の色を指定するキーワードではなく,対象の色を反転させた色を指定するキーワードです。
CSS2仕様書18.5に「Magnification」というものがありますが,ここには「CSS2対応を謳うWWWブラウザであれば,文書表示の拡大縮小機能をサポートして欲しい」とだけ書かれています。特に拡大縮小のためのプロパティを定義するものではありません。
文書の音声再生というと,一般には視覚障碍者むけの処理だと思われがちですが,実際には皆の役に立つものです。たとえば,劇の台本ににおける役者への指示がきとしてCSS2を用いれば,その内容をコンピュータによって客観的に確かめられます(もちろん,芸術性には欠けるでしょうが)。また,CSS2の音声再生の範疇には文字の読み上げだけではなくBGMや「章の開始御」なども含まれていますので,スタイルシート中に「スクリーン表示用」と「音声再生用」の両方を記述しておけば,それだけでマルチメディアプレゼンテーションが可能になります。他にも,いわいる「ながら」仕事のためには,コンピュータが文書を読み上げてくれると便利だと思いませんか?
@media aural{ P.heidi{ /* ハイジ */ voice-family: female; /* 女の子 */ pitch: high; /* やや甲高い */ pitch-range: 80; /* やや感情の入れすぎ */ azimuth: center-left; /* 左寄りの位置で再生 */ } P.peter{ /* ペーター */ voice-family: male; /* 男の子 */ pitch: medium; /* 標準的な口調 */ pitch-range: 50; /* 標準的な感情表現 */ azimuth: center-right; /* 右寄りの位置で再生 */ } P.goat{ /* ヤギ */ play-during: url(meeeee.au) mixed repeat; /* メエエエエ */ } }
フォントファミリーならぬボイスファミリーです。「系統名」には,「male(男性)」「female(女性)」「child(子供)」の3つだけが用意されています。
音量を0から100の範囲で指定します。ただし,0は必ずしも無音ではありません。無音はキーワード「silent」で指定します。なお,silent指定では,本来読み上げるのに必要だった時間だけ「休む」ことになります。読み飛ばすのであれば,「display:none」あるいは「speak:none」を指定します。
音楽業界の用語で,再生できる最小の音量と最大の音量の間のレンジ(幅)をダイナミックレンジといいます。volumeプロパティの0〜100は,基本的にはダイナミックレンジに対するパーセントだと解釈できます。
さて,CSS2の仕様書には,ダイナミックレンジの利用法に関して面白い記述がありますので,要約してみます。
読み上げ速度を,一分間に読み上げる単語数で指定します。コメントにあげた指定は,CSS2仕様書が提示する「目安」の値です。相対指定キーワード「faster」「slower」は,親要素の指定からの相対指定になります。
読み上げの平均的なピッチ(声の調子,音程)を指定します。<振動数>の単位には「Hz(ヘルツ)」および「kHz(キロヘルツ)」が用意されており,数値は正の実数です。なお,CSS2仕様書によれば,人間の喋り声の平均的なピッチは,男性で120Hz,女性で210Hzです。
用意されているキーワードは,その要素のボイスファミリーにおける標準的な「低い」〜「高い」を要求するためのキーワードです。
読み上げにおけるピッチの上下変動具合を指定します。いいかえると,読み上げの抑揚具合を指定します。あまりよいたとえではないかもしれませんが,0だと「棒読み」で,100だと「感情の入れすぎ」になります。
アクセント位置における音素の発音の強調具合を指定します。数値が大きいほど「大袈裟」になります(指定するのは具体的なHz幅ではなく,相対的な意味合いの0〜100の数値です)。
仕様書の表現では,「数値が大きいほど“carry”,小さいほど“soft”」となっています。筆者の不明により,よい訳語が見当たりません。このプロパティの値が大きいほど倍音成分が多い音色,すなわち俗に言う「太い音になる」と言えば通じるでしょうか。
その単語を読み上げる前後の「一時停止」時間を指定します。一括指定の場合,ひとつだけ指定すれば「前後一括」,ふたつ記述した場合は順に「前」「後」です。
なお,<時間>の単位は「s(秒)」と「ms(ミリ秒)」の二つだけが規定されています。
その要素を読み上げる前後に,音の装飾を挿入する場合に指定します。CSS2仕様書では「音のアイコン」と表現されています。なお,音ファイルの形式はWWWブラウザに一任されます。
キューの一括指定で,ひとつだけ書いた場合は前後両方を,二つ書いた場合は順に「前」「後」を指定したことになります。
要素を読み上げている間になっているサウンド(BGM)の制御のためのプロパティです。
基本的には,URLで指定されたファイルがその要素のBGMになります。キーワード「repeat」があれば繰り返し再生しますが,なければ一度しか再生しません。要素を読み上げ終わると,BGMも鳴り止みます。
HTML文書では,要素は入れ子になっています。そのため,必然的に「親要素の背景」は「子要素の背景」となり,その重ねあわせに関して注意が必要になります。背景画像や背景色の指定では「transparent(透明)」というキーワードがありましたが,ここでは「mix」「auto」「none」の3つのキーワードが用意されており,事情はなかなかに複雑です。
URLを指定した場合には,「mix」キーワードを添えるかどうかを決めなければなりません。親要素のBGMと子要素のBGMの両方を鳴らすのであれば「mix」を指定します。自分のBGMだけを鳴らして親要素のBGMをストップさせるのであれば,URLだけを記述します。後者の場合,その要素が終了したら,親要素のBGMは再開されます。
URLを指定しない場合,すなわちその要素に特にBGMを指定しない場合でも,「auto」か「none」を選択しなければなりません。親要素にBGMがあった場合にそれを受け入れるならば,「auto」を指定します。完全にBGMをなくしたい場合は「none」です。後者の場合でも,その要素が終了したら,親要素のBGMは再開されます。
以上を表7-10としてまとめます。
repeat | 繰り返し再生する |
---|---|
mix | 親要素のBGMを再生する |
auto | 親要素のBGMを引き継ぐ,親にBGMが無ければ「無し」 |
---|---|
none | 親要素にBGMがあっても,BGMを鳴らさない |
なお,指定が継承されないのは,「子要素のところで,もういちどBGMを始めから再生し直したりはしない」ためです(CSS2の汎用キーワード「inherit」で明示的に継承した場合は,どうなるのでしょう?)。
ステレオ/サラウンドサウンドでは,同じ音を左右のスピーカーから音量(やタイミング)を変えて再生させることで,その音が知覚される位置を調整できます。そのような調整を「PAN割り」といいます。azimuthプロパティは,左右のPAN割りを指定するプロパティです(ただし,CSS2仕様書では「PAN割り」という用語は使われていません)。
ラジオドラマなどでは,登場人物ごとに位置を変えることで人物の違いを把握しやすいように処理しています。スタイルシートでも同じような指定が可能です。なお,劇などの場合,舞台をイメージする意味で,人物の移動にあわせてPAN位置を変更するケースもあります。このような動的な表現はCSS2では不可能だと考えた方が良いでしょう(SPAN要素を複雑に用いれば,実現できなくも無いですが……)。
<角度>の単位は「deg(度)」「grad(グラッド)」「rad(ラジアン)」の3つだけが用意されています(表7-11)。本書の例ではdeg(度)を用います。
単位 | 読み方 | 範囲 |
---|---|---|
deg | 度 | 0度〜360度 |
grad | グラッド | 0 〜 100 〜 0 〜 -100 〜 0 (90度ごとに) |
rad | ラジアン | 0〜2π |
左右のPAN割りでは,全円を360度で表現します。Oを中心として,時計回りがプラスになります。360度=0度,180度がちょうど背面になります。なお,仕様としては「-360度〜360度」が記述できるため,「-180度〜180度」を用いるのが理解しやすいでしょう(-90度=270度です。また,プラス記号「+」は書いても書かなくても同じになります)。
用意されているキーワードには,絶対指定と相対指定があります。まず,絶対指定ですが,キーワード「left-side 〜 right-side」とオプションキーワード「behind」が存在します。behind無しでは前面(-90度〜90度)が表現でき,behindを付けると背面(90度〜180度,-180度〜-90度)が表現できます。数値による絶対指定とあわせて,図7-9に示します。
相対指定は,親要素の再生位置からの相対指定になります。時計回り方向(プラス)が「rightward」,その逆(マイナス)が「leftward」で,どちらも20度ずつの移動になります。なお,「値の限界を超えたらどうなるか」には言及されていませんが,回転しつづけると解釈して構わないでしょう。
定義としては,キーワード「behind」の単独指定も可能です。しかし,仕様書にはその場合の処理が記述されていません。可能性としては,相対指定であるとして「鏡あわせに移動」「180度移動」が考えられます。
しかし,仕様書中の指定例では,「P.comment { azimuth: behind } /* 180deg */」とあるので,ひょっとすると「center behind」として扱うのかもしれません。
個人的には,これも定義ミスで,本来は次のようになっているべきなのではないか,と考えられます。
上下のPAN割りでは,-90度〜90度を用います。キーワードの意味はコメントのとおりです。相対指定キーワード「higher」「lower」は,親要素の指定からの相対指定になります。
「display」プロパティの音声再生専用の拡張だと捉えてください(displayプロパティは,すべてのメディアを対象にしたプロパティです)。といっても,CSS2の段階では「普通に読むか,スペルで読むか」しか指定できません。
「スペルで読む」とは,英語圏の場合,spellという単語を「スペル」と読むのではなく,「s,p,e,l,l(エス,ピー,イー,エル,エル)」と読む,ということです。具体的には,「ODA」を「おだ」ではなく「オー,ディー,エイ」と読んで欲しいならば,「speak: spell-out」を指定します(日本語を「スペルで読む」場合はどのようになるのでしょう?)。
「speak: none」は読み飛ばすための指定です。ただし,ある要素に「speak: none」が指定されていても,その子孫要素までが常に読み飛ばされるとは限りません。すなわち,その子孫要素に「speak: normal」などが指定しなおされていれば,speakプロパティの値は上書きされ,その部分は読み上げられることになります。それに対して,ある要素に「display: none」が指定されている場合,その子孫要素はdisplayプロパティの値に関わらず常に無視されます。従って,確実に子孫要素もろとも読み飛ばしたい場合には「display:none」を用いることが,CSS2の仕様書では勧められています。
先の「ODA」を「<SPAN CLASS="RYAKUGO">ODA</SPAN」などと表現しても構いませんが,実は,HTML4.0の新しいインライン要素として,「略語」「頭字語」にそれぞれ相当する「ABBR要素」と「ACRONYM要素」が用意されています。こちらをもちいるのが本道でしょう。
ABBR, ACRONYM{speak: spell-out}
ところが,日本人にはこのふたつの要素の使い分けが良く分からないのです(ToT)
なお,HTML4.01仕様書9.2.1の例では,ABBR要素に適した単語として「WWW,HTTP,URI,Mass」があげられており,ACRONYM要素として「WAC,Rader」があげられています。
この使い分けは,実はどうやら英語圏の人たちにも曖昧であるようです。略語には一貫してABBR要素を使っておけばいいのではないかと思われます(以下のリソースを参照)。
記号「{}()[];:」などの読み方を指定します。通常は「none」,すなわち,読み上げません。「speak-punctuation: code」と指定すると,「カッコ開く」などと読み上げます。
数値の読み上げかたを指定します。たとえば,「123」の場合,「continuous」では「ひゃくにじゅういち」などと読み,「digits」では「いちにいさん」と読みます。
HTMLのTABLE要素で作成できる表の構成要素には,大きく分けて「データのセル(TD要素)」と「見出しのセル(TH要素)」があります。ところで,「あるセルの見出しを探す時に表を行方向に見るべきか,列方向に見るべきか」は,HTML3.2のマークアップでは判別できません。また,見出しは行列の両方に存在するかもしれません。あるいは,同じ方向に二つ以上の見出しがあるかもしれません。このような場合には,一方だけが意味を持つのでしょうか,双方が関連しているのでしょうか?(図7-10)。
図7-10を見ても分かるように,HTML3.2の不十分なTABLEマークアップであっても,WWWブラウザでコンピュータ画面に表示してしまえば,見出しの関係はなんとなく判断できるます。だからといって,そのままでは情報として十分ではありません。そこで,HTML4.0では「HEADERS属性」「SCOPE属性」「AXIS属性」を導入して,どの見出しがどのセルを対象にしているのかを記述できるようになりました。いいかえれば,見出しによってセルを分類できるようになったのです。詳しくはHTML4.0仕様書11章を参照願いたいのですが,以降の例を読んだだけでも,ある程度はご理解いただけると思います。
ところで,皆さんは表を見ることができない人に,表の内容を読み上げることによってその内容を伝えようとしたことがあるでしょうか。無いならば想像して欲しいのですが,各セルを左上から順に機械的に読み上げた時に,その内容がどれだけ伝わるでしょうか? おそらく伝わらないと思います。
表の内容を読み上げで表現するには,なんらかの工夫が必要になります。そのためにCSS2が取りいれた工夫は,「データのセルを読み上げる時に,その見出しを読み直す」というものです。
「speak-header: always」と指定すると,先に延べたように「データのセルを読み上げる時に,その見出しを読み直す」ことになります。図7-11に,読み上げイメージを書き留めます。
名前:John 楽器:Guitar & Chor
名前:Paul 楽器:Vocal & Base
名前:Ringo 楽器:Drums
名前:George 楽器:Guitar & Chor
図7-11のTABLEの記述例を提示します。
見出しが行あるいは列の一方にしかない場合は,TH要素のSCOPE属性によって,見出し構造の方向を表現できます。属性値のキーワードとしては,さしあたっては「ROW(行)」と「COL(列)」だけ覚えれば十分でしょう。
<TABLE SUMMARY="この表は,ビートルズのメンバー名と,一般的な担当楽器を示すものです。"> <CAPTION>ビートルズのメンバー表</CAPTION> <TR> <TH SCOPE="COL">名前</TH> <TH SCOPE="COL">楽器</TH> </TR> <TR> <TD>John</TD> <TD>Guitar & Chor</TD> </TR> <TR> <TD>Paul</TD> <TD>Vocal & Base</TD> </TR> <TR> <TD>Ringo</TD> <TD>Drums</TD> </TR> <TR> <TD>George</TD> <TD>Guitar & Chor</TD> </TR> </TABLE>
見出しが行列両方に存在したり,列だけでも「大見出し」と「小見出し」が存在する場合(図7-10を参照)には,HEADERS属性を用います。
このような場合は,TH要素にID属性をつけ,TD要素のHEADERS属性に,対応する見出しセルのID名を記述します。複数の見出しと関係する場合は,大見出しから順に空白で区切って書き上げます(厳密には,かならずしも「大見出しから順に」と決められているわけではありません。ただ,そのように活用したほうがより効果的です)。
<TABLE SUMMARY="この表は,ビートルズのメンバー名と,一般的な担当楽器を示すものです。"> <CAPTION>ビートルズのメンバー表</CAPTION> <TR> <TH ID="name" COLSPAN="2">名前</TH> <TH ID="inst" COLSPAN="2">楽器</TH> </TR> <TR> <TH ID="first">名</TH> <TH ID="family">姓</TH> <TH ID="main">主</TH> <TH ID="sub">副</TH> </TR> <TR> <TD HEADERS="name first">ジョン</TD> <TD HEADERS="name family">レノン</TD> <TD HEADERS="inst main">ギター</TD> <TD HEADERS="inst sub">コーラス</TD> </TR> <TR> <TD HEADERS="name first">ポール</TD> <TD HEADERS="name family">マッカートニー</TD> <TD HEADERS="inst main">ボーカル&ベース</TD> <TD HEADERS="inst sub"></TD> </TR> <TR> <TD HEADERS="name first">リンゴ</TD> <TD HEADERS="name family">スター</TD> <TD HEADERS="inst main">ドラム</TD> <TD HEADERS="inst sub">コーラス</TD> </TR> <TR> <TD HEADERS="name first">ジョージ</TD> <TD HEADERS="name family">ハリスン</TD> <TD HEADERS="inst main">ギター</TD> <TD HEADERS="inst sub">コーラス</TD> </TR> </TABLE>
HTML4.0の仕様において,「アクセス性の確保」を盛り込むことは重大な課題でした。「アクセス性の確保」とは,「マウスを使わなくても,キーボードショートカットだけでフォームやリンクを操作できる」「印刷結果(インタラクティブ性無し)でもリンクなどの意図が伝えられる」「音声再生でも文書を理解できる」といったようなことです。そのために,アンカー要素やフォーム部品には「ACCESSKEY属性」が用意されましたし,ほぼすべての要素にTITLE属性(IMG要素のALT属性と同等)が用意されました。先程紹介したHEADERS属性やSCOPE属性は必ずしも音声読み上げを可能にするための属性ではありませんが,これらによって(表の見出し構成を明確にすることで)音声再生でも表を理解可能になります。
しかし,「コンピュータ画面に表示すること」「マウスを用いること」などを前提にしてしまえば,このような属性を用いなくても記述者の意図はなんとなく伝わってしまうものです。そのせいか,暗黙のうちに「コンピュータ画面」「マウス」を前提にするきらいがあり,既存のHTML解説書はアクセス性に関する新しい属性の存在に言及せずに済ましてしまうケースがままあります。お手もとのHTML4.0に関する書籍の中に,ACCESSKEY属性やSCOPE属性の解説があるかどうかチェックしてみてください。たぶん,記述されていないと思います。本書のHTML解説部分でも省略しています。これは大変に遺憾なことです。
画像を多用される方,TABLEを多用される方,フォームを多用される方,フレームを多用される方は,ぜひ一度アクセス性の確保についてご考慮ください。その際には,W3Cの内部機関WAI(Web Accessibility Initiative)の文書を参考にすると良いでしょう。