CSSのみでテキストにグラデーションやリフレクトをかけるテクニック(ちょっと更新)


前回はiOS5のMobile Safariから使えるようになったHTML5・CSSについて前編後編に分けてご紹介しましたが、そのなかで説明していない小さなテクニックについて少し紹介したいと思います。
今回はCSSでテキストにグラデーションをかけるテクニックについてです。
前回のWeb App Demoではフッタータブに特殊なWebFontを使ってアイコンを表示させるようにしていましたが、タブがActiveのときに色が変わってエフェクトがかかるようになっています。
このエフェクト効果はCSSでテキストにグラデーションをかけるテクニックをつかってやっています。


通常、CSSでテキストカラー(colorプロパティ)にグラデーションを指定することはできませんが「:after」擬似クラスや「mask-image」プロパティを組み合わせて使うことでグラデーションのような表現をすることができます。具体的にどのようにするのか解説します。
↓さっそく今回のデモページへのリンクはこちらです。
→ Text Gradient Demo


id:y-kawaz CSSにテキスト書くとか本末転倒なのはどうにかならないの?これじゃ、適当な要素にクラスつければキレイになるとかできないじゃん。
という意見があって、確かに!と思ったのでちょっと変えてみました! contentプロパティはタイトル属性を読むようにしています。ありがとうございます!

「:before」「:after」擬似クラスのレイヤー構造

ある要素に含まれるテキストと「:before」「:after」擬似クラスにcontentプロパティで追加した要素、さらにある要素が包括する要素のレイヤー関係はこのようになるみたいです。(p要素がspan要素を包括している場合)

「:before」「:after」擬似クラスで追加した要素は通常もともとのテキストなどとは重ならないので「position:absolute」で重ねた場合のレイヤー順序です。
まぁ、z-indexプロパティで並び替えることができるので気にしなくてもいいのかもしれませんが、z-indexを使わないでやる場合はこのようになると覚えておけば良いと思います。

mask-imageプロパティとグラデーションで効果をつける

mask-imageプロパティはそのプロパティを指定した要素にマスクをかけることができます。
例えば、円形にマスクで切り抜きたい場合は右のような黒い円形の塗りがある透過画像を用意します。
mask-imageでは黒い塗りの部分だけが表示されるようにマスクされます。
黒い円形にぼかしをかければ、マスクもぼやっとくりぬいてくれます。

img{-webkit-mask-image:url(mask.png);}


mask-imageプロパティにはbackgroundプロパティと同じようにgradientを指定することもできます。なので画像を使わなくても簡単なマスク画像ならgradientで作れるんですね。
例えば、下に向かってだんだん消えていくようなマスクにしたい場合は、下に向かって透過度が増していくようなグラデーションを指定します。色をRGBAで指定します。

img{-webkit-mask-image:-webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0));}

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

これらを応用することで、「:before」「:after」擬似クラスで追加された最大2色のグラデーションをテキストに対して加えることができます。


具体的にはp要素に含まれるテキストのカラーをベースカラーとして、「:before」「:after」擬似クラスで追加した要素でグラデーションをかけます。
まずは、擬似クラスで追加した要素で追加したテキストがベースのテキストとぴったり重なるようにします。p要素にはtitle属性を追加して、contentプロパティにはタイトル属性を読むようにします。
(最初は分かりやすく、:before擬似クラスで1色だけグラデーションをかけます)

<p title="TEXT GRADIENT">TEXT GRADIENT</p>
p, p:before {
  position:absolute;
  top:0;
  left:0;
}
p:before {
  display:block;
  content:attr(title);
}

次に、どういうグラデーションにするかを決めて、ベースの要素と擬似クラスで追加した要素のテキストカラーに指定します。
(例えば、水色から濃い青に変化するグラデーションにしたい場合は、ベースカラーを水色、追加した要素を濃い青に)

p, p:before {
  position:absolute;
  top:0;
  left:0;
  color:#00b0ff;
}
p:before {
  display:block;
  content:attr(title);
  color:#003577;
}

最後に擬似クラスで追加した要素にグラデーションマスクをかけます。

