eureka

Nuxtで疑似要素のcontentを変更する

0

英語と日本語の見出しのときってみんなどうやってマークアップしてる?

最近は日本語の見出しの下に英語の見出しがあるデザインが増えてきたと思う(お道具箱然り笑)。
下記のようなデザインですね。

一時期Twitterでもちょっと話題になったような気がします。
こんな感じのとか

今実装中のものは英語がデザイン的なニュアンスになっているので英字部分を疑似要素にしたいなと思いました。
(あと英語も日本語も同じ内容ならアウトラインに出したくないなって)

てことで特に指定はなかったのでNuxtでも疑似要素でやっちゃいました。Vueでも使えると思います。

環境

nuxt 2.14.0

templateを用意

まずはHTML書いていきます。
(解説用に必要な部分のみシンプルに書きました)

<h1
  ref="pageTitle"
  class="title"
/>
  事業紹介
</h1>

ポイントはref属性です。後から使用します。

スタイルを用意

続いてスタイルを書きます。

.title {
  color: #010101;
  font-size: 36px;
  font-weight: normal;
  line-height: 1.7;
  letter-spacing: 0.1em;

  &::after {
    content: attr(data-title);
    display: block;
    font-family: Montserrat;
    letter-spacing: 0.05em;
    line-height: 1;
    font-size: 20px;
  }
}

注目すべきはこちら。

content: attr(data-title);

疑似要素にはattr()っていう機能が使えるので、この機能を利用してdata-titleの値をcontentに反映させるということをします。

いざ書き換える!

疑似要素を設定するためにVueコンポーネントのDOMにアクセスするのですが、DOMが生成されている状態でなければ参照はできませんので処理はmounted()に書きます。

export default {
  mounted() {
    const targetElement = this.$refs.pageTitle
    targetElement.setAttribute('data-title', '疑似要素セット!')
  }
}

ref属性を参照して、data-title属性を追加しました。

実際の使いどころ

私の場合はキービジュアル&タイトルをパスで出し分ける処理をしています。

こんな感じのページ情報のjsonファイルを用意して(実際にはもっと色々書いてますが)

[
  {
    id: 1,
    name: '事業紹介',
    enName: 'Business',
    pathName: 'business',
  },
  {
    id: 2,
    name: '私たちについて',
    enName: 'About us',
    pathName: 'about',
  },
  {
    ...
  }
]

script部分はざっくりこんな感じで書きました。

<script>
import PAGES from '~assets/json/samary.json'

export default {
  data() {
    return {
      PAGES,
    }
  },

  computed: {
    // samary.jsonのデータを参照して、
    // 現在のURLからページ情報を取得する関数
    getCurrentPage() {
      /**
       * 下記のようにオブジェクト形式で取得する処理をかく
       * 
       * {
       *   id: 1,
       *   name: '事業紹介',
       *   enName: 'Business',
       *   pathName: 'business',
       * }
       *
       */
    }
  },

  mounted() {
    const enName = this.getCurrentPage.enName
    const targetElement = this.$refs.pageTitle
    targetElement.setAttribute('data-title', enName)
  }
}
</script>

ちなみにテンプレートはこうです。

<h1
  ref="pageTitle"
  class="title"
  v-text="getCurrentPage.name"
/>

最後にひとこと

疑似要素に直接アクセスして取得・変更という方法もあるみたいでしたが、個人的にはこちらがスマートだなと思い採用しました。
マークアップへのこだわりがある方はぜひ。

参考

0