タグ: CSS

  • CSSのセレクタで、「最後以外」と指定する

    たとえば要素を「最後以外」すべてにスタイルを適用したい場合は、以下のように :not(:last-child) を使う方法が一般的です。

    /* リストの最後以外の li 要素を選択する例 */
    li:not(:last-child) {
      margin-bottom: 10px;
    }

    li:not(:last-child) は、「li 要素」のうち「最後の子どもではないもの」をすべて選択します。

    同様に、「最後の要素」にのみ適用したい場合は、:last-child を使います。

    (類似の方法として、:nth-last-child(n+2) を利用するやり方もありますが、通常は :not(:last-child) が分かりやすいです。)

    ブラウザ対応状況については、ほとんどのモダンブラウザで :not(:last-child) が利用できます。一方で、かなり古いブラウザを考慮する必要がある場合は、JavaScriptや別の方法で対処する必要があります。一般的には、現在の開発環境で問題なく使用できるケースが多いでしょう。

  • CSSにおける「ボーダー衝突 (border conflict)」とは何か?

    「ボーダー衝突 (border conflict)」は、HTML テーブルなどで複数のセルや要素が接する部分において、どの境界線のスタイル・太さ・色が最終的に採用されるかを決定するルールです。特に、border-collapse: collapse; を適用したテーブルでは隣接するセル同士のボーダーを“重ねて”扱うため、同じ位置(辺)に対して複数のスタイルが競合します。このとき、どのボーダーを使うかを定義したのが「ボーダー衝突解決ルール (border conflict resolution)」です。


    ボーダー衝突が発生する典型的なケース

    テーブル要素

    HTML の <table> 要素に CSS で border-collapse: collapse; を指定した場合に、セル(<td> や <th>)同士が接する部分でボーダーが衝突します。例えば、下のセルの上側のボーダーと上のセルの下側のボーダーが同じ位置に重なります。

    隣接要素同士

    テーブル以外でも、フレキシブルボックスやグリッドレイアウトなど要素同士が隣接しており、境界線をいずれも持つ場合には衝突が起こり得ます。ただし、一般的にはテーブルで用いられることが多く、CSS 仕様上もテーブルモデルにおける衝突解決がメインで記載されています。


    「ボーダー衝突解決ルール (border conflict resolution)」の背景

    • 元々、HTML4 + CSS2.1 の仕様からテーブルモデルは複雑でした。border-collapse: collapse; のときにはセルの間のボーダーを1本にまとめて描画するため、もし各セルがバラバラに異なるスタイルを指定していると、どのセルのボーダースタイルが最終的に優先されるか を決めなければなりません。
    • これを明確化したのが CSS2.1 や CSS Table Module Level 3 などに記載されているボーダー衝突解決ルールです。

    ボーダー衝突解決の流れ

    CSS2.1 の仕様や最新版の CSS テーブルモジュール仕様では、衝突したボーダーを選択する際に以下の手順を踏みます。
    (実装の都合上、ブラウザによって若干解釈が異なることはありますが、基本的には同じ優先順位の考え方を採用しています。)

    1. border-style(ボーダースタイル)の優先順位を比較
      ボーダースタイルは以下のように「強さ」が定義され、強い方が優先されます。
      1. hidden (最優先:非表示にするが衝突対象としては最も強いスタイル)
      2. double
      3. solid
      4. dashed
      5. dotted
      6. ridge
      7. outset
      8. inset
      9. groove
      10. none (最下位:そもそも表示しないが衝突対象としては最も弱いスタイル)
    • もし衝突するボーダーに hidden と他の何らかのスタイルがある場合、hidden の方が優先され、“ボーダーは描画されない”という結果になります。
    • 逆に両方とも none の場合は描画されません。
    1. 同一スタイルの場合は太さ (border-width) を比較
      ボーダースタイルが同じであれば、次は太さ(border-width)が太い方が優先されます。
      • border-width はキーワード(thin, medium, thick)や具体的な長さ(1px, 2px, など)で指定されます。
      • どちらも同じ太さなら次の判定へ進みます。
    2. 同一スタイル・同一太さの場合は「原点」を比較
      上記 1・2 の結果でも決着がつかない場合は、仕様上「セルや行グループを起点にしているボーダーが優先される」などの細かなルールがあります。代表的なものとしては、下記のような原則が挙げられます(CSS2.1 ではこれらのルールが複数段階に分かれて書かれています)。
      • セル自身 (td, th) のボーダー指定が、そのセルを含む行(tr や thead, tbody, tfoot など)のボーダー指定より優先される。
      • さらに行グループより外側(table 要素や外側の要素)で指定しているボーダーはより優先度が低い。
      • つまり内側の要素の指定ほど優先される と捉えるとわかりやすいです。
    3. 最終的に同じなら上/左が優先される場合もある
      それでも決着がつかないレアケースでは、上側または左側(左から右への書字方向の場合)のボーダーを優先するといったルールが残されています。ただし、このレベルの衝突は実際にはほとんど起こりません。

    ボーダー衝突解決ルールの具体例

    例1: セル同士で異なるスタイルが指定されている場合

    <table style="border-collapse: collapse;">
      <tr>
        <td style="border: 2px solid red;">セル1</td>
        <td style="border: 3px dotted blue;">セル2</td>
      </tr>
    </table>
    • セル1の右辺とセル2の左辺が衝突する。
    • solid と dotted では、CSS 仕様では solid の方が dotted より強いわけではありません(優先度のリストを見ても solid は dotted より上にある)。
      よって、この場合はまずスタイル優先度比較で solid > dotted となり、solid が勝つ。
    • 仮にここでスタイルが同じだったら次はボーダーの太さ 2px vs 3px で比較し、3px の方が優先される、という流れになる。

    ポイント: スタイル比較 → 太さ比較 → (同一なら) 内側要素の指定 → (さらに同一なら) 上/左優先


    例2: 隣接するセルの片方だけにボーダー指定がある場合

    <table style="border-collapse: collapse;">
      <tr>
        <td style="border: none;">セル1</td>
        <td style="border: 1px solid black;">セル2</td>
      </tr>
    </table>
    • セル1の右辺は none、セル2の左辺は solid。
    • スタイル優先度としては none が最下位、solid が上位なので、solid が描画される。

    例3: 上下セルが同一スタイル・同一太さだが色が違う

    <table style="border-collapse: collapse;">
      <tr>
        <td style="border-bottom: 2px solid red;">上セル</td>
      </tr>
      <tr>
        <td style="border-top: 2px solid blue;">下セル</td>
      </tr>
    </table>
    • border-collapse: collapse; なので、上セルの下辺と下セルの上辺が同じ場所で衝突。
    • スタイルはどちらも solid で、太さも 2px で同一。
    • すると次の優先順位として「セル自身の指定に違いがあるか、上セルの方か下セルの方か」などが考慮されますが、実際の多くのブラウザ実装では上側のボーダー(上セルの border-bottom)が優先されたり、CSS 仕様上も「同一なら上/左優先」となる場合があります。
    • 結果として描画される色は赤になる(実際のブラウザ挙動は実装差がまれにあるが、標準的には上/左優先ルールで赤)。

    border-collapse: separate; の場合との違い

    • border-collapse: separate; はセル同士のボーダーをそれぞれ独立して描画するため、衝突は起こりません。セルとセルの間に “ボーダー間隔 (border-spacing)” が設定され、それぞれのセルのボーダーがバラバラに見えます。
    • そのため、競合による優先順位の判定はなく、単に各セルの境界線がそのまま表示されます。結果としてデザインのイメージが全く異なるものになります。

    ボーダー衝突ルールが必要な主な理由

    デザインの一貫性
    テーブルの枠線を統一感あるデザインにしたい場合に、セルごとにボーダーを自由に指定できると混乱を招きやすいため、一定の優先順位を与えて整理する必要があります。
    複数指定の整合性
    古い HTML4/CSS2.1 の時代から、ユーザースタイルシート、作者スタイルシート、UA スタイルシートなどの複数のソースでボーダーが指定されることがあります。どの指定を最終的に採用するかの明確化が必要です。
    ブラウザ間互換性の確保
    ブラウザがそれぞれ好き勝手に実装すると描画がバラバラになり、開発者や利用者が困るため、CSS 仕様に「どのスタイルが優先されるか」をしっかり定めてあります。

    ボーダー衝突解決を利用する上での注意点

    hidden は最も強力
    hidden は描画しないにもかかわらず、衝突判定では最優先されます。たとえば上セルのボーダーが hidden で、下セルが solid の場合は最終的に “何も表示されない” という結果になります。
    実際のブラウザ実装差
    理論上は仕様が定義しているものの、実際には古いブラウザや特定のレンダリングエンジンによって微妙な差が生じることがあります。通常のユースケースでは大差ありませんが、細かい見た目の差異に注意が必要な場合は念入りにテストを行うとよいです。
    複雑なテーブルではわかりづらい
    border-collapse: collapse; とさまざまなセルに異なるスタイルが混在しているテーブルでは、どのボーダーが表示されるかを把握するのが難しくなることがあります。そこまで複雑になる場合は、デザイン仕様を簡素化して border-collapse: separate; に切り替える か、または “テーブルを使わずにレイアウトを行う” などのアプローチを検討するのも一案です。

    まとめ

    • ボーダー衝突 (border conflict) とは: 特に border-collapse: collapse; を用いたテーブルで、隣接するセル間のボーダーがどちらの指定を採用するかを定めるルール。
    • 解決手順の要点:
      1. ボーダースタイルの強さ (hidden → double → solid → dashed → dotted → … → none) を比較。
      2. 同じスタイルなら border-width (太さ)を比較。
      3. まだ同じなら、内側の要素の指定を優先し、それでも同じなら上/左優先ルールを適用。

    この仕組みによって、同じ位置に複数のボーダー指定があったとしても、最終的にどのボーダーを採用するかを一貫して決定 できるようになっています。テーブルにおけるデザインを厳密にコントロールしたい場合や、UI の微調整をしたい場合に知っておくと非常に役立つ知識です。


    HTML (HyperText Markup Language)
    ウェブページの基本的な構造を作成します。見出し、段落、リンク、画像などの要素を定義します。
    table 要素
    行と列で構成された表形式のデータを表示する。
    tbody 要素
    テーブルを構造化するために使用される要素の一つです。
    td 要素
    テーブルのデータ・セル
    tfoot 要素
    テーブルのフッター行グループ
    th 要素
    テーブル(表)の見出しセルを作成する。
    thead 要素
    テーブル(表)の見出し部分を定義する。
    tr 要素
    表の行を表します。
    グローバル属性
    style 属性
    要素に CSS を直接指定するための属性。
    CSS (Cascading Style Sheets)
    ウェブページのデザインやレイアウトを設定します。色、フォント、レイアウトなどのスタイルを指定します。
    Flexbox
    コンテナ内のアイテムの配置、方向、順序を柔軟に管理できるレイアウトモデルです。
    Grid layout
    グリッドレイアウトは、Webページのコンテンツを行と列に分割して配置するための強力かつ柔軟なレイアウトシステムです。
    border
    ボックスの上下左右のボーダー(境界)のスタイル・太さ・色に対して同じ値をまとめて指定することができます。
    border-bottom
    要素の下端に線(ボーダー)を指定して、色・太さ・線の種類などを設定できるプロパティです。
    border-collapse
    セルの枠線(ボーダー)の表示の仕方を指定する。
    border-spacing
    セルのボーダーの間隔を指定する。
    border-style
    ボーダーのスタイルを一括指定する。
    border-top
    上側のボーダーのみの色・太さ・スタイル
    border-width
    ボーダーの太さを一括指定する。