ユーザビリティを向上するツールチップを作る【jQuery連載06】
- カテゴリー jQuery活用サンプル
前回は、ベーシックなタブでのコンテンツの切り替えや出現方法などについてまとめましたが、今回は、リンク部分やフォームなどにマウスカーソルをあてると説明や入力サポートなどを表示させるツールチップを作成してみます。
リンク部分にマウスカーソルを当てた際にリンク先や内容説明のための説明のテキストを入れる場合にtitle属性を指定すると吹き出しのように入力した内容がでてくるが、小さかったり、一瞬で消えてしまうので、よりわかりやすく吹き出しのデザインをしてリンク先の内容の説明や入力フォームのサポートなどに使用するツールチップを作成してみました。
今回作成したサンプル
【サンプル1】title属性または、data-tips属性にtipsを設定する
http://www.html5-memo.com/sample/jq-books/04/
【サンプル2】title属性にtipsを設定する
http://www.html5-memo.com/sample/jq-books/04/index_title_attr.html
左右のリンクボタンのHTML
ツールチップの一例として、一般的な画像スライダーの操作アイコンにマウスオーバーしたときに、そのアイコンの動作内容が記載されたツールチップが表示させます。
今回のサンプルの矢印アイコンは、アイコンフォントを使用している。要素にあらかじめ設定されたclassセレクタ名を付与するだけでアイコンが利用可能になるため、ここでは左向きの矢印と右向きの矢印を使用することにする。
また、アイコンと隣接して設定しているspan要素のテキストは音声読み上げブラウザ環境向けの対応であって、実際はCSSで非表示にしているため画面上には表示されない。
a要素に設定しているtitle属性は要素の内容を説明する補助的な属性で、アクセシビリティの観点からも積極的に設定することが推奨されるが、今回のツールチップはこのtitle属性の内容を読み取って独自のデザインで内容を表示するようにしてみます。
<ul class="controls"> <li class="icon icon_left"><a href="#" title="前のスライドを見る"><i class="fa fa-arrow-left"></i><span>前のスライドを見る</span></a></li> <li class="icon icon_right"><a href="#" title="次のスライドを見る"><i class="fa fa-arrow-right"></i><span>次のスライドを見る</span></a></li> </ul>
左右のリンクボタンのCSS
操作アイコン部分のCSSでは、アイコンフォントのプレースホルダーとして配置したi要素の設定と、span要素に設定されているテキストを要素の範囲外に飛ばして非表示にする設定を行っています。
#case_slider .controls { position: relative; top: 1em; width: 100%; min-height: 5em; } #case_slider .controls li { position: absolute; display: block; float: left; font-size: 4em; width: 1em; height: 1em; line-height: 1; overflow: hidden; } #case_slider .controls .icon_left { left: 0; text-align: left; } #case_slider .controls .icon_right { right: 0; text-align: right; } #case_slider .icon a:hover { color: #666; } #case_slider .icon span { display: block; margin-top: 2em; }
フォームの入力ヒントのHTML
2つ目の例として、フォームの入力ヒントとしての事例だ。基本的には1つ目の例と一緒だが、入力の際にツールチップの吹き出しが下方向に表示されるよりも、右側やそれ以外の方向に表示したい場合に、独自data属性のdata-tips-pos属性を設定することで実現できるようにしてみよう。
data-tips-pos属性は、2文字のアルファベットで構成されていて、最初の1文字目は縦方向の位置を表していて、CSSのvertical-alignプロパティの「top」「middle」「bottom」から頭の一文字をとって、「t」「m」「b」の3段階で設定する。
また、2文字目は横方向の位置を表していて、text-alignプロパティの「left」「center」「right」から頭一文字の「l」「c」「r」の3段階で設定し、中心配置をのぞいた8方向にツールチップを配置することが可能だ。
例のフォームでは右側中央に表示されるようにするため「data-tips-pos=”mr”」(middle:中央、right:右側)と設定している。
<form id="dummy_form"> <dl> <dt><label for="name">Name</label></dt> <dd><input type="text" id="name" name="name" title="お名前をローマ字で入力してください" data-tips-pos="mr"></label></dd> </dl> <dl> <dt><label for="email">E-mail</label></dt> <dd><input type="text" id="email" name="email" title="メールアドレスを入力してください" data-tips-pos="mr"></label></dd> </dl> <dl> <dt><label for="inquiry">Inquiry</label></dt> <dd><textarea id="inquiry" name="inquiry" title="お問い合わせ内容を入力してください" data-tips-pos="mr"></textarea></dd> </dl> <p class="submitBtn"><a href="#" id="btn_submit" name="submit" title="入力いただいた内容の確認画面に移動します" data-tips-pos="tc">入力内容を確認する</a></p> </form>
フォームの入力ヒントのCSS
フォーム部分のCSSでは、ツールチップに影響を与える箇所は無いが、CSSの疑似クラス:focusを利用してフォーム内でユーザーが入力しているの箇所だけが周囲よりも少し背景が明るくなるなど、ツールチップとあわせてユーザの行動をうまくサポートする施策をおこなうことは、EFO(Entry Form Optimization:エントリーフォーム最適化)の観点からも良いことだろう。
#case_form input, #case_form textarea { -webkit-transition: background 0.4s linear; transition: background 0.4s linear; } …省略… #case_form input:focus, #case_form textarea:focus { background: #f8f8f8; }
フォーム内容の説明を表示させ使い勝手を向上させる例。入力中のフォームの傍に入力を手助けするヒントを表示。
オリジナルツールチップのJavascript
今回のサンプルは基本型、ツールチップの位置変更、画像拡大(※書籍参照)の3つの例を作成しているが、ツールチップの仕組みは1つのJavascriptファイルで実行している。
これは、HTML5から独自data属性が導入されたことで、それらに設定された値をJavascriptで読み取ることで処理の分けをする事ができるためで、このツールチップのJavascriptでも独自data属性から様々な値を読み取って処理分けを行っています。
ただ、HTMLはあくまで文書構造を記述する言語であることから、その意義を逸脱しない程度に利用することが肝心だ。
;(function(d,$){ var JQdmtips; JQdmtips = function(){ // tips用の共通設定を定義 var param = { tipsContentContainer: '.tipsContentContainer', tipsContentGenerateContainer: 'body', tipsSelector: '*[title], *[data-tips-image], *[data-tips-movie]', tipsAttrTitle: 'title', tipsAttrBasic: 'data-tips', tipsAttrImage: 'data-tips-image', tipsPositionAttr: 'data-tips-pos', dataPossessor: d.body, imageMagnificationRate: 2.5, // 画像の拡大率 // tipsバルーンのスタイル。CSSで文字色や背景色を設定したセレクタ名を入力。デフォルトは何も入力しない。 tipsBallonColorSelector: 'color3' }; // tips対象要素にマウスオンしたら表示処理 $(param.tipsSelector).on('mouseover', function(e){ showTipsContent($(this)); }); // tips対象要素からマウスが離れたら非表示処理 $(param.tipsSelector).on('mouseout', function(e){ hideTipsContent($(param.tipsContentContainer)); }); /* tipsバルーンを表示 */ function showTipsContent(_$t){ // 処理で使用する変数を定義 var _$tcn = $(param.tipsContentContainer), _$tcgn = $(param.tipsContentGenerateContainer), _p = { tipsWidth: 0, tipsHeight: 0, triggerWidth: 0, triggerHeight: 0, contentAttr: (function(){ return _$t.attr(param.tipsAttrImage) ? param.tipsAttrImage : _$t.attr(param.tipsAttrBasic) ? param.tipsAttrBasic : _$t.attr(param.tipsAttrTitle) ? param.tipsAttrTitle : null; })() }, _attr = _p.contentAttr, _pos = _$t.attr(param.tipsPositionAttr), _$cnt; // tipsコンテンツを載せる土台(コンテナ)を作成 if(isElem(_$tcn)) { hideTipsContent(_$tcn); } _$tcn = $('<div>').prependTo(_$tcgn).addClass(replaceString(param.tipsContentContainer, '.')).addClass(replaceString(param.tipsBallonColorSelector, '.')); // 属性からtipsコンテンツ内容を決める switch(_attr){ // 画像簡易拡大機能の処理 case 'data-tips-image': var _base = { w: _$t.parent().width(), h: _$t.parent().height() }, _rate = _base.h / _base.w, _magW = _base.w * param.imageMagnificationRate, _magH = _magW * _rate; _$cnt = $('<img>').appendTo(_$tcn).attr({ src: _$t.attr(_attr) }); _$tcn.css({ width: _magW, height: _magH, overflow: 'hidden' }); _p.triggerWidth = _base.w; _p.triggerHeight = _base.h; _pos = _pos || 'tc'; break; // 通常のtips default: _$cnt = $('<p>').appendTo(_$tcn).html(_$t.attr(_attr)); // tilte属性の内容をdata-tips属性に複製する _$t.attr(param.tipsAttrBasic, _$t.attr(_attr)); _$t.removeAttr('title'); } // data-tips-dir属性からtipsコンテナの位置を決める _pos = _pos || 'bc'; $.data(param.dataPossessor, 'tipsWidth', _p.tipsWidth || _$tcn.width()); $.data(param.dataPossessor, 'tipsHeight', _p.tipsHeight || _$tcn.height()); $.data(param.dataPossessor, 'triggerWidth', _p.triggerWidth || _$t.width()); $.data(param.dataPossessor, 'triggerHeight', _p.triggerHeight || _$t.height()); _$tcn.css({ top: _$t.offset().top + cordinatePosition(_pos.charAt(0)), left: _$t.offset().left + cordinatePosition(_pos.charAt(1)), opacity: 1 }); } /* tipsバルーンを非表示 */ function hideTipsContent(_$t){ if(isElem(_$t)){ _$t.animate({ opacity: 0 }, 500, function(){ _$t.remove(); }); } } // tipsバルーンの位置を調整する function cordinatePosition(_pos){ return _pos == 't' ? -detectScale('tipsHeight') - 48: _pos == 'm' ? -detectScale('tipsHeight') / 2 : _pos == 'b' ? +detectScale('triggerHeight') + 24 : _pos == 'l' ? - detectScale('tipsWidth') : _pos == 'c' ? - detectScale('tipsWidth') / 2 + detectScale('triggerWidth') / 2 : _pos == 'r' ? + detectScale('triggerWidth') + 32 : 0; } // 要素の数を調べる function isElem(_$t){ return _$t.length; } // 一時的に保持している値を取得する function detectScale(_param){ return $.data(param.dataPossessor, _param) || 0; } // 文字列置換処理 function replaceString(_str, _bf, _af, _flg){ var _reg = new RegExp(_bf, _flg || ''); return _str.replace(_reg, _af || ''); } }; // オリジナルtipsを実行する JQdmtips(); })(document, jQuery);
今回は以上になります。
書籍の方ではツールチップの仕組みを利用して、簡易的な画像拡大機能のサンプルも作成しております。
キャプション:画像を別ページやモーダルにしないで簡易的に拡大して表示させる。data-tips-image属性に画像パスを設定する事で動作する。
【サンプル3】画像のクイックプレビューを設定する(簡易的な画像拡大機能)
http://www.html5-memo.com/sample/jq-books/04/popup_image.html
次回はWebサイトをスクロールさせる際に、特定のタイミングでヘッダーナビゲーション部分を上部に固定するサンプルを作成します。
この記事を書いた人
著者 : ハヤシユタカ
2001年、有限会社ムーニーワークスを設立。WEB制作の他、書籍執筆、セミナー講演、企業研修などを行う。また、クリエイター育成機関デジタルハリウッドでは1999年より講師として本科WEBデザイナーコースやデジタルデザインコースを担当。 詳しいプロフィールはこちら