我今天的目標為實現切換字體大小功能。因為我有時也會在網頁中調整字體的大小,所以我也希望將此功能加到待辦事項網站上。
在開始之前,我先來簡單介紹一下 CSS 的 font-size 屬性。這個屬性可以用來設定文字的大小,該屬性有兩種常見的單位:
絕對單位:例如 px,它就是一種絕對單位。用絕對單位設定的文字,不論是在網頁或是在行動裝置上,文字大小都會是固定不變的。
相對單位:例如 "%"、"rem" 和 "em",它們都是相對單位。相對單位會根據其他元素的大小進行字體大小的調整。
<html>
元素的大小設定字體大小我用以下例子來解說 em:
假設我有一個 HTML 結構,如下所示:
<div class="outer">
<ul class="sub-setting-list" id="fontSizeMenu">
<li class="small">小</li>
<li class="mid">中</li>
<li class="large">大</li>
</ul>
</div>
而我將它的 CSS 樣式設定為:
.outer {
font-size: 1.5em; /* 祖父元素的字體大小為 1.5 倍 */
}
.sub-setting-list {
font-size: 1em; /* 父元素的字體大小為祖父元素的 1 倍 */
}
li {
font-size: 0.8em; /* 子元素的字體大小為父元素的 0.8 倍 */
}
也就是說若是你移動到 .outer
元素的文字大小,裡面元素的文字大小也會跟著變動,這會導致難以管理字體大小,所以 em 我比較不常使用。
最後則是特殊關鍵字,例如 small 和 larger 等等,它們會將元素的文字設置為相對較大或較小的字體大小。我最終選擇使用特殊關鍵字去設定文字大小,這樣也方便我之後做調整。
首先,在 HTML 內加上字體切換的程式碼:
<li>
<span class="selectorStyle" id="fontSize">字體大小</span>
<ul class="sub-setting-list" id="fontSizeMenu">
<li id="small">小</li>
<li id="mid">中</li>
<li id="large">大</li>
</ul>
</li>
接下來,在 SCSS 檔案中添加相對應的樣式:
.default-font-size {
font-size: medium;
}
.small-font-size {
font-size: small;
}
.large-font-size {
font-size: larger;
}
接著,依照以下步驟,使用 JavaScript 來處理字體大小切換事件。
this.fontSize = this.getElement("#fontSize");
this.fontSizeMenu = this.getElement("#fontSizeMenu");
setFontSize()
方法,用來設定字體大小setFontSize(fontSize) {
const bodyClassList = document.body.classList;
bodyClassList.remove(
"default-font-size",
"small-font-size",
"large-font-size"
);
bodyClassList.add(fontSize);
}
和昨天的字體切換功能相同,先移除所有 font-size 的類別,然後在添加相對應的類別到 <body>
元素上。
setupFontSizes()
方法設定點擊事件setupFontSizes() {
const fontSizes = {
mid: "default-font-size",
small: "small-font-size",
large: "large-font-size",
};
for (const [liId, fontSizeName] of Object.entries(fontSizes)) {
const fontSize = this.getElement(`#${liId}`);
fontSize.addEventListener("click", () => {
this.setFontSize(fontSizeName);
});
}
}
constructor()
中增加 setupFontSizes()
方法最後,為了要讓側邊欄有關字體大小的子清單可以開啟,要在 setupEventListeners()
方法中添加以下點擊事件:
toggleFontSize() {
this.fontSizeMenu.classList.toggle("show");
}
最終結果圖如下所示: