Log

いろいろ

カスタムプロパティを使用したショートハンドを含むCSSRule.cssTextが正しい値を返さない

document.styleSheetsにはスタイルシートのリストが格納されています。各スタイルシートCSSルールのリストをcssRulesに保持しており、cssTextCSSルールのテキストを取得できます。この値が想定と異なるので困ったという話です。

ちなみに何も解決していません。今すぐ答えが欲しくてココへ辿り着いた方はブラウザバック推奨。そうでない方はゆっくりしていってね。同様に困っている人への僅かな手がかりと、自分の調査メモとしてインターネットにログを残します。

技術的な内容を書く際はできるだけ公式用語を使いたいのですが、CSSはマジで分からんので不適切な表現が多々あるかもしれません。ご容赦を。

問題のCSSルール

:root {
    --main-color: red;
}

.frame {
    border: 1px solid var(--main-color);
    border-bottom: 3px dashed var(--main-color);
}

見た目はこんな感じです。

borderの一部分だけ異なるstyleを適用するために、先にborder全体のstyleを宣言して、その直後に個別のプロパティで上書きします。*1

このCSSルールをcssTextで取得してみます。

整形するとこんな感じ。

.frame {
    border-top-color: ;
    border-top-style: ;
    border-top-width: ;
    border-right-color: ;
    border-right-style: ;
    border-right-width: ;
    border-left-color: ;
    border-left-style: ;
    border-left-width: ;
    border-image-source: ;
    border-image-slice: ;
    border-image-width: ;
    border-image-outset: ;
    border-image-repeat: ;
    border-bottom: 3px dashed var(--main-color);
}

かなしい。

borderのカスタムプロパティを除くとちゃんとした値が取得できます。

:root {
    --main-color: red;
}

.frame {
    /* border: 1px solid var(--main-color); */
    border: 1px solid red;
    border-bottom: 3px dashed var(--main-color);
}
/* cssTextで取得した値 */
.frame {
    border-top: 1px solid red;
    border-right: 1px solid red;
    border-left: 1px solid red;
    border-image: initial;
    border-bottom: 3px dashed var(--main-color);
}

他に試したケース。

  • カスタムプロパティを使用したborderのみ定義→OK
  • カスタムプロパティを使用したborderとカスタムプロパティを使用していないborder-bottomを定義→NG

どうやらカスタムプロパティを含むborderとborder-bottomが混在する場合に正しい値が取得できないようです。

CSS カスタムプロパティ (変数) の使用 - CSS: カスケーディングスタイルシート | MDN

ショートハンドプロパティの展開

先ほどちゃんと取得できたと述べたcssText。

.frame {
    border-top: 1px solid red;
    border-right: 1px solid red;
    border-left: 1px solid red;
    border-image: initial;
    border-bottom: 3px dashed var(--main-color);
}

オリジナルのCSSルールとは異なりますが問題ありません。borderは複数のプロパティを一括で指定できるショートハンドであり、cssTextではそれらが展開されただけです。

border - CSS: カスケーディングスタイルシート | MDN

CSS Object Model (CSSOM)

The cssText attribute must return a serialization of the CSS rule.

CSSの仕様書なのでmustという表記になっています。ブラウザがちゃんと実装していないのでしょうか。そもそも仕様で考慮されていないのでしょうか。

いずれにせよ、このシリアライズにおいて、カスタムプロパティを含むCSSルールが適切に処理されていないことは明らかです。ここを深ぼっていくと答えが見つかりそう。

a serialization of the CSS rule

CSS Object Model (CSSOM)

あとはこれを読むだけ。がんばれ未来の自分。to be continued...

*1:そもそもこの記述がアンチパターンなのかもしれません。