技術說明

這個網站怎麼做的

介面背後的決定,以及它們的代價。

技術棧

Next.js 16(App Router)、TypeScript、Tailwind CSS v4、Framer Motion、next-intl,表單寄信用 Resend,附件存在 Supabase,部署在 Vercel。沒有使用任何 UI 元件庫——這裡的每一個元件都是為這個網站寫的,因為元件庫會帶進自己的視覺預設,而那些預設正是讓網站長得都一樣的原因。

設計系統

七個色彩 token、六級字階、一套間距量表,整個系統就這些。而且它是被強制執行的,不只是寫在文件裡:色票只在一處以 CSS 變數定義,程式碼中沒有任何地方引入這之外的顏色——包括 hover 狀態,那裡改的是透明度,而不是另外調一個色階。

強調色取自狀態燈的語彙,是琥珀而非科技網站慣用的螢光色,全站只出現七次。用得比這更頻繁,它就不再是強調。

字體在大標走 Archivo 的展寬軸,內文用 Inter Tight,讀數與標籤用 JetBrains Mono。Archivo 沒有漢字,所以中文版把寬軸關掉,改用讀者系統上的字型,並把字距放開一點——拉丁大標是收緊的,方塊字沿用會擠。這個決定的代價寫在下面的效能一節。

狀態列

視窗底部那條細長的列,是這裡唯一允許張揚的元素。它回報目前哪個區塊佔據視窗——編號與頁面本身共用同一份資料來源——以及捲動位置。

讀數是捲動時當場量出來的:看哪個區塊蓋住視窗最多,而不是用一條觸發線,因為區塊比螢幕高。這條列活在版面層,換頁不會重建,所以它不能持有任何節點——監看器會一直抓著上一頁的區塊,換回來就再也不回報。在沒有區塊的頁面上——案例詳頁、這一頁——它什麼都不報,不留一個過期的讀數。

動效

全站每一個進場動畫都走同一個元件。區塊不各自帶動效設定,頁面長大之後節奏還能一致,靠的就是這件事。

它只有三條規則。大型視覺區塊重新進入時重播,純文字段落只播一次,所以回頭再讀不會閃爍。動畫只在向下捲動時播放;往回捲時內容照樣顯示,但不帶動作,因為倒著跑的動畫看起來像壞了。開啟 prefers-reduced-motion 時,所有位移換成單純的淡入,狀態燈也停止脈動。

捲動本身交給瀏覽器。這裡曾經用過平滑捲動的函式庫,但它會接管捲動位置,和瀏覽器自己的還原打架:從首頁中段點進案例,畫面會停在最下方;返回時位置也不準。拿掉之後這些狀況一併消失,而錨點連結與回到頂端仍然是平滑的——那兩件事原生就做得到。

內容與語言

沒有任何顯示字串寫死在元件裡。介面文字放在語言檔,長篇內容——案例、這一頁——放在 MDX,一個語言一個檔。中文與英文是各自撰寫而非互相翻譯,所以兩邊讀起來都不像譯文。

切換語言會留在你正在讀的那一頁,包括個別案例,而且會記住你的選擇。

無障礙

焦點框永遠看得見:強調色、兩像素。每個表單控制項都與標籤綁定,錯誤欄位會被朗讀,錯誤訊息寫的是怎麼修好。常見問題的折疊區帶著該有的展開狀態與對應關係。內文與底色的對比是 7.3:1,最亮的文字是 16.3:1,都超過 4.5:1 的要求。

附件的選擇按鈕是自己畫的。原生檔案欄位的按鈕文字跟著瀏覽器語言走,英文版的讀者用中文系統就會看到中文,所以把它藏起來,焦點框改落在看得見的那顆按鈕上。

關閉 JavaScript 時頁面仍然可讀:所有動畫的隱藏起始狀態會被覆寫,常見問題的答案直接展開,因為沒有腳本就打不開。

效能

在正式網域上量測,不是本機——本機的模擬節流給出的數字好看,但不成立。行動裝置設定,也就是 Lighthouse 的預設,不是分數比較高的桌機模式。

之前現在
Performance7194
Accessibility100100
Best practices100100
SEO100100
First contentful paint1.7 秒1.2 秒
Largest contentful paint8.1 秒2.8 秒
Cumulative layout shift00
頁面總傳輸量1,434 KB422 KB

幾乎全部來自兩個改動。

第一個是開場的主標與副標。它們原本由 JavaScript 負責顯示,所以瀏覽器必須等整包程式下載、解析、執行完才畫得出來——在慢速手機上就是一秒的空白,而那些文字其實早就在 HTML 裡了。這些進場改由 CSS 執行,外觀與時間參數完全一樣,但它們在第一次繪製時就開始。

第二個是中文字體。漢字字型會被切成上百段 unicode range,這個網站用到其中 18 段,也就是 18 個檔案、1,149 KB,佔整頁重量的八成。現在中文交給讀者自己系統上的字型:macOS 與 iOS 是蘋方,Windows 是微軟正黑,Android 是 Noto Sans CJK。三套都是為螢幕調校過的字型,而且下載量是零。留下的三個字型檔全是拉丁文,合計 172 KB。

代價是中文在不同系統上不會長得一模一樣。對一個要讓人在手機上快速讀完的網站,這筆交換划算。

開場右側那個裝置網格是純 CSS 與元件狀態——沒有圖片、沒有影片,沒有東西要下載。