ywork2020.com

Title

CSSで計算をする

目次 (INDEX)

calcとは

ここで説明するcalc とは次の語句からなるCSSの関数です。
calculation
読み: キャルキュレイション
意味: 計算、演算、勘定

目次に戻る

calc関数の概要

この関数はCSSの処理において演算結果を返します。 つまり、この関数を使うとCSSのコード上で計算を含めた設定ができるということです。

引数には実数値以外にも単位付きの数値も含めることが可能です。しかし、掛け算と割り算を処理する場合には片方の数値は実数値である必要があります。 また、計算を処理するための+演算子と-演算子の前後には半角スペースを含めるといった制約がありますのでコードの記述では注意が必要です。

目次に戻る

構文

サンプルを見る前に構文を確認しておきます。この関数の記述は以下のような書き方になります。

セレクター{プロパティ名: calc(実数値 + 実数値);}
セレクター{プロパティ名: calc(実数値 - 実数値);}
セレクター{プロパティ名: calc(実数値 * 実数値);}
セレクター{プロパティ名: calc(実数値*実数値);}
セレクター{プロパティ名: calc(実数値 / 実数値);}
セレクター{プロパティ名: calc(実数値/実数値);}
セレクター{プロパティ名: calc(単位値 * 実数値);}
セレクター{プロパティ名: calc(単位値*実数値);}
セレクター{プロパティ名: calc(単位値 / 実数値);}
セレクター{プロパティ名: calc(単位値/実数値);}

概要のところでも書きましたが、足し算と引き算の演算子の前後には半角スペースが必要です。 これは正の数と負の数に使われる+-と別であるということを表しています。実際の例でみると以下のようになります。

  • calc(200 + 100)の結果は300
  • calc(200 - 100)の結果は100
  • calc(+200 - -100)の結果は300

目次に戻る

実機サンプルとサンプルコード

ここからは実際のHTML要素のプロパティに関数を適用させて結果を見ていきたいと思います。

サンプルに使用する要素はdiv要素です。

基本: 四則演算

この関数は、calc(引数)という構文の引数の部分に計算式を与えることで、計算結果を返してくれる関数です。

ここでは、シンプルにcalc関数の使い方について説明します。

要素の横幅を指定するための width プロパティを設定する場合の例ですが、単純にpx(ピクセル)値を足し算、引き算、掛け算、割り算で実行してみました。

計算式を記述する上で注意していただきたいのは次の2つのことです。

1. 算術に使用する+演算子と-演算子の前後には半角スペースを入れて記述してください。 しかし、負の数を指定するための-記号は半角スペースは使わないでください。

2. 掛け算と割り算のところで、単位付きの数値と実数値で計算しているところです。 例えば掛け算の部分でいうと「160px * 2」の部分です。これを「160px * 2px」と書かないでください。 掛け算と割り算をする場合には、片方の数値は実数値である必要があります。

width: calc(150px + 150px);
結果: 300px
width: calc(400px - 150px);
結果: 250px
width: calc(160px * 2);
結果: 320px
width: calc(100% / 2);
結果: 50%

div{width: calc(演算内容は各要素に記載しています);}

目次に戻る

応用サンプル: 要素を移動アニメーションする場合に位置を計算する

このサンプルは、 二つのdiv要素を入れ子にして、子要素であるidChildrenをクリックしている状態で親要素であるidParent内の右側に移動する仕様です。

calc関数を使用する場合にはカスタムプロパティ( CSSの変数 )を使うことが多いと思いますので、コードに組み込んでいます。

なお、javascriptを使っても、このサンプルと同様のことができますが、javascriptを使う場合にはCSSのcalc関数を使うことは少ないと思いますので、 このサンプルではjavascriptを使っていません。 しかし、javascriptのコードも参考になるかもしれませんので、 このセクションの終りに同じ動作をするjavascriptバージョンのサンプルを掲載しておきます。

idParent
idChildren
この要素をクリックしている間は右へ移動します。クリックを解除すると元の位置に戻ります。

:root{
	--parent-Width: 600px;
	--parent-Padding: 5px;
	--child-Margin: 10px;
	--child-Width: 200px;
}
#idParent{
	background-color: lightskyblue;
	width: var(--parent-Width);
	padding: var(--parent-Padding);
}
#idChildren{
	border: 1px solid #aaa;
	background-color: khaki;
	margin: var(--child-Margin);
	width: var(--child-Width);
	position: relative;
	transform: translateX(0);
	transition: transform 1s;
}
#idChildren:active{
	transform: translateX(
		calc(var(--parent-Width) - (var(--parent-Padding)*2) - (var(--child-Margin)*2) - var(--child-Width))
	);
}

目次に戻る

参考: 応用サンプルをjavascriptで実装してみる

ここからは上記のCSSサンプルの動作をjavascriptで実装したものです。

idParent_JS (javascriptバージョン)
idChildren_JS
この要素をクリックしている間は右へ移動します。クリックを解除すると元の位置に戻ります。

javascriptバージョンのサンプルコード: CSS
<style>
	#idParent_JS{
		background-color: lightseagreen;
		width: 600px;
		padding: 5px;
	}
	#idChildren_JS{
		border: 1px solid #aaa;
		background-color: khaki;
		margin: 10px;
		width: 200px;
		position: relative;
		transform: translateX(0);
		transition: transform 1s;
	}
</style>
javascriptバージョンのサンプルコード: HTML
<body>
	<div id="idParent_JS">親要素
		<div id="idChildren_JS">子要素</div>
	</div>
</body>
javascriptバージョンのサンプルコード: script
<script>
	document.open();
	let elmParent_JS = document.getElementById("idParent_JS");
	let elmChildren_JS = document.getElementById("idChildren_JS");
	let propParentWidth = parseFloat(window.getComputedStyle(elmParent_JS).getPropertyValue("width"));
	let propParentPadding = parseFloat(window.getComputedStyle(elmParent_JS).getPropertyValue("padding"));
	let propChildrenMargin = parseFloat(window.getComputedStyle(elmChildren_JS).getPropertyValue("margin"));
	let propChildrenWidth = parseFloat(window.getComputedStyle(elmChildren_JS).getPropertyValue("width"));
	elmChildren_JS.addEventListener("mousedown",function(){
		elmChildren_JS.style.setProperty(
			"transform",
			"translateX(" +
			(propParentWidth-propParentPadding*2-propChildrenMargin*2-propChildrenWidth)
			+ "px)"
		);
	},false);
	elmParent_JS.addEventListener("mouseup",function(){
		elmChildren_JS.style.setProperty(
			"transform",
			"translateX(0)"
		);
	},false);
	document.close();
</script>

目次に戻る