CSSのとても便利な機能のひとつに「::before」と「::after」があります。これを使うと、新たに要素を追加したり、オシャレな装飾を施したりといった処理を簡単に行うことができます。
ここでは、「::before」と「::after」の使い方についてまとめています。
::beforeとは何か?
「::before」は指定した要素の前方に新たな要素を追加する処理です。
以下のようにCSSファイルの中で、対象の要素に「:before」を記述して使います。
対象要素::before{ 処理 }
処理の中で「contentプロパティ」を使って指定した値が、対象の要素の前方に表示されます。
contentプロパティとは、擬似要素「::before
」と「::after
」で使う専用のプロパティです。指定した値を新たな要素として追加することができます。
::beforeや::afterの説明で「疑似要素」という言葉を耳にすることがあります。疑似要素とは、::beforeや::afterで作り出した要素のことを指しています。
疑似要素の詳細については下記をご参考ください。
::before使用時の注意点
::beforeを使う時の注意点は大きく以下の6つです。
- contentを省略してはいけない。(文字列を表示しないときは空文字「””」とする)
- ::beforeを適用するのは、セレクタの後ろ(タグやクラス名の後ろではない)
- 対象要素のプロパティが引き継がれる。
- 同じ要素に対して::beforeで作成できる疑似要素は1つだけ。
- ::beforeを複数記述した場合は、下方のプロパティで上書きされる(プロパティが被らない場合は追記になる)
- ::afterで作成した要素と重なる場合は、下になる。
contentを省略してはいけない
::beforeを使うとき必ず「contentプロパティ」を設置します。テキストを表示するのではなく、ボックスなどの図形を表示したい場合は値を空文字「””」にします。
contentプロパティを記述しないと何も表示されなくなります。
対象要素::before{
content: "";
他のスタイル指定
}
::beforeを適用するのは、セレクタの後ろ
::beforeを適用するのは、セレクタの後ろです。htmlタグやクラス属性の中のクラス名の後ろにつけると動作しません。
<p::before>xxx</p>
<p class="test::before" >xxx</p>
対象要素のプロパティが引き継がれる
::beforeで作成した疑似要素には、対象要素のプロパティが引き継がれます。
例えば、「p::before」としたときに、pタグに「color: red;」が指定してあれば、::beforeで作成した要素にも同じく「color: red;」が適用されます。
色を変えたい場合は、::beforeの中でcolorプロパティを指定する必要があります。
同じ要素に対して::beforeで作成できる疑似要素は1つだけ
ある要素に対して::beforeで作成できる疑似要素は1つだけです。複数作成することはできますが、後ろのプロパティの値が優先されます。
例えば、以下のようにpタグに対して「::before」を2つつけたとします。
p::before{
content: '★★★';
}
p::before{
content: '●●●';
}
すると、疑似要素として作成されるのは「●●●」のみになります。
::beforeを複数記述した場合は、下方のプロパティで上書きされる
上記で示したように、::beforeで作成できる疑似要素は1つだけですが、::beforeを2つ以上使ってはいけないというわけではありません。
2つ以上記述しても問題ありませんが、プロパティが被った場合は、下方に記述してある値で上書きされていきます。
被っているプロパティが無い場合は、上にある::beforeのプロパティがそのまま適用されます。
例えば、以下のようにpタグに対して「::before」を2つあるとします。
p::before{
content: '★★★';
color: red;
font-size: 30px;
font-weight: bold;
}
p::before{
content: '●●●';
color: green;
font-weight: normal;
}
これは以下の記述と同じになります。
p::before{
content: '●●●';
color: green;
font-size: 30px;
font-weight: normal;
}
1つ目の::beforeのfont-sizeプロパティのみ重複がないので、「font-size: 30px;」がそのまま適用されます。
::afterで作成した要素と重なる場合は、下になる。
::beforeと同じく疑似要素を作成する書き方に「::after」があります。
1つの要素に対して::beforeと::afterの両方を設置し、かつそれぞれの疑似要素が重なりあった場合は、::afterの疑似要素が上側になり、::beforeの疑似要素が下側になります。
::beforeと::afterの2つともを設置した場合に以下の条件を満たせば、::beforeの要素を上側に表示することもできます
- 対象要素に「position: relative;」を設定する。
- ::beforeに「position: absolute;」を設定する。
- ::beforeに「z-index: 正の整数」 を設定する。
- ::afterにもz-indexがある場合は、::beforeのz-indexの数値の方が大きくなるようにする。
疑似要素の場所を指定する方法
::beforeを使う際に、対象の要素に対して、生成した要素の位置を指定したいことが頻繁にあります。
例えば、吹き出しの三角形の部分を、下側や上側、真ん中、左から10pxの位置といった指定をする場合などです。
そのようなときは、対象となる要素に「position: relative;」を設置し、「::before」の処理の中で「position: abusolute;」を指定します。
すると、対象の要素の位置を基準として、top, left, right, bottomのプロパティで位置を細かく指定することができます。
対象要素{
position: relative;
}
対象要素::before{
content: "値";
position: absolute;
他のスタイル指定
}
疑似要素に画像を指定する場合
画像のサイズ変更が不要な場合
::beforeを使って画像を疑似要素として追加することもできます。contentの値でurl関数を使って以下のように記述します。
対象要素::before{
content: url(画像のパス);
他のスタイル指定
}
contentの値で画像を指定した場合、widthやheightなどで画像のサイズを変更することができません。
コード例
.test::before {
content: url(/images/small-cat.jpg);
vertical-align: middle;
}
画像のサイズを変更したい場合
::beforeを使って追加する画像のサイズを変更したい場合は、contentの値として画像を読み込みません。
background-imageプロパティの値にurl関数を使って画像のパスを指定することで画像を背景として読み込みます。
また、画像を表示させるために、疑似要素を「display: inline-block;」でインラインブロックに変更する必要があります。
そしてwidth, heightなどのプロパティを使って画像を表示する場所のサイズを調整します。
このままでは呼び出した画像のサイズ自体は変化していないので、指定した枠の中に納まるように「background-size: contain;」をつけます。
こうすることで、::beforeで表示した画像のサイズ調整が可能となります。
対象要素::before{
content: "";
backgroud-image: url(画像のパス);
background-size: contain;
display: inline-block;
height: 画像の高さ;
width: 画像の幅;
他のスタイル指定
}
contentの値に何も指定しない場合でも、あえて「content: “”;」のように空文字を指定しておきます。
コード例
.test::before {
content: "";
display: inline-block;
background-image: url(/images/small-cat.jpg);
background-size: contain;
width: 100px;
height: 100px;
}
::beforeの実例
::beforeの実例として、以下の7つの処理を解説しています。
- 前方にテキスト(文字列)を追加する。
- 疑似要素の場所を指定する。
- 前方に画像を追加する(サイズの指定なし)。
- 前方に画像を追加する(サイズの指定あり)。
- 下線を表示する。
- 縦線を表示する。
- 対象要素のプロパティの引継ぎと打ち消し
また、以降の::afterの章で、::beforeと::afterを併用した処理の実例も記載しています。
前方にテキスト(文字列)を追加する
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

