Bootstrap 实践指南(三)
五、主题参考:第二部分
在第四章“主题参考:第一部分”中,你已经了解了一些最重要的 Twitter Bootstrap 组件,并且你已经开始为它们创建一个参考页面。在本章的第二部分中,您将在同一个参考项目中继续学习更多的组件。
特别是,我承诺向大家展示的其余组件是
-
选项卡,用于对信息进行分组
-
警报,用于显示突出的消息
-
进度条,用于直观地向用户显示一个正在进行的工作已经完成的百分比
-
卡片,美丽的矩形区域,内容丰富,能吸引观众的注意力
-
Carousel,一个像图像或其他丰富内容幻灯片一样工作的组件
最后,您将被要求创建一个页面,该页面要求您使用前面的大部分组件(图 5-1 )。
图 5-1
包含各种元素的 Twitter 引导示例页面
学习目标
-
了解如何创建选项卡。
-
了解如何创建通知。
-
了解如何创建进度条。
-
了解如何制作卡片。
-
了解如何创建旋转木马。
介绍
您将继续您在前一章中开始的 Twitter Bootstrap 主题参考项目。让我们开始添加更多的组件。
制表符
有时,您希望使用选项卡来组织页面上的信息。选项卡很好,因为它们将部分信息组合在一个标题下,并且不会同时显示所有信息。用户通过点击相应的标签标题来选择要查看/阅读的信息组。
例如,参见图 5-2 中的一些选项卡。
图 5-2
选项卡示例
显示的信息根据所单击的选项卡标题而变化。
让我们看看如何实现前面的选项卡示例。
首先,您需要理解标签功能的 HTML 实现有两个部分:
-
标签标题
-
与实际信息不同的内容
标签标题
选项卡标题是一个未排序的列表ul,带有类别nav nav-tabs。列表中的每个元素(li)对应于一个选项卡标题,并且它必须具有类nav-item。每个li的内容是具有类nav-link的锚和具有值tab的数据属性data-toggle。同样,每个锚都有一个指向相应信息容器的href值。当这个锚被点击时,那个信息容器将被显示给用户。注意,对应于应该显示给用户的信息容器的li也需要有类active。
下面是上一个例子中标签头的 HTML 片段(清单 5-1 )。
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="#dashboard" data-toggle="tab">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#payments" data-toggle="tab">Payments</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#invoices" data-toggle="tab">Invoices</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#settings" data-toggle="tab">Settings</a>
</li>
</ul>
Listing 5-1The ul HTML Fragment for the Tabs Example
让我们使用前面的片段来更改您的主 HTML 页面。把它放在容器的底部。在这个ul列表之前,像添加其他标题一样添加标签的标题(列表 5-2 )。
<h1>Tabs</h1>
<hr class="my-4">
Listing 5-2Tabs Header
如果保存页面并将其加载到浏览器中,选项卡部分将如图 5-3 所示。
图 5-3
内容为空的选项卡
这是很好的一步。你可以看到标签是如何被很好地放置在页面上的。您甚至可以单击标题,以查看活动选项卡如何根据您单击的选项卡而变化。
现在缺少的是应该附在每个标签上的信息。
标签信息
您将选项卡信息放在带有类tab-content的div中。在其中,我们为每个信息组/选项卡标题创建一个div。这个div需要有一个tab-pane类。此外,它需要有正确的id,每个选项卡信息面板不同,并对应于相应选项卡的href值。
让我们将下面这段 HTML 代码(清单 5-3 )添加到主内容容器的末尾,在我们为选项卡标题创建的未排序列表之后。
<div class="tab-content">
<div id="dashboard" class="tab-pane active">
<p>
<strong>Dashboard:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="payments" class="tab-pane">
<p>
<strong>Payments:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="invoices" class="tab-pane">
<p>
<strong>Invoices:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="settings" class="tab-pane">
<p>
<strong>Settings:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
Listing 5-3HTML Fragment for Tab Content
正如您在前面的代码中看到的
-
您有一个包含所有其他 div 的
div。 -
这个父级
div具有类tab-content。 -
每个
div的id值等于相应选项卡标题锚点的href。 -
每个
div都有一个类tab-pane。 -
第一个
div也有类active,因为这是为第一个选项卡标题显示的第一个信息框,最初也是active。
如果保存前面的信息并重新加载页面,您将看到以下内容(图 5-4 )。
图 5-4
带内容的选项卡
如您所见,选项卡信息清楚地显示在选项卡标题下方。此外,如果您尝试单击不同的选项卡标题,您将看到以下信息如何相应地变化。
但是有一个问题是内容太靠近标签头了(图 5-5 )。
图 5-5
标签内容太靠近标签标题的问题
为了解决这个问题,在包含标题的ul上需要一些底部空白。您可以通过向ul元素添加实用程序类mb-3来实现这一点。
现在,如果您在浏览器上加载页面,您将看到以下内容(图 5-6 )。
图 5-6
选项卡内容上方现在有一些空闲空间
Note
Twitter Bootstrap 鼓励作者让他们的内容与辅助技术兼容,比如屏幕阅读器。这意味着,除了使用样式类之外,您可能还必须添加一些专门为此目的设计的额外 HTML 属性。例如,带有选项卡列表的ul元素的 role HTML 属性需要有值tablist。如果你想了解如何创建可访问的富互联网应用程序,你必须阅读并应用这里给出的实践: WAI-ARIA 创作实践。
检查站
你在这一页做了很多工作。在继续之前,让我们确保它包含清单 5-4 中的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Custom CSS -->
<link rel="stylesheet" href="stylesheets/main.css" type="text/css">
<title>Twitter Bootstrap Reference Page</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="#">Bootstrap Ref. Page</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#about">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#contact">Contact</a>
</li>
<!-- Drop down Menu -->
<li class="nav-item dropdown">
<a href="#"
class="nav-link dropdown-toggle"
data-toggle="dropdown">
Dropdown
</a>
<div class="dropdown-menu">
<a href="#" class="dropdown-item">Action</a>
<a href="#" class="dropdown-item">Another action</a>
<a href="#" class="dropdown-item">Something else here</a>
<div class="dropdown-divider"></div>
<div class="dropdown-header">Nav header</div>
<a href="#" class="dropdown-item">Separated link</a>
<a href="#" class="dropdown-item">One more separated link</a>
</div>
</li>
</ul>
</div>
</div>
</nav>
<!-- main content container -->
<div class="container">
<div class="jumbotron">
<p class="lead">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<h1>Buttons</h1>
<hr class="my-4">
<h2>Small Sizes</h2>
<p>
<button type="button" class="btn btn-sm btn-primary">btn btn-sm btn-primary</button>
<button type="button" class="btn btn-sm btn-secondary">btn btn-sm btn-secondary</button>
<button type="button" class="btn btn-sm btn-success">btn btn-sm btn-success</button>
<button type="button" class="btn btn-sm btn-danger">btn btn-sm btn-danger</button>
<button type="button" class="btn btn-sm btn-warning">btn btn-sm btn-warning</button>
<button type="button" class="btn btn-sm btn-info">btn btn-sm btn-info</button>
<button type="button" class="btn btn-sm btn-light">btn btn-sm btn-light</button>
<button type="button" class="btn btn-sm btn-dark">btn btn-sm btn-dark</button>
<button type="button" class="btn btn-sm btn-link">btn btn-sm btn-link</button>
</p>
<h2>Normal Sizes</h2>
<p>
<button type="button" class="btn btn-primary">btn btn-primary</button>
<button type="button" class="btn btn-secondary">btn btn-secondary</button>
<button type="button" class="btn btn-success">btn btn-success</button>
<button type="button" class="btn btn-danger">btn btn-danger</button>
<button type="button" class="btn btn-warning">btn btn-warning</button>
<button type="button" class="btn btn-info">btn btn-info</button>
<button type="button" class="btn btn-light">btn btn-light</button>
<button type="button" class="btn btn-dark">btn btn-dark</button>
<button type="button" class="btn btn-link">btn btn-link</button>
</p>
<h2>Large Sizes</h2>
<p>
<button type="button" class="btn btn-lg btn-primary">btn btn-lg btn-primary</button>
<button type="button" class="btn btn-lg btn-secondary">btn btn-lg btn-secondary</button>
<button type="button" class="btn btn-lg btn-success">btn btn-lg btn-success</button>
<button type="button" class="btn btn-lg btn-danger">btn btn-lg btn-danger</button>
<button type="button" class="btn btn-lg btn-warning">btn btn-lg btn-warning</button>
<button type="button" class="btn btn-lg btn-info">btn btn-lg btn-info</button>
<button type="button" class="btn btn-lg btn-light">btn btn-lg btn-light</button>
<button type="button" class="btn btn-lg btn-dark">btn btn-lg btn-dark</button>
<button type="button" class="btn btn-lg btn-link">btn btn-lg btn-link</button>
</p>
<h2>Block Sizes</h2>
<p>
<button type="button" class="btn btn-block btn-primary">btn btn-block btn-primary</button>
<button type="button" class="btn btn-block btn-secondary">btn btn-block btn-secondary</button>
<button type="button" class="btn btn-block btn-success">btn btn-block btn-success</button>
<button type="button" class="btn btn-block btn-danger">btn btn-block btn-danger</button>
<button type="button" class="btn btn-block btn-warning">btn btn-block btn-warning</button>
<button type="button" class="btn btn-block btn-info">btn btn-block btn-info</button>
<button type="button" class="btn btn-block btn-light">btn btn-block btn-light</button>
<button type="button" class="btn btn-block btn-dark">btn btn-block btn-dark</button>
<button type="button" class="btn btn-block btn-link">btn btn-block btn-link</button>
</p>
<h2>Outline buttons (Normal Sizes)</h2>
<p>
<button type="button" class="btn btn-outline-primary">btn btn-outline-primary</button>
<button type="button" class="btn btn-outline-secondary">btn btn-outline-secondary</button>
<button type="button" class="btn btn-outline-success">btn btn-outline-success</button>
<button type="button" class="btn btn-outline-danger">btn btn-outline-danger</button>
<button type="button" class="btn btn-outline-warning">btn btn-outline-warning</button>
<button type="button" class="btn btn-outline-info">btn btn-outline-info</button>
<button type="button" class="btn btn-outline-light">btn btn-outline-light</button>
<button type="button" class="btn btn-outline-dark">btn btn-outline-dark</button>
<button type="button" class="btn btn-outline-link">btn btn-outline-link</button>
</p>
<h1>Tables</h1>
<hr class="my-4">
<h2>Shopping List</h2>
<table class="table">
<tr><th colspan="2">Shopping List</th></tr>
<tr><th>Item</th><th>Qt</th></tr>
<tr><td>Cheese</td><td>1 kgr</td></tr>
<tr><td>Rice</td><td>1.5 kgr</td></tr>
<tr><td>Coffee</td><td>0.5 kgr</td></tr>
<tr><td>Milk</td><td>1 ltr</td></tr>
<tr><td>Wine</td><td>1 btl</td></tr>
</table>
<h2>Travel Plan</h2>
<table class="table table-bordered table-striped table-sm">
<tr><th colspan="2">Travel Plan</th></tr>
<tr class="table-active"><th>(active) Action</th><th>Due</th></tr>
<tr class="table-success"><td>(success) Book Ticket</td><td>Feb 20th</td></tr>
<tr class="table-info"><td>(info) Book Hotel</td><td>March 26th</td></tr>
<tr class="table-warning"><td>(warning) Buy Suitcase</td><td>April 20th</td></tr>
<tr class="table-danger"><td>(danger) Get Passport</td><td>April 30th</td></tr>
</table>
<h1>Labels & Badges</h1>
<hr class="my-4">
<h4>
<span class="badge badge-primary">€20.00 - Primary</span>
<span class="badge badge-secondary">€20.00 - Secondary</span>
<span class="badge badge-success">€20.00 - Success</span>
<span class="badge badge-danger">€20.00 - Danger</span>
<span class="badge badge-warning">€20.00 - Warning</span>
<span class="badge badge-info">€20.00 - Info</span>
<span class="badge badge-light">€20.00 - Light</span>
<span class="badge badge-dark">€20.00 - Dark</span>
</h4>
<button class="btn btn-light">Inbox <span class="badge badge-primary badge-pill">1</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-secondary badge-pill">2</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-success badge-pill">3</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-danger badge-pill">4</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-warning badge-pill">5</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-info badge-pill">6</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-light badge-pill">7</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-dark badge-pill">8</span></button>
<h1>Tabs</h1>
<hr class="my-4">
<ul class="nav nav-tabs mb-4">
<li class="nav-item"><a class="nav-link active" href="#dashboard" data-toggle="tab">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="#payments" data-toggle="tab">Payments</a></li>
<li class="nav-item"><a class="nav-link" href="#invoices" data-toggle="tab">Invoices</a></li>
<li class="nav-item"><a class="nav-link" href="#settings" data-toggle="tab">Settings</a></li>
</ul>
<div class="tab-content">
<div id="dashboard" class="tab-pane active">
<p>
<strong>Dashboard:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="payments" class="tab-pane">
<p>
<strong>Payments:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="invoices" class="tab-pane">
<p>
<strong>Invoices:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="settings" class="tab-pane">
<p>
<strong>Settings:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
</div>
<!-- end of main content container -->
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
Listing 5-4Twitter Bootstrap Reference Page Checkpoint
警报
有时,您希望显示一条消息来吸引用户的注意。这些被称为警报。下面是一个例子(图 5-7 )。
图 5-7
警报示例
这些消息通常显示在页面的顶部,但不一定只显示在那里。
Twitter Bootstrap 给出了应该在 block 元素(如div)上使用的类alert,以便将它变成一个警告块。除此之外,您还需要指定一个为警告着色的类,以便更好地向用户传达消息。因此,对于表示警告的消息,可以使用alert-warning类和alert类。
与警报相关的颜色类别有
-
alert-primary -
alert-secondary -
alert-success -
alert-danger -
alert-warning -
alert-info -
alert-light -
alert-dark
让我们看看这些警报的实际效果。将下面的 HTML 片段添加到主内容容器的末尾之前(清单 5-5 )。
<h1>Alerts</h1>
<hr class="my-4">
<div class="alert alert-primary">
A simple primary alert.
</div>
<div class="alert alert-secondary">
A simple secondary alert.
</div>
<div class="alert alert-success">
A simple success alert.
</div>
<div class="alert alert-danger">
A simple danger alert.
</div>
<div class="alert alert-warning">
A simple warning alert.
</div>
<div class="alert alert-info">
A simple info alert.
</div>
<div class="alert alert-light">
A simple light alert.
</div>
<div class="alert alert-dark">
A simple dark alert.
</div>
Listing 5-5HTML Fragment for Alerts Demo
如果您保存前面的代码并在浏览器上重新加载您的页面,您将在页面的 Alerts 部分看到以下内容(图 5-8 )。
图 5-8
警报演示
在您的警报中,您可以有任何有效的 HTML 内容。例如,您可以有一个到另一个页面的链接。让我们添加下面的 HTML 片段(清单 5-6 )。
<div class="alert alert-info">
<strong>London</strong> Read more about London from <a href="https://en.wikipedia.org/wiki/London">Wikipedia London Link</a>.
</div>
Listing 5-6Add an Alert with HTML Inside
如果您重新加载您的 HTML 页面,新的警告将显示如下(图 5-9 )。
图 5-9
内部带有超链接的警报
这里有一个小的样式问题,与警报内部链接的颜色有关。就是不好看。Bootstrap 建议您在锚a上使用类alert-link。这将根据警报的背景提供匹配的颜色。让我们像清单 5-7 那样添加它。
<div class="alert alert-info">
<strong>London</strong> Read more about London from <a class="alert-link" href="https://en.wikipedia.org/wiki/London">Wikipedia London Link</a>.
</div>
Listing 5-7Use the alert-link Class
如果您保存 HTML 内容并在浏览器上重新加载页面,您将会看到显示超链接的警告,如图 5-10 所示。
图 5-10
与alert-link的造型链接
进度条
进度条指示给定任务已经完成了多少,还有多少工作要做。例如,参见图 5-11 。
图 5-11
进度条示例
正如你在图 5-11 中看到的,进度条有一个颜色和一个文本指示,表明多少流程已经完成,还有多少流程有待完成。
Twitter Bootstrap 有两个与这个工具相关的类,progress和progress-bar。让我们通过将下面的 HTML 内容附加到主内容容器的末尾来看看应该如何使用它们(清单 5-8 )。
<h1>Progress Bars</h1>
<hr class="my-4">
<div class="progress">
<div class="progress-bar" style="width: 60%;">60% Complete</div>
</div>
Listing 5-8HTML Fragment to Add a Progress Bar
从前面的片段中可以看出,进度条非常容易构建。一个div有类progress;,另一个div,在第一个里面,有类progress-bar。孩子div显示的文本给出了当前进度的文本信息。这段文字是不必要的。它可能是空的。这里重要的部分是您正确地设置了子节点div的width属性的值,这样它就可以指示实际的进度。一个好的方法是在这里使用百分比,因为百分比会使子宽度成为父宽度的百分比。父类div上的progress类确保父类div占据页面的所有可用宽度,而子类div上的style="width: 60%"确保子类div恰好占据父类div的60%,因此这两个div元素合二为一,给出了进度条的视觉效果。
如果保存 HTML 页面并在浏览器上重新加载,您将看到以下内容(图 5-12 )。
图 5-12
标准进度条
进度条高度
如果你觉得这个条太短,那么你可以调整父级div的高度,这个父级有一个类progress。让我们添加样式属性如下(清单 5-9 )。
<div class="progress" style="height: 1.8rem;">
<div class="progress-bar" style="width: 60%;">60% Complete</div>
</div>
Listing 5-9Adjust the Height of the Progress Bar
如果您保存前面的内容并在浏览器上重新加载页面,您将看到以下内容(图 5-13 )。
图 5-13
调整进度条的高度
进度条颜色
除了你在图 5-13 中看到的普通进度条之外,你可以使用引导背景颜色工具类来改变进度条的颜色。这些类别是
-
bg-primary -
bg-secondary -
bg-success -
bg-danger -
bg-warning -
bg-info -
bg-light -
bg-dark
您需要在内部的div上设置这个类,与progress-bar类并排。让我们将 HTML 页面中的进度条演示代码修改如下(清单 5-10 )。
<h1>Progress Bars</h1>
<hr class="my-4">
<div class="progress mb-1 h-4">
<div class="progress-bar bg-primary" style="width: 60%;">60% Complete - primary</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-secondary" style="width: 60%;">60% Complete - secondary</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-success" style="width: 60%;">60% Complete - success</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-danger" style="width: 60%;">60% Complete - danger</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-warning" style="width: 60%;">60% Complete - warning</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-info" style="width: 60%;">60% Complete - info</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-light" style="width: 60%;">60% Complete - light</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-dark" style="width: 60%;">60% Complete - dark</div>
</div>
Listing 5-10Progress Bar Demo Code Fragment
同样,确保你的stylesheets/main.css文件有如下的类定义(清单 5-11 )。
.h-4 {
height: 1.5rem;
}
Listing 5-11Class h-4 Which Is Used in Listing 5-10
如果保存 HTML 页面并在浏览器上重新加载,您将看到以下内容(图 5-14 )。
图 5-14
各种颜色的进度条
多色进度条
最后,你可以用进度条做另一个小把戏。你可以在同一个进度条上使用不同的颜色。可以创建如下效果(图 5-15 )。
图 5-15
多色进度条
这很容易通过在progress-bar类中包含多个子div来实现。为了看到这一点,在主内容容器的末尾添加以下 HTML 片段(清单 5-12 )。
<div class="progress mb-1 h-4">
<div class="progress-bar bg-primary" style="width: 30%;">30% primary</div>
<div class="progress-bar bg-success" style="width: 50%;">50% success</div>
<div class="progress-bar bg-warning" style="width: 10%;">10% warning</div>
</div>
Listing 5-12Multicolored Progress Bar HTML Fragment
正如您在前面的代码中看到的,所有三种不同的颜色divs都在父div中。Twitter Bootstrap 足够聪明,可以在正确的位置画出每一个进度条,给定进度条的颜色,用正确的颜色画出它们。
信用卡
卡片是一个容器,它有一些特定的结构来创建非常吸引人的内容,有页眉和页脚。在图 5-16 中,你可以看到一张卡的例子。
图 5-16
卡片示例
卡片通常有图像、标题和正文。但是它也可以包含页眉和页脚。
三卡布局
让我们尝试在您的 Twitter 引导参考页面中创建以下内容(图 5-17 )。
图 5-17
Twitter 引导参考页面中的卡片
-
你要加三张牌。
-
您将选择的布局是响应式的:
-
对于高达 767px 的显示器,每行将显示一张卡片。
-
对于高达 991 像素的显示器,每行将显示两张卡片。
-
对于宽度> = 992 像素的显示器,它将在同一行显示三张卡片。
-
清单 5-13 包含了你必须添加到页面主容器底部的 HTML 代码。
<h1>Cards</h1>
<hr class="my-4">
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3">
<div class="col">
<div class="card">
<h5 class="card-header">Voted #1</h5>
<img src="https://live.staticflickr.com/3869/14437071224_43fb23705b_h.jpg" class="card-img-top" alt="lion sitting and looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Lions</h5>
<h6 class="card-subtitle">Lions Are Amazing</h6>
<p class="card-text">
The lion (Panthera leo) is a large mammal of the Felidae (cat) family. Some large males weigh over 250 kg (550 lb).
Today, wild lions live in sub-Saharan Africa and in Asia. Lions are adapted for life in grasslands and mixed areas
with trees and grass. The relatively small females are fast runners over short distances, and coordinate their hunting of herd animals.
</p>
<a href="https://simple.wikipedia.org/wiki/Lion" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
<div class="col">
<div class="card">
<h5 class="card-header">Voted #2</h5>
<img src="http://www.felineworlds.com/wp-content/uploads/Cheetah_Looking_Around_600.jpg" class="card-img-top" alt="cheetah looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Cheetahs</h5>
<h6 class="card-subtitle">Cheetahs Are Really Fast</h6>
<p class="card-text">
The cheetah (Acinonyx jubatus; /ˈtʃiːtə/) is a large cat of the subfamily Felinae that occurs in North, Southern and East Africa, and a few localities in Iran.
It inhabits a variety of mostly arid habitats like dry forests, scrub forests, and savannahs. The species is IUCN Red Listed as Vulnerable, as it suffered a
substantial decline in its historic range in the 20th century...
</p>
<a href="https://en.wikipedia.org/wiki/Cheetah" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
<div class="col">
<div class="card">
<h5 class="card-header">Voted #3</h5>
<img src="https://cdn.thinglink.me/api/image/601481335449583616/1240/10/scaletowidth" class="card-img-top" alt="panther looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Black Panthers</h5>
<h6 class="card-subtitle">Black Panthers Are Really Scary</h6>
<p class="card-text">
A black panther is the melanistic colour variant of any Panthera, particularly of the leopard (P. pardus) in Asia and Africa, and the jaguar (P. onca) in the Americas.
</p>
<a href="https://en.wikipedia.org/wiki/Black_panther" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
</div>
Listing 5-13Three Cards
布局
布局很简单。这是通过这个div实现的:
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3">
row-cols-*是为了在期望的断点上布置一列、两列或三列所需要的。
然后每张牌都被包含在一个col div 中:
<div class="col">
所有这些都是必需的,以便您可以实现所需的响应性布局。
每张卡片的 HTML
每张卡片都有类似如下的 HTML 代码:
-
整张卡被封装在一个带有类
card的div中。 -
每张卡都有一个头,它是一个带有类
card-header的h*元素。 -
这个图像是用一个标准的
img元素构造的,这个元素有一个类card-img-top。您还指定了一个特定的高度,这样所有卡片的所有图像都显示在一个特定的高度上,但是占用了所有可用的宽度。 -
然后,卡片的主要内容,也就是图像后面的内容,被放在一个带有类
card-body的 div 中。 -
在主体内部,您通常可以放入任何您想要的 HTML 代码。我们已经把
-
使用一个
h*和一个类别card-title的卡片标题。 -
使用一个
h*和一个card-subtitle类的卡片字幕。 -
有正文的段落。这个有类
card-text。 -
一个包含类
card-link和一些额外类的超链接,使它看起来像一个按钮。
-
-
在主体之后,我们用类
card-footer附加一个div。这是用来创建卡的页脚。
就这样。如果您保存 HTML 页面并将其加载到您的浏览器上,您将会看到您已经在图 5-17 中看到的卡片。
旋转木马
你将用一个叫做旋转木马的非常酷的功能来关闭这个长长的 Twitter 引导参考页面。Twitter Bootstrap 允许你创建图像和视频传送带。旋转木马是页面中逐个显示一系列图像(和/或视频)的区域。每个图像在被下一个图像替换之前会保持可见一段时间(大约 5 秒钟)。
典型的转盘由以下部分组成:
-
小指示器通常显示在底部(图 5-18
图 5-18
旋转指示器
指示器的数量等于转盘中物品的数量。在前面的示例中,有一个包含三个项目的转盘。因此,您可以看到三个条形。用白色填充的表示当前显示的项目。您也可以点按栏以在相应位置快速显示项目。
-
下一个和上一个控件(图 5-19
图 5-19
旋转下一个和上一个控件
下一个和上一个按钮,像箭头一样,允许你从一个项目到另一个项目,向左或向右导航、滑动。
-
物品(图 5-20
图 5-20
轮播项目和标题
传送带有一个项目列表,每个项目都引用一个图像并有一个标题。
说了这么多,很容易识别和理解下面的 HTML 片段,它实现了前面的 carousel。将它修改为主内容容器中 HTML 代码的最后一部分(清单 5-14 )。
<div class="page-header">
<h1>Carousels</h1>
</div>
<div id="carousel-example-generic" class="carousel slide carousel-fade" data-ride="carousel">
<!-- Indicators -->
<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>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="carousel-item active">
<img src="https://tclf.org/sites/default/files/styles/crop_2000x700/public/thumbnails/image/GovernorsIsland_hero_CharlesABirnbaum_2016_0.jpg"
alt="New York Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
New York
</div>
</div>
<div class="carousel-item">
<img src="https://1920x1080hdwallpapers.com/image/201502/city/338/tokyo-night-landscape-top-view.jpg"
alt="Tokyo Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
Tokyo
</div>
</div>
<div class="carousel-item">
<img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fspecials-images.forbesimg.com%2Fdam%2Fimageserve%2F1154977741%2F960x0.jpg"
alt="Athens Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
Athens
</div>
</div>
</div>
<!-- Controls -->
<a class="carousel-control-prev" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-example-generic" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
Listing 5-14HTML Fragment for the Carousel
下面是在创建 Twitter 引导轮播时需要注意的一些事项:
-
传送带需要用类别
carousel和slide包含在div中。如果你也想用淡入淡出效果从一张幻灯片过渡到下一张幻灯片,那么你也必须添加类carousel-fade。 -
main
div需要有一个id,就像我们在前面的 HTML 片段(carousel-example-generic)中看到的那样。这是必要的,因为它会被指示器和控件引用。如果在同一个页面上有多个轮播,这个需求就变得更加重要。 -
对于指标
-
它们需要是一个带有类
carousel-indicators的有序列表(ol)。 -
每个项目(
li)都是一个指标,你需要有和你的项目数量一样多的指标。如果你有三个图像,那么你就得有三个指标,也就是li项。 -
每个指示器需要有一个带有转盘 id 的
data-target属性。此外,它需要有一个值等于它所对应的项目的索引/位置的data-slide-to属性。注意,分度/定位从0开始。也就是说,第一个传送带项目用索引0引用,然后第二个用索引1,引用,依此类推。 -
第一个指示器需要有类
active。
-
-
所有的传送带项目都需要用类
carousel-inner包装在一个div中。 -
对于传送带项目
-
每一个都是拥有类
carousel-item的div。 -
第一个需要有类
active;否则,将不会显示转盘。 -
注意,carousel 的图像需要有处理它们的高度和显示属性的类和样式。特别
-
类
d-block和w-100:第一个(d-block)设置图像display属性block的值。第二个(w-100)设置图像宽度为100%。因此,图像将占据整个可用宽度。请注意,这些是显示和调整引导实用程序类。 -
将所有图像的高度设置为相同的样式。在示例中,它被设置为
500px。
-
-
最后,轮播项目可以有一个带有类
carousel-caption的div,作为项目的标题。请注意,您已经在标题上设置了两个额外的显示实用程序类:-
d-none,隐藏字幕。 -
d-md-block,显示中等显示和更宽显示的标题。换句话说,您希望字幕显示在宽度> =768px 的设备上。否则,它们将不会显示。
-
-
-
在 carousel 的内部内容(带有类
carousel-inner的div)下面,您为控件设置 HTML 内容,这是两个锚a元素:-
第一个有类
carousel-control-prev,,它用于导航到前一张/左边的幻灯片。 -
第二个包含类
carousel-control-next,,用于导航到下一张/右边的幻灯片。 -
两者都具有指向传送带 id (
#carousel-example-generic)的属性href。 -
两者都有一个子/内容是
span。此span用于显示左(第一个控件)和右(第二个控件)箭头。对于第一个控件,span 需要有类carousel-control-prev-icon,以便它显示左箭头。对于第二个控件,span 需要有类carousel-control-next-icon,以便它显示右箭头。
-
最终检查站
为了您的方便和复查,这里是您创建的页面的完整内容(清单 5-15 )。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Custom CSS -->
<link rel="stylesheet" href="stylesheets/main.css" type="text/css">
<title>Twitter Bootstrap Reference Page</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="#">Bootstrap Ref. Page</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#about">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#contact">Contact</a>
</li>
<!-- Drop down Menu -->
<li class="nav-item dropdown">
<a href="#"
class="nav-link dropdown-toggle"
data-toggle="dropdown">
Dropdown
</a>
<div class="dropdown-menu">
<a href="#" class="dropdown-item">Action</a>
<a href="#" class="dropdown-item">Another action</a>
<a href="#" class="dropdown-item">Something else here</a>
<div class="dropdown-divider"></div>
<div class="dropdown-header">Nav header</div>
<a href="#" class="dropdown-item">Separated link</a>
<a href="#" class="dropdown-item">One more separated link</a>
</div>
</li>
</ul>
</div>
</div>
</nav>
<!-- main content container -->
<div class="container">
<div class="jumbotron">
<p class="lead">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<h1>Buttons</h1>
<hr class="my-4">
<h2>Small Sizes</h2>
<p>
<button type="button" class="btn btn-sm btn-primary">btn btn-sm btn-primary</button>
<button type="button" class="btn btn-sm btn-secondary">btn btn-sm btn-secondary</button>
<button type="button" class="btn btn-sm btn-success">btn btn-sm btn-success</button>
<button type="button" class="btn btn-sm btn-danger">btn btn-sm btn-danger</button>
<button type="button" class="btn btn-sm btn-warning">btn btn-sm btn-warning</button>
<button type="button" class="btn btn-sm btn-info">btn btn-sm btn-info</button>
<button type="button" class="btn btn-sm btn-light">btn btn-sm btn-light</button>
<button type="button" class="btn btn-sm btn-dark">btn btn-sm btn-dark</button>
<button type="button" class="btn btn-sm btn-link">btn btn-sm btn-link</button>
</p>
<h2>Normal Sizes</h2>
<p>
<button type="button" class="btn btn-primary">btn btn-primary</button>
<button type="button" class="btn btn-secondary">btn btn-secondary</button>
<button type="button" class="btn btn-success">btn btn-success</button>
<button type="button" class="btn btn-danger">btn btn-danger</button>
<button type="button" class="btn btn-warning">btn btn-warning</button>
<button type="button" class="btn btn-info">btn btn-info</button>
<button type="button" class="btn btn-light">btn btn-light</button>
<button type="button" class="btn btn-dark">btn btn-dark</button>
<button type="button" class="btn btn-link">btn btn-link</button>
</p>
<h2>Large Sizes</h2>
<p>
<button type="button" class="btn btn-lg btn-primary">btn btn-lg btn-primary</button>
<button type="button" class="btn btn-lg btn-secondary">btn btn-lg btn-secondary</button>
<button type="button" class="btn btn-lg btn-success">btn btn-lg btn-success</button>
<button type="button" class="btn btn-lg btn-danger">btn btn-lg btn-danger</button>
<button type="button" class="btn btn-lg btn-warning">btn btn-lg btn-warning</button>
<button type="button" class="btn btn-lg btn-info">btn btn-lg btn-info</button>
<button type="button" class="btn btn-lg btn-light">btn btn-lg btn-light</button>
<button type="button" class="btn btn-lg btn-dark">btn btn-lg btn-dark</button>
<button type="button" class="btn btn-lg btn-link">btn btn-lg btn-link</button>
</p>
<h2>Block Sizes</h2>
<p>
<button type="button" class="btn btn-block btn-primary">btn btn-block btn-primary</button>
<button type="button" class="btn btn-block btn-secondary">btn btn-block btn-secondary</button>
<button type="button" class="btn btn-block btn-success">btn btn-block btn-success</button>
<button type="button" class="btn btn-block btn-danger">btn btn-block btn-danger</button>
<button type="button" class="btn btn-block btn-warning">btn btn-block btn-warning</button>
<button type="button" class="btn btn-block btn-info">btn btn-block btn-info</button>
<button type="button" class="btn btn-block btn-light">btn btn-block btn-light</button>
<button type="button" class="btn btn-block btn-dark">btn btn-block btn-dark</button>
<button type="button" class="btn btn-block btn-link">btn btn-block btn-link</button>
</p>
<h2>Outline buttons (Normal Sizes)</h2>
<p>
<button type="button" class="btn btn-outline-primary">btn btn-outline-primary</button>
<button type="button" class="btn btn-outline-secondary">btn btn-outline-secondary</button>
<button type="button" class="btn btn-outline-success">btn btn-outline-success</button>
<button type="button" class="btn btn-outline-danger">btn btn-outline-danger</button>
<button type="button" class="btn btn-outline-warning">btn btn-outline-warning</button>
<button type="button" class="btn btn-outline-info">btn btn-outline-info</button>
<button type="button" class="btn btn-outline-light">btn btn-outline-light</button>
<button type="button" class="btn btn-outline-dark">btn btn-outline-dark</button>
<button type="button" class="btn btn-outline-link">btn btn-outline-link</button>
</p>
<h1>Tables</h1>
<hr class="my-4">
<h2>Shopping List</h2>
<table class="table">
<tr><th colspan="2">Shopping List</th></tr>
<tr><th>Item</th><th>Qt</th></tr>
<tr><td>Cheese</td><td>1 kgr</td></tr>
<tr><td>Rice</td><td>1.5 kgr</td></tr>
<tr><td>Coffee</td><td>0.5 kgr</td></tr>
<tr><td>Milk</td><td>1 ltr</td></tr>
<tr><td>Wine</td><td>1 btl</td></tr>
</table>
<h2>Travel Plan</h2>
<table class="table table-bordered table-striped table-sm">
<tr><th colspan="2">Travel Plan</th></tr>
<tr class="table-active"><th>(active) Action</th><th>Due</th></tr>
<tr class="table-success"><td>(success) Book Ticket</td><td>Feb 20th</td></tr>
<tr class="table-info"><td>(info) Book Hotel</td><td>March 26th</td></tr>
<tr class="table-warning"><td>(warning) Buy Suitcase</td><td>April 20th</td></tr>
<tr class="table-danger"><td>(danger) Get Passport</td><td>April 30th</td></tr>
</table>
<h1>Labels & Badges</h1>
<hr class="my-4">
<h4>
<span class="badge badge-primary">€20.00 - Primary</span>
<span class="badge badge-secondary">€20.00 - Secondary</span>
<span class="badge badge-success">€20.00 - Success</span>
<span class="badge badge-danger">€20.00 - Danger</span>
<span class="badge badge-warning">€20.00 - Warning</span>
<span class="badge badge-info">€20.00 - Info</span>
<span class="badge badge-light">€20.00 - Light</span>
<span class="badge badge-dark">€20.00 - Dark</span>
</h4>
<button class="btn btn-light">Inbox <span class="badge badge-primary badge-pill">1</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-secondary badge-pill">2</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-success badge-pill">3</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-danger badge-pill">4</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-warning badge-pill">5</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-info badge-pill">6</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-light badge-pill">7</span></button>
<button class="btn btn-light">Inbox <span class="badge badge-dark badge-pill">8</span></button>
<h1>Tabs</h1>
<hr class="my-4">
<ul class="nav nav-tabs mb-4">
<li class="nav-item"><a class="nav-link active" href="#dashboard" data-toggle="tab">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" href="#payments" data-toggle="tab">Payments</a></li>
<li class="nav-item"><a class="nav-link" href="#invoices" data-toggle="tab">Invoices</a></li>
<li class="nav-item"><a class="nav-link" href="#settings" data-toggle="tab">Settings</a></li>
</ul>
<div class="tab-content">
<div id="dashboard" class="tab-pane active">
<p>
<strong>Dashboard:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="payments" class="tab-pane">
<p>
<strong>Payments:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="invoices" class="tab-pane">
<p>
<strong>Invoices:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
<div id="settings" class="tab-pane">
<p>
<strong>Settings:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<h1>Alerts</h1>
<hr class="my-4">
<div class="alert alert-primary">
A simple primary alert.
</div>
<div class="alert alert-secondary">
A simple secondary alert.
</div>
<div class="alert alert-success">
A simple success alert.
</div>
<div class="alert alert-danger">
A simple danger alert.
</div>
<div class="alert alert-warning">
A simple warning alert.
</div>
<div class="alert alert-info">
A simple info alert.
</div>
<div class="alert alert-light">
A simple light alert.
</div>
<div class="alert alert-dark">
A simple dark alert.
</div>
<div class="alert alert-info">
<strong>London</strong> Read more about London from <a class="alert-link" href="https://en.wikipedia.org/wiki/London">Wikipedia London Link</a>.
</div>
<h1>Progress Bars</h1>
<hr class="my-4">
<div class="progress mb-1 h-4">
<div class="progress-bar bg-primary" style="width: 60%;">60% Complete - primary</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-secondary" style="width: 60%;">60% Complete - secondary</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-success" style="width: 60%;">60% Complete - success</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-danger" style="width: 60%;">60% Complete - danger</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-warning" style="width: 60%;">60% Complete - warning</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-info" style="width: 60%;">60% Complete - info</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-light" style="width: 60%;">60% Complete - light</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-dark" style="width: 60%;">60% Complete - dark</div>
</div>
<div class="progress mb-1 h-4">
<div class="progress-bar bg-primary" style="width: 30%;">30% primary</div>
<div class="progress-bar bg-success" style="width: 50%;">50% success</div>
<div class="progress-bar bg-warning" style="width: 10%;">10% warning</div>
</div>
<h1>Cards</h1>
<hr class="my-4">
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3">
<div class="col">
<div class="card">
<h5 class="card-header">Voted #1</h5>
<img src="https://live.staticflickr.com/3869/14437071224_43fb23705b_h.jpg" class="card-img-top" alt="lion sitting and looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Lions</h5>
<h6 class="card-subtitle">Lions Are Amazing</h6>
<p class="card-text">
The lion (Panthera leo) is a large mammal of the Felidae (cat) family. Some large males weigh over 250 kg (550 lb).
Today, wild lions live in sub-Saharan Africa and in Asia. Lions are adapted for life in grasslands and mixed areas
with trees and grass. The relatively small females are fast runners over short distances, and coordinate their hunting of herd animals.
</p>
<a href="https://simple.wikipedia.org/wiki/Lion" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
<div class="col">
<div class="card">
<h5 class="card-header">Voted #2</h5>
<img src="http://www.felineworlds.com/wp-content/uploads/Cheetah_Looking_Around_600.jpg" class="card-img-top" alt="cheetah looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Cheetahs</h5>
<h6 class="card-subtitle">Cheetahs Are Really Fast</h6>
<p class="card-text">
The cheetah (Acinonyx jubatus; /ˈtʃiːtə/) is a large cat of the subfamily Felinae that occurs in North, Southern and East Africa, and a few localities in Iran.
It inhabits a variety of mostly arid habitats like dry forests, scrub forests, and savannahs. The species is IUCN Red Listed as Vulnerable, as it suffered a
substantial decline in its historic range in the 20th century...
</p>
<a href="https://en.wikipedia.org/wiki/Cheetah" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
<div class="col">
<div class="card">
<h5 class="card-header">Voted #3</h5>
<img src="https://cdn.thinglink.me/api/image/601481335449583616/1240/10/scaletowidth" class="card-img-top" alt="panther looking around" style="height: 220px"/>
<div class="card-body">
<h5 class="card-title">Black Panthers</h5>
<h6 class="card-subtitle">Black Panthers Are Really Scary</h6>
<p class="card-text">
A black panther is the melanistic colour variant of any Panthera, particularly of the leopard (P. pardus) in Asia and Africa, and the jaguar (P. onca) in the Americas.
</p>
<a href="https://en.wikipedia.org/wiki/Black_panther" class="btn btn-primary">Learn more</a>
</div>
<div class="card-footer">
from Wikipedia
</div>
</div>
</div>
</div>
<div class="page-header">
<h1>Carousels</h1>
</div>
<div id="carousel-example-generic" class="carousel slide carousel-fade" data-ride="carousel">
<!-- Indicators -->
<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>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="carousel-item active">
<img src="https://tclf.org/sites/default/files/styles/crop_2000x700/public/thumbnails/image/GovernorsIsland_hero_CharlesABirnbaum_2016_0.jpg"
alt="New York Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
New York
</div>
</div>
<div class="carousel-item">
<img src="https://1920x1080hdwallpapers.com/image/201502/city/338/tokyo-night-landscape-top-view.jpg"
alt="Tokyo Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
Tokyo
</div>
</div>
<div class="carousel-item">
<img src="https://thumbor.forbes.com/thumbor/960x0/https%3A%2F%2Fspecials-images.forbesimg.com%2Fdam%2Fimageserve%2F1154977741%2F960x0.jpg"
alt="Athens Landscape Image"
class="d-block w-100"
style="height: 500px;">
<div class="carousel-caption d-none d-md-block">
Athens
</div>
</div>
</div>
<!-- Controls -->
<a class="carousel-control-prev" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-example-generic" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<!-- end of main content container -->
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
Listing 5-15Twitter Bootstrap Reference Page
结束语
这结束了与 Twitter Bootstrap 的长期接触。您已经创建了一个包含大量 Twitter 引导特性的页面,可以用作最常用特性的参考。
然而,Twitter Bootstrap 上还有更多的内容要介绍。这将在下一章中完成。
任务和测验
Task Details
图 5-21
任务页面
- 创建如下所示的网页(图 5-21 )。
图 5-22
任务页面的元素
- 这是一个包含以下元素的页面(图 5-22 )。
关键要点
-
制表符
-
警报
-
进度条
-
信用卡
-
旋转木马
在下一章中,你将学习 Twitter Bootstrap 如何帮助你创建一个背景被图片覆盖的页面。
六、封面项目
这一章教你如何设计导航条的样式,以及如何用一个背景图片来覆盖你网站的整个页面。此外,它还教你一种技术,无论内容的高度如何,都可以垂直对齐。
您将创建如下所示的页面(图 6-1 )。
图 6-1
封面项目
学习目标
-
了解如何将导航栏的非品牌选项拉到右边。
-
了解如何使用
table/table-cell技术使内容垂直和水平居中。
介绍
这一章将教你如何创建另一个好看的 Twitter 引导项目。我称之为封面项目,因为它包含了覆盖整个浏览器页面的大背景图像。所有内容都显示在这一页的顶部。
这个练习的目的是将一些 Twitter Bootstrap 知识与你在《掌握 HTML & CSS 这本书里学到的一些技巧结合起来,这些技巧并不是 Twitter Bootstrap 特有的。
这是您将要构建的页面(图 6-2 )。
图 6-2
您将构建的页面
本页值得注意的事情
-
有一个背景图片覆盖了整个页面。
-
无论页面大小如何,图像都会覆盖页面。
-
虽然原始图像很亮,但页面上显示的图像亮度降低了。这有助于覆盖图像的文本具有更好的对比度,并且更容易阅读。
-
顶部导航栏类似于我们之前构建的导航栏。但是,选项的非品牌部分向右对齐。
-
此页面的主要内容垂直和水平居中。
-
页面底部有一个固定的页脚,文本水平居中对齐。
空的 Twitter 引导页面
让我们从空的 Twitter 引导页面开始(清单 6-1 )。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Custom CSS -->
<link rel="stylesheet" href="stylesheets/main.css" type="text/css">
<title>Cover Page Project</title>
</head>
<body>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
Listing 6-1Empty Twitter Bootstrap Page
将前面的文件另存为index.html,并创建一个空文件stylesheets/main.css。如果你在浏览器上加载这个页面,你会看到一个空页面,但是加载了 Twitter 引导。
背景图像
你应该已经知道如何应用背景图片了(如果没有,请看我之前的书 Master HTML & CSS ,其中有第 22 章题为“图片背景”)。我们将在该页面的body元素上这样做。将以下规则添加到您的stylesheets/main.css文件中(清单 6-2 )。
html {
height: 100%;
background-color: White;
}
body {
min-height: 100%;
background-color: #2b542c;
background-image: url("img/prague-czech-republic.jpg");
background-repeat: no-repeat;
background-attachment: fixed;
background-position: left top;
background-size: 100% 100%;
}
Listing 6-2CSS File Contents
这很标准。
如果您保存并重新加载页面,您将看到以下内容(图 6-3 )。
图 6-3
应用于 Body 元素的背景图像
如图 6-3 所示,图像显示清晰。它覆盖了整个浏览器窗口,如果您尝试调整窗口大小,您会看到它会自动调整以覆盖新的窗口大小。
图像亮度
让我们看看如何降低图像的亮度。我们绝对可以使用 GIMP 或 Adobe Photoshop 这样的图像编辑软件来改变图像的亮度。但是,如果你不知道如何做到这一点,或者如果你不想改变原来的形象,你可以随时做以下技巧。
您将一个div元素定义为body元素的子元素。这个div将被绝对定位在页面的左上角,并将覆盖其父body元素的整个宽度和高度。让我们称之为div cover分部。cover div需要有一个黑色的背景色,但是要有一些透明度,这样它后面的一些图像颜色就可以被看到。你可以试试rgba(0, 0, 0, 0.5)。
就这么办吧。
添加cover div:
<body>
<div id="cover"></div>
</body>
然后添加以下 CSS 规则:
body {
position: relative;
}
#cover {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
正如您在前面的代码中看到的那样,#cover上的position: absolute;正确工作的先决条件是其父元素body具有非静态定位。这就是为什么我们将position: relative;设置为body元素。
如果保存前面的代码并在浏览器上重新加载页面,您将看到图 6-4 。
图 6-4
应用了透明度的黑色封面
这正是你想要达到的结果。背景图像现在有点暗,所以你在背景图像上叠加的任何文字都很容易阅读。
导航栏
我们现在要附加一个导航栏,就像我们在前面的章节中所做的那样。
在cover div后增加以下内容(清单 6-3 )。
<nav id="navigation-bar-container" class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Cover</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="nav-item"><a class="nav-link" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#about">About</a></li>
<li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
</ul>
</div>
</nav>
Listing 6-3HTML Fragment for the Navigation Bar
如果您保存页面的 HTML 内容并在浏览器上重新加载,您将看到以下内容(图 6-5 )。
图 6-5
增加了标准引导导航栏
如果你注意清单 6-3 中的代码,你会看到在 toggler 按钮之前定义了品牌链接(见图 6-6 )。
图 6-6
Toggler 按钮前的品牌链接
这将使 toggler 按钮出现在最右边。尝试缩短显示器的宽度,您将看到以下内容(图 6-7 )。
图 6-7
托格勒出现在最右边
尝试切换 HTML 片段的位置,首先是按钮,然后是品牌链接,如清单 6-4 所示。
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Cover</a>
Listing 6-4First, the Toggler Button and Then the Brand Link
这将使品牌链接出现在导航栏的最右边,toggler 出现在最左边。参见图 6-8 。
图 6-8
托格勒左,品牌链接右
到目前为止,一切都很好,但是如果你仔细看你想要实现的页面,你会注意到
-
导航栏的左右两边都有一些边距。它不会占据页面的整个宽度。
-
此外,它上面还有一些空白。
-
最后,它的边框有圆角。
在您实际实现前面的需求之前,您还将再设置一个。对于超小型和小型设备,您希望导航条是全宽的,但是对于所有其他情况,导航条只有页面宽度的 50%。
以下 CSS 规则将满足这些要求(清单 6-5 )。
#navigation-bar-container {
margin: 10px auto;
border-radius: 10px;
}
@media (min-width: 768px) {
#navigation-bar-container {
width: 50%;
}
}
Listing 6-5CSS Rules for Navigation Bar Requirements
从前面的代码中可以看出,导航栏的默认宽度是100%,,因为它是一个 div。您正在使用一个@media查询规则,以便为更大的设备将其转换为50%。
在样式表/main.css 中添加上述规则,并在浏览器中重新加载页面。您将看到图 6-9 中描述的内容(假设您有一个宽度为> =768px 的显示器)。
图 6-9
在大型设备上显示的导航栏
如果你将浏览器窗口缩小到 768px 以下,你会看到导航条占据了整个宽度(图 6-10 )。
图 6-10
在< 768px 的设备上,导航栏占据了整个页面宽度
进一步在导航栏上工作,你现在要实现的是把菜单的非品牌选项拉到右边。这可以用需要应用到持有这些选项的ul的ml-auto Twitter Bootstrap 实用程序类轻松完成。
让我们加上ml-auto。而不只是
<ul class="nav navbar-nav">
写
<ul class="nav navbar-nav ml-auto">
ml-auto翻译成页边距左自动。换句话说,ul元素的左边距将自动设置为最大可用值。
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 6-11 )。
图 6-11
选项移至右侧
您尚未使用完导航栏。如果将当前版本与原始版本进行比较,您会发现字体大小和颜色有所不同。
让我们就此对 CSS 规则做如下修改(清单 6-6 )。
#navigation-bar-container a.navbar-brand,
#navbar ul a {
font-weight: 900;
}
#navigation-bar-container a.navbar-brand {
font-size: 3.2rem;
}
#navbar ul a {
font-size: 1.8rem;
}
Listing 6-6CSS Amendments for Font and Color of the Nav Bar
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 6-12 )。
图 6-12
具有所需字体大小和颜色的导航栏
这些是必需的字体大小和颜色属性。这样,你就完成了导航条的工作。
页面中央的内容
您继续尝试实现以下内容(图 6-13 )。
图 6-13
页面中央的内容
有一些 HTML 内容出现在页面的中央,水平和垂直都有。首先,让我们添加 HTML 内容(清单 6-7 )。
<div id="center-content">
<h1>Cover your page.</h1>
<p class="lead">This content will always be vertically and horizontally aligned</p>
<p class="lead">
<a href="#" class="btn btn-lg btn-success">Learn more</a>
</p>
</div>
Listing 6-7Content on the Center of the Page
将前面的代码添加到nav元素的下面,在body元素的结尾之前。这都是非常简单的 HTML 代码。在前面的章节中,你已经了解了这一点。
让我们保存并在您的浏览器上重新加载页面。您将看到以下内容(图 6-14 )。
图 6-14
内容放在左上方—不容易阅读
如您所见,内容已经放在左上方。而且不容易读懂。这就是我们必须介绍我们的z-index技能的地方,因为看起来#cover div是在我们刚才放进去的内容之后画出来的。
但是等等!为什么我们在导航栏上没有同样的问题?这是因为导航栏已经有了带有正整数z-index的position: fixed(等于1030——你只需要用开发工具检查一下就可以确认),而我们的#center-content div有了position static。因此#center-content是第一个未定位的元素:
-
body被定位,因为它有position relative。 -
#cover被定位,因为它有position absolute。 -
#navigation-bar-container被定位,因为它有position fixed。
如果你读了我上一本书 Master HTML & CSS 的第 23 章“元素定位”,你就会知道,如果你控制了定位元素和非定位元素所属的堆栈上下文,它们会玩得很好。每当您使用值不同于auto的z-index属性时,就会启动一个新的堆栈上下文。
换句话说,您将通过将z-index: 0设置为body元素来开始一个新的堆栈上下文。然后,#cover将有一个等于-1的 z-index,因为您希望它位于 body 元素中每个非定位元素的后面。同样,确保你阅读了我上一本书中第 23 章“定位”的最后一部分,其中我解释了浏览器绘制事物的顺序。
说到这里,请继续对body和#cover CSS 规则进行以下修改:
body {
...
z-index: 0;
}
#cover {
...
z-index: -1;
}
如果您在浏览器上保存并加载页面,您将看到以下内容(图 6-15 )。
图 6-15
前景上的内容,但仍然难以阅读文本
从按钮的颜色可以看出,内容现在绘制在前景上。但是,你仍然不能轻松地阅读文本,尽管这只是文本颜色的问题。
先换个颜色吧。您将确保任何文本元素的颜色都是white。将color: white;添加到 CSS 文件中的body元素中。
如果您这样做并重新加载页面,您将看到以下内容(图 6-16 )。
图 6-16
内容现在具有正确的颜色
那很好。内容颜色看起来不错。现在,你需要确定位置。
为了固定位置,您将使用table/table-cell技术:
-
您将告诉浏览器假设包含主要内容的
div是一个表格单元格。您可以通过为这个元素设置display: table-cell;来实现。 -
您将告诉浏览器假设父元素,也称为
body,是一个表。你可以通过为body元素设置display: table;来实现。 -
您希望表格(
body)占据由其父表格(html)定义的所有可用空间。出于这个原因,您将为body元素定义width:100%; height: 100%;。 -
您希望文档根目录占据浏览器窗口给定的所有可用空间。因此,您也将为
html元素设置width: 100%; height: 100%;。 -
您将告诉表格单元格(
center-content div)将其内容水平居中(text-align: center;)和垂直居中(vertical-align: middle;)。
以下是规则(列出 6-8 )。
html {
width: 100%;
height: 100%;
}
body {
display: table;
width: 100%;
height: 100%;
}
#center-content {
display: table-cell;
text-align: center;
vertical-align: middle;
}
Listing 6-8CSS Rules to Make Content Vertically and Horizontally Centered
如果您将前面的规则保存在 CSS 文件中,并在浏览器上重新加载页面,您将看到以下内容(图 6-17 )。
图 6-17
内容正确地放置在页面中央
Note
还有其他技术可以用来垂直居中内容。这种技术和table/table-cell一起确保了即使你改变了实际的内容,顶部和底部的边距也会自动调整。
页脚
现在剩下的就是创建页脚了。这非常简单。让我们先添加footer元素:
<footer id="footer-content">
<small>Copyright © Panos M.</small>
</footer>
在关闭正文之前,添加前面的代码。保存内容并在浏览器上重新加载页面。您将看到以下内容(图 6-18 )。
图 6-18
添加了页脚,但布局被破坏
布局已经被破坏了。但这很容易解决。您需要指定页脚的位置属性:
#footer-content {
position: absolute;
bottom: 20px;
left: 0;
width: 100%;
text-align: center;
}
您需要将上述代码添加到 CSS 规则中。页脚需要有position absolute。保存 CSS 文件并在浏览器上重新加载页面。您将看到以下内容(图 6-19 )。
图 6-19
更正页脚位置后,页面就准备好了
更正页脚位置后,页面就准备好了。
结束语
您已经看到了如何将导航栏选项放在导航栏的右侧。您还了解了垂直和水平居中内容的技巧。
任务和测验
Task Details
图 6-20
任务,封面-游览雅典
-
创建如下所示的网页(图 6-20 )。
-
它类似于您在章节中构建的页面。但是在导航栏上还是有区别的。你能看到吗?
关键要点
-
如何设计导航条的样式并将链接放在右边
-
如何显示背景图像
-
如何在页面中央显示内容
-
如何在页面底部放置页脚
在下一章中,您将学习如何创建一个管理仪表板页面。
七、管理仪表板
在本章中,我们将努力构建一个 Twitter 引导管理仪表板,如下所示(图 7-1 )。
图 7-1
基本管理仪表板
类似图 7-1 中的站点有一个固定位置的侧边栏。侧边栏在超小型设备上消失,仪表板根据设备显示宽度改变其布局。
此外,该表反应灵敏,可以在大型和小型显示器上同样良好地显示。
您还将学习各种其他新概念,比如如何以圆形显示图像,或者如何使用特定于文本颜色的类来改变文本颜色。
学习目标
-
了解如何在导航栏中使用
container或container-fluid元素。 -
了解如何在导航栏中附加搜索表单。
-
了解如何将导航栏搜索表单向右移动。
-
了解如何定义导航栏搜索表单的正确垂直位置。
-
学习如何用
form-control类快速设计输入控件的样式。 -
了解如何在左侧创建边栏。
-
了解如何使侧边栏扩展到全高。
-
了解如何使侧边栏保持在同一位置,即使用户滚动页面的主要内容。
-
了解如何使用可见性类根据显示宽度显示和隐藏页面的各个部分。
-
了解如何在 div 的一侧添加边框。
-
了解如何让一个 div 占据 100%的可用高度。
-
了解如何让一个
ul元素的内容占据整个可用宽度。 -
了解如何创建底部有水平线的漂亮页眉。
-
了解如何以圆形显示图像。
-
了解文本对齐类。
-
学习如何使用响应式图像。
-
了解影响文本颜色的类。
-
了解如何创建响应式表格。
-
了解如何应用多种 Twitter 引导技术来创建一个类似管理员的布局。
介绍
在本章中,您将使用 Twitter Bootstrap 工具创建一个基本的管理仪表板页面。
Note
这是一个很长的章节,有很多新的东西需要你去学习。但是,在你做了一些额外的工作后,你会得到最终结果的回报。
图 7-2 可以看到最后一页。
图 7-2
基本管理仪表板
该页面的特征如下:
图 7-3
超小型设备上的管理仪表板
-
它有一个导航栏,其内容扩展了整个页面的宽度。
-
导航栏非品牌选项靠右对齐。
-
导航栏内有一个搜索表单。
-
有一个带有导航选项的左侧栏。我们称之为左侧导航栏。
-
超小型设备上不显示左侧导航栏(图 7-3 )。
空的 Twitter 引导页面
让我们从空的 Twitter 引导页面开始(清单 7-1 )。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- Custom CSS -->
<link rel="stylesheet" href="stylesheets/main.css" type="text/css">
<title>Admin Dashboard</title>
</head>
<body>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
Listing 7-1Empty Twitter Bootstrap Page
导航栏
您将添加和使用的第一个东西是导航栏。
标准导航栏内容
让我们添加标准的导航栏。清单 7-2 包含了导航栏的 HTML 片段,您必须将它添加为body元素的第一个子元素。
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
<div class="collapse navbar-collapse" id="navbar">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#settings">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#help">Help</a>
</li>
</ul>
</div>
</nav>
Listing 7-2Navigation Bar
如果您保存并重新加载您的页面,您将看到以下内容(图 7-4 )。
图 7-4
添加导航栏
向右对齐
导航栏的主要选项靠左对齐。你需要把他们带到右边。您已经通过使用ml-auto类学会了如何做到这一点。让我们将ml-auto类添加到保存主要导航选项的ul中(列出 7-3 )。
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
<div class="collapse navbar-collapse" id="navbar">
<ul class="nav navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#settings">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#help">Help</a>
</li>
</ul>
</div>
</nav>
Listing 7-3Adding the ml-auto Class to the ul Element
保存更改并在浏览器上重新加载页面。您将看到以下内容(图 7-5 )。
图 7-5
导航选项向右拉
添加搜索表单
您希望在顶部导航栏中添加一个搜索表单。这不会是选项列表的一部分,但它需要是切换到小设备时折叠的div的一部分,也就是说,是#navbar div 的一部分。
让我们将下面的代码放在#navbar div 中,但是在带有导航选项的ul之前:
<form>
<input type="text" placeholder="Search...">
</form>
因此,nav元素需要如下所示(清单 7-4 )。
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
<div class="collapse navbar-collapse" id="navbar">
<form>
<input type="text" placeholder="Search...">
</form>
<ul class="nav navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#settings">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#help">Help</a>
</li>
</ul>
</div>
</nav>
Listing 7-4Navigation Bar with Search Form
如果您保存前面的代码并重新加载页面,您将看到以下内容(图 7-6 )。
图 7-6
导航栏中的搜索表单
搜索表单已经放在了导航栏里面。但是我们想把它移到右边。如果你在表单上添加了ml-auto类,你会得到如下结果(图 7-7 )。
图 7-7
ml-auto搜索表单上的类别
搜索表单不在最右边,而是在选项的左边,因为您需要从ul中移除ml-auto类。你不能同时在搜索表单和ul元素上。
继续将ml-auto从ul元件上移除。如果您保存并重新加载页面,您将看到以下内容(图 7-8 )。
图 7-8
位于右侧的搜索表单
有两个类可以应用于搜索表单,这将使它看起来更好。我将在下一章讨论这些类,但是没有什么可以阻止你现在使用它们来设计搜索表单:
-
在表单 HTML 元素上使用类
form-inline。 -
在输入 HTML 元素上使用类
form-control。
因此,表单标记应该如下所示:
<form class="form-inline ml-auto">
<input type="text" placeholder="Search..." class="form-control">
</form>
如果您在浏览器上保存并重新加载页面,您将看到以下内容(图 7-9 )。
图 7-9
带有样式类的搜索表单
您已经完成了顶部导航栏。既然您已经在其中引入了搜索表单,那么最好检查一下当页面在小型设备上显示时,这个搜索表单是如何显示的(图 7-10 )。
图 7-10
小型设备上的搜索表单和菜单选项
前面布局中的搜索表单有问题。它上面没有任何边距。如果有一些像下面这样的上边距就更好了(图 7-11 )。
图 7-11
带有上边距的搜索表单
为了实现这一点,您可以使用一个 sizing Bootstrap 实用程序类,例如mt-3,它添加了一个大小为 3 的上边距。将表单标记更改如下:
<form class="form-inline ml-auto mt-3">
<input type="text" placeholder="Search..." class="form-control">
</form>
并在浏览器上重新加载页面。切换到小显示器(如 iPhone X)设备。当你打开菜单时,你会看到顶部空白的搜索表单看起来更好,如图 7-11 所示。
但是,如果您切换回大显示设备,您将看到以下内容(图 7-12 )。
图 7-12
在大显示器上搜索表单上边距
正如你所看到的,因为mt-3的存在,导航栏的布局已经被破坏了。换句话说
-
当菜单选项折叠时,您只希望在小设备上使用
mt-3。 -
当菜单选项展开时,你不想要
mt-3。
您知道您的菜单在lg断点上展开(感谢navbar-expand-lg类)。因此,当你在lg断点之上时,为了否定mt-3类的效果,你将添加mt-lg-0类。因此,表单标记应该是
<form class="form-inline ml-auto mt-3 mt-lg-0">
<input type="text" placeholder="Search..." class="form-control">
</form>
同样,前面的标记在显示小于lg断点的设备上保留了mt-3,并在显示大于lg断点的设备上使用了类mt-lg-0。
如果您保存前面的代码并在浏览器上重新加载页面,您将看到导航栏恢复了正确的样式。而缩小到一个小显示屏上,依然能按预期工作。
使用 Flex 实用程序类对齐
您已经使用 margin 实用程序类将导航栏的项目向右对齐。但是 Twitter Bootstrap 严重依赖于 flexbox 。它提供了可以用来相应地对齐内容的类。
例如,您可以使用类flex-row-reverse并让您的 HTML 标记逆序排列。这样做,您不需要在表单元素上使用ml-auto。见下文我的意思(列表 7-5 )。
-
您已经在
ul标记之后编写了form标记。 -
您已经在包含菜单选项和搜索表单的
div上添加了类flex-row-reverse。 -
您已经从
form标记中移除了边距类。
<div class="collapse navbar-collapse flex-row-reverse" id="navbar">
<ul class="nav navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#settings">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#help">Help</a>
</li>
</ul>
<form class="form-inline">
<input type="text" placeholder="Search..." class="form-control">
</form>
</div>
Listing 7-5Using flex-row-reverse
如果您保存前面的代码并在浏览器上加载页面,您将看到以下内容(图 7-13 )。
图 7-13
使用 flex-row-reverse 在右侧绘制项目
如您所见,flex-row-reverse div的直接子元素是以相反的顺序绘制的,也就是说,首先是搜索form,然后是ul元素。
请注意,我们将form移到了div的底部,这使得小设备看起来也更好。搜索表单显示在底部。flex-row-reverse对这些设备没有任何影响,因为菜单选项是从上到下显示的(图 7-14 )。
图 7-14
搜索表单出现在底部
一切都好!现在,让我们移到左侧导航栏。
左侧导航栏
我们现在开始构建左侧导航栏(图 7-15 )。
图 7-15
左侧导航栏属性
如图 7-15 所示,左侧导航栏应该有一些属性:
-
它的背景色不是白色;它更像是灰色的。
-
活动菜单项具有白色和蓝色背景色。
-
有三组菜单项,也就是三个不同的列表。
-
它占据了页面的特定宽度。让我们假设中型、大型和超大型设备的宽度为六分之一(即 12 列中的两列),小型设备的宽度为四分之一(即 12 列中的三列)。在超小型设备上,侧边栏将不可见。
布局
先说第四个属性。因为我们希望侧边栏占据页面宽度的一部分,所以我们将使用正确的网格类。在nav元素下添加以下内容(清单 7-6 )。
<div id="main-container" class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2">
<!-- Left Sidebar Content will go here -->
</div>
<div id="main-content-container" class="col-sm-9 col-md-10">
<!-- Main Content will go here -->
</div>
</div>
</div>
Listing 7-6Layout Markup
正如你在前面的代码中看到的,我们有一个侧边栏的div,它使用网格类col-sm-3用于小型设备,因此占据了 12 列中的 3 列,使用类col-md-2用于中型、大型和超大型设备,因此占据了 12 列中的 2 列。
主要内容将放在第二个div中,它也使用网格类col-sm-9和col-md-10,因此它占据了剩余的可用宽度。对于小型设备,它将占据 12 列中的 9 列;对于中型、大型和超大型设备,它将占据 12 列中的 10 列。
保存前面的内容。如果您在浏览器上再次加载该页面,您将看不到任何区别,因为侧边栏和主内容中没有任何实际内容。
侧边栏中的列表
您已经在左侧导航栏中确定了三个列表。让我们像往常一样用ul元素创建它们(列出 7-7 )。
<div id="main-container" class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2">
<!-- Left Sidebar Content will go here -->
<ul>
<li class="active"><a href="#">Overview</a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul>
<li><a href="#">Nav item</a></li>
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
<li><a href="#">More navigation</a></li>
</ul>
<ul>
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
</ul>
</div>
<div id="main-content-container" class="col-sm-9 col-md-10">
<!-- Main Content will go here -->
</div>
</div>
</div>
Listing 7-7HTML with ul Elements for the Lists
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 7-16 )。
图 7-16
左侧栏—添加了列表
你现在看到的一个问题是顶部列表被导航栏隐藏了。这是你过去曾经面临过的问题。您需要给正文内容一些顶部填充,至少等于导航栏的高度。你就给56px。
在stylesheets/main.css文件中,添加以下规则:
body {
padding-top: 56px;
}
在浏览器上保存并重新加载页面。您将看到以下内容(图 7-17 )。
图 7-17
导航栏不会隐藏列表
这是一个进步。现在,您将在列表上应用类nav。正如您在前面章节中所记得的,ul元素上的nav类删除了列表项上显示的默认项目符号。
继续将类nav添加到左侧导航栏的所有ul元素中。然后在浏览器上加载页面。您将看到以下内容(图 7-18 )。
图 7-18
应用于 ul 元素的类别nav
类nav已经从列表的元素中移除了项目符号。但它也做了其他事情。它把ul元素变成了display flex,flex-wrap等于wrap。这就是为什么你会看到li元素一个挨着一个。
因为您希望列表从上到下排列,所以您可以添加类flex-column,它将使所有的直接子元素都绘制在一列中。
继续,在nav类的旁边,也添加flex-column类。在浏览器上保存并加载页面。您将看到以下内容(图 7-19 )。
图 7-19
flex-column应用的类别
左边栏开始看起来好多了。然而,它还没有完成。
隐藏超小型设备上的侧边栏
您想要隐藏超小型设备上的侧边栏,只为小型、中型、大型和超大型设备显示侧边栏。您可以使用显示实用程序类来实现这一点:
-
类
d-none将隐藏元素。 -
类
d-sm-block将在sm断点之上显示任何显示的元素。
让我们将它应用于保存左侧导航栏列表的容器div。清单 7-8 给出了 HTML 标记片段。
<div class="col-sm-3 col-md-2 d-none d-sm-block">
<!-- Left Sidebar Content will go here -->
<ul class="nav flex-column">
<li class="active"><a href="#">Overview</a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav flex-column">
<li><a href="#">Nav item</a></li>
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
<li><a href="#">More navigation</a></li>
</ul>
<ul class="nav flex-column">
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
</ul>
</div>
Listing 7-8HTML Fragment for the Container of the Left-Side Navigation Bar
如果您在浏览器上保存并重新加载页面,您将会看到左侧导航栏隐藏在宽度为 575px 的显示屏上(图 7-20 )。
图 7-20
575px 显示屏上隐藏的左侧栏
但是,它在 576px 显示器上是可见的(图 7-21 )。
图 7-21
576px 显示器上可见的侧边栏
侧边栏的进一步样式
现在,您将进一步设计侧栏的样式。为了做到这一点,您将在保存三个列表的div容器上应用类sidebar,然后您将为这个特定的类编写一些 CSS 规则。以下是规则(列出 7-9 )。
.sidebar {
padding-top: 10px;
padding-bottom: 10px;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
Listing 7-9First Styling Rules for the Left Sidebar
不要忘记将类sidebar添加到包含三个ul元素和左侧导航栏选项的div中。
然后,保存并在浏览器上重新加载页面。您将看到以下内容(图 7-22 )。
图 7-22
侧边栏上的一些样式
前面的样式设置了侧边栏右侧的背景颜色和边框,以及顶部和底部的一些填充。
现在,您需要确保侧边栏的高度占据了整个可用高度。为此,您需要在row div及其所有祖先元素上指定height: 100%。
确保stylesheets/main.css文件包含以下内容(列表 7-10 )。
html {
height: 100%;
}
body {
padding-top: 56px;
height: 100%;
}
#main-container,
#main-container .row{
height: 100%;
}
.sidebar {
padding-top: 10px;
padding-bottom: 10px;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
Listing 7-10stylesheets/main.css File Content
注意,#main-container指的是保存页面主要内容的容器的 id,正好在nav元素之后。为了帮助您,#main-container的 HTML 片段应该如清单 7-11 所示。
<div id="main-container" class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 d-none d-sm-block sidebar">
<!-- Left Sidebar Content will go here -->
<ul class="nav flex-column">
<li class="active"><a href="#">Overview</a></li>
<li><a href="#">Reports</a></li>
<li><a href="#">Analytics</a></li>
<li><a href="#">Export</a></li>
</ul>
<ul class="nav flex-column">
<li><a href="#">Nav item</a></li>
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
<li><a href="#">More navigation</a></li>
</ul>
<ul class="nav flex-column">
<li><a href="#">Nav item again</a></li>
<li><a href="#">One more nav</a></li>
<li><a href="#">Another nav item</a></li>
</ul>
</div>
<div id="main-content-container" class="col-sm-9 col-md-10">
<!-- Main Content will go here -->
</div>
</div>
</div>
Listing 7-11#main-container HTML Content
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 7-23 )。
图 7-23
侧边栏占据了整个高度
您将继续侧边栏的样式:
-
您将确保用户能够区分一组选项和下一组选项。您将在侧边栏的
ul元素上应用底部边距。 -
您将增加列表中元素的高度,以便选项非常明显,并且从一个到下一个有一些垂直空间。
-
您希望列表占据所有可用的宽度。因此当鼠标指针移动到任何元素上时,突出显示从左到右进行。为了实现这一点,您将从侧边栏容器中移除左右填充。
-
但是,您希望每个列表项都有一些填充,这样文本就不会从栏的左边缘开始。
这里是您必须应用的更改上带有蓝色的stylesheets/main.css的内容(列表 7-12 )。
html {
height: 100%;
}
body {
padding-top: 56px;
height: 100%;
}
#main-container,
#main-container .row{
height: 100%;
}
.sidebar {
padding: 10px 0;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
.sidebar ul {
margin-bottom: 20px;
}
.sidebar ul li {
padding-left: 10px;
min-height: 2.2rem;
}
Listing 7-12Further Styling of the Sidebar
如果您在浏览器上保存并重新加载页面,您将看到以下内容(图 7-24 )。
图 7-24
左侧栏的进一步样式化
你继续在侧边栏菜单的选项上应用一些背景和前景色。以下是您需要应用的额外 CSS 规则(清单 7-13 )。
.sidebar ul li a {
text-decoration: none;
}
/* Active <li> and <a>, and for hover over NON-active <li> and <a> */
.sidebar ul li.active,
.sidebar ul li.active a,
.sidebar ul li:hover,
.sidebar ul li:hover a,
.sidebar ul li a:hover {
background-color: #428BCA;
color: White;
}
.sidebar ul li:hover {
cursor: pointer;
}
Listing 7-13Extra CSS Rules for Left Sidebar Options
如果您在浏览器上保存并加载页面,您将看到以下内容(图 7-25 )。
图 7-25
颜色选项
如果您将鼠标移动到左侧导航栏的选项上,您会看到它们获得了不同的背景颜色和文本颜色。此外,光标正在变成鼠标指针(图 7-26 )。
图 7-26
悬停在非活动选项上
主要内容区域
您停止样式化侧边栏,并继续构建主要内容区域。您将从仪表板顶部区域开始,在该区域中,您应该呈现一系列图表(图 7-27 )。
图 7-27
仪表板—带图表的顶部区域
请注意以下关于目标的内容:
图 7-28
在超小型设备上—每行两个信息容器
-
底部有一个带横线的
Dashboard表头。你可以用你在前面章节看到的hr和my-4类来创建这个效果。 -
您可以看到四个信息容器(图形图像+文本)。
-
在超大显示屏上,一行显示四个信息容器。大中型设备也是如此。在小型和超小型设备上,我们每行显示两个信息容器(图 7-28 )。
-
您将为图形图像使用一些占位符图像。
我们开始吧。
仪表板标题
首先,添加Dashboard标题:
<h1>Dashboard</h1>
<hr class=my-4>
添加前面的代码作为#main-content-container的第一个子元素。在浏览器上保存并重新加载页面。您将看到以下内容(图 7-29 )。
图 7-29
添加了仪表板页面标题
这很简单,你过去也这么做过。现在,在元素hr和类my-4的帮助下,您可以看到样式为页眉的Dashboard。
信息容器
信息容器是 HTML 代码块,包含
-
一个图像,一个
img元素 -
一个小标签,在一个
h4元素里面 -
标签下方显示一些文本的范围
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
每一个容器——我们有四个——我们需要用正确的 Twitter 引导网格类包含在一个div中:
<div class="col-6 col-md-3">
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
</div>
div有网格类col-6和col-md-3。在超小型和小型设备上,每个信息容器块将占用一半的可用宽度(12 列中的 6 列)。因此,每行将有两个这样的列。在较大的设备上,它将占据可用宽度的四分之一(12 列中的三列)。因此,每行将有四个这样的列。
您需要再重复三次,并用类row将整组div列封装到一个div(清单 7-14 )。
<div class="row">
<div class="col-6 col-md-3">
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
</div>
<div class="col-6 col-md-3">
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
</div>
<div class="col-6 col-md-3">
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
</div>
<div class="col-6 col-md-3">
<img src="https://via.placeholder.com/200" width="200" height="200"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span>Something else</span>
</div>
</div>
Listing 7-14HTML Fragment with Information Blocks
将前面的代码放在Dashboard div容器的正下方。保存文件并在浏览器上重新加载页面。您将看到以下内容(图 7-30 )。
图 7-30
仪表板—放在页面上的信息容器
现在,信息容器已经成功地放置在页面上,在页面标题的下面。但是您需要做一些风格调整,以达到预期的效果。
让我们首先确保图像显示为圆形。这很容易做到。您只需在img元素上添加类rounded-circle。
如果您这样做了,保存并在浏览器上重新加载页面,您将看到以下内容(图 7-31 )。
图 7-31
信息容器具有圆形的图像
接下来,您要做的是确保信息容器的图像和文本都居中对齐。您将使用类text-center来包装图像和文本的所有div元素。
text-center是 Twitter Bootstrap 提供的一个类。它实际上将 CSS 样式text-align: center;应用到它所附加的元素上。Twitter Bootstrap 提供了更多与对齐相关的类。完整列表如下:
-
text-left:对应text-align: left; -
text-right:对应text-align: right; -
text-center:对应text-align: center; -
text-justify:对应text-align: justify;
此外,您可以使用这些类及其特定于断点的变体。例如,您可以使用 t ext-md-center类,它将使内容居中,但仅适用于中等或更宽的显示。
继续在所有信息容器上应用类text-center,然后在浏览器上重新加载页面。您将看到以下内容(图 7-32 )。
图 7-32
内容居中对齐
虽然图 7-32 看起来好像你已经完成了信息容器,但是如果你在一个宽度较短的设备上看到你的页面,有一个小问题变得很明显。例如,使用您的开发工具尝试 iPad 模拟。您将看到以下内容(图 7-33 )。
图 7-33
图像在 iPad 上显示不正常
如果您将类img-fluid应用于img元素,就可以解决这个问题。就这么办吧。然后在浏览器上重新加载页面。您将看到以下内容(图 7-34 )。
图 7-34
使用img-fluid类时,图像显示正常
img-fluid类做两件事:
-
它将
max-width设置为100%。这意味着图像宽度不能比图像所在的父块宽。 -
它将
height设置为auto。这意味着高度将根据宽度自动计算,以便图像具有正确的纵横比。
有了这些限制,图像最终可以在任何显示尺寸下正确绘制。
剩下要做的就是改变文本Something else的颜色。它需要是浅灰色的(见图 7-35 )。
图 7-35
“其他东西”短语的颜色
只需应用其中一个 Twitter Bootstrap 颜色实用程序类,就可以快速轻松地对文本元素的颜色进行更改。这些类别是
-
text-primary -
text-secondary -
text-success -
text-danger -
text-warning -
text-info -
text-light -
text-dark -
text-body -
text-muted -
text-white -
text-black-50 -
text-white-50
你可以在图 7-36 中看到它们的颜色等价物。
图 7-36
引导文本颜色实用程序类
让我们在保存Something else文本的 span 上应用类text-black-50。在浏览器上保存并加载页面。您将看到以下内容(图 7-37 )。
图 7-37
应用了 text-black-50 类的“其他内容”短语
在我们结束关于信息容器的这一部分之前,我将在这里给出应该存在于#main-content-container div中的 HTML 片段,因为它直到现在都是由仪表板标题和信息块组成的。参见清单 7-15 。
<div id="main-content-container" class="col-sm-9 col-md-10">
<!-- Main Content will go here -->
<h1>Dashboard</h1>
<hr class="my-4">
<div class="row">
<div class="col-6 col-md-3 text-center">
<img src="https://via.placeholder.com/200" width="200" height="200"
class="rounded-circle img-fluid"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-black-50">Something else</span>
</div>
<div class="col-6 col-md-3 text-center">
<img src="https://via.placeholder.com/200" width="200" height="200"
class="rounded-circle img-fluid"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-black-50">Something else</span>
</div>
<div class="col-6 col-md-3 text-center">
<img src="https://via.placeholder.com/200" width="200" height="200"
class="rounded-circle img-fluid"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-black-50">Something else</span>
</div>
<div class="col-6 col-md-3 text-center">
<img src="https://via.placeholder.com/200" width="200" height="200"
class="rounded-circle img-fluid"
alt="Generic placeholder thumbnail">
<h4>Label</h4>
<span class="text-black-50">Something else</span>
</div>
</div>
</div>
Listing 7-15Main Container Content
仪表板表
管理页面的下一部分是仪表板表。您已经学习了如何使用 Twitter Bootstrap 设计表格。所以这不会是一个困难的练习。
节标题
您可以使用下面这段 HTML 代码添加节标题:
<h2>Section title</h2>
<hr class="my-4">
将它放在包含您之前实现的信息容器的结束row div之后。如果您保存代码并在浏览器上重新加载页面,您将看到以下内容(图 7-38 )。
图 7-38
不显示部分标题
如您所见,没有显示部分标题。这是为什么呢?事实上,如果您向下滚动,您可以看到该部分的标题。它位于页面底部,如图 7-39 所示。
图 7-39
页面底部的部分标题
为什么会这样?这是因为你已经将100% height应用到了#main-container .row CSS 选择器中(参见你的stylesheets/main.css文件)。这条规则是为了让侧边栏占据整个高度。但是,从我们添加一个额外的row div元素(保存信息块的元素)开始,这条规则也适用于那个div。这最后一个应用程序在您看到的位置推送了部分标题(图 7-40 )。
图 7-40
嵌套 Div 100%高度如何影响布局
您真正想要的是这个 100% height CSS 语句只应用于#main-container div 中的第一级嵌套div。为了做到这一点,规则
#main-container,
#main-container .row {
height: 100%
}
需要更改为
#main-container,
#main-container > .row {
height: 100%
}
>是直接子选择器。前面的 CSS 规则选择了#main-container以及它的第一级直接子元素.row。
为了确保你的代码是对齐的,我在这里给你你的页面应该使用的整个stylesheets/main.css文件(清单 7-16 )。
html {
height: 100%;
}
body {
padding-top: 56px;
height: 100%;
}
#main-container,
#main-container > .row {
height: 100%
}
.sidebar {
padding: 10px 0;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
.sidebar ul {
margin-bottom: 20px;
}
.sidebar ul li {
padding-left: 10px;
padding-top: 5px;
min-height: 2.2rem;
}
.sidebar ul li a {
text-decoration: none;
}
/* Active <li> and <a>, and for hover over NON-active <li> and <a> */
.sidebar ul li.active,
.sidebar ul li.active a,
.sidebar ul li:hover,
.sidebar ul li:hover a,
.sidebar ul li a:hover {
background-color: #428BCA;
color: White;
}
.sidebar ul li:hover {
cursor: pointer;
}
Listing 7-16stylesheets/main.css Content
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 7-41 )。
图 7-41
部分标题在正确的位置
我在这个布局上看到的一个问题是,部分标题在顶部需要一些空间。您可以通过将类mt-4添加到部分的 h2 来添加一些顶部边距:
<h2 class="mt-4">Section title</h2>
如果你保存了这个更改,并在浏览器上重新加载页面,你会看到如下(图 7-42 ),这就好多了。
图 7-42
有一些上边距的部分
桌子
现在让我们在部分标题下添加表格(清单 7-17 )。
<p>Sales table is compiled from data retrieved from the main database</p>
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
<th>Header 7</th>
<th>Header 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>1,001</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
</tr>
<tr>
<td>1,002</td>
<td>amet</td>
<td>consectetur</td>
<td>adipiscing</td>
<td>elit</td>
<td>amet</td>
<td>consectetur</td>
<td>adipiscing</td>
<td>elit</td>
</tr>
<tr>
<td>1,003</td>
<td>Integer</td>
<td>nec</td>
<td>odio</td>
<td>Praesent</td>
<td>Integer</td>
<td>nec</td>
<td>odio</td>
<td>Praesent</td>
</tr>
<tr>
<td>1,003</td>
<td>libero</td>
<td>Sed</td>
<td>cursus</td>
<td>ante</td>
<td>libero</td>
<td>Sed</td>
<td>cursus</td>
<td>ante</td>
</tr>
<tr>
<td>1,004</td>
<td>dapibus</td>
<td>diam</td>
<td>Sed</td>
<td>nisi</td>
<td>dapibus</td>
<td>diam</td>
<td>Sed</td>
<td>nisi</td>
</tr>
<tr>
<td>1,005</td>
<td>Nulla</td>
<td>quis</td>
<td>sem</td>
<td>at</td>
<td>Nulla</td>
<td>quis</td>
<td>sem</td>
<td>at</td>
</tr>
<tr>
<td>1,006</td>
<td>nibh</td>
<td>elementum</td>
<td>imperdiet</td>
<td>Duis</td>
<td>nibh</td>
<td>elementum</td>
<td>imperdiet</td>
<td>Duis</td>
</tr>
<tr>
<td>1,007</td>
<td>sagittis</td>
<td>ipsum</td>
<td>Praesent</td>
<td>mauris</td>
<td>sagittis</td>
<td>ipsum</td>
<td>Praesent</td>
<td>mauris</td>
</tr>
<tr>
<td>1,008</td>
<td>Fusce</td>
<td>nec</td>
<td>tellus</td>
<td>sed</td>
<td>Fusce</td>
<td>nec</td>
<td>tellus</td>
<td>sed</td>
</tr>
<tr>
<td>1,009</td>
<td>augue</td>
<td>semper</td>
<td>porta</td>
<td>Mauris</td>
<td>augue</td>
<td>semper</td>
<td>porta</td>
<td>Mauris</td>
</tr>
<tr>
<td>1,010</td>
<td>massa</td>
<td>Vestibulum</td>
<td>lacinia</td>
<td>arcu</td>
<td>massa</td>
<td>Vestibulum</td>
<td>lacinia</td>
<td>arcu</td>
</tr>
<tr>
<td>1,011</td>
<td>eget</td>
<td>nulla</td>
<td>Class</td>
<td>aptent</td>
<td>eget</td>
<td>nulla</td>
<td>Class</td>
<td>aptent</td>
</tr>
<tr>
<td>1,012</td>
<td>taciti</td>
<td>sociosqu</td>
<td>ad</td>
<td>litora</td>
<td>taciti</td>
<td>sociosqu</td>
<td>ad</td>
<td>litora</td>
</tr>
<tr>
<td>1,013</td>
<td>torquent</td>
<td>per</td>
<td>conubia</td>
<td>nostra</td>
<td>torquent</td>
<td>per</td>
<td>conubia</td>
<td>nostra</td>
</tr>
<tr>
<td>1,014</td>
<td>per</td>
<td>inceptos</td>
<td>himenaeos</td>
<td>Curabitur</td>
<td>per</td>
<td>inceptos</td>
<td>himenaeos</td>
<td>Curabitur</td>
</tr>
<tr>
<td>1,015</td>
<td>sodales</td>
<td>ligula</td>
<td>in</td>
<td>libero</td>
<td>sodales</td>
<td>ligula</td>
<td>in</td>
<td>libero</td>
</tr>
</tbody>
</table>
Listing 7-17
Table HTML Fragment
如果您保存前面的代码并在浏览器上重新加载页面,您将看到以下内容(图 7-43 )。
图 7-43
表格显示正确
但是,在小型设备上查看页面时有一个小问题。尝试 iPhone X 仿真。您将看到该表被截断。实际上,页面是水平扩展的,以便显示整个表数据。如果用户滚动是为了显示隐藏的其余表格数据,那么图像图形也会向左滚动,最终体验非常糟糕。见图 7-44 中的问题截图。
图 7-44
移动设备上的表格样式不佳
有一个非常简单的方法可以解决这个问题。你可以使用 Twitter 引导类table-responsive。您需要将这个类交给table元素。事实上,只为超小型、小型和中型设备设置它可能是一个更好的主意。对于大型和超大型设备,您可以让该表默认运行。
因此,继续将类table-responsive-lg附加到表中。该类执行以下操作:从lg断点开始,表将正常运行。但是在这个断点之下,也就是说,对于 displays < 992px,它将自动获得一个overflow-x: auto;,而不需要您将它添加到您的 CSS 规则中,这将允许用户水平滚动以查看表格的全部内容。
为 iPhone X 模拟器保存并重新加载浏览器上的页面。您将看到以下内容(图 7-45 )。
图 7-45
表格在 iPhone X 上显示正确
如果水平滚动,您会看到页面的其余部分仍然正确显示。
一些最后的调整
您已经设法使页面看起来与您最初作为目标的页面一模一样。有一个小的改进,我想和你一起努力。
当浏览器高度较低时,用户在主仪表板区域上滚动,以便访问/查看不可见的表格内容。例如,在下面的示例中,您可以看到当用户滚动到页面底部以显示表格底部时所看到的内容(图 7-46 )。
图 7-46
左侧导航栏有问题
如您所见,左侧导航栏有问题。随着侧边栏内容与主内容的其余部分一起滚动,选项消失了。您希望所有的侧边栏选项在任何时候都是可访问和可见的,这样无论主内容的实际滚动位置如何,用户都可以点击它们。
为了让一个div always可见,不管浏览器窗口的滚动位置如何,你需要固定它的位置。让我们在 CSS 文件中添加以下内容:
/* fix the position of the sidebar */
position: fixed;
left: 0;
top: 56px;
在sidebar CSS 选择器块中添加前面的 CSS 属性。保存前面的代码,并在浏览器上加载页面。你会看到类似图 7-47 的东西。
图 7-47
位置固定的侧边栏—主要内容有问题
相对于固定位置的侧边栏,这是一个改进。尽量滚动主要内容;你会看到边栏上的所有选项都是可见的。
另一方面,它将主要内容部分带到了左侧,与侧边栏内容重叠。这是因为侧边栏div不是普通页面元素流的一部分。您已经用网格类col-sm-3和col-md-2指定了侧边栏div的宽度,但是实际位置是固定的,因此,当浏览器定位#main-content-container div时,不会考虑这个元素。
你如何解决这个问题?有一个非常简单的解决方案。你只需要对 Bootstrap 说,将容器行的内容向右对齐。在justify-content-*类的帮助下,尤其是在justify-content-end类的帮助下,您已经学会了如何做到这一点。
将类 justify-content-end 添加到所有内容的父行中:
<div id="main-container" class="container-fluid">
<div class="row justify-content-end">
<div class="col-sm-3 col-md-2 d-none d-sm-block sidebar">
<!-- Left Sidebar Content will go here -->
...
如果保存 HTML 内容并在浏览器上加载页面,您将看到以下内容(图 7-48 )。
图 7-48
主要内容两端对齐的仪表板
最后一个需要解决的问题是左侧导航栏没有延伸到窗口底部。这是意料之中的,因为您已经将sidebar div变成了一个位置固定的定位元素。定位的元素根据它们包含的内容扩展到必要的宽度和高度。
通过将min-height属性设置为 100%,可以很容易地改变sidebar div的高度。继续将这个 CSS 属性添加到你的stylesheets/main.css文件中。然后在浏览器上重新加载页面。你会看到图 7-49 。
图 7-49
全高左侧栏
完美!左侧边栏现在占据了整个高度。尝试滚动和更改显示宽度。你会看到一切都如预期的那样工作。
任务和测验
Task Details
图 7-51
任务—管理控制面板(页面底部)
图 7-50
任务—管理控制面板(页面顶部)
-
您需要实现如下所示的页面(图 7-50 和图 7-51 )。
-
When the page is displayed on medium devices, two information containers per row should be displayed (Figure 7-53).
图 7-53
中型设备上每行两个信息容器
-
你需要注意的事情如下:
-
你需要使用字体系列
Anonymous Pro。看看谷歌字体。 -
侧栏
-
不应将其高度扩展到等于可用的最大高度
-
应该有透明的背景色
-
应该有一个彩色的
#eee边框,纯色,周围 1px -
它的边界半径应该是 2px
-
即使我们滚动主要内容区域,它的位置也应该是固定的
-
位置应该是左 10px,上 70px
-
应该让仪表板区域由 300 × 300 的图像占位符组成
注:如果您想生成此类占位符,请访问
https://placehold.it,了解如何生成占位符。例如,您可以访问https://placehold.it/450x450,您将获得一个具有所请求的 450px × 450px 尺寸的图像占位符。您可以右键单击并选择Save Image,以便将其作为图像文件保存在您的计算机中,供以后在您的站点中使用。 -
When the page is displayed on extrasmall and small devices, only one information container per row should be displayed (Figure 7-52).
图 7-52
超小型设备上每行一个信息容器
-
-
-
When the page is displayed on large and extralarge devices, three information containers per row should be displayed (Figure 7-54).
图 7-54
大型设备上每行三个信息容器
除此之外,该练习与本章中描述的工作类似。
关键要点
-
如何在顶部导航栏中放置一个搜索表单
-
你怎么能有一个粘性的侧边导航栏
-
如何在小型设备上隐藏部分页面
-
如何创建圆形图像
-
如何对齐内容并制作管理仪表板
-
如何创建响应表
-
许多其他的细节和技术来调整你的页面布局
在下一章中,你将使用 Twitter Bootstrap 构建令人惊叹的表单。