🧷

CSSのclip-pathを使って画像を使わずにフォームのステップ表示を実装してみよう!

に公開

はじめに

こんにちは、安立です。
みなさん、clip-path使っていますか?

今回はclip-pathを使って以下のようなフォームのステップ表示を作ってみようと思います。
背景画像を使ったり、擬似要素とborder組み合わせて三角作ったりしていた事もありましたね、懐かしい。

以下の画像のステップ表示を作ってみましょう。


clip-pathとは

https://developer.mozilla.org/ja/docs/Web/CSS/clip-path

clip-path は CSS のプロパティで、要素のどの部分を表示するかを設定するクリッピング領域を作ります。具体的には、領域の内部の部分は表示され、外側の部分は非表示になります。

テキストだと分かりにくいのですが、デモを見ると掴みやすいかと思います。
雑にいうと、パス書いて切り抜いて表示する・・・って事ですね。

指定する方法はいろいろあるのですが、今回はpolygonを使います。


polygonの使い方

単純な形ならば、考え方を理解できればpolygonを使って比較的簡単に実装できると思います。
複雑な形を指定したい場合は、svgを読み込ませたりpathを使ったりしましょう。

記法

clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);

50% 0%の部分はカンマ区切りで何個でも増やすことができますよ。
それぞれがパスの頂点の情報となっていて、1番目の50%が横位置、2番目の0が縦位置の指定です。
単位は%じゃなくても問題ないです。pxやremなどなど。

このコードの場合は4つの頂点があるため、四角形になります。
言葉だけだと分かりにくいですが、このコードを正方形の要素に指定する場合は以下の図のようになります。

グレーの線が要素、青い丸が頂点、赤い部分がclip-pathで切り抜かれた結果の表示です。

1番目の頂点は横50%で縦0%の位置に配置、2番目の頂点は横100%で縦50%の位置・・・といった具合で指定されていきます。頂点と頂点は直線で繋がれます。


ステップ表示を作りましょう

1.まずはパパッとHTMLとCSSを書きましょう

HTML

HTMLコード
<ol class="step-list">
  <li class="step-list__item">
    <span class="step-list__inner">
      <span class="step-text">STEP1</span>
      <span class="step-text2">入力</span>
    </span>
  </li>
  <li class="step-list__item step-list__item--current">
    <span class="step-list__inner">
      <span class="step-text">STEP2</span>
      <span class="step-text2">確認</span>
    </span>
  </li>
  <li class="step-list__item">
    <span class="step-list__inner">
      <span class="step-text">STEP3</span>
      <span class="step-text2">完了</span>
    </span>
  </li>
</ol>

CSS

CSSコード
.step-list {
  display: flex;
  margin: 0;
  padding: 0;
  gap: 4px;
}

.step-list__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  padding: 0 28px;
  flex: 1;
  list-style: none;
  background-color: #e0e0e0;
  text-align: center;
}

.step-list__item--current {
  background-color: #264C7D;
  color: #fff;
}

.step-text {
  display: block;
  font-size:12px;
}

.step-text2 {
  display: block;
  font-size: 14px;
  font-weight: bold;
}

とりあえず横並びにして、基本的な色等のスタイルをせってした形です。
flexを使っているのは、ステップ数が増えた時のやりやすさを考慮した形です。

見た目

ここまでで、以下のような見た目になります。

さて、ここからいよいよclip-pathを設定していきます。

2. .step-list__itemにclip-pathを設定していきましょう。

まずは.step-list__itemに対するスタイルを設定しましょう。
デザインのSTEP2部分に当たるものです。
.step-list__itemに対してスタイルを当てる事で、STEP表示が増えた時でもそのまま対応ができます。例えばSTEPが4に増えた時は、STEP2とSTEP3にそのスタイルが当たる事になります。

頂点

頂点は以下のように6つです。

左右の三角部(?)が28pxとなっています。

ポイントは②と④の頂点の設定の仕方になります。
⑥の頂点は比較的簡単で
0% 28px
とすることで実現できます。

②と④は%だけで指定してしまうと、配置する場所の幅にパスの位置が引きずられてしまい、デザイン通りの形にできません。
calcを使いましょう。
②も④も右100%から28pxをマイナスすれば良いです。それぞれの値にcalcが使えます。
②はcalc(100% - 28px) 0%、④はcalc(100% - 28px) 100%となります。

というわけで、結論以下のようにCSSを設定します。

