使用CSS自定義屬性實現骨架屏效果

  發布時間:2022-06-20 16:09:22   作者:陽光是sunny   我要評論
這篇文章主要介紹了使用CSS自定義屬性實現骨架屏效果,在網上可以看到骨架屏的使用已經非常廣泛,Facebook,Google,Slack等公司都在使用,本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下

前言

其實這篇文章網上已經有翻譯版本,但是讀起來明顯是機翻的,實在是受不了,于是就用自己的理解翻譯了一下

正文

項目要不要加載loading狀態通常是在項目完成后才考慮的事情,當然,有時候直接就不考慮了。

開發人員的職責不只是提高性能,同時優化網絡差時,請求接口緩慢導致的頁面的慢渲染也是非常重要的。

速度的錯覺

隨著我們對移動體驗的期望的變化,我們對性能的理解也在變化。我們期望,無論當前的網絡如何,web頁面都能像原生應用程序一樣順滑,一樣快速響應。

骨架屏的出現。這個想法使得用戶更有耐心,因為他們知道正在發生什么,并且在內容實際存在之前能夠預測內容,那么他們會認為系統更快。這在很大程度上保持了用戶等待的熱情。

骨架屏??

這個概念可能包括顯示文本,圖像或其他內容元。在網上可以看到骨架屏的使用已經非常廣泛,Facebook,Google,Slack等公司都在使用。

舉個例子

假設你正在構建一個旅行相關的Web應用程序,用戶可以分享他們的旅行以及推薦的地點,它的主要內容可能看起來像這樣:

您可以將該卡片簡化到其基本視覺形狀(UI組件的骨架)

每當有人從服務器請求新內容時,您可以立即開始顯示骨架,同時在后臺加載數據。內容準備就緒后,只需將骨架換成實際卡即可。

您可以使用圖像來顯示骨架,但這會引入額外的請求和數據開銷。我們本身已經在這里加載了東西,所以還要去等待另一個圖像先加載,這可不是一個好主意。另外圖片不是響應式的,如果我們決定調整卡片的樣式,我們將不得不更改骨架圖像,以便它們再次匹配。??。

一個更好的解決方案是只用 CSS 創建骨架屏。沒有額外的請求,最小的開銷。而且以后修改更加的方便快捷。

CSS 中繪制骨架

首先,我們需要繪制構成卡片骨架的基本形狀。

我們可以通過向background-image屬性添加不同的漸變來做到這一點。默認情況下,線性漸變從上到下運行,具有不同的顏色過渡。如果我們只定義一個色標,其余的保持透明,我們就可以繪制形狀。

請記住,多個背景圖像在這里堆疊在一起,因此順序很重要。最后一個漸變定義將展示在后面,最先定義的展示在前面。

.skeleton {
  background-repeat: no-repeat;
  background-image: 
    /* layer 2: avatar */
    /* white circle with 16px radius */
    radial-gradient(circle 16px, white 99%, transparent 0),
    /* layer 1: title */
    /* white rectangle with 40px height */
    linear-gradient(white 40px, transparent 0),
    /* layer 0: card bg */
    /* gray rectangle that covers whole element */
    linear-gradient(gray 100%, transparent 0);
}

這些元素通過拉伸來填充整個空間,就像常規的塊級元素一樣。如果我們想要改變它,我們必須為它們定義明確的尺寸。background-size的值來設置每個圖層的寬度和高度,background-size的值的順序保持我們使用的background-image順序相同

.skeleton {
  background-size:
    32px 32px,  /* 頭像 */
    200px 40px,  /* 標題 */
    100% 100%; /* 卡片背景 */
}

最后一步是將元素定位在卡片上。這與position:absolute類似,跟它的left和top屬性的值一樣。例如:我們可以給頭像和標題 模擬 padding:24px,以匹配真實卡片的外觀。

.skeleton {
  background-position:
    24px 24px,  /* 頭像 */
    24px 200px, /* 標題 */
    0 0;        /* 卡片背景 */
}

使用自定義屬性

如果我們想構建一些稍微復雜一點的東西,CSS 很快就會變得混亂并且很難閱讀。如果將代碼交給其他開發人員,他們將不知道所有這些神奇數字的來源。維護它肯定會很糟糕。

值得慶幸的是,我們現在可以使用CSS 自定義屬性,以更簡潔、對開發人員更友好的方式來編寫骨架樣式。

.skeleton {
  /*
    define as separate properties
  */
  --card-height: 340px;
  --card-padding:24px;
  --card-skeleton: linear-gradient(gray var(--card-height), transparent 0);

  --title-height: 32px;
  --title-width: 200px;
  --title-position: var(--card-padding) 180px;
  --title-skeleton: linear-gradient(white var(--title-height), transparent 0);

  --avatar-size: 32px;
  --avatar-position: var(--card-padding) var(--card-padding);
  --avatar-skeleton: radial-gradient(
    circle calc(var(--avatar-size) / 2), 
    white 99%, 
    transparent 0
  );

  /* 
    now we can break the background up 
    into individual shapes 
  */
  background-image: 
    var(--avatar-skeleton),
    var(--title-skeleton),
    var(--card-skeleton);

  background-size:
    var(--avatar-size),
    var(--title-width) var(--title-height),
    100% 100%;

  background-position:
    var(--avatar-position),
    var(--title-position),
    0 0;
}

