假设我们已经想好了要给自己的作品弄一个在线站点。一如既往,时间紧迫。我们需要快一点,但作品展示效果又必须专业。当然,站点还得是响应式的,能够在各种设备上正常浏览,因为这是我们向目标客户推销时的卖点。这个项目可以利用Bootstrap的很多内置特性,同时也将根据需要对Bootstrap进行一些定制。

1.设计目标

虽然对大屏幕中的展示效果已经胸有成竹,但我们还应该从小设备开始,强迫自己聚焦在关键的要素上面。

这个作品展示站点应该具有下列功能:

□ 带Logo的可折叠的响应式导航条;

□ 重点展示四张作品的图片传送带;

□ 单栏布局中包含三块内容,每块内容中都包含标题、短段落和吸引人点击阅读的大按钮;

□ 页脚包含社交媒体链接。

下面的屏幕截图展示了设计方案:

【Bootstrap】2.作品展示站点-LMLPHP

总体来看,这将是对我们工作的一个完美的展示。图片传送带比较高,可以充分展示我们作品的图片。当然,导航到底下的内容也不难,用户可以先了解每一项的大致情况,然后决定深入阅读那块内容。通过把重要的练级做成大按钮,从视觉上突出了重要的操作,可以起到吸引用户点击的作用,而且就算是手指粗大的用户都可以轻易点触。

为了便于维护,我们只考虑两个主要的断点。在小于768px的小屏幕中使用单栏布局,否则就切换到一个三栏布局:

【Bootstrap】2.作品展示站点-LMLPHP

在这个针对大屏幕的设计效果中,可以发现下列功能:

□ 位于顶部的导航条,而且各导航条都附带图标;

□ 宽屏版的图片传送带,其中的图片拉伸至与浏览器窗口同宽;

□ 三栏布局分别容纳三块文本内容;

□ 页脚在布局中水平居中。

这个设计的配色很简单,只有灰阶以及用于链接和突出显示的金绿色。

明确了设计目标,接下来就可以布置内容了。

2.基本页面搭建

根据前面文章 【Bootstrap】1.初识Bootstrap 的说明,我们可以暂时把项目的基本框架搭建起来。其html文档代码如下:

DOCTYPE html>




<html class="no-js">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>作品展示站点title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link href="favicon.ico" type="image/x-icon" rel="shortcut icon" />
    
    <link rel="stylesheet" href="css/main.css">
    
    <script src="js/vendor/modernizr-2.6.2.min.js">script>
    
    
head>
<body>
    
    <header role="banner">
        <nav role="navigation" class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar">span>
                        <span class="icon-bar">span>
                        <span class="icon-bar">span>
                    button>
                    <a class="navbar-brand" href="index.html">Bootstrappin'a>
                div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li class="active"><a href="index.html">Homea>li>
                        <li><a href="#">Portfolioa>li>
                        <li><a href="#">Teama>li>
                        <li><a href="#">Contacta>li>
                    ul>
                div>
                
            div>
            
        nav>
    header>
    <div role="main">
            <img src="img/okwu.jpg" alt="OKWU.edu Homepage">
            <img src="img/okwu-athletics.jpg" alt="OKWU Athletics Homepage">
            <img src="img/bartlesvillecf.jpg" alt="Bartlesville Community Foundation">
            <img src="img/emancipation.jpg" alt="Emancipation Stories">

            <h2>Welcome!h2>
            <p>Suspendisse et arcu felis, ac gravida turpis. Suspendisse potenti. Ut porta rhoncus ligula, sed fringilla felis feugiat eget. In non purus quis elit iaculis tincidunt. Donec at ultrices est.p>
            <p><a href="#">See our portfolioa>p>

            <h2>Recent Updatesh2>
            <p>Suspendisse et arcu felis, ac gravida turpis. Suspendisse potenti. Ut porta rhoncus ligula, sed fringilla felis feugiat eget. In non purus quis elit iaculis tincidunt. Donec at ultrices est.p>
            <p><a href="#">See what's new!a>p>

            <h2>Our Teamh2>
            <p>Suspendisse et arcu felis, ac gravida turpis. Suspendisse potenti. Ut porta rhoncus ligula, sed fringilla felis feugiat eget. In non purus quis elit iaculis tincidunt. Donec at ultrices est.p>
            <p><a href="#">Meet the team!a>p>
        div>
    <footer role="contentinfo">
        <p><a href="index.html">
            <img src="img/logo.png" width="80" alt="Bootstrappin'">a>p>
        <ul class="social">
            <li><a href="#" title="Twitter Profile">Twittera>li>
            <li><a href="#" title="Facebook Page">Facebooka>li>
            <li><a href="#" title="LinkedIn Profile">LinkedIna>li>
            <li><a href="#" title="Google+ Profile">Google+a>li>
            <li><a href="#" title="GitHub Profile">GitHuba>li>
        ul>
    footer>
    <script src="js/vendor/jquery-1.10.2.min.js">script>
    <script src="js/plugins.js">script>
    <script src="js/main.js">script>
