1.023world - ヤドカリパークとマリンアクアリウム -

海洋の仕組みと細菌・微生物から学ぶマリンアクアリウムサイト

1.023world Facebook

結果 Oh! Life (旧ブログ)

懲りずに書いてみたりする結果オーライな日記

CSSで三角形を作る→ツールチップへの応用

ウェブ@海水業界 エイジ 09:09

2011/10/15 JavaScriptソース修正

­ ­

この三角形、CSS だけで実現されているって判ります?
実はボーダーを配したレイヤの角で得られるエンボス効果を利用したものなんですね。
言われてみれば納得ですが、これを三角形に応用しようなんて、僕も思いもつきませんでした。

ちなみにこれは、マイコミジャーナルの記事からネタ元(英語)を見て知りました。
さらにそちらでは、この三角形をツールチップに応用したソースも公開されていました。
この方法なら、角丸は別としても(爆)、吹き出しフレームに不可欠なポインター(尖ったとこ)まで、画像を使わず CSS のみで実現可能になります。
いやぁ、なんでも考える人がいるもんですね。感心させられます。

ところで僕自身はツールチップと言うもの自体あまり好きくないのですが(笑)、せっかくなのでこれをさらに進化させて、CSS + JavaScript で自動的にツールチップを生成する実験をしてみました。

サンプルページ

このアンカー(リンク)のソースはこうなってます。

<a href="#" class="tooltip"
 title="このツールチップは画像を使わずCSSのみで実現しています">ここ</a>

ツールチップを出したいアンカーに、class="tooltip" と、title="テキスト" を設定しておけば自動的に JavaScript でツールチップへ変換してくれるという仕組みです。構成は外部CSSファイルと外部JSファイルを予めヘッダ内で読み込ませるだけです。あとは上記の方法でリンクを書けば、勝手にツールチップが生成されます。要するに、ブラウザデフォルトのツールチップをオリジナルのモノに置き換えると言う方式ですね。

ネタ元の方法ではツールチップの内容を直接フィールドに配置していますが、僕の場合は本来の用途そのままにアンカーのタイトルに入れました。これはいろいろ考えた末の結果ですが、世知辛い時代ですので、どちらが良いのかの判断はみなさまにお任せしたいと思います(爆)

ツールチップ自動生成ツールの概要

このツールは、外部CSSファイルと外部JSファイルをヘッダ内に読み込ませるだけで動作します。

大まかなフローだけ説明しますと、ページ読み込み完了時に JavaScript でページ内をスキャンして、クラス名に「tooltip」を持つアンカーで且つタイトル属性が設定されていれば、そのタイトルをツールチップに変換するというものです。

なるべくソースを簡潔にするために、必要最小限の構成になっています。あまり厳密なことはやってないので、気になる方は気の済むように弄ってください(汗)。親切な方からのアドバイス等も頂けたら嬉しいです。

注意点としては、変換されたツールチップは body 末尾に不可視状態で蓄積され、アンカーへのオンカーソルに応じて該当のツールチップを可視制御しています。アンカーとツールチップには連番の ID が割り当てられますので、対象ページでの既存 ID との衝突にご注意ください (滅多なことは無いと思うけど)

アンカー ID 連番: ancher-0 ~ ancher-n
ツールチップ ID 連番: tooltip-0 ~ tooltip-n

その他、動作環境ですが、一応以下のブラウザで動作確認ができました。いずれも Windows のみでの確認。

  • IE 7 OK (角丸無し)
    IE 6 は transparent の処理が変だけど OK (角丸無し)
  • Firefox 2以上 OK
  • Safari 3 以上 OK
  • Netscape 7.1 以上 OK
  • Opera 9.6 OK (角丸無し)
  • Chrome 1.0 OK

以下、汚いソース(汗)で恐縮ですが、興味があればご自由にどうぞ。
但し角丸は IE と Opera では再現されませんのであしからず(汗)

外部CSSファイル用ソース

