---
# System prepended metadata

title: 網頁設計入門課

---

# 網頁設計入門指南

## 今日目標

這堂課將手把手帶你認識 **網頁設計基本 3 要素**：
- HTML
- CSS
- JavaScript (JS)

親手做出一個**互動式個人介紹頁面**，包含：
- 你的名字、照片與技能標籤
- 漂亮的 CSS 樣式
- 可以切換深色模式的按鈕
- 點擊技能標籤會有動態效果

最後將網頁發佈到網路上，就可以將你的網頁分享給其他人啦～

---

## 第一部分：暖身

- ### 網站的構成三要素

    想像你在蓋一棟房子：

    ```
    🏗️ HTML  →  骨架（牆壁、門、窗戶在哪裡）
    🎨 CSS   →  裝潢（顏色、大小、字型、間距）
    ⚙️ JS    →  電器（讓東西會動、會互動）
    ```

    三者分工合作，少了任何一個，網頁就不完整。

- ### 開發人員工具（DevTools）
    
    內建於瀏覽器中的網頁開發測試與除錯工具，以下是開啟方式：
    
    **Windows/Linux：**
    - `F12` 或 `Ctrl` + `Shift` + `I`
    - 點右鍵 -> 「檢查 (Inspect)」
    
    **macOS：**
    - `Cmd` + `Option` + `I`
    - 點右鍵 -> 「檢閱元件」

    >注意：若使用 Safari 須先進行額外設定
    >1. 選單列點選 Safari → 設定
    >1. 切換到 「進階」 頁籤
    >1. 勾選底部的 「顯示網頁開發者功能」


---

## 第二部分：HTML — 蓋骨架

- ### HTML 的邏輯：元素（element）

    ```html
    <標籤名稱>內容</標籤名稱>
    ```

    - 用「標籤」來描述內容的用途，形成一個**元素**
    - 標籤通常有**開頭**和**結尾**，把內容夾在中間
    - 內容可以包含**多個元素**。

    ---

- ### 實作一：建立完整 HTML 結構

    打開 VS Code 創建 `index.html` 檔案，並將以下程式碼貼上：

    ```html=
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>My Personal Website</title>
            <meta charset="UTF-8">
            <link rel="stylesheet" href="style.css">
            <script src="script.js" defer></script>
        </head>

        <body>
            <h1>My Personal Website</h1>

            <button id="darkToggle">🌙 深色模式</button>

            <div class="card">
                <img src="https://i.pravatar.cc/150?" alt="我的照片">
                <h1>你的名字</h1>
                <p class="bio">熱愛設計的工程師</p>

                <h3>Skill Tags</h3>
                <ul class="skills">
                    <li class="skill-tag">Python</li>
                    <li class="skill-tag">C++</li>
                    <li class="skill-tag">UI 設計</li>
                </ul>

                <p class="skill-msg"></p>

                <a href="mailto:your@email.com" class="btn">聯絡我</a>
            </div>
        </body>
    </html>
    ```
    
    在檔案總管點開 `index.html` 檔案，進入瀏覽器後就能看到文字和圖片出現了！

    
    :::info
    *若想要在修改程式碼的過程中，即時更新網頁狀態，可以在 VS Code 的延伸模組中安裝 `Live Server`。*
    :::

    ---

- ### DOM (Document Object Model)
    瀏覽器把 HTML 解析後，轉換成一棵「可操作的樹狀結構」，CSS 和 Javascript 便能透過它尋找指定的元素並修改。
    
    - #### HTML 結構：

        <img src="https://hackmd.io/_uploads/SyjJgKs6Ze.png" width="90%" style="border: 1px solid black; border-radius: 8px;">
    
    - #### DOM 示意圖：

        <img src="https://hackmd.io/_uploads/ryeXZvqTbe.png" width="75%" style="border: 1px solid black; border-radius: 8px;">