body>
html>
登录后复制

打开页面后,可以看到导航栏后面就是作品图片:

【Bootstrap】2.作品展示站点-LMLPHP

作品图片后面就是文本块和包含一组社交链接的页脚:

【Bootstrap】2.作品展示站点-LMLPHP

倒也简单。还是开始让它变身吧!

我们从添加Bootstrap类着手,这样可以利用Bootstrap默认的CSS样式和JavaScript行为,迅速搭建起来基本的界面元素。

3.搭建传送带

下面先来搭建传送带,传送带会循环展示我们作品的四张特写图片。其标记结构的官方文档地址是:http://getbootstrap.com/javascript/#carousel

可以按照示例中的结构设置其中的元素。以下代码就是传送带的所有标记,包含各个部分,首先是进度指示器:

<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

<ol class="carousel-indicators">
    <li data-target="#carousel-example-generic" data-slide-to="0" class="active">li>
    <li data-target="#carousel-example-generic" data-slide-to="1">li>
    <li data-target="#carousel-example-generic" data-slide-to="2">li>
    <li data-target="#carousel-example-generic" data-slide-to="3">li>
ol>
登录后复制

整个传送带是一个带ID属性的div标签,其 carousel 类用于把Bootstrap 的传送带CSS应用到这个元素,为指示器、传送带项和前一张及后一张控件添加样式。

进度指示器的 data-target 属性必须使用传送带的 ID carousel-example-generic 。有了这个属性,JavaScript 插件才能为活动的传送带项添加 active 类。在此我们预先为第一个指示器添加了active类。然后,类的切换就由JavaScript控制了。它会删除第一个指示器的这个类,再添加到后续指示器,如此循环。

此外,还要注意 data-slide-to 的值从0开始,与JavaScript和其他编程语言一样。记住:从0开始,不是从1开始。

指示器后面,是类为 carousel-inner 的元素。这个元素是所有传送带项(item),也就是所有图片。

carousel-inner 元素内部是传送带项,是一组div标签,每个都带有class="item"。把第一项修改成包含item 和active 两个类,使其一开始就可见。

此时的标记结构如下所示:


<div class="carousel-inner" role="listbox">
<div class="item active">
  <img src="img/okwu.jpg" alt="OKWU.edu Homepage">
div>
<div class="item">
  <img src="img/okwu-athletics.jpg" alt="OKWU Athletics Homepage">
div>
<div class="item">
  <img src="img/bartlesvillecf.jpg" alt="Bartlesville Community Foundation">
div>
<div class="item">
  <img src="img/emancipation.jpg" alt="Emancipation Stories">
div>
div>
登录后复制

传送带项之后,还需要添加传送带控件,用于在传送带左、右两侧显示前一个和后一个按钮。你会发现其中有类对应着 Glyphicon字体图标。在控件后面,我们在用一个结束div标签关闭整个传送带。


<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left">span>
    <span class="sr-only">Previousspan>
a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right">span>
    <span class="sr-only">Nextspan>
a>
div>
登录后复制

PS:每个传送带控件的href属性必须是最外围传送带元素的ID值(这里是 carousel-example-generic )。

添加以上代码之后,保存刷新浏览器。Bootstrap的样式和JavaScript都应该生效,页面中的图片应该变身成为滚动的传送带。现在的显示效果如下:

