網頁的外觀主要由 CSS 決定,而 JavaScript 負責在適當的時機「切換」樣式或啟動動畫。本篇介紹最推薦的做法:用 classList 切換 CSS 類別、用 CSS 變數改變主題色,並用瀏覽器內建的動畫功能製作簡單的動態效果。
一、直接修改 style(適合單一、臨時的變化)
const box = document.getElementById('box');
box.style.backgroundColor = '#ffe9a8'; // CSS 的 background-color 要改成駝峰式
box.style.width = '200px';
box.style.display = 'none'; // 隱藏
直接寫 style 的缺點是樣式散落在程式裡,不容易維護,而且 box.style 只能讀到「行內樣式」,讀不到 CSS 檔案裡設定的值。要讀取實際套用的樣式,請用 getComputedStyle(box).width。
二、classList:切換 CSS 類別(建議做法)
把樣式寫在 CSS,JavaScript 只負責「加上或移除類別」,兩邊各管各的,最好維護。
| 方法 | 說明 |
|---|---|
classList.add('on') | 加上類別 |
classList.remove('on') | 移除類別 |
classList.toggle('on') | 有就移除,沒有就加上 |
classList.contains('on') | 檢查是否有此類別(回傳 true/false) |
範例:展開與收合
<style>
.panel { overflow: hidden; max-height: 0; transition: max-height 0.3s ease; }
.panel.open { max-height: 200px; }
</style>
<button id="toggleBtn">顯示/隱藏說明</button>
<div id="panel" class="panel">
<p>這是可以展開與收合的說明文字。</p>
</div>
<script>
const panel = document.getElementById('panel');
document.getElementById('toggleBtn').addEventListener('click', () => {
panel.classList.toggle('open');
});
</script>
CSS 的 transition 會讓 max-height 的變化變成平滑的動畫,JavaScript 完全不需要處理動畫細節。
三、CSS 變數:一次改變整個主題
<style>
:root { --bg: #ffffff; --fg: #222222; }
body { background: var(--bg); color: var(--fg); transition: background 0.3s; }
body.dark { --bg: #1e1e1e; --fg: #eeeeee; }
</style>
<button id="themeBtn">切換深色/淺色</button>
<script>
document.getElementById('themeBtn').addEventListener('click', () => {
document.body.classList.toggle('dark');
});
// 也可以直接用程式修改變數
document.documentElement.style.setProperty('--bg', '#fff7e6');
</script>
需要讓使用者自己挑顏色時,用 setProperty('--變數名稱', 值) 即可立刻影響所有使用該變數的地方。
四、濾鏡:舊式寫法已淘汰,改用 CSS filter
早期的教材會用 Internet Explorer 專屬的濾鏡語法做模糊、透明等效果。這些寫法現在的瀏覽器都不支援,請改用標準的 CSS filter 屬性:
img.style.filter = 'grayscale(100%)'; // 黑白
img.style.filter = 'blur(3px)'; // 模糊
img.style.filter = 'brightness(1.2) contrast(1.1)'; // 可組合多個效果
img.style.filter = 'none'; // 還原
半透明用 opacity(0 是全透明,1 是不透明)即可。
五、Web Animations API:用程式做動畫
需要由程式決定「何時、怎麼動」時,可以直接呼叫元素的 animate():
const ball = document.getElementById('ball');
document.getElementById('goBtn').addEventListener('click', () => {
ball.animate(
[
{ transform: 'translateX(0)' },
{ transform: 'translateX(200px)' }
],
{ duration: 600, easing: 'ease-in-out', fill: 'forwards' }
);
});
- 第一個參數是「關鍵影格」陣列,描述起點與終點的樣式。
duration是時間(毫秒),fill: 'forwards'表示動畫結束後停在最後的樣子。- 效能考量:動畫盡量改變
transform與opacity,比改變left、width更順暢。
範例:輸入錯誤時的抖動提示
function shake(el) {
el.animate(
[
{ transform: 'translateX(0)' },
{ transform: 'translateX(-8px)' },
{ transform: 'translateX(8px)' },
{ transform: 'translateX(0)' }
],
{ duration: 300 }
);
}
六、尊重使用者的「減少動態效果」設定
有些使用者會因為動畫感到不適,而在系統中開啟「減少動態效果」。程式應該尊重這個設定:
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!reduce) {
ball.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 400 });
}
在 CSS 裡也可以寫 @media (prefers-reduced-motion: reduce),把動畫時間縮短或關閉。
七、練習題
- 做一個「字體放大」按鈕,每按一次加上
big類別,再按一次移除。 - 用 CSS 變數做一個顏色挑選器:
<input type="color">改變頁面的主色。 - 替第八篇的表單,在欄位不合格時呼叫
shake()提示使用者。
結語
原則很簡單:樣式寫在 CSS,JavaScript 負責切換類別與觸發動畫;動畫優先使用 transform 與 opacity,並尊重使用者的偏好設定。最後一篇,我們要把前面學到的東西整合成一個完整的小專案。
沒有留言:
張貼留言