HOME / BLOG
BLOG

疑似要素::before・::afterが表示されない原因7選

::before::afterは、見出しの飾り、リストアイコン、ボタンの矢印、ホバー演出などでよく使います。ただ、書いたはずなのに表示されないことも多いです。

この記事では、疑似要素が表示されない代表的な原因を7つに分けて、確認ポイントと修正コードをまとめます。

原因1:content が指定されていない

疑似要素はcontentがないと生成されません。装飾目的で文字を入れない場合でも、content: "";が必要です。

.title::before {
  width: 12px;
  height: 12px;
  background: #ff2f63;
}
.title {
  position: relative;
  padding-left: 24px;
}

.title::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 12px;
  height: 12px;
  background: #ff2f63;
  transform: rotate(45deg);
}

原因2:width と height だけ指定している

::before::afterは、初期状態ではインライン要素です。幅や高さを効かせたい場合は、display: blockinline-block、またはposition: absoluteで扱いやすくします。

.badge::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 8px;
  background: #ff2f63;
}

原因3:position:absolute の基準がない

疑似要素を絶対配置する場合、親要素にposition: relativeがないと、意図しない場所に配置されます。表示されていないのではなく、遠くに飛んでいるケースもあります。

原因4:z-index や背景の裏に隠れている

疑似要素を背景として使うとき、z-index: -1で親要素の背景や他の要素の裏に隠れることがあります。親にisolation: isolateを入れると、重なり順を管理しやすくなります。

.button {
  position: relative;
  isolation: isolate;
}

.button::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: #ffd329;
}

原因5:img や input など置換要素に付けている

imginputtextareaなど、一部の要素では疑似要素が期待通りに使えません。装飾したい場合は、ラッパー要素を作ってそこに疑似要素を付けます。

<span class="image-frame">
  <img src="thumb.jpg" alt="">
</span>
.image-frame {
  position: relative;
  display: block;
}

.image-frame::after {
  content: "";
  position: absolute;
  inset: 8px;
  border: 2px solid #ff2f63;
  pointer-events: none;
}

原因6:セレクタが対象に当たっていない

クラス名の打ち間違い、詳細度、ブロックエディタが出力するHTML構造の違いで、そもそもセレクタが当たっていないことがあります。DevToolsで対象要素を選択し、::before::afterがStylesに出ているか確認しましょう。

原因7:overflow:hidden で切れている

見出しやカードの外側へ疑似要素をはみ出して配置している場合、親や祖先のoverflow: hiddenで切られます。外側に出したい装飾なら、親のoverflow指定を見直すか、疑似要素を内側に収めます。

実務で使えるリストアイコン例

記事内の箇条書きやカードリストには、以下のような疑似要素アイコンが使いやすいです。背景と同化しないように、中の塗りは白にしておくと読みやすくなります。

.article-list {
  display: grid;
  gap: 18px;
  padding: 0;
  list-style: none;
}

.article-list li {
  position: relative;
  padding-left: 28px;
}

.article-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 10px;
  height: 10px;
  border: 3px solid #ff2f63;
  background: #fff;
  transform: rotate(45deg);
}

CodePen

CodePenでは、contentがない状態、displayを指定した状態、position: absoluteで配置した状態を並べると、表示されない原因を比較しやすいです。

まとめ

疑似要素が表示されないときは、まずcontent、次にdisplaypositionz-index、対象要素、セレクタ、overflowの順で確認すると早いです。装飾をHTMLに増やさず作れる便利な機能なので、原因を切り分けられるようにしておくとUI実装がかなり楽になります。

参考資料