# 二、HTML 的內容結構
本章我們將深入探討 HTML 如何組織更複雜的內容,包含建立網頁之間的連結、呈現清單、嵌入多媒體,以及透過表格和表單來展示資料與收集使用者輸入。
## 2.1 超連結與清單結構
### 超連結:網頁世界的核心
**超連結 (Hyperlink)** 是 HTML 最重要的特性之一,它讓使用者能從一個頁面「跳轉」到另一個頁面,這也是「**超文字 (HyperText)**」這個名稱的由來。連結是構成全球資訊網 (World Wide Web) 的基礎。
#### 範例:基本超連結
```html
<a href="https://www.google.com">前往 Google</a>
```
#### 範例說明
- `<a>`:這是 `anchor` (錨點) 標籤,用於建立超連結。
- `href`:這是 `hypertext reference` 的縮寫,指定連結的目標網址,這是 `<a>` 標籤**最重要且必填**的屬性。
- `前往 Google`:這是顯示在頁面上的連結文字,使用者會點擊它。
#### 顯示結果

---
### 超連結的屬性
`<a>` 標籤還有一些常用屬性,可以控制連結的行為:
| 屬性 | 功能 | 說明 |
| :--- | :--- | :--- |
| `target` | 開啟方式 | `_self` (預設): 在目前的分頁開啟。<br>`_blank`: 在新的分頁開啟,適合連結到外部網站。 |
| `title` | 提示文字 | 當滑鼠停留在連結上時,會顯示的額外提示文字。 |
| `download` | 下載檔案 | 告知瀏覽器要下載 `href` 指定的檔案,而不是跳轉頁面。可以設定下載的檔案名稱,如 `download="report.pdf"`。 |
#### 範例:使用 `target` 與 `title`
```html
<a href="https://developer.mozilla.org/" target="_blank" title="前往 MDN Web Docs 學習更多">
MDN 文件
</a>
```
#### 顯示結果

---
### 常見超連結類型
#### 1. 外部連結 (External Link)
連結到其他網站的頁面。
```html
<a href="https://www.example.com" target="_blank">開啟範例網站</a>
```
> 💡 **最佳實務**: 連到外部網站時,建議加上 `target="_blank"`,避免使用者離開你的網站。
#### 2. 內部連結 (Internal Link)
連結到自己網站內的其他頁面。
```html
<!-- 連到同一個資料夾下的 about.html -->
<a href="about.html">關於我們</a>
<!-- 連到根目錄下的 contact.html -->
<a href="/contact.html">聯絡方式</a>
```
#### 3. 錨點連結 (Anchor Link)
跳到**同一個頁面**的特定位置。
```html
<!-- 連結 -->
<a href="#section-intro">跳到第一節</a>
<!-- 頁面下方的目標位置 -->
<h2 id="section-intro">第一節:認識 HTML</h2>
```
#### 範例說明
- 連結的 `href` 值是 `#` 加上目標元素的 `id`。
- 目標元素必須有一個 `id` 屬性,其值與 `href` 中的名稱相對應。
#### 4. Email 連結
點擊後會開啟使用者的預設郵件應用程式。
```html
<a href="mailto:example@gmail.com">寄信給我們</a>
```
#### 5. 電話連結
在行動裝置上點擊後,會提示使用者是否要撥打電話。
```html
<a href="tel:+886912345678">撥打客服專線</a>
```

---
### 清單結構
清單用於組織與呈現條列式的資訊,讓內容更有結構、易於閱讀。HTML 提供三種主要的清單類型。
#### 1. 無序清單 (Unordered List)
使用 `<ul>` 標籤,每個清單項目是 `<li>` (List Item)。項目之間沒有順序關係,通常以項目符號 (•) 呈現。
#### 範例:購物清單
```html
<ul>
<li>蘋果</li>
<li>鳳梨</li>
<li>香蕉</li>
</ul>
```
#### 顯示結果

---
#### 2. 有序清單 (Ordered List)
使用 `<ol>` 標籤,項目之間有明確的先後順序,通常以數字 (1, 2, 3) 呈現。
#### 範例:操作步驟
```html
<ol>
<li>開啟 VS Code</li>
<li>建立 index.html</li>
<li>啟動 Live Server</li>
</ol>
```
#### 顯示結果

