2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-10-20

少し時間があったので数年前に作った管理画面のソースを眺めてたんですが
「あれ?この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だとツールチップ上でも可能という
違いはありますが、こっちの方が使い勝手がよいので・・・ヨシとさせてくださいませ。

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

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

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?