
(端起茶杯,吹了吹熱氣,慢條斯理地抿了一口溫熱的茶)
此時,夕陽斜斜地照在院落的泥土與老藤椅上,泛起一陣溫暖的 藤椅深棕 (Rattan Brown) 光澤。天空被染成了一片溫柔安詳的 晚霞暮紫 (Twilight Mauve)。大孫女正眉頭深鎖地盯著筆電螢幕,小孫女則在一旁抱著玩偶,歪著頭看著姐姐發愁。
阿公看著大孫女,呵呵笑著問:「怎麼啦,大妞?今天不是在整理你們課堂上學到的那些數據分析資訊圖嗎?怎麼看著螢幕直嘆氣呢?」
大孫女扁著嘴說:「阿公,我想把這 22 張精緻的零售分析資訊圖,做成跟實體書一模一樣、可以左右翻頁的流暢網頁。但我引入了網路上大家都在用的 Turn.js 等大型 3D 翻頁庫之後,網頁在舊手機上動起來卡得不得了,而且遇到手機這種直立式螢幕,版面完全跑掉,這要怎麼教給學校啊?」
阿公摸了摸大孫女的頭,說話不急不徐地開導她:
「現在的孩子們學寫網頁,總喜歡先去上網拿別人的工具來用(框架、第三方庫),但有時候那些工具就像是幾十斤重的大鐵耙,太沉了,反而把自己給絆倒了。阿公今天不講古,阿公教你用最乾淨、最不拖泥帶水的傳統手藝——CSS Grid 與 Vanilla JS(原生 JavaScript),手寫出一個極致流暢、不帶一絲贅肉的響應式 RWD 翻頁書。坐過來,聽阿公慢條斯理地跟你道來……」
大孫女剛才遇到的,正是許多網頁開發者最容易踩到的坑:
阿公常說,這就像我們下田挑水,水桶夠用、結實就好,你非要挑個千斤重的青銅古鼎去運水,這不是折騰自己嗎?既然我們的目標是流暢、輕量、離線可用,那最好的方法就是「純手寫」。
這個翻頁書專案,我們採用最乾淨的架構:一個 index.html 負責結構,一個 styles.css 負責排版與動畫,一個 script.js 負責所有的互動與狀態,不依賴任何外部框架。
這是解決手機版面跑掉的關鍵。我們要利用 CSS 的媒介查詢(Media Queries)設定一個斷點(例如 860px):
3-4 / 22 自動更新成單頁的 3 / 22,讓小螢幕使用者讀起來最舒服。ArrowLeft(上一頁)與 ArrowRight(下一頁),讓習慣用電腦鍵盤的讀者能順手操作。touchstart 與 touchend 事件,計算使用者手指水平滑動的距離(X軸位移)。阿公叮嚀:一定要設定一個滑動距離的門檻值,而且要過濾掉上下的垂直滑動,這樣客人在用手機上下滑動頁面時,才不會不小心誤觸到翻頁。在主閱讀區下方,我們要設計一個能呈現 22 張資訊圖的縮圖列:
active 狀態,點擊任何縮圖就能直接跳转到該頁。既然是精緻的資訊圖表,字體和數據有時會比較細。只要使用者點擊主閱讀區的圖片,就開啟全螢幕的 Lightbox。
body 加上 overflow: hidden),這樣使用者滑動放大圖時,背景才不會跟著亂動。大孫女拉著阿公的衣袖問:「阿公,那翻頁動畫在一些比較舊、比較便宜的手機上,如果卡顿(掉幀)怎麼辦?」
阿公神色認真了起來,拍了拍手,指著筆電說:
「這就是很多年輕工程師常踩的雷了。大家在寫位移動畫時,很喜歡用 left 或是 margin-left 來做位置移動。這可是大忌!」
left 或 margin?transform: translateX(),因為 transform 只會觸發瀏覽器的合成(Composite)階段,不影響幾何佈局。.page-container {
will-change: transform;
}
這行程式碼就像是「提前跟手機的顯卡晶片打招呼」,強迫瀏覽器將這個元素交給 GPU(圖形處理器)進行硬體加速。這樣一來,即使在老舊、低階的手機上運行,翻頁動效依然能像抹了麻油一樣,無比滑溜!「既然是大孫女做的精緻作業,咱們網頁的顏色也要配得舒服、有家的感覺。」阿公呵呵笑著,指了指天邊正要落下的太陽。
我們可以使用這套代表阿公院子的 「溫馨夕陽院落 (Warm Twilight Courtyard)」 專屬配色,透過 CSS 變數來管理:
--bg-light: #F4F1EA —— 採用白髮銀霜 (Silver Hair),像阿公花白頭髮一樣和藹、溫柔,不傷眼睛。--bg-dark: #98849F —— 採用晚霞暮紫 (Twilight Mauve),像傍晚的餘暉,給人寧靜、懷舊的沈浸閱讀感。--text-primary: #6B584C —— 採用藤椅深棕 (Rattan Brown),如院子裡老藤椅的色澤,確保淺色模式下字體對比清晰、好閱讀,絕對不會出現白底白字的尷尬狀況。--accent-color: #C88B52 —— 採用琥珀熱茶 (Amber Tea),像阿公手裡這杯溫潤的熱茶,用於上一頁/下一頁和重要按鈕。--accent-soft: #DFA8A6 —— 採用稚嫩粉櫻 (Soft Blossom),用於縮圖 active 時的亮麗框線,就像你們兩姊妹一樣活潑有朝氣。同時,我們要在網頁裡做一個深淺色切換(Dark/Light Mode)按鈕,並用 localStorage 把它牢牢記在瀏覽器裡,下次客人打開時,就會自動套用他最喜歡的主題。
「大妞啊,做事要給自己留一條退路(後路)。萬一客人的瀏覽器比較舊,或者因為資安規定關掉了 JavaScript 功能,你的網頁難道就要變成一片死寂、什麼都看不到嗎?」
這時候,阿公教你用原生 HTML 的 <noscript> 標籤來做「優雅降級」:
<noscript>
<div class="noscript-fallback-gallery">
<h2>全部零售分析資訊圖一覽</h2>
<!-- 這裡直接把 22 張圖用簡單的 <img> 列表全部排出來 -->
<img src="infographics/01.png" alt="資訊圖 1">
<img src="infographics/02.png" alt="資訊圖 2">
<!-- ...以此類推 -->
</div>
</noscript>
當客人的瀏覽器不執行 JS 時,我們的網頁會自動停用翻頁和燈箱功能,改為把所有圖片整整齊齊地列出來,讓客人可以用最傳統的滑鼠滑動,安安靜靜地把 22 張精彩的圖表讀完。這份體貼的心意,就是最頂級的網頁設計素養!
此時,旁邊愛撒嬌的小孫女揉了揉眼睛,拉著老爺爺的衣角,靠在阿公花白的頭髮旁,聲音黏糊糊地說著她也想聽故事。
老爺爺一邊輕輕拍著小孫女的肩膀,一邊對大孫女笑著說:
「好啦,大妞。聽完阿公跟你嘮叨這些 CSS 與 GPU 的土方法,是不是覺得,其實根本不用去裝那些幾十 MB 的外國大型庫了?寫程式啊,就跟我們在院子裡搭菜園的棚架是一樣的。用最乾淨、最少卻最結實的木頭和麻繩(CSS Grid + Vanilla JS),反而最能耐得住風雨摧折。去吧,去把網頁寫好,阿公等著等一下看你的翻頁書動起來。」
大孫女眼睛發亮,用力地點點頭,神采奕奕地在筆電前開始敲起了代碼……