クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【CSS】background-clip: textで背景を文字形に切り抜いてさらにグラデのアニメにする

iPhone Xsのページで背景画像が文字の形で切り抜かれた表現があり、調べてみたらbackground-clip: textというスタイルだった。このスタイルで出来ること、出来ないことを検証してみました。

※目次:

※参考:CSSの基本
【CSSの基本】書ける前に読む!HTML、CSS、JSの書式-3 - クモのようにコツコツと

背景を文字形で切り抜くbackground-clip: text

iPhone Xsのページを見てたらこんな表現がありました。

f:id:idr_zz:20180916174203j:plain

はて?文字のうしろが画像みたいだぞ。文字の形で画像を切り抜いているってことか?それにしても一文字ごとの背景ではなくテキストボックス全体が画像になっているようだ。

※参考:iPhone - Apple(日本)

ソースを見てみるとbackground-clip: textというスタイルのようだった。
実際にやってみた。「そうだ小田急乗ろう」

f:id:idr_zz:20180916174800j:plain

写真は前回と同じ、小田急線のインスタ写真です。

instagram.com

こんなコードです。

section {
  color: rgba(0,0,0,0);
  -webkit-background-clip: text;
   background-image: url(../img/hoge.jpg);
}
  • 文字の色を透明にする。
  • 背景を文字形に切らぬく。
  • 背景の画像を設定

background-clipはまだベンダープレフィックス -webkitが必要でした。付けないとうまく当たらなかった。。

※参考:Can I use... Support tables for HTML5, CSS3, etc

Firefox, Chrome and Safari support the unofficial -webkit-background-clip: text (only with prefix) 1

こうなりました。外側のセクションに設定したら見出しと本文も一体として設定できた。

さて、ここからやりたいことがあります。

※やりたいこと:

  • 背景を画像ではなくCSSのグラデにしたい
  • CSSアニメでグラデの色変更をループさせたい

background-imageをbackground-colorにする

まずは背景を画像ではなく普通の一色にしてみる。

section {
  color: rgba(0,0,0,0);
  -webkit-background-clip: text;
   background: #2382f5;
}

背景をbackground: #2382f5とただの色にしたところ…

See the Pen background-clip 02-ng by イイダリョウ (@i_ryo) on CodePen.

ありゃ?背景全体が出てしまって、文字の形で切り抜かれない。この設定ってもしかして画像のみに適用できる設定なのかな?

調べたところ、background-clipが適用できるのはbackground-imageとbackground-colorのみらしい。

要素に background-image 又は background-color がない場合、このプロパティは (border-style 又は border-image によって) 境界に透明な領域や部分的に不透明な領域がある場合のみ視覚効果があります。そうでなければ、境界は異なるマスク方法になります。

※参考: background-clip - CSS: カスケーディングスタイルシート | MDN

でもいじってるうちに適用された!はてな?よく見たら文字色から color より先に背景backgroundを書くと大丈夫みたい。書き順が影響する?

section {
  background: #2382f5;
  color: rgba(0,0,0,0);
  -webkit-background-clip: text;
}

切り抜けた!!

See the Pen background-clip 02 by イイダリョウ (@i_ryo) on CodePen.

まあこれなら背景切り抜きじゃなくて普通に文字色をcolor: #2382f5;でいいじゃないかって話ですよね(汗) ではいよいよ、これをグラデにしてみませう!

背景をCSSグラデーションlinear-gradientに変更する

CSSのグラデはlinear-gradient()です。さっそく適用します。

