吉本集の個人ブログ
Web制作の技術について書いています。たまに日記も書きます。

【JS入門】CSSを制御する Vol.2(算出スタイルを参照する)

2018年2月21日 / category : javascript

前回の記事「CSSを制御する Vol.1(インラインスタイルの制御)」で解説したインラインスタイルを取得するプロパティやメソッドでは、style属性に設定したCSSのプロパティを取得していましたが、これではいくつか問題が出てきてしまいます。最も大きい問題としては、前回の記事でも触れましたが、style属性で設定したCSSの情報しか参照できず、style要素や外部のcssファイルの情報は参照できない点ですが、それ以外にも問題があります。次のようなコードを見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>
<body>
<p id="txt" style="font-size: 1em; width: 50%;">お腹減った。</p>
<script src="./js/sample.js"></script>
</body>
</html>
sample.js
let txt = document.getElementById('txt');
console.log( txt.style.fontSize ); // 1em
console.log( txt.style.width ); // 50%

上のコードでは、正しくstyle属性を取得できていますが、実際のサイズ(何pxなのか)がわかりません。この点が大きな問題です。ある要素のフォントサイズや横幅などのサイズをpx単位で参照したい場合は、Windowインターフェースで定義してあるメソッドgetComputedStyleを使用します。

算出スタイルを参照する

算出スタイルとは、インラインスタイルやstyle要素、外部のcssファイルなど全ての適応されたスタイルルールをブラウザで算出した結果のプロパティセットです。計算済みスタイルと呼ばれることもあります。

window.getComputedStyle(element,pseudoElt):算出スタイルを取得する
引数 element(Element) : スタイルを取得するターゲットとなるオブジェクト
引数 pseudoElt(string) : 類似要素を指定する文字列(不要な場合は、空文字列を指定)
戻り値(return): 算出スタイル(CSSStyleDeclaration)
構文

let style = window.getComputedStyle(element,':before');

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
<style>
	#txt{
		margin: 5%;
	}
</style>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<p id="txt" style="font-size: 1em; width: 50%;">お腹減った。</p>
<script src="./js/sample.js"></script>
</body>
</html>
styles
#txt{
	padding: 25%;
}
sample.js
let txt = document.getElementById('txt');
let style = window.getComputedStyle(txt, '');
console.log( style.width ); // 482px
console.log( style.fontSize ); // 16px
console.log( style.margin ); // 48.1875px
console.log( style.padding ); // 241px

インラインスタイル以外に、style要素や外部cssファイルで設定しているCSSの情報が取得できています。
また、margin,padding,widthは%指定、font-sizeはem指定ですが、取得した値は全てpx単位になっています。%指定やem指定などの相対単位は全て、絶対値(px単位)になります。
(コンソールに表示されている値の中で%指定のプロパティは、ブラウザのサイズによって異なります。)

メソッドgetComputedStyleで返ってくるオブジェクトは、CSSStyleDeclarationインターフェースを継承したオブジェクトですが、このオブジェクトは読み出し専用です。次のコードをみてみます。

sample.js
let txt = document.getElementById('txt');
let style = window.getComputedStyle(txt,'');
style.width = '0px'; // error

取得したCSSStyleDeclarationオブジェクトのプロパティwidthに値を代入しようとしましたが、エラーになりました。

先ほど、%指定やem指定などの相対単位は絶対値(px単位)になると解説しました。色の値についてはどうでしょうか。次のコードを見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<p id="color1">テキスト1</p>
<p id="color2">テキスト2</p>
<p id="color3">テキスト3</p>
<script src="./js/sample.js"></script>
</body>
</html>
styles
#color1{
	color: red;
}

#color2{
	color: #f00;
}

#color3{
	color: #ff000080;
}
sample.js
let txt1 = document.getElementById('color1');
let txt2 = document.getElementById('color2');
let txt3 = document.getElementById('color3');

function getColor(element){
	let style = window.getComputedStyle(element);
	return style.color;
};

console.log( getColor(txt1) ); // rgb(255, 0, 0)
console.log( getColor(txt2) ); // rgb(255, 0, 0)
console.log( getColor(txt3) ); // rgb(255, 0, 0, 0.5)

関数getColorを定義し、それぞれの要素をターゲットにしてCSSのプロパティcolorを返しています。
全てrgb単位もしくはrgba単位に変換されていることがわかります。
続いて、CSSのfont-familyについて見てみます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<p id="txt">お腹減った。</p>
<script src="./js/sample.js"></script>
</body>
</html>
styles
#txt{
	font-family: [{[{-apple-system, BlinkMacSystemFont}, "Helvetica Neue"], "Segoe UI"}, {"Yu Gothic", YuGothic}, sans-serif];
}
sample.js
let txt = document.getElementById('txt');
let style = window.getComputedStyle(txt,'');
console.log( style.fontFamily ); // "Hiragino Kaku Gothic ProN"

外部cssファイルで指定したfont-familyの値と、メソッドgetComputedStyleで取得したプロパティfontFamilyの値が異なります。これは、先に解説した通り、ブラウザで算出した結果のプロパティセットを返すため、ブラウザで適応されているフォトファミリーの値を返しています。

メソッドgetComputedStyleの第2引数を指定することで類似要素を指定することができます。

styles
#txt{
	position: relative;
	margin: 0 0 0 10px;
	font-size: 14px;
	line-height: 1;
}

#txt:before{
	content: '';
	display: block;
	position: absolute;
	width: 5px;
	height: 14px;
	margin: 0 0 0 -10px;
	background: #f00;
}
sample.js
let txt = document.getElementById('txt');
let style = window.getComputedStyle(txt,':before');
console.log( style.width, style.height ); // 5px 14px

上のコードでは、類似要素であるbeforeをターゲットにしてCSSの情報を取得しています。