このテキストの前に3つ星「★★★」を表示するには以下のように記述します。
p::before{
content: "★★★";
}
すると、対象の要素の前方にcontentで指定した値が表示されます。

とてもシンプルです。
疑似要素として前方に表示したテキストの色やサイズなどを変更したい場合は、同じく、::beforeの処理の中に記述します。
p::before{
content: "★★★";
color: blue;
font-size: 30px;
vertical-align: middle;
margin-right: 30px;
text-decoration: underline;
text-decoration-color: cyan;
}
すると、画面の表示は以下のようになります。

「何の変哲もないテキスト」が「::before」によってなんとなく豪華になりました。
疑似要素の場所を指定する
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

このテキストの前に3つ星「★★★」をつけて、これを、テキストの中央下に表示する場合は対象要素のpタグに「position: relative;」を設置して、::beforeの中に「position: absolute;」を記述し、top, left, right, bottomプロパティを使って位置を指定します。
p{
position: relative;
}
p::before{
content: "★★★";
position: absolute;
bottom: -18px;
left: 60px;
}
すると、対象の要素のを基準として、指定した位置に疑似要素が表示されます。

前方に画像を追加する(サイズの指定なし)
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

このテキストの前方に画像を追加する場合は、content
プロパティの値にurlメソッドを使って呼び出したい画像のパスを指定します。
p::before {
content: url(./dog.jpg);
}
画像のサイズはオリジナルの状態で表示されます。

