1. 程式人生 > 資訊 >小米 MIUI 12.5 增強版釋出會吐槽微信:2 年新增約 80 個功能點,後臺記憶體增加 67.9%

小米 MIUI 12.5 增強版釋出會吐槽微信:2 年新增約 80 個功能點,後臺記憶體增加 67.9%

當你的使用者需要一些額外的上下文來放置圖示,或者當他們需要一些保證來點選按鈕,或者可能是一個復活節彩蛋的標題來搭配一個圖片時,工具提示是一個很好的方法來增強使用者介面。現在讓我們來製作一些動畫工具提示,只使用html和css。

演示

以下是我們的工作目標:

主要目標是擁有一種新增工具提示的簡單方法,因此我們將通過新增自定義tooltip屬性來做到這一點:

<span tooltip="message">visible text or icon, etc.</span>

關於可訪問性和功能的說明

如果您正在尋找508相容的工具提示,或者需要更智慧的工具提示,支援容器衝突檢測和/或支援html內容與純文字,那麼有許多使用第三方指令碼的解決方案可以滿足您的這些需求。

讓我們設定幾個預期

  • 不需要JavaScript

  • 我們將會使用屬性選擇器(而不是類名),以及css內建的模式匹配

  • 加到現有的DOM元素(你的標籤中不需要新的元素)

  • 程式碼例子中是沒有字首的(如有需要,為你的目標瀏覽器加上供應商字首)

  • 假設通過 mouseover/hover 來觸發提示框

  • 僅僅是純文字提示框(HTML,圖片等等都不支援)

  • 當喚起提示框時,有巧妙的動畫

下面我們開始

我們還要先處理一個問題,是關於"不需要額外標籤"的。畢竟,這很巧妙。 我們的提示框真的不需要額外的DOM元素,因為它們完全是基於偽元素的(::before和::after),我們可以通過CSS來控制。

如果你已經在其它樣式集中使用了一個元素的偽元素,又希望在這個元素是加一個提示框,那麼你可能需要稍稍做一些重構。

提示框

還有一個警告:CSS定位。為了提示框正常運作,它們的父元素(我們把提示框新增在它後面)需要是

  • position: relative,或者

  • position: absolute,或

  • position: fixed

基本上,什麼都行,只要不是 position: static — 這是瀏覽器賦給幾乎所有元素的預設定位模式。提示框是絕對定位的,所以它們需要知道它們的絕對值在什麼邊界內是有意義的。

預設的定位指令 static 不會宣告它的邊界,也不會給我們的提示框以上下文來進行相對定位。所以提示框會使用之後,最近的,有宣告邊界的父元素。

你需要決定哪個位置指令最適合你如何使用工具提示。本教程假設位置:相對於父元素。如果您的UI依賴於一個絕對定位的元素,那麼可能還需要一些重組(額外的標記)來在該元素上部署工具提示。

屬性選擇器:快速回顧

大多數CSS規則印象中都是用類名寫的,比如.this-thing,但是CSS有幾個型別的選擇器。我們巧妙的提示框打算使用屬性選擇器——也就是方括號表示法。

[foo] {
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
}

當瀏覽器看到諸如此類的東西時:

<span foo>Check it out!</span>

瀏覽器會知道,它需要應用[foo]規則了,因為<span>標籤有一個叫做foo的屬性。在這個例子中,span自身會有一個半透明的黑色背景,以及白色文字。

HTML元素有著各種各樣的內建屬性,但是我們也可以給出我們自己的屬性。比如 foo ,又或者是 tooltip 。預設情況下,HTML不知道這些東西是什麼意思,但是有了CSS,我們可以告訴HTML這些自定義屬性是什麼意思。

為什麼用屬性選擇器?

我們後面會使用屬性選擇器,主要是出於側重分離的目的。使用屬性而不是類名,並不會讓我們在詳細程度上獲得更多益處,類和屬性在詳細程度上是相同的。 然而,通過使用屬性,我們可以把我們的內容放在一塊兒,因為HTML屬性可以有值,而類名沒有值。

在這個例子的程式碼中,來權衡一下類名.tooltip對比屬性[tooltip]。類名是[class]屬性的值中的一個,而tooltip屬性可以存放一個值,它就是我們要顯示的文字。

<span>lorem ipsum</span>
<span tooltip="sit dolar amet">lorem ipsum</span>

使用提示框

