📱 第十三章:RWD 響應式設計與魔術漢堡選單
你花了好幾個小時,在你的 27 吋螢幕上把露營網站雕琢得美輪美奐。 然後你興高采烈地傳給老闆,老闆用 iPhone 點開網址,眉頭一皺:「這什麼鬼?文字全部疊在一起,圖片也超出去螢幕了!」
這就是所有前端工程師的惡夢:沒有做響應式設計 (Responsive Web Design, 簡稱 RWD)。
在過去,要讓網站適應手機、平板、電腦三種螢幕,你需要寫好幾個 media query CSS 檔案,非常痛苦。
但現在,我們有 Tailwind CSS!加上 AI 的輔助,RWD 將變成一塊小蛋糕。
這堂課,我們將用 5 個 Vibe Prompt,教你如何一秒修復手機版破版,並實作出那個經典的「漢堡選單 (Hamburger Menu)」!
📐 實戰 1:掌握 Tailwind 的斷點魔法
在 Tailwind 中,最核心的 RWD 概念就是加上前綴字:
- 什麼都沒加 (預設) = 手機版 (Mobile-first 思維)
md:= 平板版 (Medium)lg:= 電腦版 (Large)
💡 Vibe Prompt 實戰 1:一秒解決文字擠成一團的問題
[!IMPORTANT] 請複製以下 Prompt 傳送給 AI:
我在設計露營網站的標題。目前的 class 是:text-6xl font-bold text-center在電腦上看很霸氣,但在手機上看,字體太大直接超出版面了!請幫我用 Tailwind 的 RWD 寫法 (sm, md, lg) 來修改。需求:1. 手機版 (預設) 時字體小一點,用 text-3xl。2. 平板以上 (md:) 用 text-5xl。3. 電腦以上 (lg:) 用 text-7xl。請直接給我修改後的那一行 div。
🤖 AI 生成的響應式程式碼:
<!-- 舊的寫法:手機直接爆版 -->
<h1 class="text-6xl font-bold text-center">探索未知的營地</h1>
<!-- 🔥 AI 修改後的 RWD 寫法:隨螢幕自動縮放! -->
<h1 class="text-3xl md:text-5xl lg:text-7xl font-bold text-center">探索未知的營地</h1>
🔍 深度解析:
這就是「Mobile-first (手機優先)」思維。我們一開始設定的 text-3xl 是給手機看的。當螢幕變大,跨過 md: (平板) 的斷點時,Tailwind 就會自動把它覆蓋成 text-5xl。你再也不用自己去寫複雜的 @media (min-width: 768px) 了!
🍔 實戰 2:從無到有打造「魔術漢堡選單」
在電腦版,我們的導覽列 (Navbar) 有很多按鈕:「首頁」、「營地列表」、「登入」、「註冊」,它們可以橫排顯示。 但在手機版,寬度根本不夠塞!這時候,我們需要一個「三條線的漢堡圖示 (Hamburger Icon)」。點擊它,選單才會滑出來。
這牽涉到 React 的狀態 (State) 切換。這對新手來說很難,但對 AI 來說易如反掌。
💡 Vibe Prompt 實戰 2:指揮 AI 寫出有邏輯的漢堡選單
[!IMPORTANT] 請複製以下 Prompt 傳送給 AI:
我要用 React 實作一個導覽列 (Navbar)。需求如下:1. 在電腦版 (md: 以上),選單連結 ("首頁", "探索", "登入") 橫向排列在右側。2. 在手機版,隱藏這些連結,並顯示一個「漢堡圖示按鈕 (三條水平線)」。3. 請使用 useState 宣告一個 isOpen 的狀態,預設為 false。4. 當點擊漢堡按鈕時,切換 isOpen 的狀態。5. 如果 isOpen 為 true,請在導覽列下方顯示一個滿版寬度的直向選單。請給我完整的 React 元件程式碼。
🤖 AI 生成的真實程式碼 (結構解析):
import React, { useState } from 'react';
export default function Navbar() {
// 控制手機版選單開關的靈魂!
const [isOpen, setIsOpen] = useState(false);
return (
<nav className="bg-zinc-900 border-b border-zinc-800 p-4">
<div className="max-w-6xl mx-auto flex justify-between items-center">
{/* 左側 Logo */}
<div className="text-xl font-bold text-white">🏕️ 露營趣</div>
{/* 電腦版選單 (手機隱藏 md:flex,只有平板以上才顯示) */}
<div className="hidden md:flex gap-6 text-zinc-300">
<a href="#" className="hover:text-white">首頁</a>
<a href="#" className="hover:text-white">探索</a>
<a href="#" className="hover:text-white">登入</a>
</div>
{/* 手機版漢堡按鈕 (平板以上隱藏 md:hidden) */}
<button
className="md:hidden text-white text-2xl"
onClick={() => setIsOpen(!isOpen)}
>
{/* 如果打開就顯示 ✕,關閉就顯示 ☰ */}
{isOpen ? "✕" : "☰"}
</button>
</div>
{/* 手機版的直向下拉選單 (條件渲染:如果 isOpen 是 true 才顯示) */}
{isOpen && (
<div className="md:hidden mt-4 flex flex-col gap-4 text-center pb-4 text-zinc-300">
<a href="#" className="hover:text-white border-b border-zinc-800 pb-2">首頁</a>
<a href="#" className="hover:text-white border-b border-zinc-800 pb-2">探索</a>
<a href="#" className="hover:text-white pb-2">登入</a>
</div>
)}
</nav>
);
}
✨ 實戰 3:太生硬了!給選單加上 Framer Motion 動畫
上面的漢堡選單可以運作,但它的出現方式是「瞬間閃現」,非常沒有高級感。 身為高質感的 Vibe Coder,我們不允許這種生硬的體驗存在。 我們將請出 React 動畫界的霸主:Framer Motion,讓選單用「滑出」的方式優雅登場!
💡 Vibe Prompt 實戰 3:注入百萬級滑順動畫
[!IMPORTANT] 請複製以下 Prompt 傳送給 AI:
我剛剛寫好了手機版的直向選單 (isOpen 控制顯示)。但它是瞬間出現的,太生硬了。請幫我引入 'framer-motion' 庫 (使用 <AnimatePresence> 和 <motion.div>)。我要讓手機版選單出現時,有以下動畫效果:1. 初始狀態 (initial):高度為 0,透明度為 0 (opacity: 0, height: 0)2. 出現狀態 (animate):高度為 auto,透明度為 1 (opacity: 1, height: "auto")3. 消失狀態 (exit):回到高度 0,透明度 0請幫我修改剛才的 Navbar 元件。
🤖 AI 動畫大師出手:
import React, { useState } from 'react';
// 🔥 引入 Framer Motion 動畫神器
import { motion, AnimatePresence } from 'framer-motion';
export default function Navbar() {
const [isOpen, setIsOpen] = useState(false);
return (
<nav className="bg-zinc-900 border-b border-zinc-800 p-4 relative z-50">
{/* ...上面的 Logo 區塊跟按鈕都不變... */}
{/* 使用 AnimatePresence 包裝,這是讓組件「消失時也能有動畫」的關鍵 */}
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.3, ease: "easeInOut" }}
className="md:hidden overflow-hidden mt-4 flex flex-col gap-4 text-center text-zinc-300"
>
{/* 選單內容 */}
<div className="py-4 space-y-4">
<a href="#" className="block hover:text-white">首頁</a>
<a href="#" className="block hover:text-white">探索</a>
<a href="#" className="block hover:text-white">登入</a>
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
);
}
🔍 深度解析: 看到了嗎?這就是價值所在!一般的新手工程師,光是為了解決「高度 0 變成 auto 的動畫無效」這個 CSS 千古難題,就會卡上三天三夜。 但你透過使用 Framer Motion 加上 AI 輔助,只要一兩分鐘,就產出了一個像是蘋果官網一樣滑順的手機下拉選單!
🚫 終極避坑指南:Z-index 疊加地獄
做了漂亮的漢堡選單下拉,最常發生的災難就是:「選單滑出來了,結果被下面的地圖或是圖片擋住!」 使用者想點「登入」,卻按到了後面的「放大地圖」按鈕。
這是因為 CSS 中的 z-index (層級) 沒有設定好。
💡 Vibe Prompt 實戰 4:解決選單被遮擋的問題
[!IMPORTANT] 請複製以下 Prompt 傳送給 AI:
我的 Navbar 漢堡選單打開時,下拉的內容被下方的一個 Leaflet 地圖區塊遮擋住了!我該怎麼用 Tailwind 的 class 來確保我的 Navbar 永遠處於畫面的最上層?請給我修改 <nav> 標籤的具體 Class 建議。
🤖 AI 的排版急救:
<!-- ❌ 舊的寫法:層級不夠,被地圖吃掉 -->
<nav class="bg-zinc-900 p-4">
<!-- ✅ 正確寫法:加入 relative 或 fixed,並賦予極高的 z-index -->
<nav class="bg-zinc-900 p-4 relative z-[999]">
<!--
【AI 深度解析】:
z-index (層疊順序) 就像是千層派。數字越大的在越上面。
Leaflet 地圖或某些絕對定位的圖片,預設會有 z-index (例如 400)。
如果你沒有為 Navbar 設定 z-index,它就會被地圖蓋過去。
加上 `relative z-[999]` 可以確保導覽列無論如何都在最高層級!
-->
🔒 進階體驗優化:防止選單打開時背景滾動
還有一個高級網站的隱藏細節:當手機版漢堡選單滿版打開時,如果你手滑動螢幕,背後的網站內容不應該跟著捲動!這會讓人覺得網站很廉價。
💡 Vibe Prompt 實戰 5:封鎖背景滾動
[!IMPORTANT] 請複製以下 Prompt 傳送給 AI:
當我的手機版漢堡選單打開 (isOpen 為 true) 時,我不希望使用者可以滾動背後的整個網頁。請幫我寫一段 React 的 useEffect 邏輯。當 isOpen === true 時,將 body 的 overflow 設為 'hidden'。當 isOpen === false 或是元件解除安裝時,將 body 的 overflow 恢復為 'auto'。
🤖 AI 的細節體驗升級:
// 放在 Navbar 元件內
useEffect(() => {
if (isOpen) {
// 鎖死背景,禁止滾動
document.body.style.overflow = 'hidden';
} else {
// 恢復正常滾動
document.body.style.overflow = 'auto';
}
// 💡 清理函數 (Cleanup function):
// 確保當使用者切換頁面、或是 Navbar 被銷毀時,不會把背景永遠鎖死
return () => {
document.body.style.overflow = 'auto';
};
}, [isOpen]); // 當 isOpen 改變時,這個 Effect 就會觸發
✅ 本章總結與實戰落幕
恭喜你完成了這門 露營官方網站架設 (Camping Official Site) 的全部 13 個章節! 我們從最基礎的 Astro 設定,一路做到了:
- 資料庫串接 (Supabase)
- 高階玻璃擬態排版 (Bento Grid)
- 百萬級過場動畫 (Framer Motion)
- 完美的手機適應與細節優化 (RWD + Scroll Lock)
現在,你不僅僅是完成了一個玩具專案,你是完成了一個**「可以拿去賣給真實客戶」的高級 SaaS 官網雛形。**
這就是 Vibe Coding 的精髓。你不必去背誦 z-index 的預設值,也不必手寫 overflow: hidden。你只需要知道**「什麼樣的細節能讓網站看起來昂貴?」** (例如:防止背景滾動、加入平滑動畫)。
當你知道了這些「商業上的需求」,你就能用精準的 Prompt 指揮 AI 幫你寫出這些程式碼。
如果你準備好挑戰更有趣的互動邏輯,歡迎進入下一個進階專案:露營定點地圖與資訊導購 (Map & AI Articles)。我們將教你如何在地圖上撒點,並串接 AI 讓它幫你自動寫露營推薦文章!我們下堂課見!