Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@n_a

jsを使ったツールチップ(ピン止め可)をcssだけで実装する

More than 3 years have passed since last update.

少し時間があったので数年前に作った管理画面のソースを眺めてたんですが
「あれ?このscript、全部cssでかけるんじゃね?」
「このscriptなくなれば、このページjqueryの読み込みいらないじゃん・・・」
ということがあり・・・

まぁ当時はあまりcssはそんなに明るくなくて・・・ゴニョゴニョ

で、どんなscriptなのかというと
マウスを載せる(乗せる?)とツールチップが表示される
まぁよくあるアレですw
「バルーン」ですね。

仕様(一応)

  • マウスを載せるとツールチップを表示する。
  • ツールチップに出ている文字をクリップボードにコピーできるようにツールチップをピン止めできるようにする
  • ピン止めしたツールチップは外すことができる

こんな感じです。

ピン止めの方法はクリックにしました。
クリックすることでピン止めされ、ピン止めすると枠色を変化させて、ユーザはピン止めしているかを知る。
再クリックでピン止めが外され、枠色も戻る。

サンプルをざくっと作ったのでbefore-afterを全文載せときます。
細かい部分でミスがあったら見逃して下さいw
(一応チェックしてますけど・・)

Before

  • 画面
    tooltip_before.png

  • ソース

before.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
    <title>自作ツールチップテスト</title>
    <script src="jquery.min.js" type="text/javascript"></script>
    <script language="JavaScript">
    $(document).ready(function() {
        $(".has_detail").hover(
            function(){
                $(this).children(".detail_info").show();
            },
            function(){
                $(this).children(".detail_info").not(".always").hide();
            }
        );
        $(".has_detail").click(
            function(){
                var tips = $(this).children(".detail_info");
                if(!$(tips).hasClass("always")){
                    $(tips).addClass("always");
                }
            }
        );
        $(".detail_info").click(
            function(){
                $(this).removeClass("always");
                return false;
            }
        );
    });
    </script>
<style>
* {
  margin: 0;
}
ul {
  list-style: none;
}
p.title {
  font-weight: bold;
  color: #000099;
}
div.contents {
  border: none;
  min-height: 750px;
  background-color: #ffffff;
  padding: 8px 16px;
}
div.contents > div {
  margin-top: 30px;
}
div.contents > div:first-child {
  margin-top: 10px;
}
div#goods_list > ul {
  display: table;
  border-collapse: collapse;
  width: 100%;
}
div#goods_list > ul > li {
  display: table-row;
  line-height: 2.0em;
}
div#goods_list > ul > li > ul {
  display: table-cell;
  padding-left: 20px;
}
div#goods_list > ul > li > ul > li {
  display: inline-block;
}
div#goods_list span.goods_no {
  display: inline-block;
  width: 30px;
  text-align: center;
}
ul#list_data span.goods_detail {
  display: inline-block;
  width: 100px;
  text-align: center;
  background-color: #bbccff;
  position: relative;
}
ul#list_data span.goods_detail:hover {
  background-color: #ff8c00;
  cursor: pointer;
}
div#goods_list li.goods_name,li.goods_price,li.goods_open,li.goods_memo {
  width: 160px;
  text-align: center;
}
ul#list_header > li {
  background-color: #E0F2F7;
  border-bottom: 1px solid #000;
}
ul#list_data > li {
  border-bottom: 1px solid #059;
}
ul#list_data > li:hover {
  background-color: #dce5f4;
}
span.detail_info {
  background: antiquewhite;
  border: 2px solid #fc6;
  position: absolute;
  top: 15;
  left: -225;
  text-align: center;
  padding: 10px 12px;
  z-index: 2;
  display: none;
}
span.detail_info.always {
  border-color: #f60;
}
</style>
</head>
<body>
<div class="contents">
  <div id="goods_list">
    <p class="title">商品一覧</p>
    <hr/>
    <ul id="list_header">
      <li>
        <span class="goods_no"></span>
        <ul>
          <li class="goods_name">商品名</li>
          <li class="goods_price">価格</li>
          <li class="goods_open">販売日</li>
          <li class="goods_memo"></li>
        </ul>
      </li>
    </ul>
    <ul id="list_data">
      <li>
        <span class="goods_no">1</span>
        <ul>
          <li class="goods_name">勉強机A</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <span class="goods_detail has_detail">詳細表示
        <span class="detail_info">
          <table style="width : 200px; margin-left: auto; margin-right: auto;">
          <tr>
            <th>日付</th>
            <th>内容</th>
          </tr>
          <tr>
            <td>2016/04/01</td>
            <td>在庫切れ</td>
          </tr>
          </table>
        </span></span>
      </li>
      <li>
        <span class="goods_no">2</span>
        <ul>
          <li class="goods_name">勉強机B</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <span class="goods_detail">詳細表示</span>
      </li>
      <li>
        <span class="goods_no">3</span>
        <ul>
          <li class="goods_name">勉強机C</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <span class="goods_detail hasDetail">詳細表示</span>
      </li>
    </ul>
  </div>
</div>
</body>

After

  • 画面
    tooltip_after.png
    beforeと同じかw

  • ソース

after.html
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
    <title>自作ツールチップテスト</title>
    <script src="jquery.min.js" type="text/javascript"></script>
    <script language="JavaScript">
    $(document).ready(function() {
        //$(".has_detail").hover(
        //  function(){
        //      $(this).children(".detail_info").show();
        //  },
        //  function(){
        //      $(this).children(".detail_info").not(".always").hide();
        //  }
        //);
        //$(".has_detail").click(
        //  function(){
        //      var tips = $(this).children(".detail_info");
        //      if(!$(tips).hasClass("always")){
        //          $(tips).addClass("always");
        //      }
        //  }
        //);
        //$(".detail_info").click(
        //  function(){
        //      $(this).removeClass("always");
        //      return false;
        //  }
        //);
    });
    </script>