我們的提示框會使用兩種不同的屬性:

  • tooltip: 這個屬性存放了提示框的內容(一個純文字字串)

  • flow:可選;這個屬性允許我們控制如何顯示提示框。我們可以支援很多方位,但是我們會覆蓋4各常用方位:上,左,右,下

1. 相對性

這是用在提示框的父元素上的。讓我們來給定一個定位指令,這樣提示框的組成部分(即::before和::after偽元素)的絕對定位就可以以父元素做參照進行定位,而不是以整個頁面或祖父元素或DOM樹上方的其它外圍元素作為參照進行定位。

[tooltip] {
  position: relative;
}

2. 偽元素準備

在這裡,我們要對::before和::after設定常用屬性。content屬性是真正讓偽元素工作的屬性,不過我們稍後再討論它。

[tooltip]::before,
[tooltip]::after {
    line-height: 1;
    user-select: none;
    pointer-events: none;
    position: absolute;
    display: none;
    opacity: 0;
 
    /* opinions */
    text-transform: none; 
    font-size: .9em;
}

3、Dink

它是一個尖尖的小三角形,通過指向它的呼叫者,為提示框提供對話氣泡的感覺。 注意到我們在邊界顏色這一塊,使用了tranparent;由於上色要根據提示框的flow值來,所以之後再加上顏色。

[tooltip]::before {
    content: '';
    z-index: 1001;
    border: 5px solid transparent;
}

content: '';宣告中的值是一個空字串,這並不是筆誤。字串裡面,我們不想要任何東西,但是我們需要這個屬性,使得偽元素得以存在。

為了生成一個三角形,我們定義了一個實現邊框,在空的盒子(沒有內容)上加了一些厚度,而不設定盒子的寬度和高度,僅僅對盒子的每一條邊都給一個邊框顏色。

4、氣泡

這裡是重點了。注意內容:attr(tooltip)部分說:“此偽元素應使用tooltip屬性的值作為其內容。”這就是為什麼對類名使用屬性是如此之好!

[tooltip]::after {
    content: attr(tooltip); /* magic! */
    z-index: 1000;
     
    /* most of the rest of this is opinion */
    font-family: Helvetica, sans-serif;
    text-align: center;
     
    /* 
    Let the content set the size of the tooltips 
    but this will also keep them from being obnoxious
    */
    min-width: 3em;
    max-width: 21em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
     
    /* visible design of the tooltip bubbles */
    padding: 1ch 1.5ch;
    border-radius: .3ch;
    box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35);
    background: #333;
    color: #fff;
}

請注意,dink和氣泡的z-index值。 這些是任意值,但請記住,z索引值是相對的。 含義:z-index為3的元素內部的z-index值為1001只是意味著1001元素將是該z-index:3容器中最頂層的元素。

氣泡的z-index應比Dink的z-index至少降低1步。 如果它等於或高於該dink,那麼如果您的工具提示使用了框陰影,則最終會在dink上產生不一致的著色效果。

https://www.houdianzi.com/ vi設計公司

5、互動作用

我們的提示框是通過把滑鼠移動到帶提示框的元素上面,來啟用的。差不多是這樣。

[tooltip]:hover::before,
[tooltip]:hover::after {
    display: block;
}

如果您在第2步中回顧我們的樣式塊,應該會看到我們使用了opacity:0;連同顯示:無; 用於我們的工具提示部分。 我們這樣做是為了在顯示和隱藏工具提示時可以使用CSS動畫效果。

display屬性是不能做成動畫的,但是opacity屬性可以!我們留到最後來處理動畫的問題。如果你對動畫提示框沒興趣,只要把第2步中的opacity: 0;刪掉,無視第7步即可。

最後一件要應用到所有提示框上的是,如果提示框沒有內容,能有一個方法來抑制提示框。如果你使用某種動態系統(vue.js, Angular, 或者react,php等等)來生成提示框的話,我們就不需要笨笨的空白氣泡了!

/* don't show empty tooltips */
[tooltip='']::before,
[tooltip='']::after {
    display: none !important;
}

6、流控制

這一步會變得更加複雜,因為我們會使用一些不那麼常見的選擇器,來幫助我們的提示框基於 flow 值(或沒有flow屬性)來確定位置。

在我們寫樣式之前,讓我們看看將要用到一些選擇器模式。

[tooltip]:not([flow])::before,
[tooltip][flow^="up"]::before {
    /* ...
    properties: values
    ... */
}

這是在告訴瀏覽器:“對於所有帶有tooltip屬性來說,其中沒有 flow 屬性的元素,或者有flow元素,但它的值是以'up'開頭的:將這些樣式套用到這類元素的::before偽元素上。”