---
#### 3. 巢狀清單 (Nested List)
清單可以互相嵌套,形成多層次的結構。
#### 範例:課程大綱
```html
<ul>
<li>前端技術
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript
<ol>
<li>基礎語法</li>
<li>DOM 操作</li>
</ol>
</li>
</ul>
</li>
<li>後端技術
<ul>
<li>Node.js</li>
<li>Python</li>
</ul>
</li>
</ul>
```
#### 顯示結果


---
#### 4. 描述清單 (Definition List)
使用 `<dl>` (Definition List) 標籤,適合用於術語解釋、問答或名詞與定義的配對。
| 標籤 | 功能 | 說明 |
| :--- | :--- | :--- |
| `<dl>` | 描述清單 | (Definition List) 整個清單的容器。 |
| `<dt>` | 術語名稱 | (Definition Term) 要被定義的名詞。 |
| `<dd>` | 術語解釋 | (Definition Description) 對名詞的詳細描述。 |
#### 範例:網頁技術名詞解釋
```html
<dl>
<dt>HTML</dt>
<dd>超文字標記語言,負責網頁的內容與結構。</dd>
<dt>CSS</dt>
<dd>階層式樣式表,負責網頁的外觀與排版。</dd>
</dl>
```
#### 顯示結果

<br/>
## 2.2 圖片與多媒體元素
網頁不只有文字,豐富的圖片和多媒體是吸引使用者的關鍵。本節將介紹如何在網頁中嵌入各種媒體,讓你的網頁更生動。
### 插入圖片 `<img>`
圖片是網頁中最常見的元素,使用 `<img>` 標籤來插入。這是一個自閉合標籤。
#### 範例:基本圖片
```html
<img src="images/cat.jpg" alt="一隻可愛的橘貓正躺在沙發上" width="300" />
```
#### 屬性說明
| 屬性 | 功能 | 說明 |
| :--- | :--- | :--- |
| `src` | 圖片來源 (Source) | **必填**。指定圖片的檔案路徑或網址。 |
| `alt` | 替代文字 (Alternative) | **必填**。當圖片無法顯示時,會出現這段文字。對 SEO 和螢幕閱讀器至關重要。 |
| `width` | 寬度 | 設定圖片的顯示寬度 (單位: 像素)。 |
| `height`| 高度 | 設定圖片的顯示高度。**建議只設定寬高其中一個**,讓瀏覽器自動等比例縮放,避免圖片變形。 |
| `title` | 提示文字 | 滑鼠停留在圖片上時顯示的提示文字,非必要。 |
> ⚠️ **可及性提醒**:`alt` 屬性是無障礙網頁的基石。請務必為每張具有資訊性的圖片填寫清楚、有意義的描述。如果圖片純粹是裝飾用,可以將 `alt` 設為空 (`alt=""`)。
---
### 圖片路徑的類型
#### 1. 相對路徑 (Relative Path)
相對於**目前 HTML 檔案**的位置。
```html
<!-- 圖片與 HTML 在同一個資料夾 -->
<img src="photo.jpg" alt="照片">
<!-- 圖片在下一層的 images 資料夾內 -->
<img src="images/logo.png" alt="Logo">
<!-- 圖片在上一層資料夾 -->
<img src="../background.jpg" alt="背景圖">
```
#### 2. 絕對路徑 (Absolute Path)
完整的網址,通常用於引用其他網站的圖片。
```html
<img src="https://www.example.com/images/photo.jpg" alt="範例照片">
```
> 💡 **最佳實務**:專案內部的圖片建議一律使用**相對路徑**,方便管理且在網站搬移時不會失效。引用外部圖片才使用絕對路徑。
---
### 圖片格式的選擇
選擇正確的圖片格式可以在品質與檔案大小之間取得平衡,提升網站載入速度。
| 格式 | 特性 | 適用情境 |
| :--- | :--- | :--- |
| **JPEG/JPG** | 破壞性壓縮,檔案小,不支援透明。 | 最適合風景、人物等色彩豐富的**照片**。 |
| **PNG** | 無損壓縮,品質高,支援透明背景。 | Logo、圖示、需要去背的圖片。 |
| **SVG** | 向量圖形,無限放大不失真,可用程式碼控制。 | Logo、Icon、簡單的幾何圖形。 |
| **WebP** | 新一代格式,壓縮率高,品質佳,支援透明與動畫。 | **現代網站首選**,能有效取代 JPEG 和 PNG。 |
| **GIF** | 支援動畫,但色彩數少 (256色)。 | 簡單的動畫、表情符號 (Meme)。 |
---
### 使用 `<figure>` 和 `<figcaption>`
當圖片需要標題或說明時,使用 `<figure>` 包裹 `<img>`,並用 `<figcaption>` 加上圖說,是語意最正確的作法。
#### 範例:為圖片加上圖說
```html
<figure>
<img src="chart.png" alt="2024年第一季銷售成長圖">
<figcaption>圖 2-1:公司在 2024 年第一季的銷售成長趨勢圖。</figcaption>
</figure>
```
#### 顯示結果

