CHAPTER 02 / STYLING

CSS:
網頁的皮膚

HTML 蓋好了一個沒裝潢的毛胚屋。CSS 就是裝潢工程:刷油漆、鋪地板、選沙發、調光線。 這章是前端最有趣也最頭痛的部分,很多人放棄都放棄在這。但學會 Flexbox 跟 Grid,你就贏了 80% 的人。

  • 把任何 HTML 變漂亮
  • 讓網站在電腦、平板、手機都好看(RWD)
  • 做出滑鼠 hover 動畫、頁面載入動畫
  • 用 Flexbox 跟 Grid 排出複雜版面
  • 會用 CSS 變數、規模化你的樣式
LESSON 2.1

CSS 是什麼?怎麼用?

CSS(Cascading Style Sheets,串接樣式表)是規則。它告訴瀏覽器:「這個 h1 要紅色」、「這個 p 字要 16px」。

規則的長相:

h1 {
  color: red;
  font-size: 32px;
}

翻譯:「找到所有 h1,把字變紅、變 32px」。前面的 h1選擇器,大括號裡叫宣告

三種引入 CSS 的方法

方法一:行內樣式(不推薦)

<h1 style="color: red;">標題</h1>

方法二:寫在 head 裡

<head>
  <style>
    h1 { color: red; }
  </style>
</head>

方法三:外部 CSS 檔(最推薦)

// index.html
<link rel="stylesheet" href="style.css">
/* style.css */
h1 { color: red; }

正式專案永遠用方法三。HTML 一個檔、CSS 一個檔、JS 一個檔。混在一起寫很爽,兩週後維護想哭。

LESSON 2.2

選擇器:怎麼挑出要改的元素

CSS 第一個關卡:怎麼跟瀏覽器精準說「我要改的是這個」。

選擇器意思範例
*所有元素* { margin: 0; }
h1所有 h1h1 { color: red; }
.btnclass 是 btn.btn { ... }
#heroid 是 hero#hero { ... }
div pdiv 裡所有 particle p { ... }
div > pdiv 的直接子層 pnav > a { ... }
h1 + p緊接 h1 的 p
a:hover滑鼠移過去a:hover { color: blue; }
input:focus正在輸入
li:first-child第一個 li
li:nth-child(2)第二個 li
[type="email"]type 是 email

組合起來用

/* nav 裡的 a,當滑鼠移過去 */
nav a:hover { color: orange; }

/* class 是 card 且 也有 featured */
.card.featured { border: 2px solid gold; }

/* class 是 btn 但 不是 disabled */
.btn:not(.disabled) { cursor: pointer; }

優先級(specificity)

當兩條規則套到同一個元素,分數高的贏:

新手很愛濫用 !important。它會無視所有規則直接贏。但用了 !important 之後就只能再用 !important 蓋它,最後整份 CSS 都是 !important不到萬不得已不要用

LESSON 2.3

顏色、字體、單位

顏色寫法

color: red;                    /* 顏色名稱 */
color: #ff0000;                /* 16 進位 */
color: #f00;                   /* 短寫 */
color: rgb(255, 0, 0);         /* RGB */
color: rgba(255, 0, 0, 0.5);   /* 多了透明度 0~1 */
color: hsl(0, 100%, 50%);      /* 色相、飽和度、亮度 */

記住基本顏色對照:#000 黑、#fff 白、#f00 紅、#0f0 綠、#00f 藍。

字體

body {
  font-family: 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
  font-size: 16px;
  font-weight: 400;        /* 100~900,400 = 普通,700 = 粗 */
  line-height: 1.6;        /* 行高,1.5~1.8 最舒服 */
  letter-spacing: 0.02em;  /* 字距 */
}

font-family 寫多個值是「萬一第一個沒有,用下一個」。最後一定要寫 sans-serifserif 保底。

單位

單位意思用在哪
px像素(絕對值)邊框、icon
%父元素的百分比寬度
em父元素 font-size 倍數內距
remhtml 的 font-size 倍數大部分東西
vw視窗寬度的 1%滿版區塊
vh視窗高度的 1%全螢幕區塊

px 是「絕對」的,不管螢幕多大都長一樣。rem 是「相對」的,使用者放大字體會跟著放大。字體用 rem,邊框用 px 是新手最快上手的規則。

