CSS hover 時左右傾斜的背景效果
這篇教學會使用元素中不同的子元素,判斷滑鼠 hover 時所在的區間,進而透過漸層色或 clip-path 裁切路徑的方式,產生有趣的左右傾斜背景動態效果。
快速導覽:
判斷 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>
使用漸層色產生左右傾斜背景效果
了解原理後,只需要將背景顏色改成「線性漸層」背景,搭配「自訂屬性 @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>
使用 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 無法像 JavaScript 可以準確獲得滑鼠的座標,但透過一些「旁門左道」,仍然可以做出判斷滑鼠所在區間的有趣效果。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~