iT邦幫忙

2025 iThome 鐵人賽

DAY 28
2
Modern Web

關於那些有趣的 CSS 效果系列 第 28

( Day 28 ) 純 CSS hover 時左右傾斜的背景效果

  • 分享至 

  • xImage
  •  

某天經過公園看到小朋友在玩翹翹板,心血來潮也跑過去問說「可不可一起玩?」,他們問說「大哥哥 ( 羞 ) 為什麼想要一起玩?」我說「因為我想要用純 CSS 做出這種左右傾斜的效果」,然後他們跟我說聲「阿伯掰掰!」之後就走了,留下了茫然又不知所措的我,站在原地研究起這種效果的寫法...

純 CSS hover 時左右傾斜的背景效果

正文開始

這篇教學會使用元素中不同的子元素,判斷滑鼠 hover 時所在的區間,進而透過漸層色或 clip-path 裁切路徑的方式,產生有趣的左右傾斜背景動態效果。

CSS 教學 - CSS hover 時左右傾斜的背景效果

判斷 hover 位置

單純依靠 CSS 無法直接判斷滑鼠位置,只能在需要判斷的位置擺放元素,透過元素的位置感應出滑鼠坐落在哪個區間,由於虛擬元素 ::before::after 不支援 :hover 選擇器 ( 因為虛擬元素必須放在選擇器最末端 ),所以必須使用實際元素進行判讀,下方範例會建立左右兩個 div 判讀滑鼠所在區間,並根據所在區間,改變第二個 div::before 背景色 ( 因為無法透過子元素控制父元素樣式,所以使用子元素的虛擬元素作為背景 )。

<!-- HTML 程式碼 -->
<div class="b">
  <div></div>
  OXXO
  <div></div>
</div>

<!-- CSS 程式碼 -->
<style>
  .b {
    position: relative;     /* 讓子元素定位 */
    box-sizing: border-box; /* 避免 padding 影響寬度 */
    width: max-content;     /* 根據最大內容寬度決定寬度 */
    border: 1px solid #000;
    margin: 50px;
    padding: 10px;
    font-size: 100px;
    line-height: 1;
  }
  .b div{
    position: absolute;     /* 子元素絕對定位 */
    width: 33.33%;          /* 寬度為父元素的 1/3 */
    height: 100%;           /* 高度等於父元素高度 */
    top: 0;                 /* 定位在上方 */
  }
  .b div:nth-of-type(1) {
    left: 0;                /* 第一個 div 定位在左側 */
    background: #f009;
  }
  .b div:nth-of-type(2) {
    right: 0;               /* 第一個 div 定位在右側 */
    background: #00f9;
  }

  .b div:nth-of-type(2)::before {
    position: absolute;     /* 子元素的虛擬元素絕對定位 */
    content: "";
    z-index: -1;
    width: 300%;            /* 因為元素寬度為父層的 1/3,所以改為 300% 才能填滿背景 */
    height: 100%;
    top: 0;
    left: -200%;            /* 因為元素定位在 2/3 處,所以往左移動 200% */
    background: #0c0;
    transition: .3s;
  }
  .b div:nth-of-type(1):hover ~ div:nth-of-type(2)::before{
    background: #f00;       /* 當第一個 div hover 時,改變同一層第二個 div 的虛擬元素背景 */
  }
  .b div:nth-of-type(2):hover::before{
    background: #00f;       /* 元素本身 hover 時改變虛擬元素背景 */
  }
</style>

CSS 教學 - CSS hover 時左右傾斜的背景效果 - 判斷 hover 位置改變背景色

使用漸層色產生左右傾斜背景效果

了解原理後,只需要將背景顏色改成「線性漸層」背景,搭配「自訂屬性 @property」改變漸層角度,就能實現左右傾斜的背景效果。

<!-- HTML 程式碼 -->
<div class="b">
  <div></div>
  OXXO
  <div></div>
</div>