positionを使って場所の指定をすることはできますが、サイズの変更はできません。
このため以下のようにwidthとheightを指定しても画面の表示は変化しません。
p::before {
content: url(./dog.jpg);
width: 300px;
height: 200px;
}
前方に画像を追加する(サイズの指定あり)
::beforeで呼び出した画像のサイズを変更したい場合はcontentではなく、background-imageを使って画像を呼び出します。ただし、これだけでは何も表示されません。
画像を画面上に表示するためには、「display: inline-block;」でインラインブロックに変更し、widthとheigthで表示する場所を作成する必要があります。
p::before {
content: "";
background-image: url(./dog.jpg);
width: 300px;
height: 200px;
display: inline-block;
}
ただし、上記の状態では画像のサイズは元のままなので、以下のように枠の中にきちっと納まりません。

背景画像を疑似要素で作成した枠の中にピッタリ収めるためには、「background-size: contain;」を使います。
background-size: contain;
は縦横比は保持して、枠に収まる最大サイズになるように背景画像を拡大縮小する指示です。
background-sizeプロパティでは、「contain」の他にも、「auto」や「cover」などの指定をすることができます。auto
の場合は余白を埋める分だけ背景画像を自動で繰り返します。cover
の場合は枠に収まる最少サイズになるよう拡大縮小します。
コードは以下のようになります。
p::before {
content: "";
background-image: url(./dog.jpg);
width: 300px;
height: 200px;
display: inline-block;
background-size: contain;
}
すると、以下のように画像が指定のサイズで表示されます。

あとは、marginやpadding, positionなどで場所を指定するといった装飾を追加します。
なお、表示されているテキストを中心にして表示したい場合は、「vertical-align: middle;」を使うと、疑似要素が中央にくるように自動調整することができます。
p::before {
content: "";
background-image: url(./dog.jpg);
width: 300px;
height: 200px;
display: inline-block;
background-size: contain;
vertical-align: middle;
}

下線を表示する
::before
を使うと、テキストに好きな長さの下線を引くこともできます。オシャレな見出し(ヘッドライン)などで使われることがあります。
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

このテキストの下に、ゴールドで長さ80px、太さ4pxの下線を引く場合は以下のようになります。
p{
position: relative;
}
p::before {
content: '';
position: absolute;
background: gold;
width: 80px;
height: 4px;
bottom: 0;
}
下線を疑似要素で作成し、positionとbottomを使って、対象の要素の下から0pxの位置に表示する指示になります。