【Bootstrap】2.作品展示站点-LMLPHP

默认情况下,传送带的幻灯片每5秒切换一次。为了充分展示我们的作品,可以改成8秒。

(1) 打开 js/main.js

(2) 添加以下代码。这里先用jQuery方法检测相应的页面元素是否存在,如果存在则将传送带的间隔初始化为8000毫秒。

$(document).ready(function () {
    $(".carousel").carousel({
        interval:8000
    });
});
登录后复制

(3) 保存并刷新。

相关的选项可以参考Bootstrap 传送带的官方文档:http://getbootstrap.com/javascript/#carousel 。

4.创建响应式分栏

页面中有三个文本,每块都有标题、段落和链接。在大于平板电脑的屏幕上,我们希望内容分为三栏,而在较窄的屏幕上,我们希望内容变成一栏全宽。

这里将拥戴Bootstrap 移动优先的响应式网格,其官方文档地址为:http://getbootstrap.com/css/#grid (其中文文档地址为: http://v3.bootcss.com/css/#grid)。

简单的说,Bootstrap 内置12栏网格系统,其基本的类结构支持 col-12 表示全宽,col-6表示半宽,col-4表示四分之一宽,以此类推。

在Bootstrap3 中,由于创造性地使用了媒体查询,网格体统具有极强的适应力。如前所述,我们希望欢迎消息在比平板小的屏幕中呈现一栏全宽,而在大约768px 时变成三分之一栏宽。巧合的是,Bootstrap 内置的小屏幕断点恰好是768px,也就是 @screen-sm-min 变量的默认值。而大于 768px 的中屏幕断点是992px,对应变量是@screen-md-min。然后,大于1200px断点的算大屏幕。

小断点有一个特殊的栏类命名法:col-sm-。因为我们向在小断点之上使用三栏,所以这里使用 class="col-sm-4"。这样在小断点之下,分块元素会保持全宽,而在小断点之上,则会各站三分之一宽并肩排列。完整的结构如下所示:

        <div class="container">
            <div class="row">
                <div class="col-sm-4">
                    <h2>Welcome!h2>
                    <p>....p>
                    <p><a href="#">See our portfolioa>p>
                div>
                <div class="col-sm-4">
                    <h2>Recent Updatesh2>
                    <p>....p>
                    <p><a href="#">See what's new!a>p>
                div>
                <div class="col-sm-4">
                    <h2>Our Teamh2>
                    <p>...p>
                    <p><a href="#">Meet the team!a>p>
                div>
            div>
        div>
登录后复制

下面稍微解释下 container 和 row 类的作用:

□ container 类用于约束内容的宽度,并使其在页面内居中;

□ row 类用于包装三个栏,并未栏间流出左右外边距;

□ container 类和row 类都设定了清除,因而它们可以包含浮动元素,同时又清除之前的浮动元素。

现在,保存并刷新。可以看到对应的显示效果如下:

【Bootstrap】2.作品展示站点-LMLPHP

这样就利用响应式网格系统完成了响应式分栏,接下来我们要利用Bootstrap的按钮样式,把内容分块中的链接做成突出的效果。

5.把链接变成按钮

把重要的内容链接转换成突出显示的按钮很简单。为此要用到如下几个关键的类。

□ btn 类用于把链接变成按钮的样式;

□ btn-primary 类用于把按钮变成主品牌颜色;

□ pull-right 类用于把链接浮动到右侧,使其占据更大的空间,从而便于发现和点击。

把上述这几个类添加到三个内容块末尾的链接上:

<p><a href="#" class="btn btn-primary pull-right">See our portfolioa>p>
登录后复制

保存并刷新,其显示效果如下:

【Bootstrap】2.作品展示站点-LMLPHP

此处按钮的标记结构的官方文档地址为:http://getbootstrap.com/css/#buttons (中文文档:http://v3.bootcss.com/css/#buttons)。

在基本的标记结构就为的条件下,接下来可以进行微调了。谓词需要用到自定义的CSS,而我们要借此机会体验一下Bootstrap的LESS文件的强大威力。

6.理解LESS

