Notes
Nuxt3 App
Notes
About

筆記內容

  • css配置
  • 取得作業系統的顏色模式
  • 自訂可切換的顏色模式
  • ServerSideRender和ClientSideRender差異

相關筆記

  • Nuxt3 features

顏色模式實現概念

透過html結構裡的上下層繼承變數的特性,當上層變數指向的背景色、文字色改變時,下層的樣式即可響應。

css配置

在document html樹狀結構中,html或body都可以作為綁定的上層。這裡預設一個body預設的樣式對照,使用了css變數的語法(ex. --mode-text-color:rgba(0, 0, 0, 0.8););而另一個深色模式則是多了一個class名稱的body。

body.light-mode {
  background-color: #fff;
  color: rgba(0, 0, 0, 0.8);
  --mode-text-color: rgba(0, 0, 0, 0.8);
  --mode-text-color-hover: #6d28d9;
  --border-color: #ccc;
}
body.dark-mode {
  background-color: #091a28;
  color: #ebf4f1;
  --mode-text-color: #ebf4f1;
  --mode-text-color-hover: #6d28d9;
  --border-color: #fff;
}

在html渲染結果對照

而在下層的樣式中,就可以使用上層定義好的變量。

.tocBox {  border-color: var(--border-color);}.prose {  color: var(--mode-text-color);}

取得作業系統的顏色模式

瀏覽器可以取得使用者作業系統的顏色模式,再讓javascript來讀取,這部分的資訊儲存於media內。並且多一個監聽事件,在使用者改變系統顏色模式時來響應。

window.matchMedia('(prefers-color-scheme: dark)').matches :Booleanwindow    .matchMedia("(prefers-color-scheme: dark)")    .addEventListener("change", function (event) {        console.log(event.matches)    }

自訂可切換的顏色模式

跟使用者作業系統的顏色模式相對脫鉤,我預想是把顏色模式儲存於瀏覽器的localstorage,對於使用者切換上更便利,不需要再去改動作業系統的顏色模式。

//可以先抓取作業系統的顏色模式let mode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : //再抓取使用者存取瀏覽器操作的顏色模式紀錄mode = localStorage.getItem('app-color-mode') ?? (mode ?? 'light');//最後去把目標的上層html tag綁定對應顏色模式的class名稱document.getElementsByTagName('body')[0].setAttribute('class', `${mode}-mode`);

ServerSideRender和ClientSideRender差異

window和document物件必須是在Client端的瀏覽器運行時才能使用,所以當渲染機制是使用SSR時,就必須注意這段取得和判別顏色模式的腳本是在client端發生,才能符合這次介紹的顏色模式機制。

//Nuxt3 SSR情境下,判別的腳本寫在onMounted這個hook中onMounted(() => {  let mode = localStorage.setItem('nuxt3-app-color-mode', mode) ?? 'light'  document?.getElementsByTagName('body')[0]?.setAttribute('class', `${mode}-mode`);});

同時在nuxt3框架之下,狀態管理的方式可以這樣使用,來實作切換功能。

const colorEnum =  DARK: 'dark',  LIGHT: 'light',  SEPIA: 'sepia',};const const => {  switch (appMode.value) {    case colorEnum.LIGHT: {      appMode.value = colorEnum.DARK;      break;    }    case colorEnum.DARK: {      appMode.value = colorEnum.SEPIA;      break;    }    case colorEnum.SEPIA: {      appMode.value = colorEnum.LIGHT;      break;    }  }  setTimeout(() => {    addModeClass(appMode.value);  }, 100);};

Nuxt3內實作完整程式碼

How to Watch for System Dark Mode Changes Using JavaScript and CSS

2022-08-01 編輯