以下のような挙動があって混乱したのでメモ。
ファイル構成
index.html
<link rel="stylesheet" href="main.css">
<script src="main.js" async></script>
main.css
@import url("external.css");
html {
font-size: 62.5%;
}
external.css
/* empty file */
main.js
console.log(getComputedStyle(document.body).fontSize)
setTimeout(function () {
console.log(getComputedStyle(document.body).fontSize)
}, 500)
コンソールへの出力結果
想定した出力
10px
10px
実際の出力
16px
10px
つまり…
最初のconsole.log()
時に以下のスタイルが未適用の状態になっているっぽい。
html {
font-size: 62.5%;
}
回避方法
追記:実際には回避できてないかもしれないので↓のコメントも参照。
1. @import
を使わずlink
タグで読み込む
index.html
+<link rel="stylesheet" href="external.css">
<link rel="stylesheet" href="main.css">
<script src="main.js" async></script>
main.css
-@import url("external.css");
-
html {
font-size: 62.5%;
}
2. link
タグを使わずstyle
でHTML内に直接書く
index.html
+<style>
+@import url("external.css");
+
+html {
+ font-size: 62.5%;
+}
+</style>
<script src="main.js" async></script>
main.css
-@import url("external.css");
-
-html {
- font-size: 62.5%;
-}
3. script
タグのasync
属性を使わずコード内でDOMContentLoaded
イベントを待つ
index.html
<link rel="stylesheet" href="main.css">
-<script src="main.js" async></script>
+<script src="main.js"></script>
main.js
+document.addEventListener('DOMContentLoaded', function () {
+
console.log(getComputedStyle(document.body).fontSize)
setTimeout(function () {
console.log(getComputedStyle(document.body).fontSize)
}, 500)
+
+})
- diffを見やすくするためインデントは省略。
4. script
タグ内にJSを書く
index.html
<link rel="stylesheet" href="main.css">
-<script src="main.js" async></script>
+<script>
+document.addEventListener('DOMContentLoaded', function () {
+ console.log(getComputedStyle(document.body).fontSize)
+
+ setTimeout(function () {
+ console.log(getComputedStyle(document.body).fontSize)
+ }, 500)
+})
+</script>
main.js
-console.log(getComputedStyle(document.body).fontSize)
-
-setTimeout(function () {
- console.log(getComputedStyle(document.body).fontSize)
-}, 500)
- 以下のように
body
後にscript
を配置してDOMContentLoaded
を使わない形も可。
index.html
<link rel="stylesheet" href="main.css">
-<script src="main.js" async></script>
+<body></body>
+<script>
+console.log(getComputedStyle(document.body).fontSize)
+
+setTimeout(function () {
+ console.log(getComputedStyle(document.body).fontSize)
+}, 500)
+</script>
5. 何もしないscript
タグを挿入する
index.html
<link rel="stylesheet" href="main.css">
+<script> </script>
<script src="main.js" async></script>
-
<script></script>
ではダメで、スペースを入れる必要がある。
6. @import
を後ろに持ってくる
main.css
-@import url("external.css");
-
html {
font-size: 62.5%;
}
+
+@import url("external.css");
- 当然これによって評価順序が変わるので注意。
感想
難しいなぁ。なんかバグっぽいと思ったけど、Chrome、Firefox、Safariで同じ挙動だったので、おそらく仕様で決まっているのかも。