CSS

mask-image lets you “cut out” what part of an element is visible by using an image or a gradient, where the transparency controls how much you can see.

mask-image

mask-image は「要素の見える部分だけを“型抜き”するための画像(またはグラデーション)を指定して、透明〜不透明の濃さで“どこをどれだけ見せるか”をコントロールできる機能」です。

mask-image の全体像

clip-path が「線でバッサリ切る(内側だけ残す)」だとしたら、mask-image は「透明度で“じわっと”切る(薄いところは半分だけ見せる)」ができます。

マスクの“白っぽい(不透明)”ところ
よく見える
マスクの“黒っぽい(透明)”ところ
見えない
その間のグレー
半透明(ちょっと見える)

この「途中の薄さ」を使えるのが、デザイン的にかなり強いです。ぼかし・フェード・くり抜き文字・模様の透過などが、画像加工なしでCSSだけでできます。

何が指定できる?(画像だけじゃない)

mask-image は「マスクに使う素材」を指定します。

“画像を用意しないと無理”ではなく、まずグラデーションだけで練習できます。これが初心者にとってかなり助かります。

最小の書き方(まずこれだけでOK)

次のコードだけで、「上が見えて下に行くほど消える」を作れます。

ここにテキストや画像が入ります。
下に行くほどフェードして消えるイメージ。

HTML

<div class="maskFade">
	ここにテキストや画像が入ります。<br>
	下に行くほどフェードして消えるイメージ。
</div>

CSS