PS:本节基于bootstrap v3.0.2,这个版本在GitHub上的介绍和下载地址为:https://github.com/twbs/bootstrap/releases/tag/v3.0.2

PS:当前的最新版本是: v4.0.0-alpha.4

本节会介绍创建创建、编辑、顶置一些LESS文件,以便为我们的设计生成期望的CSS。

□ LESS 文档:http://lesscss.org/#docs

□ Sitepoint 网站关于 LESS 的完整介绍:https://www.sitepoint.com/a-comprehensive-introduction-to-less/

简而言之,使用LESS预处理器来生成CSS是一件既令人激动又十分轻松的事。

6.1 嵌套规则

嵌套规则极大提高了组合样式的效率。比如,CSS中的选择符可能会多次重复出现:

.navbar-nav {...}
.navbar-nav > li {...}
.navbar-nav > li > a {...}
.navbar-nav > li > a:hover,
.navbar-nav > li > a:focus {...}
登录后复制

其中这些相同的选择符用LESS写会简洁很多,只要使用一个简单的嵌套即可:

.navbar-nav { ...
  > li { ...
   > a { ...
      &:hover,
      &:focus { ... }  
   }
  }
}
登录后复制

编译后,这些规则会生成标准的CSS。但 LESS的嵌套规则更容易写,也更容易维护。

6.2 变量

使用变量可以让我们只设定(或修改)一次,就能自动影响(更新)整个样式表中用到该值的属性。比如,可以像下面这样使用颜色变量:

@off-white: #e5e5e5;
@brand-primary: #890000;
登录后复制

在这些变量的值变化后,可以自动将它们更新到整个站点。这是因为我们在LESS文件中使用了这些变量:

a { color:@brand-primary; }
.navbar {
  background-color:@brand-primary;
  > li > a { color:@off-white;}
}
登录后复制

6.3 混入

混入可以让生成整套规则更方便也容易管理。比如,可以利用它简化为元素应用border-box 属性的任务。在CSS中,要涵盖所有浏览器,需要用到每种浏览器的供应商前缀,为此针对每个元素都要写三行相同的声明,而且还要记住每一种前缀的写法:

.box{
 -webkit-box-sizing:border-box;
    -moz-box-sizing:border-box;
         box-sizing:border-box;
}
登录后复制

在LESS 中,可以只写一个供混入的规则,后面则可以通过 @boxmodel 参数来指定期望的盒模型:

.box-sizing(@boxmodel){
 -webkit-box-sizing:@boxmodel;
    -moz-box-sizing:@boxmodel;
         box-sizing:@boxmodel;
}
登录后复制

然后就可以在需要的地方使用这个混入了:

.box { 
  .box-sizing(border-box); 
}
.another-element {
  .box-sizing(border-box); 
}
登录后复制

编译后,还会为每个元素生成三行CSS 。

6.4 运算式

通过运算式可以基于变量实现数学计算。比如,可以将一种颜色作为基准,对其进行加亮和减暗处理:

a:hover { darken(@link-color, 15%); }
登录后复制

还可以计算内边距的值,以适应导航条的高度。比如,以下Bootstrap 的 navbar.less 文件中的代码,就将导航项的内边距值设为导航条高度减去行高之后剩余的高度值。然后,把这个值一分为二,平均应用为顶部和底部内边距:

.navbar > li > a {
  padding-top:((@navbar-height - @line-height-computed) / 2);
  padding-bottom:((@navbar-height - @line-height-computed) / 2);
}
登录后复制

6.5 导入文件

LESS 编译器支持导入并组合多个文件,最终生成一个统一的CSS文件。我们可以指定导入的次序,按照需要的层叠关系精确组织结果样式表。

Bootstrap 的导入文件 bootstrap.less 一开始导入了基本的变量和混入。然后,又导入了(代替CSS 重置样式表的) normalize.css 的LESS 版,之后是针对打印媒体的基本样式(print.css)、基本的全局样式(scaffolding.less)和排版样式(type.less)。结果这个bootstrap.less 文件的开头几行就是这样的:

// Core variables and mixins
@import "variables.less";
@import "mixins.less";

// Reset
@import "normalize.less";
@import "print.less";

