033.2 レッスン 1
Certificate: |
Web開発の要点 |
---|---|
Version: |
1.0 |
Topic: |
033 CSSコンテンツスタイリング |
Objective: |
033.2 CSSセレクターとスタイルアプリケーション |
Lesson: |
1 of 1 |
はじめに
CSSルールを記述する際には、そのルールがどの要素に適用されるかをブラウザに伝える必要があります。そのためには、要素や要素のグループにマッチするパターンである「セレクタ」を指定します。セレクタにはさまざまな形式があり、要素の名前、属性、文書構造内での相対的な配置、またはこれらの特性の組み合わせに基づいています。
ページ全体のスタイル
CSSを使用する利点の一つは、同じスタイルを共有する要素に個別のルールを記述する必要がないことです。アスタリスクは、次の例のように、Webページ内のすべての要素にルールを適用します。
* {
color: purple;
font-size: large;
}
ページ内のすべての要素にスタイルルールを適用する方法は、 *
セレクタだけではありません。単純にタグ名で要素にマッチするセレクタを タイプセレクタ と呼びますので、 body
、 p
、 table
、 em
など、どんなHTMLタグ名でもセレクタとして使うことができます。CSSでは、親のスタイルは子の要素に 継承 されます。したがって、実際には、 *
セレクタを使うと、 body
要素にルールを適用するのと同じ効果があります。
body {
color: purple;
font-size: large;
}
さらに、CSSのカスケード機能を使えば、要素の継承されたプロパティを細かく調整することができます。ページ内のすべての要素に適用される一般的なCSSルールを書いてから、特定の要素や要素のセットに対してルールを書くことができます。
同じ要素が2つ以上の相反するルールにマッチした場合、ブラウザは最も具体的なセレクタのルールを適用します。以下のCSSルールを例に挙げてみましょう。
body {
color: purple;
font-size: large;
}
li {
font-size: small;
}
ブラウザは color: purple
と font-size: large
のスタイルを body
要素内のすべての要素に適用します。しかし、ページ内に li
要素がある場合、ブラウザは font-size: large
スタイルを font-size: small
スタイルに置き換えます。これは li
セレクタが body
セレクタよりも li
要素と強い関係を持っているためです。
CSSでは同一スタイルシート内の同等のセレクタの数を制限していないので、同じセレクタを使ったルールが2つ以上あっても構いません。
li {
font-size: small;
}
li {
font-size: x-small;
}
この場合、どちらのルールも同じように li
要素に特化しています。ブラウザは相反するルールを適用することはできないので、CSSファイルの中で後から来たルールを選択します。混乱を避けるためには、同じセレクタを使用するすべてのプロパティをグループ化することが推奨されます。
スタイルシートに表示されるルールの順番は、ドキュメントでの適用方法に影響しますが、 important
ルールを使用することで、この動作をオーバーライドすることができます。何らかの理由で、2つの独立した li
ルールを維持しつつ、2つ目のルールではなく1つ目のルールを強制的に適用したい場合は、1つ目のルールをimportantとしてマークします。
li {
font-size: small !important;
}
li {
font-size: x-small;
}
!important
と書かれたルールは、自然なスタイルシートのカスケードを崩し、CSSファイル内の問題を見つけて修正するのを難しくするため、注意して使用する必要があります。
制限付きセレクタ
特定のタグにマッチするセレクタを使用することで、継承された特定のプロパティを変更できることを確認しました。しかし、通常は同じタイプセレクタの要素に異なるスタイルを使用する必要があります。
HTMLタグの属性をセレクタに組み込むことで、参照する要素のセットを制限することができます。 例えば、あなたが作業しているHTMLページには、2種類の順序なしリスト( <ul>
)があります。1つはページの上部でWebサイトのセクションへのメニューとして使用され、もう1つはテキスト本文の従来のリストに使用されます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CSS Basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
<div id="content">
<p>The three rocky planets of the solar system are:</p>
<ul>
<li>Mercury</li>
<li>Venus</li>
<li>Earth</li>
<li>Mars</li>
</ul>
<p>The outer giant planets made most of gas are:</p>
<ul>
<li>Jupiter</li>
<li>Saturn</li>
<li>Uranus</li>
<li>Neptune</li>
</ul>
</div><!-- #content -->
<div id="footer">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
</div><!-- #footer -->
</body>
</html>
デフォルトでは、各リストアイテムの左に黒い円が付いています。トップメニューのリストから円を削除し、他のリストには円を残したい場合があります。しかし、単純に li
セレクタを使用すると、テキストボディセクション内のリストの円も削除されてしまいます。一方のリストで使われているリストアイテムだけを変更し、もう一方のリストでは変更しないようにブラウザに指示する方法が必要です。
ページ内の特定の要素にマッチするセレクタを書くには、いくつかの方法があります。先に述べたように、まずは要素の属性を利用する方法を見てみましょう。今回の例では、 id
属性を使って、トップリストだけを指定することができます。
id
属性は、対応する要素に一意の識別子を割り当てるもので、これをCSSルールのセレクタ部分に利用することができます。CSSルールを記述する前に、サンプルのHTMLファイルを編集して、トップメニューに使われている ul
要素に id="topmenu"
を追加します。
<ul id="topmenu">
<li>Home</li>
<li>Articles</li>
<li>About</li>
</ul>
HTMLドキュメントの head
セクションには、同じフォルダにあるスタイルシートファイル style.css
を指し示す link
要素がすでにあるので、そこに以下のCSSルールを追加します。
ul#topmenu {
list-style-type: none
}
ハッシュ文字は、セレクタの中で、要素に続いて、IDを指定するために使われます(スペースで区切ることはありません)。同じIDを持つ要素は存在しないので、ハッシュの左にあるタグ名は任意です。したがって、セレクタは単に #topmenu
と書くことができます。
list-style-type
プロパティは ul
要素の直接のプロパティではありませんが、親要素のCSSプロパティはその子要素に継承されるので、 ul
要素に割り当てられたスタイルは、その子要素である li
要素にも継承されます。
すべての要素が選択可能なIDを持っているわけではありません。実際、IDを持つことが期待されるのは、ページ内の主要なレイアウト要素のうちのいくつかだけです。例えば、サンプルコードで使われている惑星のリストです。このように繰り返される個々の要素に固有のIDを割り当てることは可能ですが、コンテンツの多い長いページではこの方法は実用的ではありません。そこで、親の div
要素のIDをセレクタとして利用し、その内側の要素のプロパティを変更する方法が考えられます。
しかし、 div
要素はHTMLのリストとは直接関係がないので、 list-style-type
プロパティを追加しても、その子には何の影響もありません。したがって、コンテンツ div
内のリストの黒い円を中空の円に変更するには、 descendant(子孫) セレクタを使用する必要があります。
#topmenu {
list-style-type: none
}
#content ul {
list-style-type: circle
}
#content ul
セレクタは、IDが content
である要素の子である ul
要素のみにマッチするため、子孫セレクタと呼ばれます。必要に応じて何段階もの子孫を使うことができます。例えば、 #content ul li
とすると、IDが content
である要素の子孫である ul
要素の子孫である li
要素のみにマッチします。しかし、この例では、 li
要素が親の ul
に設定されたCSSプロパティを継承するので、長いセレクタを使っても、 #content ul
を使ったのと同じ効果が得られます。子孫セレクタは、ページレイアウトが複雑になってくると必須のテクニックです。
例えば、 topmenu
のリストと footer div のリストのアイテムの font-style
プロパティを変更して、斜めに見えるようにしたいとします。単に ul
をセレクタにしてCSSルールを書いても、 content div 内のリストアイテムも変更されてしまうので、できません。これまでは、一度に一つのセレクタを使ってCSSプロパティを変更してきましたが、この方法はこの作業にも使えます。
#topmenu {
font-style: oblique
}
#footer ul {
font-style: oblique
}
別々のセレクタを使うのが唯一の方法というわけではありません。CSSでは、カンマで区切られたセレクタのリストを使って、1つまたは複数のスタイルを共有するセレクタをグループ化することができます。
#topmenu, #footer ul {
font-style: oblique
}
セレクタをグループ化することで、スタイルを重複して書くという余計な作業を省くことができます。さらに、将来的に再びプロパティを変更したいと思っても、すべての異なる場所で変更することを覚えていないかもしれません。
クラス
要素の階層構造をあまり気にしたくない場合は、カスタマイズしたい要素のセットに class
を追加するだけでよいでしょう。クラスはIDに似ていますが、ページ内の単一の要素だけを識別するのではなく、同じ特徴を持つ要素のグループを識別することができます。
例えば、今回作成しているHTMLのサンプルページを参照してください。実際のページでは、このような単純な構造を見かけることは少ないので、クラスのみを使って要素を選択するか、クラスと子孫を組み合わせて要素を選択する方が実用的です。クラスを使ってメニューリストに font-style: oblique
プロパティを適用するには、まずHTMLファイルの要素に class
プロパティを追加する必要があります。まず、トップメニューでそれを行います。
<ul id="topmenu" class="menu">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
そして、フッターのメニューでは、
<div id="footer">
<ul class="menu">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
</div><!-- #footer -->
これで、セレクタグループ #topmenu, #footer ul
を、クラスベースのセレクタ .menu
に置き換えることができます。
.menu {
font-style: oblique
}
IDベースのセレクタと同様に、クラスベースのセレクタでもドットの左にタグ名を追加することは任意です。ただし、IDとは異なり、同じクラスを複数の要素で使用することが想定されており、それらが同じタイプセレクタである必要はありません。したがって、 menu
クラスが異なるタイプセレクタの要素で共有されている場合、 ul.menu
セレクタを使用すると、 menu
クラスを持つ ul
要素のみにマッチします。その代わり、セレクタに .menu
を使用すると、タイプセレクタに関係なく、 menu
クラスを持つすべての要素にマッチします。
さらに、要素は複数のクラスに関連付けることができます。上のメニューと下のメニューを区別するには、それぞれに別のクラスを追加します。
<ul id="topmenu" class="menu top">
そして、フッターメニューでは、
<ul class="menu footer">
class
属性に複数のクラスを指定する場合は、スペースで区切らなければなりません。これで、 menu
クラスの要素間で共有されるCSSルールに加えて、トップとフッターのメニューをそれぞれのクラスを使って扱うことができるようになりました。
.menu {
font-style: oblique
}
.menu.top {
font-size: large
}
.menu.footer {
font-size: small
}
.menu.top
という書き方は、 .menu .top
(単語の間にスペースを入れます)とは異なることに注意してください。最初のセレクタは、 menu
クラスと top
クラスの両方を持つ要素にマッチしますが、2番目のセレクタは、 top
クラスと、 menu
クラスを持つ親要素を持つ要素にマッチします。
特別なセレクタ
CSSセレクタは、要素の動的な状態にも対応できます。これらのセレクタは、ハイパーリンクのようなインタラクティブな要素に特に有効です。訪問者の注意を引くために、ハイパーリンクの上にマウスポインタが移動したときに、ハイパーリンクの外観を変化させたい場合があります。
サンプルページに戻って、トップメニューのリンクから下線を取り除き、マウスポインタが対応するリンクの上に移動したときだけ下線を表示するようにしてみましょう。そのためには、まず、トップメニューのリンクから下線を消すルールを書きます。
.menu.top a {
text-decoration: none
}
次に、同じ要素の :hover
疑似クラスを使って、マウスポインタが対応する要素の上にあるときだけ適用されるCSSルールを作成します。
.menu.top a:hover {
text-decoration: underline
}
擬似クラスセレクタの :hover
は、従来のCSSルールのすべてのCSSプロパティを受け入れます。その他の疑似クラスとしては、既に訪問されたハイパーリンクにマッチする :visited
や、フォーカスを受けたフォーム要素にマッチする :focus
などがあります。
演習
-
あるHTMLページに、次の2つのルールを含むスタイルシートが関連付けられているとします。
p { color: green; } p { color: red; }
ブラウザは、
p
要素内のテキストにはどのような色を適用しますか? -
IDセレクタの
div#main
と#main
の違いは何ですか? -
ID属性が
#main
のdiv
内で使用されているすべてのp
要素にマッチするセレクタは何ですか? -
クラスセレクタの
p.highlight
と.highlight
の違いは何ですか?
発展演習
-
font-style
プロパティをoblique
に変更する単一の CSS ルールを記述してください。このルールは、<div id="sidebar"></div>
または<ul class="links"></ul>
の中にあるa
要素のみにマッチしなければなりません。 -
<p class="article reference">
のように、class
属性が.article .reference
に設定されている要素のスタイルを変更したいとします。しかし、.article .reference
のセレクタでは、それらの要素の外観を変更していないように見えます。なぜセレクタは期待通りに要素にマッチしないのでしょうか? -
ページ内のすべての訪問済みリンクの
color
プロパティをred
に変更するCSSルールを記述してください。
まとめ
このレッスンでは、CSSセレクタの使い方と、ブラウザが各要素に適用するスタイルを決定する仕組みについて説明しました。HTMLのマークアップとは別に、CSSはページ内の個々の要素や要素のグループに合わせて多くのセレクタを提供します。このレッスンでは、以下の概念と手順を説明しました。
-
ページ全体のスタイルとスタイルの継承
-
タイプセレクタ別の要素のスタイリング
-
要素のIDとクラスをセレクタとして使用する
-
複合セレクタ
-
擬似クラスを使用した動的な要素のスタイリング。
演習の回答
-
あるHTMLページに、次の2つのルールを含むスタイルシートが関連付けられているとします。
p { color: green; } p { color: red; }
ブラウザは、
p
要素内のテキストにはどのような色を適用しますか?色は
red
です。2つ以上の同等のセレクタのプロパティが相反する場合、ブラウザは最後のセレクタを選択します。 -
IDセレクタの
div#main
と#main
の違いは何ですか?セレクタ
div#main
は、IDmain
を持つdiv
要素にマッチしますが、#main
セレクタは、IDmain
を持つ要素に、そのタイプセレクタに関わらずマッチします。 -
ID属性が
#main
のdiv
内で使用されているすべてのp
要素にマッチするセレクタは何ですか?セレクタ
#main p
。 -
クラスセレクタの
p.highlight
と.highlight
の違いは何ですか?セレクタ
p.highlight
はタイプセレクタがp
でクラスがhighlight
である要素のみにマッチしますが、.highlight
セレクタはタイプセレクタに関係なくクラスがhighlight
であるすべての要素にマッチします。
発展演習の回答
-
font-style
プロパティをoblique
に変更する単一の CSS ルールを記述してください。このルールは、<div id="sidebar"></div>
または<ul class="links"></ul>
の中にあるa
要素のみにマッチしなければなりません。#sidebar a, ul.links a { font-style: oblique }
-
<p class="article reference">
のように、class
属性が.article .reference
に設定されている要素のスタイルを変更したいとします。しかし、.article .reference
のセレクタでは、それらの要素の外観を変更していないように見えます。なぜセレクタは期待通りに要素にマッチしないのでしょうか?.article .reference
セレクタは、クラスarticle
を持つ要素の子孫で、クラスreference
を持つ要素にマッチします。article
とreference
の両方のクラスを持つ要素にマッチさせるためには、セレクタは.article.reference
としなければなりません(これらの間にはスペースを入れません)。 -
Write a CSS rule to change the
color
property of all visited links in the page tored
.a:visited { color: red; }