.maskFade {
    padding: 24px;
    background: linear-gradient(135deg, #222, #666);
    color: #fff;
    font-size: 18px;
    line-height: 1.8;

    /* これが本体:下に行くほど透明になるマスク */
    mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
}

ここで大事な感覚

「マスクが効かない」あるある(最初につまずくポイント)

ブラウザ対応(特にSafari)

Safari系は、プレフィックス付きの -webkit-mask-* を要求する場面がまだあります。実務では“両方書く”のが安全です。

CSS

.target {
    -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
    mask-image: linear-gradient(to bottom, #000, transparent);
}

画像URLの指定は「見える場所から」読まれる

CSSファイルからの相対パスは、HTMLではなく「CSSファイルの場所」基準です。

CSS

.target {
    -webkit-mask-image: url("./masks/splash.png");
    mask-image: url("./masks/splash.png");
}

マスク画像が表示より小さいと“敷き詰め”されることがある

デフォルト挙動(繰り返し/位置/サイズ)で「あれ?変な模様が並ぶ…」になりがちです。そこで次の3点セットが超重要です。

実用でよく使う “3点セット”

「1枚のマスク画像で、中央に1回だけ置いて、要素いっぱいに広げる」例です。

CSS

.card {
    width: 320px;
    height: 200px;
    background: url("./img/photo.jpg") center / cover no-repeat;

    -webkit-mask-image: url("./mask/ink.png");
    mask-image: url("./mask/ink.png");

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-position: center;
    mask-position: center;

    -webkit-mask-size: cover;
    mask-size: cover;
}

mask-size の考え方(超ざっくり)

cover
要素を覆い尽くすまで拡大(はみ出しOK)
contain
全部入るように縮小(余白が出ることあり)
数値
mask-size: 120% 120%; みたいに自由

画像マスクとグラデーションマスクの使い分け

グラデーションが強い場面

画像が強い場面

ちょっと気持ちいい例:スポットライト(中心だけ見せる)

HTML

<div class="spot">
    <img src="./img/photo.jpg" alt="">
</div>

CSS

.spot {
    width: 360px;
    border-radius: 16px;
    overflow: hidden;
}

.spot img {
    display: block;
    width: 100%;

    -webkit-mask-image: radial-gradient(circle at 50% 40%, rgba(0, 0, 0, 1) 0 45%, rgba(0, 0, 0, 0) 60%);
    mask-image: radial-gradient(circle at 50% 40%, rgba(0, 0, 0, 1) 0 45%, rgba(0, 0, 0, 0) 60%);
}

複数マスク(重ねる)で表現が増える

mask-image はカンマ区切りで複数重ねられます。

「フェード + 形のマスク」みたいな合成ができて便利です。

CSS

.hero {
    background: url("./img/photo.jpg") center / cover no-repeat;
    height: 280px;

    -webkit-mask-image:
        linear-gradient(to bottom, rgba(0,0,0,1), rgba(0,0,0,0)),
        url("./mask/ink.png");
    mask-image:
        linear-gradient(to bottom, rgba(0,0,0,1), rgba(0,0,0,0)),
        url("./mask/ink.png");

    -webkit-mask-repeat: no-repeat, no-repeat;
    mask-repeat: no-repeat, no-repeat;

    -webkit-mask-position: center, center;
    mask-position: center, center;

    -webkit-mask-size: 100% 100%, cover;
    mask-size: 100% 100%, cover;
}

複数マスクで混乱しやすい点

mask-composite の考え方(合成ルール)

「複数マスクをどう混ぜるか」を決めるのが mask-composite(WebKit系だと -webkit-mask-composite のほうが実務で見ます)。

ただしここはブラウザ差が出やすいので、まずは “複数重ねてOK” のところまでを基本にして、合成は「必要になったら入れる」くらいがおすすめです。

mask-mode(色をどう読むか)

マスク画像の「どの情報を使うか」を指定できます。

mask-mode: luminance;
明るさ(白黒の明るさ)で効き具合を決める
mask-mode: alpha;
透明度(alpha)で効き具合を決める

実務の感覚では、

…というイメージです。

SVGマスクを使うと「解像度問題」が消える

画像マスク(PNG)だと、拡大したときに荒れます。

SVGをマスクにすると、拡大しても基本キレイです(ベクターだから)。

CSS

.badge {
    width: 220px;
    height: 220px;
    background: url("./img/photo.jpg") center / cover no-repeat;

    -webkit-mask-image: url("./mask/star.svg");
    mask-image: url("./mask/star.svg");

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-position: center;
    mask-position: center;

    -webkit-mask-size: contain;
    mask-size: contain;
}

SVG利用の実務メモ

アニメーション:マスクは「動かす」より「位置・サイズ」を動かすと簡単

例:スポットライトが左→右に動く

CSS

@keyframes sweep {
    0% {
        -webkit-mask-position: 0% 50%;
        mask-position: 0% 50%;
    }
    100% {
        -webkit-mask-position: 100% 50%;
        mask-position: 100% 50%;
    }
}

.movingSpot {
    background: url("./img/photo.jpg") center / cover no-repeat;
    height: 220px;

    -webkit-mask-image: radial-gradient(circle, rgba(0,0,0,1) 0 35%, rgba(0,0,0,0) 60%);
    mask-image: radial-gradient(circle, rgba(0,0,0,1) 0 35%, rgba(0,0,0,0) 60%);

    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;

    -webkit-mask-size: 220px 220px;
    mask-size: 220px 220px;

    animation: sweep 2.4s linear infinite;
}

実務の注意点(パフォーマンス・アクセシビリティ)

パフォーマンス

アクセシビリティ

FAQ

Q. 何が「マスク」されるんですか?
A. 要素そのもの(背景・文字・子要素ぜんぶ)の“見える範囲”が、マスク画像の透明度に合わせて決まります。
Q. PNGじゃないとダメですか?
A. いいえ。グラデーションでもOKですし、SVGでもできます。まずはグラデーションで練習すると理解が早いです。
Q. 黒が見えて白が消えるんですか? 逆ですか?
A. 基本は「不透明なところが見える/透明なところが消える」です。素材の作り方や mask-mode によって“どの情報を使うか”が変わるので、まずは透明度(alpha)で作ったPNGやグラデーションから始めるのが安全です。
Q. clip-path と何が違いますか?
A. clip-path は境界がパキッと切れますが、mask-image はグレー(半透明)を使って“フェード”や“ぼかしっぽい境界”が作れます。
Q. Safariで効きません。
A. -webkit-mask-image を併記してください。位置や繰り返しも含めて -webkit- 側をそろえると安定します。

よくあるエラー早見表

マスクがまったく効かない
-webkit-mask-image を併記(特にSafari)。URLパスがCSS基準になっているかも確認。
マスクがタイル状に並ぶ
mask-repeat: no-repeat; を指定。必要なら mask-sizemask-position もセットで。
位置がズレる/思った場所に来ない
mask-position を明示(例:center)。画像サイズに対して要素が大きすぎる場合は mask-size を調整。
拡大するとギザギザ・荒い
PNGの解像度不足の可能性。SVGマスクを検討。
アニメすると重い
適用範囲を小さく。大きい要素への連続アニメは避け、位置・サイズの変化に寄せる。