Javascriptで擬似要素のプロパティ値を変更する
動機
上記画像のような吹き出しを以下のデザイン仕様に則り実装する必要がありました。
- ?アイコンの左には様々な文章が入る(ただし1行で収まると仮定)
- 吹き出しの三角形(ポインター)部分が必ず?アイコンの上に来るようにする
?アイコンの左にどんな文章来ても吹き出しのポインターが?アイコンの真上に来るようにするため、吹き出しのポインターのX軸の位置は可変にする必要がありました。
吹き出しのポインター部分は疑似要素(::before)で作っており、疑似要素のleft
プロパティの値を動的に変更したいのですが、Javascriptで疑似要素のインラインスタイルを変更することはできません。
この記事ではこちらの問題を解決する方法について記載します。
実現方法
left
プロパティの値を変更する
カスタムプロパティを使用し、疑似要素の以下のようなHTML, CSSで吹き出し部分を作ります。
balloon
クラスの疑似要素としてポインターが作られます。
balloon
クラス(もしくはそれより上位のスコープ)でカスタムプロパティを定義し、疑似要素内でそのカスタムプロパティの値を参照するようにします。
<div class="balloon">
<span>テストテストテスト...</span>
</div>
.balloon {
--balloon-pointer-left: 0px;
::before {
left: var(--balloon-pointer-left);
}
}
そしてJavascriptから以下のようにカスタムプロパティの値を変更することで、擬似要素のleft
の値を変更する事ができます。
balloonElement.style.setProperty('--balloon-pointer-left', '100px')
こちらの方法で?アイコンの左にどんな文章来ても吹き出しのポインターが?アイコンの真上に来るようにできました。
おまけ: attr()について
今回の実現方法を調べていた際、将来的にCSS関数のattr()で同様のことが実現できるかもしれないと思い、少し紹介します。
attr()
は選択された要素の属性値を受け取り、スタイルシートの中で使用できる関数です。(疑似要素でも使用できる)
こちらの関数はどのCSSプロパティでも使用できますが、現状content
プロパティ以外の対応は実験的という状況です。
将来的に様々なプロパティでサポートされるようになれば、以下のようにカスタムプロパティではなく属性値をJavascriptで変更することで、疑似要素のプロパティ値を変更できるようになるかもしれません。
<div class="balloon" data-balloon-pointer-left="0">
<span>テストテストテスト...</span>
</div>
.balloon {
::before {
left: attr(data-balloon-pointer-left px);
}
}
balloonElement.setAttribute("data-balloon-pointer-left", "100");
Discussion