iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
Modern Web

Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站系列 第 5

Day 5 RWD 響應式網頁設計 – 讓自我介紹頁在各裝置都好看

  • 分享至 

  • xImage
  •  

今日目標

建立 行動優先(mobile-first) 的 RWD 思維

掌握三大關鍵:流式排版、彈性圖片、媒體查詢

套用到你的履歷網站(Hero、導覽列、技能網格、作品卡片、表單)

基礎概念

  1. 行動優先(Mobile-first)

先確保 **最小裝置(手機)**好用,再往較大螢幕加上「增強樣式」。做法:

預設樣式寫給手機

透過 @media (min-width: …) 逐步加強

  1. 流式排版(Fluid layout)

避免固定寬度,用百分比、max-width、min()、clamp() 讓寬高隨容器改變。

  1. 彈性媒體(Fluid media)

圖片與影片需避免超出容器:img { max-width: 100%; height: auto; }

  1. 斷點(Breakpoints)

不是背規格,是「內容斷點」。一般可從:

480px(小手機)

768px(平板)

1024px(小筆電)

1280px(桌機)
開始調整,實務上視你的版面微調。

實作

以下以你目前的檔案結構為基礎(index.html + styles/style.css)。若你前幾天已建立 :root tokens、.container、.section 等,可直接覆蓋/增量。

  1. 全域基線:字體、容器、圖片彈性(mobile-first)
    :root{
    --container: 1100px;
    --space: 16px;
    --h1: clamp(24px, 6vw, 40px);
    --h2: clamp(20px, 4.5vw, 28px);
    --h3: clamp(18px, 4vw, 22px);
    }

/* 行動裝置為預設 */
{ box-sizing: border-box; }
html,body{ height: 100%; }
body{ margin:0; line-height:1.7; font-family: system-ui, -apple-system, "Noto Sans TC", Arial, sans-serif; }
img{ max-width:100%; height:auto; display:block; } /
彈性圖片 */

.container{
max-width: var(--container);
margin: 0 auto;
padding: 0 20px;
}