- ### 標籤速查表
    
    - #### 結構標籤：
        | 標籤 | 用途 |
        |------|------|
        | `html` | 整個網頁的**根元素** |
        | `head` | 網頁設定與資訊 |
        | `body` | 使用者看到的內容 |
    
    - #### 設定常用標籤：
        | 標籤 | 用途 | 範例 |
        |------|------|------|
        | `title` | 網頁標題名稱 | `<title>標題</title>` |
        | `link` | 連接外部資源 (如 CSS) | `<link rel="用途/關係" href="來源">` |
        | `script` | 載入並執行 JavaScript | `<script src="來源"></script>` |
        | `meta` | 其他設定 | `<meta 屬性="值">` |
        

    - #### 內文常用標籤
    
        | 標籤 | 用途 | 範例 |
        |------|------|------|
        | `<h1>` ~ `<h6>` | 標題（數字越大越小） | `<h1>大標題</h1>` |
        | `<p>` | 段落文字 | `<p>這是一段文字</p>` |
        | `<img>` | 圖片 | `<img src="圖片網址" alt="描述">` |
        | `<a>` | 連結 | `<a href="網址">點我</a>` |
        | `<button>` | 按鈕 | `<button>按我</button>` |
        | `<ul>` + `<li>` | 無序清單 | `<ul><li>項目</li></ul>` |
        | `<div>` | 容器（打包用） | `<div>...</div>` |
    
    :::info
    *所有標籤的完整說明可至 [MDN Web Docs](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements) 查看*
    :::

- ### `class` 與 `id`
    
    用來幫元素「標記身分」，讓你可以用 CSS 或 JavaScript 去選取它們。

    ```html
    <div class="card">      <!-- 可重複使用-->
    <button id="darkBtn">   <!-- 唯一識別 -->
    ```

    - `class` → 可重複使用的「分類標籤」
    - `id` → 全頁唯一的「身份證」

---

## 第三部分：CSS — 上色與裝潢

現在雖然已經有了基本的骨架，但出來的結果還很醜！！沒關係，接下來交給裝潢大師 CSS 來進行美化和排版～

- ### CSS 的語法邏輯

    ```css
    選擇器 {
      屬性: 值;
    }
    ```
    
    **選擇器類別：**
    
    | 類別 | 範例 | 結果 |
    |-----------|----------|------|
    | 標籤 | `h1 {...}` | 所有 `<h1>` 標籤 |
    | class | `.card {...}` | class="card" | `.card { padding: 20px; }` |
    | id | `#darkToggle {...}` | id="darkToggle" |
    | 虛擬類別 | `.card:hover {...}` | 游標停放的 card |
    
    **多重條件選擇器：**
    
    | 類別 | 寫法 | 範例 | 結果 |
    |-----------|-----------|----------|------|
    | 複合選擇器 | 相連 | `body.card {...}` | 標籤為 `<body>` **且** class="card" |
    | 後代選擇器 | 空格隔開 | `.card h1 {...}` | class="card" **內容裡的** `<h1>` 標籤 |

    ---

