質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

4703閲覧

CSS で url() 相対パスの解決がうまくいかない

a_eau_

総合スコア5

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

5グッド

6クリップ

投稿2020/02/06 07:07

発生している問題

前任者から引き継いだウェブサイトが Chrome のみの対応で、これを Edge にも対応させようとしていますが、未解決の問題があり、質問させていただきます。

CSS のカスタムプロパティに url() を相対パスで指定しましたが、これを別の階層から呼び出したときに取得される絶対パスがブラウザによって異なるため困っています。

具体的には、以下のように ./index.html のインライン CSS でカスタムプロパティ --icon を設定し、それを外部 CSS ./css/test.css で呼び出すという流れになっています。Chrome では ./css/icon.png が参照されますが、Edge (EdgeHTML) では ./icon.png が呼ばれてしまいます。

html

1<link rel=”stylesheet” type=”text/css” href=”css/test.css”> 2... 3<p style="--icon: url(icon.png);">見出しです</h1> 4...

css

1p { 2 background-image: var(--icon); 3}

CSS の url() は相対パスを指定すると当該 CSS をベースURLとして使いますから、Chrome のように ./css/test.css と同じ階層にある ./css/icon.png を取ってきてほしいのですが、Edge では ./index.html をベースURLとして使っているようです。

カスタムプロパティを使わずに CSS を以下のように書けば、Edge でも ./css/icon.png を探してくれます。Edge ではカスタムプロパティ設定の段階で計算が行われ絶対パスに解決されてしまうのか? あるいは謎の最適化が悪さをしているのか? よくわかりません。

css

1p { 2 background-image: url(icon.png); 3}

どちらの挙動が仕様書に則ったものなのか調べてみましたが、url() の相対パスが絶対化されるタイミング(指定値→算出値?)とカスタムプロパティを var() で呼ぶタイミングがどう関連しているのかわかりませんでした。

知りたいこと

Chrome (Chromium) の挙動と Edge (EdgeHTML) の挙動のどちらが仕様書に則っているのか、またどうすれば2つのブラウザで同じ場所を参照できるのか、ご教授いただければ幸いです。

Lhankor_Mhy, GenbuHase, x_x, zu2, thyda.eiqau👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2020/02/06 07:25

質問から外れますが、Chromium Edge の配布が始まっていますので、緊急の案件ではないなら今後の動向を見てから改修した方がいいのではないでしょうか。 > Microsoftは、Windows 10 HomeおよびPro(ただし、Active DirectoryやAzure Active Directoryに参加しているデバイスは除く)に対し、今後数カ月かけてWindows Updateの自動更新で新しいMicrosoft Edgeに置き換えていく予定です。 https://www.atmarkit.co.jp/ait/articles/2001/28/news005.html
a_eau_

2020/02/06 07:45

そうですよね。Chromium Edge で試すと(当然ですが)Chrome と同じ挙動をしました。どうしてもこの仕組みでないと駄目、というわけでもないので、当座は質問中にも書いたようなカスタムプロパティを使わないやり方でしのごうかと考えています。
miyabi_takatsuk

2020/02/06 07:48

本件は、ローカルで開いていますか? それとも、サーバー(ローカルサーバー含む)で開いていますか?
a_eau_

2020/02/06 07:55

Edge はローカルがダメという話はぼんやり聞いたことがありますが、失念していました。参照がずれるという問題自体はサーバーでもローカルでも発生していますが、その後の試行錯誤はローカルでしか試していません。
miyabi_takatsuk

2020/02/06 07:58 編集

いえ、そういう問題ではないんです。 パスを相対パスにする以外の方法を勧めるために、サーバーか否かの確認でした。 ローカルで実行しているのなら、私がしようとしていた回答は、無効になっちゃいますね。 JS使うとかならありかもですが。
guest

回答1

0

ベストアンサー

CSS の仕様を見てきましたが、個人的には「Edgeが正しい」と読みました。

The url() functional notation, denoted by <url>, represents a URL

, which is a pointer to a resource.
3.4. Resource Locators: the <url> type | CSS Values and Units Module Level 3

(勝手訳)
url() 関数記法は、<url>と表記され, リソースへのポインタであるURLを表します。

そしてfunctional notation(関数表記)とは何かというと、このように書かれています。

A functional notation is a type of component value that can represent more complex types or invoke special processing.