LESSON 2.4

盒子模型(Box Model)

CSS 最核心的概念,沒搞懂這個就不要往下走

每個 HTML 元素在瀏覽器看來都是盒子。盒子由內到外有四層:

┌─────── margin(外距)─────────┐
│  ┌──── border(邊框)──────┐  │
│  │  ┌── padding(內距)─┐  │  │
│  │  │   content(內容) │  │  │
│  │  └────────────────── ┘  │  │
│  └────────────────────────┘  │
└──────────────────────────────┘

禮物盒。content 是禮物、padding 是緩衝氣泡紙、border 是紙盒、margin 是這個盒子跟其他盒子的空隙。

.box {
  width: 200px;
  padding: 20px;
  border: 2px solid black;
  margin: 16px;
}

/* 簡寫:上 右 下 左 */
.box { padding: 10px 20px 30px 40px; }

/* 上下 / 左右 */
.box { padding: 10px 20px; }

那個讓所有人崩潰的 box-sizing

預設情況下,width: 200px 只算 content。padding 跟 border 額外加上去。也就是 width: 200px; padding: 20px; border: 2px;,實際盒子寬 244px。難排版

解法:在 CSS 開頭加這段,每個專案都加

* {
  box-sizing: border-box;
}

之後 width: 200px 就是「整個盒子 200px」,padding 和 border 算進去。世界和平。

display:盒子的種類

意思
block區塊:獨佔一行,可設寬高
inline行內:跟著文字流,無法設寬高
inline-block混血:跟文字並排但可設寬高
none消失(不佔空間)
flex變 Flexbox 容器
grid變 Grid 容器
LESSON 2.5

Flexbox:水平排列救星

「我想把三個東西並排放,間距平均」——這個需求出現過上萬次。在 2015 年以前要用 float 拼湊,超痛苦。現在有 Flexbox

父元素設 display: flex它的直接子元素就會自動變成 flex 項目。

<div class="row">
  <div>項目 1</div>
  <div>項目 2</div>
  <div>項目 3</div>
</div>
.row {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
}

justify-content(主軸對齊)

align-items(交叉軸對齊)

水平垂直完美置中(神技)

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

flex 屬性(給項目用)

.item { flex: 1; }              /* 平均分配剩餘空間 */
.item:nth-child(2) { flex: 2; } /* 這項佔兩倍寬 */

flex-direction、flex-wrap

.col {
  display: flex;
  flex-direction: column;  /* 變垂直堆疊 */
}

.gallery {
  display: flex;
  flex-wrap: wrap;  /* 寬度不夠時自動換行 */
}

導覽列、卡片並排、按鈕群組、表單欄位排列、頁尾分欄——這些用 Flexbox 全部搞定。Flexbox 是接案前端的菜刀,不熟練不能出師。

LESSON 2.6

Grid:二維排版王者

Flexbox 一次處理一條軸。Grid 同時處理兩條,是排版界的魔王

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* 3 欄平均 */
  gap: 16px;
}

fr 是 fraction(份)。1fr 1fr 1fr = 三欄一樣寬。1fr 2fr = 第二欄是第一欄的兩倍寬。

RWD 神技(背下這行)

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 24px;
}

「每張卡片至少 250px 寬,能放幾張就放幾張,放不下自動換行。」接案 80% 的卡片排版會用到它。

跨欄、跨列

.featured {
  grid-column: span 2;  /* 橫跨兩欄 */
  grid-row: span 2;     /* 縱跨兩列 */
}

Flexbox vs Grid 怎麼選?

LESSON 2.7

Position:把元素釘在畫面上

意思
static預設,照正常順序排
relative相對自己原本位置偏移
absolute相對最近的「定位過的祖先」
fixed釘在視窗,捲動不動
sticky滾到某位置就黏住
/* 經典用法:徽章貼在卡片右上 */
.card { position: relative; }
.badge {
  position: absolute;
  top: 8px;
  right: 8px;
}

/* 滾動時固定的導覽列 */
nav {
  position: sticky;
  top: 0;
  z-index: 100;
}

z-index 不要設 99999。設了之後別的東西要蓋上來就要 999999,永遠在比大。用 10、100、1000 三個層級就夠了

