CSS `mask-image` を使って要素の一部だけをはみ出して見せるテクニック
Webサイトのデザインにおいて、要素がその背景やコンテナから一部分だけはみ出しているような表現を使いたい場面があります。例えば、商品画像の上部だけが背景の上に飛び出しているようなデザインです。
参考:BOTANIST | フレグランスコレクション サクラとチェリーの香り
これを実現するために、画像を複数枚用意して重ねたり、overflow: hidden
を駆使したりする方法も考えられますが、CSSの mask-image
プロパティを使うことで、よりスマートかつ柔軟に実装できます。今回はその具体的な方法について解説します。
TL;DR
下記のようなMaskで再現する。
実現したい表現
以下のような、要素(ここではボトル画像を含む div
)が、そのコンテナや背景要素の上端から、一部分だけはみ出して表示される表現を目指します。
(ここに、ユーザーが提示した画像のようなスクリーンショットや図を挿入すると分かりやすいでしょう)
下の部分はコンテナの形状に沿っていますが、上部だけが自然にはみ出しています。
mask-image
と SVG の活用
実装方法: この表現の鍵となるのが CSS の mask-image
プロパティです。このプロパティを使用すると、指定した画像(アルファチャンネルを持つPNGやSVGなど)を使って、要素のどの部分を表示し、どの部分を隠す(透明にする)かを制御できます。
今回のケースでは、SVGをマスク画像として利用します。SVGを使うことで、複雑な形状のマスクをベクターデータとして定義でき、スケーラビリティにも優れています。
HTML構造(例)
まず、対象となる要素のHTML構造を見てみましょう。非常にシンプルです。
<div class="feature-container">
<!-- 背景要素など -->
<div class="feature-background"></div>
<!-- はみ出して見せたい要素 -->
<div class="feature-visual">
<div class="feature-visual-main">
<!-- マスクを適用する画像 -->
<img src="path/to/your/image.png" alt="Product Image">
</div>
<!-- 必要であれば浮遊する他の要素など -->
<div class="feature-visual-float-elements">
<!-- 例: さくらんぼの画像など -->
</div>
</div>
</div>
重要なのは、画像を2枚用意したり、特別なラッパー要素を追加したりする必要がない点です。
CSSスタイリング
次に、CSSを見ていきましょう。ポイントは、はみ出して見せたい要素(ここでは仮に .feature-visual-main
またはその親要素に適用)に position: absolute
などで位置を調整し、mask-image
で切り抜く部分を指定することです。
実際に使われていたCSSの例(クラス名を変更しています)を以下に示します。
.feature-visual {
position: relative; /* 子要素 absolute の基準点 */
z-index: 1; /* 背景より手前に表示 */
}
.feature-visual-main {
position: absolute;
/* 要素を上に20%ずらす */
top: -20%;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: auto; /* または適切な高さ */
/* --- ここからがマスク処理 --- */
/* SVGデータをマスク画像として指定 */
-webkit-mask-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 325 470"><path d="M323.38 0H1v338h.04a38.89 38.89 0 0 0 1.55 9.34c2.29 7.77 6.93 14.6 13.07 20.6 12.32 12.03 30.57 20.6 47.55 26.57 28.8 10.12 46.6 25.07 70.43 46.24 11.88 10.55 27.49 21.9 45.09 26.02 17.52 4.1 37.1 1.06 57.12-17.37 19.79-18.27 24.56-32.75 29.31-47.18v-.01l.02-.04c2.45-7.43 4.91-14.91 9.43-22.84 4.53-7.95 11.1-16.32 21.75-25.6 18.74-16.32 26.7-35.75 27.01-55.23h.01V0Z"/></svg>');
mask-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 325 470"><path d="M323.38 0H1v338h.04a38.89 38.89 0 0 0 1.55 9.34c2.29 7.77 6.93 14.6 13.07 20.6 12.32 12.03 30.57 20.6 47.55 26.57 28.8 10.12 46.6 25.07 70.43 46.24 11.88 10.55 27.49 21.9 45.09 26.02 17.52 4.1 37.1 1.06 57.12-17.37 19.79-18.27 24.56-32.75 29.31-47.18v-.01l.02-.04c2.45-7.43 4.91-14.91 9.43-22.84 4.53-7.95 11.1-16.32 21.75-25.6 18.74-16.32 26.7-35.75 27.01-55.23h.01V0Z"/></svg>');
/* マスクの位置を下中央に設定 */
-webkit-mask-position: center bottom;
mask-position: center bottom;
/* マスク画像を繰り返さない */
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
/* マスク画像のサイズを要素の幅に合わせ、高さは自動調整 */
-webkit-mask-size: 100% auto;
mask-size: 100% auto;
}
/* 背景要素は背面に配置 */
.feature-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%; /* または適切な高さ */
z-index: 0;
/* 背景色や背景画像など */
}
ポイント解説:
-
position: absolute
とtop: -20%
: これにより、.feature-visual-main
要素が通常の配置から上にずれます。 -
mask-image
: ここでインラインSVGを指定しています。SVG内の<path>
で描画された領域が「見える」部分となり、それ以外の部分は透明になります。このSVGの形状が、要素の下部を切り取る形になっています。 -
mask-position
,mask-repeat
,mask-size
: マスク画像(SVG)を要素の下端中央に、繰り返さずに、要素の幅いっぱいに合わせて配置する設定です。これにより、上にずれた要素の下部だけがSVGの形状で切り取られます。
この方法のメリット
- HTMLがシンプル: 画像を重ねたりする必要がなく、構造がクリーンに保てます。
-
柔軟性: マスクの形状を変えたい場合、SVGの
path
を修正するだけで済みます。 - パフォーマンス: 画像を複数読み込む必要がないため、パフォーマンス面でも有利な場合があります。
- スケーラビリティ: マスクにSVGを使用しているため、拡大・縮小してもマスクの境界が綺麗です。
注意点
-
mask-image
プロパティは比較的新しい機能であり、一部の古いブラウザではサポートされていない可能性があります。Can I use...
などで対応状況を確認し、必要に応じてベンダープレフィックス (-webkit-mask-image
など) を付与したり、フォールバックを検討したりしてください。 - インラインSVGはコードが長くなりがちですが、HTTPリクエストを削減できるメリットがあります。外部SVGファイルとして読み込むことも可能です。
まとめ
CSSの mask-image
プロパティとSVGを組み合わせることで、要素の一部だけがはみ出して見えるような複雑な視覚効果を、スマートかつ柔軟に実現できます。画像編集ソフトで事前に加工したり、複雑なHTML構造を用意したりすることなく、CSSだけで高度なデザイン表現が可能になります。ぜひ試してみてください。
Discussion