純CSS實(shí)現(xiàn)有趣Emoji切換開關(guān),你知道嗎?
這是一個(gè)純CSS創(chuàng)建的動(dòng)畫切換開關(guān),它不僅能夠在視覺上吸引用戶,還能通過交互提供即時(shí)反饋。本文將解析源碼的核心實(shí)現(xiàn)邏輯,這個(gè)項(xiàng)目的核心是使用CSS變量、3D變換和過渡效果來實(shí)現(xiàn)一個(gè)動(dòng)態(tài)的、響應(yīng)式的用戶界面元素。
關(guān)鍵技術(shù)點(diǎn)
- CSS變量:用于動(dòng)態(tài)調(diào)整樣式。
- 3D變換:用于創(chuàng)建翻轉(zhuǎn)動(dòng)畫效果。
- 過渡效果:用于平滑地改變?cè)氐臉邮健?/li>
- emoji:并不是真正的emoji而是通過CSS繪制。
實(shí)現(xiàn)步驟
1. HTML
首先需要?jiǎng)?chuàng)建一個(gè)基本的HTML結(jié)構(gòu),包括一個(gè)表單元素(checkbox)和一個(gè)用于顯示Emoji的元素。這里的switch__emoji-face即是開關(guān)上面的兩個(gè)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來設(shè)計(jì)這個(gè)切換開關(guān)的樣式。這段CSS代碼主要用來實(shí)現(xiàn)以下幾個(gè)目標(biāo):
- 統(tǒng)一的顏色主題:
通過定義 --hue 變量,可以在整個(gè)網(wǎng)站中統(tǒng)一色調(diào),使得顏色方案更加一致。
--bg 和 --fg 分別定義了背景色和前景色,使得文本和背景之間有良好的對(duì)比度,提高可讀性。
- 動(dòng)態(tài)響應(yīng)的字體大?。?/li>
使用 calc() 函數(shù)和視口寬度單位 vw,可以根據(jù)屏幕大小動(dòng)態(tài)調(diào)整字體大小,實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)。
平滑的過渡動(dòng)畫:
--trans-dur 定義了過渡動(dòng)畫的持續(xù)時(shí)間,使得元素的顯示和隱藏更加平滑自然。
--trans-timing1 和 --trans-timing2 使用貝塞爾曲線定義了動(dòng)畫的緩動(dòng)效果,使得動(dòng)畫變化更加符合物理規(guī)律和視覺習(xí)慣。
易于維護(hù)和擴(kuò)展:
通過使用CSS變量,可以在一個(gè)地方修改值,而在整個(gè)文檔中生效,提高了代碼的可維護(hù)性。
同時(shí)這些變量也可以在其他樣式規(guī)則中被引用,方便進(jìn)行樣式的擴(kuò)展和復(fù)用。
: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 相關(guān)的 CSS 代碼塊。這段代碼通過使用 CSS 的 transform 屬性和一些偽元素來創(chuàng)建一個(gè)可動(dòng)的 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 屬性設(shè)置為圓形,并通過 box-shadow 為 Emoji 添加眼睛和嘴巴。
- &-eye : 用于繪制 Emoji 的眼睛。通過 border 屬性創(chuàng)建一個(gè)有邊框的圓,并利用 transform 屬性調(diào)整位置和傾斜角度。
- &-mouth : 用于繪制 Emoji 的嘴巴。通過 background-image 屬性使用漸變和徑向漸變來創(chuàng)建嘴巴的形狀。
- &-face : 用于繪制 Emoji 的臉部,通過 transform-style: preserve-3d 屬性來保留 3D 空間中的子元素位置。
- 3D 轉(zhuǎn)換 : 使用 transform 屬性的 rotateY 和 translateZ 函數(shù)來創(chuàng)建翻轉(zhuǎn)效果。
- 過渡效果 : 使用 transition 屬性來平滑地變換 Emoji 的表情。
下面是繪制 Emoji 表情的核心部分,接下來就是3D動(dòng)畫變換:
.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變換和過渡
為了實(shí)現(xiàn)Emoji的翻轉(zhuǎn)效果,我們使用CSS的3D變換和過渡屬性。點(diǎn)擊切換動(dòng)畫的主要部分涉及到 .switch__input 這個(gè) checkbox 輸入元素以及與之相關(guān)的 .switch__emoji 元素。當(dāng) checkbox 被選中時(shí),會(huì)觸發(fā) .switch__emoji 的狀態(tài)變化,從而執(zhí)行動(dòng)畫。
這里對(duì)于從右到左(如阿拉伯語或希伯來語)的語言,還實(shí)現(xiàn)了相反方向的滑動(dòng)。??
以下是實(shí)現(xiàn)點(diǎn)擊切換動(dòng)畫的核心代碼:
.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 :
- 當(dāng) .switch__input 被選中(即被勾選)時(shí),與其相鄰的 .switch__emoji 元素會(huì)執(zhí)行 transform: translateX(100%); 動(dòng)畫,即沿著 X 軸移動(dòng)自身寬度的 100%,從而實(shí)現(xiàn)滑塊開關(guān)的效果。
- [dir="rtl"] .switch__input:checked + .switch__emoji :
對(duì)于從右到左(如阿拉伯語或希伯來語)的語言,使用 translateX(-100%); 來實(shí)現(xiàn)相反方向的滑動(dòng)。
.switch__input:checked + .switch__emoji .switch__emoji-face :
當(dāng) .switch__input 被選中時(shí),.switch__emoji-face 元素會(huì)執(zhí)行 rotateY(179.99deg); 動(dòng)畫,即圍繞 Y 軸旋轉(zhuǎn) 179.99 度,接近 180 度的旋轉(zhuǎn)使得 Emoji 翻轉(zhuǎn)。
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face :
對(duì)于從右到左的語言,使用 rotateY(-179.99deg); 來實(shí)現(xiàn)相反方向的翻轉(zhuǎn)。
.switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face :
當(dāng) .switch__input 被選中時(shí),第二個(gè) .switch__emoji-face 元素會(huì)執(zhí)行 rotateY(0); 動(dòng)畫,即恢復(fù)到原始狀態(tài)。
[dir="rtl"] .switch__input:checked + .switch__emoji .switch__emoji-face + .switch__emoji-face :
對(duì)于從右到左的語言,使用 rotateY(-360deg); 來實(shí)現(xiàn)相反方向的旋轉(zhuǎn)。
動(dòng)畫效果的實(shí)現(xiàn)
核心動(dòng)畫效果是通過 CSS 的 transition 屬性來實(shí)現(xiàn)的,確保變換是平滑的。
.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); 定義了變換的持續(xù)時(shí)間和緩動(dòng)函數(shù),使得動(dòng)畫效果更加平滑自然。
通過這些代碼,點(diǎn)擊切換按鈕時(shí),Emoji 會(huì)沿著一個(gè)軸翻轉(zhuǎn),同時(shí)滑塊也會(huì)移動(dòng),從而實(shí)現(xiàn)了一個(gè)有趣的切換動(dòng)畫效果。
響應(yīng)式設(shè)計(jì)
為了確保這個(gè)按鈕在不同設(shè)備上以及暗色場(chǎng)景下都能良好顯示,源碼使用了CSS媒體查詢和相對(duì)單位。
@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);
}
}
總結(jié)
通過使用CSS變量、3D變換和過渡效果,創(chuàng)建了一個(gè)既美觀又功能豐富的Emoji Toggle按鈕。這個(gè)交互效果極大了增強(qiáng)了用戶體驗(yàn)。