p, p:before {
  position:absolute;
  top:0;
  left:0;
  color:#00b0ff;
}
p:before {
  display:block;
  content:attr(title);
  color:#003577;
  -webkit-mask-image:-webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,1));
}


これをさらに応用することで、いろいろなバリエーションのテキストエフェクトを作ることができます。
簡単に作ってみたエフェクトのサンプルコードを紹介します。(スタイルはカラーやシャドーの部分のみです)

p {
  color:#000;
  text-shadow:0 1px 0 #000;
}
pt1:after {
  color:#fff;
  -webkit-mask-image:-webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.2) 51%, rgba(0,0,0,0));
}

p {
  color:#44c0fe;
  text-shadow:0 -1px 0 rgba(255,255,255,0.6),0 1px 1px rgba(0,0,0,0.5);
}
p:before {
  color:#0036b4;
  -webkit-mask-image:-webkit-linear-gradient(-85deg, rgba(0,0,0,0), rgba(0,0,0,0) 40%, rgba(0,0,0,1) 80%, rgba(0,0,0,1));
}
p:after {
  color:#d7edff;
  -webkit-mask-image:-webkit-linear-gradient(-85deg, rgba(0,0,0,1), rgba(0,0,0,1) 10%, rgba(0,0,0,0.25) 48%, rgba(0,0,0,0) 48%, rgba(0,0,0,0));
}

p {
  color:#fff100;
  text-shadow:0 1px 0 rgba(255,255,255,1),0 -1px 0 rgba(0,0,0,0.4);
}
p:before {
  color:#e4007f;
  -webkit-mask-image:-webkit-linear-gradient(45deg, 
    rgba(0,0,0,0.5),
    rgba(0,0,0,0.5) 15%,
    rgba(0,0,0,0) 25%,
    rgba(0,0,0,0) 35%,
    rgba(0,0,0,0) 50%,
    rgba(0,0,0,0.5) 60%,
    rgba(0,0,0,1) 75%,
    rgba(0,0,0,1) 85%,
    rgba(0,0,0,1)
  );
}
p:after {
  color:#00a0e9;
  -webkit-mask-image:-webkit-linear-gradient(45deg, 
    rgba(0,0,0,0),
    rgba(0,0,0,0) 15%,
    rgba(0,0,0,0) 25%,
    rgba(0,0,0,0) 35%,
    rgba(0,0,0,0.5) 50%,
    rgba(0,0,0,0.8) 60%,
    rgba(0,0,0,0.5) 75%,
    rgba(0,0,0,0) 85%,
    rgba(0,0,0,0)
  );
}

P {
  color:#755d41;
  text-shadow:0 2px 0 #755d41,0 2px 1px rgba(0,0,0,0.8);
}
P:before {
  color:#b6a57a;
  -webkit-mask-image:-webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,1) 40%, rgba(0,0,0,0) 90%, rgba(0,0,0,0));
}
P:after {
  color:#fff;
  -webkit-mask-image:-webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0) 20%, rgba(0,0,0,0.2) 36%, rgba(0,0,0,0.5) 40%, rgba(0,0,0,0.2) 44%, rgba(0,0,0,0) 60%, rgba(0,0,0,0));
}

CSSでリフレクトをかける


おまけでリフレクトも少し紹介します。リフレクトは「box-reflect」プロパティでかけることができて、テキストに限らず反射効果をつけることができます。
というのを実は1年前の「CSS3によるTransition Effects 30」という記事の時に紹介していましたね。
繰り返し説明しておくと、box-reflectには、リフレクトを掛ける方向・オフセット値・リフレクトのマスクの3つのパラメータを指定することができます。
リフレクトを掛ける方向は、「right, left, above, below」の中から指定できて、aboveは上部・belowは下部に反射効果を描画します。
マスク画像は指定しなくてもいいですが、指定する場合はmask-imageと同じような値を指定することができます。
単純に、床に反射しているような効果をつけたい場合はこのような指定になります。(オフセット値はいい感じに調整してください)

img{-webkit-box-reflect: below -3px -webkit-linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0) 50%,rgba(0,0,0,0.5));}

先程のグラデーションテキストDemoにリフレクトをつけたデモを作ってみました。
→ Text Reflect Demo