9.

HTML a タグ href 完全ガイド — 絶対/相対/フラグメント/Laravel route

編集
この記事の要点
  • 絶対 URL: https://example.com/page ← 外部サイト
  • ルート相対: /path/page ← 同一ドメイン、サイトルートから
  • 相対 URL: ../page ← 現在のページからの相対
  • フラグメント: #section ← ページ内ジャンプ
  • 特殊スキーム: mailto: / tel: / sms:

href の基本

HTML <a> タグの href 属性はリンク先 URL を指定します。URL の書き方は複数あり、用途で使い分けます。

主な href の種類

種類解決先
絶対 URLhttps://example.com/pageそのまま
プロトコル相対//example.com/page現在のスキーム (http/https)
ルート相対/path/pageサイトルートから
相対 (同階層)page.html現在ディレクトリから
相対 (親階層)../page.html1 階層上から
フラグメント#section同ページ内
クエリ?id=1現在 URL にクエリ追加
mailto:mailto:foo@example.comメールクライアント起動
tel:tel:+81-3-1234-5678電話アプリ起動
javascript:javascript:void(0)JS 実行 (非推奨)

絶対 URL

外部サイトへのリンク、SNS シェア、メールに貼るリンク等は絶対 URL:

<a href="https://example.com/article/123" target="_blank" rel="noopener noreferrer">
  外部記事
</a>

<!-- プロトコル相対 (https/http どちらでも追従) -->
<!-- ※ 現代はすべて https なので非推奨 -->
<a href="//cdn.example.com/lib.js">CDN</a>

ルート相対 (推奨)

同一ドメイン内のリンクにはルート相対が無難:

<!-- 現在の URL が何であれ /about に飛ぶ -->
<a href="/about">About</a>
<a href="/products/laptop">ノートパソコン</a>

<!-- スラッシュで始めるのがポイント -->
<a href="/css/main.css">スタイル</a>

利点:

  • 現在のページ階層に依存しないので壊れにくい
  • ステージング / 本番のドメインが違っても同じパスで動く
  • SSR / 静的サイトジェネレータと相性◎

相対 URL

現在のページからの相対パス。ファイルシステムベースのサイトで使います:

<!-- 現在 /blog/2024/article.html の場合 -->
<a href="next.html">/blog/2024/next.html へ</a>
<a href="../2023/old.html">/blog/2023/old.html へ</a>
<a href="../../about.html">/about.html へ</a>
<a href="./page.html">同階層 (= page.html)</a>

注意: ベース URL は <base href> タグで変更可能 (後述)。

フラグメント (ページ内リンク)

<!-- 同ページの id="section1" にジャンプ -->
<a href="#section1">セクション 1 へ</a>

<h2 id="section1">セクション 1</h2>

<!-- 別ページの特定セクションへ -->
<a href="/article/123#comments">コメント欄</a>

<!-- 最上部へ -->
<a href="#">先頭へ</a>
<a href="#top">先頭へ (top はブラウザ既定)</a>

<!-- スクロール挙動を JS で滑らかに -->
<style>
  html { scroll-behavior: smooth; }
</style>

クエリパラメータ

<!-- 現在 URL にクエリだけ変更 -->
<a href="?page=2">次ページ</a>

<!-- 既存のクエリも維持したい場合は JS 必須 -->
<a href="?page=2&sort=date">並び替え</a>

<!-- 検索フォームのリンク -->
<a href="/search?q=html&lang=ja">HTML 検索</a>

特殊スキーム

<!-- メール -->
<a href="mailto:contact@example.com">お問い合わせ</a>
<a href="mailto:contact@example.com?subject=資料請求&body=お世話になります">資料請求</a>
<a href="mailto:a@x.com,b@x.com?cc=c@x.com&bcc=d@x.com">複数宛先</a>

<!-- 電話 (モバイルでタップで発信) -->
<a href="tel:+81-3-1234-5678">03-1234-5678</a>
<a href="tel:0312345678">国内表記でも可</a>

<!-- SMS -->
<a href="sms:+81-90-1234-5678?body=こんにちは">SMS</a>

<!-- ファイルダウンロード -->
<a href="/files/manual.pdf" download>マニュアルをダウンロード</a>
<a href="/files/data.csv" download="export-2024.csv">CSV を保存</a>

