最近覚えたWEBプログラミングの小細工を紹介したい。
まあ、こんな機能を知っていれば何かの役に立つかも知れない。
それは、CSSの設定において、::beforeや::afterでアクセスできる疑似要素に対して、そのcontentにattr()と言う特殊なやり方を使うと、ヘンテコな事が出来るのだ。
文章で説明するのは分りにくいので、早速実例で紹介しよう。
CSSで::beforeや::after疑似要素のcontent:attr()の使い方
まずは、以下に示すhtmlを使う。
<div id="divID"> これが本文 </div> <button id="btn1">Beforeを変更</button> <button id="btn2">Afterを変更</button>
まあ、divが一個とbuttonが二個の簡単なサンプルだ。
それらの要素の見栄え(=スタイル)を決めるCSS設定は以下のようにする。
<style> #divID::before { display: inline-block; content: attr( data-before ); border: 1px solid #00ff21; width: 100px; } #divID { border: 1px solid #ff0000; width: 400px; display: flex; margin-bottom: 20px; } #divID::after { display: inline-block; clear: both; content: attr(data-after); width: 100px; border: 1px solid #003cff; } </style>
上のCSS設定はちょっと長いので簡単に解説しておく。
この例では、一つのdiv要素と、その前後に二つの疑似要素を作成している。
::beforeはdiv要素の直前に作成される疑似要素だ。
幅は100pxにしているが、display:inline-blockにすると100pxの幅に出来る。
さて、CSS設定で重要なのが以下の部分だ。
content: attr( data-before );
恐らく多くの皆さんは初めて見る記述だと思う。
この意味はこの後で解説したいが、まずはこれらのhtmlやCSSで作成されるWEBページを表示してみる。
サンプルプログラムを実行する
その表示結果の画面キャプチャが以下の通り。
あるいは、このサンプルプログラムをこのページにも埋め込んだ。
その表示結果は以下の通り。
上のボタンをクリックするとデモが見られる。
画面キャプチャ画像と文字サイズなどが若干異なるが、それはあまり気にしなくても良い。
肝心なのは、div要素の前後にbeforeとafterの疑似要素が正しく追加されている点だ。
疑似要素に文字列を与える場合には、通常は、
content: '表示させたい文字列';
のように書くのが一般的だ。
今回は、その部分に、
content: attr( data-before ); content: attr( data-after );
などの見慣れぬ記述をしている。
この記述をする事によって、疑似要素のcontentをプログラム的に変更出来るのだ。
jQueryを使って疑似要素のcontentを動的に変更する
まずはjQueryでやってみる。
以下のプログラムコードを実行する。
<script> var divJQ = $('#divID'); divJQ.attr('data-before', 'これがBefore'); divJQ.attr('data-after', 'これがAfter'); $('#btn1').on('click', function () { divJQ.attr('data-before', 'Beforeを変更した'); }); $('#btn2').on('click', function () { divJQ.attr('data-after', 'Afterを変更した'); }); </script>
このコードの冒頭の部分で、二つの疑似要素に対してそのcontentに文字列をセットしている。
一方、二つのボタンのclickイベントでも、同じくcontentに別の文字列をセットしている。
これによって、ボタンをクリックすると、疑似要素のcontentを動的に変化させる事が可能だ。
実際に、[Beforeを変更]ボタンをクリックした後のキャプチャが以下の通り。
上のキャプチャは、before疑似要素のcontentを変更した状態だ。
もしJavaScriptだけで記述すると以下のようになる。
JavaScriptだけで疑似要素のcontentを動的に変更する
<script> var div_element = document.getElementById('divID'); div_element.setAttribute('data-before', 'これがBefore'); div_element.setAttribute('data-after', 'これがAfter'); document.getElementById('btn1').addEventListener('click', function () { div_element.setAttribute('data-before', 'Beforeを変更した'); //div_element.dataset.before = 'Beforeを変更した'; //これでも良い }); document.getElementById('btn2').addEventListener('click', function () { div_element.setAttribute('data-after', 'Afterを変更した'); //div_element.dataset.after = 'Afterを変更した'; //これでも良い }); </script>
なお、注意事項としては、content:attr(data-before); の値を変更する手法は以下のどちらの記述でも良い。
div_element.setAttribute('data-before', 'Beforeを変更した'); div_element.dataset.before = 'Beforeを変更した'; //これでも良い
data-* 属性はカスタムデータ属性と言うやつ
今回、CSS設定の中で用いたcontent:attr(data-before); の中のdata-beforeは、カスタムデータ属性と呼ばれる機能だ。
カスタムデータ属性は、一般には以下のような使い方をする。
<div id="divID" data-before="何らかのデータ"> これが本文 </div>
つまり、html要素に対して、自前のデータを保持しておく時に使う。
もう少し実用的なサンプルならこんな感じか。
<div id="divID" data-name="ワレコ" data-age="12" data-address="Osaka-fu"> ワテの個人情報 </div>
要するに、自分で好きなデータを data-* の形式でDOM要素に与える事が出来るのだ。
それらのデータはjQueryやJavaScriptで設定したり取得したり出来るのだ。
ワテの場合、こう言う便利機能が有る事を知らなかった当時は、何らかのデータを保持しておきたい場合には、兎に角JavaScriptの変数で保持していた。
でもそれだとグローバル変数になってしまうので、数が多くなるとどの変数が何の情報を保持しているのか自分自身でも分らなくなってしまう欠点がある。
それを今回紹介したDOM要素にdata-*と言うカスタムデータ属性で保持させる事で、そのDOM要素に関連するデータで有る事が一目瞭然なので、グローバル変数を大幅に減らす事が出来て混乱の解消に大いに役立つのだ。
今回の例では、
data-before data-after
と言うカスタムデータ属性を用いたが、これはワテが勝手に作成した属性なので、実際はどんな名前でも良い。
before疑似要素のcontentに使うから、data-beforeとしただけであり、data-先頭 などでも良いだろう。ただし、日本語が使えるのかどうかは未確認だ。
CSSで::beforeや::after疑似要素のcontent:attr()の使い方、その2
さて、もう少し別のサンプルを紹介したい。
今までの説明では、data-*カスタムデータ属性を使うやり方を紹介した。
でも、カスタムデータ属性以外の属性でも同様に扱う事が可能だ。
hrefデータを取り出して疑似要素のcontentにセットする
例えば href で指定しているurl文字列を同じように取り出して疑似要素のcontentにセットする例を紹介したい。
<p> <a id="aID" href="https://www.google.co.jp/">GoogleのサイトのURL→ </a> </p>
まず、上のhtmlはごく普通の <a> タグの例だ。
その<a>タグのafter疑似要素に対して、以下のCSS設定を行う。
#aID::after { content: '[ 'attr(href)' ]'; }
その表示結果は以下のようになる。
まあ、hrefに指定しているurl文字列を取り出してafter疑似要素のcontentにセットしただけであるが。
こう言うテクニックを覚えておけば、何かの役に立つだろう。
あるいは、もう少し別の例を紹介したい。
画像にタイトルを付ける
画像にタイトルを付けてみる。
<p id="pID" title="こすもす(ワテの撮影)"><img src="cosmos.PNG" alt="">この文字は取得できない。</p>
こんなhtmlと以下のCSSを使う。
#pID:after { content: attr(title); display: block; width: 487px; border:1px solid cyan; text-align: center; margin-top: 5px; }
その表示結果は以下の通り。
まあ、こんな風にわざわざ疑似要素を使わなくても、画像の下にタイトル文字列を表示するだけなら、普通にこんな風にやれば良いと思うが。
<div> <img src="cosmos.PNG" alt=""/> </div> <p>タイトル</p>
まとめ
当記事では、DOM要素に対してそのbeforeやafter疑似要素のcontentをプログラムで動的に変更する手法を紹介した。
と言うよりは、ワテの備忘録みたいなもんだな。
ここで紹介した手法を使うと、WEBページに表示している文字列を動的に変更する事が可能だ。
今回紹介した疑似要素を使う方式だと、必要最低限のDOM要素だけで実装出来るという点が長所かもしれない。
もし疑似要素を使わないで類似の事をやるなら<div>要素の前後に<div>を追加すれば良いだろう。
<div id="div_before">ここはBefore</div> <div id="divID">ここは本文</div> <div id="div_after">ここはAfter</div>
でも、その為にはjQueryやJavaScriptでdiv要素を追加すると言うDOM操作を行う必要がある。
まあそれでも良いが、今回紹介した疑似要素を使う方式なら、既存のdivIDだけで実現出来る。
と言う事で、何かの役に立つかな。
コメント