適当に名前を付けて保存してください (tooltip.css とか)

div.tooltip {
  position:absolute;
  z-index:999;
  display:none;
  width:120px;
  height:0;
  text-align:left;
  line-height:0;   /* for IE */
}

div.tooltip p {
  position:absolute;
  bottom:0;
  width:120px;
  margin:0;
  padding:4px 6px;
  text-align:left;
  line-height:1.1em;
  font-size:12px;
  font-family:Osaka,'MS UI Gothic',sans-serif;
  color:#369;
  background:#cde;
  border:solid 1px #369;
  -moz-border-radius:4px;   /* for Mozilla */
  -webkit-border-radius:4px;   /* for Safari */
  -khtml-border-radius:4px;   /* for Old Safari, KHTML */
  border-radius:4px;   /* for CSS3 */
}
html>body div.tooltip p {
  width:108px;
}

div.tooltip div {
  position:absolute;
  width:0;
  height:0;
  line-height:0;   /* for IE */
  border-right:0;
  border-bottom:0;
}
div.tooltip div.point-border {
  z-index:1;
  top:-1px;
  left:70px;
  border-top:solid 10px #369;
  border-left:solid 10px transparent;
}
div.tooltip div.point-inner {
  z-index:2;
  top:-2px;
  left:71px;
  border-top:solid 8px #cde;
  border-left:solid 8px transparent;
}

色とか自由に書き換えてください。

外部JSファイル用ソース

適当に名前を付けて保存してください (tooltip.js とか)

var ua = navigator.userAgent.toLowerCase();
var ie = (!window.opera && ua.indexOf('msie') != -1)? Number(ua.charAt(ua.indexOf('msie ') + 5)): 0;

/* ↓ 2011/10/15追加 */
if(!ie){
 (function(){
  var evt = ['mousedown','mouseover','mouseout','mousemove',
             'mousedrag','click','dblclick'];
  for(var i=0; i<evt.length; i++){
   window.addEventListener(evt[i], function(e){window.event=e;}, true);
  }
 }());
};

function setTooltip(){
  var a = document.getElementsByTagName('a');
  for(var i=0;i<a.length;i++){
    if(a[i].getAttribute('class') == 'tooltip' || a[i].getAttribute('className') == 'tooltip'){
      if(!a[i].getAttribute('title')) continue;
      var tooltip = document.createElement('div');
      tooltip.setAttribute('id','tooltip-' + i);
      setClass(tooltip,'tooltip');
      var text = document.createElement('p');
      text.appendChild(document.createTextNode(a[i].getAttribute('title')));
      tooltip.appendChild(text);
      var pointBorder = document.createElement('div');
      setClass(pointBorder,'point-border');
      tooltip.appendChild(pointBorder);
      var pointInner = document.createElement('div');
      setClass(pointInner,'point-inner');
      tooltip.appendChild(pointInner);
      document.body.appendChild(tooltip);
      a[i].setAttribute('id','ancher-' + i);
      a[i].setAttribute('title','');
      a[i].style.position = 'relative';
      a[i].onmouseover = function(){
        var id = this.getAttribute('id').split('-')[1];
        var tooltip = document.getElementById('tooltip-' + id).style;
        var pos = getPosition();
        tooltip.top = (pos.y - 20) + 'px';
        tooltip.left = (pos.x - 80) + 'px';
        tooltip.display = 'block';
      };
      a[i].onmouseout = function(){
        var id = this.getAttribute('id').split('-')[1];
        document.getElementById('tooltip-' + id).style.display = 'none';
      };
    }
  }
}

function setClass(obj,value){
  (ie && ie < 8)? obj.setAttribute('className',value): obj.setAttribute('class',value);
}

function getPosition(){
  var obj = new Object;
  obj.x = (ie)? window.event.clientX + (document.documentElement.scrollLeft|document.body.scrollLeft):
                (window.event.clientX + window.pageXOffset|window.event.pageX);
  obj.y = (ie)? window.event.clientY + (document.documentElement.scrollTop|document.body.scrollTop):
                (window.event.clientY + window.pageYOffset|window.event.pageY);
  return obj;
}

