明るく

暗く

css

CSSで疑似要素before・afterが効かない原因と解決策

CSSで疑似要素before・afterが効かない原因と解決策

CSSの疑似要素before/afterが表示されないときは、原因が限られていることが多いです。特に多いのは、contentが未指定、displayやサイズ(width/height)の指定漏れ、そしてpositionや重なり(z-indexなど)の影響です。

 

まずは次の3点を確認してください。ここで解決するケースがよくあります。

 

  • contentが指定されているか(装飾目的でもcontent: “”が必要)
  • displayやサイズ指定が必要なのに指定していないか(空のcontentで図形や背景を出したい場合など)
  • positionや重なり(z-index、配置の基準要素など)の影響で隠れていないか

 

この記事では、before/afterが効かないときの原因を8つに分け、それぞれの確認ポイントと直し方をコード例つきで解説します。

 

※本記事では便宜上before/afterと表記しますが、CSSの正式な記法は::before / ::afterです。コード例は::before / ::afterに統一します。

疑似要素before・afterとは?

疑似要素とは、HTMLを追加せずに、要素の一部(前後や先頭文字など)をCSSで扱う仕組みです。beforeとafterは、要素の中の先頭(前)や末尾(後)に、装飾用の内容を追加するときによく使われます。

 

beforeは、指定した要素の内容の先頭(最初)にコンテンツを追加します。たとえば、見出しの前にアイコンを表示したり、ちょっとした装飾を加えたりするのに便利です。

 

div::before{
    content:"先頭: ";/* 要素の先頭に「先頭: 」というテキストを追加 */
}

 

一方でafterは、指定した要素の内容の末尾(最後)にコンテンツを追加します。文章の最後に引用符を付け加えたり、区切り線を表示させたりする際に役立ちます。

 

div::after{
    content:"(続き)";/* 要素の末尾に「(続き)」というテキストを追加 */
}

 

beforeとafterを使うことで、HTMLを直接編集しなくても、CSSだけでデザインの幅を広げられます。そのため、Webサイトのメンテナンスがしやすくなるのも利点です。

疑似要素before・afterが効かない8つの原因と解決策

beforeやafterが効かない場合、以下の8つが主な原因として考えられます。

 

  1. contentプロパティが指定されていない
  2. contentが空の場合にdisplayとサイズ指定がされていない
  3. positionプロパティが設定されていない
  4. 疑似要素に閉じタグがない要素を指定している
  5. 疑似要素が他の要素に隠れてしまっている
  6. 疑似要素が重複している
  7. 動的に疑似要素を追加している
  8. CSSの記述ミスをしている

 

この後、それぞれの解決策を紹介していきます。beforeやafterを使っているのにうまく表示されないときは、ぜひチェックしてみてください。

1. contentプロパティが指定されていない

beforeやafterを使う上で、最も基本的なルールは、contentプロパティを必ず指定することです。contentプロパティは、疑似要素として挿入する内容を指定するものです。

 

contentプロパティを記述しないと、beforeやafterは表示されません。もし、beforeやafterが効かない場合は、まずcontentプロパティが記述されているかを確認してください。

 

div::before {
  content: "※"; /* 「※」マークを要素の先頭に追加 */
}

 

contentプロパティには、テキストだけでなく、画像やカウンターなども指定できます。

 

div::before {
  content: url('../image.jpg'); /* image.jpegの画像を要素の先頭に追加 */
}

 

beforeやafterを装飾目的で使用する場合(例えば、背景色を設定したり、ボーダーを表示したりする場合)でも、下記のように、空の文字列を指定する必要があります。

 

.example::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-color: blue; /* 幅10px、高さ10pxの青い四角形を表示 */
}

2. contentが空の場合にdisplayとサイズ指定がされていない

contentプロパティに空の文字列(content:””;)を指定する場合、見落としやすい点が2つあります。それは、displayプロパティとwidthやheightなどのサイズ指定が必要なことです。

 

beforeやafterで追加される内容は、標準でインライン要素として扱われます。このとき、contentが空の場合は、疑似要素の領域が自動的に確保されません。

 

特に、beforeやafterを装飾目的で使用する場合(例えば、背景色を設定したり、ボーダーを表示したりする場合)は、blockまたはinline-blockを指定し、さらにwidthとheightでサイズを指定することで、疑似要素が表示されるようになります。

 

.example::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-color: blue; /* 幅10px、高さ10pxの青い四角形を表示 */
}

3. positionプロパティが設定されていない

positionプロパティは、要素の配置方法を指定するものです。before/afterを好きな位置に置く装飾として使う場合は、positionの設定が必要になることがあります。

 

