# 網頁設計入門指南 ## 今日目標 這堂課將手把手帶你認識 **網頁設計基本 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