calc()計算式を使用してプロパティの値を指定する
calc()
関数は、CSS プロパティに指定する値を計算式で書くことができる CSS 関数です。
引数として使用できる演算子は四則計算、加算(+
)、減算(-
)、乗算(*
)、除算(/
)で、<length>(長さ)、<frequency>(周波数)、<angle>(角度)、<time>(時間)、<percentage>(%)、<number>(数値)、<integer>(整数) 型の値が許容される場所であればどこでも使用できます。
詳細説明
記述時の注意点
加算と減算 (+
, -
) に関しては演算子の前後に半角スペースを必ず入れなければなりません。
乗算と除算 (*
, /
) に関しては前後の半角スペースについて任意ですが、ミスを防ぐためにも記述上は前後に半角スペースを入れる記述で統一しておいた方がよいでしょう。
その他にも下記のような注意点があります。
演算子が +
または -
の場合
演算子が +
または -
の場合、「演算子両側の値が同じ型」、もしくは 「一方が <number> (数値) で、もう一方が <integer> (整数)」であるかがチェックされます。前者の場合はその型に解決され、後者の場合は <number> に解決されます。
つまり、width: calc(100% - 10px)
や width: calc(10rem + 10px)
は演算子の両側が <length> (<percentage> は <length> ではないのですが、width
プロパティは <length>、<percentage> を許容し、いずれも長さとして扱われるため同じ型となります) になるため、これは正しい記述ですが、width: calc(100px + 10s)
のような記述は「長さ」 と 「時間」 という異なる型の値が指定されていますので、不正ということになります。
演算子が *
の場合
「演算子両側の値のうち、少なくともどちらか一方が <number>」 であるかがチェックされます。両側とも <integer> であれば <integer> として解決され、それ以外であれば、<number> と逆側に指定された値の型で解決されます。
つまり、calc(10px * 10px)
のような指定は不正です。calc(10% * 2)
または calc(2 * 10px)
のようにしなければなりません。
演算子が /
の場合
「演算子の右側が <number>」 であるかがチェックされます。演算子の左側が <integer> であれば <number> として解決され、それ以外であれば、左側の値の型に解決されます。
つまり、<number> で割らないといけないということで、calc(2 / 10px)
のような記述をしてはいけません。calc(10px / 2)
のようにする必要があります。また 「0」 での除算はエラーになります。
計算の優先順位
calc()
関数による四則計算の優先順位は学校で習うとおりです。計算順序を指定するために 「括弧()」 を使用することができます。
calc(500 - 10 * 20 - 10 / 2)
となっていれば、500 - 200 - 5
ということになります。例えば加算、減算を優先的に計算したければ calc((500 - 10) * (20 - 10) / 2)
のように記述する必要があります。
calc()のサンプルソース
div { width: calc(100% / 3 - 2 * 1em - 2 * 1px); }
/* line-height を含めて、ちょうど 20px の padding をつけたい場合などのサンプル */ h1 { font-size: 36px; line-height: 1.4; color: #fff; background-color: #f00; padding: 20px; /* 旧ブラウザ向けに念のためフォールバックとして記述 */ padding: calc(20px - (1em * 1.4 - 1em) / 2) 20px; }
/*calc() を入れ子(ネスト)にした記述例 */ .sample { width: calc(3 * calc(20px + 30px)) }
/* CSS カスタムプロパティとの併用例 */ :root { --wrap-box-width: calc(100% - 10px * 2); --box-column: 5; } .sample { display: flex; flex-wrap: wrap; width: var(--wrap-box-width); margin: 0 auto; } .sample div { flex: 1 1 calc(var(--wrap-box-width) / var(--box-column)); }
主要ブラウザの対応
IE11 | △入れ子不可・一部バグあり |
---|---|
Edge(EdgeHTML) | ○ |
Edge(Chromium) | ○ |
Chrome | ○ |
Firefox | ○ |
Safari | ○ |
iOS Safari | ○ |
Android Chrome | ○ |