Bootstrap响应式的HTML嵌套规则

使用Bootstrap已经很长时间了,总结一些HTML嵌套规则和Bootstrap的class使用。本来要自己总结的,重新看Bootstrap官网时发现了bootlint,所以直接把内容搬了过来,进行了分类汇总。

Bootlint使用

Bootlint是Bootstrap官方推出的一个工具,用来检测HTML结构是否符合Bootstrap响应式的规则。因为不正确的HTML嵌套,Bootstrap响应式效果不会生效。

bootlint:问题代码参考地址https://github.com/twbs/bootlint/wiki

手动引入bootlint.js

</body>之前引入bootlint.js

使用bookmarklet动态引入

添加一个书签,url配置为:

1
2
> javascript:(function(){var s=document.createElement("script");s.onload=function(){bootlint.showLintReportForCurrentDocument([]);};s.src="https://maxcdn.bootstrapcdn.com/bootlint/latest/bootlint.min.js";document.body.appendChild(s)})();
>

当你点击书签时,自动在当前页面引入。

Bootstrap的HTML嵌套规则

为什么要了解Bootstrap框架规定的HTML嵌套规则呢?因为只有了解了嵌套规则才能把响应式布局用好。

.container

.container.container-fluid不能嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- wrong -->
<div class="container">
<div class="container">
...
</div>
</div>

<div class="container-fluid">
<div class="container-fluid">
...
</div>
</div>

<div class="container">
<div class="foobar">
...
<div class="container">
...
</div>
...
</div>
</div>

<div class="container-fluid">
<div class="container">
...
</div>
</div>

.row

.row的子节点应该只有.col-*-*

Bootlint found non-grid-column children of grid rows. Bootstrap’s grid system requires that all children of grid rows must be grid columns.

Wrong:

1
2
3
4
5
<div class="row">
<div class="my-awesome-thing">...</div>
<div class="other-thing">...</div>
<div class="row">...</div>
</div>

Right:

1
2
3
4
5
6
7
<div class="row">
<div class="col-sm-6">...</div>
<div class="col-lg-12">...</div>
<div class="col-xs-12">
<div class="row">...</div>
</div>
</div>

.row必须是.container或者.container-fluid的后代节点

1
2
3
4
5
<div class="container">
<div class="row">

</div>
</div>

.row and .col-*-* 不能同时用在同一个元素上

Wrong:

1
<div class="row col-xs-6">...</div>

Right (Note that the two options have different meanings):

1
2
3
4
5
6
7
8
9
<div class="row">
<div class="col-xs-6">...</div>
</div>

<!-- Or, depending on the semantics you need: -->

<div class="col-xs-6">
<div class="row">...</div>
</div>

column(.col-*-*)

.col-*-*不能应用float属性

wrong

1
2
3
<div class="col-sm-7 pull-right">

<div class="col-sm-7" style="float: left;">

多余的col-*-*

1
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6"></div>

col-xs-6适用于等于和大于它的尺寸,所以其它col-sm-6 col-md-6 col-lg-6都是多余的。

但是不同的尺寸下,宽度不一样时,不能这样使用

1
<div class="col-xs-6">这样就行了</div>

.col-*-*只应该是.row.form-groups的子节点

Wrong:

1
2
3
4
5
6
7
8
9
10
11
<div class="my-random-thing">
<div class="col-sm-6">...</div>
<div class="col-sm-6">...</div>
</div>

<div class="row">
<div class="col-sm-12">
<div class="col-sm-12">...</div>
<!-- You can't nest columns directly like this. This is missing a level of .row -->
</div>
</div>

Right:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="row">
<div class="col-sm-6">...</div>
<div class="col-sm-6">...</div>
</div>

<div class="form-horizontal">
<div class="form-group">
<div class="col-sm-6">...</div>
<div class="col-sm-6">...</div>
</div>
</div>

<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">...</div>
</div>
</div>
</div>

.input-group

.input-group 不能包含 <select>

Wrong:

1
2
3
4
5
6
7
8
9
<!-- select 不能自适应宽度 在webkit浏览器中 -->
<div class="input-group">
<span class="input-group-addon">$</span>
<select class="form-control">
<option value="5.00"><option>
<option value="50.00"><option>
<option value="500.00"><option>
</select>
</div>

.input-group 不能包含 <textarea>

Wrong:

1
2
3
4
5
<!-- input-group只能包含那些基于input的元素 -->
<div class="input-group">
<span class="input-group-addon"></span>
<textarea class="form-control" placeholder="To Whom It May Concern:"></textarea>
</div>

.input-group不能包含多个.form-control元素

Wrong (unsupported):

1
2
3
4
5
<div class="input-group">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" placeholder="Dollars">
<input type="text" class="form-control" placeholder="Cents">
</div>

Right (supported):

1
2
3
4
<div class="input-group">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" placeholder="Amount">
</div>

Wrong (unsupported):

1
2
3
4
5
<div class="input-group">
<input type="text" class="form-control" placeholder="Username">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Domain">
</div>

Right (supported):

1
2
3
4
<div class="input-group">
<input type="text" class="form-control" placeholder="Username">
<span class="input-group-addon">@example.com</span>
</div>