// Core CSS
@import "scaffolding.less";
@import "type.less";
登录后复制

而最终得到的是一个统一的CSS文件,其中的样式经过从一般到特殊的层叠,正是我们想要的。

6.5 模块化

把多个文件导入并输出成一个文件,可以让我们更方便地组织样式,对它们进行分组,并在不同的文件中对它们进行维护。这也是Bootstrap会带有那么多LESS文件的原因,导航条有一个、按钮有一个、警告框有一个、传送带有一个... ,而所有这些都会被导入到 bootstrap.less 文件。

正因为上述原因,LESS及其他 CSS预编译器才会变得如此流行。

7.根据需要定制Bootstrap的LESS文件

在定制Bootstrap的LESS文件期间,我们会发挥很大的主观能动性,具体如下:

□ 组织less文件夹,以便灵活、自由地实现我们需要,同时也让将来的维护者更方便;

□ 自定义Bootstrap提供的几个LESS文件;

□ 创建几个新的LESS文件;

□ 为站点整合一套较大的字体图标,数量翻倍,并将图标运用于社交媒体链接。

换句话说,我们不光要学习Bootstrap的约定,还要发挥自己的创造力。

为了方便起见,我们把原less文件夹下的less文件,即Bootstrap 的LESS文件移到其文件夹 bootstrap 下。

【Bootstrap】2.作品展示站点-LMLPHP

然后再less文件夹下新建 __main.less 文件,此文件是bootstrap.less 的重命名版,它导入了其他所有文件,之后就是通过编译它基于所有导入的LESS文件生成一个统一的样式表。不过记得修改其导入文件的路径:

// Core variables and mixins
@import "bootstrap/variables.less";
@import "bootstrap/mixins.less";
...
登录后复制

为什么要多此一举呢?因为我们很快就要创建自己的LESS文件了。这样一来,我们创建的文件就不会与Bootstrap内置的文件混淆,便于调整。

7.1 自定义变量

按照惯例,我们先复制一份Bootstrap的变量文件,然后对其进行修改。

(1) 找到less/bootstrap 文件夹中的 variables.less 文件,在编辑器中打开它。

(2) 浏览一下这个文件,会发现各种变量,有定义基本颜色值的,有定义页面背景颜色的,有定义基本颜色值,有定义页面背景颜色的,有定义字体的,还有定义导航条和背景高度的,等等。看起来很好,但改动一下更妙。改动之前,我们先存一个副本,以防将来改坏,好恢复。

(3) 副本另存为 bootstrap 文件夹外部,在 less 文件夹的 __main.less 文件旁边。为表示它是自定义文件,命名为 _variables.less 。

下面我们就来自定义颜色。

(1) 在新 _variables.less 文件的最开始,可以看到 Bootstrap 为灰色和品牌色定义的默认变量及其值。这里的灰色值是基于黑色按比例计算的,使用了 LESS 的 lighten 函数:

...
@gray-darker:            lighten(@gray-base, 13.5%); // #222
...
登录后复制

(2) 我们知道自己想要的值,因此直接替换即可(当然也可以尝试使用计算的值)。然后再增加两个变量,以涵盖我们需要的完整灰度空间。

(3) 代码如下:

@gray-darker:          #222;
@gray-dark:            #454545;
@gray:                 #777;
@gray-light:           #aeaeae;
@gray-lighter:         #ccc;
@gray-lightest:        #ededed;
@off-white:            #fafafa;
登录后复制

接下来再修改品牌颜色中的@brand-primary 变量,将其改为金黄色:

@brand-primary:        #c1ba62;
登录后复制

要看结果,需要导入这些新变量并重新编译生成CSS。

7.2 导入新变量

修改__main.less文件,把原来的 "bootstrap/variables.less" 替换成 "_variables.less"。然后选中 __main.less 进行编译,将输出路径设置为 css/main.css 。编译后,刷新即可看到显示效果如下:

【Bootstrap】2.作品展示站点-LMLPHP

可以看到链接和类为 btn-primary 的按钮颜色都会发生变换,因为它们使用的都是变量 @brand-primary 的颜色。

7.3 编辑导航条变量