> ✨ **優點**: 這種寫法將圖片和圖說在語意上綁定在一起,對 SEO 和無障礙閱讀都更友善。
---
### 響應式圖片
為了讓網站在不同尺寸的裝置(手機、平板、電腦)上都有良好的瀏覽體驗,我們需要使用響應式圖片技術。
#### 1. 基本作法:CSS 最大寬度
最簡單的方式是透過 CSS 設定圖片的最大寬度為 100%,讓它能自動縮放以適應容器。
```css
img {
max-width: 100%;
height: auto; /* 保持圖片的原始長寬比 */
}
```
> 💡 這是響應式設計的基礎,但此方法在任何裝置上都載入同一張大圖,可能造成頻寬浪費。
#### 2. `<picture>` 標籤:提供多種格式或版本
`<picture>` 標籤允許你為不同情境提供多個圖片來源,瀏覽器會選擇最適合的一個。這對於提供現代格式 (如 WebP) 同時相容舊版瀏覽器特別有用。
#### 範例:使用 WebP 並向後相容
```html
<picture>
<!-- 如果瀏覽器支援 WebP 格式,會優先使用此圖片 -->
<source srcset="hero.webp" type="image/webp">
<!-- 如果不支援 WebP,則會使用這張 JPEG 圖片 -->
<img src="hero.jpg" alt="主視覺圖片">
</picture>
```
#### 範例說明
- 瀏覽器會由上到下檢查 `<source>` 標籤。
- 如果 `type` 符合瀏覽器支援的格式,就會使用該 `srcset` 中的圖片。
- 如果所有 `<source>` 都不符合,最後會使用 `<img>` 標籤作為預設選項。
#### 3. `srcset` 與 `sizes` 屬性:提供多種解析度
`srcset` 讓你可以提供一組不同尺寸的圖片,而 `sizes` 告訴瀏覽器圖片在不同螢幕寬度下會佔據多大的空間,瀏覽器會依此自動選擇最適合的圖片載入。
#### 範例:根據裝置解析度選擇圖片
```html
<img src="photo-medium.jpg"
srcset="photo-small.jpg 480w,
photo-medium.jpg 800w,
photo-large.jpg 1200w"
sizes="(max-width: 600px) 480px,
(max-width: 1000px) 800px,
1200px"
alt="一張根據螢幕大小而變化的照片">
```
#### 範例說明
- `srcset`:提供一組圖片以及它們的真實寬度 (`w` 單位)。
- `sizes`:
- `(max-width: 600px) 480px` 表示:當螢幕寬度小於等於 600px 時,圖片會佔據 480px 的寬度。
- 瀏覽器會根據這些資訊和裝置的像素密度,從 `srcset` 中選擇最接近且稍大的圖片來下載,避免浪費頻寬。
---
### 嵌入影片 `<video>`
使用 HTML5 `<video>` 標籤,可以直接在網頁中播放影片,不需依賴 Flash 等外部外掛。
#### 範例:基本影片播放器
```html
<video width="640" controls poster="preview.jpg">
<source src="movie.mp4" type="video/mp4">
<source src="movie.webm" type="video/webm">
您的瀏覽器不支援 HTML5 影片播放,請<a href="movie.mp4">點此下載</a>。
</video>
```
#### 範例說明
- `<video>`:影片播放器的容器。
- `controls`:顯示播放、暫停、音量等控制介面。
- `poster`:在影片載入前或播放前顯示的預覽圖。
- `<source>`:指定不同的影片格式來源,瀏覽器會由上到下選擇第一個支援的格式來播放。
- `您的瀏覽器不支援...`:當瀏覽器完全不支援 `<video>` 標籤時,會顯示這段後備文字。
#### 常用屬性
| 屬性 | 功能 | 說明 |
| :--- | :--- | :--- |
| `autoplay`| 自動播放 | 通常需要搭配 `muted` 才能生效,避免打擾使用者。 |
| `loop` | 循環播放 | 影片結束後會自動重新播放。 |
| `muted` | 靜音播放 | 預設靜音,使用者可手動開啟聲音。 |
| `preload` | 預載策略 | `none`(不預載)、`metadata`(僅預載元數據)、`auto`(預載整個影片)。 |
---
### 嵌入音訊 `<audio>`
使用 `<audio>` 標籤來嵌入音樂或音效。
#### 範例:基本音訊播放器
```html
<audio controls>
<source src="song.mp3" type="audio/mpeg">
<source src="song.ogg" type="audio/ogg">
您的瀏覽器不支援 HTML5 音訊播放。
</audio>
```
#### 範例說明
- `controls`:顯示播放控制列。
- `<source>`:同樣可以提供多種音訊格式,以確保瀏覽器相容性。
---
### 嵌入外部內容 `<iframe>`
`<iframe>` (Inline Frame) 可以在你的網頁中「挖一個洞」,嵌入另一個完整的網頁。
#### 範例:嵌入 YouTube 影片
```html
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/影片ID"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
```
#### 範例:嵌入 Google 地圖
```html
<iframe
src="https://www.google.com/maps/embed?pb=..."
width="600"
height="450"
style="border:0;"
allowfullscreen=""
loading="lazy">
</iframe>
```
> 💡 在 YouTube 或 Google 地圖上,點擊「分享」→「嵌入」,就可以直接複製 `<iframe>` 程式碼。
#### iframe 的安全性 `sandbox`
嵌入不受信任的第三方內容時,務必使用 `sandbox` 屬性來限制其權限,避免潛在的安全風險。
```html
<!-- 安全:限制所有權限 -->
<iframe src="https://untrusted-site.com" sandbox></iframe>
<!-- 安全:選擇性開放部分權限 -->
<iframe src="https://trusted-widget.com" sandbox="allow-scripts allow-same-origin"></iframe>
```
| `sandbox` 值 | 功能 |
| :--- | :--- |
| (無) | 允許所有權限。 |
| `allow-scripts` | 允許執行 JavaScript。 |
| `allow-same-origin` | 允許將內容視為同源。 |
| `allow-forms` | 允許提交表單。 |
<br/>
## 2.3 表格與資料展示
表格用於呈現結構化、二維的資料,例如課表、產品規格、財務報表等。
### 表格的基本結構
一個基本的表格由 `<table>`、`<tr>` (列)、`<th>` (表頭) 和 `<td>` (資料格) 組成。
#### 範例:簡單的學生資料表
```html
<table>
<tr>
<th>姓名</th>
<th>年齡</th>
<th>科系</th>
</tr>
<tr>
<td>小明</td>
<td>20</td>
<td>資訊工程</td>
</tr>
<tr>
<td>小華</td>
<td>21</td>
<td>電機工程</td>
</tr>
</table>
```
#### 範例說明
- `<table>`:整個表格的容器。
- `<tr>` (Table Row):定義表格中的一列。
- `<th>` (Table Header):定義表頭的儲存格,內容預設會**粗體**並**置中**。
- `<td>` (Table Data):定義一般的資料儲存格。
#### 顯示結果

