@media (min-width: …)
逐步增強到平板、桌機。px
,多用 百分比、rem
、ch
、min()
、max()
等相對單位。@media (min-width: 768px)
→ 平板@media (min-width: 1024px)
→ 桌機max-width: 100%
防止溢出。我們保留你 Day1 的 HTML 結構(語義化標籤),只補上 viewport 與 class 鉤子,把重點放在 CSS。
檔案結構(和昨天的差不多):
day5-rwd/
├─ index.html
└─ styles/
└─ style.css
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Chiayu · 前端工程師 · 履歷網站</title>
<link rel="stylesheet" href="styles/style.css" />
</head>
<body>
<header class="site-header">
<div class="container header-inner">
<a class="brand" href="#home">Chiayu</a>
<nav class="site-nav" aria-label="主選單">
<button id="nav-toggle" class="nav-toggle" aria-expanded="false" aria-controls="nav-list">選單</button>
<ul id="nav-list" class="nav-list">
<li><a href="#about">關於我</a></li>
<li><a href="#skills">技能</a></li>
<li><a href="#projects">作品</a></li>
<li><a href="#contact">聯絡</a></li>
</ul>
</nav>
</div>
</header>
<main id="home">
<!-- Hero -->
<section class="hero container">
<div class="hero-text">
<h1>哈囉,我是 Chiayu</h1>
<p>前端工程師|專長 Angular & TypeScript</p>
<div class="hero-cta">
<a class="btn" href="#projects">看作品</a>
<a class="btn btn-outline" href="#contact">聯絡我</a>
</div>
</div>
<div class="hero-photo">
<img src="assets/me-formal.jpg" alt="Chiayu 的正式照片" width="240" height="240" />
</div>
</section>
<!-- About -->
<section id="about" class="container section">
<h2>關於我</h2>
<p>我是一名前端工程師,喜歡把想法做成能上線的產品。近期專注於 Angular、TypeScript 與效能最佳化。</p>
</section>
<!-- Skills -->
<section id="skills" class="container section">
<h2>技能 Skillset</h2>
<ul class="grid grid-2 md:grid-3 lg:grid-4">
<li>HTML / CSS / SCSS</li>
<li>TypeScript</li>
<li>Angular / React / Vue</li>
<li>Node.js / Express</li>
<li>Git / GitHub / Docker</li>
<li>Vite / Webpack</li>
</ul>
</section>
<!-- Projects -->
<section id="projects" class="container section">
<h2>作品集 Projects</h2>
<div class="grid grid-1 md:grid-2">
<article class="card">
<h3>毛毛購物(寵物電商)</h3>
<p class="muted">Angular + Node.js|購物車、結帳、RWD</p>
<p>主導前端架構與購物流程,完成商品列表到訂單頁。</p>
<a class="btn small" href="#">Live Demo</a>
</article>
<article class="card">
<h3>LINE Bot 預約系統</h3>
<p class="muted">Cloud Functions + LINE API|時段預約</p>
<p>整合聊天介面與雲端排程,完成會員預約流程。</p>
<a class="btn small" href="#">Live Demo</a>
</article>
</div>
</section>
<!-- Contact -->
<section id="contact" class="container section">
<h2>聯絡我</h2>
<address>
Email:<a href="mailto:hotdanton08@hotmail.com">hotdanton08@hotmail.com</a><br />
GitHub:<a href="https://github.com/你的帳號">github.com/你的帳號</a><br />
LinkedIn:<a href="https://linkedin.com/in/你的帳號">linkedin.com/in/你的帳號</a>
</address>
</section>
</main>
<footer class="site-footer">
<div class="container">
<p>© 2025 Chiayu Lee · All rights reserved.</p>
</div>
</footer>
<!-- (可選)一行 JS 讓手機上「選單」按鈕能開合 -->
<script>
const btn = document.getElementById('nav-toggle');
const list = document.getElementById('nav-list');
btn?.addEventListener('click', () => {
const open = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', String(!open));
list?.classList.toggle('open', !open);
});
</script>
</body>
</html>
重點:先寫手機版,再用 @media (min-width: …) 擴充到平板、桌機。
/* ===== Design Tokens(可日後抽成 SCSS 變數) ===== */
:root{
--bg:#fff; --fg:#1f2937; --muted:#6b7280; --primary:#2563eb;
--border:#e5e7eb; --container:1100px; --radius:12px; --space:16px;
--lh:1.7; --base:16px; /* 基底字級(方便用 rem) */
}
/* ===== Base(手機先行) ===== */
*{ box-sizing:border-box; }
html{ font-size: var(--base); }
body{
margin:0; background:var(--bg); color:var(--fg);
font-family: system-ui, -apple-system, "Noto Sans TC", Arial, sans-serif;
line-height:var(--lh);
}
img{ max-width:100%; height:auto; display:block; }
a{ color:inherit; }
.container{ max-width:var(--container); margin:0 auto; padding:0 20px; }
.section{ padding:56px 0 40px; }
.muted{ color:var(--muted); }
.btn{
display:inline-block; text-decoration:none;
background:var(--primary); color:#fff; border:1px solid var(--primary);
padding:.625rem 1rem; border-radius:8px;
}
.btn:hover{ opacity:.92; }
.btn-outline{ background:transparent; color:var(--primary); }
.btn.small{ padding:.5rem .75rem; font-size:.9rem; }
/* ===== Header(手機:品牌 + 漢堡選單 + 下拉清單) ===== */
.site-header{
position:sticky; top:0; background:var(--bg); border-bottom:1px solid var(--border); z-index:10;
}
.header-inner{
display:flex; align-items:center; gap:12px; padding:12px 0;
}
.brand{ font-weight:700; text-decoration:none; }
.site-nav{ margin-left:auto; }
.nav-toggle{
border:1px solid var(--border); background:transparent; padding:.5rem .75rem; border-radius:8px;
}
.nav-list{
list-style:none; margin:.5rem 0 0; padding:0; display:none; /* 手機預設收起 */
}
.nav-list.open{ display:block; }
.nav-list li{ border-top:1px solid var(--border); }
.nav-list a{ display:block; padding:.75rem 0; text-decoration:none; }
/* ===== Hero(手機:上下排列) ===== */
.hero{ display:grid; gap:20px; padding:40px 0; }
.hero-text h1{ margin:.2rem 0 .4rem; font-size: clamp(1.5rem, 5vw, 2.2rem); }
.hero-cta{ display:flex; gap:12px; margin-top:.5rem; }
.hero-photo{ max-width:240px; }
.hero-photo img{ border-radius:50%; border:4px solid var(--border); }
/* ===== Grid 工具:手機預設 1 欄 ===== */
.grid{ display:grid; gap:12px; }
.grid-1{ grid-template-columns:1fr; }
.grid-2{ grid-template-columns:1fr; } /* 先 1 欄,等中斷點再擴張 */
.md\:grid-2, .md\:grid-3, .lg\:grid-4{ grid-template-columns:1fr; } /* 較大螢幕才改 */
/* 卡片 */
.card{ border:1px solid var(--border); border-radius:var(--radius); padding:16px; }
/* ===== Footer ===== */
.site-footer{ border-top:1px solid var(--border); }
.site-footer .container{ text-align:center; padding:16px 0; color:var(--muted); }
/* ===== 斷點:平板(≥768px) ===== */
@media (min-width:768px){
.nav-toggle{ display:none; } /* 平板以上顯示水平選單 */
.nav-list{ display:flex; gap:16px; margin:0; }
.nav-list li{ border:0; }
.nav-list a{ padding:.25rem 0; }
.hero{
grid-template-columns: 1.2fr .8fr; align-items:center;
}
/* grid 工具在平板擴張 */
.md\:grid-2{ grid-template-columns: repeat(2, 1fr); }
.md\:grid-3{ grid-template-columns: repeat(3, 1fr); }
}
/* ===== 斷點:桌機(≥1024px) ===== */
@media (min-width:1024px){
.lg\:grid-4{ grid-template-columns: repeat(4, 1fr); }
.section{ padding:72px 0 56px; }
}
你會看到我們大量用 工具類 class(grid-2 / md:grid-3 / lg:grid-4)來快速定義不同斷點下的欄數。這對初學者非常直覺,也好維護。
建議截圖:
day5-mobile-hero.png
、day5-tablet-grid.png
、day5-desktop-overview.png
<meta name="viewport" content="width=device-width, initial-scale=1">
@media (min-width: …)
向上加。.card{ width: 400px }
在 360px 手機直接爆版。max-width
、百分比、clamp()
文字大小、grid
/flex
佈局。img
無限制;大圖把版面撐破。img{ max-width:100%; height:auto }
,必要時再加容器寬。display:none
直接砍內容。用 clamp()
做流體字級:font-size: clamp(1rem, 2.5vw, 1.25rem);
Skills 區塊改用 grid-auto-fit
:
.grid-auto { display:grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap:12px; }
Hero 圖片在超寬螢幕限制最大寬度,避免過度放大。
明天開始把同一份資訊架構搬進 Angular:
如果你想,我也可以把今天的 RWD 版本幫你打包成最小可上線的檔案,附一份 GitHub Pages / Vercel 的部署說明。