CSS / clip / 古い矩形クリッピングとclip-pathへの移行

clipは、要素の可視部分を長方形に制限するレガシーCSSプロパティです。position: absoluteまたはposition: fixedを持つ要素に適用されますが、非推奨となっているため、新しいコードではclip-pathを使用することが推奨されます。既存コードを移行する際には、rect()の境界座標とinset()の内側距離を区別してください。

適用条件と主な値

クリッピングは、領域外の描画を隠します。これは、元の画像ファイルを編集したり、要素の幅や高さを実際に縮小することとは異なります。clip の初期値は auto であり、継承されません。position: relative のみを設定しても、従来のクリップは適用されません。

値または条件 意味と選択肢
auto このプロパティを通じてクリッピング矩形を適用しない。
rect(top, right, bottom, left) 長さまたは auto を使用して、上、右、下、左の境界を指定します。これは従来のコンマ区切り構文です。
position: absolute / position: fixed クリップの配置条件。例では position: absolute を使用しています。
clip-path: inset(20px) 各端から20px内側に矩形を表示します。これはフロー内要素にも使用できます。

従来の clip rect はパーセンテージを受け付けません。完全な値 clip: auto は rect(auto, auto, auto, auto) とも異なります。後者は内側の境界線でクリップするため、オーバーフローする子孫要素が違いを明らかにすることがあります。 MDN clip 構文および適用条件

完全な例で元の領域と切り抜き後を比較する