section {
  background: linear-gradient(-45deg, #004ba5, #58c6ff);
  -webkit-background-clip: text;
  color: rgba(0,0,0,0);
}

CSS関数linear-gradient()の第1引数は角度で-45度傾けています。
そのあとの2つの引数はグラデの開始色、終了色。濃いブルーから薄いブルーにしてます。

さあどうなるか。

See the Pen background-clip 03 by イイダリョウ (@i_ryo) on CodePen.

できた!

css animationでループアニメ

さあ次はCSSアニメでこのグラデをループしたい!これは背景画像background-imageではできなかったこと。

cssアニメは以前、transitionを使って要素をふわっと動かしました。

※参考: スクロールするとフワッと現れたり動いたりするアニメーション【jquery.inview.js & transition】 - クモのようにコツコツと

今回はcss animationを使います。キーフレームで細かく段階的な設定ができます。

section {
animation: キーフレーム名 時間;
  animation-プロパティ: 値; 
}

@keyframes キーフレーム名 {
    from {
      開始時のスタイル
    }
   50% {
      途中(ここでは50%)のスタイル
  }
   to {
      終了時のスタイル
    }
}
  • animationプロパティに任意のキーフレーム名とアニメーションにかかる時間
  • 必要に応じて「animation-プロパティ」設定を追加する
  • 「@keyframes キーフレーム名」の中にキーフレームのスタイル設定を書く
  • fromに開始時のスタイル(0%でもok)
  • %で開始時間と終了時間の中間のスタイルを設定できる(何段階でも設定可能)
  • toで終了時間のスタイルを(100%でもok)

※参考: 【CSS3】@keyframes と animation 関連のまとめ - Qiita

さっそく書いてみる。

section {
animation: colorChange 5s;
  animation-iteration-count: infinite;
}

@keyframes colorChange {
    from {
      background: linear-gradient(-45deg, #004ba5, #58c6ff);
    }
   50% {
      background: linear-gradient(-45deg, #58c6ff, #004ba5);
  }
   to {
      background: linear-gradient(-45deg, #004ba5, #58c6ff);
    }
}
  • キーフレーム名はcolorChange、時間は5秒
  • animation-iteration-count: infiniteはループさせるという設定
  • キーフレーム開始fromは元のグラデスタイル
  • キーフレーム中間50%はグラデの色を逆さまに
  • キーフレーム終了toで色を元に戻す

これでグラデの濃い所と薄い所がジンワリと入れ替わる5秒のループアニメを期待してる。どうかな?

See the Pen background-clip 04-ng by イイダリョウ (@i_ryo) on CodePen.

あれれ?色は変わってくれたけど、期待したようなジンワリしたアニメにならない!ダメかー

調べてみると、どうやらグラデのアニメは背景サイズを大きくして、表示位置を動かすこと方法がセオリーのようでした。

※参考: CSSで背景グラデーション+アニメーションで変化する背景色を実装してみよう! | WebLifeTimes

書き換えてみた。

section {
background: linear-gradient(-45deg, #004ba5, #58c6ff);
  background-size: 200% 200%;
  -webkit-background-clip: text;
  animation: colorChange  3s;
  animation-iteration-count: infinite;
}

@keyframes colorChange {
  from {
        background-position: 0% 0%;
    }
    50% {
        background-position: 100% 100%;
    }
    to {
        background-position: 0% 0%;
    }
}
  • グラデのスタイルはキーフレームではなくセクションに書く
  • 背景サイズbackground-size、高さと幅を200%に(4倍の大きさ)
  • キーフレームの開始fromで背景位置background-positionを上0%、左0%(左上)
  • キーフレームの中間50%の背景位置を上100%、左100%(右下)に移動
  • キーフレームの終了toで背景位置background-positionを上0%、左0%(左上)に戻る

背景サイズbackground-sizeの幅と高さが倍の200%だと面積は4倍。
背景位置background-positionは左上基準なので上100%左100%は左上が中間地点なので右下に移動するわけです。

See the Pen background-clip 04 by イイダリョウ (@i_ryo) on CodePen.

やった!ジンワリと動いた!

※2019/09/04追記

コメントでステイサムさんよりご指摘いただきました。
環境によってはsectionの文字色設定をtransparentにしないと動かないようです。

section {
    color: transparent;
}

※参考:html - -webkit-background-clip:text; is not working - Stack Overflow

rgba()は不透明度を4つめの引数で指定しますが、transparentは不透明度ではなく「透明」という設定です。

※参考:rgba, transparentを使った色と透明度の指定方法

終わりに

わかったことまとめ。

  • 背景を文字形に切り抜けるのはlinear-gradient
  • bacgroundをcolorより先に書くと切り抜かれなかった
  • グラデlinear-gradientのcss animation は背景サイズを広げて背景位置を移動する。

※私ごとですがタブレットを購入しまして今回、ほぼほぼタブレットのみでブログ書きました。慣れてないので苦戦した。

※追記:その後、フリック用のアプリ「片手キーボードPRO」を入れてみたらストレスフリーに!(今それで打っています)次回はこれでコードも含めてブログを書いて見ようかと思う。海外で主流というグライド入力(一筆書き)も試すべく「Gboard」も入れてみた。コードはこちらがいい?)


※参考:ネイティブHTML & CSSやってみたシリーズ
qiita.com