關注 JS 太久,會養成任何功能都用 JS 實現的習慣,而忘記了 HTML 與 CSS 也具備一定的功能特徵。其實有些功能用 JS 實現吃力不討好,我們要綜合使用技術工具,而不是隻依賴 JS。
5 things you don't need Javascript for 這篇文章就從 5 個例子出發,告訴我們哪些功能不一定非要用 JS 做。
概述
使用 css 控制 svg 動畫
原文繪製了一個放煙花的 例子,本質上是用 css 控制 svg 產生動畫效果,核心程式碼:
.trail {
stroke-width: 2;
stroke-dasharray: 1 10 5 10 10 5 30 150;
animation-name: trail;
animation-timing-function: ease-out;
}
@keyframes trail {
from,
20% {
stroke-width: 3;
stroke-dashoffset: 80;
}
100%,
to {
stroke-width: 0.5;
stroke-dashoffset: -150;
}
}
可以看到,主要使用 stroke-dasharray
控制線條實虛線的樣式,再利用動畫效果對 stroke-dashoffset
產生變化,從而實現對線條起始點進行位移,實現線條 “繪圖” 的效果,且該 css 樣式對 svg 繪製的路徑是生效的。
sidebar
可以完全使用 css 實現 hover 時才出現的側邊欄:
nav {
position: 'absolute';
right: 100%;
transition: 0.2s transform;
}
nav:hover,
nav:focus-within {
transform: translateX(100%);
}
核心在於 hover
時設定 transform
屬性可以讓元素偏移,且 translateX(100%)
可以位移當前元素寬度的身位。
另一個有意思的是,如果使用 TABS 按鍵聚焦到 sidebar 內元素也要讓 sidebar 出來,可以直接用 :focus-within
實現。如果需要 hover 後延遲展示可以使用 transition-delay
屬性。
sticky position
使用 position: sticky
來黏住一個元素:
.square {
position: sticky;
top: 2em;
}
這樣該元素會始終展示在其父容器內,但一旦其出現在視窗時,當 top 超過 2em
後就會變為 fixed
定位並保持原位。
使用 JS 判斷還是挺複雜的,你得設法監聽父元素滾動,並且在定位切換時可能產生一些抖動,因為 JS 的執行與 CSS 之間是非同步關係。但當我們只用 CSS 描述這個行為時,瀏覽器就有辦法解決轉換時的抖動問題。
手風琴選單
使用 <details>
標籤可以實現類似一個簡易的摺疊手風琴效果:
<details>
<summary>title</summary>
<p>1</p>
<p>2</p>
</details>
在 <details>
標籤內的 <summary>
標籤內容總是會展示,且點選後會切換 <details>
內其他元素的顯隱藏。雖然這做不了特殊動畫效果,但如果只為了做一個普通的展開摺疊功能,用 HTML 標籤就夠了。
暗色主題
雖然直覺上暗色主題好像是一種定製業務邏輯,但其實因為暗色主題太過於普遍,以至於作業系統和瀏覽器都內建實現了,而 CSS 也實現了對應的方法判斷當前系統的主題到底是亮色還是暗色:prefers-color-scheme。
所以如果系統要實現暗色系主題,最好可以和作業系統設定保持一致,這樣使用者體驗也會更好:
@media (prefers-color-scheme: light) {
/** ... */
}
@media (prefers-color-scheme: dark) {
/** ... */
}
@media (prefers-color-scheme: no-preference) {
/** ... */
}
如果使用 Checkbox 勾選是否開啟暗色主題,也可以僅用 CSS 變數判斷,核心程式碼是:
#checkboxId:checked ~ .container {
background-color: black;
}
~
這個符號表示,selector1 ~ selector2
時,為選擇器 selector1
之後滿足 selector2
條件的兄弟節點設定樣式。
精讀
除了上面例子外,筆者再追加幾個例子。
幻燈片滾動
幻燈片滾動即每次滾動有固定的步長,把子元素完整的展示在可視區域,不可能出現上下或者左右兩個子元素各出現一部分的 “割裂” 情況。
該場景除了用瀏覽器實現幻燈片外,在許多網站首頁也被頻繁使用,比如將首頁切割為 5 個縱向滾動的區塊,每個區塊展示一個產品特性,此時滾動不再是連續的,而是從一個區塊到另一個區塊的完整切換。
其實這種效果無需 JS 實現:
html {
scroll-snap-type: y mandatory;
}
.child {
scroll-snap-align: start;
}
這樣便將頁面設定為精準捕捉子元素滾動位置,在滾輪觸發、滑鼠點選滾動條鬆手或者鍵盤上下按鍵時,scroll-snap-type: y mandatory
可以精準捕捉這一垂直滾動行為,並將子元素完全滾動到可視區域。
顏色選擇器
使用 HTML 原生就能實現顏色選擇器:
<input type="color" value="#000000">
該選擇器的好處是效能、可維護性都非常非常的好,甚至可以捕捉桌面的顏色,不好的地方是無法對拾色器進行定製。
總結
關於 CSS 可以實現哪些原本需要 JS 做的事,有很多很好的文章,比如:
但並不是讀了這些文章,我們就要儘量用 CSS 實現所有能做的事,那樣也沒有必要。CSS 因為是描述性語言,它可以精確控制樣式,但卻難以精確控制互動過程,對於標準互動行為比如幻燈片滑動、動畫可以使用 CSS,對於非標準互動行為,比如自定義位置彈出 Modal、用 svg 繪製完全自定義路徑動畫儘量還是用 JS。
另外對於互動過程中的狀態,如果需要傳遞給其他元素響應,還是儘量使用 JS 實現。雖然 CSS 偽類可以幫我們實現大部分這種能力,但如果我們要監聽狀態變化發一個請求什麼的,CSS 就無能為力了,或者我們需要非常 trick 的利用 CSS 實現,這也違背了 CSS 技術選型的初衷。
最後,能否在合適的場景選擇 CSS 方案,也是技術選型能力的一種,不要忘了 CSS 適用的領域,不要什麼功能都用 JS 實現。
討論地址是:精讀《不再需要 JS 做的 5 件事》· Issue #413 · dt-fe/weekly
如果你想參與討論,請 點選這裡,每週都有新的主題,週末或週一釋出。前端精讀 - 幫你篩選靠譜的內容。
關注 前端精讀微信公眾號
<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg">
版權宣告:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證)