見出し画像

CSS Clothoid Corners

クロソイド曲線を利用した視覚的にやわらかなコーナーをHTML要素に適用する、CSS clip-pathジェネレータを作った。

iOSのアプリアイコンの角にはCSSの border-radius のような一定比率ではない、特殊な曲率を用いた曲線が利用されており、視覚的に「自然でやわらか」な印象を与えます。

iOSで使われているのは「クロソイド」と呼ばれる曲線で、この曲線は高速道路のカーブでも利用されていることからも、視覚的だけでなく数学的・物理学的にも無理のない自然なものと言えます。

下図のRound Rectはコーナーに真円を使用し、Clothoid Rectにはクロソイド曲線を使用していますが、後者の方が機械的ではなく、どことなくやわらかな印象をお持ちになるのではないでしょうか。

このあたりのお話は以下の記事が大変くわしいので、ご興味ありましたらぜひ一読になってください。

• • •

CSSにはクロソイドコーナーを直接描画できるプロパティや関数は存在しない

CSSのブロック要素に角丸を適用する方法は至って簡単で、 border-radius プロパティに任意の値や単位を付けて指定するのみです。

.box {
    border-radius: 3em;
}

ただしこのプロパティによって描画されるのは「真円」を利用した角丸であり、クロソイド曲線にはなりません。

希望としては

.box {
    border-radius: clothoid(3em);
}

などとしてサクッとクロソイドコーナーを描画できるプロパティなり、関数が実装される日が来れば望ましいのですが、出来ないものは出来ません。

• • •

clip-path で擬似的にクロソイドコーナーを実現する

そこでSVGの記法で任意の要素を自由な形状にクロップすることが可能な clip-path プロパティを使うことを検討してみました。

すべてのモダンブラウザがサポートしているプロパティであり、IEのサポートが正式に打ち切られた現状では堂々と使用することが可能です。

結論から言うと、SVGの path 要素ではなく polygon を使用したことから、厳密な意味ではクロソイド「曲線」ではなく、クロソイド「多角形」を利用した擬似的なものではありますが、使い回しのしやすい clip-path の生成ができたのではないかと思います。

ジェネレータとして公開していますので、ご自由にご利用ください。

• • •

使用方法

  • Radius(半径)

  • Unit(単位)

  • Precise(精緻さ)

  • Render Mode(描画モード)

の4つの値の入力フィールドを用意していますので、希望の組み合わせを指定してください。

入力・選択と同時に画面上の要素にCSSが反映され、また textarea に出力もされます。

上記の設定のとき、以下が生成された clip-path を含む .clothoid-rect クラスのスタイルとなります。

.clothoid-corner {
  clip-path: polygon(6.945061em 0em,
    calc(100% - 6.945061em) 0em,
    calc(100% - 6.215873em) 0.003442em,
    calc(100% - 5.487074em) 0.025272em,
    calc(100% - 4.760333em) 0.082315em,
    calc(100% - 4.039637em) 0.191149em,
    calc(100% - 3.333753em) 0.372168em,
    calc(100% - 2.656185em) 0.639069em,
    calc(100% - 2.024846em) 1.000883em,
    calc(100% - 1.463209em) 1.463209em,
    calc(100% - 1.000883em) 2.024846em,
    calc(100% - 0.639069em) 2.656185em,
    calc(100% - 0.372168em) 3.333753em,
    calc(100% - 0.191149em) 4.039637em,
    calc(100% - 0.082315em) 4.760333em,
    calc(100% - 0.025272em) 5.487074em,
    calc(100% - 0.003442em) 6.215873em,
    calc(100% - 0.003442em) calc(100% - 6.215873em),
    calc(100% - 0.025272em) calc(100% - 5.487074em),
    calc(100% - 0.082315em) calc(100% - 4.760333em),
    calc(100% - 0.191149em) calc(100% - 4.039637em),
    calc(100% - 0.372168em) calc(100% - 3.333753em),
    calc(100% - 0.639069em) calc(100% - 2.656185em),
    calc(100% - 1.000883em) calc(100% - 2.024846em),
    calc(100% - 1.463209em) calc(100% - 1.463209em),
    calc(100% - 2.024846em) calc(100% - 1.000883em),
    calc(100% - 2.656185em) calc(100% - 0.639069em),
    calc(100% - 3.333753em) calc(100% - 0.372168em),
    calc(100% - 4.039637em) calc(100% - 0.191149em),
    calc(100% - 4.760333em) calc(100% - 0.082315em),
    calc(100% - 5.487074em) calc(100% - 0.025272em),
    calc(100% - 6.215873em) calc(100% - 0.003442em),
    calc(100% - 6.945061em) 100%,
    6.945061em 100%,
    6.215873em calc(100% - 0.003442em),
    5.487074em calc(100% - 0.025272em),
    4.760333em calc(100% - 0.082315em),
    4.039637em calc(100% - 0.191149em),
    3.333753em calc(100% - 0.372168em),
    2.656185em calc(100% - 0.639069em),
    2.024846em calc(100% - 1.000883em),
    1.463209em calc(100% - 1.463209em),
    1.000883em calc(100% - 2.024846em),
    0.639069em calc(100% - 2.656185em),
    0.372168em calc(100% - 3.333753em),
    0.191149em calc(100% - 4.039637em),
    0.082315em calc(100% - 4.760333em),
    0.025272em calc(100% - 5.487074em),
    0.003442em calc(100% - 6.215873em),
    0.003442em 6.215873em,
    0.025272em 5.487074em,
    0.082315em 4.760333em,
    0.191149em 4.039637em,
    0.372168em 3.333753em,
    0.639069em 2.656185em,
    1.000883em 2.024846em,
    1.463209em 1.463209em,
    2.024846em 1.000883em,
    2.656185em 0.639069em,
    3.333753em 0.372168em,
    4.039637em 0.191149em,
    4.760333em 0.082315em,
    5.487074em 0.025272em,
    6.215873em 0.003442em,
    6.945061em 0em);
}

この .clothoid-corner クラスを clip-path が有効な要素に指定することで、クロソイドカーブが適用されます。

<div class="clothoid-rect">
    〜中略〜
</div>

ポイントとして。

  • SVGの polygon の記法にCSSの calc 関数を併用したレスポンシブな設計となっていますので、適用する要素のサイズやアスペクト比(縦 : 横)はあまり気にせず、border-radius と同じ感覚で利用できます。

  • 単位に px でなく em や vw などの相対的サイズの利用も可能ですので、親要素のスタイルの変更や、ウィンドウサイズに追随するサイズ変更も可能です。

読んでいただきありがとうございます。丁寧な記事作りをこころがけていますので、記事が気に入ったなどでカンパをよせていただけるのなら励みになります。