原文: CSS Shapes Explained: How to Draw a Circle, Triangle, and More Using Pure CSS

CSS やウェブ開発を学び始めたばかりですか?インターネットのいたるところで目にする綺麗な図形がどうやって作られているか疑問に思ったことがありますか?もう疑問に思うことはありません。この記事で答えを見つけましょう。

以下、CSS で図形を作成する基本を説明します。このトピックについては説明することがたくさんあります!そのためツールや図形のすべてはカバーしませんが (扱うのはほんの一部です)、CSS で図形を描く方法の基本的な考え方がわかるはずです。

一部の図形では他の図形に比べ多くのコツが必要です。CSS による図形は通常、width、height、top、right、left、border、bottom、transform などや、:before、:after のような疑似要素を組み合わせて作成します。shape-outsideclip-path のような比較的新しい CSS プロパティもあり、こちらについても後ほど説明します。

CSS の図形 - 基本の方法

CSS のコツをいくつか使うと、よく目にする CSS プロパティだけで正方形、円、三角形などの基本的な図形を作成できます。その例を見てみましょう。

正方形と長方形

正方形と長方形は一番描きやすい図形でしょう。div 要素もデフォルトの状態で正方形または長方形です。

下記のコードに示すように、width (幅) と height (高さ) を設定します。あとは要素に背景色を追加するだけです。必要に応じてその他のプロパティも追加できます。

#square {
    background: lightblue;
    width: 100px;
    height: 100px;
}
square
CSS の正方形

円を作成するのも同じくらい簡単です。円を作成するには、要素に border-radius を設定します。このプロパティは要素の角を丸くします。

border-radius を 50% に設定すると円になります。width と height の値が異なるときは楕円になります。

#circle {
    background: lightblue;
    border-radius: 50%;
    width: 100px;
    height: 100px;
}
circle
CSS の円

三角形

三角形は少し難易度が上がります。三角形になるように border (境界線) を設定しなければなりません。要素の width と height をゼロに設定すると、実質的には境界線の幅が要素の幅になります。

要素の境界線が接する端は 45° の対角線になることを頭に置いておいてください。それを利用して三角形を作ることができます。境界線の 1 本を単色に設定し、他の境界線を transparent (透明) に設定すると、三角形の形ができます。

borders
CSS の境界線の端には角度が付いています
#triangle {
    width: 0;
    height: 0;
    border-left: 40px solid transparent;
    border-right: 40px solid transparent;
    border-bottom: 80px solid lightblue;
}
triangle
CSS の三角形

三角形 (矢印) の方向を変えたい場合は、どちら側の境界線を表示させたいかに応じて border プロパティの設定値を変更します。または transform プロパティで要素を回転させても構いません。

 #triangle {
     width: 0;
     height: 0;
     border-top: 40px solid transparent;
     border-right: 80px solid lightblue;
     border-bottom: 40px solid transparent;
 }
triangle2
別方向の CSS の三角形

以上が CSS の基本的な図形の紹介です。作成したい図形の種類は無限にあることでしょう。ここで紹介したのは基礎のみですが、少しの創造性と根気があれば、基本の CSS プロパティだけでもさまざまなことができます。

もっと高度な図形を作成する場合、:after や :before などの疑似セレクターを使うのも良いでしょう。この記事は入門として基礎的な内容にとどめておこうと思うので、疑似セレクターについては扱いません。

デメリット

上記の方法には 1 つ大きな欠点があります。例えばテキストを図形に沿って回り込ませたい場合です。通常の HTML div 要素で背景と境界線を使って図形を作る場合はそれができません。テキストは図形に沿う形ではなく、div 要素自体 (正方形または長方形) に沿って回り込みます。

下記が三角形とテキストの回り込み方を示した図です。

textflow-bad

幸い、代わりに使える新しい CSS プロパティがあります。

CSS の図形 - もう一つの方法

近年では、shape-outside という CSS プロパティが使えます。このプロパティを使ってテキストが回り込む形状を定義できます。

このプロパティでは以下のような基本的な図形が使えます。

inset()
circle()
ellipse()
polygon()

補足: clip-path プロパティを使うこともできます。このプロパティでも同様に図形を作成できますが、shape-outside と違ってテキストを図形に沿って回り込ませることができません。

shape-outside プロパティを使って形状を指定する要素は浮動 (float) 要素でなければなりません。また、width と height が指定されていなければなりません。これは重要なので覚えておきましょう!

理由について詳しくはこちらを参照してください。リンク先には次のように書かれています。

shape-outside プロパティは、浮動領域浮動要素を表す以下に挙げた値を使用して指定します。浮動領域はインラインコンテンツ (浮動要素) が囲む形状を指定します。(引用元: developer.mozilla.org)

inset()

