CSS Nite Vol.7
Web制作現場の対立を解消する!
(X)HTML+CSSガイドライン作り
益子 貴寛 (サイバーガーデン)
April 20, 2006 (Apple Store Ginza)
イントロダクション
自己紹介 (1)
- 益子 貴寛 (Takahiro Mashiko)
-
サイバーガーデン代表。Webプロデューサー。
大学院在学中の1999年5月に「CYBER@GARDEN」を立ち上げる。一般企業に勤務後、2003年5月に独立。
カニの話
そして、一部の方々には
熱狂的な「カニ好き」として
知られています
...v(-_-)v...
この前、専門学校 社会人向け講座の
生徒さんたちと、
コース修了ということで
お花見に行ったのですが、
差し入れとして、
タラバ脚ゆで 3kgと
ズワイ脚ゆで 3kgを
提供しました。
そういえば昔、カバンのなかに
毛ガニを忍ばせてそっと取り出し、
周りの人を驚かせたりしたことが
あったような...
テーマ1:
では、「対決」を
お楽しみください
商人 vs. 職人 (1)
- 商人
- 経営者
- プロデューサー
- ディレクター
- コンサル/プランナー
- ライター
- 職人
- デザイナー
- コーダー
- プログラマー
- Flashデベロッパー
- マルチメディアクリエイター
商人 vs. 職人 (2)
- 商人
- 利益 (額、率)
- 効率/納期
- 外仕事 (対ヒト)
- 結果
- 目に見える価値
- 職人
- 作品
- 達成感/納得感
- 内仕事 (対マシン)
- プロセス
- 目に見えない価値
マネジメント vs. ギーク
- マネジメントは新技術に対する理解が足りない?
→ 別にHTMLでいいじゃないか。
- ギークは新技術に右往左往?
→ IE 7 Beta 2への対応はどうしよう。
- ギークの説得、マネジメントの納得。
- ギークも立場が上がるごとにマネジメントに近づいていく。
- マネジメント感覚とギーク感覚のバランシング (個人としても、会社全体としても)。
デザイン vs. マークアップ (1)
- よくある誤解
- 正しい (Strict/Semanticな) マークアップによってデザインが制約されるのでは?
- 回答
- 両者は技術的に無関係であり、共存・共栄できる。見栄えのするページかどうかは結局、「画像の作り込み」「色づかい」「間」などが本質ということに変わりはない。
デザイン vs. マークアップ (2)
- しかし
- クロスブラウザ目的やCSSの簡素化のために、マークアップが「妥協」するシチュエーションもありうる。
- 例
- dl要素にdt要素とdd要素を連続で含めるべきところを、1セットごとに定義するなど。本来の「あり方」でなくとも、構文的にエラーでなければよいのか? (テーブルレイアウトとも相通じるところが)
構文適合性 vs. 目的適合性
- 構文適合性 (validity)
- その要素/属性の書式が構文的に正しいか。
- 目的適合性 (relevance)
- その要素/属性の使い方が本来の意味/仕様で示されている方法に合っているか。
テーブルレイアウト vs. CSSレイアウト
- Webデザイン
- (画像の作り込み、色づかい、間など)
- 実現 (1) ↓
- テーブルレイアウト
(レガシーアプローチ)
- 実現 (2) ↓
- CSSレイアウト
(スタンダーズアプローチ)
どちらのアプローチでも「正しいマークアップ」が大切。
ワイヤーフレームから vs. テキストから
- 2つの(X)HTML+CSS制作ワークフロー
-
- ワイヤーフレームからページを起こすアプローチ
- テキストからページを起こすアプローチ
- ひとつの解
- 1. のほうがデザインワークからの連続性があり、テーブルレイアウトの作業プロセスとも似ているので取り入れやすい。
ビジュアル vs. テキスト
- ビジュアル (画像など) も正しくマークアップし、代替テキストを指定すれば、サーチャビリティ (検索性) はそれなりに確保できる。
- ユーザーのことを考えると、コピー&ペーストが容易なテキストのほうがベター。ただ、フォントは環境依存的なので (サイズや種類など)、扱いにくい面も。
- ビジュアルとテキストのバランスは、サイトの雰囲気などイメージ作り/ブランディングに影響する。何でもテキストにすればよいわけではない。
マシンリーダブル vs. ヒューマンリーダブル
- マシンリーダブル
- (X)HTML = 文書構造の役割
- ヒューマンリーダブル
- CSS = 視覚表現の役割
文書構造と視覚表現を明確に分離し、きちんとマシンリーダビリティを満たしたあとにヒューマンリーダビリティを満たすという発想が大切。環境対応性/耐用性の高いWebサイトに。
リッチブラウザ vs. プアブラウザ (1)
CSSレイアウトチェックの基本は...
- CSSサポートがよいFirefox/Safariでチェック
- CSSサポートがよくないIEでチェック
Win IE 7の正式版が公開されても、Win IE 6からの移行はスムーズには進まない (2~3年? Vista版は?)。Win IE 6向けのCSSハックはまだしばらくは必要とされる。
リッチブラウザ vs. プアブラウザ (2)
- Win
- IE 6, Firefox 1.5, Opera 8, Netscape 7, IE 7 Beta 2?
- Mac
- Safari 1.3, IE 5.x?
- Win IE 7 Beta 2は正式版の公開に備えて含めておくとよい。
- Mac IE 5.x (すでに開発/配布終了) を含めると、作業負担が増加。コスト/ベネフィットの観点から含めないところも (クライアントの要望によっては含める)。
フロントエンド vs. バックエンド
- Perl, PHP, ASP ...etc.
- インターフェイスの書き出しは(X)HTML+CSS
- DOM (JavaScript, Ajax), XSLT ...etc.
- (X)HTMLの文書ツリー構造をもとに処理対象を特定
- フロントエンドとバックエンドをどう整合的にするかガイドラインで決めておく。
- id/classづけとも関連。バッティングしないように注意。
Web vs. DTP
クライアントによっては、WebサイトをDTP的に (そのままでプリントアウトできるという前提で) 使いたいという要望も。
- まずクライアントに、WebサイトとDTPの目的/役割の違いを説明。
- プリント向けCSS (media="print") での対応を提案。
- 柔軟に対応。クライアントに横幅を700px、760px、980px、変動幅のどれで作るか了解をとっておく。ただし、DTP向けの700pxではデザインは制約される (3カラムは困難など) を説明しておく。
テーマ2:
ガイドラインを
作らNite
ガイドラインの必要性
- 誰が作っても一定の品質を確保できる
- 制作チーム、更新チーム、外注、クライアント間での「無駄」の発生が防げる。キーパーソンが抜けても比較的スムーズに穴埋めできる。新しいスタッフが一定の品質のサイト/ページをアウトプットできるようになるまでの期間を短くできる。
- 社内にノウハウが残る
- 現場のノウハウを体系化し蓄積できる。
ガイドラインの下準備
- ヒアリングの実施
- 現状把握/分析、スタッフのスキル確認/コミュニケーションのため。
- 講習会の実施
- スタッフのスキルアップのため。
- ボトムアップコミュニケーションの促進
- メーリングリストなどを活用し、どのような内容を盛り込むべきかスタッフから自由に意見を出してもらう。ガイドライン策定への参加意識も生まれる。
ガイドラインの基本設計
- 目的
- SEO効果、アクセシビリティ、ユーザビリティ、メンテナンス性、互換性などの確保が基本。
- 優先度
- 制作物によってはすべての項目に準拠するのが難しい場合、各項目に優先度を設定する (例: 優先度A、優先度B、優先度C)。
ガイドラインの構成案
- 制作・運用ガイドライン
- (X)HTMLガイドライン
- CSSガイドライン
- 用語・表記ガイドライン
ガイドラインの内容 (1)
- 制作・運用ガイドライン
-
- ユーザー環境
- サイト構造とディレクトリ/ファイル
- .htaccess/robots.txt/エラーページ
- プログラムとの整合性
- アクセシビリティ/ユーザビリティ
- SEO対策
- コンテンツ基本フォーマット
ガイドラインの内容 (2)
- (X)HTMLガイドライン
-
- 基本ルールと書式
- 各部位の定義ルール
- head要素内のルール
- body要素内のルール
- マークアップ例
- トラブルシューティング集
ガイドラインの内容 (3)
- CSSガイドライン
-
- 基本ルールと書式
- スタイルレイヤーの設計ルール
- セレクタのルール
- プロパティのルール
- ハックのルール
- スタイリング例
- トラブルシューティング集
ガイドラインの内容 (4)
- 用語・表記ガイドライン
-
- 漢字と仮名のルール一覧
- 間違いやすい表現一覧
- 差別/禁止用語一覧
- 機種依存文字一覧
- 括弧の使い方
- 記号の使い方
- 特定業態向けのルール
ガイドラインも「進化」が必要
- ガイドラインの表紙にバージョン番号 (Ver.1.01など) と最終改訂日を明記しておく。
- バージョンごとの変更履歴を控えておく。
- 以前のバージョンをいつでも参照できるようにしておく。
- ガイドラインに対する意見を常にオープンに受けつけ、速やかに反映する (ただし、あまり頻繁に変えすぎても現場に混乱が発生する。月1回など改訂頻度をあらかじめ決めておいてもよい)。
制作仕様書とガイドラインの連携
- コンテンツチャート/サイトマップ
- コンテンツリスト
- スケジュール表
- デザインイメージ
- ワイヤーフレーム
- ガイドライン (外部向けに加工したもの)
- 素材管理表
- 課題リスト
テーマ3:
(X)HTML+CSS
ガイドラインの中身
(X)HTML+CSSの書式の統一は?
- 基本は「箸の上げ下げ」まで
- スペース/タブ/改行位置、(X)HTMLでは要素の入れ子階層のインデントの仕方、CSSでは宣言ごとに改行するかどうかなど。
- なぜ?
- 自分の書式と違うと気になる → 直したくなる → 無駄な作業の発生。だったら、あらかじめ決めておいたほうがよい。
(X)HTMLの書式例
[例]
<div id="nav">Rtn
Tab<ul>Rtn
TabTab<li>...</li>Rtn
TabTab<li>...</li>Rtn
TabTab<li>...</li>Rtn
Tab</ul>Rtn
</div>Rtn
Rtn
<div id="wrapper">Rtn
CSSの書式例
[例]
body {Rtn
Tabmargin: 0;Rtn
Tabpadding: 0;Rtn
Tab}Rtn
Rtn
img {Rtn
Tabborder: 0;Rtn
Tab}Rtn
ワイヤーフレームの各部位の定義 (1)
- 基本はdiv要素+id
- 必ずしもdiv要素ではなく意味的な要素 (p、ulなど) に直接idづけしてもよいが (それが理想)、現場の混乱が予想される場合は「必ずdiv要素でラップし、idづけする」と決めておく。
- ワイヤーフレーム上にもidを書いておく
- デザインワークから制作への「業務の連続性」が生まれる。
- id名の統一
- 統一的に「header」「footer」「sidebar」などのid名を使う。
ワイヤーフレームの各部位の定義 (2)
div#globalnav
div#content
div#visual
div#main
ワイヤーフレームの各部位の定義 (3)
- 全体を囲むdiv要素は「
div#container」、マルチカラムのためのdiv要素は「div#wrapper」などと決めておく (ワイヤーフレームに書いておく必要はない)。
- カテゴリーごとにスタイルを変える場合、 「
body#shopping ...」「body#careers ...」といったかたちでbody要素につけたidを頼りにスタイルを設計 (id名はディレクトリ名と同じにしておく)。
見出し要素は難しい
見出し要素の理想的な使い方は次のとおり (ISO-HTMLに基づく)。
- h1要素から出現すること
- 途中の見出しレベルを飛ばさないこと
ただし、ページ構成によっては、ある見出しレベルを使うことが躊躇されたり、ページ間で統一的なマークアップルールを設けている場合、このような階層構造を逸脱しなければならない場合もありうる。
見出し要素の限界
- 理想的な階層構造であっても、それぞれの見出しが及ぶ範囲がわかりにくいという仕様設計上の欠点は乗り越えられない (XHTML 2.0ではh要素とsection要素の組み合わせ/入れ子というかたちで改善予定)。
- 私たち人間は、h1要素、h2要素、h3要素という順序をツリー構造として頭に思い描くことができるが、ソース上はどの見出しレベルも完全にフラットな関係。
h1要素は複数出現してよいか
- 1つのページでh1要素が複数出現しても仕様 (構文) 的には全く問題はない。
- 一方、h1要素の「ルート見出し」としての性格を重んじれば、1つのページには1つのh1要素だけ、という考えになる (私もどちらかというとこのタイプ。h1要素の範囲ごとに複数のページにわけたり、見出しレベルの割り当て方を変えるといった方法で、1ページ1ルート見出しというルールを守ったほうがよいと考えている)。
h1要素をロゴなどに使うのはどうか
- h1要素では各ページ固有の内容を定義すべき?
- とすれば、すべてのページに共通のロゴをh1要素で定義するのは間違いということに (トップページぐらいしか妥当しない)。
- では、h1要素でどの内容を定義すべき?
-
- トップページはロゴ、キャッチフレーズ (キービジュアルにキャッチフレーズを含めている場合はその画像) 、または固有のページタイトル。
- 他のページは固有のページタイトル。
外部CSSの構成例
- /* 制作者情報 */
- /* ブラウザ初期化スタイル */
- /* 汎用要素スタイル */
- /* 汎用クラススタイル */
- /* ワイヤーフレーム部位別スタイル */
- /* カテゴリー別スタイル */
制作者情報の例
[例]
/* ***********************************************************
*
* Since: 2005-12-03
* Modified: 2006-04-20
* Guideline: Ver.1.03
* Editor: Takahiro Mashiko
* Editor: Taro Yamada
* Editor: Hanako Saito
*
* ***********************************************************
*/
ブラウザ初期化スタイルの例
[例]
/* Browser-formatting Styles */
* {
...
}
th, td, form, fieldset {
...
}
Win IEなどは一部の要素 (th要素やtd要素など) について「*」によるスタイル指定が効かないので、別途カンマ区切りで指定しておく。
スタイルレイヤー設計 (1)
- ワンシートアプローチ
- 1つの外部CSSでスタイルを定義。最もシンプルな方法だが、ファイルが長くなりすぎる問題も。
- マルチシートアプローチ
- 複数の外部CSSでスタイルを定義。ベースとなるCSSとレイアウトのためのCSSを分けたり、カテゴリーごとにCSSを分けるなど。しかし、部分的な修正で済むのであれば、ワンシートアプローチでコメントで区切ったほうがよい場合も。
スタイルレイヤー設計 (2)
- 部位ごとのマルチシートアプローチ
- ワイヤーフレームの各部位 (header, content, sidebar, footerなど) ごとに外部CSSを用意。ファイル数が必然的に増えるので、管理が煩雑になる場合も。
案件によって設計を柔軟に変えるのがベスト。「一元管理の簡易さ」という基本に立ち戻れば、なるべくワンシートアプローチがよいだろう。
マルチデバイス対応
- PCスクリーン向け (media="screen")
- いわゆる普通のスタイル。
- プリンタ向け (media="print")
- モノクロ印刷を前提にするのが基本。
- その他向け
- デバイス/ソフトウェア環境や実装状況を把握しきれないことが多い。携帯端末向け (handheld) は各キャリアごとのサイト/ページを用意するのが普通。
個別性を忘れていませんか? (1)
あとに記述されている (読み込まれた) スタイルが優先されるという「読み込み順序のルール」は、あくまで個別性が同じスタイルについて適用されるわけで、まず個別性を理解していなければならない。
次の式を頭に入れる。
[式]
* (0点) < 要素タイプ (1点) < class (10点) < id (100点)
個別性を忘れていませんか? (2)
[例]
* { color: silver; } /* 個別性 0点 */
em { color: gray; } /* 個別性 1点 */
p em { color: blue; } /* 個別性 2点 */
em.note { color: green; } /* 個別性 11点 */
em#note01 { color: red; } /* 個別性 101点 */
最終的に、個別性が最も高い「em#note01」のスタイルが適用され、文字色が赤 (red) になっていることを確認。
個別性を忘れていませんか? (3)
擬似クラスも10点。a要素に対する擬似クラスでは...
[例]
a:link { color: blue; } /* 個別性 11点 */
a:visited { color: purple; } /* 個別性 11点 */
a:hover { color: red; } /* 個別性 11点 */
a:active { color: yellow; } /* 個別性 11点 */
すべてのスタイルとも個別性は11点だが、:link、:visited、:hover、:active擬似クラスという指定順序に注目 (ユーザーのカーソル/キーアクションの順序どおりに)。
CSS2とCSS2.1の個別性計算の違い
| セレクタ類 |
CSS2 |
CSS2.1 |
| style属性 |
100点 (id相当) |
1,000点 |
| id |
100点 |
100点 |
| class |
10点 |
10点 |
| 擬似クラス |
10点 |
10点 |
| 属性セレクタ |
10点 |
10点 |
| 要素タイプ |
1点 |
1点 |
| 擬似要素 |
0点 (無視) |
1点 |
| ユニバーサルセレクタ |
0点 |
0点 |
原則としてidを使う、という発想
- ページ内のテキストやパーツそれぞれは本来、特定の役割を備えているはず。つまり、原則としてidを使い、他のものと役割が共通する場合や複数の役割を与えたい場合にだけ、例外的にclassを使うという発想が大切。
- idとclassでは個別性が異なる点に注意 (100点と10点)。
id/classには要素タイプを (1)
[悪い例]
#request { ... }
.examples { ... }
これらのid/classが果たしてどの要素につけられているかはCSSを見ただけではわからず、(X)HTMLを確認する必要が出てしまう。スタイルの作りこみが進むにつれ、また特に複数人管理の場合、このような事態が頻発することに。
id/classには要素タイプを (2)
したがって、基本的にid/classには要素タイプをつける (オープンにしない) と決めておいたほうがよい。
[よい例]
form#request { ... }
pre.examples { ... }
idはどのページでも同一の要素タイプでしか利用しないケースが多いが、classは複数の要素タイプで利用する場合もある。そのような場合にだけオープンにしておき、通常はきちんと要素タイプをつけておく。
id/classで使う区切り記号 (1)
- id/classでは、区切り記号としてハイフン (
-) とアンダースコア (_) が利用できる。古いブラウザではこれらの記号を解釈してくれないか混同してしまうものがあるが、モダンブラウザでは使っていても問題はない。
- アンダースコアについてはCSS2の仕様自体ではなく正誤表で認められたという経緯からか (CSS2.1では正式に認められている)、ハイフンを使っているところが多い。
id/classで使う区切り記号 (2)
これらの区切り記号を使わずに、後ろの単語を大文字ではじめることで視覚的に見やすくする方法もよく利用されている。
[例]
div#globalNav { ... }
div#siteInfo { ... }
ul#shopItems { ... }
form#searchBox { ... }
(X)HTML+CSS向けにはハイフンを使い、プログラム向けには後ろの単語を大文字ではじめる、といったルールもあり。
id/classを避けるための子孫セレクタ
- id/classのデメリット
- CSS上だけでなく(X)HTML上でも属性の追加作業が発生する、(X)HTMLソースが長く (汚く) なる、増えすぎることで管理しにくくなるなど。
- 子孫セレクタの積極利用
- id/classはなるべく使わず、ワイヤーフレームの各部位のidを頼りに子孫セレクタを積極利用する。文書ツリー構造を意識したスタイル設計が可能。
子孫セレクタで示すツリー構造 (1)
子孫セレクタは、
[例]
div#sidebar ul li a { ... }
と書いても、
[例]
div#sidebar a { ... }
と書いても、「div#sidebar ul li a」に対してスタイルが適用される。
子孫セレクタで示すツリー構造 (2)
どちらにすべきということはないが、なるべくツリー構造を丁寧に (子セレクタ的に) 書いておいたほうがよい。CSSを見ただけでツリー構造が把握できるため。
ただ、これも程度問題であって、
[例]
div#container div#wrapper div#sidebar ul li a { ... }
というようにbody要素以下のツリー構造をすべて書いておくことは果たして効率的だろうか、管理に適しているだろうかという疑問が。
子孫セレクタで示すツリー構造 (3)
ひとつの基準として、子孫セレクタはワイヤーフレーム上の各部位からはじめるのがよい。たとえば「div#header」「div#nav」「div#content」「div#sidebar」「div#footer」などから子孫セレクタをはじめるということ。
それで十分、CSSを見ただけで適用対象が特定できる。
子孫セレクタで示すツリー構造 (4)
ただし、次のように
[例]
div#content p a { ... }
div#content ul li a { ... }
div#content dl dd a { ... }
複数の要素タイプに含まれるa要素を対象にする場合は、
[例]
div#content a { ... }
とシンプルに書いたほうがよいだろう。
子孫セレクタで示すツリー構造 (5)
/* For Sidebar */
div#sidebar { ... }
div#sidebar h2 { ... }
div#sidebar p { ... }
div#sidebar ul { ... }
div#sidebar ul li { ... }
:
div#sidebar p#amazon { ... }
div#sidebar p#adsense { ... }
プロパティの指定順序
Mozilla.orgの外部CSSで示されている順序が参考になる。
- 視覚整形モデル
- ボックスモデル
- 背景と前景
- フォントとテキスト
- 生成内容
ただし、Dreamweaverなどのオーサリングツールしか使ってない場合、プロパティの指定順序まで統一するのは困難かも?
ショートハンドプロパティの使い方 (1)
基本的に省略した値は規定値に戻される、という点に注意。
[例]
h3 { font: x-large sans-serif; }
↓
[例]
h3 { font: normal normal normal x-large/normal sans-serif; }
ショートハンドプロパティの使い方 (2)
ひとつの基準として、値が1~2個の場合はショートハンドプロパティを使わず、個別のプロパティを指定する。
[例]
h3 { font: x-large sans-serif; }
↓
[例]
h3 {
font-size: x-large;
font-family: sans-serif;
}
CSSハックの利用
- どれを使うかは、ターゲットブラウザに何を含めるかと関連。
- 古いブラウザの安定動作を確保するという積極的な意味も。
- 使う前に、ソースがそもそも構文的に正しいかどうかを確認。
- なるべくCSSの構文的にエラーではないハック (validating hacks) にとどめる。というのは建前で、構文的にエラーなハック (non-validating hacks) を使わざるをえないケースはある。
CSSハックの構文的な正しさ (1)
| ハック |
構文的な正しさ |
| media="screen, tv" |
OK |
| @import " ... "; |
OK |
| !important |
OK |
| html>body h1 { ... } |
OK |
| head+body h1 { ... } |
OK |
| html:lang(ja) h1 { ... } |
OK |
| html[xmlns] h1 { ... } |
OK |
| :root h1 { ... } (CSS3) |
NG |
CSSハックの構文的な正しさ (2)
| ハック |
構文的な正しさ |
| h1 { /*\*/ color: red; /* */ } (Holly hack) |
OK |
| h1 { /*/*/ color: red; /* */ } (Caio's hack) |
OK |
| h1 { /*/*//*/ color: red; /* */ } (Fabrice's Inversion) |
OK |
| * html h1 { ... } (star hack) |
Doubtful |
| html*h1 { ... } (star 7 hack) |
NG |
| h1 { _color: red; } (underscore hack) |
NG |
| h1 { #color: red; } (hash hack) |
NG |
CSSハックの構文的な正しさ (3)
| ハック |
構文的な正しさ |
h1 {
voice-family: "\"}\"";
voice-family: inherit;
color: red;
} (Tantek box model hack) |
NG |
| h1 { c\olor: red; } (simplified box model hack) |
NG |
<!--[if IE]> ... <![endif]--> (conditional comments) |
OK |
CSSハックの記述ルール例
[例]
h1 {
color: green;
font-size: 2em;
}
* html h1 {
font-size: 1.5em; /* for Win IE 6, Mac IE 5 */
}