矩形レイアウトを超えた !? - CSS Shapes で Web のレイアウトはもっと自由になる

wakamsha
138

今年の10月に参加した Adobe MAX 2014 では、アドビ製品に関連したモノだけでなくWebの最新テクノロジーにフォーカスしたセッションも多数行われました。その中の一つに CSS の次世代プロパティとも言える CSS Shapes について解説していたセッションがあったので参加してきました。

img-css_shapes_screenshots

今回はそんな CSS Shapes についてサンプルコードを交えながら解説していきたいと思います。

CSS Shapes とは?

CSS Shapes とは、テキストといったコンテンツ要素を従来の矩形だけでなく円形、三角形、その他複雑な多角形など様々な形状の領域に流し込んだり回り込ませることが出来る仕様のことです。これにより、まるで雑誌のような複雑なレイアウトであってもマークアップによって Web 上に表現することが可能となります。

ちなみに CSS Shapes とはshape-outsideshape-marginshape-image-thresholdの3つの属性を一括りにした呼称のことです。

shape-outside
対象となる要素のシェイプを定義する
shape-outside – CSS | MDN
shape-margin
シェイプに沿った形でのマージンを定義する
shape-margin – CSS | MDN
shape-image-threshold
画像データからシェイプを定義する際に、しきい値となるAlphaチャンネル値を設定する (※ 詳細は後述します)
shape-image-threshold – CSS | MDN

CSS Shapes のブラウザ・サポート状況

現在のブラウザ・サポート状況は以下のとおりです。

Internet Explorer Firefox Chrome Safari Opera
37 ~ 7.1 ~ 25 ~
iOS Safari Android Browser Chrome for Android
8 ~ 37 ~ 39 ~

そんな訳で、現状は Webkit エンジンを搭載しているブラウザのみ対応しているようです。まだまだ実用段階とは言い難いですが、一足先に最新の機能を知っておいて損はないでしょう。

はじめての CSS Shape

Circle

まずは一番簡単なものからということで、円形の要素に沿って回りこませる方法を試してみるとします。やり方は簡単で、要素にshape-outsideというプロパティを適用するだけです。

.element {
  -webkit-shape-outside: circle(50% at 50% 50%) border-box;
          shape-outside: circle(50% at 50% 50%) border-box;
  float: left;
}

shape-outside プロパティにcircle()という値を指定しています。名前の通り円形のシェイプであることをブラウザに認識させます。circle() には以下の要領で引数を渡します。

shape-outside: circle( radius at x y );

radiusにシェイプの半径を指定します。100%で元要素の幅と同じになります。続くx, yでシシェイプの中心の座標を指定します。

ここで一つ忘れてならないのが、シェイプ要素に対してfloatを定義する必要があるということです。CSS Shapes は要素の float area を定義する仕様なので、float を定義することで周囲の要素がシェイプを取り囲むことができるようになるというわけです。

以下のサンプルは円形のシェイプに対してテキストが回りこんでいるものです。

DEMO

See the Pen CSS Shapes demo#1 by wakamsha (@wakamsha) on CodePen.

円形の要素にマウスオーバーすると拡大し、それに合わせて回りこんでいるテキストの位置も調整されます。シェイプを定義する要素はdiv要素でも画像要素でも構いません。

Ellipse

circle と同様に ellipse (楕円形)もシェイプとして定義出来ます。こちらも shape-outside にellipse()という値を設定します。

shape-outside: ellipse( radiusX radiusY at x y );

座標の指定は circle() と同じですが、半径が横軸と縦軸とで異なるので、それぞれ指定します。こちらもやはり半角スペース区切りで、間違ってもカンマで区切ってはいけません。

DEMO

See the Pen CSS Shapes demo#2 by wakamsha (@wakamsha) on CodePen.

様々な形状

画像データからシェイプを自動解析させる

先ほどのデモで使用した画像はシェイプがシンプルな正円だったので簡単でしたが、もっと複雑な形状となるとどうでしょうか。その際はshape-outsideにpngもしくはgif画像のファイルパスを指定することで簡単に解決することが出来ます。

png および gif 画像は Alpha チャンネルという不透明度のプロパティをもっており、これをしきい値としてシェイプの領域をブラウザが自動解析してくれるというわけです。便利ですね。

.element {
  padding-right: 10px;
  width: 180px;
  -webkit-shape-outside: url('wakamsha_01.png');
          shape-outside: url('wakamsha_01.png');
  -webkit-shape-image-threshold: 0.1;
          shape-image-threshold: 0.1;
  -webkit-shape-margin: 10px;
          shape-margin: 10px;
  float: left;
}

shape-image-thresholdで Alpha チャンネルのしきい値を設定します。上記の例では画像の Alpha が 0.1 以上である領域をシェイプとして定義します。デフォルト値は 0 で、完全透明な領域以外はシェイプとして定義されます。

DEMO

shape-image-threshold についての詳しい仕様は、こちらをご参照ください。

Polygon

元となる画像が Alpha チャンネルを持たない jpeg 型式であったり任意の領域を定義したい場合は、shape-outside プロパティにpolygon()という値を指定します。以下の要領で引数に多角形の座標を渡します。

.element {
  -webkit-shape-outside: polygon( x1 y1, x2 y2, x3 y3, … );
          shape-outside: polygon( x1 y1, x2 y2, x3 y3, … );
  float: left;
}

xyの座標値のペアをカンマ区切りで順番に渡していくことで多角形の領域を定義します。くれぐれも x と y をカンマ区切らないように気をつけてください。

DEMO

See the Pen CSS Shapes demo#3 by wakamsha (@wakamsha) on CodePen.

Chrome DevTool 拡張機能で複雑な Polygon も簡単に定義出来る

Polygon() に渡す座標を一つ一つ手打ちで入力するのは非常に大変ですが、Chrome の拡張機能である CSS Shapes Editor を使えば、コードを直接書くことなくマウス操作だけで直感的に Polygon シェイプを定義することが出来ます。

img-css_shapes_editor_screenshot

img-css_shapes_editor_tab

使い方は至って簡単。CSS Shapes Editor をインストールした後、Dev tool を開いて Elements タブを選択します。するとshapesというタブが新たに追加されています。ここで shape-outside と -webkit-clip-path の値をグラフィカルに編集することが出来ます。

shape-outside の右隣にあるをクリックすると、画像のようなパスが要素の周囲に表示されます。この点線上にあるポインタをドラッグすることで思い通りのシェイプを作ることが出来ます。ポインタは点線の上をクリックすればいくらでも追加することが出来ます。不要になったポインタを削除したい時は、そのポインタをダブルクリックすればOK。

demo_4___CSS_Shapes

パスを操作した結果はリアルタイムでコード化されます。最終的に以下のようなコードが出来上がりました。これを CSS ファイルにコピペすれば完了です。

shape-outside:  polygon(211px 669px, 212px 543px, 69px 481px, 108px 251px, 0px 195px, 94px -3px, 401px -2px, 401px 712px, 241px 713px);

最後に JavaScript (CoffeeScript) によるちょっとトリッキーな動きのデモを作ってみました。以下にあるデモをスクロールしてみてください。テキストがシェイプに沿って動いていくのが分かります1)実際のサイトではマトモにテキストが読めなくなるので、あくまでインパクト勝負として考えて頂ければ、と。

DEMO

See the Pen CSS Shapes demo#4 by wakamsha (@wakamsha) on CodePen.

元ネタはこちら。

参考サイト

脚注

脚注
1 実際のサイトではマトモにテキストが読めなくなるので、あくまでインパクト勝負として考えて頂ければ、と。