如何使用 Bootstrap 搭建更合理的 HTML 结构
前言
Bootstrap 的成功不仅在于其简单易用,更在于其样式的规范性以及 HTML 结构的合理性。但是很多人在使用 Bootstrap 时只是依照文档盲目的复制黏贴,并没有仔细考虑每个类的用处,也没有考虑 HTML 结构搭建的是否合理。在平时的工作中,我一直和同事强调,一定要挖掘框架的精髓,尽可能的使用框架本身具有的类实现布局,几乎所有的 UI 布局都可以使用框架本身完成而不需要编写额外的冗余的样式。本文的目的就是介绍如何使用 Bootstrap 搭建常用的布局,并保证布局具有合理的 HTML 结构。不管是传统开发,还是使用框架,搭建布局的思想是不会变的。本文所有案例均以 Bootstrap 3 为例, Bootstrap 4 变化较大,但也基本适用,需要读者仔细比对,不可盲目照抄。
合理利用栅格
保证合理嵌套
Bootstrap 栅格类的随意嵌套是造成 HTML 结构混乱的主要原因,虽然 Bootstrap 的栅格类在随意嵌套时并不会出现严重问题,但会引发潜在的问题,对于细节控是无法容忍的。比如下面的这种常见错误嵌套:
<div class="row">
<div class="col-md-6">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>
<div class="col-md-6">.col-md-6</div>
</div>
表面看并没有大问题,但是如果将栅格描边,就会看出不同,见下面的 CodePen:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
我们必须明白每个 Bootstrap 栅格类的作用。其中 .row
和 .col-*
必须要搭配使用,缺一不可,因为 .row
是为了抵消 .col-*
的 margin 负值,所以并不是可有可无的类。所以,上面例子的正确结构如下:
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>
</div>
<div class="col-md-6">.col-md-6</div>
</div>
这是我工作过程中见过的最多的一种错误,必须格外注意。
灵活利用栅格偏移
栅格的列偏移 .col-{breakpoint}-offset-*
应该也算是比较常用的布局类,但是我们往往忽视它在大块版面布局的作用。举个例子,比如一个登录框在右侧的登录页面:
对于表单在右侧的布局,实现方式有很多,比如单独使用 float
实现偏移,或者使用绝对/相对定位实现。但是更好的方式应该是使用栅格的列偏移实现,因为栅格支持响应式布局。
以下是响应式登录页的例子:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
建议在 CodePen 中打开查看效果,因为我的博客内容区较窄,所以只能看到响应式布局的小屏断点。
虽然栅格布局很好,但在工作中一定要谨慎使用,因为很多不懂前端的设计师或产品会对前端人员吹毛求疵,这样的话也只能根据具体要求做一些调整了。
水平表单排列
表单中的横向栅格布局非常常见,Bootstrap 官网也给出了案例,但是对于多列的横向表单布局会稍显复杂,过多的栅格嵌套让人抓狂。但是只要记住一点,布局就会游刃有余。
通过添加 .form-horizontal
类,表单就可以横向排布,此时的 .form-group
类就相当于 .row
类,两者的行为是一样的,所以此时无需再添加 .row
类。
<form class="form-horizontal">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
...
</form>
注意,在 Bootstrap 4 中, .row
类不能省略,需要写成这样 .form-group row
才行。其实也没有什么区别,都是为了形成 .row > .col-* > .row > .col-* 这种结构。
<form>
<div class="form-group row">
<label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
...
</form>
以下是 Bootstrap 3 横向表单布局的例子:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
上面的例子比官网多了一层栅格,只有在大屏中才能看到效果,这种栅格内的表单嵌套在不熟悉 Bootstrap 的情况下很容易写乱,但只要记住了上面提到的规则,就可以轻而易举的写出来。
静态表单排列
很多人在看到上面的结构时,几乎二话不说,就写出 ul>li 这样的布局,而且添加诸如 .list
.item
这些无意义的类。依然是开篇提到的,我们必须始终坚持一个原则,尽可能不要随意添加样式,而是探索框架本身具有的类,几乎都可以找到解决方法。
仔细想想,上面的例子中的布局方式无非就是栅格内的行内表单。所以实现方法非常简单,完全不用自己编写样式。
以下是实时演示,建议在大屏查看效果:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
表格结构
关于表格可以说的并不多,只是建议全部采用响应式表格结构,也就是添加 .table-responsive
元素。因为在实际工作中,表格的列数一般比较多,响应式表格应该是更通用的方案。
<div class="table-responsive">
<table class="table">
...
</table>
</div>
先排列,再排行
这条规则只是建议,因为 HTML 的块级元素默认是占一行,所以先排列可以减少 HTML 的结构,使结构更简洁。另一方面,对于高度不同的元素,哪怕是很小的差距,都会出现布局的错位,见下面的 CodePen:
See the Pen Bootstrap-demo by Zongbin (@nzbin) on CodePen.
为了解决这个问题,必须在每一行都添加 .row
。不过在某些时候,我们也不得不这样写。
<div class="row">
<div class="col-xs-6">
...
</div>
<div class="col-xs-6">
...
</div>
</div>
<div class="row">
<div class="col-xs-6">
...
</div>
<div class="col-xs-6">
...
</div>
</div>
...
如果是先排列,就不用担心上面的问题,这种排列方式有点像瀑布流。
<div class="row">
<div class="col-xs-6">
...
...
</div>
<div class="col-xs-6">
...
...
</div>
</div>
这条建议需要根据实际的需求调整,需要和设计师以及产品做好沟通,不然肯定面临返工的危险。只能说从结构上而言,先排列会好一些。假如使用 Flex 布局的话,就可以很好地解决这个问题了。
总结
先说点题外话,我一直觉得优秀的网页作品不是或者不全是设计师决定的,甚至不应该由设计师决定,因为国内的设计师真正懂前端的还是少数,而且设计风格难以紧跟潮流。设计师和产品经常将交互挂在嘴边,但是他们提出的很多交互形式在我们前端人员看来都是网页必备的基本要素,并不是一个亮点。反观国外,设计师懂前端甚至很精通,前端开发者也是设计师或者交互设计师,每个人都是复合型人才,这是值得我们学习的方面。
言归正传,本文主要介绍了在使用 Bootstrap 时如何搭建更合理的结构,然而在实际工作中,不管我们用不用框架,都应该尽可能的精简并规范化 HTML 结构,这是前端开发人员应该养成的良好习惯。另外说明一点,因为框架是很多问题的抽象,所以在通用性的前提下,不可避免的会有一些冗余的 HTML 结构。
我在开篇就强调尽量不要编写冗余的样式,但是如果真的不能满足布局要求时,我们首先应该使用 helper 解决,Bootstrap 3 的 helper 并不丰富,而 Bootstrap 4 则添加了大量的 helper 辅助类。我在之前也写了一篇关于 helper 的文章《如何编写通用的 Helper Class》,感兴趣的话可以看一看。
- 怎样突破表名30个字符的限制(r2笔记51天)
- C/C++——排序
- 关于move tablespace的问题总结(r2笔记50天)
- 一些极度危险的linux命令(r2笔记49天)
- 挑战数据结构与算法面试题——80题全解析(一)
- 关于操作失误的数据修复(r2笔记48天)
- 挑战数据结构与算法面试题——80题全解析(三)
- 巧用rowid简化sql查询(r2笔记47天)
- 算法类面试题解析——美团2016校招:棋子翻转
- 算法类面试题解析——美团2016校招:最大差值
- 用Python进行机器学习小案例
- 启用ODM极速调优IO (r2笔记66天)
- 通过addm分析io问题(r2笔记64天)
- python爬虫+R数据可视化 实例
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例
- PHP使用Redis实现Session共享的实现示例
- windows10在visual studio2019下配置使用openCV4.3.0
- PHP5.0 TIDY_PARSE_FILE缓冲区溢出漏洞的解决方案
- Python爬虫爬取新闻资讯案例详解
- Python代码需要缩进吗
- 解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
- Python计算信息熵实例
- 详解python logging日志传输
- 将tf.batch_matmul替换成tf.matmul的实现
- Python正则表达式高级使用方法汇总
- CentOS7.0下安装PHP5.6.30服务的教程详解
- Laravel Validator自定义错误返回提示消息并在前端展示
- 完美解决keras 读取多个hdf5文件进行训练的问题
- keras:model.compile损失函数的用法
- PHP获取当前系统时间的方法小结