2つの相対パスがあって混乱したのでまとめた。
方法
HTMLでパスを指定するときは以下のちがいを理解しておく必要がある。
| パス表記方法 | HTML内パス | URLが{base_url}/about/時のHTML内パス |
|---|---|---|
| 絶対パス | {base_url}/css/style.css |
{base_url}/css/style.css |
| ルート相対パス | /css/style.css |
{base_url}/css/style.css |
| ファイル相対パス | css/style.css./css/style.css../css/style.css |
{base_url}/about/css/style.css{base_url}/about/css/style.css{base_url}/css/style.css |
背景
静的サイトジェネレータzolaは、おなじページを以下のような異なるURLで参照できてしまう。
{base_url}/about{base_url}/about/
このときファイル相対パスだと、一階層分../の違いが生じてパスが変化し参照できなくなってしまうことがある。
使い分け
| 方法 | 動機 |
|---|---|
| 絶対パス | 異なる階層から参照されうる。 |
| ルート相対パス | ドメインを省略したい。異なる階層から参照される。 |
| ファイル相対パス | パスも省略したい。同じ階層からしか参照されない。 |
<link rel="stylesheet" href="https://example.com/css/style.css"><!--絶対パス--> <link rel="stylesheet" href="/css/style.css"><!--ルート相対パス--> <link rel="stylesheet" href="css/style.css"><!--ファイル相対パス--> <link rel="stylesheet" href="./css/style.css"><!--ファイル相対パス--> <link rel="stylesheet" href="../css/style.css"><!--ファイル相対パス-->
zolaではルート相対パスを使うべき。なぜならzolaのページは必ず、末尾に/がつくときとつかないときの2種類ある。よって異なる階層から参照されることを想定したパス指定にすべきだ。
HTMLにおけるURL参照
これはzolaのせいではなくHTMLやURLの参照仕様だと思われる。そこで、あらためてHTMLにおけるURL参照について整理してみた。
{base_url}=https://example.comとする。このときstyle.cssファイルへのURL指定方法は以下の4通りある。
| パス | 意味 |
|---|---|
style.css |
現在HTMLが存在するディレクトリからの相対パス |
./style.css |
現在HTMLが存在するディレクトリからの相対パス |
/style.css |
{base_url}からの相対パス |
https://example.com/style.css |
絶対パス |
絶対パスは明確だからわかりやすい。これを使えば今回の罠にかかることもない。ただ、ドメイン名が変更されたりしたときなどで変更が面倒になる。なので相対パスを使いたい。だが、その相対パスが厄介だ。
相対パス
問題は相対パスだ。わずかな表現のちがいでありながら、まったくことなるパスを指す。これがじつに紛らわしい。
| パス | 意味 |
|---|---|
/style.css |
{base_url}からの相対パス |
style.css |
現在HTMLが存在するディレクトリからの相対パス |
./style.css |
現在HTMLが存在するディレクトリからの相対パス |
さらにまとめてみる。
相対パスには2種類ある。基準となるパスが違う。
| 基準 | URL先頭 |
|---|---|
ルートディレクトリ({base_url}) |
/ |
| 現在HTMLディレクトリ | なにもつけない or ./ |
Linuxのファイルシステムに似ている。ルートは/で表現されるから。先頭/の相対パスはドメイン名を省略できるものだと覚えておけばいい。
URLが{base_url}/about/だとしたら、以下のようになる。
| 相対パス | 参照パス |
|---|---|
/style.css |
{base_url}/style.css |
style.css |
{base_url}/about/style.css |
./style.css |
{base_url}/about/style.css |
現在HTMLが存在するディレクトリを基準にして、その親をたどっていくパス指定もできる。
| パス | 意味 |
|---|---|
../style.css |
現在HTMLが存在するディレクトリからの相対パス(親ディレクトリ) |
../../style.css |
現在HTMLが存在するディレクトリからの相対パス(2親ディレクトリ) |
たどる親の数だけ../を足していけばいい。
区別するために名前をつける。
| 名前 | 例 | URLが{base_url}/about/時のパス |
|---|---|---|
| ルート相対パス | /style.css |
{base_url}/style.css |
| ファイル相対パス | style.css./style.css../style.css |
{base_url}/about/style.css{base_url}/about/style.css{base_url}/style.css |
ファイル相対パス
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="./css/style.css">
パスの先頭になにもつけないか./をつけると、現在ファイルがあるディレクトリからの相対パスになる。
このとき、URLが{base_url}/のように末尾に/がつくとCSSが参照できなくなってしまう。なぜならつぎのようなパスになるからだ。
| URL | 参照パス |
|---|---|
{base_url}/about |
{base_url}/css/style.css |
{base_url}/about/ |
{base_url}/about/css/style.css |
実際にCSSが存在するパスは{base_url}/css/style.cssなので以下のようになる。
| URL | 参照パス | 存在是非 |
|---|---|---|
{base_url}/about |
{base_url}/css/style.css |
⭕ |
{base_url}/about/ |
{base_url}/about/css/style.css |
❌ |
URL末尾に/があるかないか。それだけで参照できなくなってしまうバグとなる。もうそれだけでも大問題なのだが、さらに問題がある。
以下のようにすれば一応、参照できる。
<!-- {base_url}/about --> <link rel="stylesheet" href="css/style.css"> <!-- {base_url}/about/ --> <link rel="stylesheet" href="../css/style.css">
ただ、実際に存在しているのはひとつだけだ。それ以外のURLは参照エラーになってしまう。ブラウザの開発ツールでコンソールを開いたらエラーになっているのがわかる。キモチワルイ。
よって、異なる階層から参照されるときはルート相対パスで指定すべきである。
ルート相対パス
<link rel="stylesheet" href="/css/style.css">
パスの先頭に/をつけると、ルートからの相対パスになる。
このときはURLの末尾に/があってもなくても、CSSを参照できる。
なぜならURLに関わらずパスは必ず{base_url}/css/style.cssになるからだ。
結論
異なる階層から参照されうるときはルート相対パスを使おう。
つまるところ、URL指定するときは以下の要点を理解しておけばよい。
| パス表記方法 | HTML内パス | URLが{base_url}/about/時のHTML内パス |
|---|---|---|
| 絶対パス | {base_url}/css/style.css |
{base_url}/css/style.css |
| ルート相対パス | /css/style.css |
{base_url}/css/style.css |
| ファイル相対パス | css/style.css./css/style.css../css/style.css |
{base_url}/about/css/style.css{base_url}/about/css/style.css{base_url}/css/style.css |
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 5.4.83-v7l+ #1379 SMP Mon Dec 14 13:11:54 GMT 2020 armv7l GNU/Linux