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
で指定することでちょうどいいサイズになります。
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-size
とmask-position
でサイズと位置を指定しています。
ここではSVGのパスにfill
かstroke
を指定しないと切り抜きしてくれないので忘れずに指定しましょう。
ポイント
ここでのポイントとしては、画像指定に使うタグは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.
縦幅は画面いっぱいのまま、画像のサイド部分が切り抜かれています。
サイトのファーストビューやインパクトを出したい箇所にはうってつけの方法だと思います。
最後に
いかがでしょうか?
マスク(切り抜き)は奥が深く、なかなかに複雑ですが、使いこなせれば表現の幅はグッと広がります。
今回の記事がその助けになれば幸いです。