Nested rows in Bootstrap 3 fail to respect the gri

2019-05-11 04:07发布

问题:

Bootstrap seems to break its own grid once you get into nested rows. This is a good example:

div {
  border: 1px solid gray;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="row">
    <div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div>
  </div>
  <div class="row">
    <div class="col-xs-1">col</div>
    <div class="col-xs-10">
      <div class="row">
        <div class="col-xs-5">nested col-xs-5</div>
        <div class="col-xs-7">nested col-xs-7</div>
      </div>
    </div>
    <div class="col-xs-1">col</div>
  </div>
</div>

I would expect to be able to make the "nested xs-col-*" columns line up exactly with the 12 cols at the top. It also doesn't work if I make the inner classes col-xs-3/col-xs-7 (adding up to 10 like the containing col). That just leaves a gap at the right.

Is it correct to say that Bootstrap won't actually let you respect the grid once you get into nested rows if you use odd widths? Or am I doing it wrong?

It seems to me that whole point of a grid is that things should be aligned. Do I have to stay away from (nontrivial) nested rows if I want perfect alignment?

回答1:

1) Pick the proportions

Nested row also uses a 12-columns grid. So you asked Bootstrap to take 5/12 from 10 parent columns. But this is a fractional number. Because of this column boundaries do not coincide with each other.

Pick the proportions between the columns. For example:

  • 4/12 from 9 parent columns is exactly 3 parent columns
  • 3/12 from 8 parent columns is exactly 2 parent columns

div {
  outline: 1px solid gray;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="row">
    <div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div>
  </div>
  <div class="row">
    <div class="col-xs-1">col</div>
    <div class="col-xs-1">col</div>
    <div class="col-xs-1">col</div>
    <div class="col-xs-8">
      <div class="row">
        <div class="col-xs-3">nested 4</div>
        <div class="col-xs-9">nested 8</div>
      </div>
    </div>
    <div class="col-xs-1">col</div>
  </div>
  <div class="row">
    <div class="col-xs-1">col</div>
    <div class="col-xs-1">col</div>
    <div class="col-xs-9">
      <div class="row">
        <div class="col-xs-4">nested 3</div>
        <div class="col-xs-8">nested 9</div>
      </div>
    </div>
    <div class="col-xs-1">col</div>
  </div>
</div>

2) Simplify the layout

You can do the same without nested columns:

div {
  outline: 1px solid gray;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
  <div class="row">
    <div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div><div class="col-xs-1">col</div>
  </div>
  <div class="row">
    <div class="col-xs-1">col</div>
    <div class="col-xs-3">3 columns</div>
    <div class="col-xs-7">7 columns</div>
    <div class="col-xs-1">col</div>
  </div>
  <div class="row">
    <div class="col-xs-1">col</div>
    <div class="col-xs-4">4 columns</div>
    <div class="col-xs-6">6 columns</div>
    <div class="col-xs-1">col</div>
  </div>
</div>



回答2:

An alternative is to not use Bootstrap for your grid system.

http://shelvesgrid.org/ has as one of it's top 3 selling points that, "Shelves is the only fluid grid where the nested columns line up the grid, no matter how deep you go."

The trick used there is to use percentage widths all the way down but have nested percentage widths know they are nested.

For example in this situation (assuming a 12 column grid):

<div class="column-6">
    <div class="column-2"></div>
    <div class="column-2"></div>
    <div class="column-2"></div>
</div>

Shelves applies CSS that looks like this:

.column-2 { width: 16.6666667%; }
.column-6 { width: 50%; }
.column-6 .column-2 { 33.333333% }

The more specific later rule overrides the base definition of the width of a column-2 so that it will be the same size when nested in a .column-6 as it would be at the top level.

It's a pretty neat trick to have a grid that works "all the way down" so that column-2 always means 2/12ths of your grid and doesn't change its meaning (and break the grid) once you are nested.

(Sadly Shelves uses margin for the spacing between columns, not padding, and that caused problems for me so I ended up rolling my own using the above trick.)