CSSのcalc()関数で要素の可変幅を調整する

各デバイスに対応したレスポンシブWebデザインを構築していく中では、可変に対応した要素の幅をpxやemのほか、パーセントの単位もCSSで指定していくこともあります。
ここでは、要素を横並びにするレイアウトで少しつまづきそうなパーセントの指定についてお話していきます。
floatプロパティやdisplayプロパティのinline-blockなどで横並びを実装している場合には、パーセントでの幅指定にpaddingプロパティも影響してきます。
Flexboxで構築する場合は問題ありませんが。
例えば、2つの要素を50%で横並びにした場合、
paddingを30pxとして余白を指定していれば、要素の幅は「50% + 60px」となり、レイアウトが崩れます。
以下、サンプルです。
HTML
<article>
<h1>CSS calc() Function</h1>
<div class="layoutblock">
<div class="block-l">
<h2>Headline h2</h2>
<p>Example text... Example text... Example text... Example text... Example text... Example text... </p>
</div>
<div class="block-r">
<h2>Headline h2</h2>
<p>Example text... Example text... Example text... Example text... Example text... Example text... </p>
</div>
</div>
</article>
CSS
article {
max-width: 1200px;
margin: auto;
}
.layoutblock {
margin: 20px 0;
background: rgb(209, 209, 209);
padding: 40px 4%;
overflow: hidden;
}
.block-l {
background: rgb(255, 209, 209);
float: left;
width: 50%;
padding: 30px;
}
.block-r {
background: rgb(209, 209, 255);
float: right;
width: 50%;
padding: 30px;
}

paddinがパーセント指定、例えば「padding: 4%;」としたら、左右の余白にかかる8%を引いて「width: 42%;」とすればOKです。
しかし、pxやemなどの指定が関係してくると、可変幅に対応できません。
そこで便利なのが、CSSのcalc()関数です。
CSSのcalc()関数を使うことで、パーセントとpxまたはemとの幅指定でも、可変する幅に柔軟に対応することができます。
calc()関数の利用
CSSのcalc()関数では、プロパティで指定する値を数式で計算することができます。
先ほどご紹介したサンプルで見ていきましょう。
横並びにする2つの要素を以下のように、widthプロパティでcalc()関数を使って幅を調整します。
CSS
.block-l {
background: rgb(255, 209, 209);
float: left;
width: calc(50% - 60px);
padding: 30px;
}
.block-r {
background: rgb(209, 209, 255);
float: right;
width: calc(50% - 60px);
padding: 30px;
}
左右の余白の60pxをcalc()関数の計算で引いてあげることで、paddingの余白分が引かれて50%となります。

また、デザインでボーダーを採用したいこともあります。
borderプロパティはpxやemといった指定ですので、もちろん幅に影響します。
CSS
.block-r {
background: rgb(209, 209, 255);
float: right;
width: calc(50% - 60px);
padding: 30px;
border: 3px solid #666;
}

この場合、「width: calc(50% – 60px – 6px);」として、borderの太さ分をcalc()関数で計算に入れることで対応できます。
しかし、横並びの要素同士の高さを綺麗に揃えるときは、高さも調整していく必要がでてきます。
そこでちょっと便利なのがoutlineプロパティです。
outlineプロパティの利用
outlineプロパティは、アウトラインのスタイル・太さ・色をしていすることができ、線を表現することができます。
表示上の幅は太さ分だけ外側に増えますが、レイアウトには影響しません。
アウトラインのスタイルの指定は、borderプロパティと同じような指定をします。
ただborderとは違い、上下左右の概念はありません。
以下、実装のサンプルです。
CSS
.block-r {
background: rgb(209, 209, 255);
float: right;
width: calc(50% - 60px);
padding: 30px;
outline: 3px solid #666;
outline-offset: -3px;
}
表示上もしっかり幅を調整したい場合は、outline-offsetで開始位置を線の太さ分マイナスにします。
borderのデザインの要素でも、うまく横並びで調整できたのが確認できます。

幅のレイアウト崩れはいいですが、横並びの要素同士の高さを綺麗に揃えるときは、outline-offsetが必要になるでしょう。
今回ご紹介した、プロパティで指定する値を数式で計算することができるcalc()関数。
横並びのレイアウト以外でも、正確な幅の調整にはとても使える関数です。
レスポンシブWebデザインの構築ではとても使える関数ですので、ぜひ覚えておきましょう。