inset() を使うと長方形または正方形を作成でき、オプションでテキストの回り込みのオフセットを指定できます。この値で、周りのテキストが図形にどれだけ重なるかを指定できます。

四方向すべてに同じオフセットを指定するには inset(20px) のように指定します。または inset(20px 5px 30px 10px) のように、それぞれの方向を個別に指定できます。

オフセットの設定には、パーセントなど他の単位も使用できます。値は inset(上 右 下 左) の方向に対応します。

下記のコード例を見てください。この例では inset の値を上側が 20px、右側が 5px、下側が 30px、左側が 10px に設定しています。テキストを重ねるのではなく、正方形の周囲に沿ってテキストを回り込ませたいなら inset() を使用しなくても構いません。その場合は div 要素のサイズと背景を指定するだけです。

 #square {
     float: left;
     width: 100px;
     height: 100px;
     shape-outside: inset(20px 5px 30px 10px);
     background: lightblue;
 }
inset
テキストが指定された値の分オフセットされ、内側に入っています。この例では上側が 20px、右側が 5px、下側が 30px、左側が 10px です。

また、inset() に 2 つ目の値を渡して、inset の border-radius を指定することも可能です。次のとおりです。

 #square {
     float: left;
     width: 100px;
     height: 100px;
     shape-outside: inset(20px 5px 30px 10px round 50px);
     background: lightblue;
 }
inset2
inset の border-radius を 50px に設定した場合

circle()

次の例では shape-outside プロパティを使って円を作成します。円を表示させるには、対応するプロパティで clip-path も適用する必要があります。

clip-path プロパティは shape-outside プロパティと同じ値を取ることができるので、shape-outside に使ったのと同じ、標準的な circle() の形状を指定しましょう。またここではテキストとの間にスペースを空けるため、要素に 20px のマージンを適用しています。

#circle {
    float: left;
    width: 300px;
    height: 300px;
    margin: 20px;
    shape-outside: circle();
    clip-path: circle();
    background: lightblue;
}
circle-shape-margin-1
テキストが図形に沿って回り込むようになりました!

上記の例では、円の半径を指定していません。これは円を div の大きさ (300px) に合わせたかったからです。円に異なる大きさを指定することも可能です。

circle() は 2 つの値を取ります。1 つ目の値は半径、2 つ目の値は位置です。これらの値で円の中心を指定します。

下記の例では半径を 50% に設定しました。そして円の中心を 30% ずらしました。半径と位置の値の間には "at" を入れなければならないことに注意してください。

また、clip-path には異なる位置の値を指定しています。位置を 0 に動かしたことにより、円が半分に切り取られています。

 #circle {
      float: left;
      width: 150px;
      height: 150px;
      margin: 20px;
      shape-outside: circle(50% at 30%);
      clip-path: circle(50% at 0%);
      background: lightblue;
    }
circle2

ellipse()

ellipse は circle と同じように動作しますが、楕円を作成します。ellipse(25px 50px) のように、X 方向の値と Y 方向の値両方を定義できます。

circle と同様に、最後の引数として位置の値を取ることもできます。

   #ellipse {
      float: left;
      width: 150px;
      height: 150px;
      margin: 20px;
      shape-outside: ellipse(20% 50%);
      clip-path: ellipse(20% 50%);
      background: lightblue;
    }
ellipse

polygon()

polygon (多角形) は、さまざまな頂点 / 座標で定義される図形です。下記では筆者のイニシャル "T" の形を作成します。座標 0,0 からスタートして左から右へ移動し、"T" の形を描いています。

#polygon {
      float: left;
      width: 150px;
      height: 150px;
      margin: 0 20px;
      shape-outside: polygon(
        0 0,
        100% 0,
        100% 20%,
        60% 20%,
        60% 100%,
        40% 100%,
        40% 20%,
        0 20%
      );
      clip-path: polygon(
        0 0,
        100% 0,
        100% 20%,
        60% 20%,
        60% 100%,
        40% 100%,
        40% 20%,
        0 20%
      );
      background: lightblue;
    }
polygon_t

画像

背景を透過した画像の形を使うこともできます。たとえばこの丸い美しい月の画像を使います。

これは背景を透過した .png 画像です。

moon
<img src="src/moon.png" id="moon" />
#moon {
      float: left;
      width: 150px;
      height: 150px;
      shape-outside: url("./src/moon.png");
    }
moon2

以上です!お読みいただきありがとうございました。

この記事を書いた人

私はスウェーデンの開発者 Thomas Weibenfalk です。個人の YouTube チャンネルで定期的に無料のチュートリアルを投稿しています。React や Gatsby に関するプレミアムコースもあります。以下のリンクを参照してください。

Twitter — @weibenfalk
Weibenfalk on YouTube
Weibenfalk Courses Website