positionが初期値(static)のままだと、top/right/bottom/leftで位置を調整できません。その結果、疑似要素が狙った位置に出なかったり、他の要素と重なったりして見えにくくなることがあります。

 

positionの主な値は、static / relative / absolute / fixed / stickyです。absoluteで配置したい場合は、基準にしたい親要素にposition: relative;を指定するのが一般的です。

 

下記の例では、.boxを基準にして、左上から10pxの位置に赤い四角形が表示されます。

 

.box { 
  position: relative; /* ::before の基準 */
}

.box::before {
  content: "";
  position: absolute;
  top: 10px;
  left: 10px;
  width: 20px;
  height: 20px;
  background-color: red;
}

4. 疑似要素に閉じタグがない要素を指定している

HTMLの要素には、閉じタグが必要なものと、不要なものがあります。例えば、<div>や<p>は閉じタグが必要ですが、<br>や<hr>、<img>、<input>は不要です。

 

beforeやafterは、閉じタグがない要素(<img>/<input>/<br>/<hr>など)には基本的に付きません。これらに指定しても表示されないため、疑似要素を付ける対象が合っているか確認してください。

※<img>や<input>は置換要素、<br>/<hr>は空要素に当たり、疑似要素が生成されない代表例です。

5. 疑似要素が他の要素に隠れてしまっている

beforeやafterが表示されない原因として、他の要素に隠れてしまっているケースもあります。この場合は、要素の重なり順序を制御するz-indexプロパティが関係していると考えられます。

 

z-indexプロパティは、数値で要素の重なり順序を指定します。数値が大きいほど、手前に表示されます。もし、beforeやafterが他の要素に隠れてしまっている場合は、z-indexプロパティを使って、beforeやafterを前面に表示させるように調整してみましょう。

 

.overlay::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5); /* 半透明の黒色 */
  z-index: 1; /* 他の要素よりも手前に表示 */
}

 

※z-indexは、positionがstatic以外の要素でないと効かないことがあります(relative/absoluteなど)。

6. 疑似要素が重複している

同じ要素に対して、複数のbeforeやafterを指定すると、意図しない表示になることがあります。例えば、同じ要素に対して複数のbeforeを指定した場合、後に記述したbeforeが優先されます。

 

CSSのコードを整理し、原則として1つの疑似要素に対して1回だけスタイルを記述するように心がけましょう。

7. 動的に疑似要素を追加している

jQueryなどでCSSを動的に変更しても、before/afterといった疑似要素はDOMとして存在しないため、$(‘.example::after’)のように疑似要素を直接選択して操作できません。

 

たとえば、次のように書いても疑似要素には反映されません。

 

$(function () {
  // 疑似要素(::after)はDOMに存在しないため、jQueryで直接選択できません(この例は動きません)
  $('.example::after').css({
    content: '""',
    position: 'relative',
    background: 'lightblue'
  });
});

 

動的に切り替えたい場合は、要素本体(.exampleなど)にクラスを付け外しし、疑似要素の見た目はCSS側で切り替えましょう。

 

$(function () {
  $('.example').addClass('is-active'); // 状態だけを切り替える
});

 

.example.is-active::after {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  background: lightblue;
}

8. CSSの記述ミスをしている

CSSの記述ミスは、beforeやafterが効かない原因としてよく見られます。

 

たとえば、プロパティ名のスペルミス、コロン(:)やセミコロン(;)の付け忘れ、括弧({})の閉じ忘れ、全角入力、全角スペースなど、ちょっとしたミスでCSSが正しく解釈されなくなることがあります。

 

CSSコード全体を確認し、誤りがないかチェックしてみましょう。

CSSの疑似要素before/afterについてのよくある質問

before/afterは、表示されない以外にも、基本仕様の違いや書き方の違いでつまずきやすいポイントがあります。

Q. beforeとafterの違いは何ですか?

 beforeは要素の先頭側に、afterは要素の末尾側にコンテンツを追加します。どちらも疑似要素なので、表示するには基本的にcontentの指定が必要です(装飾だけでもcontent: “”を入れます)。

Q. :beforeと::beforeはどう違いますか?

::before/::after(コロン2つ)が、現在の標準的な書き方です。:before/:after(コロン1つ)は、古い書き方として残っていることがあります。

Q. content: “”を書いたのに表示されません。なぜですか?

装飾目的で空文字にする場合、疑似要素は領域が確保されないことがあります。displayをblockやinline-blockにし、width/heightなどのサイズを指定してください。さらに、重なり(z-index)や配置(position)の影響で隠れていないかも確認しましょう。

まとめ

もし、beforeやafterでうまく表示されない場合は、この記事を参考に、原因を特定し、解決策を試してみてください。beforeやafterを使いこなして、より魅力的なWebサイトを作りましょう。