我們在這裡使用了一個模式,這樣一來,這些東西可以擴充套件到其它流上,而步需要重複這麼多的CSS。這個模式flow^="up"使用了^=(開頭)匹配符。 如果你想增加其它流控制的話,通過這個模式,也可以將樣式應用在up-right和up-left方向上(程式碼中)。

Up (default):

/* ONLY the ::before */
[tooltip]:not([flow])::before,
[tooltip][flow^="up"]::before {
    bottom: 100%;
    border-bottom-width: 0;
    border-top-color: #333;
}
 
/* ONLY the ::after */
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::after {
    bottom: calc(100% + 5px);
}
 
/* Both ::before & ::after */
[tooltip]:not([flow])::before,
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::before,
[tooltip][flow^="up"]::after {
    left: 50%;
    transform: translate(-50%, -.5em);
}

Down:

[tooltip][flow^="down"]::before {
    top: 100%;
    border-top-width: 0;
    border-bottom-color: #333;
}
 
[tooltip][flow^="down"]::after {
    top: calc(100% + 5px);
}
 
[tooltip][flow^="down"]::before,
[tooltip][flow^="down"]::after {
    left: 50%;
    transform: translate(-50%, .5em);
}

Left:

[tooltip][flow^="left"]::before {
    top: 50%;
    border-right-width: 0;
    border-left-color: #333;
    left: calc(0em - 5px);
    transform: translate(-.5em, -50%);
}
 
[tooltip][flow^="left"]::after {
    top: 50%;
    right: calc(100% + 5px);
    transform: translate(-.5em, -50%);
}

Right:

[tooltip][flow^="right"]::before {
    top: 50%;
    border-left-width: 0;
    border-right-color: #333;
    right: calc(0em - 5px);
    transform: translate(.5em, -50%);
}
 
[tooltip][flow^="right"]::after {
    top: 50%;
    left: calc(100% + 5px);
    transform: translate(.5em, -50%);
}

7、對所有事物進行動畫處理

動畫是很神奇的。動畫可以做到:

  • 讓使用者感覺舒服

  • 讓使用者感受到你的使用者介面的空間感

  • 注意到該看到的東西

  • 讓使用者介面中本來非黑即白的生硬效果變得柔和

我們的提示框屬於最後那一種。如果僅僅是讓一個文字泡泡出現然後突然消失,效果是不令人滿意的,我們可以讓它更柔和一些。

@keyframes

我們需要兩個關鍵幀 (@keyframe) 動畫。向上/向下提示框要用到tooltips-vert關鍵幀,而向左/向右提示框使用tooltips-horz關鍵幀。 注意,在這些關鍵幀中,我們只定義了提示框所需的終止狀態。

我們並不需要知道它們從何處來 (提示框本身就有狀態資訊)。我們只想控制它們要到哪兒去。

@keyframes tooltips-vert {
  to {
    opacity: .9;
    transform: translate(-50%, 0);
  }
}
 
@keyframes tooltips-horz {
  to {
    opacity: .9;
    transform: translate(0, -50%);
  }
}

現在,當用戶將滑鼠懸停在觸發元素(帶有[tooltip]屬性的元素)上時,我們需要將這些關鍵幀應用於工具提示。由於我們正在使用各種流來控制工具提示的顯示方式,所以我們需要在樣式中確定這些可能性。

使用:hover將控制傳遞給動畫

[tooltip]:not([flow]):hover::before,
[tooltip]:not([flow]):hover::after,
[tooltip][flow^="up"]:hover::before,
[tooltip][flow^="up"]:hover::after,
[tooltip][flow^="down"]:hover::before,
[tooltip][flow^="down"]:hover::after {
    animation: 
        tooltips-vert 
        300ms 
        ease-out
        forwards;
}
 
[tooltip][flow^="left"]:hover::before,
[tooltip][flow^="left"]:hover::after,
[tooltip][flow^="right"]:hover::before,
[tooltip][flow^="right"]:hover::after {
    animation: 
        tooltips-horz 
        300ms 
        ease-out 
        forwards;
}

我們不能對display屬性進行動畫,但是可以通過操作opacity屬性,在提示框上加上淡入效果。我們也可以動畫transform屬性,它可以給提示框加上微妙的動作,觸發的元素就像飛入某點的一樣。

主要forward關鍵詞在動畫的宣告中,這告訴動畫當完成時不重置,而是繼續停留在結束。