
CSSのcalcで片側だけグリッドガイドライン外へ飛び出したカラム

中央揃えになっている固定グリッド(Fixed grids)から片側だけ外へ飛び出させた装飾のカラムを
リキッドレイアウトのレスポンシブデザインでスタイリングする方法です。

IE11も対応している CSSの calc()
で相対値と絶対値をかけあわせたサイズを設定するので
画面幅がかわっても、片側は中央揃えのカラムとツラをあわせたまま(端をそろえたまま)
もう片側は画面端までのびたサイズをキープできます。
※IEはpaddingの仕様に落とし穴があったので、最終的にはIEバグ対策のJavaScriptも併用しています。
INDEX
- よくある中央揃えのレスポンシブなカラム
- アシンメトリーなカラム
- まとめ
- サンプルソース
とりあえず実物から見てみたい方は、CodePenのサンプルソースからどうぞ!
See the Pen Asymmetry Column by webdev (@webdev-jp-net) on CodePen.
よくある中央揃えのレスポンシブなカラム
まず、中央揃えでレスポンシブに対応している1カラムレイアウトのCSSをおさらいしてみます。
※図中の数値は、カラム幅400px、左右外側の余白2rem、カラム内側の余白1remです。
画面幅 > カラム幅
max-width
に設定した グリッドガイドラインの幅が有効になり、センタリングされます。

画面幅 < カラム幅
width
に設定したcalc(100% - 左右の外側の余白)
が有効になり、
一定の左右マージンを保って画面幅にフィットします。

アシンメトリーなカラム
さて、ここからが本題です。
アシンメトリーカラムつくるときのポイントは、calc
を活用して
画面幅 = 変化が見込まれる値
と
カラム幅 = 常に一定の値
という
性質のちがう値どうしを組み合わせて距離を取得することです。
全体の設定を、図をまじえながら解説していきます。
- カラム全体の幅
- 外へ飛び出させた側の余白
- IE対策
1.カラム全体の幅
アンシンメトリーカラムの幅設定のポイントは、画面端からグリッドガイドラインまでの距離です。
画面幅 > カラム幅
max-width
は、画面端からグリッドガイドラインまでの距離 + グリッドガイドラインの幅
で求めます。
画面端からグリッドガイドラインまでの距離は、50% - カラム幅の半分
なので
まとめると、max-width
の求めかたはこのようになります。
calc(100% - (50% - カラム幅の半分))

画面幅 < カラム幅
width
の計算はシンプルに、
よくある中央揃えのカラムならば 画面幅から両側の余白を差し引くところ
片側の余白だけを差し引いて求めた値になります。
calc(100% - どちらか片側の外側の余白)
2.外へ飛び出させた側の余白
飛び出させた側の余白を多めにとって、内側の端をグリッドガイドラインに合わせます。
このときのポイントは、padding
と透明border
を組み合わせることです。
さきに失敗例からになりますが、
画面の端からグリッドガイドラインまでの余白をpadding
にcalc
をつかって実現しようとしたところ
画面幅が広いときは、内容とグリッドガイドラインが揃うものの
画面幅が狭くなりリキッドで縮んだ状態になるとずれてしまいます。
画面幅 > カラム幅(揃う)

画面幅 < カラム幅(ずれる)

そうならないために、画面幅が縮まったときのカラム外側の余白対策として
透明色のborder
を併用すると、常に端を揃えられるようになります。
画面幅 < カラム幅(揃う)
透明borderの幅 = calc(カラム外側の余白 + カラム内側の余白)
※図中の数値は、カラム幅400px、カラム外側の余白2rem、カラム内側の余白1remです。

3.IE対策
モダンブラウザでは、calc(50% - (カラム幅 / 2) - カラム外側の余白)
がマイナスの値になると
値が0のときと同じ振る舞いをしますが
Internet Explorerはpadding
の値がマイナスでも、そのまま再現する仕様になっています。
そのため、画面幅がカラム幅より狭くなると
内容が画面端に向かってめり込んだ状態に崩れます。
画面幅 < カラム幅(ずれる)

IEも対象環境に含め、このテクニックを使用する場合は
paddingが0を下回らないよう制限するJavaScript、Disable Negative Paddingか
それに準ずるpaddingのマイナス値を抑制する仕組みも併用してください。
スクリプトも併用すると、IEでも表示も担保できるようになりました。
Disable Negative Paddingデモ
まとめ
全体的な設定はこのようになりました。

.左寄せのアシンメトリーカラム { max-width: calc(100% - (50% - (カラム幅 / 2))); width: calc(100% - カラム外側の余白); margin-left: 0; margin-right: auto; padding: カラム内側の余白; padding-left: calc(50% - (カラム幅 / 2) - カラム外側の余白); border-left: solid transparent; border-left-width: calc(カラム外側の余白 + カラム内側の余白); }
IE対応
IEも対象とする場合は、Disable Negative Paddingも設定します。
<script src="https://webdev-jp-net.github.io/disableNegativePadding/disableNegativePadding.min.js"></script>
var init = function() { // アシンメトリーカラムの要素をみつけて処理 var asymmetrys = [].slice.call(document.querySelectorAll('.左寄せのアシンメトリーカラム')); asymmetrys.forEach(function(o) { // Disable Negative Paddingを設定 var myDNP = new disableNegativePadding(o); }); }; window.addEventListener('DOMContentLoaded', init, {once: true}); // HTML描画後に処理する
サンプルソース
CodePenのサンプルソースには、こんなおまけもついています。
深堀りしてみたい方は、ご覧になってみてください。
- Sassの
mixin
- カラム幅と余白の値を書き換えられるシミュレータ
- ボーダーやドロップシャドウで装飾するユースケースのサンプル