CSSの知っておくと便利なフクロウセレクタの使い方! 要素を積み重ねる時のマージンにかなり便利です
Post on:2023年2月28日
兄弟要素を積み重ねる時、垂直マージンをどのように実装していますか?
要素を積み重ねる時のマージンは、フクロウセレクタ(* + *
)を使うと簡単です。さらに、>
を追加することで、マージンが再帰的に与えられるのを防ぎます。たった3行のCSSで積み重ねる時のマージンを管理できる、フクロウセレクタの効果的な使い方を紹介します。
このテクニックは、テキストとテキスト、見出し直後のテキスト、流動的なフォントサイズにも非常に効果的です。
My favourite 3 lines of CSS
by Andy Bell
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
Every Layoutで私はThe Stack、要素の積み重ねについて解説しました。これはフクロウみたいなセレクタとCSSのカスタムプロパティを使用してフローとリズムを管理する方法を組み合わせたものです。
* + *
が、フクロウみたいなセレクタです。
1 2 3 |
.stack > * + * { margin-block-start: 1.5rem; } |
このセレクタを分解してみましょう。
フクロウセレクタ(* + *
)を使うことで、.stack
のすべての直接の兄弟要素にmargin-block-start
が与えられます。さらに>
を追加することで、このマージンが再帰的に与えられるのを防ぎます。margin-block-start
は論理プロパティで、英語(左から右)でもアラビア語(右から左)のwriting-mode
でもマージンは要素の上部に与えられます。
私はこのCSSを何年も前から愛用していましたが、最近は.flow
ユーティリティとして拡張しました。
1 2 3 |
.flow > * + * { margin-block-start: var(--flow-space, 1em); } |
見ての通り、The Stackと非常によく似ています。名前以外の違いは、カスタムプロパティ(特にフォールバック値)を使用することです。
CSSのカスタムプロパティでのフォールバック値の仕組み
定義されていないカスタムプロパティの値を取得しようとすると、どうなると思いますか?
初期値または継承値が使用され、カスタムプロパティが無効でフォールバックを提供しない場合、失敗します。
.flow
ユーティリティのコンテキストでは、これはかなり悪いことです。なぜなら、リセットCSSで行うように要素のデフォルトのマージンが削除されてしまうと、スペースがまったくない状態になってしまう可能性があるからです。
.flow
のフォールバック値には、2つの利点があります。
--flow-space
が誤って無効な値として設定された場合、賢明なフォールバックがあります。- もし
--flow-space
が存在しない場合、margin-top-value
は1em
になり、要素の計算されたフォントサイズに相対的になります。
スペースはデフォルトで1em
なので、フォントサイズが大きくなるほどスペースは大きくなります。これはタイプスケールを使用している場合、フローとリズムを維持するのに便利な方法です。
The Stackではなく.flowを使うのなぜですか?
これはよく聞かれることですが、もっともな質問です。その理由は2つあります。
1つ目は、私はこのユーティリティをプロジェクトのあらゆる場所で使用しています。わたし達のスタジオではすべてのプロジェクトで使用しており、おそらく今後も使用するでしょう。その理由は、流動的なタイポグラフィとスペースを使用しているためで、.flow
ユーティリティの柔軟なフォールバックベースの設定は面倒な作業をブラウザに任せるというわたし達の方法論と調和しているからです。
2つ目は、散文的なコンテンツ(この記事のような長文が多いコンテンツ)のようなコンテキストでは、特定のHTML要素がどのようにスペースを取るか管理したいと考えています。たとえば、見出しの直後に続く要素のスペースを減らしたり、画像要素の周りのスペースを増やしたい場合があります。
下記のCSSは、私のブログ記事に使用しているものです。
1 2 3 |
.prose :is(h2 + *, h3 + *, h4 + *) { --flow-space: var(--space-s); } |
このCSSの機能は次のとおりです。
h2
,h3
,h4
の直後に続く要素を探します。--flow-space
に用意したスペースから小さいスペースを割り当てます。
.prose
自体には、以下のように設定しています
1 2 3 |
.prose { --flow-space: var(--space-m-l); } |
デフォルトでは、--flow-space
を未定義のままにしておくことが多いのですが、.prose
のコンテキストでは要素間のスペースがきれいに詰まっているのが好きなので、カスタムプロパティは詳細度とカスケードの影響を受けるため、より具体的な値を作成します。
--flow-space
に使用されるスペース値(計算すると約2.5rem
)は、すべての要素間に一貫したスペースを確保することができます。
gapではなく、marginを使うのなぜですか?
これもよく聞かれることです。Safariがついにgap
をサポートしたときに、私はHeydonに「Every Layoutにgap
を使用すべきだ」と伝えました。実際にわたし達はレイアウトにgap
を採用した第2版について考えましたが、すぐにThe Stackを変えたくないことに気がつきました。
その理由の1つは、gap
を使用するには、スタックをFlexboxまたはGridの親にしなければならないからです。これは既存プロジェクトにこのレイアウトを使用している人々にとって、さまざまな問題を引き起こす可能性があります。実際に、Every Layoutを使用する人々の非常に大きな割合を占めています。
それに伴い、すべてのコントロールは要素自体ではなく、親に配置されることになります。.flow
と--flow-space
のフォールバック値の話に戻りますが、これはgap
では不可能です。なぜならgap
が親(.flow
)に設定され、子要素間のスペースを制御するからです。親要素は完全に制御されており、子要素はどのような瞬間にもgap
が何であるかについて何も言うことができません。
最後に、--flow-space
がカスケードの影響を受け、設定されていない場合は、.flow
が影響を与える子要素からスペース値を継承させるという柔軟性も併せて備えています。
私がgap
を使用したくないもう1つの理由は、論理プロパティです。個人的にはthe studioで構築するすべてのものに論理プロパティをできるだけ使用したいと考えています。彼らは現在でも、サポートが充実しています!
終わりに
正直なところ、この.flow
のイテレーションを作った時点で引退すべきでした。
1 2 3 |
.flow > * + * { margin-block-start: var(--flow-space, 1em); } |
特に今では、Set StudioでEvery Layoutのレイアウトを使用しています。複雑な特定のレイアウトを作成し、CSS Gridのレイアウトの可能性を最大限に活用する場合は別として、現時点では基本的にフロントエンドで色を付けているに過ぎません。
私がこの記事を書いた最大の理由は、なぜ.flow
やmargin
を使用するのかと質問されたときに、この記事を読んでもらうためですが、CSSのカスタムプロパティがいかに強力であるかも理解してもらえたと思います。カスタムプロパティは単なる変数以上のものであることは確かです。
sponsors