---
### 表格的語意化結構
為了讓瀏覽器和螢幕閱讀器更好地理解表格的結構,建議使用 `<thead>`、`<tbody>` 和 `<tfoot>`。
| 標籤 | 功能 | 說明 |
| :--- | :--- | :--- |
| `<thead>` | 表格頭部 | 用於群組表頭內容。 |
| `<tbody>` | 表格主體 | 用於群組表格的主要資料。 |
| `<tfoot>` | 表格尾部 | 用於群組表格的頁腳內容,例如總計。 |
#### 範例:包含語意標籤的課表
```html
<table border="1">
<thead>
<tr>
<th>課程名稱</th>
<th>學分</th>
<th>時間</th>
</tr>
</thead>
<tbody>
<tr>
<td>網頁設計</td>
<td>3</td>
<td>星期一 9:00-12:00</td>
</tr>
<tr>
<td>資料庫系統</td>
<td>3</td>
<td>星期三 13:00-16:00</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">總學分</td>
<td>6</td>
</tr>
</tfoot>
</table>
```
> ✨ **優點**:語意化的結構有助於 SEO,並且在列印長表格時,`<thead>` 的內容可以在每一頁重複出現。
#### 顯示結果

---
### 合併儲存格
使用 `colspan` (水平合併) 和 `rowspan` (垂直合併) 屬性可以合併多個儲存格。
#### 範例:合併儲存格
```html
<table border="1">
<tr>
<th>項目</th>
<th>星期一</th>
<th>星期二</th>
</tr>
<tr>
<th>上午</th>
<td>國文</td>
<td>數學</td>
</tr>
<tr>
<th rowspan="2">下午</th>
<td colspan="2">自習</td>
</tr>
<tr>
<!-- 此處的儲存格已被合併,不需再寫 -->
</tr>
</table>
```
#### 範例說明
- `rowspan="2"`:讓「下午」這個表頭儲存格垂直合併 `2` 格的高度。
- `colspan="2"`:讓「自習」這個資料儲存格水平合併 `2` 格的寬度。
> ⚠️ `border="1"` 是舊的寫法,僅為示意,現代網頁應使用 CSS 來設定表格樣式。
#### 顯示結果

