Web開発
アイコンとラベルのより良い配置
Better Icon and Label Alignment (ishadeed.com)
要約
リスト内のアイコンとテキストの配置は、特にテキストが複数行に折り返される場合に問題となることがあります。この記事では、アイコンがHTML要素として、または疑似要素として追加される場合の、この配置問題を解決するためのCSSテクニックを解説します。`lh`ユニットや`aspect-ratio`などのモダンなCSS機能を用いた、柔軟でロバストな配置方法を紹介しています。
全文翻訳
あらゆるウェブレイアウトを、自信を持って構築しましょう。The Layout Maestroコースをチェックしてください。詳細はこちら
アイコンとラベルのより良い配置
2026年9月15日
目次
見落とされがちな、または見過ごされがちな一般的なデザインパターンがあります。それは、各項目にアイコンを持つリストです。テキストが1行の場合はアイコンは中央揃えになりますが、テキストが複数行になると、アイコンは中央揃えのままですが、奇妙に見えます。例を挙げます。
この記事では、HTMLに基づいた2つのソリューションを示します。
アイコンはHTML要素(例: `<svg>`または`<img>`)です。
アイコンは疑似要素として背景画像で追加されます。
マークアップ内のアイコン
この場合、アイコンとコンテンツを持つコンテナがあります。通常、flexboxを使用します。
<ul class="list">
<li class="list-item">
<svg class="icon"></svg>
<span class="label">アイコンをラベルに配置する方法。</span>
</li>
<!-- 他の項目 -->
</ul>
.list-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
デフォルトでは、問題なく表示されます。こちらです。
しかし、リストの幅が狭くなりテキストが折り返されると、アイコンは中央揃えになります。これは望ましい動作ではありません。
テキストが折り返されたときに、アイコンを垂直方向に配置したままにするにはどうすればよいでしょうか?
まず、基本に戻りました。`align-items: center`の代わりに、`start`を値として使用しました。
.list-item {
display: flex;
align-items: start;
gap: 0.5rem;
}
しかし、これはさらに大きな配置の問題を引き起こしました。ハイライトされた領域は行の高さです。テキスト要素の高さには、フォント自体に由来する上下の空きスペースがあります。`align-items: start`が適用されると、アイコンはコンテナの上部に配置されます。
アイコンをトップラインに配置するために、アイコンを下に移動させるとどうなるでしょうか?
.list-item {
display: flex;
align-items: start;
gap: 0.5rem;
}
.icon {
transform: translateY(3px);
}
これでうまくいきました。これを限界まで試して、問題が持続するかどうか見てみましょう!
これを実現するために、以下の1つ以上の値を変更するようにデモを作成しました。
リスト項目のフォントサイズ
アイコンサイズ
コンテナの幅
試してみて、アイコンがずれることに注意してください。
固定値を使用すると、アイコンサイズ、フォントサイズ、またはコンテナ幅が変更された場合に機能しません。
解決策: `lh`ユニットを使用する
行の高さを取得でき、アイコンサイズがわかっていれば、それらに対するオフセットを相対的に計算できます。行の高さユニットについてはブログで書きましたので、さらに詳しく知りたい場合は参照してください。
.icon {
/* --icon-size はJSで定義されます。 */
--size: var(--icon-size);
--offset: calc((1lh - var(--size)) / 2);
transform: translateY(var(--offset));
}
このソリューションでは、3つの値のいずれかを変更しても、配置は正しく機能します。場合によっては、オフセットが負になることもあります。
疑似要素としてのアイコン
アイコンをHTML要素として追加する必要がない場合、疑似要素を使用します。基本的なCSSは次のとおりです。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
width: var(--size);
height: var(--size);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23222' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");
background-repeat: no-repeat;
}
一見すると、問題なく表示されているように見えますね?フォントサイズを少し大きくしてみてください。
アイコンが切り取られていることに気づきましたか?これは、背景サイズを制限する必要があるためです。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
width: var(--size);
height: var(--size);
background-image: url("data:image/svg+xml,%3Csvg .... ");
background-size: contain;
background-repeat: no-repeat;
}
フォントサイズを大きくしてみてください。アイコンの幅が縮小していることに気づきましたか?これは、デフォルトでflexアイテムが縮小するためです。これを上書きする必要があります。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
flex-shrink: 0;
width: var(--size);
height: var(--size);
background-image: url("data:image/svg+xml,%3Csvg .... ");
background-size: contain;
background-repeat: no-repeat;
}
再び…ラベルのフォントサイズを大きくしてみてください。アイコンサイズはそのままです。次のステップは、アイコンサイズ、フォントサイズ、コンテナ幅などの要因が変わる場合に、中央揃えを処理することです。
解決策
現在、リスト項目はflexboxコンテナであり、デフォルトではアイテムは(垂直方向に)ストレッチします。なぜこのケースでアイコンがストレッチしないのでしょうか?それは、固定の高さを設定したためです。`height`プロパティを`auto`に設定しました。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
flex-shrink: 0;
width: var(--size);
height: auto;
background-image: url("data:image/svg+xml,%3Csvg .... ");
background-size: contain;
background-repeat: no-repeat;
}
これで少しトリッキーになります。フォントサイズを大きくすると、アイコンの幅は正方形のように保たれます。小さくすると、余分なスペースを持つ長方形のようになります。見てみましょう。
これを避けるために、アスペクト比を強制的に正方形にする必要があります。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
flex-shrink: 0;
aspect-ratio: 1;
width: var(--size);
height: auto;
background-image: url("data:image/svg+xml,%3Csvg .... ");
background-size: contain;
background-repeat: no-repeat;
}
これで、前述のテクニックと同じように、疑似要素を数ピクセルオフセットします。
.list-item {
display: flex;
gap: 0.5rem;
}
.list-item::before {
content: "";
--size: var(--icon-size);
--offset: calc((1lh - var(--size)) / 2);
flex-shrink: 0;
aspect-ratio: 1;
width: var(--size);
height: auto;
background-image: url("data:image/svg+xml,%3Csvg .... ");
background-size: contain;
background-repeat: no-repeat;
transform: translateY(var(--offset));
}
アイコンは中央揃えになりました。ここで使用されているものを見るのは興味深いです。
flexbox
aspect-ratio
`lh`ユニット
`calc()`
`height: auto`
おわりに
これで終わりです。プロジェクトで問題を解決し、共有したいと思いました。何か新しいことを学んでいただけたなら幸いです。お読みいただきありがとうございました。
The Layout Maestro
レイアウトの構築は、特にCSSレイアウトのコアメンタルモデルを知らない場合、困難な作業となることがあります。もう心配する必要はありません。インタラクティブなCSSレイアウトコースをリリースしました。その名をThe Layout Maestroと名付けました。The Layout Maestroコースをチェックして、CSSレイアウトスキルをレベルアップしましょう。
メーリングリストに参加する
3400人以上の購読者と共に、私の考えやウェブ上の好きなリンクを探求しましょう。私は、簡潔にポイントを説明するコンテンツを共有します。
少なくとも1つの図または明確な例を含みます。
少なくとも何か新しいことを学べる、またはそれを思い出させてくれるものです。
トップクラスの質の高いコンテンツのおすすめを受け取れることを保証します。
あなたのメール