カスタムパスをラップするコンテンツ
長い間、ウェブデザイナーは長方形の制約の中でデザインを作成してきました。ほとんどのクリエイティブは長方形以外のレイアウトに挑戦しても失敗に終わるため、ウェブ上のコンテンツのほとんどはシンプルなボックスに収まっています。しかし、CSS シェイプの導入により、この状況は変わります。CSS シェイプは Chrome 37 以降で利用できます。CSS シェイプを使用すると、ウェブデザイナーは円、楕円、ポリゴンなどのカスタムパスにコンテンツをラップできるため、長方形の制約から解放されます。
シェイプは手動で定義することも、画像から推測することもできます。
非常に簡単な例を見てみましょう。
透明な部分のある画像を最初にフローティングしたとき、コンテンツが折り返されてギャップが埋まると期待していたものの、要素の周囲に長方形の折り返し形状が残り、私と同じようにがっかりしたことがあるかもしれません。この問題を解決するには、CSS シェイプを使用します。

<img class="element" src="image.png" />
<p>Lorem ipsum…</p>
<style>
.element{
shape-outside: url(image.png);
shape-image-threshold: 0.5;
float: left;
}
</style>
shape-outside: url(image.png)
CSS 宣言は、画像からシェイプを抽出するようブラウザに指示します。
shape-image-threshold
プロパティは、シェイプの作成に使用するピクセルの最小不透明度レベルを定義します。値は 0.0
(完全に透明)から 1.0
(完全に不透明)の範囲にする必要があります。shape-image-threshold: 0.5
は、不透明度が 50% 以上のピクセルのみがシェイプの作成に使用されることを意味します。
ここで重要なのは float
プロパティです。shape-outside
プロパティは、コンテンツが折り返される領域の形状を定義しますが、float がないと、その形状の効果は表示されません。
要素の float
値の反対側に浮動小数点領域があります。たとえば、コーヒーカップの画像を含む要素が左にフロートされている場合、フロート領域はカップの右側に作成されます。両側にギャップのある画像を作成することはできますが、コンテンツがラップされるのは、float プロパティで指定された反対側の図形(左または右)のみです。両側にラップされることはありません。
今後、CSS 除外機能の導入により、フローティングではない要素にも shape-outside
を使用できるようになります。
シェイプを手動で作成する
画像から形状を抽出するだけでなく、手動でコード化することもできます。シェイプを作成するには、circle()
、ellipse()
、inset()
、polygon()
の中から関数値を選択します。各シェイプ関数は座標のセットを受け取ります。この座標は、座標系を確立する参照ボックスとペアになります。参照ボックスの詳細については、後ほど説明します。
circle() 関数

円の形状値の完全な表記は circle(r at cx cy)
です。ここで、r
は円の半径、cx
と cy
は X 軸と Y 軸上の円の中心の座標です。円の中心の座標は省略可能です。省略すると、要素の中心(対角線の交点)がデフォルトとして使用されます。
.element{
shape-outside: circle(50%);
width: 300px;
height: 300px;
float: left;
}
上記の例では、コンテンツは円形のパスの内側に折り返されます。単一の引数 50%
は、円の半径を指定します。この場合は、要素の幅または高さの半分になります。要素のサイズを変更すると、円形の半径に影響します。これは、CSS シェイプをレスポンシブにする方法の基本的な例です。
先に進む前に、ちょっとした注意事項があります。CSS シェイプは、要素の周囲のフロート領域の形状にのみ影響します。要素に背景がある場合、その背景はシェイプによって切り抜かれません。この効果を実現するには、CSS マスクのプロパティ(clip-path または mask-image)を使用する必要があります。clip-path
プロパティは、CSS シェイプと同じ表記に従っているため、値を再利用できる点が非常に便利です。

