Jing's 技術筆記

[JS30] Day 3: Playing with CSS Variables and JS

2018/06/28 Share

Day 3: Playing with CSS Variables and JS

學習使用 CSS 變數並搭配 JS

主要練習:

  • CSS - Variables
  • HTML5 - data-* attribute
  • JS - element.dataset.camelCasedName
  • JS - CSSStyleDeclaration.setProperty()
  • JS - Document.documentElement

設定 CSS 變數

CSS - Variables

在原生的 CSS 中我們也可以使用變數的概念,相較於 CSS 前處理器(例如,SASS/SCSS),CSS 前處理器是在建立成 CSS 檔案前就把變數替代成真實的值了,所以當 SCSS 透過前處理器完成之後,這個 CSS 檔就是靜態無法透過修改變數來一次修改多個 style 屬性值,因此使用者是無法透過瀏覽器來修改變數的值。

但是使用 CSS 原生變數的話,則是可以透過 JavaScript 擷取,並動態修改變數值,而這個變數值一變,所有套用這個變數的 Style 屬性值也都會連帶變更,也就是說可以讓使用者透過瀏覽器改變這個變數值,做到更多一次調整瀏覽器樣式的效果。

我們利用 :root{--customName: value} 來建立 CSS 的變數,並且在 CSS 屬性值中使用 var(--customName) 來代入變數的值 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 建立變數 */
:root {
--base: #ffc600;
--spacing: 10px;
--blur: 10px;
}
/* 使用變數 */
img {
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}
.hl {
color: var(--base);
}

利用 JS 改變 CSS 變數的值

Step1 : 對所有 input 註冊監聽事件

這邊,我們用querySelectorAll()選取所有的input,並用變數inputs儲存下來,再用forEach()方法分別對input做監聽 :

1
2
3
4
5
6
const inputs = document.querySelectorAll('.controls input');

inputs.forEach(input => {
input.addEventListener('change', changeHandler);
input.addEventListener('mousemove', changeHandler);
})

為什麼這邊不是只使用 change ? 因為在html中有使用input[type="range"]的拉霸,為了能讓滑鼠在拉動的同時也能即時顯示出效果,所以才加上了一個mousemove的監聽事件。

Step2 : 寫出監聽器並改變 CSS 變數

創建一個changeHandler的事件監聽器,並利用style.setProperty('--customName', 'value')來動態修改 CSS 變數的值,但要記得要加上單位(例如, px ):

注意 : 要透過 JS 修改 CSS 變數就必須使用style.setProperty('--customName', 'value'),不能直接使用style.--customName = value

1
2
3
4
5
6
function changeHandler(){
// let sizing = this.dataset.sizing ? this.dataset.sizing : '';
let sizing = this.dataset.sizing || ''; //較精簡的寫法,相當於if判斷式,結果同上

document.documentElement.style.setProperty(`--${ this.name }`, this.value + sizing)
}

這邊的this指向的是觸發changeHandler()的元素,分別抓出該元素的namevalue值。

document.documentElement會回傳目前文件 (document)中的根元素(Element),在這就是 HTML 文件中的 <html> 元素。

若對data-* attribute不熟悉,這篇文章 有詳盡的說明。

到這,就完成啦!


完整 JS

1
2
3
4
5
6
7
8
9
10
11
const inputs = document.querySelectorAll('.controls input');

function changeHandler(){
let sizing = this.dataset.sizing || '';
document.documentElement.style.setProperty(`--${this.name}`, this.value + sizing);
}

inputs.forEach(input => {
input.addEventListener('change', changeHandler);
input.addEventListener('mousemove', changeHandler);
})

相關連結

CATALOG
  1. 1. Day 3: Playing with CSS Variables and JS
  2. 2. 設定 CSS 變數
    1. 2.1. CSS - Variables
  3. 3. 利用 JS 改變 CSS 變數的值
    1. 3.1. Step1 : 對所有 input 註冊監聽事件
    2. 3.2. Step2 : 寫出監聽器並改變 CSS 變數
  4. 4. 完整 JS
  5. 5. 相關連結