- ### ✍️ 實作二：讓頁面好看起來
    
    先在 `index.html` 的 `<head>` 內容中添加一行程式碼，讓他可以讀取 CSS 檔。
    
    ```html
    <link rel="stylesheet" href="style.css">
    ```
    
    接著創建 `style.css` 檔案，並將以下程式碼貼上：
    :::spoiler 程式碼
    
    ```css=
    /* ── 全域重置與字型 ── */
    * {
      box-sizing: border-box;
      transition: background-color 0.3s, color 0.3s;
    }

    body {
      background-color: #f0f4f8;
      font-family: sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 40px 16px;
      min-height: 100vh;
    }

    /* ── 深色模式切換按鈕 ── */
    #darkToggle {
      background: white;
      border: 2px solid #e2e8f0;
      border-radius: 8px;
      padding: 8px 16px;
      cursor: pointer;
      font-size: 14px;
      margin-bottom: 24px;
    }

    /* ── 卡片容器 ── */
    .card {
      background-color: white;
      border-radius: 16px;
      padding: 40px;
      max-width: 420px;
      width: 100%;
      text-align: center;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
    }

    /* ── 頭像 ── */
    .card img {
      width: 120px;
      height: 120px;
      border-radius: 50%;
      object-fit: cover;
      margin-bottom: 16px;
    }

    /* ── 名字與介紹 ── */
    .card h1 {
      font-size: 28px;
      color: #1a202c;
      margin: 0 0 8px 0;
    }

    .bio {
      color: #718096;
      font-size: 16px;
      margin-bottom: 24px;
    }

    /* ── 技能標籤 ── */
    .skills {
      list-style: none;
      padding: 0;
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      justify-content: center;
      margin: 0 0 16px 0;
    }

    .skill-tag {
      background-color: #ebf4ff;
      color: #3182ce;
      padding: 6px 14px;
      border-radius: 20px;
      font-size: 14px;
      cursor: pointer;
      user-select: none;
    }

    .skill-tag:hover {
      background-color: #bee3f8;
    }

    /* ── 被選中的技能標籤（JS 會加上這個 class） ── */
    .skill-tag.active {
      background-color: #3182ce;
      color: white;
      transform: scale(1.05);
    }

    /* ── 點擊提示文字 ── */
    .skill-msg {
      font-size: 14px;
      color: #3182ce;
      min-height: 20px;
      margin-bottom: 12px;
    }

    /* ── 聯絡按鈕 ── */
    .btn {
      display: inline-block;
      background-color: #3182ce;
      color: white;
      text-decoration: none;
      padding: 12px 32px;
      border-radius: 8px;
      font-size: 16px;
      margin-top: 8px;
    }

    .btn:hover {
      background-color: #2b6cb0;
    }

    /* ── 深色模式（JS 會幫 body 加上 dark class） ── */
    body.dark {
      background-color: #1a202c;
    }

    body.dark .card {
      background-color: #2d3748;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
    }

    body.dark h1 {
      color: white;
    }

    body.dark .card h1 {
      color: #f7fafc;
    }

    body.dark .card h3 {
      color: #f7fafc;
    }

    body.dark .bio {
      color: #a0aec0;
    }

    body.dark #darkToggle {
      background: #2d3748;
      color: #f7fafc;
      border-color: #4a5568;
    }
    ```
    :::
    
    可以嘗試刪除或修改一些屬性，觀察變化。
    
    :::info
    **注意**：`.skill-tag.active` 和 `body.dark` 這些樣式現在還沒有效果，因為需要 JS 來將元素動態加上對應的 class。**這就是 CSS 和 JS 合作的方式！**
    :::

    ---