このドキュメントのイラストでは、切り抜きを使用して形状を強調し、効果を理解できるようにしています。
円形に戻します。
円の半径にパーセンテージを使用する場合、値は実際には、sqrt(width^2 + height^2) / sqrt(2) という少し複雑な数式で計算されます。これは、要素のサイズが同じでない場合、結果としてどのような円になるかを想像するのに役立ちます。
シェイプ関数座標では、すべての CSS 単位タイプ(px、em、rem、vw、vh など)を使用できます。ニーズに合わせて柔軟性のあるものや堅牢なものを選択できます。
円の位置を調整するには、円の中心の座標に明示的な値を設定します。
.element{
shape-outside: circle(50% at 0 0);
}
これにより、円の中心が座標系の原点に配置されます。座標系とはここで、参照ボックスを導入します。
CSS シェイプの参照ボックス
参照ボックスは、要素の周囲にある仮想ボックスで、図形の描画と配置に使用される座標系を確立します。座標系の原点は左上隅にあり、X 軸は右、Y 軸は下を向いています。

shape-outside
は、コンテンツが折り返されるフロート領域の形状を変更します。フロート領域は、margin
プロパティで定義されたボックスの外側の端まで拡張されます。これは margin-box
と呼ばれ、明示的に指定されていない場合、シェイプのデフォルトの参照ボックスになります。
次の 2 つの CSS 宣言は同じ結果になります。
.element{
shape-outside: circle(50% at 0 0);
/* identical to: */
shape-outside: circle(50% at 0 0) margin-box;
}
要素にはまだ余白を設定していないため、この時点では、座標系の原点と円の中心が要素のコンテンツ領域の左上にあると想定しても問題ありません。余白を設定すると、次のように変わります。
.element{
shape-outside: circle(50% at 0 0) margin-box;
margin: 100px;
}
座標系の原点は、円の中心と同様に、要素のコンテンツ領域の外側(上 100 ピクセル、左 100 ピクセル)に移動しました。margin-box
参照ボックスによって確立された座標系のサーフェスの増加を考慮して、円の半径の計算値も大きくなります。


shape-outside
宣言で一度に使用できる参照ボックスは 1 つのみです。各参照ボックスは、形状に異なる影響を与えます。その影響は、場合によっては微妙なものになることもあります。CSS シェイプの参照ボックスについての記事では、さらに詳しく説明しています。
ellipse() 関数

楕円は、押しつぶされた円のような形状です。これらは ellipse(rx ry at cx cy)
として定義されます。ここで、rx
と ry
は X 軸と Y 軸上の楕円の半径で、cx
と cy
は楕円の中心の座標です。
.element{
shape-outside: ellipse(150px 300px at 50% 50%);
width: 300px;
height: 600px;
}
割合の値は、座標系のディメンションから計算されます。複雑な計算は必要ありません。楕円の中心の座標は省略できます。この場合、座標系の中心から推定されます。
X 軸と Y 軸の半径は、キーワードで定義することもできます。farthest-side
は、楕円の中心と、その中心から最も遠い参照ボックスの側面との距離に等しい半径を生成します。一方、closest-side
は正反対の意味を持ち、中心と側面との最短距離を使用します。
.element{
shape-outside: ellipse(closest-side farthest-side at 50% 50%);
/* identical to: */
shape-outside: ellipse(150px 300px at 50% 50%);
width: 300px;
height: 600px;
}
これは、要素のサイズ(または参照ボックス)が予測できない方法で変更される可能性があるが、楕円形状を適応させる必要がある場合に便利です。
circle()
シェイプ関数の半径にも、同じ farthest-side
キーワードと closest-side
キーワードを使用できます。
polygon() 関数

