『CSS Secrets』は @Lea Verou による最新の本で、CSS に関する小さな秘密がいくつか説明されています。これは CSSers にとって読む価値のある本です。一定期間読んだ後、私、@全域と @彦子は、関連する読書感想文を W3cplus で公開し、皆さんと共有します。
多くの場合、要素の兄弟要素を異なるスタイルで表示する必要があります。主な使用例は、ユーザー エクスペリエンスを向上させ、大画面での推奨事項のリストを増やすことです。以下にいくつかの使用シナリオを示します。
メール リストまたは同様のテキストベースのリスト表示。リスト項目が少数しかない場合は、それらを個別に表示できます。リスト項目が大きくなるにつれて、リスト内のプレビュー項目の数を減らすことができます。リストの高さがウィンドウの高さよりも高い場合、一部のリスト項目を非表示にしたり、ユーザーがスクロール バーをスクロールせずにリストを参照できるように最後に「さらに表示」ボタンを追加したりすることもできます。
アプリ内のTo-Doリスト(やることリスト)では、いくつかのリスト項目に大きな文字スタイルを設定できますが、リスト項目の数が増えると、リスト項目は大きな文字スタイルに設定されます。フォントサイズが小さくなります。
色を表示するために使用されるパレットアプリ。下図のように、色数が増えるにつれてそのスペースを利用してカラーコントロールパネルをコンパクトにしたい場合があります。
色数が増えるにつれてカラーコントロールポートを縮小し、使用可能なスペースを減らします。特別な場合、色が 1 つしかない場合、削除ボタンは非表示になることに注意してください。
複数の
ただし、隣接する兄弟に対してターゲット要素を選択することは、単純な CSS セレクターではありません。たとえば、リストの合計数が 4 の場合、リストに異なるスタイルを与えます。 :nth-child(4) を使用してリストの 4 番目の項目を選択できますが、これはリストの合計数が 4 の場合にリスト内のすべての項目を選択する必要があるわけではありません。
1 つのアイデアは、li:nth-child(4),li:nth-child(4)~li のように、ユニバーサル セレクター ( ~ ) を :nth-child() セレクターと組み合わせて使用することです。 。次の図に示すように、リスト項目の総数に関係なく、4 番目の項目とそれ以降のすべてのリスト項目のみが選択されます。
「後方セレクター」がないため、選択要素 兄弟要素用の以前のセレクターでは、CSS は必要なターゲット要素を選択できない運命にあるのでしょうか?私たちは信仰を失ってはなりません。何でも可能です。
列項目が 1 つだけあるという特殊なケースがあり、明白な解決策があります::only-child セレクター。このセレクターはこのケース専用です。これは非常に便利なので、仕様に追加されました。たとえば、前述のカラー コントロール パネル APP は、色が 1 つしかない場合に削除ボタンを非表示にするため、:only-child セレクターを使用してこれを実現できます。
li:only-child { /* 当只有一个列表项时的样式 */}
このセクションでは :nth-child() セレクターについて説明しますが、この説明はすべて :nth-of-type() セレクターにも同様に当てはまります。通常、このタイプのセレクターを使用すると、コンテナー内に異なるタイプの兄弟要素が存在するため、1 つのタイプのみを考慮する必要があります。この説明では例としてリスト要素を使用しますが、説明した内容はすべて任意のタイプの要素に当てはまります。
ただし、 :only-child は :first-child:last-child と同等であり、最初と最後の項目であり、論理的にはそれが唯一の項目であることになります。実際、:last-child は :nth-last-child(1) の省略形です。
li:first-child:nth-last-child(1) { /* 和li:only-child等同 */}
もちろん、ここで 1 はパラメータであり、このパラメータは好みに応じて調整できます。 li:first-child:nth-last-child(4) で選択されたターゲットを推測できますか?リストの総数が 4 個の場合、:only-child の対象要素が選択されると答えるのは、少し楽観的すぎるかもしれません。実際にはそうではありませんが、正しい選択の目標にどんどん近づいています。それぞれ :first-child と :nth-last-child(4) という 2 つのセレクターを考えてみましょう。したがって、要素の最初の子からカウントが開始され、同時に 4 番目の子から最後の子までカウントされます。では、どの要素がこの範囲を満たすのでしょうか?
正解は、以下に示すように、4 要素リストの最初の要素のみが選択されていることです。
これは私たちが望む結果ではありませんが、必要な効果に非常に近いです。リスト内の最初の子要素を選択したので、ユニバーサル セレクター ( ~ ) を使用して、最初の子要素の後に隣接する兄弟要素を選択できます。このようにして、リストにリスト項目が 4 つしかない場合、すべてのリスト項目が選択されます。これはまさに私たちが達成しようとしていることです:
li:first-child:nth-last-child(4),li:first-child:nth-last-child(4) ~ li { /* 目标选择了仅有四个列表项的列表所有列表项 */}
コードの長くて反復的な解決策を回避するには、SCSS などのプリプロセッサを使用できます。既存のプリプロセッサ構文は図よりも不格好ですが:
/* 定义mixin */@mixin n-items($n) { &:first-child:nth-last-child(#{$n}), &:first-child:nth-last-child(#{$n}) ~ & {@content; }}/* 像这样使用 */li { @include n-items(4) { /* 这里写样式 */ }}
在大多数实际运用中,我们并不希望瞄准特定数量的列表,而是希望在一个范围内。有一个小技巧,我们可以使用 :nth-child() 选择器来指定一个选择范围。例如选择第四个之后的列表项。除了使用简单的数字作为参数之外,还可以使用 an+b 表达式作为参数(例如: :nth-child(2n+1) ),其中 n 是一个变量,范围是从 0 到 +∞ (实际上,值在某点不会选择任何东西,因为我们元素的数量是有限的)。如果我们使用一个表达式 n+b ( a 默认下是 1 ),那么,如果 n 不是一个正整数时可以给我们一个小于 b 值的范围。因此,表达式 n+b 可以用来第 b 个值为第一个子元素所有子元素。例如: :nth-child(n+4) 选择除了第一、第二、第三的所有子元素。如下图所示:
如果你不想为 :nth-* 选择器做过多的思考,你可以使用一个测试工具,我写了一个 在线的工具 ,足够你做测试。
我们可以利用这个功能来选择列表项是四个或更多的列表子元素,如下图所示:
在这种情况下,我们可以在 :nth-last-child() 使用 n+4 这个表达式:
li:first-child:nth-last-child(n+4),li:first-child:nth-last-child(n+4) ~ li { /* 目标列表选择最少包含四个列表项 */}
同样,表达式 -n+b 可以用来选择第 b 个元素。因此,选择仅有四个或更少的列表项的列表的所有子元素时,就可以使用这种表达式。
如上图所示,我们代码可以这样写:
li:first-child:nth-last-child(-n+4),li:first-child:nth-last-child(-n+4) ~ li { /* 选择列表项最多只有四个的列表所有子元素 */}
当然,我们可以结合这两个,但现在的代码变得更加笨拙。假设我们列表包含 2~6 项的列表所有子元素:
li:first-child:nth-last-child(n+2):nth-last-child(-n+6),li:first-child:nth-last-child(n+2):nth-last-child(-n+6) ~ li{ /*选择包含2-6个列表项的列表所有子元素*/}