---
### 提升表格可及性
為了讓螢幕閱讀器能正確讀出表頭與資料的對應關係,可以使用 `<caption>` 和 `scope` 屬性。
- `<caption>`:為表格提供一個標題。
- `scope`:明確指定 `<th>` 是欄 (`col`) 的標題還是列 (`row`) 的標題。
#### 範例:具備可及性的表格
```html
<table border="1">
<caption>2024 年第一季產品銷售報表</caption>
<thead>
<tr>
<th scope="col">產品名稱</th>
<th scope="col">銷量</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">產品 A</th>
<td>1,500</td>
</tr>
<tr>
<th scope="row">產品 B</th>
<td>1,800</td>
</tr>
</tbody>
</table>
```
#### 顯示結果

<br/>
## 2.4 表單與使用者輸入
**表單 (Form)** 是網頁與使用者互動的主要方式。無論是登入、註冊、搜尋、問卷調查,都需要透過表單來收集資料。
### 基本表單結構 `<form>`
`<form>` 標籤是所有表單元素的容器。
| 屬性 | 功能 | 說明 |
| :--- | :--- | :--- |
| `action` | 提交位址 | 指定表單資料要被送到哪個後端 URL 進行處理。 |
| `method` | 提交方法 | `GET`:將資料附加在 URL 上送出,適合搜尋等非敏感操作。<br>`POST`:將資料放在 HTTP request body 中送出,較安全,適合登入、註冊等操作。|
---
### 輸入欄位 `<input>` 與標籤 `<label>`
`<input>` 是最核心的表單元素,而 `<label>` 用於說明該欄位的功能,對可及性至關重要。
#### 範例:使用者登入
```html
<form action="/login" method="POST">
<div>
<label for="username">帳號:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">密碼:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">登入</button>
</form>
```
#### 範例說明
- **`for` 與 `id` 的連結**:`<label>` 的 `for` 屬性值必須與對應 `<input>` 的 `id` 相同。這樣點擊標籤時,游標就會自動跳到輸入框中。
- **`name` 屬性**:這是將資料傳送到後端時所使用的「鍵」(key),**如果沒有 `name`,該欄位的資料就不會被送出**。
- **`type` 屬性**:決定了 `<input>` 的類型 (文字、密碼、數字等)。
#### 顯示結果

---
### 常見輸入類型 (`type` 屬性)
#### 1. 文字相關
```html
<!-- 一般文字 -->
<input type="text" placeholder="請輸入帳號" />
<!-- 密碼 (內容會以 ● 顯示) -->
<input type="password" name="password" placeholder="請輸入密碼" />
<!-- Email (在手機上會切換到有 @ 的鍵盤) -->
<input type="email" name="email" placeholder="請輸入Email" />
<!-- 電話號碼 (在手機上會切換到數字鍵盤) -->
<input type="tel" name="phone" placeholder="請輸入電話號碼" />
```
#### 顯示結果

#### 2. 選擇器
```html
<!-- 單選按鈕 (Radio Button) -->
<p>性別:</p>
<input type="radio" id="male" name="gender" value="male">
<label for="male">男性</label>
<input type="radio" id="female" name="gender" value="female">
<label for="female">女性</label>
<!-- 核取方塊 (Checkbox) -->
<input type="checkbox" id="agree" name="agree" value="yes">
<label for="agree">我同意服務條款</label>
```
> 💡 同一組 `radio` 按鈕必須使用**相同的 `name`**,才能達到單選的效果。
#### 顯示結果

#### 3. 日期與數字
```html
<!-- 數字 (可設定最大/最小值) -->
<input type="number" name="age" min="0" max="120">
<!-- 日期選擇器 -->
<input type="date" name="birthday">
<!-- 時間選擇器 -->
<input type="time" name="appointment">
```
#### 顯示結果

