設計你的 Astro 主題——從設計系統到實作
為什麼需要設計系統?
一個好的 Astro 主題不只是外觀好看,它還應該易於維護、易於自訂。設計系統(Design System)就是為此存在的——它提供一組統一的設計語言,讓整個主題的一致性得以保證。
第一步:建立設計 Token
設計 Token 是你的主題最底層的視覺變數。在 Astro 中,最好的做法是把它們放在 CSS 自定義屬性(Custom Properties)中:
/* src/styles/global.css */
:root {
/* ─── 顏色 ─── */
--primary: #533afd;
--ink: #0d253d;
--ink-secondary: #273951;
--ink-mute: #6b7a8f;
--canvas: #ffffff;
--surface: #f8f9fb;
--hairline: #eef0f3;
/* ─── 字體 ─── */
--font-display: 'Inter', system-ui, sans-serif;
--font-body: 'Inter', system-ui, sans-serif;
/* ─── 字級 ─── */
--text-xs: 0.75rem;
--text-sm: 0.8125rem;
--text-base: 0.9375rem;
--text-lg: 1.125rem;
--text-xl: 1.5rem;
--text-2xl: 2rem;
--text-3xl: 3rem;
/* ─── 間距(8px 基線) ─── */
--space-1: 0.5rem;
--space-2: 1rem;
--space-3: 1.5rem;
--space-4: 2rem;
--space-5: 3rem;
--space-6: 4rem;
/* ─── 圓角 ─── */
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 16px;
/* ─── 陰影 ─── */
--shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
--shadow-md: 0 4px 12px rgba(0,0,0,0.06);
--shadow-lg: 0 8px 30px rgba(0,0,0,0.08);
}
這樣做的好處是:用戶想改顏色時,只需要修改 CSS 變數,而不需要翻遍整個專案找硬編碼的值。
第二步:組件架構
Layout 組件
Layout 是每個頁面的骨架。它應該盡量保持簡單:
---
// src/layouts/Layout.astro
interface Props {
title: string;
description?: string;
}
const { title, description } = Astro.props;
---
<!doctype html>
<html lang="zh-TW">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{title}</title>
<meta name="description" content={description} />
</head>
<body>
<slot />
</body>
</html>
可複用組件
遵循「一件事做好」原則:
Nav.astro— 只負責導航Footer.astro— 只負責頁尾Card.astro— 只負責卡片樣式Tag.astro— 只負責標籤渲染
每個組件不應該知道它之外的業務邏輯。
第三步:內容與樣式分離
Astro 的 style 標籤預設是 scoped 的——樣式只作用於當前組件。這讓你可以放心地為每個組件寫專屬樣式,而不擔心全域污染。
<!-- 這個 style 只影響這個組件 -->
<style>
.card {
padding: var(--space-3);
border-radius: var(--radius-md);
}
</style>
全域樣式(reset、設計 Token、基本排版)則放在 src/styles/global.css 中,在 Layout 中引入。
第四步:可自訂性
好的主題允許用戶在不安裝 fork 的情況下自訂:
- CSS 變數覆蓋:用戶可以在自己的
global.css中重新定義--primary等變數 - 組件 props:暴露重要配置(如導航連結、社交鏈接)作為 props
- Layout slots:使用
slot讓用戶可以注入自訂內容
---
// Nav.astro 支援自訂連結
interface Props {
links?: { href: string; label: string }[];
}
const { links = defaultLinks } = Astro.props;
---
<nav>
{links.map(link => <a href={link.href}>{link.label}</a>)}
<slot name="extra" />
</nav>
第五步:文件化
最後但同樣重要——為主題寫文件。至少包含:
- 設計 Token 列表及其作用
- 如何新增內容(文章格式範例)
- 如何自訂佈局
- 部署指南
結語
建立一個好的 Astro 主題不是在追求視覺上的華麗,而是在追求一致性、可維護性和可自訂性。設計系統是達成這些目標的工具,而不是目的本身。當你的設計 Token 和組件架構清晰時,無論是維護還是迭代都會輕鬆得多。