コンテナーの幅より広がったエリアをcalcでつくる

  • 30
    Like
  • 3
    Comment
More than 1 year has passed since last update.

calc.png

タイトルがなんともわかりづらいけど、キャプチャのような表現をする話。

記事の引用とかコードの表現でこういう見た目にしたいことがある。
やり方は色々あるけど、これをCSSのcalc()でやってみる。

記事全体を包括している親要素の幅が決まっていて、一部のブロック、セクションだけ左右ぶち抜きたい。

マークアップとCSSはこんな感じ。

<article class="entry"><!-- width: 44em; -->
  <h1 class="entry-title">セロ弾きのゴーシュ</h1>
  <div class="entry-body">
    <p>...</p>
    <div class="dialogue"><!-- ぶち抜きたいところ -->
      <p>...</p>
    </div>
    <p>...</p>
  </div>
</article>
.entry {
  margin-left: auto;
  margin-right: auto;
  width: 44em;
}

ここでCalc()

先にCSSを公開。

.dialogue {
  box-sizing: border-box;
  margin-left: calc(((100vw - 44rem) / 2) * -1);
  margin-right: calc(((100vw - 44rem) / 2) * -1);
  padding: 1.5em calc((100vw - 44rem) / 2);
  background-color: #345;
  color: #F9F8F7;
}

calc()は、CSSで四則演算が使える関数。すごいのは単位が異なっても計算できること。対応ブラウザはIE9以上、他最近のものであればたいてい使える。ただAndroidに関しては4.4以上というのがちょっと残念。
この単位を越えて計算できるのを今回は利用している。
追記:*1

計算内容

.dialogue {
  margin-left: calc(((100vw - 100%) / 2) * -1);
  margin-right: calc(((100vw - 100%) / 2) * -1);
}

考えたのは、コンテナーの左右の幅をどう算出するか。
それを算出するためには、ページ幅(viewport幅)からコンテナー幅を引く
ページ幅はvw = viewport width で出す。幅全体なので100vw
そこからコンテナー幅を引く。つまり、(100vw - 100%)

これで左右余白の幅は出せた。今回の例ではネガティブマージンで左右をぶちぬくようにするので、左右それぞれの幅を出す。
これは単純に等分で割るだけ。つまり、((100vw - 100%) / 2)
かつネガティブマージンなので負の値にする。(((100vw - 100%) / 2) * -1)
あと中央に寄せるために。左右のpaddingも同じようにつくる。
これで出来上がり。

結果は後述のCodepenで。

追記:*2

Codepen

http://codepen.io/hiloki/pen/bdKQQG

あとがき

今回の例だと、44rem以下のサイズになったときの考慮を何もしてないので、実際にはメディアクエリでどうこうとかもしないとイマイチ。

コメントにいただいた方法で、コンテナ幅の計算を44remじゃなくて100%にした。感謝。

追記

  1. "Safari & iOS Safari (both 6 and 7) does not support viewport units (vw, vh, etc) in calc()."ということで、これらでは今回の方法はダメ
  2. 44rem100%に。
  3. 横スクロールバー対策として、bodyoverflow-x:hiddenだけどもっと良い方法ありそう。