CSS Shapes / shape-outside

CSS Shapes(シェイプ) や CSS ボックスモデルのボックス値 shape-box、基本シェイプを定義する basic-shape などの基本的なことや shape-outside プロパティの使い方についての覚書です。shape-outside プロパティを使えばいろいろな形状にテキストを回り込ませることができます。

clip-path プロパティと一緒に使用すれば、clip-path で切り抜いた形状にテキストを回り込ませることが簡単にできます。

作成日:2021年2月3日

CSS Shapes(シェイプ) とは

CSS Shapes とは CSS におけるシェイプ (形状)に関する定義で、以下の3つのプロパティが「CSS Shapes Module Level 1」で定義されています。

CSS Shapes プロパティ
プロパティ 概要
shape-outside フロート領域の形状を定義するプロパティ
shape-image-threshold 画像ファイルから図形を抽出する際のアルファチャンネル(透明度)のしきい値を設定するプロパティ
shape-margin 定義されたシェイプの周囲のマージンを設定するプロパテ

CSS Shapes の shape-outside プロパティを使えば、例えばこのように float を適用した図形や画像に沿ってテキストを回り込ませて配置することができます。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

float が必須

CSS Shapes(シェイプ)は要素のフロートした領域(float area)を定義する仕様で、フロートした要素に適用するように設計されています。

そのため、要素に float が設定されていない場合は CSS Shapes の設定は無効となります。

ブラウザの対応状況

現時点(2021年01月)では IE 以外の最新のブラウザはほとんど対応しているようです。

https://caniuse.com/?search=shape

参考サイト:

関連ページ:

基本的な使い方

基本的には要素に float(値は left または right)を設定し、shape-outside プロパティを使ってシェイプを定義して要素に適用します。

シェイプとはコンテンツが折り返される形状のことで、フロートした要素へのテキストなどの回り込みの形状(フロート領域の形状)のことです。

shape-outside プロパティを使ったシェイプの定義は大きく分けると以下の3つの方法があります。

  • 円や楕円、多角形などの図形を定義する基本シェイプ(basic-shape)の関数を使って定義
  • ボックスの形状を表すボックス値(shape-box )使って定義
  • 画像やグラデーションのアルファチャネル(透明度の値)に基づいて定義

以下は円形のシェイプを適用した要素に沿ってテキストを回りこませる例です。

1つ目は円のシェイプを定義する basic-shape(基本シェイプ)の関数 circle() を使う例です。

クラス .shape を指定した img 要素に float と shape-outside プロパティを適用して、後続のコンテンツのテキストを円形に回り込ませます。

以下の例では img 要素に width と height を設定しています(CSS で設定することもできます)。

HTML
<div class="shape-wrapper">
  <img class="shape" src="/images/sample.png" width="200" height="200" alt="">
  <p>Lorem ipsum dolor sit amet, ...  pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore ... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>

circle() では円の半径と中心座標を指定します。中心座標を省略した場合は要素(基準ボックス)の中心が中心座標に設定されます。指定する値は単位付きの値またはパーセントが使用できます。