LESSON 2.8

響應式設計(RWD)

2026 年了,超過 70% 的人用手機看網站。電腦上漂亮、手機上爆掉,就是廢的。

第一步:viewport meta

<meta name="viewport" content="width=device-width, initial-scale=1.0">

第二步:媒體查詢

/* 預設樣式(電腦版) */
.container { width: 1200px; }

/* 螢幕寬 768px 以下 */
@media (max-width: 768px) {
  .container { width: 100%; padding: 16px; }
  .nav { flex-direction: column; }
}

常用斷點

Mobile First 思維

新手通常先做電腦版再縫補手機版。反過來:先做手機版,用 min-width 加大螢幕的樣式。

/* 預設:手機 */
.card { width: 100%; }

/* 平板以上 */
@media (min-width: 768px) {
  .card { width: 50%; }
}

/* 桌機以上 */
@media (min-width: 1024px) {
  .card { width: 33%; }
}
LESSON 2.9

動畫與過渡

transition:簡單過渡

.btn {
  background: #5fff87;
  transition: all 0.3s ease;
}

.btn:hover {
  background: #ffb13d;
  transform: translateY(-2px);
}

transform:變形

.box {
  transform: translateX(20px);
  transform: scale(1.1);
  transform: rotate(45deg);
  transform: scale(1.1) rotate(5deg);  /* 組合 */
}

animation + @keyframes

@keyframes bounce {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(-20px); }
  100% { transform: translateY(0); }
}

.ball {
  animation: bounce 1s ease infinite;
}

不要過度動畫。每個東西都動會讓使用者頭暈也讓網站變慢。動畫只用在重點上:按鈕 hover、頁面載入、滾動進入。

LESSON 2.10

CSS 變數:可重用的設定值

專案有 50 個地方用到 #5fff87。客戶說「想換成紫色」。要改 50 個地方?太蠢了。

:root {
  --primary: #5fff87;
  --secondary: #ffb13d;
  --text: #1a1814;
  --bg: #f4ead5;
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
}

.btn {
  background: var(--primary);
  padding: var(--space-2) var(--space-3);
}

之後客戶要換顏色,:root 那一行就好

標準作業流程:拿到客戶 brand 後,第一件事就是把所有顏色、字級、間距寫成 CSS 變數。後面整個專案都用變數。要改主題色一鍵搞定。

練習:個人品牌頁

用上一章的個人介紹頁加上 CSS:

  1. 定義 CSS 變數:主色、副色、字體、間距
  2. 用 Flexbox 把 header 做成「左 logo / 右導覽」
  3. 用 Grid 做技能區塊:3 欄、卡片式、滑鼠 hover 浮起
  4. 聯絡表單置中、最大寬度 600px
  5. 導覽列 sticky 在頂部
  6. 手機版(< 768px)導覽列改成垂直、技能區改成 1 欄
  7. 頁面載入時 h1 從下往上淡入

常見卡關 FAQ

// CSS 學員最常問的問題
為什麼我寫的 CSS 沒有套用?
三個常見原因:(1) <link> 路徑寫錯;(2) 選擇器寫錯(class 前面要 . 、id 前面要 #);(3) 被優先級更高的規則蓋掉了。F12 → Elements 選你那個元素,右邊 Styles 看哪條規則生效。
手機看網站超小怎麼辦?
99% 是 head 沒寫 viewport meta。加上 <meta name="viewport" content="width=device-width, initial-scale=1.0">
margin 兩個元素間距怪怪的?
Margin Collapse。當兩個區塊的 margin 接觸時,會合併成大的那個(不是相加)。例如 .a { margin-bottom: 20px }.b { margin-top: 30px },間距是 30px 不是 50px。解法:用 gap(在 flex/grid 裡)或 padding
圖片總是出現在文字旁邊間距怪怪的?
img 預設是 inline,會跟文字一起對齊基線。加上 img { display: block; } 就正常。
我用 100vh 在手機上會被網址列遮住?
舊瀏覽器的問題。現在用 100dvh(dynamic viewport height)就會自動扣掉網址列。或備援用 min-height: 100vh; min-height: 100dvh;
← 上一章
01 HTML