CSS 文字陰影 text-shadow 懸停效果

南城大前端 發表於 2022-05-15
CSS

本文將專注於使用 CSS text-shadow 屬性來實現有趣的滑鼠懸停效果,但是實際上並不會為這些文字製作任何文字陰影效果。

text-shadow 沒有文字陰影?

通過以下的gif圖中的滑鼠懸停效果,相信你能理解使用 text-shadow 卻為什麼沒有陰影。
CSS 文字陰影 text-shadow 懸停效果

看到此圖你的第一感覺是不是複製了一份文字,比如建立偽元素,設定 content: 'text',然後為其設定單獨的動畫。但是本文完全使用text-shadow 實現,接下來將為大家展開說明四種懸停動畫的實現方式。

text-shadow 語法

text-shadow為文字新增陰影,可以為文字新增多個陰影,新增多個時陰影值之間用逗號隔開。每個陰影值由元素在X和Y方向的偏移量、模糊半徑和顏色值組成。

text-shadow: h-shadow v-shadow blur color;
引數描述
h-shadow必需。水平陰影的位置。允許負值。
v-shadow必需。垂直陰影的位置。允許負值。
blur可選。模糊的距離。
color可選。陰影的顏色。

懸停效果#1

CSS 文字陰影 text-shadow 懸停效果

CSS程式碼如下,我們將文字實際的顏色設定透明(color: #0000);然後通過text-shadow建立兩個陰影,可選引數blur不設定,這樣我們就得到了一份清晰的陰影,通過設定不同的顏色和垂直的數值即可產生炫酷的效果。

.hover-1 {
  line-height: 1.2em;
  color: #0000;
  text-shadow: 
    0 0 #000, 
    0 1.2em #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  text-shadow: 
    0 -1.2em #000, 
    0 0 #1095c1;
}

如下圖所示,紅色虛線區域是我們頁面可視區。通過設定overflow: hidden,重複的文字也就看不見了,在懸停過程中增加transition過渡時間,看起來就像是兩個文字在交替顯示,這就是本文示例中的主要技巧。

CSS 文字陰影 text-shadow 懸停效果

接下來可以繼續優化我們的CSS程式碼,如上面程式碼所示,我們多次使用了1.2em來定義了陰影的高度及移動的偏移量,通過CSS var() 自定義屬性值優化後的程式碼如下:

.hover-1 {
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 0 #000, 
    0 var(--h) #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  text-shadow: 
    0 calc(-1 * var(--h)) #000, 
    0 0 #1095c1;
}

這樣還是不夠簡潔,還可以通過calc()繼續優化:

.hover-1 {
  --h: 1.2em;   

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 calc(-1*var(--_t, 0em)) #000, 
    0 calc(var(--h) - var(--_t, 0em)) #1095c1;
  overflow: hidden;
  transition: .3s;
}
.hover-1:hover {
  --_t: var(--h);
}

懸停效果#2

CSS 文字陰影 text-shadow 懸停效果

這個動畫主要用到了兩個屬性,text-shadowbackgroundtext-shadow仍然是設定兩個圖層,但是這次只需要移動下面的一個,在移動的過程中將上面的顏色設定為透明。同時增加一個background-size修改背景色。

.hover-2 {
  /* the height */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_t,var(--h)) #fff,
    0 0 var(--_c, #000);
  background: 
    linear-gradient(#1095c1 0 0) 
    bottom/100% var(--_d, 0) no-repeat;
  overflow: hidden;
  transition: 0.3s;
}
.hover-2:hover {
  --_d: 100%;
  --_t: 0;
  --_c: #0000;
}

以上我們通過結合CSStext-shadowbackground屬性建立了懸停效果,但是我們還能繼續使用CSS變數來優化程式碼,最終只需要一個CSS自定義屬性變數即可。

.hover-2 {
  /* the height */
  --h: 1.2em;

  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_i, var(--h)) #fff,
    0 0 rgb(0 0 0 / calc(var(--_i, 1) * 100%) );
  background: 
    linear-gradient(#1095c1 0 0) 
    bottom/100% calc(100% - var(--_i, 1) * 100%) no-repeat;
  overflow: hidden;
  transition: 0.3s;
}
.hover-2:hover {
  --_i: 0;
}

懸停效果#3

CSS 文字陰影 text-shadow 懸停效果

這個效果是基於本文第一個動畫效果增加了一個前置動畫效果。經過最終優化後也只需控制一個CSS自定義變數即可。

.hover-3 {
  /* the color  */
  --c: #1095c1;
  /* the height */
  --h: 1.2em;

  line-height: var(--h);  
  color: #0000;
  overflow: hidden;
  text-shadow: 
    0 calc(-1 * var(--h) * var(--_i, 0)) var(--c), 
    0 calc(var(--h) * (1 - var(--_i, 0))) #fff;
  background: 
    linear-gradient(var(--c) 0 0) no-repeat
    calc(200% - var(--_i, 0) * 100%) 100% / 200% calc(100% * var(--_i, 0) + .08em);
  transition: .3s calc(var(--_i, 0) * .3s), background-position .3s calc(.3s - calc(var(--_i, 0) * .3s));
}
.hover-3:hover {
  --_i: 1;
}

懸停效果#4

CSS 文字陰影 text-shadow 懸停效果

這個懸停效果是基於第二種效果的改進版本,這裡新用到了clip-path,我們使用inset(0 0 0 0)類似於overflow: hidden我們所看到的只是實際文字。在懸停時,我們使用等於高度的負值更新第三個值(表示底部偏移)以顯示放置在底部的文字層。因為我們需要先執行clip-path動畫,然後再執行其他所有內容,所以我們在懸停時為所有屬性新增延遲,除了clip-path

transition: 0.4s 0.4s, clip-path 0.4s;

在滑鼠移出時,我們做相反的事情:

transition: 0.4s, clip-path 0.4s 0.4s;

最後的完整程式碼

.hover-4 {
  /* the color  */
  --c: #1095c1;
  /* the height */
  --h: 1.2em;
  
  line-height: var(--h);
  color: #0000;
  text-shadow: 
    0 var(--_t, var(--h)) #fff,
    0 0 var(--_c, #000);
  box-shadow: 0 var(--_t, var(--h)) var(--c);
  clip-path: inset(0 0 0 0);
  background: linear-gradient(var(--c) 0 0) 0 var(--_t, var(--h)) no-repeat;
  transition: 0.4s, clip-path 0.4s 0.4s;
}
.hover-4:hover {
  --_t: 0;
  --_c: #0000;
  clip-path: inset(0 0 calc(-1 * var(--h)) 0);
  transition: 0.4s 0.4s, clip-path 0.4s;
}

最後

如上的幾個例子都只用到了一個元素和CSS實現了幾種複雜的懸停效果,不需要用到其他的元素及偽元素。基於以上的動畫可以發現我們可以結合不同的動畫組成更復雜的動畫效果,且相對不需要很大的成本。

看完覺得有用,記得點贊收藏起來吧,說不定哪天就用上啦~

專注前端開發,分享前端相關技術乾貨,公眾號:南城大前端(ID: nanchengfe)