円や楕円では制限が多い場合は、ポリゴン形状関数を使用するとさまざまなオプションが利用できます。形式は polygon(x1 y1, x2 y2, ...)
で、ポリゴンの各頂点(ポイント)の x 座標と y 座標のペアを指定します。ポリゴンを指定するペアの最小数は 3 つ(三角形)です。
.element{
shape-outside: polygon(0 0, 0 300px, 300px 600px);
width: 300px;
height: 600px;
}
頂点は座標系に配置されます。レスポンシブなポリゴンでは、一部またはすべての座標にパーセンテージ値を使用できます。
.element{
/* polygon responsive to font-size*/
shape-outside: polygon(0 0, 0 100%, 100% 100%);
width: 20em;
height: 40em;
}
SVG からインポートされるオプションの fill-rule
パラメータは、自己交差するパスや閉じたシェイプの場合に、ポリゴンの「内側」をどのように考慮するかをブラウザに指示します。Joni Trythall は、SVG の fill-rule プロパティの仕組みについてわかりやすく説明しています。定義されていない場合、fill-rule
はデフォルトで nonzero
になります。
.element{
shape-outside: polygon(0 0, 0 100%, 100% 100%);
/* identical to: */
shape-outside: polygon(nonzero, 0 0, 0 100%, 100% 100%);
}
inset() 関数
inset()
シェイプ関数を使用すると、コンテンツをラップする長方形のシェイプを作成できます。CSS シェイプは、シンプルなボックスからウェブ コンテンツを解放するという最初の前提を考えると、これは直感に反するように思えます。可能性は十分あります。浮動とマージン、または polygon()
で実現できない inset()
のユースケースはまだ見つかっていない。ただし、inset()
は polygon()
よりも長方形の形状を読みやすく表現できます。
インセット シェイプ関数の完全な表記は inset(top right bottom left border-radius)
です。最初の 4 つの位置引数は、要素の端から内側へのオフセットです。最後の引数は、長方形の枠線の半径です。省略可能なため、指定しなくてもかまいません。これは、CSS ですでに使用されている border-radius
の省略形に従います。
.element{
shape-outside: inset(100px 100px 100px 100px);
/* yields a rectangular shape which is 100px inset on all sides */
float: left;
}
参照ボックスからシェイプを作成する
shape-outside
プロパティにシェイプ関数を指定しない場合、ブラウザが要素の参照ボックスからシェイプを導出できるようにできます。デフォルトの参照ボックスは margin-box
です。これまでのところ、特別なことは何もありません。これは浮動小数点数ですでに行われていることです。しかし、この手法を使用すると、要素のジオメトリを再利用できます。border-radius
プロパティについて見てみましょう。
これをフロート要素の角に適用すると、切り抜き効果は得られますが、フロート領域は長方形のままになります。shape-outside: border-box
を追加して、border-radius
によって作成された輪郭をラップします。

.element{
border-radius: 50%;
shape-outside: border-box;
float: left;
}
もちろん、すべての参照ボックスをこのように使用できます。派生シェイプの別の用途として、オフセット プルクォートがあります。

オフセット プルクォートの効果は、float プロパティと margin プロパティのみを使用して実現できます。ただし、その場合、引用符要素を HTML ツリー内のレンダリングする位置に配置する必要があります。
同じオフセット プルクォート効果をより柔軟に実現する方法は次のとおりです。
.pull-quote{
shape-outside: content-box;
margin-top: 200px;
float: left;
}
シェイプの座標系の content-box
参照ボックスを明示的に設定します。この場合、プルコートのコンテンツ量によって、外側のコンテンツがラップされる形状が決まります。ここでは、margin-top
プロパティを使用して、HTML ツリー内の位置に関係なく、プルクォートの位置(オフセット)を指定します。
図形の余白
コンテンツをシェイプにラップすると、要素に密着しすぎてしまうことがあります。シェイプの周囲にスペースを追加するには、shape-margin
プロパティを使用します。
.element{
shape-outside: circle(40%);
shape-margin: 1em;
float: left;
}
効果は通常の margin
プロパティを使用する場合と同様ですが、shape-margin
は shape-outside
値の周囲のスペースにのみ影響します。座標系にスペースがある場合にのみ、シェイプの周囲にスペースが追加されます。そのため、上記の例では、円の半径が 50% ではなく 40% に設定されています。半径を 50% に設定すると、円が座標系のすべてのスペースを占有し、shape-margin
の効果に余地がなくなります。図形は最終的に要素の margin-box
(要素とその周囲の margin
)に制限されます。図形が大きくオーバーフローした場合は、margin-box
にクリップされ、長方形になります。
shape-margin
は正の値を 1 つだけ受け入れることを理解することが重要です。長い記号はありません。円の shape-margin-top とは何ですか?
図形のアニメーション化
CSS の形状は、切り替えやアニメーションなど、他の多くの CSS 機能と組み合わせることができます。ただし、読んでいる最中にテキストのレイアウトが変更されると、ユーザーは非常に不快に感じます。シェイプをアニメーション化する場合、エクスペリエンスに細心の注意を払ってください。
circle()
シェイプと ellipse()
シェイプの半径と中心は、ブラウザが補間できる値で定義されている限り、アニメーション化できます。circle(30%)
から circle(50%)
への移動は可能です。ただし、circle(closest-side)
から circle(farthest-side)
へのアニメーション化はブラウザをクラッシュさせます。
.element{
shape-outside: circle(30%);
transition: shape-outside 1s;
float: left;
}
.element:hover{
shape-outside: circle(50%);
}

