50202


以下のようなcssがあったときにjsで`:root`のカスタムプロパティ(変数)をすべて取得する方法はありませんか?

[code]

    :root {
      --main-style__day__bg-color: #e0e0e0;
      --main-style__day__ft-color: #030303;
      --main-style__night__bg-color: #101010;
      --main-style__night__ft-color: #e0e0e0;
    
      --main-style__current__bg-color: var(--main-style__day__bg-color);
      --main-style__current__ft-color: var(--main-style__day__ft-color);
    }
    
[/code]

以下の方法ではだめでした。

[code]

    document.documentElement.style.cssText //=> ""
    window.getComputedStyle(document.documentElement).cssText.match(/--.*;/) //=> null
    
[/code]

以下のように、一度jsでhtml
tagのstyleに入れてあげれば取得できますが、そうではなく、どんなカスタムプロパティがあるかわからない状態でjsからすべてのカスタムプロパティを取得したいです。

[code]

    document.documentElement.style.setProperty('--foo-bar', 'pink')
    document.documentElement.style.setProperty('--piyo-piyo', 'blue')
    document.documentElement.style.cssText //=> "--foo-bar:pink; --piyo-piyo:blue;"
    
[/code]

(Chrome 70.0.3538.77 で動作確認)


CC BY-SA 4.0
2018-11-11T04:28:37.370
50198
2018-11-11T06:13:27.220
2018-11-11T05:10:56.047
28630
28630
question
javascript css
cssのカスタムプロパティ(変数)をすべて取得する方法


一番いい方法は以下のように[computedStyleMap](https://developer.mozilla.org/en-
US/docs/Web/API/Element/computedStyleMap)を使う方法です。

[code]

    // html要素の計算済みスタイルを取得
    const htmlStyle = document.documentElement.computedStyleMap();
    // スタイルのうちカスタムプロパティのみ表示
    for (const [propertyName, value] of htmlStyle.entries()) {
        if (/^--/.test(propertyName)) {
            // valueはCSSStyleValueとして得られるので文字列に変換
            console.log(propertyName, value.toString());
        }
    }
    
[/code]

ただし、これは新しいAPIなのでまだGoogle Chromeでしか動きません。

代わりの方法としては、完璧ではありませんが以下のような方法があります。これは、文書中のCSSスタイルシート定義を全部取得して、その中から`:root`に対して指定されているものを探すという力技な方法です。

[code]

    // この文書のスタイルシートの一覧を取得
    const sheets = document.styleSheets;
    for (const sheet of sheets) {
        if (sheet.cssRules) {
            // 各スタイルシートのルールの中から :root がセレクタのものを探す
            for (const rule of sheet.cssRules) {
                if (rule.selectorText === ':root') {
                    // :root がセレクタのルールの中身を列挙
                    for (let i =0; i < rule.style.length; i++) {
                        const propertyName = rule.style.item(i);
                        // カスタムプロパティであるもののみ表示
                        if (/^--/.test(propertyName)) {
                            console.log(propertyName, rule.style.getPropertyValue(propertyName));
                        }
                    }
                }
            }
        }
    }
    
[/code]

ご質問の例の場合は下のものでも動きますが、メディアクエリなどが関わってきた場合に下の例はうまく動かないかもしれません。


CC BY-SA 4.0
2018-11-11T06:13:27.220
50202
2018-11-11T06:13:27.220
30079
50198
answer