1256 Reflect プロパティ (-webkit-box-reflect) -webkit-box-reflect プロパティを使用して反射画像を作ってみましょう webkit の仕様なので Safari Chrome で適用されますが それ以外のブラウザは未対応です (2015 年 11 月 25 日現在 ) -webkit-box-reflect プロパティは 画像が鏡に映って反転 ( 反射画像 ) しているような状態を作ることができます 例えば写真やイラストの画像を hover したときに反射画像を表示したり ビデオ画像に反射画像を付けることもできます 写真やイラストの画像やビデオ画像のサイズをトランジションやアニメーションで変えると それに合わせて反射画像も自動的にサイズが変わります 反射画像は 周りの要素に影響を与えないので 周りの要素の位置がずれたりしません box-shadow プロパティと同じように 周りに覆いかぶさるように描かれます プロパティ -webkit-box-reflect クリッピング領域は要素のボーダーボックスのどの部分を見えるようにするかを決定し ます 値 説 明 反射の方向 above( 上 ) below( 下 ) left( 左 ) right( 右 ) 元の画像と反射画像の隙間の距離 数値 + 単位で指定 正の値は隙間が空き 負の値は元の画像と反射画像が重なる 指定なしは初期値 (0px) と同様 反射画像に適用するマスク URI(URL) で画像ファイルまたはグラデーションを指定 元の画像と反射画像の隙間の距離 と 反射画像に適用するマスク は指定がなくて も構いません 反射画像は要素と同じサイズで描かれ 要素のボーダーやパディングも含まれます border-radius プロパティで要素の角が丸く指定されていれば 反射画像の角も丸く描か 1
れます マスクは反射画像を部分的に透明色や不透明色で描きます マスク画像ファイルは PNG SVG GIF が指定でき 透明色の領域を含む画像を指定します マスクのアルファ値がピクセル単位で反射画像に適用されます 色は何色でもアルファ値だけが反射画像に影響します マスクですから マスクの透明な部分は元の画像は表示されず マスクの色のある部分は元の画像が抜き出されて表示されます マスク画像を作るときには 反射画像ではなく元の要素に掛けるマスク画像を作ります 元の要素にはマスクは掛かりませんが 反射画像はマスクの掛かった要素の反射画像として描かれます マスクにグラデーションを指定する場合は 例えば top が透明で bottom が不透明のグラデーションで指定されると 反射画像にはその逆のグラデーションが描かれます 内部反射画像 反射画像には元の要素の子孫の要素がすべて描かれます もし元の親要素に -webkit-box-reflect を指定して さらにその子要素にも-webkit-box-reflect を指定すると 最初に子要素の反射画像が描かれます この子要素の元の画像と反射画像は 親要素の反射画像の中に描かれます ( サンプルCSS1の5 番目の画像を参照してください ) サンプル CSS1 反射画像を作る ( 静止画像 ) Reflection の説明 HTML の記述 (Reflection.html) id 属性 stage の div 要素を作り その中に div 要素でボックスを記述します id 属性 textreflect1 の div 要素を記述し 中にテキストで このテキストの写像は接して います と記述します id 属性 textreflect2 の div 要素を記述し 中にテキストで このテキストの写像は接して います と記述します id 属性 simplereflect の img 要素を記述し 画像ファイル src="images/dsc00149m.jpg" を 記述します id 属性 maskreflect の img 要素を記述し 画像ファイル src="images/dsc00203m.jpg" を記 述します id 属性 innerreflect の div 要素を記述し 子要素として img 要素で画像ファイル 2
src="images/dsc00092m.jpg" を span 要素でテキスト inner Reflection および br 要素 さらにもう一つ span 要素でテキスト inner Reflection および br 要素を 記述します は半角スペースになります <!DOCTYPE html> <html> <head> <title>reflection</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="reflection.css"> </head> <body> <p> CSS3 で写像を作る </p> <div id="stage"> <div id="textreflect1"> このテキストの写像は接しています </div> <div id="textreflect2"> このテキストの写像は離れています </div> <img id="simplereflect" src="images/dsc00149m.jpg"> <img id="maskreflect" src="images/dsc00203m.jpg"> <div id="innerreflect"> <img src="images/dsc00092m.jpg"> <span>inner Reflection</span><br> <span>inner Reflection</span><br></div> </div> </body> </html> CSS の記述 (Reflection.css) 先ず ボックスを描画するための #stage の記述をします #stage { width: 750px; height: 550px; background-color: #FFFFFF; border: solid 1px #000000; position: relative; 次に各種の反射画像を記述をします テキストの反射画像 1 3
-webkit-box-reflect: below; と指定しているので 元のテキストの下に反射テキストが描かれます 元の画像と反射画像の隙間の距離 の指定がないので 元のテキストと反射テキストは接していますが テキストの場合は 文字の高さ (font-size) よりも行の高さ (line-height) が少し大きいので 見た目には少し隙間が空きます 見た目にもぴったりと接するようにしたい場合は 元の画像と反射画像の隙間の距離 にマイナスの値を指定します #textreflect1 { top: 20px; left: 20px; background-color: skyblue; text-align: center; font: bold 32px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; color: red; -webkit-box-reflect: below; テキストの反射画像 2 ここでは-webkit-box-reflect: below 10px と指定されていて 元の画像と反射画像の隙間の距離 に 10px の指定があるので 元のテキストと反射テキストは離れています マスクに-webkit-linear-gradient(top, transparent, white) とグラデーションの指定をしているので 反射テキストは元のテキストにグラデーションのマスクが掛かった状態で下方向に逆向きの状態で描かれます #textreflect2 { top: 100px; left: 20px; background-color: lightgreen; text-align: center; font: bold 32px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; color: blue; -webkit-box-reflect: below 10px -webkit-linear-gradient(top, transparent, white); 4
画像の反射画像 ここでは border-radius: 20px; と指定して画像の4 隅を丸くしているので 反射画像の4 隅も丸く描かれます -webkit-box-reflect: below 0px と指定しているので 元の画像と反射画像は隙間なく接して描かれます マスクに-webkit-linear-gradient(top, transparent, transparent 50%, white); とグラデーションの指定をしているので 反射画像は元の画像の top から transparent 50% までの部分が表示されず transparent 50% から white の部分が徐々に見えてくるようなグラデーションのマスクが掛かった状態で 下方向に逆向きの状態で描かれます #simplereflect { top: 190px; left: 20px; width: 224px; height: 168px; border-radius: 20px; -webkit-box-reflect: below 0px -webkit-linear-gradient(top, transparent, transparent 50%, white); 画像にマスクを掛けた反射画像 元の画像マスク画像反射画像 ここでは -webkit-box-reflect: below 5px url(images/reflectmask1.png); とマスクに画 像ファイル images/reflectmask1.png を指定をしているので 反射画像は元の画像にマス 5
クが掛かった状態で下方向に逆向きの状態で描かれます ( 注 : マスク画像の空白の部分は透明です ) #maskreflect { top: 190px; left: 260px; width: 224px; height: 168px; -webkit-box-reflect: below 5px url(images/reflectmask1.png); 画像と反射画像全体の反射画像( 内部反射画像 ) ここでは親要素の #innerreflect に-webkit-box-reflect : below 20px; と指定しているので 子要素の img 要素の画像と span 要素のテキストが反射画像になります さらに子要素の img 要素に-webkit-box-reflect: below 0px -webkit-linear-gradient(top, transparent, transparent 80%, white); と指定しているので 子要素の img 要素の画像の反射画像も描かれます その結果 左のように反射画像の内部にさらに反射画像が描かれている画像になります #innerreflect { top: 190px; left: 500px; -webkit-box-reflect: below 20px; #innerreflect img { width: 224px; height: 120px; border-radius: 20px; -webkit-box-reflect: below 0px -webkit-linear-gradient(top, transparent, transparent 80%, white); #innerreflect span { font: bold 18px "MS Pゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; color: red; 6
サンプル CSS2 反射画像が変形するトランジションを作ってみましょう ボタンを hover すると 3 つの反射画像がそれぞれ違った変形をしながらトランジション します ReflectTransition の説明 HTML の記述 (ReflectTransition.html) id 属性 stage の div 要素 ( トランジションが動くステージ ) を作り その中にボックスや画像を記述します id 属性 button の div 要素を作ります これがボタン ( 親ボックス ) になります font28gothicb クラスでフォントを指定し Hover を記述します id 属性 image1 の img 要素を記述し 画像ファイル src="images/dsc00203m.jpg" を記述します id 属性 image2 の div 要素を記述し 子要素として画像ファイル src="images/ DummyTrans1X1.png" と span 要素の中にテキスト ABC を記述します id 属性 image3 の div 要素を記述し 子要素として span 要素でテキスト Reflection を 2つ さらにもう一つ span 要素のタグのみを記述します ( 注 :#image2 要素には 直接テキスト ABC を記載して span 要素を使わないのが一般的な指定方法ですが そうすると Safari が反射画像を表示できないようなので 子要素の span 要素の中にテキストを記述しています Chrome は #image2 要素に直接テキストを記述しても問題ありません また #image2 要素にダミーで透明な画像を指定しているのは Safari が span 要素だけでは初期画面で反射画像が表示されず 動き出すと反射画像が表示されるという現象があるので いろいろと試してみた結果 画像が含まれていると初期画面で反射画像が表示されたので ダミーで透明な画像を指定しています Chrome は画像がなくても反射画像が表示されます 2015 年 11 月 25 日現在 ) 7
<!DOCTYPE html> <html> <head> <title>reflecttransition</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="reflecttransition.css"> </head> <body> <p> 写像を動かす </p> <div id="stage"> <div id="button"><font class="font28gothicb">hover</font> <img id="image1" src="images/dsc00203m.jpg" alt="green road"> <div id="image2"><img src="images/dummytrans1x1.png" alt="dummy"> <span>abc</span></div> <div id="image3"><span>reflection</span><span>reflection</span> <span></span></div> </div> </div> </body> </html> CSS の記述 (ReflectTransition.css) 先ず トランジションが動く #stage の記述をします #stage { width: 700px; height: 550px; background-color: #000000; position: relative; overflow: hidden; ボタンとなる #button ボックスを記述します #button { top: 20px; left: 297px; width: 100px; height: 50px; border: solid 3px #666666; text-align: center; color: #666666; line-height: 55px; cursor: default; border-radius: 10px; 8
ボタンに表示するテキストのフォントを指定します.font28GothicB { font: bold 28px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; #button ボックス ( ボタン ) を hover したら #button ボックスの背景色を background-color: #555555;( 灰色 ) に Hover の文字を color: #000000;( 黒色 ) 変化させます #button:hover { background-color: #555555; color: #000000; 次に各トランジションの記述をします 反射画像を回転移動させるトランジション 反射画像を回転移動させてみましょう #image1 ボックスは反射画像を右から左へ回転しながら移動するようにしました #image1 ボックスを記述します position は absolute にして 位置は top: 70px; left: 180px;(#button ボックスの左上端を基準とした位置 ) で指定します border-radius: 20px; を指定して4 隅を丸くします position は absolute で指定します -webkit-box-reflect プロパティで反射画像を作り 画像の下半分だけ見えて上へいくにつれて見えなくなるようにグラデーションを指定します transition の記述をします 3 秒で linear で ease-in-out で変化するように記述します #button ボックス ( ボタン ) を hover した時の変化として #image1 要素に left: -280px; へ移動 反時計回りに 360 度回転になるように指定します 9
#image1 { top: 70px; left: 180px; width: 196px; height: 147px; border-radius: 20px; -webkit-box-reflect: below 2px -webkit-linear-gradient(top, transparent, transparent 60%, white); -webkit-transition: 3s ease-in-out; #button:hover #image1 { left: -280px; -webkit-transform: rotatez(-360deg); 反射画像を 3D 横回転させるトランジション 反射画像を 3D 横回転させてみましょう #image2 ボックスを記述します 位置は top: 290px; left: -290px;(#button ボックスの左上端を基準とした位置 ) で指定します position は absolute で指定します -webkit-box-reflect: below 2px -webkit-linear-gradient(top, transparent, transparent 20%, white); を指定し 子要素の img 要素と span 要素を含めて反射画像を描きます image2 ボックスの右端を軸にして横回転させるので -webkit-transform-origin: right center; で指定します 最初の画像は少し回転した状態にしたいので -webkit-transform: perspective(500px) rotatey(60deg); と指定し 画像の右端を軸として60 度回転させます transition の記述をします 3 秒で ease-in-out で変化するように記述します 10
#image2 { top: 290px; left: -290px; width: 180px; height: 80px; -webkit-box-reflect: below 2px -webkit-linear-gradient(top, transparent, transparent 20%, white); -webkit-perspective-origin: 50% 50%; -webkit-transform-origin: right center; -webkit-transform: perspective(500px) rotatey(60deg); -webkit-transition: 3s ease-in-out; 子要素の img 要素でダミーの透明画像を指定します #image2 img { top: 0px; left: 0px; width: 150px; height: 80px; /* 注 :Safari は span 要素だけでは初期画面で反射画像が表示されません 画像が含まれていると表示されるので ダミーで透明な画像を指定しています Chrome は OK */ 子要素の span 要素にはテキストのフォントやスタイルの指定をします #image2 span { top: 0px; left: 0px; width: 180px; height: 80px; text-align: center; font: bold 82px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; line-height: 80px; background-color: skyblue; color: red; text-decoration: underline; -webkit-text-fill-color: red; -webkit-text-stroke-width: 3px; -webkit-text-stroke-color: orange; #button ボックス ( ボタン ) を hover した時の変化として #image2 要素に Y 軸の正の方向 から見て計回りに 330 度回転になるように指定します 11
#button:hover #image2 { -webkit-transform: perspective(500px) rotatey(330deg); 反射画像を傾斜 拡大させるトランジション CSS3の仕様では 反射画像は元の画像と同じサイズで描かれるので 反射画像を傾斜 拡大することはできません しかし そういうトランジションを作ってみたいのは私だけではないと思うので 反射画像を使わない別の方法でそのように見えるトランジションを作ってみます 元のテキストが上方へ遠ざかるにつれて 傾斜して映っている反射テキストが拡大し 色が薄くなります #image3 ボックスは子要素である 3 つの span 要素の基準ボックスとして位置 top: 350px; left: 130px; (#button ボックスの左上端を基準とした位置 ) とサイズ width: 280px; height: 50px; だけ指定します position は absolute で指定します #image3 { top: 350px; left: 130px; width: 280px; height: 50px; #image3 ボックスの 1 つ目の span 要素は ReflectTransition.html にテキスト Reflection が記述してあるので フォントやスタイルの指定をします ( このテキスト が元の画像に相当します )transition の記述をします 3 秒で ease-in-out で変化するよ 12
うに記述します #image3 > span:nth-child(1) { top: 0px; left: 0px; width: 230px; height: 50px; text-align: left; font: bold 48px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; line-height: 66px; color: lightgray; -webkit-transition: 3s ease-in-out; #image3 ボックスの 2 つ目の span 要素も ReflectTransition.html にテキスト Reflection が記述してあるので フォントやスタイルの指定をします ( このテキストが反射画像に相当します ) テキストに遠近感を持たせて傾けたいので -webkit-transform: perspective(500px) rotatex(60deg) scale(1.1, -2.5); と指定しています scale(1.1, -2.5) の Y 方向の値 -2.5 によってテキストが下向に拡大されます X 方向の値に 1.1 を指定しているのは 元のテキストと反射テキストの接している部分の幅を合わせるためです テキストの中心を軸にして60 度傾いているので 反射テキストの底辺部分の幅が元の幅より狭く描かれるため X 方向へも拡大して合わせています transition の記述をします 3 秒で ease-in-out で変化するように記述します #image3 > span:nth-child(2) { top: 50px; left: 0px; width: 230px; height: 50px; text-align: left; font: bold 48px "MS P ゴシック ", Osaka, " ヒラギノ角ゴ Pro", Verdana; line-height: 60px; color: lightgray; -webkit-transform: perspective(500px) rotatex(60deg) scale(1.1, -2.5); -webkit-transition: 3s ease-in-out; #image3 ボックスの 3 つ目の span 要素は 反射画像に相当するテキストにかけるグラデー ションを指定します background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.5) 30%, rgba(0, 0, 0, 0.8) 60%, rgba(0, 0, 0, 1)); と指定して います -webkit-box-reflect プロパティのマスクと違いグラデーションなので グラデー ションの透明な部分は 2 つ目の span 要素のテキストが見えて グラデーションが上に行く につれて黒色になっていくので 2 つ目の span 要素のテキストが見えなくなります 2 つ 13
目の span 要素のテキストに合わせて遠近感を持たせて傾けたいので -webkit-transform: perspective(500px) rotatex(60deg) scale(1.1, -2.5); と指定しています transition の 記述をします 3 秒で ease-in-out で変化するように記述します #image3 > span:nth-child(3) { top: 50px; left: 0px; width: 220px; height: 50px; background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.5) 30%, rgba(0, 0, 0, 0.8) 60%, rgba(0, 0, 0, 1)); -webkit-transform: perspective(500px) rotatex(60deg) scale(1.1, -2.5); -webkit-transition: 3s ease-in-out; #button ボックス ( ボタン ) を hover した時の変化として #image3 要素の各 span 要素に次のように指定します 1つ目の span 要素は top: -200px; と指定して上方へ移動させます 2つ目の span 要素は -webkit-transform: perspective(500px) rotatex(60deg) scale(1.5, -4.5); と指定し 60 度傾いたままでサイズを scale(1.5, -4.5) に徐々に拡大します サイズが拡大されるとテキストの底部の方向へも伸びるので 徐々に top: 70px; に移動しテキストの底部の位置が元の位置からずれないようにします opacity: 0.1; を指定して テキストを徐々に見えないように変化させます 3 つ目の span 要素も 2 つ目の soan 要素と同様に -webkit-transform: perspective(500px) rotatex(60deg) scale(1.5, -4.5); と指定し 60 度傾いたままでサイズを scale(1.5, -4.5) に徐々に拡大します サイズが拡大されると span 要素の底部の方向へも伸びるので 徐々に top: 70px; に移動し元の位置からずれないようにします #button:hover #image3 > span:nth-child(1) { top: -200px; #button:hover #image3 > span:nth-child(2) { top: 70px; opacity: 0.1; -webkit-transform: perspective(500px) rotatex(60deg) scale(1.5, -4.5); #button:hover #image3 > span:nth-child(3) { top: 70px; -webkit-transform: perspective(500px) rotatex(60deg) scale(1.5, -4.5); 14