下線の長さや、太さ、位置を簡単に変更することができます。
テキストの長さに合わせて自動調整するハイライトのような下線を引きたい場合は、::beforeで疑似要素を作成するのではなく、以下のようにbackgroundの値に、グラデーションを表すlinear-gradientを指定します。
background:linear-gradient(transparent 60%, #ff6 60%);
実例
<p>何の変哲もないテキスト</p>
p{
/* position: relative;*/
display: inline;
background:linear-gradient(transparent 70%, gold 90%);
}

なお、linear-gradient(transparent 70%, gold 90%)
は、上から透明な状態で始まり、70%のところまでいき、90%のところでゴールドに変わるという指示です。
冒頭に縦線を表示する
冒頭に縦線を表示する方法は、下線を付けた方法と同じ考え方です。
width, heightと位置を調整します。
p{
position: relative;
}
p::before {
content: '';
position: absolute;
display: inline-block;
background: gold;
width: 5px;
height: 20px;
left: -8px;
top: 2px;
}
画面の表示は以下のようになります。

対象要素のプロパティの引継ぎと打ち消し
::beofreで作成した疑似要素は、対象要素のプロパティを引き継ぎます。
例えば、以下のように「スタイルを調整したテキスト」があるとします。
<p>スタイルを調整したテキスト</p>
p{
color: red;
font-size: 30px;
font-weight: bold;
text-decoration: underline;
}
ブラウザでの表示は以下のようになっています。

この要素に対して、::beforeを使って「content: “★★★”」のみを指定すると次のようになります。
p{
color: red;
font-size: 30px;
font-weight: bold;
text-decoration: underline;
}
p::before {
content: '★★★';
}
ブラウザの表示は以下のようになります。

対象の要素のプロパティがそのまま引き継がれていることがわかります。
対象の要素のプロパティを打ち消したいときは、::beforeの中でそのプロパティを上書きする記述を書きます。
p{
color: red;
font-size: 30px;
font-weight: bold;
text-decoration: underline;
}
p::before {
content: '★★★';
color: blue;
font-size: 20px
font-weight: normal;
/* text-decoration: none; 効かない*/
display: inline-block;
}
画面の表示は以下のようになります。

対象要素の下線「text-decoration: underline;」を打ち消したいときに、::beforeの中で「text-decoration: none;」としても消えません。
「display: inline-block;」を設定すれば下線を消すことができます。
::afterとは何か?
「::after」は指定した要素の後方に新たな要素を追加します。
以下のようにCSSファイルの中で、対象の要素に「:after」を記述して使います。
対象要素::after{ 処理 }
「::before」と「::after」の違い
「::before」と「::after」の違いは要素を前に出すか、後ろに出すかの違いだけです。
contentプロパティや画像の出し方、位置調整など使い方は「::before」と同じです。
なお、「::after」を使っても、positionプロパティを使って位置を調整すれば、「::before」で作成した疑似要素と同じ場所に要素を作り出すことができます。
::afterはいつ使うのか?
::beforeと同じ動きをするのであれば、::afterを使う必要はないのでは?と思うかもしれません。ですが、::afterにもつかいどこがあります。
- 対象要素の後ろ側に追加の要素を表示したいとき。
- 対象要素に2つの追加要素を表示したいとき。
対象要素の後ろ側に追加の要素を表示したいとき
対象要素の後ろ側に追加要素を表示したいときは「::after」を使う方が何をしているかがわかりやすくなります。
「::before」でも疑似要素の位置を調整すれば、後方に要素を表示することができます。
対象要素に2つの追加要素を表示したいとき
対象の要素に、要素を2つ表示したい場合が出てくることがあります。
::beforeで生成できる疑似要素は1つのみです。このため、もう一つ疑似要素を追加して表示したい場合は「::after」を使う必要があります。
1つの要素に対して::beforeと::afterの両方を設置し、かつそれぞれの疑似要素が重なりあった場合は、::afterの疑似要素が上側になり、::beforeの疑似要素が下側になります。
::beforeと::afterの2つともを設置した場合に以下の条件を満たせば、::beforeの要素を上側に表示することもできます
- 対象要素に「position: relative;」を設定する。
- ::beforeに「position: absolute;」を設定する。
- ::beforeに「z-index: 正の整数」 を設定する。
- ::afterにもz-indexがある場合は、::beforeのz-indexの数値の方が大きくなるようにする。
::afterの実例
ここでは::afterを使った処理として以下を実例で解説しています。
- 対象要素の後ろ側に追加の要素を表示する。
- 対象要素の後ろ側に追加した要素を移動する。
対象要素の後ろ側に追加の要素を表示する
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

この要素の後方に緑色の「●●●」を表示したい場合は以下のようにします。
p::after {
content: '●●●';
color: green;
}
すると画面の表示は以下のようになります。

対象要素の後ろ側に追加した要素を移動する
上記で対象要素の後ろ側に追加に追加した要素を移動する場合は、
対象要素のpタグに「position: relative;」を設置して、::afterの中に「position: absolute;」を記述し、top, left, right, bottomプロパティを使って位置を指定します。
その際、位置の基準となるのは対象のタグ一番左上(前側)です。
例えば、「left: 0px;」を指定すると、対象の要素の先頭と同じ位置に移動します。
p{
position: relative;
}
p::after {
content: '●●●';
color: green;
position: absolute;
bottom: -20px;
left: 0px;
}
上記の場合、::afterで指定した要素が、対象要素と頭が揃って下側に表示されます。

なお、この場合は、::afterを::beforeに変えても全く同じ処理になります。
p{
position: relative;
}
p::before {
content: '●●●';
color: green;
position: absolute;
bottom: -20px;
left: 0px;
}

::beforeと::afterの併用
::beforeと::afterの併用として以下の4つの例を紹介しています。
- 対象要素に2つの追加要素を表示する。
- 疑似要素が重なりあうと::beforeが下に、::afterが上にくる。
- ::beforeの要素を上に表示する。
- モーダルを作成する。
対象要素に2つの追加要素を表示する
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

この要素の前方に青い「★★★」、後方に緑色の「●●●」を表示したい場合は以下のようにします。
p::before {
content: '★★★';
color: blue;
}
p::after {
content: '●●●';
color: green;
}
すると画面の表示は以下のようになります。

1つのpタグに対して、2つの疑似要素が適用されていることがわかります。
疑似要素が重なりあうと::beforeが下に、::afterが上にくる
例えば、以下のように「何の変哲もないテキスト」があるとします。
<p>何の変哲もないテキスト</p>
CSSを適用しないデフォルトの状態では画面の表示は以下のようになっています。

この要素の::beforeで青色の「★★★」を、::afterで緑色の「●●●」を追加します。
これを、positionを使って位置を調整し重ね合わせると以下のようになります。
p{
margin-top: 30px;
position: relative;
}
p::before {
content: '★★★';
color: blue;
font-size: 30px;
position: absolute;
left: 30px;
bottom: -40px;
}
p::after {
content: '●●●';
color: green;
font-size: 25px;
position: absolute;
left: 37px;
bottom: -35px;
}
すると画面の表示は以下のようになります。

::afterで表示している緑色の●が、::beforeで表示している青い★の上にのっていることがわかります。
::beforeの要素を上に表示する
::beforeと::afterで表示した要素が重なりあったときに、z-indexを使って調整すれば::beforeを上にすることもできます。
z-indexとはz方向(奥行)の位置を調整するプロパティです。要素の重なり合わさる順番を調整することができます。
::beforeの要素に「z-index: 1」を追加します。z-indexの指定が無い要素のz方向の位置は0となっているため、::beforeの疑似要素を1つだけ手前に出す指示になります。
重なり合わせの色がわかりやすいように、上記の例で、::afterの要素を黄色に変更しておきます。
p{
margin-top: 30px;
position: relative;
}
p::before {
content: '★★★';
color: blue;
font-size: 30px;
position: absolute;
left: 30px;
bottom: -40px;
z-index: 1;
}
p::after {
content: '●●●';
color: yellow;
font-size: 25px;
position: absolute;
left: 37px;
bottom: -35px;
}
すると、画面の表示は以下のようになります。

::afterで表示している緑色の●が、::beforeで表示している青い★の裏に移動したことがわかります。
モーダルを作成する
「::before」「::after」と「:target」を組み合わせることで、一時的に画面上を覆うモーダルを作成することもできます。
「:target」とは何か?については下記をご参考ください。
しかも、モーダル表示中はモーダルの要素以外の画面のどこかをクリックすれば、モーダルが閉じる便利な仕様です。
HTMLで用意するのは、モーダルを表示するためのリンク(aタグ)とモーダル用のdivタグのみです。
<a href="#modal-element">モーダルを開く</a>
<div class="modal" id="modal-element">
<div class="modal-box">
<a href="#" class="close"></a>
<p>疑似クラス:targetを使ってモーダルを表示しています。</p>
</div>
</div>
モーダルの中にモーダルを閉じるためのリンクを設置しているところがポイントです。
<a href="#" class="close"></a>
この要素に対して「::before」で全体を覆う黒い背景を設定し、「::after」で閉じるボタンを作成します。
どちらもaタグの疑似要素なので、どこをクリックしてもページトップに戻る処理となります。リンク先が変わるので、モーダルに適用している:targetのスタイルが適用されなくなります。
スタイルの構成要素は以下の5つです。
- モーダルをデフォルト非表示にする。
- モーダルの位置調整(画面中央に表示する)
- モーダルの中身。
- 画面を黒く覆う部分。
- 閉じるボタン。
それぞれのスタイルを記述すると以下のようになります。
/* モーダルはデフォルト非表示 */
.modal {
display: none;
}
/* モーダルの位置調整。画面中央に表示する */
.modal:target {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
/* モーダルの中身(ピンク色の部分) */
.modal-box p {
width: 80%;
position: relative;
padding: 40px;
background-color: lightpink;
border-radius: 10px;
}
/* 画面を黒く覆う部分 */
.modal .close::before {
left: 0;
top: 0;
width: 100%;
height: 100%;
position: fixed;
background-color: rgba(0,0,0,.7);
content: "";
cursor: default;
}
/* 閉じるボタンの位置調整のため */
.modal .close {
position: relative;
/* display: block; */
}
/* 閉じるボタン */
.modal .close::after {
right: -30rem;
top: 3px;
width: 30px;
height: 30px;
position: absolute;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
background-color: black;
border-radius: 50%;
color: white;
content: "×";
cursor: pointer;
}
デフォルトでは画面の表示は以下のようになっています。

↓ リンクをクリック。

↓ 閉じるボタン(あるいは画面の黒い部分)をクリック

モーダルが閉じます。
CSSファイルで「.modal .close」のようにスタイルを適用する要素を絞り込む方法については下記をご参考ください。
【CSS】セレクタの記号の意味は何か?違いや使い方を実例で解説。半角スペース(空白)、>(大なり・不等号)、*(アスタリスク)、+(プラス)、,(カンマ)、.(ドット)で指定する方法