<style>
* {
  margin: 0;
}
ul {
  list-style: none;
}
p.title {
  font-weight: bold;
  color: #000099;
}
div.contents {
  border: none;
  min-height: 750px;
  background-color: #ffffff;
  padding: 8px 16px;
}
div.contents > div {
  margin-top: 30px;
}
div.contents > div:first-child {
  margin-top: 10px;
}
div#goods_list > ul {
  display: table;
  border-collapse: collapse;
  width: 100%;
}
div#goods_list > ul > li {
  display: table-row;
  line-height: 2.0em;
}
div#goods_list > ul > li > ul {
  display: table-cell;
  padding-left: 20px;
}
div#goods_list > ul > li > ul > li {
  display: inline-block;
}
div#goods_list span.goods_no {
  display: inline-block;
  width: 30px;
  text-align: center;
}
ul#list_data label.goods_detail {
  display: inline-block;
  width: 100px;
  text-align: center;
  background-color: #bbccff;
  position: relative;
}
ul#list_data label.goods_detail:hover {
  background-color: #ff8c00;
  cursor: pointer;
}
div#goods_list li.goods_name,li.goods_price,li.goods_open,li.goods_memo {
  width: 160px;
  text-align: center;
}
ul#list_header > li {
  background-color: #E0F2F7;
  border-bottom: 1px solid #000;
}
ul#list_data > li {
  border-bottom: 1px solid #059;
}
ul#list_data > li:hover {
  background-color: #dce5f4;
}
span.detail_info {
  background: antiquewhite;
  border: 2px solid #fc6;
  position: absolute;
  top: 15;
  left: -225;
  text-align: center;
  padding: 10px 12px;
  z-index: 2;
  display: none;
}
span.detail_info.always {
  border-color: #f60;
}
input[type="checkbox"] {
  display: none;
}
input[type="checkbox"]:not(:checked) + .has_detail .detail_info {
  border-color: #fc6;
  display: none;
}
input[type="checkbox"]:not(:checked) + .has_detail:hover .detail_info {
  display: inline;
}
input[type="checkbox"]:not(:checked) + .has_detail:not(:hover) .detail_info {
  display: none;
}
input[type="checkbox"]:checked + .has_detail .detail_info {
  border-color: #f60;
  display: inline;
}
</style>
</head>
<body>
<div class="contents">
  <div id="goods_list">
    <p class="title">商品一覧</p>
    <hr/>
    <ul id="list_header">
      <li>
        <span class="goods_no"></span>
        <ul>
          <li class="goods_name">商品名</li>
          <li class="goods_price">価格</li>
          <li class="goods_open">販売日</li>
          <li class="goods_memo"></li>
        </ul>
      </li>
    </ul>
    <ul id="list_data">
      <li>
        <span class="goods_no">1</span>
        <ul>
          <li class="goods_name">勉強机A</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <input type="checkbox" id="goods_no_1">
        <label for="goods_no_1" class="goods_detail has_detail">詳細表示
        <span class="detail_info">
          <table style="width : 200px; margin-left: auto; margin-right: auto;">
          <tr>
            <th>日付</th>
            <th>内容</th>
          </tr>
          <tr>
            <td>2016/04/01</td>
            <td>在庫切れ</td>
          </tr>
          </table>
        </span></label>
      </li>
      <li>
        <span class="goods_no">2</span>
        <ul>
          <li class="goods_name">勉強机B</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <input type="checkbox" id="goods_no_2">
        <label for="goods_no_2" class="goods_detail">詳細表示</label>
      </li>
      <li>
        <span class="goods_no">3</span>
        <ul>
          <li class="goods_name">勉強机C</li>
          <li class="goods_price">20000</li>
          <li class="goods_open">2016/02/01</li>
          <li class="goods_memo"></li>
        </ul>
        <input type="checkbox" id="goods_no_3">
        <label for="goods_no_3" class="goods_detail hasDetail">詳細表示</label>
      </li>
    </ul>
  </div>
</div>
</body>

jqueryを外す前で、scriptをコメントアウトしてる状態です。

ポイントてきなもの

見えないチェックボックスを作って
チェック状態の場合は表示、非チェック状態の場合は非表示
という感じになります。
ラベルを使ってチェックボックスする感じですかね。

~略~

input[type="checkbox"] {
  display: none;
}
input[type="checkbox"]:not(:checked) + .has_detail .detail_info {
  border-color: #fc6;
  display: none;
}
input[type="checkbox"]:not(:checked) + .has_detail:hover .detail_info {
  display: inline;
}
input[type="checkbox"]:not(:checked) + .has_detail:not(:hover) .detail_info {
  display: none;
}
input[type="checkbox"]:checked + .has_detail .detail_info {
  border-color: #f60;
  display: inline;
}

~略~

追加したのはここの部分ですね。
あとはspanをlabelにしているだけになります。

最後に・・

ピン止め設定/解除のクリックがafterだとツールチップ上でも可能という
違いはありますが、こっちの方が使い勝手がよいので・・・ヨシとさせてくださいませ。

また、ツールチップ内の文字をコピペしやすいように
詳細表示とツールチップのブロックを少し重ねてあります。

以上、自分用メモですが皆さんのご参考になれば。

3
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
n_a
java屋です。 でもここでは備忘録という感じで java以外のことをメインに書いていきたいです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?