CSSによるテキスト・ボックスの作り方
ホームページにおいては、従来テキスト領域は一般的に正方形ないし長方形に配置されてきましたが、CSS の新たな仕様によってそれが変わりつつあります。
この記事では、そのCSS Shapesという新しい機能について、それが何なのかと、核になるコンセプトについて説明したいと思います。
すべての使用例を用意してありますので、見映えを確認したりソースコードをダウンロードして実際に実験することができます。
CSS Shapesとは何か?
CSS Shapesとは、CSSで使用できる幾何学的な形状の定義です。
Level 1は現在勧告候補ステータスで、Shapesをフロート要素のみに適用できるようになっています。
例を見るのが最も分かりやすいでしょう。
.shape { float: left; width: 150px; height: 150px; margin: 20px; shape-outside
上記の例ではイメージに適用しています。イメージを左にフロートさせて幅と高さ、マージンを与え、shape-outsideプロパティを使ってテキストを丸く回りこむように指定しています。
サンプルを見てください。
さらに先に進める前に、Chromeで以下のページに行って、ShowShapesブックマークレットをブックマーク・バーに追加しておいてください。
そしてサンプルのページに行ってブックマークレットを実行すれば、下記のような円形の形状が描かれているのが分かるかと思います。
Basic Shapes (基本的な形状)
我々のサンプルで使ったshape-outsideプロパティは、様々な値を取ることができます。まずは”Basic shapes”と呼ばれる仕様で定義されており、基本的な形状は以下のようになっています。
.inset()
.circle()
.ellipse()
.polygon()
inset()
このinset()関数は長方形の要素を定義するもので、殆どの場合、これで用が足り、様々なコントロールを追加することでより便利になります。
内部の余白を定義する4つの数字と長方形の角の丸みを定義するroundというキーワードを用います。
Inset(top right bottom left round berder-radius);
例)
inset(10px 20px 10px 20px round 50%);
この定義で、例えばすべてのマージンの合計を20ピクセルにしたい場合は以下のように簡略化して記述することもできます。
inset(10px round 50%);
このサンプルだと、イメージの下に大きな余白ができてしまいますが、以下のように記述することで、テキストをよりイメージの近くに配置することもできます。
.shape {float: left; width: 200px; height: 200px; shape-outside: inset(0 0 70px 0 round 10px); }
Show Shapes ブックマークレットを使って、サンプルがどのように見えるか確認して下さい。
circle()
この記事の冒頭で円形の基本的なshapeを見ていただきました。
その際に使ったcircle()関数の値は、以下のようになります。
Circle(r at cx cy);
rが円の半径で50%にすると、要素のちょうど半分の大きさになります。残りのx、yは円の中心座標で、円をどこに置くかを指定します。先の例で、
circle(50%);
としましたが、これは
circle(50% at 50% 50%);
と記述するのと同じことです。
サンプルのページで、半透明の背景のアイコンをグレーの背景カラーに配置し、パディングやボーダー、マージンを以下のように指定しています。
.shape { float: left; width: 150px; height: 150px; margin: 20px; padding: 20px; background-color: #cccccc; border: 10px solid #999999; }
これはフロートの左側を指定するもので、このイメージに何もshapeを適用しなければ、以下のスクリーンショットのように表示されます。
また、簡単に以下のように円形のshapeを加えることができます。
.circle {shape-outside: circle(50%); }
円に値について、以下のようにshape-insideの値を与えると座標が変わり、shape左上に移動します。
.circle-coords { shape-outsite: circle(50% at 30% 30%); }
背景画像の位置指定について、絶対的あるいは相対的な座標、キーワードを用いることが可能です。
このとき、参照ボックスについて理解しておくと良いでしょう。
使用することができる参照ボックスには以下の4つがあります。
content-box
padding-box
border-box
margin-box
circleのためのデフォルトの参照ボックスはmargin-boxです。
shape-outside:circle(50%) margin-box;
以下のように書いても同様です。
shape-outside:circle(50%);
margin-boxが要素のマージンやボーダーのマージン、パディングボックスによるパディングコンテンツ・ボックスなどに制約される場合はそちらが優先されます。
CSS Shapesにおいて参照ボックスがどのように動作するか詳しく知りたい場合はこちらの解説をご覧ください。
Show Shapesブックマークレットのページの用例をご覧頂いても、動作がよくお分かりになるかと思います。
最後にご覧いただくcircleの例は、あなたの作った形状に沿ってどのようにコンテンツを切り取るかをお見せするものです。可視化されたパディングとボーダーを要素に加えてあるので、テキストがオーバーラップしているのを見ることができます。CSS マスキングレベル1仕様を用いることで、形状にそって輪郭を切り取ることができます。現時点ではプリフィックスが必要です([Can I Use][7]をご覧ください)。
.circle-clip { shape-outside: circle(50%) margin-box; -webkit-clip-path: circle(50%) ; clip-path:circle(50%) ; }
上記のスクリーンショットを見てお分かりの通り、曲線にそって要素がクリッピングされており、テキストをイメージに回りこませて表示させるのにぴったりの方法です。
ellipse()
ellipseを使うことで、それが実際に楕円でない場合もテキストを楕円状に回り込ませて表示させることができます。
circle命令と良く似ていますが、違うのは半径を指定するのにx、yの2つの値を個別に指定することです。
shape-outsite (rx ry at cx xy);
半径の値は絶対値か相対値、もしくはclosest-sideと farthest-sideというキーワードを用いることが可能です。キーワードは円の半径を指示するのに使用することもできますが、あまり実用的とは言えないかもしれません。
shapeを適用しない例では、シンプルなフロートになっています。
.shape { float: left; width: 200px; height: 200px; margin: 20px; }
半径にキーワードを使用することもできます。
.ellipse-keywords { shape-outside:ellipse(closest-side farthest-side at 50% 50%); }
これは実際のイメージの寸法を長方形として、円を要素上に作成しています。
絶対値で長さを指定することで、楕円を配置することもできます。
.ellipse-values { shape-outside: ellipse(90px150px at 50% 50%); }
座標を変更すれば、楕円の位置が移動します。
.ellipse-center { shape-outside: ellipse(closest-side farthest-side at 70% 80%); }
polygon()
さらに細かく配置をコントロールしたい場合は、ポリゴンを使ってshapeを描くと良いでしょう。shapeを形作るのに必要なすべての座標を指定することが可能で、最低3つの座標を指定する必要があります。
また、それぞれの座標はカンマで区切る必要があります。
.shape-polygon { shape-outside: polygon(0 20px,160px 40px, 180px 70px, 180px 120px, 120px 200px,60px 210px, 0 220px); }
Show Shapes ブックマークレットでどのように見えるか確認することができます。
イメージからshapeを作る
shapeを作成するもう一つの方法は、イメージそのものを要素の輪郭として与える方法です。そのためにはイメージがアルファ・チャンネルを持っている必要があります(Adobe Web Platformブログを見れば、Photoshopを使ったそのイメージの作り方が分かります)。
あなたがすでにページ上で使っているイメージの他、どこか別な場所にあるイメージも使うことができます。
注意: イメージはCORS対応である必要があります。最初、ローカルで試してみてうまく動作せず、原因を調べるのに苦労しました。詳しくはこちらをご覧ください)。
サンプルには、このテクニックについて3つの異なる使用法が含まれています。最初のサンプルは私のページ内のイメージを使い、さらにこのイメージをURLとして与えてshapeを作っています。
.shape-image { shape-outside:url(‘noun_109069.png’); shape-image-threshold:0.5; }
shape-image-thresholdはその領域の透明度を定義するもので、0で完全に透明、1で不透明になります。
2つ目のサンプルでは、異なるアイコンで、shape-marginプロパティを使ってみました。これによって要素周りのパスを円形にかたどっています。
.shape-image-margin { shape-outside:url(‘noun_109207_cc.png’); shape-image-threshold:0.5; shape-margin: 20px; }
必ずしもページ上にあるものに基づいてshapeを作らなければいけないわけではありません。
最後のサンプルでは、Photoshopで作った以下のようなイメージを使ってみました。これを使って、斜めの線上に沿ったテキストを生成して配置させてみました。
.content:before { content: “”; float: left;width: 200px; height: 200px; shape-outside:url(‘alpha.png’); shape-image-threshold: 0.5; }
つまり、マスクされたイメージを作り、これに沿ってテキストを表示させることも可能なわけです。
参照ボックスからshapeを作る
先にcircle()のところで説明した参照ボックスのshape-outsideプロパティに値を与えることもできます。
例)
.circle-margin-box { shape-outside: margin-box; }
これは例のように、要素に円形の境界を与えたい時や、単純に、コンテンツを境界に沿って曲線的に配置したいときに便利です。
ブラウザー・サポート
CSS Shapesの素晴らしい点の一つは、floatに与えられる定義なので、サイトのプログレッシブ・エンハンスメントを容易に可能にする、ということです。
つまり、Shapesをサポートしていないブラウザーでは、要素周りのスクエアボックスを使用して従来通りの表示をし、サポートしているブラウザーでは特定のシェイプを表示するわけです。The Web Ahead ポッドキャストの新しいサイトでその素晴らしい例を見ることができます。このポッドキャストのページでは、CSS Shapesを使って、参加者たちの円形の写真にテキストが回りこむように設定されています。
Chromeでは左の図のように表示されますが、Firefoxではまだshapesがサポートされていないので、右の図のようにイメージの周りに矩形に表示されます。
Firefoxのユーザーはこのちょっとしたギミックを見ることができませんが、ユーザー・エクスペリエンスにダメージを与えるわけではありません。これをサポートしているブラウザー上でのみ美しく表示されるというわけです。
ブラウザーのサポート状況をCan I Useサイトで見ることができます。本原稿を執筆している時点では、SafariはCSS Shapesプロパティにwebkit prefixを追加する必要があります。
Shapes Level 1は現在、勧告候補ステータスですが、近い将来すべてのブラウザーでサポートされることが期待されています。現時点でこれを仕上げに使ってはいけない理由はありませんが、念のために、非サポートのブラウザーでもテキストがコンテンツの上にかぶさって読みにくくなっていないか確認するようにしてください。
polyfill Shapesを非サポートのブラウザー上でどう見えるか試したい場合は、AdobeのWeb PlatformチームがGithub上にpolyfillを使ったコードを公開していますのでご参考ください。