JavaScript URL (非推奨)

<!-- ❌ 非推奨: CSP / セキュリティで弾かれる -->
<a href="javascript:alert('hi')">クリック</a>
<a href="javascript:void(0)" onclick="doSomething()">処理</a>

<!-- ✅ 推奨: button を使う -->
<button type="button" onclick="doSomething()">処理</button>

<!-- ✅ どうしても a タグなら -->
<a href="#" onclick="event.preventDefault(); doSomething();">処理</a>

target / rel / download 属性

<!-- 新タブ (必ず rel="noopener noreferrer" を付ける) -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  外部
</a>

<!-- iframe 内のリンクを親フレームに -->
<a href="/page" target="_parent">親に開く</a>
<a href="/page" target="_top">最上位に開く</a>

<!-- ダウンロード強制 -->
<a href="/files/report.pdf" download>レポート</a>

<!-- リンク先言語 -->
<a href="/en/article" hreflang="en">English</a>

<!-- リンク種類 -->
<a href="https://shop.example.com" rel="sponsored noopener">広告</a>

Laravel での書き方

Laravel では URL ヘルパー / ルートヘルパーを使うと、ルート定義変更時にも壊れません:

// Blade テンプレ

// 1. ルート名で生成 (推奨)
<a href="{{ route('home') }}">ホーム</a>
<a href="{{ route('article.show', ['id' => 123]) }}">記事 123</a>

// 2. URL ヘルパー
<a href="{{ url('/about') }}">About</a>
<a href="{{ url('/article/' . $id) }}">記事</a>

// 3. asset ヘルパー (CSS / JS / 画像)
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<img src="{{ asset('images/logo.png') }}" alt="ロゴ">

// 4. 現在のクエリを保持
<a href="{{ url()->current() }}?page=2">次ページ</a>
<a href="{{ request()->fullUrlWithQuery(['page' => 2]) }}">次ページ</a>

// 5. ログインユーザーのプロフィールへ
<a href="{{ route('users.show', auth()->id()) }}">マイページ</a>

routes/web.php 側:

Route::get('/article/{id}', [ArticleController::class, 'show'])->name('article.show');
Route::get('/', [HomeController::class, 'index'])->name('home');

<base href> (相対パスのベースを変更)

<!DOCTYPE html>
<html>
<head>
  <!-- すべての相対 URL がこのベースから解決される -->
  <base href="https://cdn.example.com/v2/">
</head>
<body>
  <!-- → https://cdn.example.com/v2/img.png -->
  <img src="img.png">
  <!-- → https://cdn.example.com/v2/page.html -->
  <a href="page.html">ページ</a>
</body>
</html>

SPA や iframe 多用ページで便利。ただし副作用 (フラグメント #anchor も絶対 URL 化される) があるので慎重に。

href の選び方フローチャート

  • 外部サイトへのリンク? → 絶対 URL + target="_blank" rel="noopener noreferrer"
  • 同サイト内?
    • 同ページ内ジャンプ → フラグメント (#id)
    • サーバサイドルーティング (Laravel/Rails) → ルート相対 (route ヘルパー推奨)
    • 静的サイト (HTML 直書き) → ルート相対
  • メール / 電話アプリ起動 → mailto: / tel:
  • ファイルダウンロード → 絶対 or ルート相対 + download
  • JS 実行のみ → button タグに置き換える

FAQ

Q: 相対 URL とルート相対 URL、どちらを使うべき?
A: 個別ファイルでサイト構成が変わらないなら相対でも OK。テンプレ展開やリファクタリングが多いプロジェクトはルート相対 (または route ヘルパー) が壊れにくい。

Q: href="" (空) はどうなる?
A: 現在のページを再読み込みします (POST 後の意図しない再送信に注意)。意図せず空になっていないかチェック。

Q: SPA で a タグだと全リロードしてしまう
A: フレームワーク標準の Link コンポーネント (Next.js Link, Vue Router RouterLink) を使うと SPA 遷移になります。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Templateの使用準備
  2. Template の定義方法
  3. テンプレートの作成と共通化
  4. setting.pyにおけるテンプレートの設定
  5. テンプレートの名前の重複について
  6. 静的ファイルの読み込み
  7. if文
  8. テンプレートで定数を使用する方法
  9. aタグのhrefの記載方法

最近更新/作成されたページ