构建了公司网站之后,接下来就可以考虑设计一个在线商店了。
此次的设计以上一章的设计为基础, 只是添加了一个包含如下元素的新页面:
□ 包含商品小图、标题和说明的产品网格;
□ 位于左侧的变懒,用于按类别、品牌等筛选商品;
□ 方便用户导航的面包屑和分页链接。
大家先看一看Zappos (http://www.zappos.com/) 和 Amazon (https://www.amazon.com/) 的网站,搜索或者浏览一下其中的商品。此处所要创建的页面,就包含与之类似的商品网格。
完成后的设计在大、中、小屏幕中的效果应该如下图所示:
在超小屏幕上,我们希望页面的布局变成如下所示:
Bootstrap 为完成此次设计提供了很好起点,在此基础上,我们要使用LESS完成调整工作。
1.商品页的标记
我们可以看到页头、导航条内容以及页脚都和上一章的一致,主要是主内容部分不一样。可以从效果图看出,我们可以把主内容分为三个部分:
第1部分: 用无序列表生成的面包屑导航链接。
第2部分:用 h1 表示的页面标题。
第3部分:
□ 一系列用于筛选商品的选项;
□ 九个商品,分别带有小图、标题、说明和按钮;
□ 用无序列表生成的分页链接,位于商品之下,站点页脚之上。
1.1 包屑导航链接
可以参考官方文档:http://getbootstrap.com/components/#breadcrumbs (中文文档:http://v3.bootcss.com/components/#breadcrumbs)
(1)很简单,我们先根据文档敲出代码如下:
<div role="main"> <div class="container"> <ol class="breadcrumb"> <li><a href="#">Home</a></li> <li><a href="#">Parent Category</a></li> <li class="active">Current Category</li> </ol> </div> </div>
可以看到显示效果如下:
(2) 然后我们来自定义面包屑的设计,去掉浅灰色背景和多余的内边距。对于这个简单的调整,我们可以直接修改 bootstrap 文件夹中的 breadcrumbs.less 文件,同时注释掉不需要的行,这样可以留下修改的痕迹:
.breadcrumb {
padding: 0; //@breadcrumb-padding-vertical @breadcrumb-padding-horizontal;
margin-bottom: @line-height-computed;
list-style: none;
//background-color: @breadcrumb-bg;
修改后显示效果如下:
1.2 页面标题
同样,官方文档:http://getbootstrap.com/components/#page-header (中文文档:http://v3.bootcss.com/components/#page-header)
(1) 同样,参考文档,可以敲出代码如下:
<div class="page-header"> <h1>Product Category Name <small>with explanatory text</small></h1> </div>
可以看到显示效果如下:
(2) 我们简单的调整下样式,删除下方边框。打开 bootstrap 文件夹中的 type.less 文件,搜索 .page-header 并把规则 border-bottom 注释掉:
.page-header {
padding-bottom: ((@line-height-computed / 2) - 1);
margin: (@line-height-computed * 2) 0 @line-height-computed;
//border-bottom: 1px solid @page-header-border-color;
}
保存,编译,刷新,就会看到更清爽的结果。更多的空白与我们整体设计保持了一致,如下所示;
1.3 侧边栏、商品网格、分页链接
我们的主要显示内容就是左侧的侧边栏和右侧的商品网格,很明显,我们用栅格系统把它分为两个部分:
<div class="row"> <div class="grid-options col-sm-3"> </div> <div class="products-grid col-sm-9"> </div> </div>
1.3.1 侧边栏
我们可以看到侧边栏由几个标题和对应的筛选商品的选项以及一个超链接按钮组成,我们可以先简单的实现代码如下,具体样式,我们之后再调整。
<div class="grid-options col-sm-3"> <h2>Narrow your selection</h2> <a class="choose-clearance" href="#"> <h3>Clearance Sale</h3> <p>View clearance items</p> </a> <h3>Categories</h3> <ul class="options-list options-categories"> <li><a href="#">Option 1</a></li> <li><a href="#">Option 2</a></li> <li><a href="#">Option 3</a></li> <li><a href="#">Option 4</a></li> <li><a href="#">Option 5</a></li> <li><a href="#">Option 6</a></li> <li><a href="#">Option 7</a></li> <li><a href="#">Option 8</a></li> <li><a href="#">Option 9</a></li> <li><a href="#">Option 10</a></li> </ul> <h3>Brands</h3> <ul class="options-list options-brands"> <li><a href="#">Option 1</a></li> <li><a href="#">Option 2</a></li> <li><a href="#">Option 3</a></li> <li><a href="#">Option 4</a></li> <li><a href="#">Option 5</a></li> <li><a href="#">Option 6</a></li> <li><a href="#">Option 7</a></li> <li><a href="#">Option 8</a></li> <li><a href="#">Option 9</a></li> <li><a href="#">Option 10</a></li> </ul> <h3>Another Filter</h3> <ul class="options-list options-other"> <li><a href="#">Option 1</a></li> <li><a href="#">Option 2</a></li> <li><a href="#">Option 3</a></li> <li><a href="#">Option 4</a></li> <li><a href="#">Option 5</a></li> <li><a href="#">Option 6</a></li> <li><a href="#">Option 7</a></li> <li><a href="#">Option 8</a></li> <li><a href="#">Option 9</a></li> <li><a href="#">Option 10</a></li> </ul> </div>
1.3.2 商品网格
至于商品网格,我们可以看到是由九种商品的商品网格,以及商品网格下的分页链接组成。
同样,我们用栅格系统简单实现九个商品的显示,每行三个商品,共三列。
<div class="products-grid col-sm-9"> <div class="row"> <div class="product-item col-sm-4"> <a href="#"><img src="img/product.png" alt="sample product" /></a> <h2><a href="#">Product Title</a></h2> <p>This text describes the above product a little not too much but just enough or maybe a little more</p> <a class="btn btn-default btn-xs pull-right" href="#">View this product <i class="fa fa-arrow-circle-right"></i></a> </div>
... </div> <!-- /.row --> </div>
1.3.3 分页链接
这个很简单,一般使用无序列表实现。不过,我们可以参考分页的官方文档或者中文文档,可以实现代码如下:
<nav> <ul class="pagination"> <li class="disabled"><a href="#">«</a></li> <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">»</a></li> </ul> </nav>
显示效果如下:
这样主页内容就搭建起来了,我们需要的就是对商品网格和侧边栏进行调整。
2.调整商品网格
我们需要把商品网格调整到位。之前我们使用栅格系统,通过 col-sm-4 类来约束每个商品的宽度,但整个网格看起来仍然尽不如人意。
<div class="product-item col-sm-4">
主要是由于商品简介的长短的不一致,导致每个商品的高度不确定。因此,Bootstrap 在向左浮动所有商品时,后面的商品就可能插入到前面的商品中。结果就是整个网格显得很混乱,如下图所示:
目前,在中大型视口,第4~7个商品由于高度不等,浮动后没有对齐。
我们的任务就是调整网格系统,让所有网格的视觉效果得到增强。
(1) 创建新文件 less/_product-grid.less ,并在 __main.less 文件中引用。
(2) 我们先调整下图片宽度、字号、内边距和外边距,代码如下:
.product-item {
padding-bottom: 32px;
img {
width:100%;
}
h2 {
font-size: @font-size-large;
line-height: 1.2;
padding: 0 !important;
margin-top:6px;
margin-bottom:2px;
}
p {
font-size: @font-size-small;
line-height:1.3;
color:@gray;
}
}
(3) 现在该来解决布局问题了。解决问题的关键是找到最高的商品。假设我们有一个指南,其中对每个商品使用什么图片和文字介绍都有规划。所有商品的小图都是标准大小,文字说明也不会比当前我们示例页面中的多。这样的话,我们就可以给所有商品都设置一个固定的高度,或者使用 em 或 ex 等更灵活的单位。在这个示例中,我们就使用360px 的固定值,并把超出的部分隐藏起来。
.product-item {
height: 360px;
overflow: hidden;
...
}
这样布局问题就解决了,现在的显示效果如下;
(4) 在此之后,我们就可以放心地使用 Bootstrap 的响应式分栏类,去调整不同视口的布局效果了。具体来说,我们希望当视口小和超小的时候,每行只显示两个商品;而当视口中等或较大时,每行显示三个商品。为实现这个效果,我们要找到并替换每个商品中的类,结果要变成如下所示:
<div class="product-item col-xs-6 col-md-4">
替换成这两个类之后,每个商品在超小和小视口将会是屏幕宽度的一半,而在中大视口中将切换成屏幕宽度的三分之一。
以下是小视口下的情景:
超小视口下因为侧边栏的干扰,还是有显示问题,所以我们接下来就需要调整侧边栏了。
3.侧边栏和筛选选项
在小、中、大视口中,侧边栏目前都位于左侧。
目前侧边栏如下所示:
而在完成设计工作后,我们希望把 Clearance Sale 做成一个超大按钮,把筛选选项排成两栏,而且每个选项前都是复选框而非项目符号,如下所示:
下面先从基本的样式开始,把布局弄好。
3.1 基本布局
我们先来调整字体、颜色、外边距和内边距。在_product-grid.less 中添加规则如下:
.grid-options {
.panel;
.panel-default;
padding-top:12px;
padding-bottom:24px;
> h2 {
margin-top:0;
font-size:1.5 * (@font-size-large);
line-height:1.2;
color:@gray-dark;
}
}
上面代码的用途如下:
□ 给侧边栏应用 Bootstrap 默认的 panel样式和 panel-default 样式 (参见:http://getbootstrap.com/components/#panels);
□ 给侧边栏添加上、下边距;
□ 调整 h2 标题的字号、行高和颜色。
3.2 Clearance Sale 按钮
我们要把Clearance Sale 链接变成一个超大的吸引人的按钮。
按照下面的说明调整标记:
□ 把链接的标题和段落都转换成按钮;
□ 添加自定义的按钮类 btn-feature,这是我们在上一章创建的:
□ 给整个标签添加 Font Awesome 图标,通过使用 Font Awesome 内置的 icon-3x 类,将图标放大三倍。
PS:要了解 Font Awesome 特殊尺寸类的更多信息,可以参考相关文档:http://fontawesome.io/examples/#larger
调整后的标记如下所示:
<a class="btn btn-feature choose-clearance" href="#">
<span class="icon fa fa-tag fa-3x"></span> <h3>Clearance Sale</h3> <p>View clearance items</p> </a>
显示效果如下:
下面再细化,完成下列目标:
(1) 将 Clearance Sale 显示为块级元素,使用 .center-block() 这个 Bootstrap 的混入将其居中;
(2) 强制其宽度为包含栏的92.5%;
(3) 添加上、下内边距;
(4) 覆盖 Bootstrap 按钮的 white-space:nowrap 规则,让文本可以折行(Bootstrap 的white-space 规则是在 less/bootstrap/buttons.less 中定义的,关于这个属性的更多信息,大家可以参考:https://css-tricks.com/almanac/properties/w/whitespace/)
(5) 将按钮设置为相对定位,以便对标签应用绝对定位;
(6) 调整标题和段落的字体、颜色和外边距;
(7) 把标签图标定位到右上角。
以上目标通过下列规则就可以实现:
.choose-clearance {
.center-block();
width: 92.5%;
padding-top: 20px;
padding-bottom: 12px;
white-space: normal;
position: relative;
h3{
font-weight: normal;
color: #fff;
padding-top: 4px;
margin: 6px;
}
p {
margin:6px 20px;
line-height: 1.2;
}
.icon {
position: absolute;
top: 0;
right: 2px;
}
}
显示效果如下:
3.3 选项列表
本节,我们要把几个列表转换成筛选选项。
如果花点时间分析下在线商店 Amazon (https://www.amazon.com/)或者 Zappos (http://www.zappos.com/) 的商品筛选选项,会发现这些选项其实是链接列表,而且每个选项都被调整成了复选框的样子。我们也要把链接做成复选框的样式,用户只要选择就会勾选,另外我们还要调整它们以适应多样化的设备,包括平板电脑和智能手机。
Amazon:
Zappos :
PS:在 Amazon 和 Zappos 等电子商务网站上,筛选项与内容管理系统是关联的,网格中的商品会随着用户选择筛选项而动态变化。 Bootstrap 是一个前端设计框架,不是内容管理系统。因此,我们这个示例做不到动态筛选商品。但我们 这个页面完成后,是完全可以在内容管理系统中使用的。
先从每个列表的 h3 元素开始,我们调整它们的大小、行高、外边距和颜色:
.grid-options {
...
>h3 {
font-size: @font-size-large;
line-height: 1.2;
margin-top: 12px;
color: @gray-dark;
}
}
然后,我们把注意力集中到无序列表上。我们有给每个无序列表上都添加了一个特殊的类,叫 options-list,我们就用它作为选择符,确保只针对这些特殊的列表。
首先去掉项目符号和内边距:
.grid-options {
...
.options-list {
list-style-type: none;
padding-left: 0;
}
}
接下来是链接样式。稍后我们还要给列表项添加样式,因此我们把这些样式包含了嵌套的选择符中。
.options-list {
...
li {
a {
.btn;
.btn-sm;
padding-left: 0;
padding-right: 0;
color: @gray;
&:hover,
&:focus,
&:active,
.active & {
color: @link-color;
} ...
以上规则的作用如下:
□ 我们利用 LESS 通过 .btn 类加入了基本的按钮样式,包括显示 inline-block 链接和额外的内边距:
■ 因为没有添加其他按钮类,所以也没有出现背景颜色;
■ 通过添加基本的按钮样式,可以让用户更方便点击,使用手指或鼠标皆宜。
□ 再通过 .btn-sm 类引入相关样式,以减少内边距,并让字号比标准按钮再小一些。
□ 接着删除无序列表的左和右内边距。
□ 再把链接文本的颜色改为 @gray。
□ 最后,设置悬停、焦点和活动链接的颜色为 @link-color 。
现在的显示结果如下图所示:
PS:有人可能会奇怪为什么作者要在这里借用按钮的 .btn和 .btn-sm 类,而不是直接把这两个类写进标记。当然也可以那么做,但考虑到链接的数量那么多,还是通过CSS来应用样式更便捷。
3.4 为选项链接添加 Font Awesome 图标复选框
我们将在LESS中使用 Font Awesome图标在选项链接做出添加复选框,另外还要加入另一个 Font Awesome 图标,以表示悬停、聚焦和活动状态下勾选的复选框。
通过 LESS 添加图标需要从三个文件中取得 Font Awesome 样式。首先,从 font-awesome 文件夹的 core.less 中获得基本样式。在这个文件中,可以看到以下重要的样式:
.@{fa-css-prefix} {
display: inline-block;
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
font-size: inherit; // can't have font-size inherit on line above, so need to override
text-rendering: auto; // optimizelegibility throws things off #1094
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
以上样式是所有 Font Awesome 图标样式的基础,包括作为字体的 Font Awesome 图标,以此为基础可以进一步加强相应的样式。
对现在的需求来说,我们不需要选择符也不需要花括号,只需要其中的规则。我们要把这些样式应用给选项链接。最重要的,我们要使用 :before 伪元素,因为可以确保结果最佳。
从 core.less 中复制上面的规则(不包括选择符),粘贴到 _product-grid.less 文件中,嵌套如下:
.grid-options { ...
.options-list { ...
li { ...
a { ...
&:before{
display: inline-block;
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} ...
这些规则为我们下一步打下了基础。下一步就可以指定使用哪个 Font Awesome 图标了。浏览这个页面:http://fontawesome.io/icons/ ,就会发现空复选框的图标和类名:
这个图标的 LESS 规则可以在 font-awesome 文件夹的 icons.less 文件里找到。打开该文件,搜索字符串"}-square-o" ,可以看到下面这一行:
.@{fa-css-prefix}-square-o:before { content: @fa-var-square-o; }
对于前面这一行,我们只需要 content: @fa-var-square-o 。把它复制到之前的 &:before 选择符中的规则后面:
&:before{ ...
content: @fa-var-square-o;
}
最后,我们想取得另一些 Font-Awesome 样式,为图标设置固定的宽度,避免图标再切换时出现位移。这些样式可以在 font-awesome 文件夹的 fixed-width.less 文件中找到。复制下面这两行,同样粘贴到 &:before 选择符中:
width: (18em / 14);
text-align: center;
添加上面的样式后,编译它们为CSS并刷新浏览器。可以看到效果如下:
接下来,我们以同样的方式添加选择符和规则,把 Font Awesome 复选框图标的勾选版应用给链接的悬停、焦点和活动状态:
.options-list { ...
li { ...
a { ...
&:hover:before,
&:focus:before,
&:active:before,
.active &:before {
content: @fa-var-check-square-o;
}
保存编辑后刷新浏览器可以看到效果如下:
3.5 使用 LESS 混入在栏中对其选项
前面,我们使用 LESS 实现了以往需要通过添加标记实现的功能。考虑到筛选项的数量很多,这样做效率最高。同样的思路也适用于我们对齐侧边栏中的选项。
当然,如果使用 Bootstrap 的 row 和栏类,通过调整标记也是可以的:
<ul class="options-list options-categories row"> <li class="col-xs-6"><a href="#">Option 1</a></li> <li class="col-xs-6"><a href="#">Option 2</a></li> ...
显示效果如下:
但有了 Bootstrap 的混入,我们用几行 LESS 就可以实现同样的效果。
(1) 首先 .options-list 选择符应用 .make-row() 混入:
.options-list {
.make-row();
...
这个混入加入的样式与我们在标记中添加 row 类加入的样式一样。但这里只需要一行代码。
(2) 然后使用 .make-xs-col() 混入给列表项应用分栏规则:
.options-list { ...
li {
.make-xs-column(6);
...
这样就跟我们给相关的li 标签添加 col-xs-6 类的效果一样了。
3.6 针对平板和手机调整选项列表布局
我们要限制选项面板的宽度,让它在平板电脑中不至于太宽。
目前来看,Clearance Sale 按钮有点太宽。在 480px~768px 下,选项列表相隔太远了。
相应的截图如下:
其实只要给选项版设置一个最大宽度就行了:
.grid-options {
...
max-width: 480px;
...
下面我们再调整选项列表,让它们在小视口中显示为三栏。使用LESS ,可以在适当的选择符中嵌套一个媒体查询,然后在其中添加一个用于调整的 .make-xs-column(4) 混入:
li {
.make-xs-column(6);
@media screen and (max-width:@screen-xs-max){
.make-xs-column(4);
}
...
现在保存,编译,刷新浏览器,查看效果。但是我们可能会发现侧边栏靠左对齐的,右侧留白太多。而且商品网格的显示有问题每行只显示了一个商品。
很明显,首先我们需要使侧边栏居中,使用 .center-block() 这个Bootstrap 的混入就可以了,代码如下
.grid-options {
...
.center-block();
另外,商品的显示问题,调试发现是上一章中CSS选择器 div[role="main"] [class*="col-"]清除浮动造成的。
所以,我们只需要不清楚浮动就可以了:
.product-item {
...
clear:none !important;
...
现在的效果就可以了:
3.7 在手机上折叠选项面板
现在,筛选项占据了相当对的垂直空间。这在小屏幕上是个问题,会把商品网格推到页面下方很远的地方。
原因就是筛选项不必要地占据了大量空间。商品本身才是最应该首先显示的。我们既要让用户迅速看到商品,也可以在需要时打开筛选项。
为此,我们使用 Bootstrap 的折叠插件。下面几步讲解如何对选项面板使用折叠插件,同时添加一个扩展面板的按钮,并把折叠行为限定在窄视口中。
(1) 打开 html 文档,添加一个div标签,包装 Clearance Sale 按钮和三个选项列表。给这个div 添加一个特殊的类 collapse,以及一个唯一的 ID,以便 JavaScript 插件找到它,同时也添加一个同名的类,代码如下(可以参考文档:http://getbootstrap.com/javascript/#collapse):
<div class="grid-options col-sm-3"> <h2>Narrow your selection</h2> <div id="options-panel" class="options-panel collapse"> ... </div> </div>
(2) 保存文件并刷新浏览器。你会发现 Clearance Sale 按钮和选项列表从眼前消失了。只剩下选项面板上方的 h2 标题了,效果图如下:
现在需要一个切换按钮,在点击时显示筛选项。
(3) 然后我们在这个h2标题中添加一个button按钮以及相应属性如下:
<div class="grid-options col-sm-3"> <h2 class="clearfix">Narrow your selection <button type="button" class="options-panel-toggle btn btn-primary pull-right" data-toggle="collapse" data-target="#options-panel">
<span class="icon fa fa-cog fa-2x"></span> </button> ...
简单解释下上面的标记:
□ 给 h2 添加的 clearfix 类可以确保它包含切换按钮,因为切换按钮是浮动到右边的;
□ 类 btn 和 btn-primary 会给新的按钮添加 Bootstrap 的基本按钮样式,背景颜色为 @brand-primary;
□ 类 pull-right 会把按钮浮动到右侧;
□ 在 button 元素中,放了一个 Font Awesome 齿轮图标,使用 fa-2x 类放大到两倍。
保存并刷新浏览器,可以看到显示效果如下:
(4) 下面要写一些规则,在中大屏幕中隐藏切换按钮并展开选项面板。为此,可以在 _product-grid.less 中添加以下规则:
@media (min-width:@screen-sm-min){
.options-panel{
display:block;
}
.options-panel-toggle {
display:none;
}
}
(5) 这些规则的作用如下:
□ 媒体查询保证只把规则应用到小中大视口;
□ 第一条规则抵消 collapse 类的作用,它默认是隐藏元素;
□ 第二条则隐藏切换按钮。
保存并刷新,应该就能看到想要的效果了。
在超小视口中,选项列表会折叠起来,但切换按钮可见:
在小、中、大视口,切换按钮隐藏,选项列表可见:
这样,我们的这个页面就完工了。
4.小结
这个示例,我们做了以下事情:
□ 利用 Bootstrap 的样式快速实现了面包屑、页面标题和分页导航,并根据需要进行了定制;
□ 调整了 Bootstrap 的网格样式,为商品创建了整齐的布局,关键是所有商品的高度要一致;
□ 为复杂的 Clearance Sale 按钮应用了样式,用到了 @brand-feature 这个红色背景;
□ 利用 btn 类的样式让筛选按钮更容易点击或触摸,通过自定义满足了我们的特殊需求;
□ 使用 Bootstrap 的分栏类,加上响应式调整,对齐了筛选项列表,而且适合多视口;
□ 在自定义样式表中借用 Font Awesome 样式在筛选项旁边添加复选框;
□ 设置了选项面板在窄视口中折叠,在小中大视口中可见。
此例显示效果地址:http://yexiaochao.github.io/show/bootstrap-code-05.html (附《Bootstrap 实战》的PDF文档和源码链接:http://pan.baidu.com/s/1slPDoux)
本例源码下载:bootstrap-code-05.zip