かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

CSS 100%幅の子要素にネガティブマージンを使うと右側だけはみ出して横スクロールが表示されてしまう

所謂Bootstrapの.row.col-で使われているような親要素が左右のネガティブマージンを持ち子要素がfloatを使ったカラムレイアウトを100%の画面に入れた時に右側だけが100%のブラウザサイズからはみ出して横スクロールが表示される現象に遭遇しました。

横スクロールが発生する例

HTML

<div class="container">
  <div class="row">
    <div class="col col-half">
      <div class="content">content</div>
    </div>
    <div class="col col-half">
      <div class="content">content</div>
    </div>
  </div>
</div>

CSS (stylus表記)

*
  box-sizing: border-box
.container
  width: 100%
.row
  margin-left: -15px
  margin-right: -15px
  .col
    float: left
    padding-left: 15px
    padding-right: 15px
  .col-half
    width: 50%

f:id:kikiki-kiki:20170325212944p:plain
こんな風に横スクロールが発生してしまいます。

解決方法1 ネガディブマージンを持つ要素の親にパディングを持たせる

Bootstrapをよくよく観察していると、ネガティブマージンを持つ.rowの親要素には必ずネガティブマージン分のパディングを持つ要素がある事に気が付きました。親要素にパティングを持たせておくことでウィンドウサイズからはみ出さないようにしているようです。

HTML

<div class="container">
  <div class="wrap">
    <div class="row">
      <div class="col col-half">
        <div class="content">content</div>
      </div>
      <div class="col col-half">
        <div class="content">content</div>
      </div>
    </div>
  </div>
</div>

CSS

.wrap
  padding-left: 15px
  padding-right: 15px

ネガティブマージンを持つ要素を囲み、囲った要素にネガティブマージン分のパディングをもたせればOKです。
f:id:kikiki-kiki:20170325223024p:plain
横スクロールは発生しませんが、.content.colの持つパディング分左右が小さくなります。
border-boxを使っているこの状態なら下記のような.rowに初めからネガティブマージンを持たせないものと同じ結果です。

*
  box-sizing: border-box
.container
  width: 100%
.row
  .col
    float: left
    padding-left: 15px
    padding-right: 15px
  .col-half
    width: 50%

解決方法2 ネガティブマージンを持つ要素の親にoverflow: hiddenを設定する

.colの持つパディング分を画面外に出し、.contentを画面の端一杯にしたいときは、ネガティブマージンをもつ.rowの親に幅指定と共にoverflow: hiddenを設定すればOKです。
HTML

<div class="container">
  <div class="row">
    <div class="col col-half">
      <div class="content">content</div>
    </div>
    <div class="col col-half">
      <div class="content">content</div>
    </div>
  </div>
</div>

CSS

*
  box-sizing: border-box
.container
  width: 100%
    overflow: hidden // <- 追加
.row
  margin-left: -15px
  margin-right: -15px
  .col
    float: left
    padding-left: 15px
    padding-right: 15px
  .col-half
    width: 50%

f:id:kikiki-kiki:20170325223042p:plain
図のように画面端から.contentのエリアになります。
overflow: hiddenを使用するのであまり上のレイヤーの要素にこの設定をしてしまうと他のデザインで苦労する自体が発生しかねないので注意が必要です。
 
しばらくCSSとか書いてなかったので予期しないレベルダウンを感じています…
今までこんな所に躓いたこと無かった気が…

ITがメインではない仕事に就いている(正確には仕事がない)とドンドンレベルダウンしていっているのを身にしみて感じていて、今迄できていたような事がカンタンに出来なくなるってのが凄まじいストレスと自己嫌悪になるので、都会に引越ししてエンジニア的なお仕事に再就職したい今日この頃なのでした…


[参考]

はじめてのCSS設計 フロントエンドエンジニアが教えるメンテナブルなCSS設計手法 (WEB Engineer’s Books)

はじめてのCSS設計 フロントエンドエンジニアが教えるメンテナブルなCSS設計手法 (WEB Engineer’s Books)