CSSソース内で値に計算式が使える便利なcalc()
CSSで幅や高さなどの長さを指定する際に、割合(80%)や数値(250px)そのものではなく、四則演算を使った計算式「 ( 100% - 30px ) / 2 」などが書けると、指定の柔軟さが広がります。横幅を「15文字分(=15em)に8ピクセル(=8px)だけ加えた長さ」にしたいという場合は、計算式「 15em + 8px 」をそのまま値として指定できれば分かりやすくて便利でしょう。CSSの値に計算式を指定するための記述方法が、CSS3で追加されたcalc()です。今回は、そんな便利なcalc()の使い方を解説いたします。
【目次】
- CSSソース内に計算式が書けるcalc()の概要
- CSSソース内で四則演算ができるcalc()の使い方
- 値にcalc()が使えるCSSの記述場所
- CSSでcalc()による計算式が効かない場合
- 1. 演算子のプラスやマイナス記号と数値をぴったりくっつけると効かない
- 2. 数値には、単位がないと効かない場所と、単位を書くと効かない場所がある
- 3. calc()が使えるはずの場所でも効かない場合や、描画に不具合が出る場合がある
CSSソース内に計算式が書けるcalc()の概要
下図は、div要素で作成したボックスの横幅(widthプロパティ)に、計算式を指定してみた表示例です。- 一番上は、横幅に値「100%」を指定しています。横幅いっぱいに描画されます。
- 真ん中は、横幅を「100% - 1em」という計算式で指定してセンタリングした例です。横幅いっぱいの長さから1文字分(1em)だけ引いた長さが横幅になります。
- 一番下は、さらにその幅を3等分するように割り算も含めた計算式「(100% - 1em) / 3」を横幅に指定した例です。「横幅の長さから1文字分を引いた長さ」を3で割った長さが横幅になります。
このように、割合や単位付きの数値なども含めて加減乗除して値を決定したい場合には、CSSソース内にcalc()を使って計算式が書けるととても便利です。
■CSSソース内に計算式が書けるcalc()は、既に多くのブラウザで使える
calc()はCSS3で追加された仕様ですが、既に多くのブラウザで使用可能です。IE8では使えませんし、IE9でも部分的にしか使えませんでしたが、どちらもサポートが終了したバージョンですから考慮しなくて良いでしょう。
代表的な各ブラウザで、CSSの値にcalc()が使えるバージョン番号
※Edgeは全バージョンで使用可能
IE以外のブラウザでは、かなり古いバージョンから使えます。例えば、Firefoxは16以上、Chromeは26以上、Safariは6.1以上、Operaは(miniを除いて)15以上で使えます。IEの後継であるEdgeは、最初のバージョン(Edge12)から使用可能です。
CSSソース内で四則演算ができるcalc()の使い方
calc()では、足し算「+」、引き算「-」、かけ算「*」、割り算「/」の各記号を使って計算式を記述できます。計算の順序を明示するためにカッコ ( ) を使うこともできます。書き方は簡単で、以下のような感じで記述します。calc( 計算式 )このcalc()自体は、CSSで普段「100%」や「250px」などのような値を記述していた場所にそのまま記述できます。例えば、div要素の幅(width)や字下げ幅(text-indent)の値を計算式にしたい場合は、以下のような感じでCSSを書きます。
div { width: calc( 計算式 ); text-indent: calc( 計算式 ); }計算式の記述例は以下の通りです。
■足し算 (横幅を50%より30pxだけ大きくしたい場合の書き方例)
width: calc( 50% + 30px );「割合」に「単位付きの数値」を加えるような計算もできます。なお、「+」記号の前後には空白が必要です。
■引き算 (横幅を800pxより5文字分だけ小さくしたい場合の書き方例)
width: calc( 800px - 5em );「px」と「em」など、異なる単位の数値を混合させて計算することもできます。なお、「-」記号の前後には空白が必要です。
■割り算 (横幅を3等分したい場合の書き方例)
width: calc( 100% / 3 );ボックスを指定個数だけ横に並べたい場合などに割り算が使えると便利です。割り算では、式の右側は「何の単位も付加しない数値」である必要があります。
■かけ算 (2.5文字分の6倍を指定したい場合の書き方例)
width: calc( 2.5em * 6 );かけ算は、変数を併用しない限りあまり使う機会はないかもしれません。かけ算では、式の左右のどちらか一方は「何の単位も付加しない数値」である必要があります。
■加減乗除の混合 (100%から35px減らした長さを半分にしたい場合の書き方例)
width: calc( ( 100% - 35px ) / 2 );冒頭にも例で示しましたが、加減乗除は混合して使えます。計算順序を指定するためにカッコを使うこともできます。
値にcalc()が使えるCSSの記述場所
CSSソース内でcalc()を使った計算式を値として記述できる場所は、- 長さを指定する場所(width、height、margin、padding、top、leftなど)
- 数値(整数/小数)を指定する場所(line-height、flex-grow、orderなど)
- 時間を指定する場所(transition-durationなど)
- 角度を指定する場所(linear-gradient、rotateなど)
■ボックスの左側余白を、横幅の1割よりも5pxだけ大きく取りたい場合
下記は、div要素に対して左側にマージンを設けるCSSソースの記述例です。
div { margin-left: calc( 10% + 5px ); }marginプロパティには「%」を使った割合や「px」などの単位を使った数値を指定できますから、計算式内でもそれらを使って指定します。ここで、「 10% + 5 」と書いてしまうと無効になりますから注意して下さい。marginプロパティには「単位のない数値」は指定できませんから、計算式の中でも「単位のない数値」を足したり引いたりはできません(※かけ算や割り算では使えます)。
なお、marginプロパティなど「長さ」を指定する場面では、「margin: 0」のようにゼロに限っては単位を省略できます。しかし、calc()で指定する計算式の中で「 10% + 0 」とは書けません(無効になります)。「 10% + 0px 」や「 10% + 0em 」などであれは有効です。もっとも、0を足したり引いたりすることはあまりないでしょうが。値の試行錯誤の途中で一時的に数値をゼロにしてみる際などには注意して下さい。
■グラデーションの指定のうち、カラーストップの位置を計算式で表す
下記は、p要素に対して背景にグラデーションを指定するCSSの記述例です。
p { background: linear-gradient(45deg, white calc(25% - 15px), green calc(25% + 15px), yellow calc(75% - 15px), white calc(75% + 15px)); }プロパティの値に直接calc()を使う以外に、上記に記したlinear-gradientなどのように複数の値を取る記述で、数値1つ1つに対してcalc()を使うこともできます。
上記では、背景のグラデーションとして「25%より15px手前」までは白色、「25%より15px後ろ」で緑色、「75%より15px手前」で黄色、「75%より15px後ろ」で白色になるよう指定しています。表示例は下図の通りです。
グラデーションのカラーストップ(色の変更位置)に対して、calc()の書式で計算式を使うこともできる
CSSでcalc()による計算式が効かない場合
値にcalc()を使って計算式を書いたとき、記述内容が効かない(無効になっている)ように見えることがあります。その際には、calc()が使用可能な場所か、calc()の書き方を間違えていないか、数値を仕様通りに記述しているかどうかなどを確認してみて下さい。以下に、確認のポイントを3つ示しておきます。- 演算子のプラスやマイナス記号と数値をぴったりくっつけると効かない
- 数値には、単位がないと効かない場所と、単位を書くと効かない場所がある
- calc()が使えるはずの場所でも効かない場合や、描画に不具合が出る場合がある
1. 演算子のプラスやマイナス記号と数値をぴったりくっつけると効かない
calc()内に足し算や引き算の式を書きたいとき、足し算を表すプラス記号「+」や引き算を表すマイナス記号「-」と、それに続く数値をぴったりくっつけてしまうと、計算式だとは認識されません。例えば、下記の(A)の書き方は正しく引き算として計算されますが、(B)の書き方では計算されません。/* (A)有効 */ width: calc( 80% - 50px ); /* (B)無効 */ width: calc( 80% -50px );
上記の(A)と(B)で異なるのは空白文字の有無だけです。
- (A)は「80%から50pxを引く」と解釈されるので正しく計算されます。
- しかし(B)は、「80%という値と、-50pxという値の2つが併記されている」と解釈されるので計算されません。
JavaScriptなどのスクリプトとは違って、CSSのcalc()独特の仕様なので注意して下さい。このように空白が必要なのは足し算と引き算の場合だけですが、どんな場合でも「演算子の前後は空白を入れておく」と覚えておくのが楽で良いでしょう。
2. 数値には、単位がないと効かない場所と、単位を書くと効かない場所がある
calc()内に記述する計算式では、数値に単位を付ける必要がある場合と、単位を付けてはいけない場合とがあります。calc()での計算指定が効いていないように思える場合は、計算式の中で指定している値に正しい単位を書いているかどうかを確認してみて下さい。■単位を付ける必要がある場合
例えば、高さを指定するheightプロパティや横幅を指定するwidthプロパティのように、対象の「長さ」を指定する値では、計算結果も「長さ」として出るように単位を付ける必要があります。「30% + 12px」や「600px + 5em」などは有効ですが、「30% + 12」や「5em + 600」などのように単位のない値を書いてしまうと無効です。
また、計算式の中で使っている単位が正しいかどうかも確認して下さい。角度を指定する場面では「45deg」(45度)や「-100grad」(-100度)のように単位degやgradなどを使う必要があります。時間を指定する場面では「0.3s」(0.3秒)や「400ms」(400ミリ秒)のように単位sやmsを使う必要があります。
■単位が必要な場面で、単位を付けても無効になる例
例えば、長さと時間を加算する「320px + 400ms」のような計算や、角度と長さを加算する「90deg + 300px」のような計算は無効です。
また、CSSの文法では数値と単位の間に空白を挟むことはできません。例えば「3px」という記述は有効ですが、「3 px」のように数値と単位の間が開いていると無効です。これはcalc()での書き方に限らず、CSS全般で共通の仕様です。
■単位を付けてはいけない場合
- 順序を指定するorderプロパティなどのように、元々「単位なしの数値」を指定しなければならないプロパティに対しては、単位なしの数値だけが使えます。
- 割り算の右側に単位付きの数値を指定する「400px / 3px」のような計算はできません(先述の割り算の仕様をご参照下さい)。
- かけ算の両側に単位付きの数値を指定する「3em * 5em」のような計算もできません(先述のかけ算の仕様をご参照下さい)。
■計算式の中にゼロを使う場合の注意
値に単位なしの「0」が使えるプロパティであっても、計算式の中で「3em + 0」のように書くと無効になります。計算式の中では、長さの「0px」や時間の「0s」や角度の「0deg」などのように、ゼロにも単位が必要です。ただし、かけ算では「30px * 0」のように単位なしのゼロを使う必要があります(先述のかけ算の仕様をご参照下さい)。
※CSSの文法では、単位を省略した「0」を指定できるのは「長さ」の場合だけです。時間を表す「0s」を「0」と表記したり、角度を表す「0deg」を「0」と表記することは、本来はできません。ただし、ブラウザによっては時間や角度に単位なしの「0」を書いても、「0s」や「0deg」だと解釈してくれるものもあります。
3. calc()が使えるはずの場所でも効かない場合や、描画に不具合が出る場合がある
CSSの文法上ではcalc()が使用可能な場所でも、ブラウザによっては効かない制限があったり、他の箇所の描画がおかしくなったりする問題があります。本稿執筆時点では、以下のような問題点が報告されていました(※)。- IEでは、calc()を使うとbox-shadowが描画されなくなる。
- IE11では、動的に生成された内容に対しては使えない場合がある。
- IE11では、ネストされた(入れ子になった)式を使うと不具合が出る場合がある。例えば、小数の丸め方に違いが出るなど。
- IE10では、「calc()が使われたdiv要素」の子要素に対して、同じプロパティの値に「inherit」を指定するとクラッシュする。
- IEやEdge14未満では、transformプロパティが使われたボックスの内側では使えない。
- IE・Edgeでは、flexプロパティが使われたボックスの内側では使えない場合がある。
- IE・Edge・Firefoxでは、表のセル(table-cell)に対しては使えない。
- Firefox48未満では、line-height、stroke-width、stroke-dashoffset、stroke-dasharrayの各プロパティでは使えない。
- Safari8未満では、calc()内で「vw」や「vh」などのViewportに関する単位は使えない。
IEは11が最後のバージョンですから、IEに存在する不具合は今後も解消はされないでしょう。もしどうしてもIEを対象にしなければならない場合は、上記のような記述を避けるようにするしかありません。
CSSで幅や高さの指定に計算式が使えるcalc()の書き方
今回は、CSSソース内で値に計算式が使えるcalc()の書き方をご紹介いたしました。計算式が使えると、指定の柔軟さが広がります。ぜひ、試してみて下さい。【関連記事】