ブログ

Blog

疑似要素の内容を可変にするテクニックを紹介!

疑似要素の内容を可変にするテクニックを紹介!

疑似要素、使いこなしてますか?

どうも。フロントエンドエンジニアの杉原睦弘です。

皆さん、疑似要素は使いこなしていますか?
三角矢印を作ったりするとか、そういう装飾にだけ使ってはいませんか?
疑似要素って、装飾以外にも案外使えるものなんですよね。

本記事では、疑似要素の装飾以外の使い方を紹介しようと思います。

data属性の値を取得する

疑似要素のcontentプロパティには、attrを指定することができます。
attrはattributeの略で属性値を取得することができます。
そのため、data属性の値を疑似要素で使うことが可能です。
下記のように記述します。

.hoge {
  content: attr(data-hoge);
}

一例として、ツールチップを表示するCSSを作成します。

ツールチップを表示するサンプル

DEMO

テキスト本文だよツールチップがある文字だよテキスト本文だよ

上記の「ツールチップがある文字だよ」にマウスをホバーするとツールチップが表示されます。
(スマートフォンの場合は文字をタップや長押しすると表示されます)

※動作しない場合の為にキャプチャを用意しました。

HTML, CSSの構造は下記のようになっています。

ツールチップのHTML

<p>テキスト本文だよ<span class="tooltip" data-tooltip="ツールチップだよ">ツールチップがある文字だよ</span>テキスト本文だよ</p>

ツールチップのCSS

.tooltip {
  color: #e50281;
  cursor: pointer;
  display: inline-block;
  position: relative;
  margin: 10px 0;
}

.tooltip::before,
.tooltip::after {
  display: none;
  z-index: 2;
}

.tooltip:hover::before,
.tooltip:hover::after {
  display: block;
}

.tooltip::before {
  content: attr(data-tooltip);
  color: #fff;
  background: #e50281;
  font-size: 16px;
  position: absolute;
  top: calc(100% + 6px); /* 三角マーク分加算 */
  left: 0;
  padding: 4px 8px;
}

.tooltip::after {
  content: "";
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0 4px 6px 4px;
  border-color: transparent transparent #e50283 transparent;
  position: absolute;
  top: 100%;
  left: 10px;
}

色々と装飾があるため長くなっていますが、今回の趣旨であるattrでdata属性値を取得している箇所は、下記の部分です。

<span class="tooltip" data-tooltip="ツールチップだよ">ツールチップがある文字だよ</span>
.tooltip::before {
  content: attr(data-tooltip);
}

HTMLタグにある「data-tooltip」というdata属性値を、contentプロパティで使用しています。
このようにCSSを作成すると、HTMLタグのdata属性の値を変えさえすれば、疑似要素に表示する文字を可変にすることができます。

もし、attrを使わないようにして同様のツールチップを作成するとしたら、下記のようにツールチップの文章ごとにクラスを作成することになってしまうでしょう

.tooltip.type1::before {
  content: "ツールチップだよ";
}

.tooltip.type2::before {
  content: "tooltip-dayo";
}

このような作りでは記述量が多くなってしまいます。
また、文言をHTMLではなくCSSに記載してしまうと、文言修正の際に管理するファイルが増えてしまって運用上もよろしくありません。

疑似クラス:emptyセレクタ

:emptyセレクタはHTMLタグの中に空(空白文字もない)状態にマッチするセレクタです。
この疑似クラスと疑似要素を組み合わせると、「要素が空の時には疑似要素で文字を表示する」ということができます。

一例として、inputタグに入力した情報がpタグに反映されるものを作成しました。
inputタグが空になれば、pタグも空になり、疑似要素の文字が表示されます。

:emptyに疑似要素の文字を表示するサンプル

DEMO

DEMO

※動作しない場合の為にキャプチャを用意しました。

HTMLとCSSの構造は下記のようになっています。

:emptyサンプルのHTML

<p class="empty-check"></p>

:emptyサンプルのCSS

.empty-check:empty::before {
  content: "この要素は空です";
  color: #e50281;
  font-size: 16px;
  display: inline-block;
}

今回は疑似要素の文字を固定にしましたが、空の時の文章が可変なようであれば、data属性値を使う方法で改変した方がよいでしょう。

counter関数を使う

contentプロパティには counter, counters といった関数で、を使用することができます。
counter関数を使うにあたり、counter-reset, counter-increment というプロパティを併用します。
counter-resetプロパティはカウントする変数の値を0に初期化します。
counter-incrementプロパティは数値を増やしていきます。

一例として、目次の連番の数字を疑似要素で生成するサンプルを作成します。

counter関数のサンプル

counter関数サンプルのHTML

  <p>目次だよ</p>
  <ol class="counter-list">
    <li>タイトルだよ
      <ol class="counter-list">
        <li>タイトルだね</li>
        <li>タイトルかな</li>
        <li>タイトルだな</li>
      </ol>
    </li>
    <li>タイトルだし</li>
    <li>タイトルかも</li>
  </ol>

counter関数サンプルのCSS

.counter-list {
  counter-reset: count; /* 値を0として初期化 */
}

.counter-list li {
  counter-increment: count; /* 数値をインクリメント */
}

.counter-list li::before {
  content: counter(count) "."; /* contentプロパティに数値を渡す */
  display: inline-block;
  margin-right: 10px;
}

リストがネストした場合は、各リストごとに数値がインクリメントされていることがわかるかと思います。
これはcounter-resetプロパティで値を初期値0に設定しているため、各リストごとに連番が作成されます。

counter-resetプロパティを指定しない場合は以下のように、各リストごとではなく、親のリストの連番としてインクリメントされます。

counters関数を使う

counters関数は、ネストしたリスト内で、親の連番の数値を利用することができます。
第1引数には変数名を指定し、第2引数には親のリストの数値と結合させる時の区切り文字を指定します。

一例として、三階層にネストさせたリストのサンプルを作成します。

counters関数のサンプル

counters関数サンプルのHTML

<div class="wrap">
  <p>目次だよ</p>
  <ol class="counter-list">
    <li>タイトルだよ
      <ol class="counter-list">
        <li>タイトルだね
          <ol class="counter-list">
            <li>タイトルだもの</li>
            <li>タイトルだから</li>
          </ol>
        </li>
        <li>タイトルかな</li>
        <li>タイトルだな</li>
      </ol>
    </li>
    <li>タイトルだし</li>
    <li>タイトルかも</li>
  </ol>
</div>

counters関数サンプルのCSS

.counter-list {
  counter-reset: count; /* 値を0として初期化 */
}

.counter-list li {
  counter-increment: count; /* 数値をインクリメント */
}

.counter-list li::before {
  content: counters(count, '.'); /* 第2引数で区切り文字を指定 */
  margin-right: 10px;
}

三階層目のリストが「1.1.1」という具合に区切り文字の「.(ドット)」で結合されて表示されています。
counters関数は、利用規約のページなど、連番が親の数値を利用する形式の文章の時に使えるかと思います。

最後に

疑似要素に表示する項目を可変にする方法を紹介してきました。
こんな便利機能を知ってしまうと、使いたくなっちゃいますよね?
特に、data属性の値を取得する方法は設計次第でいくらでも応用が利きます。
是非活用してみてください。

ではでは

  • SNS
  • 投稿日
  • カテゴリー

    BTM Useful