CSS
.shape {
  float: left; /* フロートを指定(必須) */
  shape-outside: circle(50%); /* 円形のシェイプを定義 */
  margin: 0 20px 20px 0;
}
/* わかりやすい(見やすい)ように外側の要素に以下を指定 */
.shape-wrapper {
  margin: 50px 0;
  padding: 20px;
  max-width: 600px;
  background-color: #DEF3FB;  /* 水色の背景色 */
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

2つ目の以下の例は、同じ HTML で前述とほぼ同じことを shape-box のボックス値のキーワード margin-box を指定してシェイプを定義しています。

margin-box はマージン辺で囲まれた形状を定義し、border-radius を使って形状を角丸にすることができます。この例では border-radius に 50% を指定して形状を円にしています。

CSS
.shape {
  float: left; /* フロートを指定(必須) */
  shape-outside: margin-box; /* ボックス値(キーワード)を指定 */ 
  border-radius: 50%;
  margin:  0 20px 20px 0;
  width: 200px;
  height: 200px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

3つ目の例は画像のアルファチャネル(透明部分)に基づいてシェイプを定義しています。

この例の場合、以下のような背景が透明の PNG 画像を使用しているので、後続のコンテンツ(テキスト)を画像の不透過な部分に回り込ませることができます。

shape-outside プロパティに透明部分のある画像のパスを url() で指定するだけです。

但し、この場合、シェイプの周囲とテキストとの間のマージンを shape-margin プロパティを使って指定しています。

.shape {
  float: left; /* フロートを指定(必須) */
  shape-outside: url(/images/sample.png); /* 画像への参照を指定 */
  margin:  0 20px 20px 0;
  shape-margin: 20px; /* シェイプとテキストとの間のマージンを指定 */
  width: 200px;
  height: 200px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

今までの例では画像に沿ってテキストを回り込ませていましたが、空の要素などにシェイプを定義して見えない線に沿ってテキストを流し込むこともできます。

以下は空の div 要素にシェイプを定義して、見えない円の形状に沿ってテキストを流し込む例です。

HTML
<div class="shape-wrapper">
  <div class="shape"></div>
  <p>Lorem ipsum dolor sit amet, ...  pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore ... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>

以下のいずれの方法でも同じ結果になります。

CSS
/* 基本シェイプの circle() を使う場合 */
.shape {
  float: left;
  shape-outside: circle(50%);
  width: 200px;
  height: 200px;
}

/* ボックス値のキーワード margin-box を使う場合 */
.shape {
  float: left;
  shape-outside: margin-box;
  border-radius: 50%;
  width: 200px;
  height: 200px;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

疑似要素を使う例

前述の例のような場合、疑似要素(::before)を使って CSS だけで同様のことを実現することができます。

以下は高さと幅が200pxの疑似要素を生成して、その要素にシェイプを適用しています。

HTML
<div class="shape-wrapper circle-shape">
  <p>Lorem ipsum dolor sit amet, ...  pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore ... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>

以下のいずれの方法でも同じ結果になります。但し、3つ目の方法は Firefox でのみ機能します。

/* 基本シェイプ circle() を使う方法 */
.circle-shape::before {
  content: "";  
  display: block;
  height: 200px;
  width: 200px;
  float: left; 
  shape-outside: circle(50%);
}
  
/* ボックス値 margin-box を使う方法 */
.circle-shape::before {
  content: "";
  display: block;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  float: left;
  shape-outside: margin-box;
}

/* Firefox のみ機能 | 画像のアルファチャネル(透明部分)を使う方法 */
.circle-shape::before {
  content: "";
  display: block;
  height: 200px;
  width: 200px;
  float: left;
  shape-outside: url(/images/sample.png);
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

clip-path と shape-outside

シェイプを作成(定義)するために使う基本シェイプ(basic-shape)とボックス値(shape-box)は、 clip-path の値として使用するものと同じです。

このため、clip-path で切り抜いた画像(要素)にテキストを回り込ませるには shape-outside に clip-path に指定した同じ値を使用します(異なる値を使って位置をずらす等もできます)。

前述の例では円形の画像を使用しましたが、以下では次の画像を使います。

300px 225px

以下は基本シェイプの circle() を使って clip-path で切り抜いた画像の回りに shape-outside でテキストを流し込む例です。

この例の場合、clip-path での circle() では花の部分を中心に切り取るため座標位置を指定していますが、シェイプとしては shape-outside の circle() と同じ半径の円になります。

HTML
<div class="shape-wrapper">
  <img class="clip-shape" src="/images/sample.png" width="200" height="200" alt="">
  <p>Lorem ipsum dolor sit amet, ...  pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore ... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>
.clip-shape {
  float: left; /* フロートを指定(必須) */
  clip-path: circle(112.5px at 140px 112.5px);   /* 円形に切り抜き */       
  shape-outside: circle(112.5px); /* clip-path と同じ値を指定 */
  margin-left: -30px; /* 位置の調整 */
}   

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

300px 225px (140px , 112.5px) r = 112.5px circle(112.5px at 140px 112.5px) での切り抜き部分

clip-path の詳細は「CSS clip-path の使い方」を御覧ください。

以下は CSS シェイプのそれぞれのプロパティの詳細です。

shape-outside

shape-outside プロパティを使ってシェイプを定義することができます。

shape-outside プロパティは折り返しの形状を定義し、その形状の周りにテキストを折り返す(回り込ませる)ことができます。shape-outside に指定する値によりシェイプを定義する方法は異なってきます。

また、shape-outside プロパティはフロート要素に対してのみ有効なため、shape-outside プロパティを指定する要素には、同時に float を指定する必要があります。

以下が shape-outside プロパティのおおまかな構文です。

shape-outside: shape-box | basic-shape | image | none 

以下のように shape-box のキーワードや basic-shape の関数、画像への参照、グラデーションの値などを指定できます。指定する値により定義する方法が異なってきます。

/* none や shape-box のキーワード */
shape-outside: none;
shape-outside: margin-box;
shape-outside: content-box;
shape-outside: border-box;
shape-outside: padding-box;

/* basic-shape(基本シェイプ)の関数 */
shape-outside: circle();
shape-outside: ellipse();
shape-outside: inset(10px 10px 10px 10px);
shape-outside: polygon(10px 10px, 20px 20px, 30px 30px);
shape-outside: path('M0.5,1 C0.5,1,0,・・・中略・・・ C1,0.7,0.5,1,0.5,1 Z');

/* url() を使った画像への参照 */
shape-outside: url(image.png);

/* グラデーションの値 */
shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px);

shape-outside プロパティは以下のような値を指定することができます。初期値は none です。

shape-outside プロパティ(MDN | CSS Shapes Module Level 1
説明
shape-box
ボックス値
フロート領域は border-radius による形状も含め、フロートした要素の CSS ボックスモデルで定義されている以下のボックス値に従って算出されます。
  • margin-box
  • border-box
  • padding-box
  • content-box
basic-shape
基本シェイプ
フロート領域は、以下のいずれかの basic-shape(基本シェイプ)の関数によって作成された形状に基づいて算出されます。
  • inset()
  • circle()
  • ellipse()
  • polygon()
  • path() ※レベル2(草案)で追加
shape-box も指定されている場合は、basic-shape 関数の参照ボックスを定義します。 それ以外の場合、参照ボックスはデフォルトで margin-box になります。
image
画像値
フロート領域は指定された image の shape-image-threshold で定義されたアルファチャネル(透明度の値)に基づいて抽出および算出されます。
none 初期値。フロート領域は影響を受けません。 shape-outside を指定しないのと同じで、インラインコンテンツは通常どおり要素のマージンボックスを囲みます。

shape-box / ボックス値からシェイプを作成

シェイプ(shape-outside の値)にボックス値のキーワードを指定すると、CSS ボックスモデルで定義された辺でコンテンツを折り返すことができます。

margin マージン辺 border ボーダー辺 padding パディング辺 content 内容辺 CSS ボックスモデルで定義された辺
<div class="sample-wrapper">
  <div class="sample">
    <p class="content" >content</p>
  </div>
</div>
.sample-wrapper {
  border: 1px dashed #666; /* 親要素のボーダー(グレーの点線) */
  width: 320px;
} 
.sample{
  margin:30px; /* マージン */
  border: 20px solid darkseagreen; /* ボーダー(緑系の色) */
  padding: 20px; /* パディング */
  background-color: #EF6D6F; /* 背景色(パディング部分の赤系の色) */
  width:260px;
  height:140px;
}
.content {
  background-color:#4C68D0;; /* 内容の背景色(青系の色) */
  color: white; 
  width: 180px; 
  height: 60px; 
  margin: auto;
}

以下のようなボックス値が定義されています。

margin-box
マージン辺で囲まれた形状。margin の縁と border-radius(シェイプの角の半径)によって定義されます。
border-box
ボーダー辺で囲まれた形状。border の外側の縁で定義されるシェイプで、border の外側の角の丸め規則に従います。CSS の border プロパティを使用していない場合、境界は padding-box と同じになり、シェイプはパディングの縁の外側として定義されます。
padding-box
パディング辺で囲まれた形状。パディングの縁に囲まれたシェイプを定義し、境界の内側の角の丸め規則に従います。パディングがない場合、 padding-box は content-box と同じです。
content-box
内容辺で囲まれた形状。コンテンツの外側の縁で囲まれたシェイプを定義します。このボックスにおけるそれぞれの角の丸めの半径は、以下の式の結果を 0 以上に切り上げた値になります。
border-radius − border-width − padding

動作確認サンプル

以下は shape-outside の値に上記のボックス値のキーワードを指定して動作を確認するサンプルです。

高さと幅を指定した div 要素(.shape-box1)に float と border-radius を指定し、shape-outside を設定してシェイプを作成しています。

初期状態では shape-outside に margin-box を指定しています。border-radius や margin、border、padding、float の値を変更することができます。

HTML
<div class="shape-wrapper">
  <div class="shape-box1"><p>content content content</p></div>
  <p>Lorem ipsum dolor sit ....pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam .... Quae, quasi!</p>
  <p>Suscipit aliquam maiores ... fugiat, totam!</p>
</div>
CSS
.shape-wrapper {
  margin: 50px 0;
  padding: 20px;
  max-width: 600px;
  background-color: #DEF3FB;
}
.shape-box1 {
  float: left;
  shape-outside: margin-box;
  border-radius: 50%;
  margin: 30px;
  border: 20px solid silver;
  padding: 30px;
  background-color: gold; 
  width: 160px;
  height: 160px;
  box-sizing: border-box;
}
.shape-box1 p {
  background-color: white;
  color: limegreen;
}

content content content

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

shape-outside
border-radius 50%
margin 30
border 20
padding 30
float left right none
box-sizing border-box content-box
初期状態に戻す

参考サイト:MDN ボックス値からのシェイプ

basic-shape / 基本シェイプで作成

shape-outside の値に以下のいずれかの basic-shape(基本シェイプの関数)を指定してシェイプを定義することができます(clip-path プロパティに指定する basic-shape と同じです)。

basic-shape 基本シェイプの関数
意味
inset() 矩形(四角形)を定義します。
circle() 正円を定義します。
ellipse() 楕円を定義します。
polygon() 多角形を定義します。
path() パスによる図形を定義します。※レベル2(CSS Shapes Module Level 2 草案)で追加

必要に応じて basic-shape の後に shape-box(ボックス値)を続けて指定することで、basic-shape 関数の基準ボックス(参照ボックス)を設定することができます。

指定しない場合の既定の基準ボックスは margin-box です。

.shape {
  shape-outside: circle(50%) border-box; /* 基準ボックスを border-box に設定 */
}

参考サイト:

inset()

inset() は内側へオフセットされた矩形(四角形)を定義します。以下がおおまかな書式です。

inset( length [ round ] )
意味
length 要素(基準ボックス)の各端からの距離(オフセット)を単位付きの値または % で指定します。指定方法は margin などと同じで値を1〜4個まで半角スペースで区切って指定します。
  • 値が1つ:「上下左右」
  • 値が2つ:「上下」と「左右」
  • 値が3つ:「上」と「左右」と「下」
  • 値が4つ:「上」と「右」と「下」と「左」(時計回り)
round ボックスの角を丸くする(角丸にする)場合に角丸の半径の値を指定します。指定方法は border-radius の略式プロパティと同じです。
  • 値が1つ:全ての角の半径
  • 値が2つ:「左上と右下」と「右上と左下」
  • 値が3つ:「左上」と「右上と左下」と「右下」
  • 値が4つ:「左上」と「右上」と「右下」と「左下」(時計回り)

inset() は長方形(矩形)の形状を定義します。HTML の領域は矩形なのであまり便利ではないように思えますが、オフセットを定義できるため、コンテンツをシェイプの内側に引き込むことができます。

また、round に角丸の半径を指定して角を丸くすることができます。

以下は inset() にオフセット(length)と角丸(round)を指定してコンテンツをシェイプを適用した要素の内側に表示する例です。

HTML
<div class="shape-wrapper dark">
  <img class="inset1" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ... pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore .... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>
            
<!-- 上記は以下のように img 要素を囲む div 要素にシェイプを定義しても同じです -->            
<div class="shape-wrapper dark">
  <div class="inset1">
    <img src="/images/sample.jpg" alt="">
  </div>
  <p>Lorem ipsum dolor sit amet, ... pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore .... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,...fugiat, totam!</p>
</div>
CSS
.inset1 {
  float: left;
  width: 300px;
  height: 225px;
  shape-outside: inset( 40px 50px 40px 0 round 100px );
  margin: 10px;
}
.shape-wrapper {
  margin: 50px 0;
  padding: 20px;
  max-width: 600px;
  background-color: #DEF3FB;
}
.dark {
  background-color: #444;
  color: #fefefe;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

上記の inset( 40px 50px 40px 0 round 100px ) では以下のようなシェイプが定義されています。

40px 40px 50px 0 (px) 半径:100px の角丸

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

clip-path

以下は clip-path で inset() を使って切り抜いた画像の回りに、同じ inset() の値を指定した shape-outside でテキストを回り込ませる例です。

HTML
<div class="shape-wrapper"> 
  <img class="inset2" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ... pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam .... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta,... fugiat, totam!</p>
</div>
CSS
.inset2 {
  float: left;
  width: 300px;
  height: 225px;
  clip-path: inset( 30px 50px 30px 25px round 40px 40px 60px 60px );
  shape-outside: inset( 30px 50px 30px 25px round 40px 40px 60px 60px );
  margin:0 20px 0 -30px; /* 画像の位置を調整 */
}
.shape-wrapper {
  margin: 50px 0;
  padding: 20px;
  max-width: 600px;
  background-color: #DEF3FB;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

clip-path:inset( 30px 50px 30px 25px round 40px 40px 60px 60px ) による切り抜きは以下のようになっています。

25px 50px 30px 30px r=40 r=40 r=60 r=60
circle()

circle() は正円を定義します。以下がおおまかな書式です。

circle( shape-radius [at position ] )
意味
shape-radius 正円の半径を単位付きの値またはパーセントで指定します。 パーセントで指定する場合、要素(基準ボックス)に対しての比率になり、基準ボックスの[ 幅, 高さ ]から式[ √( 横幅の 2 乗 + 縦幅の 2 乗 ) ÷ √ 2 ]を基準に算出されます。また、値の代わりに次のキーワードを指定することもできます。
  • closest-side:図形の中心から 基準ボックスの最も近い側までの長さ
  • farthest-side:図形の中心から 基準ボックスの最も遠い側までの長さ
at position 円の中心を定義します。at に続けて円の中心の座標(半角スペース区切りのX座標とY座標)やキーワードを指定します。
  • 省略時の既定は center (基準ボックスの中心)になります。
  • position に指定するキーワードは
    • left | center | right (X軸方向)
    • top | center | bottom(Y軸方向)
    center 以外のキーワードでは一緒にオフセット値を指定することができます。

以下は幅と高さが200pxの div 要素に circle() を使って円形のシェイプを定義する例です。

シェイプを適用している div 要素にも border-radius: 50% を指定して円形にしています。

<div class="shape-wrapper">
  <div class="circle1"></div>
  <p>Lorem ipsum dolor sit amet,...dicta nulla pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores ...expedita fugiat, totam!</p>
</div>

以下は circle() に円の半径 50% と中心 center を指定しているので、画像の中心から半径 50% のシェイプが作成されます。

また、 基本シェイプの後に shape-box(ボックス値)を続けて指定することで、basic-shape 関数の基準ボックスを設定することができます。この例では既定値の margin-box を指定しています。

.circle1 {
  float: left;
  shape-outside: circle(50% at center) margin-box;
  width: 200px;
  height: 200px;
  margin: 20px;
  padding: 20px;
  border: 20px solid #fff;
  background-color:#F8D6E0;
  box-sizing: border-box;
}
.shape-wrapper {
  margin: 50px 0;
  padding: 20px;
  max-width: 600px;
  background-color: #DEF3FB;
}

以下は circle() の半径と中心座標(この例では一部キーワードのみ選択可能)を変更して、作成されるシェイプを確認するサンプルです。初期状態では上記 .circle1 の設定になっています。

適用される div 要素のマージンやパディング、ボーダーは変更することができますが、width と heigth は一定で box-sizing は border-box としているので、表示されている div 要素の大きさは変わりません。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

円の半径 50%
中心座標
margin 20
border 20
padding 20
float left right none
基準ボックス
半径をパーセントで指定

半径をパーセントで指定することができますが、パーセントで指定する場合、要素(基準ボックス)に対しての比率になり、基準ボックスの[ 幅, 高さ ]から以下の式を基準に算出されます。

√( 幅の 2 乗 + 高さの 2 乗 ) ÷ √ 2 
            
または以下のような書き方もします(width:幅, height:高さ)

sqrt( width^2 + height^2 )/sqrt(2)

また、基準ボックスに対しての比率になるので、例えば、既定の margin-box の場合は、margin の値も含めて算出されるので注意が必要です。

縦横比が1:1(幅と高さが同じ)であれば簡単ですが、そうでない場合は少し面倒です。

例えば、幅が300px、高さが225pxの場合、パーセントで指定する際の基準値は以下になります。

√( 300 の 2 乗 + 225 の 2 乗 ) ÷ √ 2 = 265.16505(この値が100%)

高さ 225px の画像で高さいっぱいの円にするには 112.5px を半径に指定すればよいのですが、%で指定する場合は以下のように約 42.42% になります。

112.5 ÷ 265.16505 = 0.424264

clip-path と併用

以下は幅が300px、高さが225pxの画像を高さの半分の半径(%で指定)でクリッピングしてその回りにテキストを流し込む例です。

HTML
<div class="shape-wrapper">
  <div class="circle2"><img src="/images/sample.jpg" width="300" height="225" alt=""></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.circle2 {
  /* フロートを指定 */
  float: left; 
  width: 300px;
  height: 225px;
  /* 円形に切り抜き(高さの半分の半径 112.5px を%で指定) */
  clip-path: circle(42.42%);   
  /* clip-path と同じ値を指定 */
  shape-outside: circle(42.42%); 
  /* 位置の調整 */
  margin: 20px 20px 20px -30px;    
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

ellipse()

ellipse() は楕円を定義します。以下がおおまかな書式です。

ellipse( shape-radius [at position ] )
意味
shape-radius 楕円のX軸半径とY軸半径を半角スペース区切りで、単位付きの値または % で指定します。 % で指定する場合、X軸半径とY軸半径はそれぞれ要素(基準ボックス)の幅と高さに対しての比率になります。また、値の代わりに次のキーワードを指定することもできます。
  • closest-side:図形の中心から 基準ボックスの最も近い側までの長さ
  • farthest-side:図形の中心から 基準ボックスの最も遠い側までの長さ
at position 楕円の中心を定義します。at に続けて楕円の中心の座標(半角スペース区切りのX座標とY座標)やキーワードを指定します。
  • 省略時の既定は center (基準ボックスの中心)になります。
  • position に指定するキーワードは
    • left | center | right (X軸方向)
    • top | center | bottom(Y軸方向)
    center 以外のキーワードでは一緒にオフセット値を指定することができます。

ellipse() は circle() に似ていますが、ellipse() はX軸(水平方向)とY軸(垂直方向)の半径を半角スペース区切って「X軸半径 Y軸半径」の順番で指定します。

circle() 同様、at に続いて中心座標を指定でき、省略した場合は規定の center (基準ボックスの中心)になります。

以下は幅100px、高さが150pxの div 要素に ellipse() を使って楕円のシェイプを定義する例です。

シェイプを適用している div 要素にも border-radius: 50% を指定して楕円にしています。

HTML
<div class="shape-wrapper">
  <div class="ellipse"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.ellipse {
  /* フロートを指定 */
  float: left;  
  shape-outside: ellipse(50% 50% at center) margin-box;
  width: 100px;
  height: 150px;
  margin: 30px 20px 30px 0;
  padding: 20px;
  border: 10px solid #fff;
  background-color: #F8F09B;  /* 淡黄色 */
  border-radius: 50%;
  box-sizing: border-box;
}

上記の shape-outside プロパティの座標(at center)と基準ボックス(margin-box)は既定値なので単に shape-outside: ellipse(50% 50%) としても同じです。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

半径をパーセントで指定

半径をパーセントで指定する場合、X軸半径とY軸半径はそれぞれ「基準ボックスの幅と高さ」に対しての比率になります。

前述の例では幅100px、高さが150pxの div 要素に ellipse(50% 50%) と指定していますが、同じことをpxで指定する場合は以下のように基準ボックスを考慮に入れる必要があります。

  • X軸半径:(幅 100px + 右マージン 20px)/2 = 60px
  • Y軸半径:(高さ 150px + 上下マージン 60px)/2 = 105px
.ellipse {
  float: left;
  shape-outside: ellipse(60px 105px) ;
  ...
}
ellipse() サンプル

以下は ellipse() の動作を確認するサンプルです。

このサンプルでは、ellipse() の X軸半径とY軸半径は 50% 50% の固定にしてあり、シェイプを適用する div 要素の width と height を変更できるようにしています。また、div 要素自体には border-radius: 50% を設定して楕円にしています。

HTML
<div class="shape-wrapper">
  <div class="ellipse2"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
.ellipse2 {
  float: left;
  shape-outside: ellipse(50% 50% at center) margin-box;
  width: 100px;
  height: 150px;
  margin: 20px;
  padding: 20px;
  border: 20px solid #fff;
  background-color: #F8F09B;   /* 淡黄色 */
  border-radius: 50%;
  box-sizing: border-box;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

div 要素 width 100px
div 要素 height 150px
中心座標
margin 20px
border 20px
padding 20px
float left right none
基準ボックス

このサンプルでは、ellipse() の X軸半径とY軸半径を変更できるようにしています。div 要素の width と height はそれぞれ 200px、150px の固定にしてあります。

HTML
<div class="shape-wrapper">
  <div class="ellipse3"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
.ellipse3 {
  float: left;
  shape-outside: ellipse(50% 50% at center)  margin-box;;
  width: 200px;
  height: 150px;
  margin: 20px;
  padding: 20px;
  border: 20px solid #fff;
  background-color: #F8F09B;   /* 淡黄色 */
  border-radius: 50%;
  box-sizing: border-box;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

X軸半径 50%
Y軸半径 50%
中心座標
margin 5px
border 5px
padding 5px
float left right none
基準ボックス

clip-path と併用

以下は幅が300px、高さが225pxの画像を clip-path と ellipse() で楕円に切り抜きして、clip-path に指定した値と同じ値を shape-outside に指定してその回りにテキストを流し込む例です。

HTML
<div class="shape-wrapper">
  <div class="ellipse4">
    <img src="/images/sample.jpg" width="300" height="225" alt="">
  </div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.ellipse4 {
  /* フロートを指定 */
  float: left;
  width: 300px;
  height: 225px;
  /* 楕円形に切り抜き(X軸、Y軸半径を指定) */
  clip-path: ellipse(50% 40%);
  /* clip-path と同じ値を指定 */
  shape-outside: ellipse(50% 40%) margin-box;
  margin: 20px;
}

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

polygon()

polygon() は多角形(3つ以上の頂点を持つ任意の形状)を定義します。以下がおおまかな書式です。

polygon( [fill-rule,] 頂点の座標1, 頂点の座標2, 頂点の座標3,... )
意味
fill-rule 塗り潰し方法を指定します。nonzero(初期値)または evenodd(領域が囲まれている線の本数が奇数の場合は塗り潰し、偶数の場合は塗らない)を指定できます。参考:SVG fill-rule プロパティ
頂点の座標 多角形の頂点のスペース区切りのX座標とY座標のペアをカンマ区切りで指定します。座標は左上が原点 (0px 0px) または (0% 0%) になり、値は単位を含む数値や相対的な%で指定でき、数値と%を混ぜて指定することもできます。

以下は幅と高さが200pxの div 要素に polygon() を使って3角形のシェイプを定義する例です。

polygon() には3つの頂点の座標を指定しています。

HTML
<div class="shape-wrapper">
  <div class="polygon1"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.polygon1 {
  float: left;
  shape-outside: polygon(0% 0%, 100% 50%, 0% 100%);
  width: 200px;
  height: 200px;
  margin: 0;
  padding: 0;
  background-color: #F8F09B;
}

上記では polygon() に指定する座標の値をパーセントで指定していますが、以下のようにピクセルの値や、両方を混ぜて指定することもできます。

適用する要素が伸縮する(レスポンシブにする)場合はパーセントで指定します。

/* この例の場合、以下はいずれも同じこと */
shape-outside: polygon(0% 0%, 100% 50%, 0% 100%);
shape-outside: polygon(0px 0px, 200px 100px, 0px 200px);
shape-outside: polygon(0px 0px, 100% 50%, 0px 100%);
(0px 0px) (200px 100px) (0px 200px)

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

clip-path と併用

以下は幅が300px、高さが225pxの画像を clip-path と polygon() で7つの頂点を持つシェイプに切り抜き、clip-path に指定した値と同じ値を shape-outside に指定してその回りにテキストを流し込む例です。

HTML
<div class="shape-wrapper">
  <img class="polygon2" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>

この例では shape-margin プロパティを使ってシェイプとテキストの間にマージンを適用しています。

.polygon2 {
  float: left;
  clip-path: polygon(28% 20%, 47% 12%, 67% 22%, 76% 47%, 60% 81%, 35% 81%, 18% 49%);
  shape-outside:  polygon(28% 20%, 47% 12%, 67% 22%, 76% 47%, 60% 81%, 35% 81%, 18% 49%);
  shape-margin: 10px; /* シェイプとテキストの間にマージン */
  width: 300px;
  height: 225px;
  margin-left: -30px; /* 位置の調整 */
  padding: 0;
} 
(28%, 20%) (47%, 12%) (67%, 22%) (76%, 47%) (60%, 81%) (35%, 81%) (18%, 49%)

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

CSS clip-path ジェネレーター

polygon() に指定する座標を簡単に生成してくれるサービス(サイト)があるので利用すると便利です。

上記の例の polygon() に指定する座標の値も Clippy というサイトを利用しました。

関連項目:CSS clip-path ジェネレーター

また、Firefox のシェイプパスエディターを使うと、シェイプの確認や編集が簡単にできます。

path()

path() はパスによる図形を定義します。この関数はレベル2(CSS Shapes Module Level 2 草案)で追加されていて、現時点(2021年1月)でサポートしているブラウザはないようです。

以下がおおまかな書式です。

path( fill-rule, string )
意味
fill-rule 塗り潰し方法を指定します。nonzero(初期値)または evenodd(領域が囲まれている線の本数が奇数の場合は塗り潰し、偶数の場合は塗らない)を指定できます。
string SVG パスデータ文字列(有効な SVG path コマンドの文字列)。 パスを閉じるコマンド(z または Z)が無い場合には、暗黙的にパスは閉じられます。

以下はハートの図形の SVG ファイルです。path 要素の d 属性にパスデータ文字列が指定されているので、その値を利用できます。関連ページ:Photoshop で SVG

heart_shape.svg
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="225" viewBox="0 0 300 225">
  <path d="M96.152,221.017 C96.152,221.017 -55.242,63.750 21.918,12.318 C66.423,-17.351 95.396,20.618 95.396,20.618 C95.396,20.618 124.369,-17.351 168.874,12.318 C246.033,63.750 96.152,221.017 96.152,221.017 " fill-rule="evenodd" fill="rgb(220, 7, 7)"/>
</svg>

以下は上記 SVG ファイルをインラインで表示しています(表示幅は 80px に変更)。

この例では img 要素に shape-outside でシェイプを適用し、同時に clip-path で切り抜きます。

HTML
<div class="shape-wrapper">
  <img class="path1" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>

clip-path にも同じ値を指定して、シェイプと同じ形状に切り抜きます。

.path1{
  float:left;
  width: 300px;
  height: 225px;
  shape-outside: path("M96.152,221.017 C96.152,221.017 -55.242,63.750 21.918,12.318 C66.423,-17.351 95.396,20.618 95.396,20.618 C95.396,20.618 124.369,-17.351 168.874,12.318 C246.033,63.750 96.152,221.017 96.152,221.017");
  /* clip-path にも同じ値を指定 */
  clip-path: path("M96.152,221.017 C96.152,221.017 -55.242,63.750 21.918,12.318 C66.423,-17.351 95.396,20.618 95.396,20.618 C95.396,20.618 124.369,-17.351 168.874,12.318 C246.033,63.750 96.152,221.017 96.152,221.017");
  
}  

現時点(2021年1月)では、clip-path の path() はサポートしているブラウザはありますが、shape-outside の path() をサポートしているブラウザはないようなので、ハート型に切り抜きはされますが、テキストは定義したシェイプに流し込まれず単に画像をフロートした状態になります。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

Firefox のシェイプパスエディターで確認すると、shape-outside の値は無効になっています。

polygon() で代用

現時点では path() は機能しないので、path() の代わりに polygon() でシェイプを定義する例です。

以下は Firefox のシェイプパスエディターを使って、clip-path で切り取った画像の回りに polygon() でシェイプを作成しています。

HTML
<div class="shape-wrapper">
  <img class="path2" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.path2{
  float:left;
  width: 300px;
  height: 225px;
  clip-path: path("M96.152,221.017 C96.152,221.017 -55.242,63.750 21.918,12.318 C66.423,-17.351 95.396,20.618 95.396,20.618 C95.396,20.618 124.369,-17.351 168.874,12.318 C246.033,63.750 96.152,221.017 96.152,221.017");
  shape-outside: polygon(0% 0%, 56% -0.44%, 63.92% 11.89%, 66.95% 22.97%, 66.27% 36.03%, 62.45% 48.64%, 55.4% 65.2%, 33.67% 102.67%, 0% 100%);
}    

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

画像でシェイプを作成

この例の場合、画像からシェイプを作成すると簡単です。この例では、ハートの図形の SVG ファイルのパスの値を clip-path に指定してクリッピングしているので、その SVG ファイルへの参照を shape-outside に指定するだけです。

<div class="shape-wrapper"> 
  <img class="image" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
.image {
  float:left;
  width: 300px;
  height: 225px;
  /* ハートの図形の SVG ファイルへの参照 */
  shape-outside: url("/images/heart_shape.svg");;
  clip-path:path("M96.152,221.017 C96.152,221.017 -55.242,63.750 21.918,12.318 C66.423,-17.351 95.396,20.618 95.396,20.618 C95.396,20.618 124.369,-17.351 168.874,12.318 C246.033,63.750 96.152,221.017 96.152,221.017");
  /* シェイプとテキストの間のスペースは shape-margin を使用 */
  shape-margin: 10px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

シェイプパスエディター

Firefox のシェイプパスエディターを使うと、clip-path や shape-outside プロパティで作成したシェイプの確認や編集ができます。使い方は簡単で clip-path や shape-outside プロパティを設定したページを Firefox で表示します。

例えば、以下のような shape-outside プロパティを設定して、Firefox でインスペクターを開いて対象の要素を選択します。以下の例では先ず、polygon() で対象の要素全体を選択する座標を指定しておいて、シェイプパスエディターで編集しています。

.polygon3 {
  width: 300px;
  height: 225px;
  float:left;
  shape-outside: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}

shape-outside などを設定した「有効な値」のそばにシェイプのアイコンが表示されます(無効な設定の場合は表示されません)。

アイコンをクリックすると、シェイプを適用している要素にパスが表示され、頂点には○が表示されます。

頂点の○をドラッグして移動させることができ、パス上でダブルクリックするとその位置に頂点が追加されます。

また、作成した頂点は、ダブルクリックで削除することができます。

これらの変更はインスペクターに反映されるのでコピーすることができます。

但し、ページを再読込するとそれまでの設定は保存されず、もう一度要素を選択して作成しなおさなければなりません。

以下は Firefox のシェイプパスエディターを使って単純な polygon() の値に頂点を追加したりして座標の値を編集した例です。

HTML
<div class="shape-wrapper">
  <img class="polygon3" src="/images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.polygon3 {
  float:left;
  width: 300px;
  height: 225px;
  /* インスペクターからコピーしたものを利用 */
  shape-outside: polygon(17.01% 8.88%, 47.97% 29.4%, 75.27% 6.49%, 98.39% 64.52%, 49.32% 101.53%, -0.34% 67.11%);
  /* shape-outside と同じ値を clip-path にも指定 */
  clip-path:polygon(17.01% 8.88%, 47.97% 29.4%, 75.27% 6.49%, 98.39% 64.52%, 49.32% 101.53%, -0.34% 67.11%);
  margin: 20px 10px 10px 0;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

詳しい使い方については以下に掲載されています。

MDN:CSS シェイプのパスを編集する

image / 画像からシェイプを作成

透明や半透明の部分(アルファチャネル)を持つ画像を使用してシェイプを定義することもできます。

具体的には shape-outside の値に画像へのパスを url() で指定します。

PNG や GIF、SVG 画像はアルファチャンネルという不透明度のプロパティを持っています。shape-image-threshold プロパティを設定して不透明度の値をしきい値としてブラウザに伝えてシェイプの形状を作成することができます。

shape-image-threshold の初期値は 0.0 なので、shape-image-threshold を設定しない場合は初期値 0.0 が適用され完全に透明な部分からシェイプが作成されます。

次の例では完全に透過した領域(完全に透明な部分)がある以下のような画像(sample.png)を使います。

完全に透明な部分がある蓮の花の画像

この画像を shape-outside の URL 値として使用すると、シェイプは透明でない部分の周りに作られます。

HTML
<div class="shape-wrapper">
  <img class="image1" src="/images/sample.png" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>

シェイプとテキストの間のスペースは shape-margin プロパティを使用して設定することができます。shape-margin には作成されたシェイプの周囲とテキストとの間のマージンを指定します。

CSS
.image1 {
  float: left; /* フロートを指定 */
  shape-outside: url(/images/sample.png); /* 画像への参照を url() で指定 */
  margin: 0 20px 20px 0;
  shape-margin: 20px; /* シェイプとテキストとの間のマージンを指定 */
  width: 200px;
  height: 200px;
}      

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

不透明度のしきい値

shape-image-threshold を使用すると、半透明の領域からシェイプを作成することもできます。

shape-image-threshold の値が初期値の 0.0 の場合は、完全に透明な領域からシェイプは作成されます。

値が 1.0 の場合は完全に不透明を意味しますが、shape-image-threshold に0以上1未満の値を設定することで中間の値を元にシェイプを作成することができます。

次の例の画像は背景が完全に透明ではなく、30%の不透明度の背景で作成されています。

HTML
<div class="shape-wrapper">
  <img class="image2" src="/images/sample2.png" alt="">
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>

シェイプとテキストの間のスペースは shape-margin プロパティを使用して設定することができます。shape-margin には作成されたシェイプの周囲とテキストとの間のマージンを指定します。

CSS
.image2 {
  float: left; 
  shape-outside: url(/images/sample2.png); 
  margin: 0 20px 20px 0;
  shape-margin: 20px; 
  width: 200px;
  height: 200px;
  shape-image-threshold: 0.3;
}      

この場合、shape-image-threshold を 0.3 より大きくするとシェイプが形成され、0.3 以下の場合はシェイプは作成されません。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

shape-image-threshold 0.30

次の例の画像は中心から外側へ透明になっていく円形のグラデーションで作成されていて、端の部分の一部は透明になっています。

shape-image-threshold の値を変更することで形成されるシェイプも変わるのが確認できます。

CSS
.image2 {
  float: left; 
  shape-outside: url(/images/sample3.png); 
  margin: 0 20px 20px 0;
  shape-margin: 20px; 
  width: 200px;
  height: 200px;
  shape-image-threshold: 0.0;
}      

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

shape-image-threshold 0.0

shape-image-threshold

shape-image-threshold プロパティは shape-outside の値に image(透明部分を含む画像やグラデーション)を指定してシェイプを作成する際の、アルファチャネルのしきい値を設定します。

画像やグラデーションがシェイプの定義に使用される場合、透明度(透過度)が shape-image-threshold で設定したしきい値以上の部分のみがシェイプとして定義されます(境界を特定するためのシェイプの一部とみなされます)。

shape-image-threshold を設定することで、透明度に応じてどのピクセルがシェイプを作成するかをブラウザに通知することができます。

関連項目:不透明度のしきい値

以下が shape-image-threshold プロパティの構文です。

shape-image-threshold: 値;

シェイプはアルファ値がしきい値より大きいピクセルによって定義されます。 0.0 (完全に透明) 〜 1.0 (完全に不透明) の範囲で指定します。初期値は 0.0(完全な透明)です。

値は 0.0 〜 1.0 の数値、または 0% 〜 100% のパーセントで指定できます。

グラデーションでシェイプを作成

シェイプは画像ファイルだけではなく、グラデーションを使って定義することもできます。

以下はシェイプを適用する div 要素に background-image を使用して線形グラデーションを設定し、shape-outside プロパティに同じグラデーションを指定しています。

そして shape-image-threshold に 0.35 を指定してグラデーション内のピクセルの不透明度が35%以上の部分をシェイプとして定義するようにしています。

HTML
<div class="shape-wrapper"> 
  <div class="gradient1"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>

background-image では linear-gradient で角度が45度、開始色がピンクで60%の位置で透明になる線形グラデーションを設定しています。

そして shape-image-threshold で不透明度が35%以上の部分をシェイプとして定義するようにしきい値を設定しています。

CSS
.gradient1 {
  float: left;
  width: 300px;
  height: 200px;
  background-image: linear-gradient(45deg, pink 0%, transparent 60%, transparent);
  shape-outside: linear-gradient(45deg, pink 0%, transparent 60%, transparent);
  /* 不透明度が35%以上の部分をシェイプとして定義 */
  shape-image-threshold: 0.35;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

以下は linear-gradient や shape-image-threshold などの値を変更して動作を確認するサンプルです。

HTML
<div class="shape-wrapper"> 
  <div class="gradient2"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.gradient2 {
  float: left;
  width: 300px;
  height: 200px;
  background-image: linear-gradient(45deg, gold 0%, transparent 60%, transparent);
  shape-outside: linear-gradient(45deg, gold 0%, transparent 60%, transparent);
  /* 不透明度が35%以上の部分をシェイプとして定義 */
  shape-image-threshold: 0.35;
  shape-margin: 0px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

linear-gradient の値
角度 45
(角度は float: left の場合は1~179、right の場合は 181~359 が有効)
開始位置 0%
中間位置 60%
アルファチャネルのしきい値
shape-image-threshold 0.35
その他
width 300
height 200
shape-margin 0px
float left right none

以下は円形グラデーション(radial-gradient)を使用するサンプルです。

HTML
<div class="shape-wrapper"> 
  <div class="gradient3"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.gradient3 {
  float: left;
  width: 300px;
  height: 200px;
  background-image: radial-gradient(ellipse farthest-corner, green 0%, transparent 60%, transparent);
  shape-outside: radial-gradient(ellipse farthest-corner, green 0%, transparent 60%, transparent);
  /* 不透明度が35%以上の部分をシェイプとして定義 */
  shape-image-threshold: 0.35;
  shape-margin: 0px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

radial-gradient の値
形状 ellipse circle
サイズ farthest-corner farthest-side
closest-corner closest-side
開始位置 0%
中間位置 60%
アルファチャネルのしきい値
shape-image-threshold 0.35
その他
width 300
height 200
shape-margin 0px
float left right none

shape-margin

shape-margin プロパティは、shape-outside を使用して作成したシェイプのマージン(シェイプとテキストの間のスペース)を設定します。

以下が shape-margin プロパティの構文です。

shape-margin: 値;

値には px や em などの単位のついた数値や要素の幅に対するパーセントを指定できます。但し、負の値は指定できません。

以下は高さと幅が200pxの正方形の要素を clip-path で三角形に切り抜き、shape-outside にも clip-path と同じ値を指定してシェイプを作成してテキストをその形状に回り込ませています。

シェイプとテキストの間のスペースは shape-margin で 10px に設定しています。

HTML
<div class="shape-wrapper">
  <div class="polygon1"></div>
  <p>Lorem ipsum dolor sit amet, ...pariatur voluptatem.</p>
  <p>Nesciunt ipsa, magnam inventore... Quae, quasi!</p>
  <p>Suscipit aliquam maiores soluta, ea...fugiat, totam!</p>
</div>
CSS
.margin1 {
  float: left;
  shape-outside: polygon(0% 0%, 100% 50%, 0% 100%);
  clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
  /* シェイプとテキストの間のスペース */
  shape-margin: 10px;  
  width: 200px;
  height: 200px;
  /* シェイプを適用した要素自体のマージン */
  margin-top: 0px;
  margin-right: 0px;
  margin-bottom: 0px;
  margin-left: 0px;
  background-color: lightgreen;
  opacity: 0.7;
}    

オレンジ色の点線はシェイプを適用した要素の元の形状と位置を表しています。

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

Nesciunt ipsa, magnam inventore commodi dolorem, deleniti quidem facere quas rem mollitia eos, minima consectetur voluptate quos consequuntur illo dicta vitae ab ipsam blanditiis maxime vel saepe sed. Quae, quasi!

Suscipit aliquam maiores soluta, ea. Libero vitae fugit perspiciatis laboriosam tempora officiis, expedita sequi ex fugiat cum, illo quaerat ab architecto adipisci rerum ratione repudiandae! Minus tenetur expedita fugiat, totam!

以下の値を変更すると、シェイプとテキストの間のスペースや要素自体のマージンの動作を確認できます。

シェイプとテキストの間のスペース
shape-margin 10px
要素自体のマージン
margin-top 0px
margin-right 0px
margin-bottom 0px
margin-left 0px