1. 程式人生 > >CSS3 animation實現點點點loading動畫

CSS3 animation實現點點點loading動畫

一、再續前緣

去年夏天,寫了篇名為“CSS3 animation漸進實現點點點等待提示效果”的文章,主要內容是實現類似下面打點等待提示效果,比干巴巴的字元...要更人性化:
點點點gif動畫效果

之前實現的原理是通過寬度和margin控制實現,但是,問題非常明顯,字元寬度受制於字型,例如移動端,沒有宋體,字元可能就會被半路剪裁,從而出現顯示bug, 用計算機術語描述就是“健壯性不足”。

上週,實現某載入提示時候,上面圈圈轉,下面就是乾巴巴的靜態文字:“資料匯入中…”~

由於忘記吃藥,我“看東西不順眼”的病就犯了,心中不停地糾結:“這...要是能用CSS動起來就好了!成本又低,效果又好,價效比超高,一勞永逸,多好啊!”

雖然忙到兩泡尿攢成一大泡才去廁所的程度,還是趁著飯點搗騰了幾下。首先看看以前的思路,確定不能在實際專案使用,於是,開腦洞想想有沒有其他更好的方式實現打點動畫效果(當然,要漸進相容)。這一年多學習不止,還是有一些積累的,很快折騰了一個比以前的實現更加靠譜的方法,利用CSS3 xxx-xxxxxx屬性實現, IE6+都能正常顯示,顏色跟隨文字變化,看上去很贊,然而還是有瑕疵。於是,週末整理demo的時候順便實踐了自己的另外一個想法,發現效果果然如自己所料,這是一個更perfect的方法。趁著剛去萬達看完《智取威虎山》有點high,特意分享下

二、基於box-shadow實現的打點效果

理論上,box-shadow

可以實現任意的圖形效果,可參考我去年寫的“CSS3 box-shadow盒陰影圖形生成技術”一文,自然我們可以利用box-shadow生成我們的點效果,然後通過animation控制不同時間點點的數目就可以實現點點點... loading效果了~

1. 漸進相容
各個瀏覽器下的效果分別如下表:

IE7 IE8 IE9 IE10/IE11(gif) Chrome(gif) FireFox(gif)
IE7截圖 IE8截圖 IE9截圖 IE10/IE11 git動畫效果 Chrome瀏覽器gif動畫效果 FireFox瀏覽器下動畫效果

支援CSS3 animation動畫的瀏覽器顯示的就是打點動畫效果;對於不支援的瀏覽器,IE7/IE8顯示的是真實的字元..., IE9瀏覽器雖然也是CSS3生成,但是是靜態的,沒有動畫效果;此乃漸進相容。

2. 實現原理
首先HTML非常簡單,就是一個標籤一個類名(標籤裡面一定要空空如也),其他什麼都不需要關心,就可以遊刃幾乎各種場景,如下:

訂單提交中<span class="dotting"></span>

上面程式碼這個類名為dottingspan就是我們所有的玄機所在,頁面任意地方,只要有這一小撮HTML就可以有打點動畫,與文字混排良好,且顏色自動匹配。例如,本文“標題一”和“標題二”後面的點點點動畫就是添加了這麼點HTML.

下面是萬眾矚目的CSS程式碼了:

.dotting {
    display: inline-block; min-width: 2px; min-height: 2px;
    box-shadow: 2px 0 currentColor, 6px 0 currentColor, 10px 0 currentColor; /* for IE9+, ..., 3個點 */
    animation: dot 4s infinite step-start both; /* for IE10+, ... */
    *zoom: expression(this.innerHTML = '...'); /*  for IE7. 若無需相容IE7, 此行刪除 */
}
.dotting:before { content: '...'; } /* for IE8. 若無需相容IE8, 此行以及下一行刪除*/
.dotting::before { content: ''; } /* for IE9+ 覆蓋 IE8 */
:root .dotting { margin-right: 8px; } /* for IE9+,FF,CH,OP,SF 佔據空間*/

@keyframes dot {
    25% { box-shadow: none; }                                  /* 0個點 */
    50% { box-shadow: 2px 0 currentColor; }                    /* 1個點 */
    75% { box-shadow: 2px 0 currentColor, 6px 0 currentColor;  /* 2個點 */ }
}

上面每行CSS都有其存在的道理(詳見註釋),這裡我們又看到了currentColor這個關鍵字,IE9+瀏覽器支援,其可以讓CSS生成的圖形的顏色跟所處環境的color屬性值一樣,也就是跟文字顏色一樣,具體可參考我不久前寫的“currentColor-CSS3超高校級好用CSS關鍵字”一文。