這不僅更具可讀性,而且以后更改一些值也更容易。另外,我們可以使用一些變量(像 --avatar-size、--card-padding等)來定義實際卡片的樣式,并始終使其與骨架版本保持同步。

添加一個媒體查詢來調整不同斷點的部分骨架現在也很簡單:

@media screen and (min-width: 47em) {
  :root {
    --card-padding: 32px;
    --card-height: 360px;
  }
}

瀏覽器對自定義屬性的支持很好,但不是 100%?;旧?,所有現代瀏覽器都支持,IE/Edge 有點晚了。對于這個特定的用例,很容易使用 Sass 變量添加回退。

添加動畫

為了使它更好,我們可以為我們的骨架設置動畫,讓它看起來更像一個加載指示器。我們需要做的就是在頂層放置一個新的漸變,然后用@keyframes.

這是完成骨架卡外觀的完整示例:

可以查看預覽:https://codepen.io/mxbck/pen/EvmLVp

<div class="card"></div>
/*
 * Variables
 */
:root {  
  --card-padding: 24px;
  --card-height: 340px;
  --card-skeleton: linear-gradient(lightgrey var(--card-height), transparent 0);
  
  --avatar-size: 32px;
  --avatar-position: var(--card-padding) var(--card-padding);
  --avatar-skeleton: radial-gradient(circle 16px at center, white 99%, transparent 0
  );
  
  --title-height: 32px;
  --title-width: 200px;
  --title-position: var(--card-padding) 180px;
  --title-skeleton: linear-gradient(white var(--title-height), transparent 0);
  
  --desc-line-height: 16px;
  --desc-line-skeleton: linear-gradient(white var(--desc-line-height), transparent 0);
  --desc-line-1-width:230px;
  --desc-line-1-position: var(--card-padding) 242px;
  --desc-line-2-width:180px;
  --desc-line-2-position: var(--card-padding) 265px;
  
  --footer-height: 40px;
  --footer-position: 0 calc(var(--card-height) - var(--footer-height));
  --footer-skeleton: linear-gradient(white var(--footer-height), transparent 0);
  
  --blur-width: 200px;
  --blur-size: var(--blur-width) calc(var(--card-height) - var(--footer-height));
}
/*
 * Card Skeleton for Loading
 */
.card {
  width: 280px; //demo
  height: var(--card-height);
  
  &:empty::after {
    content:"";
    display:block;
    width: 100%;
    height: 100%;
    border-radius:6px;
    box-shadow: 0 10px 45px rgba(0,0,0, .1);
    background-image:
      linear-gradient(
        90deg, 
        rgba(lightgrey, 0) 0, 
        rgba(lightgrey, .8) 50%, 
        rgba(lightgrey, 0) 100%
      ),                          //animation blur
      var(--title-skeleton),      //title
      var(--desc-line-skeleton),  //desc1
      var(--desc-line-skeleton),  //desc2
      var(--avatar-skeleton),     //avatar
      var(--footer-skeleton),     //footer bar
      var(--card-skeleton)        //card
    ;
    background-size:
      var(--blur-size),
      var(--title-width) var(--title-height),
      var(--desc-line-1-width) var(--desc-line-height),
      var(--desc-line-2-width) var(--desc-line-height),
      var(--avatar-size) var(--avatar-size),
      100% var(--footer-height),
      100% 100%
    ;
    
    background-position:
      -150% 0,                      //animation
      var(--title-position),        //title
      var(--desc-line-1-position),  //desc1
      var(--desc-line-2-position),  //desc2
      var(--avatar-position),       //avatar
      var(--footer-position),       //footer bar
      0 0                           //card
    ;
    background-repeat: no-repeat;
    animation: loading 1.5s infinite;
  }
}
@keyframes loading {
  to {
    background-position:
      350% 0,        
      var(--title-position),  
      var(--desc-line-1-position),
      var(--desc-line-2-position),
      var(--avatar-position),
      var(--footer-position),
      0 0
    ;
  }
}
/* 
 * Demo Stuff
 */
body {
  min-height:100vh;
  background-color:#FFF;
  display:flex;
  justify-content:center;
  align-items:center;
}

到此這篇關于使用CSS自定義屬性實現骨架屏效果的文章就介紹到這了,更多相關css骨架屏內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • CSS實現Skeleton Screen骨架屏效果

    這篇文章主要介紹了CSS實現Skeleton Screen骨架屏效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-16
  • 淺談只要css就能實現的骨架屏方案

    這篇文章主要介紹了淺談只要css就能實現的骨架屏方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學
    2019-09-20

最新評論

美丽人妻被按摩中出中文字幕