本篇是張鑫旭老師的 CSS基礎測試2 的閱後筆記。(另外感謝 XboxYan 的解答,邏輯很是清晰)javascript
話很少說,先上題,HTML 以下:css
<a href="javascript:" class="icon-delete css-tips" data-title="刪除" role="button" >
刪除
</a>
複製代碼
現需實現以下效果:html
要求:java
分析完題目以後,能夠看到,出題者很貼心的給了 a
標籤兩個 class:git
意圖很明顯,icon-delete
用於實現把文字替換成圖標的功能,而 css-tips
用於實現氣泡提示效果。 那麼首先把比較簡單的功能完成。github
這裏能夠經過把字體大小設置爲 0,而後經過設置背景的方式來完成圖標化:學習
.icon-delete{
display: block;
width: 30px;
height: 30px;
font-size: 0px;
background: url(./del.png) no-repeat center;
background-size: cover;
}
複製代碼
這樣就完成了這個簡單的功能,效果以下:測試
這個功能較爲複雜,咱們先不考慮各類場景,只單獨的把這個氣泡提示作出來。字體
給元素附加掛件的效果,這裏咱們能夠經過 before
和 after
僞類來作。優化
因爲氣泡浮於元素上方,因此這裏第一反應是要用到絕對定位:
.css-tips {
position: relative;
}
.css-tips[data-title]::before,
.css-tips[data-title]::after {
content: "";
width: 20px;
height: 20px;
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
background: #373c42;
}
複製代碼
到這裏,咱們成功的將 before
和 after
定位到了按鈕的正上方:
接下來分別對 before
和 after
進行調整,這裏咱們使用 before
來作爲裝填文字的容器,使用 after
做爲氣泡下方的箭頭。
首先因爲咱們並不知道提示文字長度,因此沒必要設置高寬。 那麼 before
就沒什麼好注意的了。(因爲提示消息長度不固定,因此可能出現提示文本過長的狀況,這樣應該可以將文本換行,這個情景後面再提)
.css-tips {
position: relative;
}
.css-tips[data-title]::before,
.css-tips[data-title]::after {
content: "";
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
background: #373c42;
}
.css-tips[data-title]:before {
content: attr(data-title);
border-radius: 3px;
padding: 6px 10px;
line-height: 18px;
text-align: left;
background-color: #373c42;
color: #fff;
font-size: 12px;
font-style: normal;
white-space: nowrap;
}
複製代碼
效果以下:
上圖能夠看到,在氣泡中間有一塊黑色的遮擋,這個就是 after
了,只須要將它畫成倒三角,而且貼在 before
的下方便可。
畫倒三角的方法有不少,這裏簡單介紹一個最省事的。
咱們給一個元素添加一個 60px 的 border,而後將上下左右設置成不一樣的顏色:
.border{
border: 6px solid #fff;
border-top-color: black;
border-left-color: red;
border-bottom-color: blue;
border-right-color: yellow;
}
複製代碼
能夠看到,四個角恰好是四個三角形,那麼須要什麼樣的三角形,將其餘的 color 設置爲 transparent
便可,這裏也用這種方法來畫 after
.css-tips[data-title]::before,
.css-tips[data-title]::after {
content: "";
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
background: #373c42;
}
.css-tips[data-title]:after {
content: "";
width: 0;
height: 0;
margin-bottom: -12px;
overflow: hidden;
border: 6px solid transparent;
border-top-color: currentColor;
}
複製代碼
效果如圖:
接下來須要作的就是在 hover 的時候顯示氣泡,別的時候隱藏便可,沒什麼好說,最終代碼以下:
.icon-delete {
font-size: 0;
width: 30px;
height: 30px;
background: url(./del.png) no-repeat center;
background-size: cover;
}
.css-tips {
position: relative;
}
.css-tips[data-title]:before,
.css-tips[data-title]:after {
content: "";
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
color: #373c42;
opacity: 0;
visibility: hidden;
}
.css-tips[data-title]:before {
content: attr(data-title);
border-radius: 3px;
padding: 6px 10px;
line-height: 18px;
text-align: left;
background-color: #373c42;
color: #fff;
font-size: 12px;
font-style: normal;
white-space: nowrap;
}
.css-tips[data-title]:after {
content: "";
width: 0;
height: 0;
margin-bottom: -12px;
overflow: hidden;
border: 6px solid transparent;
border-top-color: currentColor;
}
.css-tips[data-title]:hover:before,
.css-tips[data-title]:hover:after {
visibility: visible;
opacity: 1;
}
複製代碼
效果以下:
優化要從兩個方面提及:
(其實說白了都是體驗優化)
咱們先來講說體驗優化,能夠看到上面最後的動圖效果很是僵硬,而且鼠標移動過來就馬上出現氣泡,假設如今有一個這樣的場景:
一個表格,每一行均可以刪除,用戶從下往上移動鼠標,想要刪除第 n 行,但因爲鼠標放上去,氣泡立馬彈出來了,因此這個時候有可能第 n+1 行的氣泡彈了出來,而且擋住了第 n 行的按鈕,這個時候用戶只能從新以不一樣角度移動過來,這樣的體驗是至關不友好的。
解決上述場景,咱們有一個小技巧:延時。
咱們讓氣泡延遲一點出現,這樣當鼠標劃過的時候就並不會出現氣泡,而是停留的時候纔會出現,這樣就不會形成上述場景了:
.css-tips[data-title]:before,
.css-tips[data-title]:after {
content: "";
display: block;
position: absolute;
z-index: 1;
left: 50%;
bottom: 100%;
transform: translate(-50%, -20px);
color: #373c42;
opacity: 0;
transition: 0.15s 0.15s;
visibility: hidden;
}
複製代碼
效果以下:
到這裏其實氣泡也顯得並不那麼生硬了,固然若是願意的話能夠再增長一個過渡,顯得更加靈動:
.css-tips[data-title]:hover:before,
.css-tips[data-title]:hover:after {
visibility: visible;
transform: translate(-50%, -10px);
opacity: 1;
}
複製代碼
效果以下:
接下來咱們聊聊極端場景,及題目中提到的邊界問題。
當這個按鈕出如今屏幕頂端的時候,若是氣泡依然是從頂部出現,很明顯將會部分或者徹底不可見。解決這個問題,我想到的方案是給氣泡添加方向屬性,經過從不一樣方向出現來避免對應的邊界。
咱們能夠爲元素添加一個 data-title-dir
屬性,默認從上方彈出氣泡,若是設置方向,則從指定方向彈出:
屬性 | 描述 | 使用 |
---|---|---|
data-title-dir |
規定提示的方向,能夠取值top(默認)、right、bottom、left | <span class="css-tips" data-title="刪除" data-title-dir="right">提示右</span> |
實現原理上面已經分析過了,就再也不贅述:
/* right */
.css-tips[data-title][data-title-dir="right"]:before,
.css-tips[data-title][data-title-dir="right"]:after{
left: 100%;
top: 50%;
bottom: auto;
transform: translate(20px, -50%);
}
.css-tips[data-title][data-title-dir="right"]:after {
margin: 0;
margin-left: -12px;
border-color: transparent;
border-right-color: currentColor;
}
.css-tips[data-title][data-title-dir="right"]:hover:before,
.css-tips[data-title][data-title-dir="right"]:hover:after {
visibility: visible;
transform: translate(10px, -50%);
opacity: 1;
}
/* bottom */
.css-tips[data-title][data-title-dir="bottom"]:before,
.css-tips[data-title][data-title-dir="bottom"]:after{
left: 50%;
top: 100%;
bottom: auto;
transform: translate(-50%, 20px);
}
.css-tips[data-title][data-title-dir="bottom"]:after {
margin: 0;
margin-top: -12px;
border-color: transparent;
border-bottom-color: currentColor;
}
.css-tips[data-title][data-title-dir="bottom"]:hover:before,
.css-tips[data-title][data-title-dir="bottom"]:hover:after {
visibility: visible;
transform: translate(-50%, 10px);
opacity: 1;
}
/* left */
.css-tips[data-title][data-title-dir="left"]:before,
.css-tips[data-title][data-title-dir="left"]:after{
left: auto;
right: 100%;
top: 50%;
bottom: auto;
transform: translate(-20px, -50%);
}
.css-tips[data-title][data-title-dir="left"]:after {
margin: 0;
margin-right: -12px;
border-color: transparent;
border-left-color: currentColor;
}
.css-tips[data-title][data-title-dir="left"]:hover:before,
.css-tips[data-title][data-title-dir="left"]:hover:after {
visibility: visible;
transform: translate(-10px, -50%);
opacity: 1;
}
複製代碼
效果以下:
還有一個場景就是提示文本過長。這個問題咱們也能夠像邊界問題那樣給元素添加一個 data-title-muti
屬性來指定是否換行:
屬性 | 描述 | 使用 |
---|---|---|
data-title-muti |
適用於提示文本較多的狀況,自動換行 | <span class="css-tips" data-title="刪除" data-title-muti>提示</span> |
/* muti */
.css-tips[data-title][data-title-muti]:before {
width: 150px;
white-space: normal;
}
複製代碼
效果如圖:
對於這個需求,其實還能夠繼續優化擴展,好比添加狀態,不一樣狀態有不一樣的顏色來提示,好比結合 js 添加回調等等。
固然這些功能早就有不少開源庫作了,並且作得很好很強壯,因此在平常開發中,便沒必要在重複造輪子了,做爲學習瞭解原理和設計思路能夠,但切記不要捨本逐末。