Linear: 軟體設計的新標準
Linear如何成為現代軟體的設計標準:鍵盤優先UX、樂觀UI、命令面板和深色模式。包含CSS和TypeScript實作模式。
Linear:軟體設計的新標準
「軟體應該有主見且快速。」— Karri Saarinen,Linear 執行長
Linear 是一款專案管理工具,重新定義了現代軟體的使用體驗。由前 Uber 和 Airbnb 設計師於 2019 年推出,它證明了 B2B 軟體不必醜陋或緩慢。
為何 Linear 如此重要
Linear 是對臃腫、由委員會設計的企業軟體的一次設計宣言。它展示了當設計師為設計師打造產品時會發生什麼。
主要成就: - 讓企業軟體擁有消費級軟體的體驗 - 證明了鍵盤優先的介面也能很美觀 - 展示了效能本身就是一項功能 - 為 SaaS 產品品質樹立了新標竿
重點摘要
- 速度是功能,不只是指標 - Linear 對低於 100 毫秒互動的執著證明了感知效能能創造情感共鳴
- 鍵盤優先意味著進階用戶獲勝 - 命令面板(Cmd+K)和助記快捷鍵(S 代表 Status,P 代表 Priority)讓專家加速操作,同時不阻礙新手
- 資訊密度勝過留白 - 用更少的裝飾展示更多資料;透過懸停顯示細節,而非隱藏在點擊後面
- 深色模式作為主要體驗 - 以深色模式為優先設計,創造高級質感並減少進階用戶的眼睛疲勞
- 樂觀 UI 消除等待 - 先在本地更新,在背景同步,只在錯誤真正發生時才顯示
核心設計原則
1. 速度即功能
Linear 對速度有著近乎偏執的追求。每個互動都感覺即時。
他們如何實現: - 樂觀 UI 更新(假設成功,失敗時回滾) - 本地優先架構 - 積極快取 - 最小化網路請求
實作洞察:
// Optimistic update pattern
function updateIssue(id: string, changes: Partial<Issue>) {
// 1. Update local state immediately
localStore.update(id, changes)
// 2. Show success state
ui.showSaved()
// 3. Sync with server in background
api.updateIssue(id, changes).catch(() => {
// 4. Rollback only on failure
localStore.rollback(id)
ui.showError()
})
}
設計應用: - 載入狀態應盡可能不可見 - 只在必要時使用骨架畫面 - 永遠不要阻止用戶進行下一個操作
2. 鍵盤優先,滑鼠友善
Linear 為進階用戶設計,但對新手同樣友善。
命令面板(Cmd+K): - 所有操作的統一入口 - 對所有內容進行模糊搜尋 - 可發現鍵盤快捷鍵 - 永遠不需要離開鍵盤
┌────────────────────────────────────────────────────────────┐
│ Cmd+K │
├────────────────────────────────────────────────────────────┤
│ > Search issues, projects, or commands... │
│ │
│ Recent │
│ ├─ FE-123 Fix navigation animation Cmd+O │
│ ├─ BE-456 API rate limiting Cmd+O │
│ └─ Create new issue C │
│ │
│ Commands │
│ ├─ Change status S │
│ ├─ Assign issue A │
│ └─ Set priority P │
│ │
└────────────────────────────────────────────────────────────┘
實作原則: - 每個操作都有鍵盤快捷鍵 - 快捷鍵採用助記法(S 代表 Status,P 代表 Priority) - 滑鼠完美運作,鍵盤更快 - 說明永遠只需一個按鍵
3. 恰到好處的資訊密度
Linear 展示大量資訊卻不顯得雜亂。
他們如何平衡密度:
CLUTTERED (typical enterprise):
┌────────────────────────────────────────────────────────────┐
│ [ ] * FE-123 | Fix bug | John | High | In Progress | 2d │
│ Tags: frontend, urgent, sprint-12, reviewed │
│ Created: Jan 1 | Updated: Jan 5 | Due: Jan 10 │
│ Comments: 5 | Attachments: 2 | Subtasks: 3/5 │
├────────────────────────────────────────────────────────────┤
│ [ ] * FE-124 | Another bug | Jane | Medium | Todo | 1d │
│ ... (repeating all metadata) │
└────────────────────────────────────────────────────────────┘
LINEAR'S APPROACH:
┌────────────────────────────────────────────────────────────┐
│ [x] FE-123 Fix navigation animation bug ^ John ** │
│ [ ] FE-124 Update user profile endpoint Jane * │
│ [x] FE-125 Add dark mode toggle ^ Alex ***│
└────────────────────────────────────────────────────────────┘
^ ^
Priority Assignee Estimate
(caret) (name) (dots)
原則: - 每個層級只顯示所需內容 - 使用圖示和符號取代文字標籤 - 懸停/選取時顯示細節 - 按需漸進式揭露
4. 一致的視覺語言
Linear 的設計系統嚴謹且一致。
色彩系統:
/* Linear-inspired semantic colors */
:root {
/* Status colors - highly saturated, distinct */
--status-backlog: #6B7280; /* Gray - not started */
--status-todo: #3B82F6; /* Blue - ready */
--status-progress: #F59E0B; /* Amber - in work */
--status-done: #10B981; /* Green - complete */
--status-cancelled: #EF4444; /* Red - cancelled */
/* Priority - consistent hue shift */
--priority-urgent: #EF4444; /* Red */
--priority-high: #F97316; /* Orange */
--priority-medium: #EAB308; /* Yellow */
--priority-low: #6B7280; /* Gray */
--priority-none: #374151; /* Dark gray */
/* Surface hierarchy */
--bg-primary: #0D0D0D; /* Main background */
--bg-elevated: #141414; /* Cards, panels */
--bg-hover: #1F1F1F; /* Hover states */
--bg-active: #292929; /* Active/selected */
}
字體排版:
/* Linear uses Inter for everything */
:root {
--font-family: 'Inter', -apple-system, sans-serif;
/* Tight scale, high readability */
--text-xs: 11px; /* Metadata */
--text-sm: 12px; /* Secondary */
--text-base: 13px; /* Body (smaller than typical) */
--text-lg: 14px; /* Emphasis */
--text-xl: 16px; /* Headings */
--text-2xl: 20px; /* Page titles */
}
5. 預設深色模式
Linear 選擇深色模式作為主要體驗。
為何這樣做有效: - 減少進階用戶的眼睛疲勞(長時間使用) - 創造高級、專注的美學 - 讓狀態顏色更加突出 - 與開發者工具的美學一致
實作:
/* Dark-first design */
:root {
color-scheme: dark;
--text-primary: rgba(255, 255, 255, 0.95);
--text-secondary: rgba(255, 255, 255, 0.65);
--text-tertiary: rgba(255, 255, 255, 0.45);
--border-default: rgba(255, 255, 255, 0.08);
--border-hover: rgba(255, 255, 255, 0.12);
}
/* Light mode as override */
[data-theme="light"] {
--text-primary: rgba(0, 0, 0, 0.90);
--text-secondary: rgba(0, 0, 0, 0.60);
/* ... */
}
6. 令人愉悅的微互動
Linear 中的每個互動都經過深思熟慮。
範例: - Issue 卡片在滑鼠懸停時會微微上浮 - 狀態變更有細膩的顏色過渡效果 - 拖放功能具有流暢、符合物理原則的動態效果 - 核取方塊點擊後有令人滿足的回饋感
動畫原則:
/* Linear's motion */
:root {
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
--duration-fast: 100ms; /* Micro feedback */
--duration-normal: 150ms; /* Standard transitions */
--duration-slow: 250ms; /* Page transitions */
}
.issue-card {
transition:
transform var(--duration-fast) var(--ease-out),
box-shadow var(--duration-normal) var(--ease-out);
}
.issue-card:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
值得學習的設計模式
指令面板
Linear 的 Cmd+K 現已成為現代軟體的標準模式。
實作指南:
<!-- Command palette structure -->
<dialog class="command-palette" aria-label="Command menu">
<header>
<input
type="text"
placeholder="Search issues or commands..."
aria-describedby="command-hint"
/>
</header>
<nav aria-label="Command results">
<section aria-label="Recent">
<h3>Recent</h3>
<ul role="listbox">
<li role="option" tabindex="0">
<span class="issue-id">FE-123</span>
<span class="issue-title">Fix bug</span>
<kbd>Cmd+O</kbd>
</li>
</ul>
</section>
<section aria-label="Commands">
<h3>Commands</h3>
<!-- ... -->
</section>
</nav>
</dialog>
情境選單
右鍵選單精準顯示你所需的功能。
Right-click on issue:
┌────────────────────────────────┐
│ Open issue Cmd+O │
│ Open in new tab Cmd+Shft+O │
├────────────────────────────────┤
│ Set status S │
│ Set priority P │
│ Assign A │
├────────────────────────────────┤
│ Copy link Cmd+C │
│ Copy ID │
├────────────────────────────────┤
│ Delete Backspace│
└────────────────────────────────┘
行內編輯
無需彈出對話框即可編輯。
BEFORE (click to edit):
┌────────────────────────────────────────┐
│ Fix navigation bug [Edit] │
└────────────────────────────────────────┘
AFTER (inline edit on click):
┌────────────────────────────────────────┐
│ Fix navigation bug| │ ← Cursor appears
│ ────────────────── │ in place
└────────────────────────────────────────┘
從 Linear 借鑒的精華
適用於任何軟體專案
- 速度是不可妥協的 - 優化感知效能與實際效能
- 處處皆有鍵盤快捷鍵 - 但不強制使用
- 指令面板 - 統一的功能入口
- 正確實作深色模式 - 不是事後補上的功能
- 資訊密度 - 以更少的空間呈現更多內容
- 一致的設計語言 - 每個元素都有關聯性
具體技巧
| 技巧 | 應用方式 |
|---|---|
| 樂觀式 UI | 先在本地更新,背景同步 |
| 模糊搜尋 | 在指令面板使用 Fuse.js 或類似工具 |
| 助記快捷鍵 | S 代表 Status,P 代表 Priority,A 代表 Assign |
| 細微浮起效果 | 懸停時上浮 1-2px,而非誇張的陰影 |
| 語義化顏色 | 一致的狀態/優先級顏色系統 |
| 緊湊的字體排版 | 13px 內文字體,密集但清晰可讀 |
Linear 團隊的經典語錄
「我們將速度視為一項功能。如果某個操作需要 300ms,那感覺就是壞掉了。」
「每個像素都應該是有意圖的。如果你無法解釋某個元素存在的原因,就移除它。」
「鍵盤優先不代表只能用鍵盤。它意味著尊重進階使用者。」
常見問題
是什麼讓 Linear 比其他專案管理工具更快?
Linear 採用樂觀式 UI 更新、本地優先架構和積極的快取策略。當你變更 issue 狀態時,UI 會立即更新,同步則在背景進行。大多數互動感覺是即時的,因為 Linear 預設操作會成功,只在發生錯誤時才顯示錯誤訊息,而非阻塞等待網路請求。
Linear 的指令面板 (Cmd+K) 如何運作?
指令面板是一個統一入口,透過模糊搜尋橫跨 issues、專案和指令。它支援助記鍵盤快捷鍵(S 代表 Status,P 代表 Priority,A 代表 Assign),使用者可以透過面板發現這些快捷鍵,然後直接使用而無需開啟面板。這創造了從新手到進階使用者的漸進式學習路徑。
為什麼 Linear 選擇深色模式作為預設?
Linear 的設計目標是長時間使用應用程式的進階使用者。深色模式減少眼睛疲勞,創造出有別於典型企業軟體的高級質感,並讓狀態顏色更加鮮豔。淺色模式作為替代選項存在,但深色模式才是主要的設計目標。
Linear 如何在高資訊密度下避免雜亂感?
Linear 使用符號和圖示取代文字標籤,在列表層級只顯示必要的中繼資料,並在滑鼠懸停或選取時才揭示詳細資訊。字體排版比一般更緊湊(13px 內文字體),一致的間距創造視覺節奏,同時不浪費留白空間。
Linear 對鍵盤快捷鍵的設計理念是什麼?
Linear 中的每個操作都有鍵盤快捷鍵,而且快捷鍵具有助記性(容易記憶)。指令面板會在每個操作旁顯示對應的快捷鍵,藉此教導使用者。這意味著滑鼠使用者可以順利操作,但鍵盤使用者可以工作得更快。設計理念是「鍵盤優先,滑鼠友善」。
資源
- 官方網站: linear.app
- 更新日誌: Linear 的更新日誌本身設計精美
- 部落格: 團隊的工程與設計文章
- Twitter: @linear 獲取設計更新