---
### 其他表單元素
#### `<select>` 下拉選單
```html
<label for="city">居住城市:</label>
<select id="city" name="city">
<option value="">請選擇</option>
<option value="taipei">台北市</option>
<option value="taichung" selected>台中市</option>
<option value="kaohsiung">高雄市</option>
</select>
```
- `<option>` 的 `value` 是送到後端的實際值。
- `selected` 屬性可以設定預設選項。
#### 顯示結果

#### `<textarea>` 多行文字輸入
```html
<label for="message">留言:</label>
<textarea id="message" name="message" rows="5" placeholder="請在此輸入您的訊息..."></textarea>
```
#### 顯示結果

#### `<button>` 按鈕
```html
<!-- 提交表單 (預設行為) -->
<button type="submit">送出</button>
<!-- 重置表單 (清空所有欄位) -->
<button type="reset">清除</button>
<!-- 一般按鈕 (通常搭配 JavaScript 使用) -->
<button type="button">點我</button>
```
#### 顯示結果

---
### 表單驗證
HTML5 提供內建的前端驗證功能,可以在資料送出前檢查格式。
| 屬性 | 功能 |
| :--- | :--- |
| `required` | 設為必填欄位。 |
| `minlength` / `maxlength` | 限制最小/最大字元數。 |
| `min` / `max` | 限制數字或日期的最小/最大值。 |
| `pattern` | 使用正則表達式自訂驗證規則。 |
#### 範例:帶有驗證的欄位
```html
<input type="password" name="password" minlength="8" required>
<input type="text" name="zipcode" pattern="[0-9]{3,5}" title="請輸入 3 到 5 位數字的郵遞區號">
```

### 進階表單元素 (補充)
#### `<fieldset>` 與 `<legend>` - 表單分組
當表單很長時,使用 `<fieldset>` 將相關欄位分組,並用 `<legend>` 加上標題,能讓結構更清晰。
```html
<form>
<fieldset>
<legend>個人資料</legend>
<label for="name">姓名:</label>
<input type="text" id="name" name="name">
</fieldset>
<fieldset>
<legend>聯絡方式</legend>
<label for="email">Email:</label>
<input type="email" id="email" name="email">
</fieldset>
</form>
```
#### 顯示結果

#### `<datalist>` - 輸入建議清單
提供輸入框的「自動完成」建議,使用者可以從清單選,也可以自己打字。
```html
<label for="browser">你最愛的瀏覽器:</label>
<input list="browsers" name="browser" id="browser">
<datalist id="browsers">
<option value="Chrome"></option>
<option value="Firefox"></option>
<option value="Safari"></option>
<option value="Edge"></option>
</datalist>
```
#### 顯示結果

<br/>
## 2.5 通用容器與與版面概念
在 HTML 中,我們會發現有些標籤會獨佔一行(如 `<h1>`),有些則會並排在同一行(如 `<a>`)。這是因為 HTML 元素主要分為兩大類顯示模式。這對於未來的 CSS 排版非常重要。
### 區塊元素 (Block Element) 與 行內元素 (Inline Element)
| 特性 | 區塊元素 (Block) | 行內元素 (Inline) |
| :--- | :--- | :--- |
| **換行行為** | **總是從新的一行開始**,並獨佔整行寬度。 | **不會換行**,只佔據內容所需的寬度,會與其他元素並排。 |
| **寬高設定** | 可以設定寬度 (`width`) 與高度 (`height`)。 | **無法**設定寬高,大小由內容決定。 |
| **常見標籤** | `<div>`, `<p>`, `<h1>`~`<h6>`, `<ul>`, `<li>`, `<form>`, `<table>` | `<span>`, `<a>`, `<img>`, `<strong>`, `<em>`, `<input>`, `<label>` |
| **巢狀規則** | 可以包含其他區塊元素或行內元素。 | 通常只能包含文字或其他行內元素,**不能**包含區塊元素。 |
> 💡 **簡單記憶法**:區塊元素像是「堆積木」,一塊疊一塊;行內元素像是「串珠珠」,一顆接一顆串在同一行。
> (註:`<img>` 屬於特殊的「行內區塊 (Inline-block)」,它雖然並排但不換行,卻可以設定寬高。)
---
### 通用容器標籤:`<div>` 與 `<span>`
當我們需要將內容分組以便排版或套用樣式,但現有的語意標籤(如 `<article>` 或 `<p>`)都不適合時,就會使用這兩個「無語意」的通用容器。
#### 1. `<div>` (Division) - 區塊容器
`<div>` 是最常用的**區塊元素**,用於將網頁內容劃分為大的區塊。
```html
<div class="card">
<h3>卡片標題</h3>
<p>這是卡片的內容。</p>
</div>
```
#### 2. `<span>` - 行內容器
`<span>` 是常用的**行內元素**,用於包裹文字中的一小部分,以便單獨設定樣式。
```html
<p>這是一段文字,其中 <span style="color: red;">這幾個字</span> 是紅色的。</p>
```
> ⚠️ **注意**:`<div>` 和 `<span>` 本身沒有任何語意。在 HTML5 中,應優先使用 `<nav>`, `<header>`, `<article>` 等有語意的標籤,真的沒有合適的標籤時才使用 `<div>`。
<br/>
## 2.6 HTML 進階屬性
### 全域屬性 - 所有元素都可用
以下屬性可以用於任何 HTML 元素,提供額外的功能:
#### contenteditable - 可編輯內容
讓任何元素的內容變成可編輯狀態:
```html
<div contenteditable="true">
點擊這裡可以直接編輯文字!
</div>
```
**用途:**
- 簡易的所見即所得 (WYSIWYG) 編輯器。
- 讓使用者能即時修改頁面上的文字。
#### 顯示結果