function setOnload(func){
  (window.addEventListener)? window.addEventListener('load',func,false):
  (window.attachEvent)? window.attachEvent('onload',func):
  window.onload = func;
}

setOnload(setTooltip);

うまくコピペできないときは、以下のファイルを参考にしてください。

CSSファイル:tooltip.css
JavaScriptファイル:tooltip.js

念のためヘッダへの記述方法

<link type="text/css" rel="stylesheet" href="tooltip.css" />
<script type="text/javascript" src="tooltip.js"></script>

パスはきちんと通るように記述してくださいね。絶対パスが無難でしょう。

何かご意見ご指摘等あればコメントをお願いします。

こちらのエントリーもどうぞ♪

コメントとトラックバック

  1. 1. kiona 2011/10/14 16:04

    面白いエントリー、ありがとうございます。

    tooltip使わせていただいているのですが、Firefox7以降で表示されないようです。cssをいじってみたのですが変わらず、javascriptのほうかなと思うのですが、自分では解決できません。

    お時間がありましたら、ちらとチェックしていただけないでしょうか。
    (当方の環境 MacOSX 10.6.4, 10.7, Windows XP)

  2. 2. エイジ 2011/10/14 17:49

    コメントありがとうございます。

    当方の環境(Win XP SP3 + Firefox 7.0.1)ですと、互換モード/標準モード共に、正常に動作するようでした。(ちなみにXP+IE8+互換モードではエラーが見つかりました汗)

    可能であれば該当のページを拝見できれば、お調べしてみます。
    公開が無理なら、必要ファイルを一式メールでお送りいただいても結構です。
    info@1023world.netまで

  3. 3. kiona 2011/10/15 03:55

    ありがとうございます!!

    ちなみにこちらのページに仕込んでおります。
    http://manicode.jp/gallery.html

    こちらでは XP(SP3) IE8では多少ゆらゆらする場合もありますが表示され、Firefox 7ではXP, Mac OSX(10.6.4)ともに表示されず。ツールチップ自体が出ず・・

    shadowboxを入れているので、その絡みかもしれません。webkit系ではきれいに出るのですが。

    お手数おかけしますが、よろしくお願いします。

  4. 4. エイジ 2011/10/15 18:47

    kionaさん、

    よくよく調べてみましたら、JavaScriptに漏れが見つかりました(汗)
    赤字で追記しておきましたので、上のソースを参考に修正してみてください。

    あと、kionaさんのページも拝見しましたが、もしかしたらに直記されているonloadのせいもあるかもしれません。tooltip.js自身も内部でonloadを使っているので、それが直記onloadのせいで上書き(消失)されてる可能性もありそうです。
    もしお時間があるなら、思い切って現在の冗長なコード(失礼)を一新なさってみては?
    (いくつかのブラウザではサムネイルが表示されていませんでした)

  5. 5. エイジ 2011/10/15 22:45

    kionaさん、

    気まぐれでサムネイル管理スクリプトを作成してみました。
    コメント投稿時のメールアドレスへお送りしておきました。ご確認ください。
    良かったら参考にしてみてください。

  6. 6. kiona 2011/10/16 19:06

    エイジさま

    Firefox 7で表示できるようになりました。Macでも、変わらず問題ありません。かたじけないです。

    こんな風にササッとコードが書けるようになりたいです^ ^ ありがとうございました。

  7. 7. kiona 2011/10/20 05:07

    おかげさまで、先のネイルのページに実装させていただきました。
    jsに少し追記して、ツールチップ内で任意の改行ができるようにしました。
    (軽く言ってますが、さんざん苦労しました^ ^)

    ご報告かたがた。いろいろとありがとうございました。

  8. 8. エイジ 2011/10/21 05:16

    お役に立ててよかったです♪

コメントフォーム