Webデザインの表現を一段引き上げたいときに便利なのが「mask-image」です。画像やグラデーションを使って表示範囲をコントロールすることで、単純なレイアウトでは出せない洗練された演出を実現できます。
mask-imageは、要素の「見せる部分」と「隠す部分」を定義するためのCSSプロパティで、透明度をベースに表示を制御するのが特徴です。黒・白・グラデーションを使い分けることで、フェードや切り抜きなど柔らかい表現が可能になります。
画像だけでなく、linear-gradientやradial-gradientなどのCSS生成画像もマスクとして利用できるため、コードだけで複雑なデザインを再現できるのも大きなメリットです。
この記事では、mask-imageの基本的な使い方から、実務で活用できる具体的なテクニックまでを分かりやすく解説していきます。
CSSのmaskとは
mask は要素に対してマスク画像の種類、配置、サイズ、繰り返し、基準ボックスなどをまとめて設定する
一括指定プロパティ です。mask は
mask-image、mask-mode、mask-position、mask-repeat、mask-size、mask-origin、mask-clip、mask-composite
をまとめる形として整理されています。つまり、.card { mask: ...; } のように セレクタの中で使う値 が mask です。
似た見た目を作る手段に clip-path がありますが、役割は同じではありません。clip-path
は境界の内外をはっきり切るのに向いており、mask は半透明やグラデーションを使った やわらかい消え方
まで扱えます。画像の一部をぼかし気味に見せたい、端だけフェードさせたい、ロゴ形状で切り抜きたいという場面では mask のほうが自然です。
| 構成要素 | 役割 | 先に触るべきか |
|---|---|---|
mask-image |
何をマスクとして使うかを決める | 最優先 |
mask-mode |
透明度で読むか、輝度で読むかを決める | 画像ソースで挙動が変わるときに確認 |
mask-position / mask-size / mask-repeat |
配置、縮尺、繰り返しを決める | 見え方がズレたら確認 |
mask-origin / mask-clip |
どのボックスを基準に置くか、どこまで描くかを決める | padding や border がある要素で重要 |
最初に試しやすい4つの mask-image
最初の段階では、mask 全体を一気に覚える必要はありません。まずは 何をマスク画像として使えるか を押さえると理解が進みます。
特に CSS だけで検証しやすいのは
radial-gradient()、linear-gradient()、repeating-linear-gradient()、url()
の4つです。
使いどころはそれぞれ異なります。丸く見せたいなら radial-gradient()、端をやわらかく消したいなら
linear-gradient()、縞や穴を等間隔で並べたいなら repeating-linear-gradient()、形を固定したいなら SVG 画像を
url() で渡す書き方が向いています。注意点は、マスクの色そのものではなく、透明度や明るさが効く
ことです。色だけ変えても、mask-mode の扱いを理解していないと結果を読み違えます。
radial-gradient()
中心だけ見せる
丸い切り抜きでアバターやアイキャッチに向きます。
linear-gradient()
左端をフェード
横スクロールやカルーセルの端を自然に消せます。
repeating-linear-gradient()
縞状に抜く
装飾帯やパターン穴あけに使いやすいです。
url()
SVG 形状で固定
ロゴやアイコン形状をそのままマスクに使えます。
<!-- HTML -->
<div class="demo-mask-card demo-mask-card--radial"></div>
<div class="demo-mask-card demo-mask-card--edge"></div>
<div class="demo-mask-card demo-mask-card--stripe"></div>
<div class="demo-mask-card demo-mask-card--star"></div>
/* CSS */
.demo-mask-card--radial {
-webkit-mask-image: radial-gradient(circle at center, #000 0 52%, transparent 53% 100%);
mask-image: radial-gradient(circle at center, #000 0 52%, transparent 53% 100%);
}
.demo-mask-card--edge {
-webkit-mask-image: linear-gradient(90deg, transparent 0 14%, #000 34% 100%);
mask-image: linear-gradient(90deg, transparent 0 14%, #000 34% 100%);
}
.demo-mask-card--stripe {
-webkit-mask-image: repeating-linear-gradient(135deg, #000 0 18px, transparent 18px 34px);
mask-image: repeating-linear-gradient(135deg, #000 0 18px, transparent 18px 34px);
}
.demo-mask-card--star {
-webkit-mask-image: url("data:image/svg+xml,...");
mask-image: url("data:image/svg+xml,...");
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: 72%;
mask-size: 72%;
}
mask-image と mask-mode で透明度の読み方を理解する
mask-image でソースを決めても、どう評価して見せるか は mask-mode で変わります。
mask-image の既定値の match-source は多くの画像ソースで alpha として解決され、SVG の
<mask> を参照したときだけ luminance
になるケースがあると整理されています。ここを曖昧にすると、「同じ色を置いたのに見え方が違う」と感じやすくなります。
alpha は 透明度だけ を見ます。黒でも白でも不透明なら同じように見えます。一方の luminance は 明るさ ×
透明度 で評価されるため、白は強く見え、黒は消え、色付きでも明るい色ほど残ります。グラデーションや SVG マスクの調整がうまくいかないときは、まず mask-mode
を明示して期待と一致しているか確認してください。
alpha と luminance を4例で比べる
次の4例では、前半2つを alpha、後半2つを luminance にしています。役割は 透明度だけで消すか、明るさまで使って消すか
の違いを目で確認することです。使いどころとしては、PNG やグラデーションの透過量をそのまま使いたいなら alpha、白黒や明度差のある画像をマスクとして流用したいなら
luminance が自然です。注意点は、luminance にすると 色そのものが濃いか薄いか
で見え方が変わるため、ブランドカラー画像をそのままマスクにすると想定より薄く見えることです。
alpha
不透明な円
黒でも白でも、不透明なら同じ強さで表示されます。
alpha
半透明の縞
アルファ値だけで見え方が段階化します。
luminance
白が残って黒が消える
白黒グラデーションをマスクとして使う典型です。
luminance
明るい色ほど残る
白、金、紫で残り方の差が見えます。
<!-- HTML -->
<div class="demo-mask-card demo-mask-card--alpha-solid"></div>
<div class="demo-mask-card demo-mask-card--alpha-soft"></div>
<div class="demo-mask-card demo-mask-card--lum-bw"></div>
<div class="demo-mask-card demo-mask-card--lum-color"></div>
/* CSS */
.demo-mask-card--alpha-solid {
-webkit-mask-image: radial-gradient(circle at center, rgb(0 0 0 / 1) 0 46%, transparent 58% 100%);
mask-image: radial-gradient(circle at center, rgb(0 0 0 / 1) 0 46%, transparent 58% 100%);
-webkit-mask-mode: alpha;
mask-mode: alpha;
}
.demo-mask-card--alpha-soft {
-webkit-mask-image: repeating-linear-gradient(135deg, rgb(0 0 0 / 1) 0 20px, rgb(0 0 0 / 0.45) 20px 40px, transparent 40px 60px);
mask-image: repeating-linear-gradient(135deg, rgb(0 0 0 / 1) 0 20px, rgb(0 0 0 / 0.45) 20px 40px, transparent 40px 60px);
-webkit-mask-mode: alpha;
mask-mode: alpha;
}
.demo-mask-card--lum-bw {
-webkit-mask-image: linear-gradient(90deg, black 0 26%, white 26% 74%, black 74% 100%);
mask-image: linear-gradient(90deg, black 0 26%, white 26% 74%, black 74% 100%);
-webkit-mask-mode: luminance;
mask-mode: luminance;
}
.demo-mask-card--lum-color {
-webkit-mask-image: linear-gradient(90deg, rebeccapurple 0 33%, gold 33% 66%, white 66% 100%);
mask-image: linear-gradient(90deg, rebeccapurple 0 33%, gold 33% 66%, white 66% 100%);
-webkit-mask-mode: luminance;
mask-mode: luminance;
}
mask-position と mask-size と mask-repeat で配置を制御する
見え方の大半は mask-image で決まりますが、実務で詰まりやすいのは配置系です。mask-position と mask-size
で置き方を調整できることが例付きで説明されています。星型やロゴ型のようにサイズが固定された画像を使う場合は、ここを省略すると意図せずタイル状に並びやすくなります。
判断の順番は単純です。まず 繰り返すのか、1個だけ置くのか を決め、次に どこへ置くのか、最後に どの大きさで置くのか
を決めます。mask の一括指定でまとめてもかまいませんが、最初は
mask-image、mask-position、mask-size、mask-repeat
を分けて書いたほうが原因切り分けはしやすいです。
位置・サイズ・繰り返しの違いを4例で見る
次の4例は、同じ星型マスクでも配置系だけで印象が変わることを確認するためのものです。中央固定はアイコン風、右下オフセットは角バッジ風、contain
は枠いっぱいに形を保ちたい場面、repeat-x は帯状装飾に向いています。注意点は、小さい SVG を no-repeat
なしで置くと意図しない連続模様になる ことです。単発表示にしたいなら、mask-repeat: no-repeat と mask-size
の明示を先に入れてください。
center + no-repeat
中央固定
アイコンやサムネイルの主役位置を作れます。
offset
右下オフセット
角の演出や通知バッジのような見せ方に向きます。
contain
枠内に収める
縦横比を保ったまま全体像を優先できます。
repeat-x
横方向に並べる
区切り線や帯装飾を CSS だけで作れます。
<!-- HTML -->
<div class="demo-mask-card demo-mask-card--pos-center"></div>
<div class="demo-mask-card demo-mask-card--pos-offset"></div>
<div class="demo-mask-card demo-mask-card--size-contain"></div>
<div class="demo-mask-card demo-mask-card--repeat-row"></div>
/* CSS */
.demo-mask-card--pos-center {
-webkit-mask-image: url("data:image/svg+xml,...");
mask-image: url("data:image/svg+xml,...");
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-size: 108px 108px;
mask-size: 108px 108px;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
.demo-mask-card--pos-offset {
-webkit-mask-position: right 12px bottom 12px;
mask-position: right 12px bottom 12px;
-webkit-mask-size: 84px 84px;
mask-size: 84px 84px;
}
.demo-mask-card--size-contain {
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
.demo-mask-card--repeat-row {
-webkit-mask-size: 46px 46px;
mask-size: 46px 46px;
-webkit-mask-repeat: repeat-x;
mask-repeat: repeat-x;
}
mask-clip と mask-origin で基準ボックスを切り替える
padding や border がある要素にマスクをかけるときは、mask-position だけでは足りません。mask-origin は
どのボックスを基準に位置を計算するか、mask-clip は どこまで描画を許すか を決めます。
mask-position と mask の説明でも、これらが一括指定の一部として扱われています。普段のカード UI なら、content、padding、border
のどこを残したいかで選ぶのが分かりやすいです。
見分け方は単純です。content-box は本文だけ残したいとき、padding-box は余白込みで残したいとき、border-box
は外枠までそのまま見せたいときに向いています。注意点は、mask-origin と mask-clip を同じ値にしなくてもよいことです。位置計算だけ
content-box にし、描画範囲は border-box にするというように、基準と表示範囲を分離 できます。
ボックス基準の違いを4例で確認する
次の4例では、前半3つを同じベタ塗りマスクで比べ、最後だけ mask-origin と mask-clip を分離しています。役割は、padding と border
がある要素で どこまで残るか を視覚化することです。フォーム部品やカードコンポーネントで「border
まで見せたいのに中身だけ抜けた」といった事故は、この指定を理解すると防ぎやすくなります。
content-box
本文だけ残る
padding と border を消したいときの基準です。
padding-box
余白込みで残る
内側の余白を含めて見せたいときに向きます。
border-box
外枠まで残る
カード全体をそのまま見せる基準です。
origin と clip を分離
位置は内側、描画は外側
ロゴだけ内側基準で置きたい場面に使えます。
<!-- HTML -->
<div class="demo-box-mask demo-box-mask--content">...</div>
<div class="demo-box-mask demo-box-mask--padding">...</div>
<div class="demo-box-mask demo-box-mask--border">...</div>
<div class="demo-box-mask demo-box-mask--mixed">...</div>
/* CSS */
.demo-box-mask--content {
-webkit-mask-image: linear-gradient(#000 0 0);
mask-image: linear-gradient(#000 0 0);
-webkit-mask-origin: content-box;
mask-origin: content-box;
-webkit-mask-clip: content-box;
mask-clip: content-box;
}
.demo-box-mask--padding {
-webkit-mask-origin: padding-box;
mask-origin: padding-box;
-webkit-mask-clip: padding-box;
mask-clip: padding-box;
}
.demo-box-mask--border {
-webkit-mask-origin: border-box;
mask-origin: border-box;
-webkit-mask-clip: border-box;
mask-clip: border-box;
}
.demo-box-mask--mixed {
-webkit-mask-image: url("data:image/svg+xml,...");
mask-image: url("data:image/svg+xml,...");
-webkit-mask-origin: content-box;
mask-origin: content-box;
-webkit-mask-clip: border-box;
mask-clip: border-box;
-webkit-mask-position: right bottom;
mask-position: right bottom;
-webkit-mask-size: 94px 94px;
mask-size: 94px 94px;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
複数レイヤーと実務上の注意点をまとめて押さえる
mask はカンマ区切りで複数レイヤーを書けます。1枚の画像だけでは表現しにくいときでも、星形を左右に2つ置く、中央の円と全体フェードを重ねるといった構成を CSS
だけで作れます。その代わり、レイヤー数が増えるほど 位置、サイズ、繰り返しの値も同じ順序で増える
ため、管理が雑だと一気に読みにくくなります。複数レイヤーにした時点で、mask-position や mask-size を省略しないほうが安全です。
互換性については、古いデバイスやブラウザでは動かない可能性があります。2026年4月時点で主要ブラウザの最新系は概ね対応していますが、古い Safari や古い Chromium
系には部分対応の期間があります。そのため、実務では -webkit-mask-* の併記
と、マスクが効かなくても読める見た目のフォールバックを残す判断が妥当です。また、mask-image には、URL 画像は HTTP/HTTPS
で配信されたものしか受け付けず、file:// では透明な黒として扱われるケースがあるとあります。ローカル検証では data URI かローカルサーバーを使ってください。
複数レイヤーと安全運用の4パターン
最後の4例は、複数レイヤーの基本形と実務での安全策をまとめたものです。役割は、mask
を実際の案件へ持ち込むときに崩れやすい箇所を先に潰すことです。2つの星を別位置に置く例と、円とフェードを重ねる例でレイヤーの考え方を確認し、残り2つで 一括指定の書き方 と
data URI を使ったローカル検証 を押さえます。注意点は、1行の mask: にまとめた瞬間に他の mask-*
が上書きされることです。途中で mask-repeat だけ別に書き足すつもりなら、どのレイヤーの何番目へ効かせたいのかを意識してください。
multiple layers
左右に2つ置く
同じマスク画像でも位置だけ変えて重ねられます。
multiple layers
円とフェードを重ねる
中央強調と全体の消え方を分離できます。
shorthand
一括指定で明示する
no-repeat とサイズを一緒に固定して事故を減らします。
data URI
ローカル検証しやすい
file:// 問題を避けやすく、サンプル共有にも便利です。
<!-- HTML -->
<div class="demo-mask-card demo-mask-card--layers-double"></div>
<div class="demo-mask-card demo-mask-card--layers-mixed"></div>
<div class="demo-mask-card demo-mask-card--safe"></div>
<div class="demo-mask-card demo-mask-card--data-uri"></div>
/* CSS */
.demo-mask-card--layers-double {
-webkit-mask-image: url("data:image/svg+xml,..."), url("data:image/svg+xml,...");
mask-image: url("data:image/svg+xml,..."), url("data:image/svg+xml,...");
-webkit-mask-position: left 18px center, right 18px center;
mask-position: left 18px center, right 18px center;
-webkit-mask-size: 72px 72px, 72px 72px;
mask-size: 72px 72px, 72px 72px;
-webkit-mask-repeat: no-repeat, no-repeat;
mask-repeat: no-repeat, no-repeat;
}
.demo-mask-card--layers-mixed {
-webkit-mask-image: radial-gradient(circle at center, #000 0 42%, transparent 43% 100%), linear-gradient(180deg, #000 0 58%, transparent 82% 100%);
mask-image: radial-gradient(circle at center, #000 0 42%, transparent 43% 100%), linear-gradient(180deg, #000 0 58%, transparent 82% 100%);
}
.demo-mask-card--safe {
-webkit-mask: url("data:image/svg+xml,...") center / 92px 92px no-repeat;
mask: url("data:image/svg+xml,...") center / 92px 92px no-repeat;
}
.demo-mask-card--data-uri {
-webkit-mask-image: url("data:image/svg+xml,...");
mask-image: url("data:image/svg+xml,...");
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
ここまでを整理すると、mask は
何をマスクに使うか、どう読むか、どこへ置くか、どのボックス基準で描くか
の4段階で考えると混乱しにくくなります。最初は mask-image と mask-repeat、mask-size を明示し、次に
mask-mode と mask-position、必要になったら mask-origin と mask-clip
へ進む流れが安全です。mask をセレクタと呼ばず、一括指定プロパティとして整理しておくと、どの値をどこで調整すべきかが見えやすくなります。
まとめ
mask は見た目の装飾というより、表示の制御を柔軟に行うための仕組みです。重要なのは、個々のプロパティを単体で覚えるのではなく、役割ごとに整理することです。
- 何を使うか:
mask-image(gradient / SVG / 画像) - どう評価するか:
mask-mode(alpha / luminance) - どう配置するか:
mask-position/mask-size/mask-repeat - どの範囲で描画するか:
mask-origin/mask-clip
実務ではまず mask-image と mask-repeat、mask-size を明示し、意図しない繰り返しやサイズ崩れを防ぐことが基本になります。そのうえで、見え方に違和感があれば mask-mode を確認し、レイアウト上のズレがあれば配置系、さらに複雑なケースでボックス基準を調整します。
また、複数レイヤーや一括指定を使う場合は、各レイヤーごとの値の対応関係が崩れやすくなるため、省略せず明示することが安定した実装につながります。加えて、-webkit-mask-* の併記やフォールバックを用意しておくことで、環境差による崩れも抑えられます。
この順序で整理しておくと、見た目が崩れたときも「どの段階の問題か」を切り分けやすくなり、調整コストを抑えられます。