.input-group.form-group不能同时应用同一元素

应该在.from-group中嵌套.input-group

Wrong:

1
2
3
4
<div class="form-group input-group">
<div class="input-group-addon">@</div>
<input class="form-control" type="email" placeholder="Enter nickname">
</div>

Right:

1
2
3
4
5
6
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">@</div>
<input class="form-control" type="email" placeholder="Enter nickname">
</div>
</div>

.input-group and .col-*-* 不能同时直接应用在同一元素上

.col-*-*不能用在 .input-group元素上. 应该在 .col-*-*中嵌套.input-group

Wrong:

1
2
3
4
<div class="input-group col-sm-5">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Username">
</div>

Right:

1
2
3
4
5
6
<div class="col-sm-5">
<div class="input-group">
<span class="input-group-addon">@</span>
<input type="text" class="form-control" placeholder="Username">
</div>
</div>

.input-group不支持在input单边(左边或者右边)包含多个.input-group-addon

Right (two add-ons are fine so long as they’re on different sides):

1
2
3
4
5
<div class="input-group">
<span class="input-group-addon">$</span>
<input type="text" class="form-control">
<span class="input-group-addon">.00</span>
</div>

Wrong:

1
2
3
4
5
<div class="input-group">
<span class="input-group-addon">USD</span>
<span class="input-group-addon">$</span>
<input type="text" class="form-control">
</div>

Wrong:

1
2
3
4
5
<div class="input-group">
<input type="text" class="form-control">
<span class="input-group-addon">.00</span>
<span class="input-group-addon">USD</span>
</div>

button

.btn 只能用在<a> button <label> <input>元素上

1
2
3
4
<a class="btn btn-primary">Button</a>
<button type="button" class="btn btn-primary">Button</button>
<input type="button" class="btn btn-primary" value="Button">
<label class="btn btn-primary">Button</label>

button和input大小(在input-group中)

应该使用input-group-lg代替btn-lg

Wrong:

1
2
3
4
5
6
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default btn-lg" type="button">Go!</button>
</span>
<input type="text" class="form-control input-lg" />
</div>

Right:

1
2
3
4
5
6
<div class="input-group input-group-lg">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
<input type="text" class="form-control" />
</div>

.btn.dropdown-toggle 只能是button group最后一个元素.

Due to current limitations, for proper rendering, the dropdown toggle button in a split button dropdown must be the last button in the .btn-group.

Wrong:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="btn-group">
<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
<button type="button" class="btn btn-danger">Action</button>
</div>

Right:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>

checkbox

.checkboxclass要求结构固定

.checkbox>label>input[type="checkbox"]

1
2
3
4
5
<div class="checkbox">
<label>
<input type="checkbox" /> Label text goes here
</label>
</div>

.checkbox-inline 只能用在 <label>元素

Wrong:

1
2
3
<span class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" value="option1" /> Option number one
</span>

Right:

1
2
3
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" value="option1" /> Option number one
</label>

.checkbox-inline class正确的标签结构

正确的结构是label.checkbox-inline>input[type="checkbox"]

.checkbox-inline requires a specific DOM structure. There cannot be any intervening layers of elements.

Wrong:

1
2
3
4
5
<label class="checkbox-inline">
<span class="my-awesome-wrapper">
<input type="checkbox" id="inlineCheckbox1" value="option1" /> Option number one
</span>
</label>

Right:

1
2
3
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" value="option1" /> Option number one
</label>

.radioclass要求固定结构

.radio>label>input[type="radio"]

1
2
3
4
5
6
<div class="radio">
<label>
<input type="radio" name="someChoiceGroup" value="option1" />
This is option number one
</label>
</div>

.radio-inline 只应该用在 <label>元素

Wrong:

1
2
3
4
5
6
<span class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio1" value="option1" /> Option one
</span>
<span class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio2" value="option2" /> Option two
</span>

Right:

1
2
3
4
5
6
<label class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio1" value="option1" /> Option one
</label>
<label class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio2" value="option2" /> Option two
</label>

.radio-inline class正确使用方式

正确标签结构:label.radio-inline>input[type="radio"]

.radio-inline requires a specific DOM structure. There cannot be any intervening layers of elements.

Wrong:

1
2
3
4
5
6
7
8
9
10
<label class="radio-inline">
<span class="my-awesome-wrapper">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio1" value="option1" /> Option one
</span>
</label>
<label class="radio-inline">
<span class="my-awesome-wrapper">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio2" value="option2" /> Option two
</span>
</label>

Right:

1
2
3
4
5
6
<label class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio1" value="option1" /> Option one
</label>
<label class="radio-inline">
<input type="radio" name="someInlineRadioOptions" id="inlineRadio2" value="option2" /> Option two
</label>

.active & checked

.checkbox.radio.active状态

.bt-group中使用.checkbox.radio,当input[type="checkbox"]input[type="radio"]元素是checked状态,它们的<label>标签必须添加.active样式。

Wrong:

1
2
3
4
5
6
7
8
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="checkbox" checked /> Option 1 (pre-checked)
</label>
<label class="btn btn-primary active">
<input type="checkbox" /> Option 2 (not pre-checked)
</label>
</div>

