HTML+CSSだけでマスク(切り抜き)したいときに参考にしたいテクニック3選

マスク(切り抜き)したいときに参考にしたいテクニック3選 CSS

Webデザインをする上でやりたくなるテクニックの一つに切り抜き(マスク)があります。

文字や好きなシェイプの形で背景を切り抜いたりすると、華やかさというかなんかオシャレに見えるんですよね。

今回は色んな切り抜きのテクニックをご紹介します。

テキストの色にグラデーションをかける

テキストは通常では単色でしか指定できず、グラデーションがかけられません。

でもCSSでプロパティーをちょちょいと加えるだけで簡単にグラデーションがかけられるようになります。

<div class="gradation bg-clip">
  Lorem ipsum dolor sit, amet consectetur adipisicing elit.
</div>
.gradation {
  // 好きな色でグラデーション
  background: linear-gradient(30deg, #090979, #090979, #00d4ff, #090979, #090979);
}

.bg-clip {
  background-clip: text;
  color: transparent;
}

これ一つでもサイトの印象がガラリと変わりますね。

解説

テキストにグラデーションをかけるテクニックは、テキスト自体の色をグラデーションに変えているわけではなく、背景にグラデーションをかけてそれをテキストの形で切り抜き(マスク)をしています。

仕組みとしてはbackground-clip: text;で背景を前面にあるテキストの形で切り抜きをして、color: transparent;でテキストを透明にして背景の色を見えるようにしている、というカタチです。

ちょっと応用

グラデーションが動いてキラキラしてたらもっと目を引く演出になりそうじゃないですか?

ということで背景のグラデーションを動かしてみます。

.move {
  background-size: 300% 100%;
  background-position: 50% 50%;
  animation: move-background 1.5s infinite ease-in-out;

  @keyframes move-background {
    0% {
      background-position: 0% 50%;
    }
    100% {
      background-position: 100% 50%;
    }
  }
}

背景のサイズを大きくしてアニメーションで左から右へ移動させるようにしています。

より光沢のような高級感が出せていると思います。

実際の動きはこちらで見てみてください。

See the Pen background-clip: text; by mimihokuro (@mimi_hokuro) on CodePen.

SVGで切り抜き

次はSVG画像の形に切り抜く方法をご紹介します。

まずは実際のデモをご覧ください。

See the Pen clip-path by mimihokuro (@mimi_hokuro) on CodePen.

これの何がいいかって、「SVG」で切り抜いているところですよね。

SVGはベクター形式なので拡大縮小に強いのでキレイに切り抜けるところがいいところです。

スクロール量に合わせて拡大して次のコンテンツを見せる、みたいな使い方もできるので使いこなせれば表現の幅もグッと広がりますね。

SVGでの切り抜き方法には主に2つのパターンがあります。

  • clip-pathプロパティー+clipPathタグを使った方法
  • mask系プロパティー+maskタグを使った方法

clip-pathプロパティー+clipPathタグを使った方法

<div class="clip-path">
  <img src="https://picsum.photos/seed/picsum/300/300" alt="">
  <svg viewBox="0 0 512 512" width="0" height="0">
    <clipPath id="svg" clipPathUnits="objectBoundingBox">
      <path d="M378.409,0H208.294h-13.176l-9.314,9.315L57.017,138.101l-9.314,9.315v13.176v265.513   c0,47.36,38.528,85.896,85.895,85.896h244.811c47.361,0,85.888-38.535,85.888-85.896V85.896C464.297,38.528,425.77,0,378.409,0z M432.493,426.104c0,29.877-24.214,54.091-54.084,54.091H133.598c-29.877,0-54.091-24.214-54.091-54.091V160.592h83.717 c24.884,0,45.07-20.179,45.07-45.071V31.804h170.114c29.87,0,54.084,24.214,54.084,54.091V426.104z" />
      <path d="M180.296,296.668l-4.846-0.67c-10.63-1.487-14.265-4.978-14.265-10.104c0-5.78,4.309-9.817,12.383-9.817   c5.653,0,11.305,1.62,15.745,3.764c1.886,0.942,3.903,1.487,5.789,1.487c4.845,0,8.612-3.63,8.612-8.616   c0-3.226-1.481-5.921-4.71-7.939c-5.384-3.372-15.476-6.06-25.572-6.06c-19.781,0-32.436,11.171-32.436,27.998   c0,16.15,10.232,24.898,28.938,27.454l4.846,0.67c10.903,1.48,14.129,4.846,14.129,10.229c0,6.326-5.247,10.766-14.939,10.766 c-6.727,0-12.111-1.745-19.645-5.921c-1.616-0.942-3.634-1.62-5.788-1.62c-5.115,0-8.885,3.91-8.885,8.756 c0,3.226,1.616,6.326,4.713,8.344c6.054,3.764,15.878,7.8,28.798,7.8c23.823,0,35.934-12.24,35.934-28.795   C209.097,307.84,199.273,299.356,180.296,296.668z" />
      <path d="M281.108,259.382c-4.577,0-7.939,2.43-9.556,7.674l-16.69,54.51h-0.402l-17.634-54.51   c-1.745-5.244-4.978-7.674-9.551-7.674c-5.653,0-9.692,4.176-9.692,9.287c0,1.347,0.269,2.834,0.67,4.175l23.286,68.104   c2.96,8.477,6.727,11.57,12.652,11.57c5.785,0,9.555-3.093,12.516-11.57l23.282-68.104c0.406-1.341,0.674-2.828,0.674-4.175   C290.664,263.558,286.76,259.382,281.108,259.382z" />
      <path d="M364.556,300.836h-18.841c-5.114,0-8.344,3.1-8.344,7.806c0,4.713,3.23,7.814,8.344,7.814h6.193   c0.538,0,0.803,0.258,0.803,0.803c0,3.505-0.265,6.598-1.075,9.014c-1.882,5.796-7.67,9.426-14.669,9.426   c-7.943,0-12.921-3.903-14.939-10.096c-1.075-3.365-1.48-7.8-1.48-19.648c0-11.842,0.405-16.15,1.48-19.516   c2.018-6.325,6.867-10.228,14.67-10.228c5.924,0,10.362,1.885,13.859,6.724c2.695,3.777,5.387,4.852,8.749,4.852   c4.981,0,9.021-3.638,9.021-8.888c0-2.151-0.674-4.035-1.752-5.921c-4.842-8.204-15.071-14.264-29.877-14.264   c-16.287,0-28.935,7.408-33.644,22.204c-2.022,6.466-2.559,11.576-2.559,25.038c0,13.454,0.538,18.573,2.559,25.031   c4.709,14.802,17.357,22.204,33.644,22.204c16.286,0,28.668-8.204,33.374-22.881c1.617-5.111,2.29-12.645,2.29-20.716v-0.95   C372.362,303.664,369.538,300.836,364.556,300.836z" />
    </clipPath>
  </svg>
</div>
.clip-path {
  width: 300px;
  height: 300px;
  clip-path: url(#svg);

  img {
    width: 100%;
    height: 100%;
  }

  clipPath {
    transform: scale(0.00195);
  }
}

解説

まずHTMLの方では、imgタグで指定した画像が切り抜かれたときの背景となり、svgタグ内で指定したパスで実際に切り抜きを行うんですが、ポイントは2つあります。

  • svgパスをclipPathタグで囲う
  • clipPathタグにclipPathUnits属性を指定する

clipPathタグ自体は、囲ったパスを切り抜きに使うことを定義するためのもので、clipPathUnits属性は描画する範囲を指定しています。今回はobjectBoundingBoxを指定していますが、この場合はclipPathで囲うパスのサイズに合わせて描画します。

ここで注意なのがパスのサイズ

そのままだと元々のSVG画像のサイズで切り抜きしようとしてしまうので、元のサイズがどデカいとデカすぎて切り抜きされてるのにされてないと錯覚してしまうこともしばしば。

そのため、clipPathタグに対してtransform: scale; で縮小している、というわけです。

ここで指定している値は決まったものではなく、SVG画像のviewboxのサイズによって変動します。

値の出し方としては、1 ÷ viewboxの値という式になり、デモで使っているSVG画像のサイズの場合、1 ÷ 512 ≒ 0.00195で指定することでちょうどいいサイズになります。

≒としたのは、実際計算すると0.001953125となります。viewboxサイズによってはもっと細かい数値になることもあるかもしれず、正確に指定してもいいですが、省略した場合との差は微々たるものなのでここでは省略しています。正確に指定するかある程度で省略するかは、チームや会社の方針などに従って決めてください。

mask系プロパティー+maskタグを使った方法

<svg class="mask" viewBox="0 0 512 512" x="0" y="0">
  <image href="https://picsum.photos/seed/picsum/300/300"></image>
  <mask id="customMask">
    <path d="M378.409,0H208.294h-13.176l-9.314,9.315L57.017,138.101l-9.314,9.315v13.176v265.513   c0,47.36,38.528,85.896,85.895,85.896h244.811c47.361,0,85.888-38.535,85.888-85.896V85.896C464.297,38.528,425.77,0,378.409,0z M432.493,426.104c0,29.877-24.214,54.091-54.084,54.091H133.598c-29.877,0-54.091-24.214-54.091-54.091V160.592h83.717 c24.884,0,45.07-20.179,45.07-45.071V31.804h170.114c29.87,0,54.084,24.214,54.084,54.091V426.104z" />
    <path d="M180.296,296.668l-4.846-0.67c-10.63-1.487-14.265-4.978-14.265-10.104c0-5.78,4.309-9.817,12.383-9.817   c5.653,0,11.305,1.62,15.745,3.764c1.886,0.942,3.903,1.487,5.789,1.487c4.845,0,8.612-3.63,8.612-8.616   c0-3.226-1.481-5.921-4.71-7.939c-5.384-3.372-15.476-6.06-25.572-6.06c-19.781,0-32.436,11.171-32.436,27.998   c0,16.15,10.232,24.898,28.938,27.454l4.846,0.67c10.903,1.48,14.129,4.846,14.129,10.229c0,6.326-5.247,10.766-14.939,10.766 c-6.727,0-12.111-1.745-19.645-5.921c-1.616-0.942-3.634-1.62-5.788-1.62c-5.115,0-8.885,3.91-8.885,8.756 c0,3.226,1.616,6.326,4.713,8.344c6.054,3.764,15.878,7.8,28.798,7.8c23.823,0,35.934-12.24,35.934-28.795   C209.097,307.84,199.273,299.356,180.296,296.668z" />
    <path d="M281.108,259.382c-4.577,0-7.939,2.43-9.556,7.674l-16.69,54.51h-0.402l-17.634-54.51   c-1.745-5.244-4.978-7.674-9.551-7.674c-5.653,0-9.692,4.176-9.692,9.287c0,1.347,0.269,2.834,0.67,4.175l23.286,68.104   c2.96,8.477,6.727,11.57,12.652,11.57c5.785,0,9.555-3.093,12.516-11.57l23.282-68.104c0.406-1.341,0.674-2.828,0.674-4.175   C290.664,263.558,286.76,259.382,281.108,259.382z" />
    <path d="M364.556,300.836h-18.841c-5.114,0-8.344,3.1-8.344,7.806c0,4.713,3.23,7.814,8.344,7.814h6.193   c0.538,0,0.803,0.258,0.803,0.803c0,3.505-0.265,6.598-1.075,9.014c-1.882,5.796-7.67,9.426-14.669,9.426   c-7.943,0-12.921-3.903-14.939-10.096c-1.075-3.365-1.48-7.8-1.48-19.648c0-11.842,0.405-16.15,1.48-19.516   c2.018-6.325,6.867-10.228,14.67-10.228c5.924,0,10.362,1.885,13.859,6.724c2.695,3.777,5.387,4.852,8.749,4.852   c4.981,0,9.021-3.638,9.021-8.888c0-2.151-0.674-4.035-1.752-5.921c-4.842-8.204-15.071-14.264-29.877-14.264   c-16.287,0-28.935,7.408-33.644,22.204c-2.022,6.466-2.559,11.576-2.559,25.038c0,13.454,0.538,18.573,2.559,25.031   c4.709,14.802,17.357,22.204,33.644,22.204c16.286,0,28.668-8.204,33.374-22.881c1.617-5.111,2.29-12.645,2.29-20.716v-0.95   C372.362,303.664,369.538,300.836,364.556,300.836z" />
  </mask>
</svg>
.mask {
  width: 300px;
  height: 300px;

  image {
    width: 100%;
    mask-image: url(#customMask);
    mask-size: cover;
    mask-position: center;
  }

  path {
    fill: #ffffff;
  }
}

解説

簡単に言うと、imageタグで背景としたい画像を設定、maskタグで切り抜きしたいSVGパスを指定します。

CSSではmask-imageプロパティで切り抜きしたい対象のSVG画像を指定、mask-sizemask-positionでサイズと位置を指定しています。

ここではSVGのパスにfillstrokeを指定しないと切り抜きしてくれないので忘れずに指定しましょう。

ポイント

ここでのポイントとしては、画像指定に使うタグはimgタグではなく、imageタグであるというところ。

imageタグはSVGにだけ使える特殊なタグで、今回のmaskプロパティーとSVGを使った切り抜きの場合には、svgタグの配下に入れないと機能しません。

imageタグについての詳細はMDNをご参照ください。

画像を縦横サイズ関係なく任意の比率で切り抜き

お次は画像を引き延ばしせずに、縦長・横長・正方形など好きな比率で切り抜くテクニックです。

これまたどういうこっちゃという方に、デモご用意しました。

See the Pen object-fit by mimihokuro (@mimi_hokuro) on CodePen.

すべて同じ画像を使っていて、真ん中と右の画像ではCSSで一部だけ切り抜いています。

コードの抜粋はこちら

<div class="object-fit">
  <img src="https://picsum.photos/id/20/500/300">
</div>

<div class="object-view-box">
  <img src="https://picsum.photos/id/20/500/300">
</div>
.object-fit img {
  width: 200px;
  height: 300px;
  object-fit: cover;
  object-position: 30% 10%;
}

.object-view-box img {
  object-view-box: inset(100px 50px 30px 50px);
}

解説

ポイントとしては、切り抜きたい画像にobject-fitプロパティーとサイズを指定するだけです。

コードにはobject-positionプロパティーも指定されていますが、こちらは表示したい位置指定のものなので、必要に応じて使いましょう。

object-view-boxプロパティーでは元のサイズの上下左右からどれだけの範囲を表示するかを指定しています。

こんなシーンで

レスポンシブ対応で、画像の表示方法についてよくある問題として挙がります。PCとスマホでは画面比率が違うので、PCで表示していた画像をそのままスマホで表示すると小さくなりすぎて見づらかったり、はたまたスマホでは同じ画像の一部だけ表示したいから複数画像を用意するほどでもない、など考えなければならないことがあります。

object-fitでは指定のサイズで切り抜けるだけでなく、画面幅に合わせることもできるので煩わしい設定をする必要がなくなります。

こちらのデモを、スマホかデベロッパーツールでスマホモード、もしくはブラウザサイズの横幅を縮めてみてください。

See the Pen Untitled by mimihokuro (@mimi_hokuro) on CodePen.

縦幅は画面いっぱいのまま、画像のサイド部分が切り抜かれています。

サイトのファーストビューやインパクトを出したい箇所にはうってつけの方法だと思います。

最後に

いかがでしょうか?

マスク(切り抜き)は奥が深く、なかなかに複雑ですが、使いこなせれば表現の幅はグッと広がります。

今回の記事がその助けになれば幸いです。

タイトルとURLをコピーしました