---
#### hidden - 隱藏元素
`hidden` 屬性完全隱藏元素,其效果類似 CSS 的 `display: none`。
```html
<!-- 這段文字在畫面上完全不可見 -->
<p hidden>這是一則隱藏的訊息。</p>
<!-- 可以用 JavaScript 動態切換 hidden 狀態 -->
<button onclick="document.getElementById('message').hidden = !document.getElementById('message').hidden">
顯示/隱藏
</button>
<p id="message" hidden>這是一則可以被切換的訊息。</p>
```
**`hidden` vs `display: none`:** 雖然效果相似,但 `hidden` 屬性帶有更強的語意,表示該內容在**目前**對使用者是**不相關**的。
---
#### tabindex - Tab 鍵導覽順序
控制元素在鍵盤導航(按 `Tab` 鍵)時的順序。
| `tabindex` 值 | 行為 |
| :--- | :--- |
| `正整數 (1, 2, ...)` | 明確指定 Tab 鍵的跳轉順序。**不建議使用**,因為難以維護且容易破壞自然的導覽流程。 |
| `0` | 讓原本無法被 Tab 鍵聚焦的元素(如 `<div>`, `<span>`)可以被聚焦,並依照其在 DOM 中的自然順序排列。 |
| `-1` | 讓元素無法被 Tab 鍵聚焦,但仍然可以透過 JavaScript 的 `.focus()` 方法使其獲得焦點。 |
```html
<!-- 這個 div 現在可以被 Tab 鍵選取到 -->
<div tabindex="0">可聚焦的區塊</div>
<!-- 這個按鈕會被 Tab 鍵跳過 -->
<button tabindex="-1">無法透過 Tab 聚焦</button>
```
> ⚠️ **最佳實務**:避免使用正整數的 `tabindex`。讓 DOM 結構的順序來決定自然的導覽順序是最好的作法。只有在需要讓非互動元素可聚焦時才使用 `tabindex="0"`。
---
### 📝 選擇練習題:HTML 的內容結構
**1. 下列何者是建立超連結的正確語法?**
- A) `<link href="page.html">點我</link>`
- B) `<a href="page.html">點我</a>`
- C) `<url src="page.html">點我</url>`
- D) `<hyperlink to="page.html">點我</hyperlink>`
<details>
<summary>點選查看答案</summary>
答案: B) `<a href="page.html">點我</a>`
</details>
**2. 若要讓超連結在新分頁開啟,應使用哪個屬性?**
- A) `new="true"`
- B) `target="_blank"`
- C) `window="new"`
- D) `open="tab"`
<details>
<summary>點選查看答案</summary>
答案: B) `target="_blank"`
</details>
**3. 下列哪個標籤用於建立無序清單?**
- A) `<ol>`
- B) `<ul>`
- C) `<list>`
- D) `<menu>`
<details>
<summary>點選查看答案</summary>
答案: B) `<ul>`
</details>
**4. `<img>` 標籤中,哪個屬性用於描述圖片內容(對視障人士重要)?**
- A) `title`
- B) `description`
- C) `alt`
- D) `caption`
<details>
<summary>點選查看答案</summary>
答案: C) `alt`
</details>
**5. 在表格中,下列哪個標籤用於定義標題欄位(通常是粗體)?**
- A) `<td>`
- B) `<th>`
- C) `<tr>`
- D) `<thead>`
<details>
<summary>點選查看答案</summary>
答案: B) `<th>`
</details>
**6. 若要合併表格的兩個欄位,應使用哪個屬性?**
- A) `merge="2"`
- B) `span="2"`
- C) `colspan="2"`
- D) `columns="2"`
<details>
<summary>點選查看答案</summary>
答案: C) `colspan="2"`
</details>
**7. 表單中,下列哪種 input type 會隱藏輸入的內容?**
- A) `type="text"`
- B) `type="hidden"`
- C) `type="password"`
- D) `type="secret"`
<details>
<summary>點選查看答案</summary>
答案: C) `type="password"`
</details>
---
#### 綜合應用題
**8. 小明想建立一個點擊圖片就能跳轉到關於我們頁面的功能,下列哪個寫法正確?**
- A) `<img src="logo.png" href="about.html" alt="關於我們" />`
- B) `<a href="about.html"><img src="logo.png" alt="關於我們" /></a>`
- C) `<img><a href="about.html" src="logo.png">關於我們</a></img>`
- D) `<link href="about.html"><img src="logo.png" /></link>`
<details>
<summary>點選查看答案</summary>
答案: B)`
**解析:**
- A) 錯誤:`<img>` 標籤沒有 `href` 屬性
- B) 正確:將 `<img>` 放在 `<a>` 標籤內部,整個圖片就變成可點擊的連結
- C) 錯誤:`<img>` 是自閉合標籤,不能包含其他標籤;且 `src` 屬性應在 `<img>` 上
- D) 錯誤:`<link>` 是用於引入外部資源(如 CSS),不是超連結標籤
</details>
**9. 下列關於表格結構的敘述,何者正確?**
- A) `<table>` 內可以直接放 `<td>`,不需要 `<tr>`
- B) `<th>` 只能用在表格的第一行
- C) 一個 `<tr>` 可以同時包含 `<th>` 和 `<td>`
- D) `<thead>`、`<tbody>`、`<tfoot>` 必須全部都使用,不能只用其中一個
<details>
<summary>點選查看答案</summary>
答案: C) 一個 `<tr>` 可以同時包含 `<th>` 和 `<td>`
**解析:**
- A) 錯誤:`<td>` 必須放在 `<tr>` 內,表示「這個儲存格屬於哪一列」
- B) 錯誤:`<th>` 可以用在任何位置,既可以是欄位標題(第一行),也可以是列標題(第一欄)
- C) 正確:例如第一欄用 `<th>` 作為列標題,其他欄位用 `<td>` 放資料
- D) 錯誤:這些標籤是選用的,可以只使用其中部分或完全不使用
</details>
**10. 若要建立一個註冊表單,包含帳號、密碼、Email、送出按鈕,下列哪個結構最完整且符合最佳實務?**
- A) `<form><input type="text" placeholder="帳號">...</form>`
- B) `<form action="/register" method="post"><label for="username">帳號:</label>...</form>`
- C) `<div><input type="text">帳號...</div>`
- D) `<form>帳號:<input type="text"><br>...</form>`
<details>
<summary>點選查看答案</summary>
答案: B)
**解析:**
選項 B 最完整且符合最佳實務,原因:
1. ✅ 使用 `<form>` 標籤並設定 `action` 與 `method` 屬性。
2. ✅ 每個輸入欄位都有對應的 `<label>`,並透過 `for` 與 `id` 正確連結,提升可及性。
3. ✅ 每個 `input` 都有 `name` 屬性,確保資料能被後端接收。
4. ✅ 使用 `required` 屬性進行前端必填驗證。
5. ✅ 按鈕明確指定 `type="submit"`。
</details>
**11. 下列關於清單與連結的組合使用,何者最符合語意且常見於網站導覽列?**
- A) `<ul><a href="#">首頁</a><a href="#">關於</a></ul>`
- B) `<nav><a href="#">首頁</a> | <a href="#">關於</a></nav>`
- C) `<ul><li><a href="#">首頁</a></li><li><a href="#">關於</a></li></ul>`
- D) `<ol><a><li href="#">首頁</li></a><a><li href="#">關於</li></a></ol>`
<details>
<summary>點選查看答案</summary>
答案: C) `<ul><li><a href="#">首頁</a></li><li><a href="#">關於</a></li></ul>`
**解析:**
標準的導覽列結構是使用無序清單 `<ul>`,其中每個清單項目 `<li>` 包含一個超連結 `<a>`。
</details>