Right:

1
2
3
4
5
6
7
8
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="checkbox" checked /> Option 1 (pre-checked)
</label>
<label class="btn btn-primary">
<input type="checkbox" /> Option 2 (not pre-checked)
</label>
</div>

Wrong:

1
2
3
4
5
6
7
8
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="options" id="option1" checked /> Option 1 (preselected)
</label>
<label class="btn btn-primary active">
<input type="radio" name="options" id="option2" /> Option 2 (not preselected)
</label>
</div>

Right:

1
2
3
4
5
6
7
8
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" checked /> Option 1 (preselected)
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" /> Option 2 (not preselected)
</label>
</div>

panel

.panel-footer.panel-heading 父元素必须是 .panel

.panel-footer.panel-heading必须是.panel的直接子节点。.panel-footer.panel-heading.panel之间不能有任何的其它节点干扰。

Wrong:

1
2
3
4
5
6
7
8
9
10
11
<div class="panel panel-default">
<div class="my-super-special-wrapper">
<div class="panel-heading">Panel heading without title</div>
</div>
<div class="panel-body">
Panel content
</div>
<div class="my-super-special-wrapper">
<div class="panel-footer">Panel footer</div>
</div>
</div>

Right:

1
2
3
4
5
6
7
<div class="panel panel-default">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
Panel content
</div>
<div class="panel-footer">Panel footer</div>
</div>

.panel-title父元素必须是.panel-heading

table

.table-responsice应用在table的父元素上,而不是table元素

Wrong:

1
2
3
<table class="table table-responsive">
...
</table>

Right:

1
2
3
4
5
<div class="table-responsive">
<table class="table">
...
</table>
</div>

form

.form-group元素不能嵌套

1
2
3
4
5
6
<div class="form-group">
...
</div>
<div class="form-group">
...
</div>

.form-inline 或者.form-horizontal直接使用在 .form-group. 元素上

或者 .form-group 嵌套在 .form-inline or .form-horizontal内部

1
2
3
4
5
6
7
8
9
10
11
<div class="form-inline">
<div class="form-group">
...
</div>
</div>

<div class="form-horizontal">
<div class="form-group">
...
</div>
</div>

.form-control-feedback

.form-control-feedback元素的祖先元素必须有 .form-group.has-feedback 样式

Wrong:

1
2
3
4
5
<div class="form-group has-error">
<label class="control-label" for="inputError2">Input with error</label>
<input type="text" class="form-control" id="inputError2">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>

Right:

1
2
3
4
5
<div class="form-group has-feedback has-error">
<label class="control-label" for="inputError2">Input with error</label>
<input type="text" class="form-control" id="inputError2">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
</div>

.form-control不能用在没有交互输入的文本属性的input

Right

1
2
3
4
5
6
7
<input type="text" class="form-control" value="Text input" />
<textarea class="form-control">Text area</textarea>
<select class="form-control">
<option>Option 1</option>
<option>Option 2</option>
...
</select>

glyphicon

.glyphicon-*必须和.glyphicon结合使用

1
<span class="glyphicon glyphicon-heart"></span>

.glyphicon-*的元素,不能有子节点和文本节点

Wrong:

1
<span class="glyphicon glyphicon-heart"><a href="#love">I love this</a></span>

Right:

1
<span class="glyphicon glyphicon-heart"></span> <a href="#love">I love this</a>

modal正确的嵌套结构

.modal .modal-dialog .modal-content .modal-header .modal-title .modal-body .modal-footer嵌套结构不能改变。

.modal-header .modal-footer是可选的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<div class="modal-body">
<p>One fine body</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>

.hide should not be used on .modal in Bootstrap v3.

.hide在Bootstrap3中不能应用在.modal身上。

.modal必须含有tabindexrole属性

1
2
3
<div class="modal" tabindex="-1" role="dialog">
...
</div>
1
2
3
<div class="modal-dialog" role="document">
...
</div>

.alert

.alert 包含dismiss button时 必须包含 .alert-dismissible样式

1
2
3
4
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" data-dismiss="alert">Dismiss</button>
Better check yourself, you're not looking too good.
</div>

.alert.closebutton必须是第一个子节点

1
2
3
4
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
Better check yourself, you're not looking too good.
</div>

media

.media-left and .media-right.media 内部使用.

1
2
3
4
5
6
7
8
<div class="media">
<div class="media-left">
...
</div>
<div class="media-body">
...
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-42">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-42">
<p class="navbar-text navbar-right">Signed in as Mark Otto</p>
</div>
</div>
</nav>
1
2
3
4
5
<div class="carousel-inner" role="listbox">
<div class="item active">...</div>
<div class="item">...</div>
...
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="carousel-example-generic" class="carousel slide">
<ol class="carousel-indicators">...</ol>

<div class="carousel-inner" role="listbox">
...
</div>

<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>

等等规则,详情见bootlint wiki

参考

https://www.tutorialrepublic.com/twitter-bootstrap-tutorial/

https://github.com/twbs/bootlint/

https://github.com/twbs/bootlint/blob/master/dist/browser/bootlint.js