下面,我们来编辑设定导航条高度、颜色和悬停效果的变量。

(1) 在 _variables.less 中,搜索到下列变量,并修改为下列值。这样一来,就可以增加导航条的高度、把品牌色应用给链接,同时利用其他相关的颜色变量。

@navbar-height:                        64px;
@navbar-margin-bottom:                 0;
...
@navbar-default-color:                 @gray;
@navbar-default-bg:                    #fff;
@navbar-default-border:               @gray-light;
...
// Navbar links
@navbar-default-link-color:               @navbar-default-color;
@navbar-default-link-hover-color:         @link-hover-color;
@navbar-default-link-hover-bg:            @off-white;
@navbar-default-link-active-color:        @link-hover-color;
@navbar-default-link-active-bg:           @gray-lightest;
@navbar-default-link-disabled-color:      @gray-lighter;
@navbar-default-link-disabled-bg:         transparent;
...
登录后复制

(2) 保存修改、编译并刷新。其修改前后的显示效果如下:

【Bootstrap】2.作品展示站点-LMLPHP

可以看到有关导航条的新特性:

□ 高度增加了14px;

□ 背景变成了白色;

□ 底部边框稍微变暗了一些;

□ 导航项的背景在悬停时稍暗了一点;

□ 导航项的背景在活动时稍暗一些;

□ 链接文本的颜色在悬停时和活动时变成了品牌色。

接下来,我们把Logo放置到位。

8.添加 Logo 图片

在 img 文件夹里找到 logo.png 文件。你会发现这个图片非常大,有900px 宽。在我们最终的设计中,这个Logo只有120px宽。因为多出来的像素将被压缩到较小的空间内,所以这也是让图片在所有设备(包括视网膜屏设备)中保持清晰的一种简便方法。与此同时,这个图片的尺寸也针对Web进行了优化,只有19 KB。

下面就把它放置到位并限制其宽度。

(1) 在html文档中找到导航条标记中的这一行代码:

<a class="navbar-brand" href="index.html">Bootstrappin'a>
登录后复制

(2) 把其文本 Bootstrap' 替换成 img 标签,并添加 alt 和 width 属性。其修改后的代码为:

<a class="navbar-brand" href="index.html">
  <img src="img/logo.png" alt="Bootstrap'" width="120" />
a>
登录后复制

(3) 保持后并刷新浏览器,可以看到Logo已经出现在了相应的位置上。

【Bootstrap】2.作品展示站点-LMLPHP

9.调整导航项内边距

现在,我们来调整一下导航项,以便文本与Logo位于同一基线之上。

(1) 在 less 文件夹下,新建文件 _navbar.less,并把其Bootstrap的 navbar.less 文件内容拷贝进去。

(2) 在 _navbar.less 中,找到选择符 .navbar-nav,这是导航项的父元素 ul。在相应的规则里,可以看到嵌套的媒体查询。(关于媒体查询,可以参考LESS文档:http://lesscss.org/)。

(3) 相关的行如下所示:

  // Uncollapse the nav
  @media (min-width: @grid-float-breakpoint) {
    float: left;
    margin: 0;

    > li {
      float: left;
      > a {
        padding-top:    @navbar-padding-vertical;
        padding-bottom: @navbar-padding-vertical;
      }
    }
  }
登录后复制

这里的变量 @grid-float-breakpoint 指定了一个临界宽度,大于这个宽度,导航条就会扩展到与屏幕同宽;小于这个宽度,导航条就会折叠起来变成移动应用风格的响应式导航。(这个变量是在 _variables.less 中定义的)。

(4) 现在,padding-top 和 padding-bottom 值都是动态计算的,以确保导航中的文本垂直居中。而我们想增加上内边距,减少下内边距。与此同时,我们还要扩大导航项的间隔,再把字体增大一些。把原来的代码使用单行注释,把需要的规则写在下面:

> a {
   //padding-top:@navbar-padding-vertical;
   //padding-bottom: @navbar-padding-vertical;
   padding:30px 30px 14px;
   font-size:18px;
}
登录后复制

(5) 保存、编译并刷新浏览器,可以看到显示效果如下:

09-03 21:11