我們動畫一個週期4秒鐘,每秒分別顯示的是0~3個點,使用step-start讓動畫不連續(animation所有關鍵字“CSS3 animation漸進實現點點點等待提示效果”這篇文章後面深藏詳細介紹,如有疑問,可參考),於是就有個類似gif打點動畫效果,相信不難理解。

3. 美中不足
雖然幾乎所有瀏覽器都有模有樣,但是,從效果上講,還是有瑕疵的,IE10+以及FireFox瀏覽器下的點的邊緣有些虛(參見下截圖),雖然CSS程式碼並沒有設定盒陰影模糊。這種羽化現象可以讓IE以及FireFox在大數值盒陰影時候效果更接近photoshop的陰影效果;但是,在小尺寸陰影時候,並不是我們想要的。
IE10瀏覽器下box-shadow的虛化

苛刻的設計師、完美主義的處女座顯然是不能對這個置若罔聞的。好在,我又想了另外一種方法實現

三、基於border + background實現的打點效果

我們除了可以使用box-shadow生成三個點,還可以使用border + background-color實現等寬3點效果(如本標題)。

1. 漸進相容
各個瀏覽器下的效果分別如下表(主要關注IE10+以及FF下效果):

IE7 IE8 IE9 IE10/IE11(gif) Chrome(gif) FireFox(gif)
IE7截圖 IE8截圖 IE9截圖 IE10/IE11 git動畫效果 Chrome瀏覽器gif動畫效果 FireFox瀏覽器下動畫效果

定睛一看,會發現IE9以及IE10+以及FireFox的點再也不是模糊的,而是清清楚楚的小方點!

2. 實現原理
HTML還是那個HTML:

訂單提交中<span class="dotting"></span>

CSS程式碼如下:

.dotting {
    display: inline-block; width: 10px; min-height: 2px;
    padding-right: 2px;
    border-left: 2px solid currentColor; border-right: 2px solid currentColor;   
    background-color: currentColor; background-clip: content-box;
    box-sizing: border-box;
    animation: dot 4s infinite step-start both;
    *zoom: expression(this.innerHTML = '...'); /* IE7 */
}
.dotting:before { content: '...'; } /* IE8 */
.dotting::before { content: ''; }
:root .dotting { margin-left: 2px; padding-left: 2px; } /* IE9+ */

@keyframes dot {
    25% { border-color: transparent; background-color: transparent; }          /* 0個點 */
    50% { border-right-color: transparent; background-color: transparent; }    /* 1個點 */
    75% { border-right-color: transparent; }                                   /* 2個點 */
}

一些說明:

  1. 同樣是4秒動畫,每秒鐘顯示1個點;
  2. IE7/IE8實現原理跟上面box-shadow方法一致,都是內容生成,如果無需相容IE7/IE8, 可以按照第一個例子CSS程式碼註釋說明刪除一些CSS;
  3. currentColor關鍵字可以讓圖形字元化,必不可少;
  4. 最大功臣是CSS3 background-clip屬性,可以讓IE9+瀏覽器下左右padding沒有背景色,於是形成了等分打點效果。CSS3 Background博大精深,有興趣可參考一篇很讚的文章“CSS3 Backgrounds相關介紹”,很多圖,移動端非wifi慎點;
  5. box-sizing是讓現代瀏覽器和IE7/IE8佔據寬度完全一樣的功臣:IE7/IE8實際寬度是width+padding-right12畫素,其他現代瀏覽器為width+margin-left也是12畫素;
  6. 這裡CSS程式碼主要用來展示原理,故沒有顯示-webkit-animation以及@-webkit-keyframes私有字首,實際目前還是需要的;

3. 優勢所在

  1. CSS生成的點沒有虛化,效果更好;
  2. 佔據的尺寸各個瀏覽器完全一致,都是12畫素寬度;
  3. 顏色繼承;
  4. 天然字元化顯示,與文字渾然天成;

四、結束語

同志們,去看看你的網站,如果發現有「正在載入中…」這樣的提示時候,就可以把其中的點點點...放心大膽地換成<span class="dotting"></span>了。不支援animation的瀏覽器還是那個字元;支援的瀏覽器會漸進增強動畫顯示,只有好處,沒有壞處,適合於各種場景,何樂不為呢!!

技術無止境,我目前提供的方案,不一定是最好的方法,拋磚引玉,如果你有更好的實現idea, 歡迎分享,也歡迎反饋使用問題。

更新於2016年7月9日
後來我真的發現了更好的方法,就是使用text-shadow,已申請專利,不詳述。

然後,今天,又發現了更好的方法,藉助CSS3 ch單位。詳細參見這篇文章

感謝閱讀,新年快樂!