CSSのattr関数を使ったデザイン実装サンプル
CSSのattr関数を使うと、本来CSSのcontent:で記述する文字情報をHTMLの中から読み込む事ができます。
attr関数を使う事でCSSの本文であるデザインと構造の分離が守れます。
HTMLソースを計量化でき、修正などもHTML側だけで済み、CSS管理もしやすくなるメリットがあります。
CSSのcontentプロパティの問題点
cssの「content:」は、要素の直前または直後に文字列や画像などのコンテンツを挿入する事ができるプロパティです。
擬似要素である:before或いは:afterを適用する事で、マークや文字の表示によく使われます。
例えばリスト項目の先頭につく「マーク」や「アイコン」などが代表例でしょう。
content:表現の問題
様々な文字や画像を入れる事ができる便利なプロパティですが、いくつか問題もあります。
・css内に表示する文字・画像が入るため、コンテンツと装飾が分離できなくなる
・コンテンツを修正する際に、毎回cssを編集する必要がある
基本的に文字はHTMLソース内に記述するのがセオリーですが、content:の表現はCSSの中に書かなければなりません。
たくさんの装飾を設定すればする程、それだけCSS側の設定も膨らむ事になりますよね。
いざその箇所を修正をするとなると、毎回CSSファイルを開いてcontent:の箇所を修正する必要が出てきます。
そこで登場するのがcss関数のattrです。
CSSのattr関数
attrはhtmlからデータを取得できる
attrは、javascriptのようにhtmlからデータを取得する事ができる関数です。
このCSS関数を利用すると、contentプロパティを使ってHTMLソース内の情報を参照する事ができるのです。
この関数により読み出す文字列をCSS内に書く必要がなくなり、修正はHTML側だけで済みます。
CSSの本文に忠実な関数
本来CSSは、構造とデザインを分離するのが本来の役割ですよね。
attrにより構造や内容を全てHTML内にまとめる事ができれば、記述を少なくする事にもつながります。
管理が煩雑にならず、逆にしやすくなるメリットもあります。
attr関数を使ったデザインサンプル
今回はcontent:表現のattr()関数を使ったデザインサンプルをご紹介します。
他にも様々な使い方がありますが、今回はほんの一例の紹介に留めます。
今回は共通マークの様な単純な文字ではなく、きちんとした文字情報をdata属性に格納してデザインをした事例となります。
全てデータをHTMLファイルの中に集約しているので編集も容易です。
Wordpressの場合もwp-header.phpを編集するだけになりますので、大変便利ですよね。
タグ量の省エネにつながる
極論、HTML内に記述するのであれば、わざわざcontent:を使った表現の必要はないと言えるかも知れません。
しかし上手く表現すればHTMLタグの量、CSSによる制御の量を減らす事にもつがなるのです。
ナビゲーションメニューの補足テキスト
ナビゲーションメニューで日本語と英語とを一緒に表示させている事ってありますよね。
本サンプルでは英語を大きく、その下に日本語を小さく表示させてデザインしています。
実装サンプル
HTMLタグ
<div class="attr"> <ul> <li><a href="#" data-text="ホーム">Home</a></li> <li><a href="#" data-text="会社概要">Corp</a></li> <li><a href="#" data-text="実績紹介">Example</a></li> <li><a href="#" data-text="ブログ">Blog</a></li> <li><a href="#" data-text="お問い合わせ">Contact</a></li> </ul> </div>
CSS
.attr{ padding-bottom: 40px; overflow-x: scroll; } .attr ul { white-space: nowrap; margin: 20px 0 0 0; padding: 0; list-style: none; text-align: center; } .attr ul li { display: inline-block; margin: 0 1em; } .attr ul li a { display: inline-block; padding: .2em 1em; color: #333; font-family: 'Open Sans', sans-serif; font-weight: 400; line-height: 1; text-transform: uppercase; text-decoration: none; } .attr ul li a::after { content: attr(data-text); display: block; margin-top: .7em; color: #aaa; font-size: 11px; }
CSS解説
英語メニュー部分はHTMLのul liタグを使ってそのまま表示し、下の日本語部分はdata-text内に表示させています。
仮にこの日本語の部分をタグで別途記述すると、記述量も増えますしその分CSSによるデザインコントロールの必要が出てきます。
data属性に入れる事でコンパクトにまとめられた良い事例と言えます。
日本語表記を::afterで表現
英語メニュー部分は、liの各項目をdisplay: inline-block;扱いにして横並びにしています。
さらにul li a::afterで、格納された日本語テキストメニューを表示させます。
margin-topを入れる事で、各英語メニューの下に位置するようにしている訳ですね。
スマホ版に注意
本サンプルはレスポンシブルメニューではないので、スマホ版で枠外にはみ出ないようにoverflow-x:scroll;を設定しています。
ナビゲーションマウスオーバー時のツールチップ
本サンプルは上のサンプルの改良版となります。
英語メニュー部分をHTMLで表示し、data属性に格納したテキストは日本語ツールチップとして利用しています。
このツールチップ部分は基本非表示で、マウスオーバーすると表示される仕組みです。
このサンプルではマウスオーバー時に表示させるため「data-hover」としています。
実装サンプル
下のメニューにマウスを合わせるとツールチップが表示されます。
HTMLタグ
<div class="attr"> <ul> <li><a href="#" data-hover="ホーム">Home</a></li> <li><a href="#" data-hover="会社概要">About</a></li> <li><a href="#" data-hover="実績紹介">Works</a></li> <li><a href="#" data-hover="ブログ">Blog</a></li> <li><a href="#" data-hover="お問い合わせ">Contact</a></li> </ul> </div>
CSS
.attr{ padding-bottom: 40px; overflow-x: scroll; } .attr ul { margin: 0; padding: 0; list-style: none; text-align: center; } .attr ul li { display: inline-block; margin: 0 1.5em; } .attr ul li a { position: relative; display: inline-block; padding: .2em .5em; color: #333; font-family: 'Open Sans', sans-serif; font-weight: 400; line-height: 1; text-transform: uppercase; text-decoration: none; } .attr ul li a::after, .attr ul li a::before { position: absolute; transition: .3s ease-in-out; opacity: 0; } .attr ul li a::after { /*通常時の角丸長方形の位置*/ top: 26px; left: 0; content: attr(data-hover); display: block; width: 100%; padding: .6em 0 .9em; background-color: rgba(0, 0, 0, .5); border-radius: 4px; color: #fff; font-size: 11px; } .attr ul li a::before { /*通常時の三角の位置*/ top: 10px; left: 50%; content: ''; margin-left: -8px; border: 8px solid transparent; border-bottom-color: rgba(0, 0, 0, .5); } /*マウスオーバー時の角丸長方形の位置*/ .attr ul li a:hover::after, .attr ul li a:focus::after { top: 34px; opacity: 1; } /*マウスオーバー時の三角形の位置*/ .attr ul li a:hover::before, .attr ul li a:focus::before { top: 18px; opacity: 1; }
CSS解説
after・before両方を絶対配置にしています。これがツールチップを構成します。
ul li a::afterでツールチップの土台となる黒色の角丸長方形を作っています。
ul li a::beforeで吹き出し部分となる三角形を作っています。
ツールチップはこの角丸長方形と三角で作られています。
ツールチップがフェードインしてくるギミック
メニューにマウスが乗る前、角丸長方形と三角はいずれも透明になっています(opacity: 0;)。
マウスが乗る前とhoverやfocusした時とで、それぞれの絶対配置の位置を少しずらしておきます。
その上でtransition: .3s ease-in-out;により、マウスオーバー時に角丸長方形と三角が滑らかに表示されるようにしています。
tableデータのレスポンシブ加工表示
本サンプルはtableタグで大量のデータ表示させている際に、スマホ版のレスポンシブルデザイン案の一つとして有効な方法になると思います。
tableタグ構成としては、基本的にセオリー通りです。
thタグで横並びしているtitle1、title2、title3の欄と同じものがtdのdata-title内に入っています。
実装サンプル
title1 | title2 | title3 | title4 | title5 | title6 | |
---|---|---|---|---|---|---|
category01 | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ |
category02 | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ | テーブルデータテーブルデータテーブルデータテーブルデータ |
HTMLタグ
<table class="base-table"> <thead> <tr> <th></th> <th>title1</th> <th>title2</th> <th>title3</th> <th>title4</th> <th>title5</th> <th>title6</th> </tr> </thead> <tbody> <tr> <th>category01</th> <td data-title="title1"></td> <td data-title="title2"></td> <td data-title="title3"></td> <td data-title="title4"></td> <td data-title="title5"></td> <td data-title="title6"></td> </tr> <tr> <th>category02</th> <td data-title="title1"></td> <td data-title="title2"></td> <td data-title="title3"></td> <td data-title="title4"></td> <td data-title="title5"></td> <td data-title="title6"></td> </tr> </tbody> </table>
CSS
.base-table { width: 100%; margin: 0; } .base-table th, .base-table td { padding: 10px; } .base-table { border-collapse: collapse; border: 1px solid #999; } .base-table thead th { background: #CCC; border: 1px solid #999; } .base-table tbody th { background: #47cf73; border: 1px solid #999; } .base-table tbody td { border: 1px solid #999; } @media only screen and (max-width: 767px) { .base-table { box-sizing: border-box; border: none; } /*th欄を消す*/ .base-table thead th { display: none; } .base-table tbody th { display: block; background: #47cf73; margin-bottom: 20px; } /*td欄を縦に並べる*/ .base-table tbody td { padding: 0 0 10px; margin: 0; display: block; width: 100%; position: relative; box-sizing: border-box; border: none; } /*data-titleをグレー小見出しにする*/ .base-table tbody td:before { content: attr(data-title); background: #CCC; width: 100%; display: block; box-sizing: border-box; padding: 10px; margin-bottom: 10px; font-weight: bold; } }
PC版の場合
PC版では特に変化はなく、そのままのデザインでtableタグを表現していますね。
サンプルでは6列なのでなんとか一応枠内に収まっていますが、これが10列などになれば見切れてしまう場合もあります。
その場合はoverflow-x scrollなど横軸のスクロールバーで、見切れた分を表示できる様にする必要がありますね。
スマホ版の場合
@media only screen and (max-width: 767px)内がスマホ版のデザインになります。
まずtheadのthの欄については、全てdisplay: none;で消してしまいます。
次にtbodyのthの欄(縦並び)をdisplay:block;とし、緑の帯の大見出しにします。
さらにPC版で列並びのtdデータ欄は、display:block;とwidth:100%とする事で1段ずつ縦に並ぶようにします。
ここまではスマホ版向け仕様としてよく行われますね。
CSSの解説:ポイント
そしてここでtd内にあるdata-titleの出番です。
td:beforeでdata-title欄を独立させ、グレー帯の小見出しとして表示します。
列並びしていたth部分を消したので、代役をtdのdata-titleに務めさせている点が重要です。
長い列数を全て行に変える
これでどんなに横に長い(列数が多い)tableデータであっても、スマホ版では全て縦並びになりますので画面から見切れる事がありません。
例えば10列4段のテーブルタグなら、10段1セットのデータが4セット縦に並ぶ事になりますね。
セクションの背景テキストデザイン
ダーク色で塗りつぶされた要素を置き、その上にdata属性で設定されたテキストを透過状態で載せます。
その上に文章テキストが乗ったサンプルです。
実装サンプル
文章テキスト
文章テキスト
文章テキスト
文章テキスト
メインテキストの「背景」として映える様、英語テキスト「background」が透過されたサンプルです。
HTMLタグ
<div class="feed-area"> <div class="row"> <div class="col-sm-12"> <div data-text="background" class="site-title text-center"> <p>文章テキスト<br>文章テキスト<br>文章テキスト<br>文章テキスト</p> </div> </div> </div> </div>
CSS
.feed-area { margin: 40px 0 0 0; padding: 0; position: relative; height: 200px; z-index: 1; } .feed-area::before { position: absolute; content: ''; height: 100%; width: 100%; top: 0; left: 0; background-color: rgba(0,0,0,.58); z-index: -1; } .feed-area .site-title { position: relative; z-index: 1; } .feed-area .site-title::before { position: absolute; content: attr(data-text); top: 0px; left: 50%; font-size: 10rem; color: #FCFCFC; z-index: -1; font-weight: 600; transform: translate(-50%, 0); width: 100%; opacity: 0.3; } .feed-area .site-title p { font-size: 2rem; line-height: 2.3; color: #fff; }
CSSの解説
まずは::beforeを使って、feed-area要素にグレー背景を重ねます。
site-title要素のdata属性内には「background」の英語テキストを入れています。
次にsite-title要素の::beforeで、data-text内の文字を薄く透過させて設置します。
軽くて簡単なソース
このサンプルの特徴としてはやはり、HTMLソースが少なくて済む点ですよね。
さらに編集時もコンテンツごとにdata-textのHTMLテキストを変更すれば済みます。
セクションの背景テキストデザイン2
前のサンプル同様、コンテンツの背景としてアルファベット1文字を薄く表示したサンプルです。
実装サンプル
HTMLタグ
<div class="row"> <div class="col-sm-4"> <div class="wt-icon-box-wraper data-title-large"> <div class=" m-b30"> <h4 class="wt-tilte-large" data-title="A">Aサンプル見出し</h4> <p></p> </div> </div> </div> <div class="col-sm-4"> <div class="wt-icon-box-wraper data-title-large"> <div class="m-b30"> <h4 class="wt-tilte-large" data-title="B">Bサンプル見出し</h4> <p></p> </div> </div> </div> <div class="col-sm-4"> <div class="wt-icon-box-wraper data-title-large"> <div class="m-b30"> <h4 class="wt-tilte-large" data-title="C">Cサンプル見出し</h4> <p></p> </div> </div> </div> </div>
CSS
.wt-icon-box-wraper{ position: relative; z-index: 1; } .data-title-large{ position: relative; overflow: hidden; } .data-title-large .wt-tilte-large:after{ font-family: 'Poppins', sans-serif; position: absolute; content: attr(data-title); opacity: 0.1; color: #000; font-weight: 700; font-size: 160px; line-height: 160px; bottom: 3%; right: 0px; z-index: 2; -webkit-text-fill-color: rgba(0,0,0,0); -ms-text-fill-color: rgba(0,0,0,0); -moz-text-fill-color: rgba(0,0,0,0); -o-text-fill-color: rgba(0,0,0,0); -webkit-text-stroke-width: 1px; -ms-text-stroke-width: 1px; -moz-text-stroke-width: 1px; -o-text-stroke-width: 1px; } .data-title-large p{ margin-bottom: 15px; }
CSSの解説
data-title内にアルファベットの一文字を入れて、任意の位置に表示しています。
例えば各項目ごとのアルファベットをdata属性に入れておけば簡単に変える事ができます。
もしこれをcontent:でやろうとすると、それぞれCSSの記述が必要になりますのでCSSの余計な肥大を防げます。
複数並べる事でデザイン性が上がるサンプル例です。
アルファベットの縁取り
アルファベットには縁取りがしてありますが、テキストを直接装飾しています。
これを実現しているのがtext-fill-colorとtext-stroke-widthの部分です。
ベンダープレフィックスしてあるので複数の設定が並べてあるだけです。