跳到主要內容
← 回到學習

學習 · 前端基礎

html link作法

目錄 · 6 個段落
  1. 01四種寫法比較(三種是錯的)
  2. 02為什麼不能用 <button> 模擬連結
  3. 03為什麼不能互相包
  4. 04想要連結看起來像按鈕?用 CSS
  5. 05何時真的該用 <button>
  6. 06React / Next.js 注意事項

HTML 連結作法:<a> vs <button>

TL;DR
連結用 <a href>、行為用 <button>,永遠不要把它們互相包。語意正確 = 鍵盤可達 + 螢幕閱讀器友善 + SEO 給分。

四種寫法比較(三種是錯的)

<!-- ✅ 正確:用 <a> -->
<a href="https://example.com">Link</a>
 
<!-- ⚠️ 不推薦:<button> 模擬連結 -->
<button onclick="location.href='https://example.com'">Link</button>
 
<!-- ❌ 錯誤:<a> 包 <button> -->
<a href="https://example.com"><button>Link</button></a>
 
<!-- ❌ 錯誤:<button> 包 <a>(在 HTML 規範上是 invalid) -->
<button><a href="https://example.com">Link</a></button>
html
方式鍵盤螢幕閱讀器SEO中鍵新分頁Cmd+Click推薦
<a href>✅ Tab + Enter「連結」✅ 爬蟲抓得到✅✅⭐
<button> + JS✅ Tab + Enter/Space「按鈕」❌ 看不到 href❌ 不行❌ 不行❌
<a><button></a>⚠️ 雙焦點混亂✅✅✅❌
<button><a></button>⚠️ HTML 違規混亂—❌❌❌

為什麼不能用 <button> 模擬連結

1. 失去原生連結行為

<a href> 自帶的功能用 <button onclick> 全沒了:

  • 中鍵點擊開新分頁
  • Cmd/Ctrl + Click 在背景開新分頁
  • 右鍵選單(複製連結、新視窗開啟)
  • 拖曳到書籤列

2. SEO 爬不到

Google 爬蟲解析 href 屬性,看不到 onclick handler 裡的 URL。把連結藏在 button 裡 = 從搜尋引擎隱形。

3. 螢幕閱讀器念錯角色

VoiceOver / NVDA 念到 <a> 會說「連結 ...」,念到 <button> 會說「按鈕 ...」。==使用者預期不同——按鈕 = 觸發動作、連結 = 跳轉==,弄混會讓視障使用者困惑。


為什麼不能互相包

<a> 包 <button>

雙重 focusable element → Tab 鍵會經過兩次,鍵盤體驗破碎。

<button> 包 <a>

HTML 規範 不允許 <button> 內含互動元素(HTML Spec:「No interactive content descendants」)。瀏覽器會用各種方式「修正」這個錯誤,行為不一致。


想要連結看起來像按鈕?用 CSS

<a href="/signup" class="btn">Sign Up</a>
html
.btn {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  background: var(--color-accent);
  color: white;
  border-radius: 0.5rem;
  text-decoration: none;
  font-weight: 600;
}
.btn:hover { background: var(--color-accent-hover); }
.btn:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
css

語意 + 視覺分離 —— 這才是 CSS 的本意。


何時真的該用 <button>

純 前端行為(不跳轉 URL)的時候:

<button type="button" onclick="toggleModal()">Open Modal</button>
<button type="submit">Submit Form</button>
<button type="button" onclick="copyToClipboard()">Copy</button>
html
判斷準則
點擊後 URL 會變嗎?
  • 會 → &lt;a href&gt;
  • 不會 → &lt;button&gt;

React / Next.js 注意事項

// ✅ Next.js Link
import Link from 'next/link';
<Link href="/about">About</Link>
 
// ❌ 用 router.push 在 <button> 裡(失去所有原生連結行為)
<button onClick={() => router.push('/about')}>About</button>
tsx

<Link> 內部會 render 成 <a>,所以同樣享有 Cmd+Click、新分頁、SEO 等好處。

目錄