今夜がλ

夜だけプログラマー

Bootstrapでborder持ち要素の余白を調整する方法

Bootstrapでborderを持った要素を並べようとすると要素同士のborderがぴったりとくっついて面倒なことになったので、解決手段をメモ。結論としては、「並べる要素の直下に囲い込むための要素を追加して囲い込む要素にborderを持たせる」のが今回対応した方法。
Bootstrap3でも4でも問題なく対応できるはず。
以下詳細。

普通に並べると隣接要素のborderがくっつく(失敗例)

Bootstrapのグリッドレイアウトを利用する基本ルールとして、「並べる要素」を「.container(もしくは.container-fluid)」と「.row」で囲むものとなる。今回の説明ではborderを持つ「li」を並べると仮定して以下のようなHTMLコードをを基に話を進める。

<style>
li{
  border: 1px solid black;
}
</style>

<div class="container">
  <ul class="row">
    <li class="col-xs-12">aaa</li>
    <li class="col-xs-12">bbb</li>
    ...
    <li class="col-xs-12">zzz</li>
  </ul>
</div>
並べる要素に直接marginを加えるのはNG

Bootstrapでは「.col-*」の左右にpaddingを持たせることで要素同士の余白を取る。つまり、「li」同士にmarginがないため、このままではborderがぴったりとくっついた形になる。
さらに、「.container」が左右にpaddingを持ち、「.row」がそのpaddingを打ち消す形でネガティブmarginを持っているので、「li」同士の余白を持ちながらも、左右端の「li」は「ul」の左右端に張り付くレイアウトを可能にしている。

そのため、「li」の左右にmarginをかけるとBootstrapで左端・右端にぴったりとくっつけるための機構を壊してしまう形になる。「li」marginをかけずに余白をとるために、「li」の直下要素にborderを持たせる必要がある。

borderを持った「li」に余白を持たせる場合、上記コードを変更すると以下のようになる。

隣接要素のborderがくっつかないように修正
<style>
.original-ul.row{
  margin-left: -20px; /* 「rowがデフォルトで持つネガティブmargin(-15px)」 - 「liに持たせたいpadding 」*/
  margin-right: -20px; /* 「rowがデフォルトで持つネガティブmargin(-15px)」 - 「liに持たせたいpadding 」*/
}
.original-ul > li{
  padding: 0 5px; /* 隣り合うborder同士の余白 */
}
li div{
  border: 1px solid black;
}
</style>

<div class="container">
  <ul class="row original-ul">
    <li class="col-xs-12"><div>aaa</div></li>
    <li class="col-xs-12"><div>bbb</div></li>
    ...
    <li class="col-xs-12"><div>zzz</div></li>
  </ul>
</div>

今回は隣り合うborder同士のpaddingを5pxとしたので、「.row」が持つネガティブmarginもその分加える(marginを減らす)必要がある。
全ての「.row」に変更後のスタイルが当たらないように、別途class(.original-ul)を追加してスタイルを当てた。

ある程度きっちりとしたデザインを作るのにBootstrapは適していないが、どうしてもborderを持った要素を並べたい場合は、上記のように対応するのがいいかと思われる。