<!-- CSS 程式碼 -->
<style>
  /* 定義角度屬性 */
  @property --deg {
    syntax: "<angle>";
    inherits: true;
    initial-value: 0deg;
  }
  .b {
    position: relative;
    box-sizing: border-box;
    width: max-content;
    border: 1px solid #000;
    margin: 50px;
    padding: 10px;
    font-size: 100px;
    line-height: 1;
  }
  .b div{
    position: absolute;
    width: 33.33%;
    height: 100%;
    top: 0;
  }
  .b div:nth-of-type(1) {left: 0;}
  .b div:nth-of-type(2) {right: 0;}

  .b div:nth-of-type(2)::before {
    position: absolute;
    content: "";
    z-index: -1;
    width: 300%;
    height: 100%;
    top: 0;
    left: -200%;
    background: linear-gradient(var(--deg), #f00 50%, #fff5 50%); /* 漸層背景 */
    transition: .3s, --deg .3s;  /* 轉場效果新增自訂屬性 --deg */
  }
  .b div:nth-of-type(1):hover ~ div:nth-of-type(2)::before{
    --deg: 10deg;        /* 當第一個 div hover 時,改變自訂屬性數值 */
  }
  .b div:nth-of-type(2):hover::before{
    --deg: -10deg;       /* 元素本身 hover 時,改變自訂屬性數值 */
  }
</style>

CSS 教學 - CSS hover 時左右傾斜的背景效果 - 使用漸層色產生左右傾斜背景效果

使用 clip-path 產生左右傾斜背景效果

除了使用漸層色,也可以運用 clip-path 裁切路徑的方式,將下層元素裁切出左右傾斜的背景色,這種做法甚至可以實現雙色文字的特殊效果,要使用這種做法必須將 HTML 程式碼稍作修改,移除內容的文字,將文字改成屬性的方式呈現,並透過 CSS 讀取 HTML 屬性,詳細說明可參考下方範例的註解。

<!-- HTML 程式碼 -->
<div class="b" text="OXXO">
  <div></div>
  <div></div>
</div>

<!-- CSS 程式碼 -->
<style>
  .b {
    --text: attr(text);     /* 取得屬性值 */
    --px: 50px;             /* 左右 padding 數值 */
    --py: 10px;             /* 上下 padding 數值 */
    position: relative;
    width: max-content;     /* 根據內容決定寬度 */
    border: 1px solid #000;
    margin: 50px;
    padding: var(--py) var(--px);      /* 根據變數值設定 padding */
    font-family: impact, arial-black;  /* 設定成比較粗的字體 */
    font-size: 100px;
    line-height: 1;
  }
  .b::before {
    color: #000;
    content: var(--text);  /* 父元素的虛擬元素內容為變數 --text 內容 */
  }
  .b div{
    position: absolute;
    width: 33.33%;        /* 內容兩個 div 寬度是 1/3 */
    height: 100%;
    top: 0;
  }
  .b div:nth-of-type(1) {left: 0;}  /* 左邊 div */
  .b div:nth-of-type(2) {right: 0;} /* 右邊 div */

  .b div:nth-of-type(2)::before {
    position: absolute;
    z-index: 2;
    width: calc(300% - var(--px)*2);  /* 第二個 div 的虛擬元素寬度除了要放大 300%,還要減去 padding */
    height: calc(100% - var(--py)*2); /* 第二個 div 的虛擬元素高度要減去 padding */
    padding: var(--py) var(--px);     /* 設定 padding */
    content: var(--text);             /* 設定內容 */
    top: 0;
    left: -200%;                      /* 原本位於 2/3 位置,往左移動 200% */
    color: white;
    background: #06c;
    clip-path: polygon(0 50%, 0 100%, 100% 100%, 100% 50%); /* 裁切路徑,裁切出長方形 */
    transition: .3s;
  }
  .b div::before, .b div::after {
    pointer-events: none;             /* 讓使用者可以穿透廚發下層 hover */
  }
  .b div:nth-of-type(1):hover ~ div:nth-of-type(2)::before{
    clip-path: polygon(0 30%, 0 100%, 100% 100%, 100% 70%); /* 裁切路徑傾斜四邊形 */
  }
  .b div:nth-of-type(2):hover::before{
    clip-path: polygon(0 70%, 0 100%, 100% 100%, 100% 30%); /* 裁切路徑傾斜四邊形 */
  }
</style>

CSS 教學 - CSS hover 時左右傾斜的背景效果 - 使用 clip-path 產生左右傾斜背景效果

小結

雖然 CSS 無法像 JavaScript 可以準確獲得滑鼠的座標,但透過一些「旁門左道」,仍然可以做出判斷滑鼠所在區間的有趣效果。


上一篇
( Day 27 ) 純 CSS 樓梯文字動態效果
下一篇
( Day 29 ) 純 CSS ICON 圖示形狀變換
系列文
關於那些有趣的 CSS 效果35
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言