polygon()
シェイプをアニメーション化すると、より興味深い効果を得ることができます。ただし、2 つのアニメーション状態間でポリゴンの頂点数が同じである必要があります。頂点を追加または削除すると、ブラウザは補間できません。
1 つの方法として、必要な最大数の頂点を追加し、アニメーションの状態において、図形のエッジが少ないように、頂点をまとめて配置します。
.element{
/* four vertices (looks like rectangle) */
shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: shape-outside 1s;
}
.element:hover{
/* four vertices, but second and third overlap (looks like triangle) */
shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}

図形内にコンテンツを折り返す

CSS シェイプ仕様の最初のドラフトには、シェイプ内にコンテンツを折り返すことができる shape-inside
プロパティが含まれていました。一時期は Chrome と WebKit にも実装されていました。ただし、任意の位置に配置されたコンテンツをカスタムパス内にラップするには、考えられるすべてのシナリオを網羅し、バグを回避するために、はるかに多くの労力と調査が必要になります。そのため、shape-inside
プロパティは CSS シェイプ レベル 2 に延期され、その実装は取り下げられました。
ただし、多少の工夫と妥協をすれば、カスタム シェイプ内にコンテンツをラップする効果を実現できます。ハックは、shape-outside
を使用して 2 つのフローティング要素を使用し、コンテナの反対側に配置することです。ただし、セマンティックな意味を持たない空の要素を 1 ~ 2 つ使用する必要があります。これらの要素は、内部に形状があるように見せるための支柱として機能します。
<div>
<div class='left-shape'></div>
<div class='right-shape'></div>
Lorem ipsum...
</div>
コンテナの上部にある .left-shape
ストラット要素と .right-shape
ストラット要素の位置は重要です。これらの要素は、コンテンツの両側に浮動表示されるからです。
.left-shape{
shape-outside: polygon(0 0, ...);
float: left;
width: 50%;
height: 100%;
}
.right-shape{
shape-outside: polygon(50% 0, ...);
float: right;
width: 50%;
height: 100%;
}