以下の完全なコードを clip-example.html として UTF-8 で保存し、ブラウザで開いてください。外部の画像、ライブラリ、サーバーは不要です。これらのデモ用スタイルは共有サイトのスタイルシートに貼り付けず、このファイル内に保持してください。3つのボックスすべてを比較し、1回に1つの値を変更して保存し、リロードしてください。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>clip と clip-path の比較</title>
  <style>
    body { margin: 0; padding: 16px; font: 16px/1.6 sans-serif; }
    main { max-width: 760px; margin: auto; }
    h1 { font-size: 1.5rem; }
    h2 { font-size: 1rem; }
    .samples { display: flex; flex-wrap: wrap; gap: 24px; }
    .frame { position: relative; width: 200px; height: 120px;
      background: #e5e7eb; outline: 1px solid #666; }
    .target { width: 100%; height: 100%; padding: 0; border: 0;
      background: linear-gradient(135deg, #006c9c, #ffd166); }
    .legacy { position: absolute; top: 0; left: 0;
      clip: rect(20px, 180px, 100px, 20px); }
    .modern { clip-path: inset(20px); }
  </style>
</head>
<body>
  <main>
    <h1>clip と clip-path の比較</h1>
    <div class="samples">
      <section><h2>clip: auto</h2>
        <div class="frame"><div class="target"></div></div></section>
      <section><h2>clip: rect(20px, 180px, 100px, 20px)</h2>
        <div class="frame"><div class="target legacy"></div></div></section>
      <section><h2>clip-path: inset(20px)</h2>
        <div class="frame"><div class="target modern"></div></div></section>
    </div>
  </main>
</body>
</html>

最初のボックスは参照用で、全体の 200×120px のグラデーションを表示します。2番目と3番目のボックスは、各辺から 20px を除外した後の 160×80px の領域を表示するはずです。灰色の背景とアウトラインは別のフレームに属するため、元のボックスサイズがそのまま表示されます。窓幅が狭い場合、比較用ボックスは別の行に折り返されます。

rectの座標をinsetの距離に変換する

これら二つの宣言は、数字が異なる意味を持つため、見た目上同じ領域を生成します。これらのルールは、完全な例の.legacyおよび.modernに対応しています。

.legacy {
  position: absolute;
  clip: rect(20px, 180px, 100px, 20px);
}
.modern {
  clip-path: inset(20px);
}

従来のrectでは、topとbottomは内側の上端の境界線から測定され、leftとrightは内側の左端の境界線から測定されます。right座標が180pxであるからといって、右側から180pxを取り除くという意味にはなりません。4つのinset値は、それぞれの辺から内側への距離を測定し、別の参照ボックスが指定されていない限りborder-boxを使用します。この例のターゲットにはパディングも境界線もないため、参照ボックスの違いは比較に影響しません。

エッジ rect境界座標 inset距離
上 20px 20px
右 180px 200 − 180 = 20px
下 100px 120 − 100 = 20px
左 20px 20px

パディングやボーダーのない幅W、高さHのボックスに対して、rect(t, r, b, l)はinset(t, W − r, H − b, l)に対応します。実際のCSSでは、W − rのような説明式をコピーせず、計算した長さを挿入してください。ボーダー、パディング、または異なる参照ボックスがある場合は、まず座標系を揃えてください。MDN clip-path 参照ボックスと形状

要素のサイズを変更して比較する

まず、完全な例の中で.frameだけを幅300px、高さ180pxに変更します。古いrectの座標をそのままにすると160×80pxの表示領域になりますが、inset(20px)だと大きいボックスの各辺から20pxを除外することで260×140pxになります。同じ数値でも同じクリップ結果にならない理由を比較してください。

両方の方法を再び一致させるために、.legacyの右境界を280px、下境界を160pxに変更します。完全な例の中でこれら2つのルールを以下のように置き換えます。.modernの宣言は変更せずにそのままにしてください。

.frame {
  width: 300px;
  height: 180px;
}
.legacy {
  clip: rect(20px, 280px, 160px, 20px);
}

両方の方法は現在、260×140pxの領域を残すはずです。比較後、.frame を 200×120px に、rect を 20px、180px、100px、20px に戻します。レスポンシブボックスで同じ内側の間隔を保持するには、固定境界を繰り返し再計算するよりも、inset の方が意図をより直接的に表現します。

クリッピングとレイアウト・アクセシビリティ

clip-path を使ったクリッピングは一般的に要素のレイアウトスペースを変更しません。例の .modern は 200×120px を占め、描画される領域のみが小さくなります。.legacy 要素は絶対配置のため通常のフローから外れています; 親の .frame が比較用のスペースを確保しています。クリッピング自体と配置効果を区別してください。

新しいコードでは、四角形の場合はinset、円の場合はcircleのようなclip-pathの形状を検討してください。はみ出したコンテンツを隠したりスクロールを提供することが目的の場合は、overflowの別の役割を考慮してください。none以外のclip-path値はスタッキングコンテキストを作成することもあるため、移行後に重なり合う要素を確認してください。クリッピングと要素のジオメトリにおけるCSSマスキング

クリッピングはアクセス制御やプライバシー保護ではありません。隠れたテキストはドキュメント内に残る可能性があり、支援技術による扱いは別途確認が必要です。ボタン、入力欄、重要な情報、キーボードのフォーカス表示を切り抜き、利用者の操作を妨げないようにしてください。ズーム時やタッチ・キーボードナビゲーション時にコンテンツを読む方法を提供してください。

適用されない場合や表示が異なる場合

  • 開発者ツールで選択した要素の計算済み位置とクリップを確認します。相対位置(relative)や静的位置(static)は、レガシークリップの条件を満たしません。この例では、.legacy の position を relative に変更して、クリップが消えるかどうかを比較し、その後 absolute に戻します。
  • 矩形の順序は上、右、下、左です。右が左より小さい場合、または下が上より小さい場合、期待される矩形は保持されません。幅や高さを変更した後、古い座標が保持されているか確認してください。
  • 親要素の overflow、clip-path、またはその他のクリップ規則によって、表示領域がさらに制限されることがあります。開発者ツールで宣言を個別に無効化・再有効化して、原因を特定してください。
  • clip を clip-path に置き換える際には、位置決め、参照ボックス、境界線、パディング、スタッキング、およびフォーカスインジケータを比較してください。clip で使用される従来の rect() と clip-path の新しい rect() 形状は構文が異なり、名前が一致しても値を互換にすることはできません。