CSS Values and Units Module Level 3

(勝手訳)
関数記法は、複合タイプや特別な処理呼び出しを表す、値のコンポーネントタイプです。

url()が呼び出している特殊な処理については、やはり仕様に書かれています。

Relative URLs (as defined in [URL]) are resolved to full URLs using a base URL. RFC 3986, section 3, defines the normative algorithm for this process.

3.4.1. Relative URLs | CSS Values and Units Module Level 3

(勝手訳)
相対URLはベースURLを用いて完全なURLに解決されます。RFC 3986, section 3 に、このプロセスで用いる標準アルゴリズムが定義されています。

というわけで、相対パスを絶対パスに変換する処理は、url()に呼び出され、完全なURLが解決され、リソースへのポインタを返す、と解釈していいかと思います。


傍証として、同じ関数記法のcalc()の仕様を挙げます。

Where percentages are not resolved at computed-value time, they are not resolved in calc() expressions, e.g. calc(100% - 100% + 1em) resolves to calc(1em + 0%), not to 1em. If there are special rules for computing percentages in a value (e.g. the height property), they apply whenever a calc() expression contains percentages.

8.1.3. Computed Value | CSS Values and Units Module Level 3

(勝手訳)
パーセンテージが値計算時に解決されない場合、それは calc() 表記で解決しません。たとえば、calc(100% - 100% + 1em) は calc(1em + 0%) として解決されます。1em ではありません。(height プロパティのように)パーセンテージの計算に特別なルールがある場合、calc() 表記に含まれていたパーセンテージは必ずそのルールが適用されます。

相対URLもパーセンテージも、適用される文脈が関わるという意味で同じです。
もし、関数記法が「適用される文脈が変数使用時である」という仕様であるならば、calc()のこの部分の処理は記述されなくてよいものであるでしょう。


ところで、しかしそうすると、Chromeでは以下のようなことが起きるのですね……
うっかりしそうなので、気をつけたいです。

css

1/* /css/b.css */ 2p { 3 background-image: var(--icon); 4} 5 6/* 7 * ↑と↓は違うファイルを見る。 8 */ 9 10/* /css/module/c.css */ 11p.hoge { 12 background-image: var(--icon); 13}

投稿2020/02/06 10:18

Lhankor_Mhy

総合スコア36960

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi_takatsuk

2020/02/06 10:26

横槍すみません。 めちゃ勉強になりました。 なるほど・・・。 確かに、仕様に則るなら、 あくまで、url()実行時のファイルからのパスとしているEdgeの方が正しいですね。 どちらの挙動が良いかは別として・・・。 (どちらもメリットデメリットありそう)
Lhankor_Mhy

2020/02/06 11:01

ありがとうございます。私見なので正しいのかどうかわかりませんが…… 相対URLの次の項にも、「フラグメントだけのパスの時には、フラグメントだけとして扱え」と書いてあって、これも Chrome の解釈が正しいなら必要のない注記ですよね……? いや違うのかな? https://www.w3.org/TR/css-values-3/#local-urls
a_eau_

2020/02/06 11:25

回答ありがとうございました。仕様書の抄訳もたいへん参考になりました。 Chrome としては、カスタムプロパティは設定時には利用されない(つまり、--icon: url(icon.png) と指定しただけでは属性値が何にも適用されていない)から、url() 実行は先延ばしにしよう、という「気持ち」なのでしょうかね。気をつけよう……。
a_eau_

2020/02/06 11:53

いやしかし、挙げていただいたcalc() の部分を読んでいて思い直しましたが、calc() は呼び出す環境によってemや%の基準が違いますよね。たとえば --size: calc(1em+5pt) としておいて、font-size: 10ptの場所でvar(--size)を呼び出した場合とfont-size: 15ptの場所でvar(--size)を呼び出した場合とでは、ChromeもEdgeもvar(--size)の値が相対的に変わりますよね。それは呼び出される環境によってemや%が依存するベースが異なるからで、仕様書の「calc(1em+0%)であって1emでない」というのは、そのような場合は計算を先延ばしにするという宣言のようにも読めます。だとするとurl()もやはり、呼び出される環境によって依存するベースが異なりうるのだから、Chromeのように呼び出されるごとに計算されるのが一貫した態度のようにも思えます。
Lhankor_Mhy

2020/02/06 13:07

そうですね。そうかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問