[CSS]三角形で繋がったパンくずのナビゲーションを実装するスタイルシートのテクニックまとめ
Post on:2019年5月9日
サイトのパンくずやフォームのステップでよく見かける、ブロックに三角形の山形を隣接させたリンクの列をCSSで実装するテクニックを紹介します。
CSSでの実装方法はいろいろあり、またCSSでシャドウやグラデーションを適用したバリエーションの実装方法も解説します。
Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
三角形を使ったパンくずのナビゲーション
階層を表示したパンくずのナビゲーションで見かける、各ブロックに三角形の山形を持つ隣接するリンクの列を作成する方法を見てみましょう。
このパターンはよく見かけると思います。フォームのステップやサイトのパンくずなどによく使用されています。ここではこれらを「リボン」と呼ぶことにします。
階層を表示したパンくずのナビゲーション
Webで見かける多くのUI要素と同様に、いろいろな方法でこのリボンを実装することができます。CSSの三角形、SVGの背景、CSSのclip-pathプロパティなど、デモページを作成しました。
HTMLの構造
ここではいろいろな実装方法を紹介しますが、各デモのHTML構造はほぼ同じです。親要素として<nav>があり、その子としてリンクの<a>があります。
1 2 3 4 5 |
<nav class="ribbon ribbon--modifier" role="navigation" aria-label="breadcrumbs"> <a class="ribbon__element" href="https://www.silvestar.codes/">Home</a> <a class="ribbon__element" href="https://www.silvestar.codes/categories/articles/">Blog</a> <a class="ribbon__element" href="https://www.silvestar.codes/articles/building-an-animated-sticky-header-with-custom-offset/" aria-current="page">Post</a> </nav> |
メモ:
A11y Style Guideによると、これらの要素はアクセシブルであることに注意を払ってください。アクセシビリティを念頭に置いてコンポーネントを実装し、最初からアクセシビリティを導入することが「アクセシブルにするのを忘れた」という状況を防ぐための最善の方法です。
CSS: ベースのスタイル
最初に、要素のサイズが正しく定義されていることを確認しましょう。.ribbonのラッパーでフォントサイズを定義してから、リンクである子要素にemユニットを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 |
/* ラッパー要素のフォントサイズを定義 */ .ribbon { font-size: 15px; } /* emを使ってリボン要素のサイズを定義 */ .ribbon__element { font-size: 1.5em; letter-spacing: 0.01em; line-height: 1.333em; padding: 0.667em 0.667em 0.667em 1.333em; } |
ラッパーのフォントサイズは三角形を計算するためにも使用します。emを使用してリボン要素のサイズを計算しているので、ラッパー要素のfont-sizeを再定義することによってすべての要素のサイズを変更することができます。
レイアウトには、CSS Gridを使用します。最初に、4つの列を定義します。
- 3つは、リボン要素のために。
- 1つは、スペースを調整するためです。
スペースを調整しないと、右矢印の形がリボンコンポーネントの外側に配置されてしまい、全体のサイズが想定よりも大きくなってしまいます。
1 2 3 4 5 6 7 8 9 10 |
/* ラッパー要素 * CSS Gridを使用、ブラウザのサポート要件を満たしていることを確認してください。 * ベンダープレフィックスは省略しています。 */ .ribbon { display: grid; grid-gap: 1px; grid-template-columns: repeat(auto-fill, 1fr) 1em; /* サイズ変更の問題を解決するために3つのリボン要素と1つの列を定義 */ } |
リボン要素を伸ばさないようにするには、グリッドの定義を変えます。例えば、max-contentを使用すると、コンテンツのサイズで列を調整できます。ただし、一部のブラウザではmax-contentがまだサポートされていません。
参考: max-contentのサポートブラウザ
1 2 3 4 |
/* リボンの列を最大コンテンツサイズに合わせる */ .ribbon--auto { grid-template-columns: repeat(3, max-content) 1em; } |
実装には、さまざまな方法があると思います。この方法は複雑な計算なしでリボン要素間の正確なギャップを定義するので、私はこの実装方法が好きです。
アクセシビリティは、aria属性を加えるだけではありません。色のコントラストやリーダビリティ、そしてホバーやフォーカスの状態を加えることも含みます。もしアウトラインのスタイルが気に入らない場合は、例えばbox-shadowなど他のプロパティを使用することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 |
/* リンク色は継承、ホバーに下線を追加 */ .ribbon__element:hover, .ribbon__element:active { color: inherit; text-decoration: underline; } /* アウトラインスタイルを消去し、フォーカス時にインセットのbox-shadowを適用 */ .ribbon__element:focus { box-shadow: inset 0 -3px 0 0 #343435; outline: none; } |
CSS: 三角形の実装方法
リボンの端に三角形を実装するには、複数の選択肢があります。
- 疑似要素のborderを使用して三角形を作成。
- 擬似要素にSVG背景画像を使用して三角形を作成。
- インラインのSVG画像を使用して三角形を作成。
- polygon()関数を使ってclip-pathで三角形を作成。
それぞれの実装方法を見てみましょう。
オプション1: 疑似要素のborderを使用して三角形を作成
See the Pen
CSS Grid Ribbon - Alpha by Silvestar Bistrović (@CiTA)
on CodePen.
最初に、要素のボックスの形状は必要無いので幅と高さを0に設定し、borderを使用して三角形を描画します。具体的には、背景の色と一致する左の実線のborderを定義して、リボンの他の部分とブレンドするようにします。詳しくは、画像無しで三角形を作成する仕組みとそれを応用するチュートリアルをご覧ください。
その後に、上下のborderを定義し、それらを透明にします。ポイントはborderのサイズを求める計算式です。リボン要素はline-heightの値に加えて上下のpaddingの値を持っています。
つまり、上下のborderはその半分の大きさになります。やらなければいけないことは、要素をコンポーネントの正しい側に絶対配置することです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* 左の矢印 */ .ribbon--alpha .ribbon__element:before { /* コンテンツのサイズを0に設定 */ content: ''; height: 0; width: 0; /* 疑似要素をリボンサイズに合わせるためにborderを使用 */ border-bottom: 1.333em solid transparent; border-left: 0.667em solid #fff; border-top: 1.333em solid transparent; /* リボン要素の左側に要素を絶対配置 */ position: absolute; top: 0; bottom: 0; left: 0; } /* 右の矢印 */ .ribbon--alpha .ribbon__element:after { /* コンテンツのサイズを0に設定 */ content: ''; height: 0; width: 0; /* 疑似要素をリボンサイズに合わせるためにborderを使用 */ border-bottom: 1.333em solid transparent; border-left: 0.667em solid; border-top: 1.333em solid transparent; /* リボン要素の右側に要素を絶対配置して外側に押す */ position: absolute; top: 0; right: 0; bottom: 0; -webkit-transform: translateX(0.667em); transform: translateX(0.667em); } |
直角三角形はリボンの背景色と一致するので、各リボンの擬似要素にborderの正しい色を定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* 最初の要素の右矢印 */ .ribbon--alpha .ribbon__element:nth-child(1):after { border-left-color: #11d295; } /* 二番目の要素の右矢印 */ .ribbon--alpha .ribbon__element:nth-child(2):after { border-left-color: #ef3675; } /* 三番目の要素の右矢印 */ .ribbon--alpha .ribbon__element:nth-child(3):after { border-left-color: #4cd4e9; } |
オプション2: 擬似要素にSVG背景画像を使用して三角形を作成
See the Pen
CSS Grid Ribbon - Beta by Silvestar Bistrović (@CiTA)
on CodePen.
背景画像を使用して、三角形を作成することもできます。これは少し面倒ですが、デザインに合った画像を作成する必要があります。ここではどんな解像度にも滑らかに表示されるので、SVGを使用します。
borderを使った実装とは異なり、擬似要素の高さをリボン要素の高さ、すなわち100%にする必要があります。コンポーネントの幅はborderの三角形の左の幅と一致する必要があり、この例では0.666666emです。次に、左側の三角形の背景画像に白い三角形を使用し、右側の三角形に色の付いた三角形の画像を使用します。
繰り返しになりますが、リボン要素の正しい側に三角形を配置するために絶対配置を使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/* 左の矢印 */ .ribbon--beta .ribbon__element:before { /* 矢印のサイズを定義 */ content: ''; height: 100%; width: 0.666666em; /* 背景色と一致する背景画像を定義 */ background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); background-position: center left; background-repeat: no-repeat; background-size: 100%; /* リボン要素の左側に要素を絶対配置 */ position: absolute; bottom: 0; top: 0; left: 0; } /* 右の矢印 */ .ribbon--beta .ribbon__element:after { /* 矢印のサイズを定義 */ content: ''; height: 100%; width: 0.667em; /* 背景画像の属性を定義 */ background-position: center left; background-repeat: no-repeat; background-size: 100%; /* リボン要素の右側に要素を絶対配置して外側に押す */ position: absolute; top: 0; right: 0; bottom: 0; -webkit-transform: translateX(0.667em); transform: translateX(0.667em); } /* 最初の要素の背景色と一致する背景画像を定義 */ .ribbon--beta .ribbon__element:nth-child(1):after { background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjMTFkMjk1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); } /* 2番目の要素の背景色と一致する背景画像を定義 */ .ribbon--beta .ribbon__element:nth-child(2):after { background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjZWYzNjc1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); } /* 3番目の要素の背景色と一致する背景画像を定義 */ .ribbon--beta .ribbon__element:nth-child(3):after { background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjNGNkNGU5IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); } |
オプション3: インラインのSVG画像を使用して三角形を作成
See the Pen
CSS Grid Ribbon - Gamma by Silvestar Bistrović (@CiTA)
on CodePen.
Option 2の背景画像ごとに異なる三角形を使用する代わりに、HTML内にインラインのSVG画像を使用することもできます。
この方法を使用すると、各SVGの矢印の色はfillで定義できます。矢印のサイズはリボンのサイズによって計算されます。ここでも、これまで見てきた他の方法と同様にem単位を使用してサイズを定義し、矢印を絶対配置にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* 矢印を絶対配置して正しいサイズを設定 */ .ribbon--gamma .ribbon__element svg { height: 2.667em; position: absolute; top: 0; width: 0.667em; } /* 左の矢印 */ .ribbon--gamma .ribbon__element svg:first-child { fill: #fff; /* 背景色と一致する背景画像を定義 */ left: 0; /* リボン要素の左側に左矢印を貼り付ける */ } /* 右の矢印 */ .ribbon--gamma .ribbon__element svg:last-child { left: 100%; /* リボン要素の外側に右矢印を押す */ } /* 最初の要素の背景色と一致する塗りつぶし色を定義 */ .ribbon--gamma .ribbon__element:nth-child(1) svg:last-child { fill: #11d295; } /* 2番目の要素の背景色と一致する塗りつぶし色を定義 */ .ribbon--gamma .ribbon__element:nth-child(2) svg:last-child { fill: #ef3675; } /* 3番目の要素の背景色と一致する塗りつぶし色を定義 */ .ribbon--gamma .ribbon__element:nth-child(3) svg:last-child { fill: #4cd4e9; } |
オプション4: polygon()関数を使ってclip-pathで三角形を作成
See the Pen
CSS Grid Ribbon - Delta by Silvestar Bistrović (@CiTA)
on CodePen.
背景を覆うポリゴンで三角形を作成することもできます。FirefoxのShape EditorはClippyと同様に、ブラウザで簡単に図形を描画できる素晴らしいツールです。
ポリゴンは%を使用して作成する必要があるため、三角形のサイズに合わせて定義する必要があります。また、%ベースのポリゴンは、特にラッパー要素のように要素サイズが周囲に適応している場合には、一部のビューポートでは少し変に見えるかもしれません。ビューポートごとにポリゴンを再定義することを検討してください。
1 2 3 |
.ribbon--delta .ribbon__element { clip-path: polygon(95% 0, 100% 50%, 95% 100%, 0% 100%, 5% 50%, 0% 0%); } |
CSS Gridでラッパー要素を定義したので、リボン要素を展開し、最後の要素はポリゴン三角形のサイズ、つまり5%にします。最後のリボン要素は、最初の2つの例と一致するように、borderの三角形の幅だけ広くする必要があります。
1 2 3 4 5 6 7 8 9 |
/* 最後を除くすべてのリボン要素をポリゴン三角形のサイズだけ広くする */ .ribbon--delta .ribbon__element:not(:last-child) { width: 105%; } /* 最後のリボン要素をborderの三角形のサイズだけ広くする */ .ribbon--delta .ribbon__element:last-child { width: calc(100% + .667em); } |
オプションのバリエーション
パンくずリボンの実装方法をいくつか学んだので、シャドウ、グラデーション、さまざまなサイズを追加するなど、デザインに合わせてバリエーションがあります。
シャドウを加える
See the Pen
CSS Grid Ribbon - Shadow by Silvestar Bistrović (@CiTA)
on CodePen.
リボンの要素には、簡単にシャドウを加えることができます。リボン要素の左側または右側のシャドウは避けてください。
1 2 3 4 |
/* 各リボン要素の下にシャドウを付ける */ .ribbon--shadow .ribbon__element { box-shadow: 1px 3px 3px -3px black; } |
グラデーションを加える
See the Pen
CSS Grid Ribbon - Gradient by Silvestar Bistrović (@CiTA)
on CodePen.
グラデーションも加えることができます。その際は必ず、三角形の色と一致させてください。また、コントラストのアクセシビリティにも注意が必要です。
例えば、borderまたは背景画像を使用した場合は、水平方向(つまり左から右方向)のグラデーションを使用する必要があります。clip-pathを使用した場合は、任意のグラデーションバージョンを使用できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* 最初のリボン要素にグラデーションを追加 */ .ribbon--gradient .ribbon__element:nth-child(1) { background-image: linear-gradient(to right, #11ced2, #11d295); } /* 2番目のリボン要素にグラデーションを追加 */ .ribbon--gradient .ribbon__element:nth-child(2) { background-image: linear-gradient(to right, #ef36b2, #ef3675); } /* 3番目のリボン要素にグラデーションを追加 */ .ribbon--gradient .ribbon__element:nth-child(3) { background-image: linear-gradient(to right, #4c9fe9, #4cd4e9); } |
サイズのバリエーション
See the Pen
CSS Grid Ribbon - Small by Silvestar Bistrović (@CiTA)
on CodePen.
リボンは、サイズを小さくすることも大きくすることもできます。
See the Pen
CSS Grid Ribbon - Big by Silvestar Bistrović (@CiTA)
on CodePen.
リボン要素のサイズはラッパー要素のフォントサイズに依存するので、サイズを変更するのはかなり簡単です。
1 2 3 4 5 6 7 8 9 |
/* 小さいリボン */ .ribbon--small { font-size: 10px; } /* 大きいリボン */ .ribbon--big { font-size: 20px; } |
バリエーションの組み合わせ
ここで紹介したバリエーションは、組み合わせることも可能です。例えば、シャドウとグラデーションを一緒に使用してみます。
See the Pen
CSS Grid Ribbon - Shadow Gradient by Silvestar Bistrović (@CiTA)
on CodePen.
他に検討すべき点
CSSのさまざまなテクニックを使用して要素を作成することは、わたし達一人ひとりが知識を向上させたりアップデートするのに最適な方法です。ただし始める前に、構築しているコンポーネントの保守性とモジュール性について少し考えておく価値があります。BEMのような一貫した命名規則は確かにその助けになります。アクセシビリティもまた大切なので、それを念頭に置いて始め、その過程でアクセシビリティ機能を文書化することはあなたに役立つでしょう。
この記事では、リボンの三角形を実装するための4つの異なる方法を解説しました。あなたはこれらとは違う方法を使用していますか? また知っていますか? コメントで私に教えてください。
sponsors