【実務・中級編】liタグのdisplayプロパティとレイアウトへの影響 – HTML実践ガイド

`display: flex`でリストマーカーが消える?`li`要素の解剖学とモダンな制御術

フロントエンドの現場で、「リストを横並びにしたい」という要件は、もはや呼吸をするのと同じくらい日常的なものです。そこで迷わず `display: flex` を当てる。するとどうなるか。

そう、あの愛すべき(あるいは時として厄介な)リストマーカー(`list-style`)が、跡形もなく消え去るのです。

「なんで消えるんだ?」「`::before`で疑似要素を作ればいいじゃないか」――そう思ったあなた。半分正解ですが、あと半分は仕様の深い部分まで掘り下げる必要があります。今日は、`li`要素の裏側で何が起きているのか、そしてモダンなレイアウトの中でどうスマートにマーカーを制御すべきか、プロの視点で深掘りしていきましょう。

なぜ `display: list-item` は特別なのか

まず、ブラウザの内部的な話をしましょう。`li`要素には、デフォルトで `display: list-item` という特殊な値がセットされています。

これは単なるブロックボックスではありません。内部的に「主ボックス(コンテンツ領域)」と「マーカーボックス」という2つの領域を生成する特殊な箱なのです。CSSの仕様書を紐解くと、`display` プロパティを `flex` や `grid` に書き換えた瞬間、ブラウザはこの「マーカーボックスを生成する権限」を強制的に剥奪します。

だからこそ、`display: flex` をあてた瞬間に、どんなに `list-style-type` を指定してもマーカーは表示されなくなる。これはバグではなく、仕様なのです。

マーカースタイルを「失わずに」レイアウトする手法

では、現代のフロントエンド開発において、この「リストらしさ」と「柔軟なレイアウト」を両立させるにはどうすればいいのか。私が現場で採用している、最も堅牢でメンテナンス性の高いアプローチをいくつか紹介します。

1. `::marker` 疑似要素を活用する(モダンな本命)

CSSの `::marker` 疑似要素を使えば、リストアイテムそのものを `flex` にしても、マーカーだけを独立して制御することが可能です。これが現在のベストプラクティスと言えるでしょう。

ul {
list-style: disc; / 通常のマーカーを定義 /
padding-left: 20px;
}

li {
display: flex; / リストの中身をflex化してもマーカーは維持される /
align-items: center;
gap: 10px; / テキストとの間隔も調整可能 /
}

/ マーカーの色やサイズだけを変えたい場合も容易 /
li::marker {
color: #ff5722;
font-weight: bold;
}

この手法の素晴らしい点は、HTML構造を汚さず、CSSだけで完結することです。ブラウザのアクセシビリティツリーにも「リストである」というセマンティクスが正しく伝わります。

2. `display: contents` で「箱」を透過させる

もう一つのテクニックとして、`ul` に `display: flex` を適用し、その直下の `li` に `display: contents` を与える方法もあります。これは「`li`要素の存在をレイアウトエンジンから消す」というトリッキーな手法です。

ul {
display: flex; / コンテナをflex化 /
gap: 20px;
}

li {
/ liのレイアウト的な役割を無効化し、中身の要素をflexの子として振る舞わせる /
display: contents;
}

/ ただし、この方法はマーカーを表示し続けるのが難しいため、
マーカーを擬似要素で自作する場合に有効です /

正直に言います。この方法は難易度が高く、フォーカス管理や読み上げ順序に影響が出る可能性があるため、「どうしてもリスト構造を維持しつつ、直下の要素をflexコンテナの直下に配置したい」という極めて特殊なケース以外では避けるのが賢明です。

現場で直面する「泥臭い」落とし穴

中級エンジニアの皆さんに、一つ忠告しておきたいことがあります。それは「`list-style` を安易に殺すな」ということです。

デザインカンプで「マーカーが独自のデザインだから」という理由で、全ての `ul/li` に `list-style: none` を当てて、中身に `` を入れて……とやりがちですが、それはスクリーンリーダーを使うユーザーにとっての視認性を損なう可能性があります。

もし自作のSVGマーカーなどを使いたい場合は、以下のように記述するのがプロの作法です。

li {
display: flex;
align-items: flex-start;
padding-left: 1.5em; / マーカー用の余白を確保 /
position: relative;
}

/ 疑似要素で独自アイコンを配置する場合 /
li::before {
content: “”;
position: absolute;
left: 0;
width: 1em;
height: 1em;
background: url(‘custom-icon.svg’) no-repeat center;
}

最後に:ツールを使いこなす側になれ

フロントエンドにおいて、「なぜそうなっているのか」を知ることは、単なる知識の蓄積ではありません。それは、予期せぬレイアウト崩れが起きたときに、数秒で原因を特定できる「勘」を養うプロセスです。

`display: list-item` の裏側にあるマーカーボックスの挙動を理解していれば、`flex` や `grid` を当てたときに起きる現象は、すべて「想定内」の出来事になります。

仕様と戦うのではなく、仕様の特性を味方につける。今日紹介した `::marker` のようなプロパティを使いこなして、美しく、そしてアクセシブルなコードを書いていきましょう。

あなたの書くコードが、誰かのWeb体験を少しでも快適なものにすることを期待しています。それでは、また現場で。

コメント

タイトルとURLをコピーしました