clip-path: polygon(0% 0%, calc(100% - 28px) 0%, 100% 50%, calc(100% - 28px) 100%, 0% 100%, 28px 50% );
ここでのCSSコードまとめ
.step-list {
  display: flex;
  margin: 0;
  padding: 0;
  gap: 4px;
}

.step-list__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  padding: 0 28px;
  flex: 1;
  list-style: none;
  background-color: #e0e0e0;
  text-align: center;
  clip-path: polygon(0% 0%, calc(100% - 28px) 0%, 100% 50%, calc(100% - 28px) 100%, 0% 100%, 28px 50% );
}

.step-list__item--current {
  background-color: #264C7D;
  color: #fff;
}

.step-text {
  display: block;
  font-size:12px;
}

.step-text2 {
  display: block;
  font-size: 14px;
  font-weight: bold;
}

ここまでやると以下のような見た目になります。

次に、最初の要素と最後の要素を調整しましょう。

3. 最初と最後の.step-list__itemのclip-pathを調整しましょう。

最初の要素(first-child)は⑥の頂点が不要で、最後の要素は②と④の頂点が不要となります。
ということで、以下を追記します。

.step-list__item:first-child {
  clip-path: polygon(0% 0%, calc(100% - 28px) 0%, 100% 50%, calc(100% - 28px) 100%, 0% 100% );
}

.step-list__item:last-child {
   clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%, 28px 50% );
}

ここまでやると以下のような見た目になります。
あとちょっとですね。

4. 食い込み分をネガティブマージンで調整する

左右ともに28px分のパスの頂点を設定しているため、それの半分の値の14pxを左右にネガティブマージンを設定します。隣り合う要素で14pxずつネガティブマージンをすれば、28px分パスを書いた分ちょうど良くなると言った形です。

.step-list__item {
  ()
  margin: 0 -14px;
}

ただし、最初と最後の要素は28px分の調整をしていないため、ネガティブマージンを打ち消します。
最初の要素は左のネガティブマージンが不要で、最後の要素は右のネガティブマージンが不要です。
また、それに伴いそれぞれpaddingの値も調整をしています。
コードは以下です。

.step-list__item:first-child {
  ()
  margin-left: 0;
  padding-left: 0;
}

.step-list__item:last-child {
  ()
  margin-right: 0;
  padding-right: 0;
}

これで完成です!!!


結論:今回のまとめ

直線ベースの比較的単純な形なら、svgやジェネレーターなどを使わなくてもclip-pathを組み立てられますね。
是非チャレンジしてみてください。

時間がない人は、以下のHTMLとCSSコードをコピペすれば動きますよ。

HTML

<ol class="step-list">
  <li class="step-list__item">
    <span class="step-list__inner">
      <span class="step-text">STEP1</span>
      <span class="step-text2">入力</span>
    </span>
  </li>
  <li class="step-list__item step-list__item--current">
    <span class="step-list__inner">
      <span class="step-text">STEP2</span>
      <span class="step-text2">確認</span>
    </span>
  </li>
  <li class="step-list__item">
    <span class="step-list__inner">
      <span class="step-text">STEP3</span>
      <span class="step-text2">完了</span>
    </span>
  </li>
</ol>

CSS

.step-list {
  display: flex;
  margin: 0;
  padding: 0;
  gap: 4px;
}

.step-list__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  padding: 0 28px;
  flex: 1;
  list-style: none;
  background-color: #e0e0e0;
  text-align: center;
  clip-path: polygon(0% 0%, calc(100% - 28px) 0%, 100% 50%, calc(100% - 28px) 100%, 0% 100%, 28px 50% );
  margin: 0 -14px;
}

.step-list__item:first-child {
  clip-path: polygon(0% 0%, calc(100% - 28px) 0%, 100% 50%, calc(100% - 28px) 100%, 0% 100% );
  margin-left: 0;
  padding-left: 0;
}

.step-list__item:last-child {
   clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%, 28px 50% );
  margin-right: 0;
  padding-right: 0;
}

.step-list__item--current {
  background-color: #264C7D;
  color: #fff;
}

.step-text {
  display: block;
  font-size:12px;
}

.step-text2 {
  display: block;
  font-size: 14px;
  font-weight: bold;
}

表示確認

ブラウザでどう表示されるかはこのページを見てください。

CodePen

CodePenに登録してあるので、サクッと編集してみたい人はこちらもどうぞ。
https://codepen.io/datty/pen/MYYLMQG

以上です。
それではまた〜。

株式会社ソニックムーブ

Discussion