Cocoonをカスタマイズしようとすると、自然とCSSを学ぶことになります。今回取り上げるのは、余白を指定するmarginプロパティです。
このサイトを作成した頃、デザインは余白で決まる…という内容の本を手にしたのをきっかけに、あらためて自分のサイトを見返してみました。
メリハリがない…というか、かなりギッチリと詰まっているように感じました。
そこで、見出し前後の余白を調整することにしたのですが、それにはCSSでmargin
プロパティを使うくらいの知識はありました。
余白サイズの指定自体は難しいことではありませんが、Cocoonを使っているという前提があるので、初期設定の確認や疑問に思うことがあって、改めてmarginプロパティの特性について勉強したところ、色々と面白い発見がありました。
今回の記事では単に余白を設定する方法だけではなく、marginプロパティの特性や、新しく発見した:has()疑似クラスについてをまとめています。
Cocoonの見出し設定
下の図は、Cocoonの初期設定の見出しh2~h6のサンプルです。
デザインを注目しがちですが、今回は要素同士の間隔に注目してください。
そういう目で見ると、全ての間隔が同じに見えますね。
ただ、実際はビミョウ~にサイズが異なります。
初期値の確認
この設定をChromeの検証ツールで確認してみたところ、主要な要素の上下余白は次のように設定されていました。
Chromeの検証ツールは
[F12]キーで起動できます!
・・・ margin-bottom: 2.1em;
・・・ margin-bottom: 2.4em;
単位に「em」を使っているので、親要素のフォントサイズから相対的にサイズが割り出されます。
つまり、同じ指定サイズであっても、基準となるフォントサイズが異なれば、実際の余白サイズは異なります。
実際に設定されていた数値から実数値を算出した結果が次の表になります。
要素 | 初期設定 | 余白サイズの計算式 | 余白実数値 |
---|---|---|---|
サイト全体のフォントサイズ | 18px | 18px | |
目次のフォントサイズ | 0.9em | 18×0.9 | 16.2px |
目次の下余白 | 2.4em | 16.2×2.4 | 38.88px |
p(段落)の下余白 | 2.4em | 18×2.4 | 43.2px |
h2~h6(見出し)の下余白 | 2.16em | 各レベルごとに計算 | |
h2 のフォントサイズ | 24px | 24×2.16 | 51.84px |
h3 のフォントサイズ | 22px | 22×2.16 | 47.52px |
h4~h5 のフォントサイズ | 20px | 20×2.16 | 43.20px |
スキンの中には、見出しの文字サイズを大きめにカスタマイズしているものがあります。その場合は基準のフォントサイズが大きくなった分、見出し下の余白が広くなっている可能性があります。
また、サイト管理者がサイト全体のフォントサイズをカスタマイズしている場合も基準値が変わるので、実数値に影響してきます。
こうして各要素の上下余白を調べるうちに、あることに気づきました。
margin-top は無いの?
そうなんです。
上下余白…と思って調べたのに、下の余白しか設定されていなかったんです。
なんでだろう…
marginプロパティ
余白を指定する場合は、CSSのmargin
を使います。
margin
そのものは、ひとつのプロパティで上下左右の指定が行える一括指定プロパティです。
各辺にそれぞれ指定する場合は次のプロパティを使います。
- margin-top
- margin-right
- margin-bottom
- margin-left
リストの順番が変だな?と感じるかもしれませんが、一括指定をする場合は、上辺→右辺→下辺→左辺 というように時計回りで指定するので、その順に書いています。
どっちを使う? ‘margin-top’と ‘margin-bottom’
さて、Cocoonでは何故かmargin-top
を見かけないので気になって調べてみると、世のWeb制作者達の間では『margin-top vs. margin-bottom』論争というのがあるとわかりました。
独学の身では、前後のデザインを見ながら「なんとなく」決めていた上下余白でしたが、実は上下のどちらか一方に統一すべきだという考え方があると知って目からウロコでした。
ところが、統一するなら「上か? 下か?」の決着がついていないようです。
元になるコードをチョコチョコとカスタマイズしている人間とは違い、全体を考えてコーディングするプロにとっては、メンテナンスしやすいコードを組み立てる(コーディング)ことが重要なのは当然ですよね。
しかも複数の人間がサイト運営に関わる場合は、プロジェクト内で統一した設定が大切なことも理解できます。
それでも「上か下か?」が論争になるほどプロでさえ意見が分かれているというのも面白いですよね。
これに関してはアンケート結果というのがあって、僅差ではあるものの、今のところ『下派』が優勢なようでした。
そうした事情を知った上でCocoonの設定を見ると、「ほほぅ~」という妙な納得感があります。
が、、、この「どちらかに決めたほうが良い」という言葉を目にしてしまったことで、ついついドツボにハマってしまいました。
このサイト、
上余白・・・指定しないほうがいいの?
きれいに統一されたコードの中に、突然margin-top
を混ぜても良いものだろうか…? と悩むことになったんです。
目指すデザインは、見出し直後の要素との間隔は狭く、見出し直前の要素との間隔は広く取るという、メリハリのあるデザインです。
例えば、こんな感じに…
見出しの下なら、margin-bottom
の数値を小さくすれば済むことです。
問題は、見出しの上にくる要素との間隔です。
見出しの上と考えるならmargin-top
を使えば済むことですが、margin-bottom
しか使わないという縛りがある場合、どうやって実装すればいいのでしょう?
:has()疑似クラス
『要素間の上下余白を指定する場合はmargin-bottom
しか使わない』
というように統一した場合、、、
『見出しレベル2の上だけは、余白を多めに取りたい』というケースに対して、どのようにコーディングすれば良いのでしょうか?
セレクタは「見出しレベル2の直前に来る要素」にしたいわけです。
隣接セレクタというのがあって、セレクタを『+』で区切ると、隣にある要素を指定することができます。
この場合、要素 + 要素
という形で記述するので、h2 + p
というように記述します。
読み解くと、「<h2>の隣に来る<p>に対する指定」となります。
ただ、隣と言うのは『直後』という意味なので、『直前』を指定したい場合には使えません。
普通に考えたら『指定する要素を前に遡るというのは無理な話ですよねぇ~』となりますね。
ところが、見つけました。:has()
という疑似クラスを。
:has()疑似クラスは、「()」の中に指定した要素を持つことを条件にした要素を指定します。
なにソレ~
分かりやすく書くと、「A:has(B) 」とした場合、「Bを持ったAに対する指定」となります。
例えばh1:has(+ p)
と記述した場合は、直後に<p>
要素を持つ<h1>
要素に対してスタイルを指定できます。
使い方
セレクタによってスタイルの適用箇所が変わるのを、実例を使って確認してみましょう。
基本のHTMLコードが次のように記述されているとします。
<h2>見出し1</h2>
<p>テキスト</p>
<p>テキスト</p>
<p>テキスト</p>
<h2>見出し2</h2>
<p>テキスト</p>
<p>テキスト</p>
<p>テキスト</p>
p
要素全てのフォントカラーを「赤(tomato)」にする場合、次のようにCSSを記述します。
p {
color: tomato;
}
pタグで囲まれたテキストが
全部「赤」で表示されます。
h2
直後の<p>
タグで囲まれた文字の色を「赤」にします。
h2 + p{
color: tomato;
}
「h2タグの直後」に限定されるよ!
それでは:has()
を使ってみましょう。
直後にh2
を持つ<p>
タグで囲まれた文字の色を「赤」にします。
p:has(+ h2){
color: tomato;
}
これこれっ!
まさに、『見出しの上』が選択できています。
全称クラスタ
今回目指しているのは、見出しの上の余白を広くすることです。
ただ、ここまではわかりやすさ重視で<p>
タグを使って説明してきましたが、実際の記事では、見出しの上に必ずしもp
要素が来るとは限りません。
画像やテーブルなどが来ることもあるでしょう。
そうなると、特定のタグに限定するよりも、全てのタグを対象にできたら便利ですよね。
そこで使いたいのが「*(アスタリスク)」です。
*
は「全称セレクタ」と呼ばれ、全ての要素が対象になります。
Cocoon用にコーディング
Cocoonのメインカラムで使うことを想定して、次の設定を行うとします。
h2
の前に来る要素には、下余白「4em」を設定する。(=h2
の直前余白)h3
の前に来る要素には、下余白「3em」を設定する。(=h3
の直前余白)h1
~h6
の下余白は「1.4em」に設定する。
これをコードにすると、次のようになります。
.entry-content *:has(+ h2){
margin-bottom: 4em !important;
}
.entry-content *:has(+ h3){
margin-bottom: 3em !important;
}
.article h2,
.article h3,
.article h4,
.article h5,
.article h6{
margin-bottom: 1.4em;
}
「!important」はスタイルが適用される優先順位を最優先にする時に使います。
実験してみたところ、Chromeでは問題なく、感動ものの表示になってくれました。
:has() ブラウザ対応状況
せっかく見つけた:has()疑似クラスですが、満遍なくブラウザが対応しているかとなると、まだ完ぺきとは言えない状況です。
対応状況は、以下のサイトで確認できます。
日本での普及率が高い Chrome や Safari では大丈夫ですが、Firefoxがまだ対応できていません。
この対応状況を知った上でこの設定を使うか、それともmargin-top
を使うか…
結論:margin-top を使う
悩んでみたものの、、、
コーディングの際に「上か下かで統一すべき」という考え方には一定の納得感はありますが、素人がそこまでこだわる必要があるか?と考えると、悩むこと自体も笑ってしまうくらいのことかもしれません。
今回は:has()
という疑似クラスを発見したことを収穫として、実際に使うのはもう少し様子を見てからという結論に至りました。
ということで、margin-topを使うコードは、次のようにしました。
.article h2{
margin-top: 4em;
}
.article h3{
margin-top: 3em;
}
.article h2,
.article h3,
.article h4,
.article h5,
.article h6{
margin-bottom: 1.4em;
}
時機を見て変更することもあるかもしれません。
最後に…
見出しの上下にある余白を調整したいと考えたことから、CSSのmargin
プロパティについて、あらためて考えるきっかけになりました。
もうひとつ「へぇ~、そうだったんだ…」と改めて知ったのがmarginの相殺です。
下余白を設定した要素と、上余白を指定した要素が縦に並んだ時、それぞれの余白は足し算にはならず、数値の大きいほうが優先されるというルールです。
要素と要素との間隔を「50px」にしたい場合に、上の要素に「30px」のmargin-bottomが指定してあるからといって、それなら下に来る要素には「20px」のmargin-topを指定すればいいや…とはならないのです。
この場合は「50px」という指定が優先されます。
こちらのサイトが参考になります。
何気なく使っていることも、何かがきっかけになって新しい発見ができるのは楽しいことですね。CSS自体が進化を続けていることや、考え抜かれて設計されていることがよくわかり、面白かったです。