- ### CSS 核心概念說明

    - #### 盒子模型（Box Model）

        每個 HTML 元素都是一個盒子：
        ![截圖 2026-04-26 清晨7.13.34](https://hackmd.io/_uploads/SJkhqpqaZg.png =50%x)

        - margin -> 外距（元素與外界距離）
        - border -> 邊框
        - padding -> 內距（內容內側空間）
        - 藍色部分為內容

    - #### 顏色
        
        在 CSS 中，顏色的常用寫法為十六進制的 RGB，以 `#RRGGBB` 的結構來表示。
        每個顏色的範圍：`00 ~ FF`（0~255）
        

---

## 第四部分：JavaScript — 讓頁面動起來

- ### JS 是什麼？

    如果你學過 Python，JS 的邏輯你基本也能看得懂——只是語法不一樣，而且 JS 是在**瀏覽器裡跑的**，可以直接操控網頁上的元素。

    **python 寫法：**

    ```python
    name = "Billy"
    print("Hello, " + name)
    ```

    **JavaScript 寫法：（幾乎一樣的邏輯！）**

    ```javascript
    const name = "Billy";
    console.log("Hello, " + name);
    ```
    
    > *對 `const`, `let`, `var 三種變數型態的差別有興趣可以自行上網查。`*
    
    ---

- ### 核心概念：DOM 操作

    JS 可以透過 DOM 的樹狀結構，**找到任何元素並修改它**。
    
    **搜尋：**

    ```javascript
    // 用 id 找元素（回傳單一元素）
    document.getElementById("darkToggle");
    
    // 用 class 找元素所有元素（回傳即時更新陣列）（較少使用）
    document.getElementsByClassName('.skill-tag');

    // 透過 CSS 方式找所有元素（回傳靜態陣列）
    document.querySelectorAll(".skill-tag.active");
    ```
    
    **修改：**
    
    ```javascript
    // 修改文字內容
    element.textContent = "新的文字";

    // 移除元素
    element.remove();

    // 新增 / 移除 class（最常用！）
    element.classList.add("active");
    element.classList.remove("active");
    element.classList.toggle("active");  // 有就移除，沒有就加上
    ```
    
    ---
    
- ### ✍️ 實作三：深色模式切換

    先在 `index.html` 的 `<head>` 內容中添加一行程式碼，讓他可以讀取 JavaScript 檔。
    
    ```html
    <script src="script.js" defer></script>
    ```
    
    創建 `script.js` 檔案，並將以下程式碼貼上：

    ```javascript=
    // 找到按鈕元素
    const darkBtn = document.getElementById("darkToggle");

    // 監聽點擊事件
    darkBtn.addEventListener("click", function() {

      // 切換 body 的 dark class
      document.body.classList.toggle("dark");

      // 更新按鈕文字
      if (document.body.classList.contains("dark")) {
        darkBtn.textContent = "☀️ 淺色模式";
      } else {
        darkBtn.textContent = "🌙 深色模式";
      }

    });
    ```

    **試試看**：點擊「深色模式」按鈕，頁面應該要切換！

    > **關鍵觀念**：JS 做的事很簡單——**幫元素加上或移除 class**。真正讓畫面改變的是 CSS 裡的 `body.dark` 規則。**CSS 負責「長什麼樣」，JS 負責「什麼時候變」**。

    **語法補充：**
    - `element.addEventListener(事件, 函式)`：監聽此元素上發生的事件，並執行對應函數。
    - `function(參數) {...}`：匿名函式——直接定義函式，不需額外命名。
    - `element.classList.contains("class")`：判斷此元素是否包含特定 class。

    ---

- ### ✍️ 實作四：點擊技能標籤互動

    繼續在 `script.js` 新增以下程式碼：

    ```javascript=
    // 找到所有卡片元素
    const cards = document.querySelectorAll(".card");

    // 對每一張卡片都加上事件監聽
    cards.forEach(function(card) {
      // 找到所有技能標籤與訊息元素
      const skillTags = card.querySelectorAll(".skill-tag");
      const skillMsg = card.querySelector(".skill-msg");

      // 幫每一個標籤都加上點擊事件
      skillTags.forEach(function(tag) {

        tag.addEventListener("click", function() {

          // 先移除所有標籤的 active class
          skillTags.forEach(function(t) {
            t.classList.remove("active");
          });

          // 幫被點擊的標籤加上 active class
          tag.classList.add("active");

          // 顯示提示訊息
          skillMsg.textContent = "對「" + tag.textContent + "」有興趣！";

        });
      });
    });
    ```

    **試試看**：點擊不同的技能標籤，看看有什麼反應！
    
    **語法補充：**
    
    - `NodeList.forEach(函式)`：對 NodeList（`querySelectorAll` 回傳的陣列）中每個元素執行指定的函式。

---

## 第五部分：發布上線（GitHub Pages）
可參考前面社課的 [教材](https://hackmd.io/Ms_RrqttSpWe1_iXO-SLhA?view#建立你的-GitHub-Pages)

1. ### 建立 Repository

    1. 進入 Repository 頁面
    2. 點選 "New" 建立新儲存庫
    3. 設定 Repository 名稱，並確認儲存庫為 Public
    
2. ### 上傳網站檔案
    1. 點選 "uploading an existing file"
    2. 上傳前面製作的三個檔案

3. ### 開啟 GitHub Pages 設定
    1. 進入該專案的 "Settings" 頁面
    2. 在左側選單點選 "Pages"
    3. 在 "Build and deployment" 下的 Source 選擇 `Deploy from a branch`
    4. 在 Branch 處選擇 `main` 並選擇 `/(root)` 資料夾，點選 "Save"

最後網址會是 `https://GitHub帳號.github.io/repository名稱`。
例如：https://boxun-shih.github.io/Website_Example/

---

## 程式碼參考範例

- https://github.com/xujk0217/xujk0217.github.io
- https://github.com/xujk0217/GDG-Member-Wall