深色模式 (Dark Mode) 在近代使用者裝置上顯得越來越普遍,iOS、MacOS、Android、Windows 在更新上都不約而同的推出。長時間暴露在高亮度的白底介面中,往往容易造成眼睛疲勞、乾澀,甚至影響專注力與睡眠品質。為了改善這樣的使用體驗,深色模式誕生了。
或許不見得要一開始就導入深色模式,但若有提供這個啟閉選項,在使用者的體驗上肯定是更好的。想先列出幾個優點以及需要顧慮的點。
優點:
缺點:
這邊以 Next.js 作為示範,若有需要在 Vite、Astro、Remix 上實作,可以參考 Shadcn/ui Dark Mode。
專案中安裝 next-themes
、Shadcn/ui 的 Button
、Dropdown Menu
、lucide-icon
npm install next-themes
npx shadcn@latest add "https://animate-ui.com/r/icon.json"
npx shadcn@latest add button dropdown-menu
在 components
資料夾,新增 theme-provider.tsx
檔案,並加上以下程式碼
若沒有
components
資料夾,可以在專案目錄中新增
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
export function ThemeProvider({
children,
...props
}: React.ComponentProps<typeof NextThemesProvider>) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
修改 app/layout.tsx
在 import 區域增加
import { ThemeProvider } from "@/components/theme-provider"
並且在 export default function RootLayout(...){return(...)}
中修改
export default function RootLayout({ children }: RootLayoutProps) {
return (
<>
<html lang="zh-Hant" suppressHydrationWarning>
<head />
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
</>
)
}
找個合適的位置放置深淺色模式切換。在這邊的範例中,我將切換按鈕放在 next.js logo 下方。
打開 app/page.tsx
,並且將必要的 import 載入
找到 export function ...{}
當中加入這個 React Hook,用途是後面要 onclick 動作時可以觸發
const { setTheme } = useTheme()
在 return(<html>...</html>)
中加入深淺色模式切換按鈕和 Menu
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
執行 npm run dev
測試效果
今天示範如何完成深淺色模式的設置,並且觀察在切換深淺色時使用 onClick
事件的運作方式。其實不只 dropdown menu
,還能夠透過 switch、icon 等不同元件來實現切換。以上算是最基礎的範例,幫助大家建立概念。
明天我們將進一步探索 Animate UI 的文字動畫效果,看看如何讓文字活起來~
雖然平常還是喜歡白色但用久了真的需要深色mode突然眼睛變得好舒服哈
沒錯 適時的切換讓頭腦清醒一下🤣
長時間暴露在高亮度的白底介面中,往往容易造成眼睛疲勞、乾澀,甚至影響專注力與睡眠品質。
聽起來像是筆者本人的親身經歷
被發現了哈哈 所以才更想要推廣對使用者面向的網頁、App 都具備深淺色切換🥳
真厲害