用 data-* 屬性做出純 CSS 的 tooltip

最近因為案子需求,要做「tooltip」的功能,簡單來說,tooltip 是一種「當滑鼠移過文字時,會跳出一個簡短的提示說明」的特效。

tooltip 技術已存在很久,發展也有一段時間了,不論是用純 CSS 製作,或是透過 JavaScript 控制都有人寫過,不過最近我發現還可以利用 HTML5 的新標籤data-*達成。去年我有寫過一篇利用data-*在 HTML 以及 jQuery 存取資料的文章,但data-*厲害的地方不僅在此,我們還可以直接利用 CSS 的attrdata-*資料抓出來噢!!

那話不多說,就先上範例吧:

See the Pen eousc by MUKi (@mukiwu) on CodePen.

可以看到當滑鼠移過「Hover Me」的文字時,右方會淡出一個提示訊息;滑鼠移過「Push you mouse here」文字時,右方會出現多行的提示。

在此跟各位簡單介紹一下,如何使用data-*達成該功能。

在 html 加入 data-* 屬性

首先要做的第一件事情,就是設定 tooltip 的 html 程式碼。我的寫法為:

<div class="tip">
  Hover Me!!!
</div>

span裡面寫上data-tooltip的屬性,然後可以把它當作 HTML 屬性直接使用,在值(value)裡寫上提示文字。data-tooltip的「tooltip」名字可以自取,只要前面的格式以data-為開頭即可。

在 CSS 利用 attr 抓取 data-* 屬性

CSS 的偽元素是個很強大的東西,我們可以利用他做很多運用,通常為了做一些效果,content:" "多半會留空,但其實可以在裡面寫上attr抓資料歐!

我們可以這樣寫:

.tip span:before {
  content: attr(data-tooltip);
}

attr裡面塞入我們在 html 新增的data-tooltip屬性,這樣偽元素(:before) 就會得到該值。

利用 pre 解決 tooltip 自動換行

將 tooltip 的樣式做好後,也許你會發現文字的換行有點奇怪,可能會出現這樣的情況:

「Hello World」文字並沒有按照預期的情況換行,簡單來說是因為預設會使用空白換行,因此我們可以使用pre標籤保留空白字元,寫法為white-space: pre;

利用 Unicode 字元顯示多行 tooltip

最後,如果我們希望 tooltip 可以顯示多行文字該怎麼辦呢?
一開始我很直覺的在data-tooltip裡面加入br標籤,但他會直接將br秀出來:
data-tooltip="this is line 1< br >this is line 2"

後來我發現 bootstrap 有寫好 tooltip 的元件,他的做法是如果你要在data-*裡面使用 HTML 標籤,就必須加入一行data-html="true"的設定,當時看完覺得超神奇的,他把這串設定寫在 javascript 裡面做判斷,但我還是似懂非懂,不知道 bootstrap 的具體設定方法。

最後,我採用 Unicode \a 作處理。

在想要換行的地方改用&# xa取代br,這樣文字就會自動換行囉!!

1. &#xa 中間其實不用空格,這邊會空格是因為 WordPress 編輯器會把語法吃掉
2. 底下語法的span也是同樣狀況。
<div class="tip">
  <s pan data-tooltip="this is line 1 &#xa;this is line 2">push you mouse here!!!</ span>
</div>

(參考來源:http://stackoverflow.com/questions/16451553/css-data-attribute-new-line-character-pseudo-element-content-value)
(雖然我還是很想知道 bootstrap 到底是怎麼寫的,有在 FB 問過朋友,但其實還是看不懂,OTL)

tooltip 簡易語法分享

最後是將上述提到的一些觀念與做法,轉換成 HTML & CSS 讓大家參考。

<section>
  <h2>single line</h2>
    <div class="tip"><s pan data-tooltip="hello world">Hover Me!!!</ span></div>

  <h2>mutliple line</h2>
    <div class="tip"><s pan data-tooltip="this is line 1 &#xa; this is line 2">push you mouse here!!!</ span></div>
</section>
/* tooltip settings start */
.tip span{
  position: relative;
  display: inline-block;
  &:hover {
    cursor: pointer;
    &amp;:before, &amp;:after {
      opacity: 1;
    }
  }
  &::before {
    content: attr(data-tooltip);
    background: #d9444a;
    color: #fff;
    padding: .8em 1em;
    position: absolute;
    left: 100%;
    top: -90%;
    margin-left: 14px;
    white-space: pre;
  }
  &::after {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    border-width: 8px;
    border-style: solid;
    border-color: transparent #d9444a transparent transparent;
  }
  &::before, &::after {
    opacity: 0;
    @include transition(opacity .3s ease-out);
  }
}

當然,你也可以直接參考我的 codepen 範例,有完整的語法以及實作:http://codepen.io/mukiwu/full/eousc

See the Pen eousc by MUKi (@mukiwu) on CodePen.

data-*真的是一個強大又好玩的東西,不僅可以自定義屬性(把自己當成 HTML 的規則制定者?),還可以透過 jQuery & CSS 存取~,大家一起來玩吧 😀