CSSの作業効率がアップする、少し高度な使い方のまとめ
Post on:2018年3月19日
Webページやスマホアプリをはじめ、レスポンシブ対応ページなどで役立つ、CSSのあまり知られていない仕様や少し高度な使い方を紹介します。
Lesser known CSS quirks & advanced tips
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- 01. 垂直方向のpaddingは要素の幅に対して相対的
- 02. マージンの相殺が適用されない条件
- 03. 不透明度でz-indexの積み重ね順序を変更できる
- 04. CSSのカスタムプロパティ(変数)
- 05. vertical-align: top | middle | bottom
- 06.「height: 100%;」の挙動
- 07. idとclassの詳細度
- 08. 属性のターゲティング
- 09. 複数の値を指定する場合、垂直、水平の順番になるとは限らない
- 10. 背景を複数指定する簡単な方法
- 11. CSSアニメーションを重ねる
- 12.「position: fixed;」の不思議な振る舞い
- 13. ハッシュリンクのターゲット要素のスタイリング
- 14. 知っていると便利なcontentプロパティの機能
- 15. fontは一括指定プロパティ
- 16. ブラウザのサポートを確認するための@support
- 17.「:」を使用したclass名
- 18. フクロウみたいなセレクタ
- 19. douchebag vertical align
- 20. OpenTypeフォントのためのfont-feature-settings
- 21. テキストがはみ出した場合に省略記号「…」に自動変換
- おまけ: wbr要素
- CSS Gridはどこですか?
01. 垂直方向のpaddingは要素の幅に対して相対的
垂直方向のpaddingは要素の高さにではなく、要素の幅に対して相対的です。例えば「padding-top: 50%;」と指定した場合は、要素の高さの50%をpaddingとして与えるのではなく、親要素の幅の50%をpaddingとして与えます。
See the Pen Vertical padding by Peedu Tuisk (@matude) on CodePen.
これを利用することで、高さ/幅の比を維持するレスポンシブに対応した要素を簡単に作成できます。
1 2 3 4 5 |
.square { width: 100%; height: 0; padding-bottom: 100%; } |
02. マージンの相殺が適用されない条件
下記のように、上の要素に「margin-bottom:20px;」を、下の要素に「margin-top:20px;」を指定した場合、その間のマージンはいくつになるでしょうか?
答えは、40pxではなく、20pxが正解です。これはマージンの相殺と呼ばれるもので、特定の状況で発生します。
1 2 |
<div style="margin-bottom:20px">foo</div> <div style="margin-top:20px">foo</div> |
See the Pen Margins overlap by Peedu Tuisk (@matude) on CodePen.
マージンの相殺には例外があります。以下の状況では発生しません。
- フロートされた要素
- 絶対配置された要素
- インライン ブロック要素
- overflowに「visible」以外が指定された要素(子要素とのマージンは崩れません)
- クリア用の要素(親ブロックの下マージンで上のマージンは崩れません)
- ルート要素
マージンの相殺の仕組みについては、下記で詳しく説明されています。
03. 不透明度でz-indexの積み重ね順序を変更できる
下記のデモでは、z-indexを指定した3つのdiv要素が積み重なっています。z-indexの数字が小さいほど下に配置され、数字が大きいほど上に配置されます。
「z-index: 10;」を指定したレッドのdiv要素は一番上に配置されていますが、これに「opacity: 0.99;」を加えると、一番下にあるように見えます。
See the Pen Z-index order and opacity by Peedu Tuisk (@matude) on CodePen.
これがなぜ起こるのかに関する詳細は、What No One Told You About Z-Indexを見てみてください。
04. CSSのカスタムプロパティ(変数)
CSSのカスタムプロパティ(変数)は、SassやLESSなどのプリプロセッサで利用できる機能と同等であると考えられるかもしれませんが、異なる点がいくつかあります。
まずは、カスタムプロパティの基本的な書式を見てみましょう。
1 2 3 4 5 6 7 |
// 下記のようにカスタムプロパティを設定して使用することができます :root { --foo: #000; } button { background-color: var(--foo); // これで背景は、ブラックになります } |
CSSのカスタムプロパティは継承可能です。この変数を使用すると、すべての子要素にスタイルが適用されます。プリプロセッサとは異なり、ブラウザはすべての変数と式を再計算します。
フォールバックはコンマで使用でき、コンマの後に複数のフォールバックを記述することもできます。
1 2 3 |
.foo { color: var(—-my-var, 'blue'); } |
これがプリプロセッサと異なる点です。CSSの変数はDOMの構造を認識しており、動的に利用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
::root { --default-color: #000000; } header { --primary-color: #ff0000; } a { color: var(--primary-color, --default-color); } <a href="">this is black</a> <header> <a href="">this is red.</a> </header> |
継承の最初の例のとは異なり、上記の例では、カスタムプロパティが親のDOM要素に設定されているかどうかを認識しているフォールバックに依存しています。
See the Pen CSS custom properties and variables by Peedu Tuisk (@matude) on CodePen.
さらに、JavaScriptを使って簡単に変更することもできます。
1 2 3 4 |
// インラインスタイルから変数を取得します element.style.getPropertyValue("—-my-var"); // インラインスタイルに変数を設定します element.style.setProperty("--my-var", jsVar + 4); |
CSSのカスタムプロパティは、Edge15+にサポートされています。
05. vertical-align: top | middle | bottom
「vertical-align: top | middle | bottom」はinline(インラインブロックを含む)とtable-cellで機能します。直感的には子要素を親の内側に揃えるためのものと思うかもしれませんが、適切な使い方ではありません。
親要素の内側の子要素を揃えるためには、flexboxか、douchebag vertical alignと呼ばれるテクニックが適しています。
参考
06.「height: 100%;」の挙動
「height: 100%;」が期待通りにならないことがあります。その原因は親要素の高さが設定されていない時に起こります。例えば、下記のコードを見てみてください。
1 2 3 4 5 |
<html> <body> <div style=”height:100%;background:red;”></div> </body> </html> |
このコードではページ全体の背景をレッドにはしません。
全体の背景をレッドにするには、bodyとhtmlの両方の高さを100%に設定する必要があります。
07. idとclassの詳細度
idのスタイルは、すべてのclassのスタイルを覆します。これはCSSの詳細度と呼ばれるもので、記述の順番には影響されず、セレクタのポイントにより優先順位が決まります。詳細度では、idはclassより優先されます。
そのため、下記のコードでは#fooのスタイルが優先され、テキストはレッドになります。
1 2 3 4 |
#foo { color: red; } .bar { color: green; } <h1 id="foo" class="bar">this will be red not green</h1> |
08. 属性のターゲティング
CSSでは、srcやhref属性のコンテンツのように、特定の属性とそのコンテンツをターゲットにすることができます。
1 2 3 4 5 |
// すべてのzipファイルを対象(大文字と小文字を区別しない) a[href$=".zip" i] { } // google.comのリンクをレッドにします [href*="google.com"] { color: red; } |
これはデバッグする時にも役立ちます。例えば、img要素のalt属性が空の場合をチェックする時には、下記のように記述します。
1 2 3 4 5 6 7 |
img:not([alt]) { border: 2px dashed red; } img[alt=""] { border: 2px dashed red; } |
AngularJSを使用している場合、このテクニックはng-clickを含むいくつかの要素のターゲットにするのに役立ちます。他にもローカルではなく「http」または「https」で始まるすべてのリンクをターゲットにすることもできます。
09. 複数の値を指定する場合、垂直、水平の順番になるとは限らない
プロパティに水平軸と垂直軸の値を宣言する時は通常、最初の値は垂直軸で、次の値が水平軸を宣言します。つまり、「padding: 10px 20px;」では、10pxが上下で、20pxが左右です。これはpaddingだけでなく、marginやborderなども同じです。
しかし、テーブルの「border-spacing」は異なります。最初の値が水平軸で、次の値が垂直軸になるので、注意してください。
10. 背景を複数指定する簡単な方法
1つの要素に複数の背景を加え、それらをすべて別々に配置することもできます。カンマで区切るだけです。
1 |
background: url(example1.png’) no-repeat center 50px, url(‘example2.jpg’) no-repeat bottom top; |
IE11+にサポートされています。
11. CSSアニメーションを重ねる
背景と同じように、CSSアニメーションも重ねることができます。
1 2 3 4 5 6 7 8 9 10 11 |
@keyframes foo { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes bar { 0% { transform: translateX(-100px); } 100% { transform: translateX(0px); } } .element { animation: foo 2s 0s, bar 1s 0s; } |
残り半分となりました。
CSSを効果的に使用すると、劇的に変わります!
12.「position: fixed;」の不思議な振る舞い
「position: fixed;」された要素を含むコンテナに「transform: translateZ(0);」を加えると、固定配置された要素を画面からユーザーの方に移動し、コンテナに揃えます。
See the Pen TranslateZ and position: fixed behavior by Peedu Tuisk (@matude) on CodePen.
13. ハッシュリンクのターゲット要素のスタイリング
:target擬似クラスを使用して、ターゲット要素をターゲットにすることができます。どういうことかと言うと、ハッシュリンク<a href="#foo">Fooに移動</a>をクリックすると、ページ上の<div id="foo">foo</ div>要素に移動します。
そして、CSSで「#foo:target{color: red;}」を記述すると、ターゲットの#foo div要素のテキストがレッドになります。これは、www.example.com/#fooのように、外部ハッシュリンクを介してページに訪れたビジターにターゲット要素をハイライト表示させたい場合に便利です。
ブラウザが正しい要素に移動するだけでなく、CSSを使用してこのターゲットされたセクションを視覚的により明瞭にすることができます。ユーザーエクスペリエンスを向上させるためには非常に便利なテクニックです。
See the Pen Hash target pseudo-class highlighting in CSS by Peedu Tuisk (@matude) on CodePen.
14. 知っていると便利なcontentプロパティの機能
data属性
contentプロパティにdata属性を使用して、動的なテキストを表示することができます。
1 2 3 4 5 |
<div data-text="foo">bar</div> div:before { content: attr(data-text); } |
この機能は、擬似クラスのコンテンツテキストを表示する場合(ツールチップなど)に便利です。現在contentプロパティではattr()がサポートされており、他のプロパティではサポートされていません(将来は可能性があります)。attr()の値は文字列なので、このように使われることに意味があります。ちなみに、単位(font-sizeなど)やURL(content:url()など)に使用することはできません。
content: url()
これは、多くのタイプのメディア(画像、音、動画)に使用できます。
1 2 3 4 5 |
<div>foo</div> div:before { content: url(image.jpg); } |
しかし、DOMからCSSへのコンテンツの受け渡しに使用できるものは、前述のカスタム プロパティです。
1 2 3 4 5 6 |
<div style="--background-image: url('http://via.placeholder.com/150x150');"></div> div:after { content: ''; background-image: var(--background-image); } |
counter-increment
「content: counter();」を使用すると、擬似要素に自動で連番を付けることができます。
1 2 3 4 5 6 7 8 9 |
p { counter-increment: myIndex; } p:before { content:counter(myIndex); } <p>foo</p> <p>bar</p> |
See the Pen CSS counter-increment property by Peedu Tuisk (@matude) on CodePen.
content: open-quote; | close-quote;
:beforeや:afterのような擬似クラスのcontentプロパティは、引用符を開いたり閉じたりするのに使うことができます。
1 2 3 4 5 6 |
q:before { content: open-quote; } q:after { content: close-quote; } |
引用時には前述のdata属性と組み合わせて、quotesプロパティだけでサイトの言語に基づいて特定のローカライズされたスタイルの引用を設定することもできます。
1 2 3 |
html[lang=”fr”] q { Quotes: “«” “»”; } |
15. fontは一括指定プロパティ
fontは、CSSの一括指定プロパティです。そのため、すべてのプロパティを別々に記述する代わりに、すべてのプロパティを1つにまとめて記述しても構いません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
h1 { font-weight: bold; font-style: italic; font-size: 1rem; //etc… } // vs h1 { font: italic lighter 1rem/150% Verdana, Helvetica, sans-serif; } // 一括指定の順番 // font: font-style font-variant font-weight font-size/line-height font-family; |
16. ブラウザのサポートを確認するための@support
@supports機能のクエリを使用して、ブラウザのサポートを確認することができます。例えば、flexboxを使用する際に、下記のように@supportsでサポートブラウザのみに適用することができます。
1 2 3 4 5 |
@supports (display: flex) { div { display: flex; } } |
17.「:」を使用したclass名
class名にコロン「:」を使用すると、目的をはっきりさせるのに役立ちます。CSSのフレームワーク(Tailwindなど)では、下記のような命名規則が採用されています。
1 2 3 |
<div class="justify-start sm:justify-center md:justify-end lg:justify-between xl:justify-around"> <button class=”bg-blue hover:bg-blue-dark text-white hover:text-blue-light”>Button</button> |
ホバー時のスタイルで特定のclassを宣言することは、ほとんどの場合おそらく有用ではありませんが、この命名規則を採用することでホバー状態がはっきりと認識できるようになり、読みやすくなります。これは非常に記述的です。
CSSでは、下記のようにコロンをエスケープする必要があります。
1 |
.sm\:justify-center{} |
18. フクロウみたいなセレクタ
この記事を読んでいる人は、フクロウみたいなセレクタについて知っておくべきです
1 2 3 |
* + * { margin-top: 2rem; } |
「* + *」がフクロウの顔のように見えるのが、その由来です。
このセレクタの使い方は、同じ種類の複数の要素がある場合(リストやナビゲーションのアイテムなど)に便利です。
1 2 3 4 5 6 7 8 9 10 11 12 |
li + li { margin-top: 1rem; } // vs li { margin-bottom: 1rem; } li:last-of-type { margin-bottom: 0; } |
「li + li」を使用すると、最後のマージンを取り除く必要はありません。
19. douchebag vertical align
面白い呼び名がついたセレクタをもう一つ。
「05. vertical-align: top | middle | bottom」にも出てきた「douchebag vertical align」です。これは垂直方向で揃える時に役立つテクニックです。
1 2 3 4 5 |
.element { position: relative; top: 50%; transform: translateY(-50%); } |
20. OpenTypeフォントのためのfont-feature-settings
OpenTypeフォントはfont-feature-settingsプロパティを使用して、フォントを好きなように調整するための機能があります。この機能を使用すると、例えばカウントダウンタイマーにフォントを使用する場合ですが、モノスペースのフォントではありません。数字の幅が変わり、コンテンツを押し続けることを意味します。
1 2 |
font-feature-settings: “tnum”; font-variant-numeric: tabular-nums; |
Countdown clock kept shifting because the width of numbers change. Got to use this to fix it!
font-feature-settings: "tnum";
font-variant-numeric: tabular-nums; pic.twitter.com/iUsIkceys1— Wes Bos 🔥 (@wesbos) 2017年11月20日
21. テキストがはみ出した場合に省略記号「…」に自動変換
「text-overflow: ellipsis;」を使用すると、テキストがはみ出した場合に省略記号「…」に自動で変換されます。
1 2 3 4 5 |
p { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } |
See the Pen Truncate texts with just css, add 3 dots or ellipsis to the end by Peedu Tuisk (@matude) on CodePen.
おまけ: wbr要素
CSSではありませんが、テキストに関係するのでおまけです。
あまり知られていない興味深いHTML要素があります。<wbr>は、改行しても良い位置をテキスト内に明示することができます。
CSS Gridはどこですか?
この記事は十分長くなってしまったので、次に期待してください。CSSの興味深いことはまだまだたくさんあります。
ここまで読んでくださって、ありがとうございます!
sponsors