/* 流式標題尺寸(不需大量 media queries) */
h1{ font-size: var(--h1); margin: 0 0 8px; }
h2{ font-size: var(--h2); margin: 0 0 8px; }
h3{ font-size: var(--h3); margin: 0 0 6px; }

  1. 導覽列:手機直向堆疊 → 平板以上橫列
    .site-header{
    position: sticky; top:0; background: var(--bg, #fff);
    border-bottom: 1px solid #e5e7eb; z-index: 10;
    }
    .site-header .container{
    display:flex; align-items:center; gap:12px; padding:12px 20px;
    }
    .brand{ text-decoration:none; font-weight:700; color:inherit; }

/* 手機:導覽列縱向+可換成漢堡(先用簡單版本) */
.site-nav ul{
list-style:none; margin: 8px 0 0; padding:0;
display:flex; flex-direction: column; gap:8px;
}
.site-nav a{ color:inherit; text-decoration:none; padding:6px 8px; border-radius:8px; }
.site-nav a:focus{ outline: 2px solid #2563eb; outline-offset:2px; }

/* >=768px:導覽列橫向 */
@media (min-width:768px){
.site-nav ul{ flex-direction: row; margin:0 0 0 auto; gap:16px; }
}

  1. Hero:小裝置單欄 → >=900px 兩欄
    .hero{ padding: 40px 0; display:grid; gap:20px; }
    .hero-cta{ display:flex; flex-wrap:wrap; gap:10px; margin-top: 12px; }
    .hero-photo{ justify-self:center; text-align:center; }
    .hero-photo img{ border-radius:50%; border:4px solid #e5e7eb; }

/* >=900px:兩欄 */
@media (min-width:900px){
.hero{ grid-template-columns: 1.2fr .8fr; align-items:center; }
.hero-photo{ justify-self:end; }
}

  1. 技能網格:1 欄 → 2 欄 → 3 欄
    .skill-grid{
    list-style:none; padding:0; margin:16px 0 0;
    display:grid; grid-template-columns: 1fr; gap:12px;
    }
    .skill-grid li{ border:1px solid #e5e7eb; border-radius:12px; padding:12px; }

/* >=520px:2 欄 /
@media (min-width:520px){
.skill-grid{ grid-template-columns: repeat(2,1fr); }
}
/
>=900px:3 欄 */
@media (min-width:900px){
.skill-grid{ grid-template-columns: repeat(3,1fr); }
}

  1. 作品卡片:手機單欄 → 平板雙欄
    .project-grid{
    display:grid; gap:16px; margin-top: 12px;
    grid-template-columns: 1fr; /* 手機單欄 */
    }
    .card{ border:1px solid #e5e7eb; border-radius:12px; padding:16px; background: rgba(0,0,0,0.02); }

/* >=900px:雙欄 */
@media (min-width:900px){
.project-grid{ grid-template-columns: repeat(2,1fr); }
}

  1. 表單:小裝置全寬 → 大裝置兩欄(可選)
    #contact-form{ display:grid; gap:12px; }
    .field label{ display:block; margin:0 0 6px; }
    input, textarea{
    width:100%; padding:10px 12px; border:1px solid #e5e7eb; border-radius:8px; background:transparent;
    }

/* >=900px:兩欄佈局(訊息全寬) /
@media (min-width:900px){
#contact-form{ grid-template-columns: 1fr 1fr; }
.field:has(textarea){ grid-column: 1 / -1; } /
讓訊息欄跨兩欄(若瀏覽器不支援 :has 可改加 class) */
}

  1. 行動端互動區塊的觸控可用性
    a, button{ min-height: 40px; line-height: 1; }
    .btn{ display:inline-block; border:1px solid #2563eb; background:#2563eb; color:#fff; padding:10px 16px; border-radius:8px; text-decoration:none; }
    .btn-outline{ background:transparent; color:#2563eb; }

針對 iOS Safari 等裝置,40px 以上點擊目標比較不易誤觸。

成果(你應該看到)

手機寬度(<520px)

導覽列直向堆疊

Hero 單欄、照片置中

技能清單 1 欄、作品卡片 1 欄、表單全寬

小平板(≈768px)

導覽列橫排

技能 2 欄

桌機(≥900px)

Hero 變兩欄(文字+照片)

技能 3 欄、作品 2 欄

表單兩欄(訊息欄跨欄)

字體使用 clamp() 隨寬度在合理範圍內縮放,可讀性更穩定

小心踩雷(常見誤用 → 正確作法)

以桌機為主、再用 max-width「縮」下去
問題:在手機會載入一堆不必要的樣式與資源,體驗差。
做法:Mobile-first + @media (min-width) 由小放大。

亂設固定寬度(width: 1200px;)
問題:小螢幕爆版。
做法:用 max-width+百分比或格線,必要時 min()、clamp() 控制上限。

圖片沒做彈性
問題:超出容器、橫向捲動。
做法:img{ max-width:100%; height:auto; };最好再加明確寬高避免 CLS。

斷點憑感覺、到處一條
問題:難維護。
做法:固定少數關鍵斷點(例如 520/768/900/1280),內容需求導向調整。

用 與   控版面
問題:不可維護,RWD 一變就亂。
做法:用 Flex/Grid、margin/padding 佈局與間距。

忘記 viewport meta
問題:手機上被縮到很小、使用者要手動放大。
做法:

進一步強化(可選)

容器查詢(Container Queries):當某個卡片容器變窄就改為單欄,無需靠全域視窗寬度(現代瀏覽器已支持)。

prefers-reduced-motion:對不喜歡動態的使用者關閉動畫。

prefers-color-scheme****+主題切換:自動偵測系統主題,再由按鈕覆寫。

圖片種類:以 srcset / sizes 提供不同解析度檔案,行動端載小圖、省流量。

@media (prefers-reduced-motion: reduce){
*{ animation-duration:0.01ms !important; animation-iteration-count:1 !important; transition-duration:0.01ms !important; }
}

練習題

把「導覽列」改成 漢堡選單(小螢幕隱藏清單,點按鈕展開;≥768px 固定顯示)。

讓「作品卡片」在 ≥1280px 變成 3 欄。

將「Hero 大標」以 clamp() 做更平滑的流式字體(例如 clamp(24px, 5vw, 48px)),比較不同螢幕的可讀性。

使用 容器查詢(若可):當 .project-grid 寬度 < 700px 時改成 1 欄。


上一篇
DOM 操作與事件綁定 – 用 TS 操作 HTML 元素
下一篇
Day 6 小專案:純原生 HTML/CSS/TS 的自我介紹頁(可交付 MVP) 今日目標
系列文
Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言