這是一個純CSS創建的動畫切換開關,它不僅能夠在視覺上吸引用户,還能通過交互提供即時反饋。本文將解析源碼的核心實現邏輯,這個項目的核心是使用CSS變量、3D變換和過渡效果來實現一個動態的、響應式的用户界面元素。
關鍵技術點
- CSS變量:用於動態調整樣式。
- 3D變換:用於創建翻轉動畫效果。
- 過渡效果:用於平滑地改變元素的樣式。
- emoji:並不是真正的emoji而是通過CSS繪製。
實現步驟
1. HTML
首先需要創建一個基本的HTML結構,包括一個表單元素(checkbox)和一個用於顯示Emoji的元素。這裏的switch__emoji-face即是開關上面的兩個emoji表情。
<div class="switch">
<input type="checkbox" class="switch__input" id="toggle">
<label for="toggle" class="switch__label">Toggle</label>
<div class="switch__wrapper">
<div class="switch__emoji">
<div class="switch__emoji-face"></div>
<div class="switch__emoji-face"></div>
</div>
</div>
</div>
2. CSS
接下來,我們使用CSS來設計這個切換開關的樣式。這段CSS代碼主要用來實現以下幾個目標:
-
統一的顏色主題:
- 通過定義
--hue變量,可以在整個網站中統一色調,使得顏色方案更加一致。 --bg和--fg分別定義了背景色和前景色,使得文本和背景之間有良好的對比度,提高可讀性。
- 通過定義
-
動態響應的字體大小:
- 使用
calc()函數和視口寬度單位vw,可以根據屏幕大小動態調整字體大小,實現響應式設計。
- 使用
-
平滑的過渡動畫:
--trans-dur定義了過渡動畫的持續時間,使得元素的顯示和隱藏更加平滑自然。--trans-timing1和--trans-timing2使用貝塞爾曲線定義了動畫的緩動效果,使得動畫變化更加符合物理規律和視覺習慣。
-
易於維護和擴展:
- 通過使用CSS變量,可以在一個地方修改值,而在整個文檔中生效,提高了代碼的可維護性。
- 同時這些變量也可以在其他樣式規則中被引用,方便進行樣式的擴展和複用。
:root {
--hue: 223;
--bg: hsl(var(--hue),10%,90%);
--fg: hsl(var(--hue),10%,10%);
--trans-dur: 0.5s;
--trans-timing1: cubic-bezier(0.65,0,0.35,1);
--trans-timing2: cubic-bezier(0.65,0,0.35,1.5);
font-size: calc(56px + (120 - 56) * (100vw - 280px) / (3840 - 280));
}
Emoji 的繪製主要依賴於 .switch__emoji 相關的 CSS 代碼塊。這段代碼通過使用 CSS 的 transform 屬性和一些偽元素來創建一個可動的 Emoji 效果。以下是核心代碼部分的解釋:
.switch__emoji {
$hue: 48;
$sat: 90%;
$radius: 0.5em;
box-shadow: 0.25em 0.25em 0.125em hsl(0,0%,0%,0.3);
overflow: hidden;
pointer-events: none;
top: 0.25em;
left: 0.25em;
width: 1em;
height: 1em;
/* ...其他樣式... */
&:before,
&:after,
&-eye,
&-mouth,
&-face {
display: block;
position: absolute;
}
/* ...其他樣式... */
}
- 偽元素
&:before和&:after:
用於繪製 Emoji 的臉的上半部分和下半部分,通過border-radius屬性設置為圓形,並通過box-shadow為 Emoji 添加眼睛和嘴巴。 &-eye:
用於繪製 Emoji 的眼睛。通過border屬性創建一個有邊框的圓,並利用transform屬性調整位置和傾斜角度。&-mouth:
用於繪製 Emoji 的嘴巴。通過background-image屬性使用漸變和徑向漸變來創建嘴巴的形狀。&-face:
用於繪製 Emoji 的臉部,通過transform-style: preserve-3d屬性來保留 3D 空間中的子元素位置。- 3D 轉換 :
使用transform屬性的rotateY和translateZ函數來創建翻轉效果。 - 過渡效果 :
使用transition屬性來平滑地變換 Emoji 的表情。
下面是繪製 Emoji 表情的核心部分,接下來就是3D動畫變換:
.switch__emoji-eye {
border: 0.0625em solid hsl(var(--hue),10%,10%);
border-radius: 50%;
top: 50%;
left: 50%;
width: 0.25em;
height: 0.25em;
transform: translate(-50%,-50%) rotateY(-22.5deg) translateZ($radius) rotateZ(45deg);
}
.switch__emoji-mouth {
background-image: ...;
top: 50%;
left: 50%;
width: 0.5em;
height: 0.5em;
transform: translate(-50%,-50%) rotateX(-15deg) translateZ($radius);
}
3. 3D變換和過渡
為了實現Emoji的翻轉效果,我們使用CSS的3D變換和過渡屬性。點擊切換動畫的主要部分涉及到 .switch__input 這個 checkbox 輸入元素以及與之相關的 .switch__emoji 元素。當 checkbox 被選中時,會觸發 .switch__emoji 的狀態變化,從而執行動畫。
這裏對於從右到左(如阿拉伯語或希伯來語)的語言,還實現了相反方向的滑動。👍
以下是實現點擊切換動畫的核心代碼:
.switch__input:checked + .switch__emoji {
transform: translateX(100%);
}
[dir="rtl"] .switch__input:checked + .switch__emoji {
transform: translateX(-100%);
}
.switch__input:checked + .switch__emoji .switch__emoji-face {
transform: rotateY(179.99deg);
}
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face {
transform: rotateY(-179.99deg);
}
.switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face {
transform: rotateY(0);
}
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face {
transform: rotateY(-360deg);
}
代碼解析
-
.switch__input:checked + .switch__emoji:- 當
.switch__input被選中(即被勾選)時,與其相鄰的.switch__emoji元素會執行transform: translateX(100%);動畫,即沿着 X 軸移動自身寬度的 100%,從而實現滑塊開關的效果。
- 當
-
[dir="rtl"] .switch__input:checked + .switch__emoji:- 對於從右到左(如阿拉伯語或希伯來語)的語言,使用
translateX(-100%);來實現相反方向的滑動。
- 對於從右到左(如阿拉伯語或希伯來語)的語言,使用
-
.switch__input:checked + .switch__emoji .switch__emoji-face:- 當
.switch__input被選中時,.switch__emoji-face元素會執行rotateY(179.99deg);動畫,即圍繞 Y 軸旋轉 179.99 度,接近 180 度的旋轉使得 Emoji 翻轉。
- 當
-
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face:- 對於從右到左的語言,使用
rotateY(-179.99deg);來實現相反方向的翻轉。
- 對於從右到左的語言,使用
-
.switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face:- 當
.switch__input被選中時,第二個.switch__emoji-face元素會執行rotateY(0);動畫,即恢復到原始狀態。
- 當
-
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face:- 對於從右到左的語言,使用
rotateY(-360deg);來實現相反方向的旋轉。
- 對於從右到左的語言,使用
動畫效果的實現
核心動畫效果是通過 CSS 的 transition 屬性來實現的,確保變換是平滑的。
.switch__emoji-face {
transform-style: preserve-3d;
transition: transform var(--trans-dur) var(--trans-timing2);
}
transform-style: preserve-3d;確保子元素在 3D 空間中的位置得以保留。transition: transform var(--trans-dur) var(--trans-timing2);定義了變換的持續時間和緩動函數,使得動畫效果更加平滑自然。
通過這些代碼,點擊切換按鈕時,Emoji 會沿着一個軸翻轉,同時滑塊也會移動,從而實現了一個有趣的切換動畫效果。
響應式設計
為了確保這個按鈕在不同設備上以及暗色場景下都能良好顯示,源碼使用了CSS媒體查詢和相對單位。
@media (prefers-color-scheme: dark) {
:root {
--bg: hsl(var(--hue),10%,10%);
--fg: hsl(var(--hue),10%,90%);
}
.switch__input {
background-color: hsl(var(--hue),10%,20%);
box-shadow: 0.0625em 0.0625em 0.0625em hsl(var(--hue),10%,25%) inset, -0.0625em -0.0625em 0.0625em hsl(var(--hue),10%,20%) inset, 0 0 0 0.125em hsl(var(--hue),10%,30%) inset, 0.25em 0.25em 0.125em hsla(0,0%,0%,0.3) inset, 0.0625em 0.0625em 0.0625em hsla(0,0%,0%,0.3);
}
}
總結
通過使用CSS變量、3D變換和過渡效果,創建了一個既美觀又功能豐富的Emoji Toggle按鈕。這個交互效果極大了增強了用户體驗。希望這篇文章能激發你探索更多CSS的可能性,感興趣的可以嘗試看看~
在線預覽:https://code.juejin.cn/pen/7419571759471165455
看完本文如果覺得有用,記得點個贊支持,收藏起來説不定哪天就用上啦~
專注前端開發,分享前端相關技術乾貨,公眾號:南城大前端(ID: nanchengfe)