このスタイル設定では、2 つのフローティング ストラットが要素内のすべてのスペースを占有しますが、shape-outside
プロパティによって残りのコンテンツのためのスペースが確保されます。
ブラウザで CSS シェイプがサポートされていない場合、すべてのコンテンツが下に押し下げられ、見栄えが悪くなります。そのため、この機能を段階的に強化していくことが重要です。
前述の形状アニメーションの例では、テキストが移動するのが煩わしい場合があります。すべてのユースケースでアニメーション化されたシェイプが適しているわけではありません。ただし、CSS シェイプとやり取りする他のプロパティをアニメーション化して、必要に応じて効果を追加できます。
CSS シェイプのアリス イン ワンダーランドのデモでは、スクロール位置を使用してコンテンツの上部余白を変更しました。テキストが 2 つのフロート要素の間に押し込まれています。下に移動するときに、2 つのフロート要素の shape-outside
に従って再レイアウトする必要があります。これにより、テキストが「うさぎの穴に落ちていく」ような印象を与え、ストーリーテリングのエクスペリエンスが向上します。ボーダーラインの不必要性必要な場合もある。でも、かっこいいですね。
テキストのレイアウトはブラウザによってネイティブに行われるため、JavaScript ソリューションを使用するよりもパフォーマンスが向上します。ただし、スクロール時に margin-top を変更すると、多くの再レイアウト イベントとペイント イベントがトリガーされ、パフォーマンスが著しく低下する可能性があります。使用する際はご注意ください。ただし、CSS シェイプをアニメーション化せずに使用しても、パフォーマンスへの影響はほとんどありません。
プログレッシブ エンハンスメント
まず、ブラウザが CSS シェイプをサポートしていないと仮定して、この機能を検出したときにその上に構築します。機能検出には Modernizr が適しています。「コア以外の検出」セクションに CSS シェイプのテストがあります。
一部のブラウザでは、外部ライブラリを必要とせずに、@supports
ルールを介して CSS で機能検出が可能です。CSS シェイプもサポートしている Google Chrome は、@supports
ルールを認識します。以下に、この機能を使用して段階的に強化する方法を示します。
.element{
/* styles for all browsers */
}
@supports (shape-outside: circle(50%)){
/* styles only for browsers which support CSS Shapes */
.element{
shape-outside: circle(50%);
}
}
CSS @supports ルールの使用方法について詳しくは、Lea Verou の記事をご覧ください。
CSS 除外による不明確性の解消
今日の CSS シェイプは、仕様の初期段階では CSS 除外とシェイプと呼ばれていました。名前の変更は微妙な違いのように思えますが、実際には非常に重要です。CSS 除外は、個別の仕様になりました。これにより、float プロパティを必要とせずに、任意に配置された要素の周囲にコンテンツをラップできるようになりました。絶対配置された要素の周囲にコンテンツをラップするとします。これは CSS 除外のユースケースです。CSS シェイプは、コンテンツが折り返されるパスを定義するだけです。
したがって、シェイプと除外は同じものではないものの、互いに補完し合います。CSS シェイプは現在ブラウザで使用できますが、CSS 除外はシェイプの操作ではまだ実装されていません。
CSS シェイプを操作するためのツール
従来の画像作成ツールでパスを作成できますが、現時点ではどのツールも CSS シェイプ値に必要な構文をエクスポートしません。仮に可能だったとしても、そのような働き方は現実的ではありません。
CSS シェイプは、ブラウザで使用することを想定しており、ページ上の他の要素に反応します。シェイプの編集がその周囲のコンテンツに与える影響を視覚化するために非常に便利です。このワークフローに役立つツールはいくつかあります。
Brackets: Brackets 用 CSS シェイプ エディタ拡張機能は、コードエディタのライブプレビュー モードを使用して、シェイプ値を編集するためのインタラクティブ エディタをオーバーレイします。
Google Chrome: Google Chrome 用 CSS シェイプ エディタ拡張機能は、ブラウザのデベロッパー ツールを拡張し、シェイプの作成と編集を行うコントロールを追加します。選択した要素の上にインタラクティブ エディタが表示されます。
Google Chrome のインスペクタには、シェイプのハイライト表示が組み込まれています。shape-outside
プロパティを持つ要素にカーソルを合わせると、要素が光ってシェイプが示されます。
画像から図形を生成: 画像を生成してブラウザで図形を抽出する場合は、Rebecca Hauck によるPhotoshop のチュートリアルをご覧ください。
ポリフィル: Google Chrome は、CSS シェイプをリリースした最初のメジャー ブラウザです。この機能は、Apple の iOS 8 と Safari 8 で近日中にサポートされる予定です。他のブラウザ ベンダーも今後検討する可能性があります。それまでは、基本的なサポートを提供する CSS シェイプ ポリフィルがあります。
まとめ
コンテンツのほとんどがシンプルなボックスに収められているウェブにおいて、CSS シェイプは表現力豊かなレイアウトを作成するための方法を提供し、ウェブと印刷デザインの忠実度ギャップを埋めます。もちろん、図形を悪用して注意をそらすこともできます。ただし、適度に、そして慎重に使用すれば、コンテンツの表現を強化し、ユーザーの注意を独自の方法で引き付けることができます。
最後に、他のクリエイターによる作品集をご紹介します。ほとんどが印刷物ですが、長方形以外のレイアウトの興味深い使い方をご覧いただけます。CSS シェイプを試して、新しいデザインのアイデアを試すきっかけになれば幸いです。
この記事をレビューして貴重な分析情報を提供してくださった Pearl Chen、Alan Stearns、Zoltan Horvath の皆様に心より感謝いたします。