• getComputedStyle()はCSSの適用結果を読み、style属性の指定値と分けて使う

getComputedStyle()はCSSの適用結果を読み、style属性の指定値と分けて使う

公開日: 執筆:佐藤

getComputedStyle()は、スタイルシート、セレクタの優先順位、継承などを反映した後のCSS値を読みます。element.styleが読むのは、その要素のstyle属性へ直接書かれた宣言です。同じCSSStyleDeclarationを扱っても、見ている場所は同じではありません。

要素が実際に何色、何文字で表示されるかを調べるならgetComputedStyle()を使います。style属性へ指定した値の有無を確認し、そこへ新しい値を書くならelement.styleを使います。

element.styleはstyle属性に書かれた宣言を読む

次のHTMLでは、文字色を外部または文書内のスタイルシートで指定し、文字サイズだけをstyle属性へ書いています。

<p id="notice" class="notice" style="font-size: 16px;">受付時間を確認してください。</p>
.notice {
    color: #333333;
}

JavaScriptからelement.styleを読むと、font-sizeは得られますが、スタイルシートで指定したcolorは得られません。

var notice = document.getElementById('notice');

var inlineFontSize = notice.style.getPropertyValue('font-size');
var inlineColor = notice.style.getPropertyValue('color');

この例では、inlineFontSizeにはstyle属性の値が入り、inlineColorは空文字になります。画面で文字が灰色に見えることと、style属性にcolorがあることは別です。

W3CのCSSOMは、要素のstyleを、style属性にある宣言を持つCSSStyleDeclarationとして定めています。属性がなければ宣言の一覧は空です。

getComputedStyle()はスタイルシートと継承を含めて読む

同じ要素へgetComputedStyle()を使うと、CSSを適用した結果を読めます。

var notice = document.getElementById('notice');
var resolvedStyle = window.getComputedStyle(notice, null);

var resolvedColor = resolvedStyle.getPropertyValue('color');
var resolvedFontSize = resolvedStyle.getPropertyValue('font-size');

resolvedColorはスタイルシートから適用された文字色、resolvedFontSizeはstyle属性から適用された文字サイズです。親要素から継承した値も、要素へ適用された結果として読めます。

getComputedStyle()が返す宣言は読み取り専用です。表示状態を確認するための値へ書き込むのではなく、変更する場合はelement.styleへ指定するか、状態を表すclassを付け外しします。

notice.style.setProperty('color', '#222222', '');

この書き方はstyle属性へ宣言を追加します。同じ状態を複数の要素へ使う、hoverやmedia queryも含めて管理するという目的なら、JavaScriptでclassを変更し、具体的な見た目はCSSへ置く方が管理しやすくなります。

返る値はすべて単純なcomputed valueではない

関数名だけを見ると、すべてのpropertyでCSSのcomputed valueが返るように見えます。しかし、CSSOMはgetComputedStyle()から得られる値をresolved valueとして整理しています。

多くのpropertyではcomputed valueを返しますが、表示されている要素のwidth、height、margin、padding、line-heightなどではused valueを返す場合があります。位置指定された要素のtop、right、bottom、leftにも条件があります。

そのため、次の二つを分けます。

知りたいこと 読む対象
CSSへ何を直接指定したか 対象のstyle属性または該当するCSS rule
ブラウザーが要素へ適用した結果 getComputedStyle()のresolved value

getComputedStyle()の値から、どのCSS fileの何行が勝ったかまでは分かりません。指定元を調べるには、開発者用ツールなどで一致したruleと上書きされたruleを確認します。

読み取りと変更を同じ変数の役割にしない

次のように、現在の表示を読み、条件に応じてclassを変更する処理では、測定と変更の順を分けます。

var notice = document.getElementById('notice');
var styleBeforeChange = window.getComputedStyle(notice, null);
var isHidden = styleBeforeChange.getPropertyValue('display') === 'none';

if (isHidden) {
    notice.classList.add('is-visible');
}

classの変更後に値が必要なら、変更後の状態を改めて読みます。変更前に得た値を、新しい表示状態の値として使い続けないようにします。

また、表示の確認をするたびにgetComputedStyle()を何度も呼ぶ必要はありません。一つの判定で複数のpropertyを読むなら、返されたCSSStyleDeclarationを一つの処理内で使います。処理速度を数値だけで決めず、読み取りの目的と、CSSを変更する時点を明確にすることが先です。

最初の一手は、既存コードのelement.styleを一つ選び、知りたいのが「style属性の指定」か「CSSの適用結果」かを書き分けることです。後者ならgetComputedStyle()へ置き換え、変更処理はclassまたはelement.styleへ残します。

戻る