HTML5-和-CSS3-响应式-Web-设计入门指南-二-

95 阅读1小时+

HTML5 和 CSS3 响应式 Web 设计入门指南(二)

原文:Beginning Responsive Web Design with HTML5 and CSS3

协议:CC BY-NC-SA 4.0

五、响应式设计的框架

我相信您能够理解,响应式开发确实给项目增加了额外的工作,在这种情况下,开发人员需要考虑网站在不同屏幕分辨率下的所有不同变化。在构建网站时,我们可以减少工作量的一种方法是使用响应式框架作为起点。

当看到第四章中讨论的流体设计时,我解释了 CSS 网格的基础,你学会了如何开发自己的网格。然而,在所提供的示例中,网格被大大简化了,开发一个更复杂的网格实际上可能相当耗时。值得庆幸的是,作为开发人员,我们有一个开放源代码的世界,本章将探索一些最流行的网格和框架。

在关于网格和框架的这一章中,我将解释的主题是:

Grid systems   CSS frameworks   What is best for a particular web site   Prototyping a site using CSS frameworks  

网格系统

最简单的形式是,网格系统是一种结构,您可以在其中构建网站的布局。它由水平行和垂直列组成,包含网站的内容,可以跨越一列或多列。在构建网站时,网格系统可以提供很大的好处,允许你在构建中实现间距的一致性,从而提高网站的可用性,因为文本更容易理解。

在寻找开源网格系统时,您会注意到它们通常非常简单,只包含渲染网格所需的样式,而将如何构建站点的所有其他决定留给您自己。本章中解释的网格系统都是为响应而构建的,所以除了基本网格之外,它们还包括允许它们响应浏览器视窗宽度的媒体查询。

尽管 mobile first 响应式设计有很多好处,并且在 web 开发社区中也有接受它的驱动力,但是大多数独立的网格系统仍然是先构建桌面的。因此,在考虑网格系统时,首先要考虑它们是否是移动的,这一点很重要。

本章将介绍三种流行的移动优先响应网格。检查的网格系统有:

Fluidable ( http://fluidable.com/ )   CSS Smart Grid ( http://dryan.github.io/css-smart-grid/ )   csswizardry-grids ( http://csswizardry.com/csswizardry-grids/ )  

流动的

Fluidable ( 5-1 显示其主页。

A978-1-4302-6695-2_5_Fig1_HTML.jpg

图 5-1。

The Fluidable home page

我问 Andri 他开发自己的网格系统背后的原因是什么,他解释如下:

I want a grid that can be configured for any number of columns, which is fluid (usage percentage), and most importantly, has slots of fixed width. I think this is the only way to make a grid. From the design point of view, shrinking your gutters is a big taboo. You want to be able to control when to change gutters. Then, when responsive design began to appear, it was no longer meaningful to use pixels. My last reason is that I really want something lightweight, which can be used for smaller projects, such as single pages and smaller websites, where it is unnecessary to use a mature framework.

在与 Andri 交谈后,很明显他在构建他的网格时试图实现我们在构建自己的网格时探索的许多内容,然而,在花了更多时间进行工作后,他已经实现了一个完整的 12 列网格(见图 5-2 )。

A978-1-4302-6695-2_5_Fig2_HTML.jpg

图 5-2。

Screenshot of the different grid arrangements shown on the Fluidable web site

在查看 Fluidable grid 是如何构建的过程中,可以看到它为每种不同的设备类型定义元素跨越多少列的能力,这意味着当使用这种技术时,可以轻松控制站点如何向下查看单个设备类型。实现这一点的方法是通过用于元素类名的命名约定:

.col-mb-x Defines how many columns it should span on mobile   .col-x Defines how many columns it should span on a tablet   .col-dt-x Defines how many columns it should span on a desktop  

对于其中的每一个,x代表元素应该跨越的列数。在示例网格中使用了类似的方法,允许移动设备具有不同的网格布局,但是,它没有将平板电脑与桌面分开。Fluidable 没有这个限制,而是提供了三个不同的列类集,如上所列。我对他们实现的唯一不满是列类名的命名约定不一致,tablet 使用了col-x,这还不清楚。

从技术的角度来看,Fluidable 是使用 CSS 预处理器 LESS (leaner CSS [CSS 预处理器将在本书后面讨论])构建的,这意味着如果您通过更改变量的值来使用 LESS,也可以自定义您的网格。Fluidable 可使用五个变量进行配置,即@columns、@maxWidth、@gutterWidth、@ screenTablet 和@screenDesktop,这使得它更加灵活。

CSS 智能电网

下一个电网系统是丹尼尔·瑞恩( http://dryan.github.io/css-smart-grid/ )的 CSS 智能电网。Daniel 最初于 2011 年在 GitHub 上发布了 CSS 智能电网,在九次发布之后,在撰写本文时它已经是 4.0 版了。图 5-3 显示了 CSS 智能电网的主页和文档网站。

A978-1-4302-6695-2_5_Fig3_HTML.jpg

图 5-3。

The CSS Smart Grid home page

我联系了 Daniel,问他为什么选择开发自己的网格系统,而不是使用现有的网格。我创建的网格诞生于 2011 年夏天,是专门为奥巴马竞选而设计的。我们希望首先实现移动化,但当时并没有很多健壮的网格采用这种方法。然后我们遇到了 polyfilling @media 查询对我们来说是一个真正的问题,因为所有的 JavaScript 解决方案都使用 AJAX 来加载和解析 CSS。我们的 CSS 是在一个不支持 CORS 报头的 CDN 上提供的,所以这对我们来说是不可行的。我的最后一个要求是网格必须是轻量级和高性能的。

他提出的最有趣的一点是他过去在多填充媒体查询方面的问题,所以我将解释这是如何作为 CSS 智能网格的一部分进行设计的。

CSS 智能网格设计巧妙,无需 JavaScript polyfill 即可支持 Internet Explorer 8。这是通过使用条件注释将类添加到 HTML 标记来实现的,HTML 标记可用于向 Internet Explorer 8 显示默认的 960 网格。通过使用这种技术,仍然可以使用移动优先的方法来构建网格,并在不需要任何 JavaScript 的情况下为 Internet Explorer 8 提供桌面布局。

已经了解了是什么让这个网格脱颖而出,让我们看看实际的网格,看看网格本身如何与这里正在研究的其他网格系统相比较(见图 5-4 )。

A978-1-4302-6695-2_5_Fig4_HTML.jpg

图 5-4。

Screenshot of the different grid arrangements shown on the CSS Smart Grid site

CSS 智能网格中的列是通过添加类“columns”和附加类来定义的,以指定它应该跨越的列数(例如,一、二、三)。最多支持 12 列。或者,您也可以使用关键字来指定元素的宽度,它们是:

one-fourth: equal to 25 percent or three columns’ width   one-half: equal to 50 percent or six columns’ width   one-third: equal to 33.33 percent or four columns’ width   two-thirds: equal to 66.66 percent or eight columns’ width  

下面是一个实际使用网格的例子。正如您将看到的,定义了一行和两列,每列的宽度都是使用上面讨论的关键字定义的:

<div class="row">

<div class="columns two-thirds">

<p>Lorem ipsum</p>

</div>

<div class="columns one-third">

<p>Lorem ipsum</p>

</div>

</div>

使用这些关键字为您选择如何标记列增加了额外的灵活性,但是,重要的是要注意,在 CSS 中,它的作用就像您简单地使用数字列类名一样。

网格本身是使用 SASS(语法上令人敬畏的样式表)CSS 预处理器构建的,对于 CSS 智能网格,Daniel 提供了将列宽作为“mixin”的选项,而不是使用 HTML 中的类。这样做的好处是 HTML 看起来不那么混乱,因为您不需要在标记中添加那么多的类。然而,这样做的缺点是,因为您是在 CSS 中定义宽度,所以您的元素只能在该特定宽度下工作。相反,如果您要在 HTML 中使用列宽类,您可以简单地通过更改类来更改元素的大小。在这方面,块本身将是一个流体宽度;然后 column 类会简单地给它一个定义的宽度。这使您的代码更加灵活,因为您可以通过简单地更改所使用的列宽类,在不同宽度的多个位置使用相同的代码块。

CSS wizardy-网格

下一个网格是 Harry Roberts 的 CSS wizardy-grids(http://csswizardry.com/csswizardry-grids/)。这是一个移动优先的响应网格,可以在 GitHub 上下载(见图 5-5 )。

A978-1-4302-6695-2_5_Fig5_HTML.jpg

图 5-5。

csswizardry-grids home page

我联系了 Harry Roberts,询问他开发 CSS wizard-grids 背后的原因:

I want a practical answer to a complex question; Most other solutions look complicated. 1

网格非常灵活,与前面讨论的网格相比还有一个额外的好处,就是它允许您定义列是居中还是无间距。这意味着,您可以通过使用一个类来简单地使列居中,而不是尝试均匀地偏移列来使其居中。网格还具有额外的灵活性,允许您在其他列中嵌套列(参见图 5-6 )。

A978-1-4302-6695-2_5_Fig6_HTML.jpg

图 5-6。

Screenshot of the different grid arrangements shown on the csswizardry-grid site

与 CSS 智能网格类似,这个网格系统使用一个类命名约定,将列宽称为分数,例如:

one-half   one-third, two thirds   one-quarter, two-quarters, three-quarters  

这种类命名约定比大量网格系统使用的 span-X 方法更容易阅读。

同样,以类似于 CSS 智能网格的方式,csswizardry-grids 允许您使用 SASS(这是一个 CSS 预处理器,将在本书后面讨论),您可以简单地将列的规则扩展到您自己的 CSS 类选择器,这意味着如果您选择,您可以避免将额外的类添加到 HTML 本身。使用这种方法的优点和缺点与使用 CSS 智能电网的优点和缺点相同。

使用 csswizardry-grids 的一个主要缺点是,它不使用 floats,而是使用 inline 块将列一个接一个地放置,所以如果 HTML 中的列之间有空格,那么在呈现的页面中就会出现多余的空格。有两种常见的方法可以防止这种情况:在元素之间放置 HTML 注释,如下所示:

<div class="one-half">

lorem ipsum

</div><!--

--><div class="one-half">

lorem ipsum

</div>

或者简单地删除列之间的空格,如下所示:

<div class="one-half">

lorem ipsum

</div><div class="one-half">

lorem ipsum

</div>

虽然这是使用内联块的一个缺点,但是使用内联块比使用浮点有几个优点。它允许您使用dir HTML 属性颠倒内容的顺序。这可以添加到一个特定的元素中来定位站点的特定区域,也可以添加到 HTML 元素中来定位整个页面。HTML 属性有两个可能的值:ltr代表从左到右,而rtl代表从右到左的文本。图 5-7 显示了使用dir属性如何影响 CSS wizard-grids。

A978-1-4302-6695-2_5_Fig7_HTML.jpg

图 5-7。

Grid default alignment on the left, the text direction set to “right to left” on the right

使用dir属性有它自己的优点;首先,你可以按照可访问性和搜索引擎优化的重要性来排列你的内容,而不是简单地按照设计来组织你的内容。第二,如果你正在构建一个支持从右到左语言的多语言网站,你可以使用dir属性简单地反转布局。

对网格使用 inline block 的另一个好处是,元素自然具有正确的高度,并且您不必清除浮动。

CSS 框架

除了开源网格系统,还有各种各样的开源网格框架。CSS 框架是典型 CSS 网格系统的扩展,除了提供网格布局之外,它还提供标准的浏览器重置、版式和用户界面元素,您可以使用它们来构建响应性站点。虽然它被称为 CSS 框架,但重要的是要知道,这些 CSS 框架中常见的一些界面元素通常需要框架附带的 JavaScript。

有许多不同的 CSS 框架可用,但是,有两个真正被 web 开发社区所接受:Twitter Bootstrap 和 Zurb Foundation。

CSS 框架中常见的用户界面元素有:

Dropdowns   Button’s and button groups   Forms   Navbar   Breadcrumbs   Pagination   Labels   Badges   Page header   Thumbnails   Alerts   Progress bars   Media object   List group  

通过提供广泛的组件选择,CSS framework 使开发人员的生活更加轻松,因为当他们需要一个公共元素时,他们可以简单地从现有的组件中进行选择,使他们能够将时间集中在站点的外观和感觉上,以及适应他们正在构建的站点的新的自定义组件上。

让我们看看几个最流行的 CSS 框架。

Twitter 引导

Twitter Bootstrap 是一个 CSS 框架,最初由 Mark Otto 和 Jacob Thornton 构建;然而,它已经成为 GitHub 上最受欢迎的项目,有近 600 名贡献者和超过 25,000 个分支。该框架也相当成熟,已经发布了 25 个版本,在撰写本文时已经发布到 3.2.0 版。

显然,Twitter Bootstrap 正在被大量的开发者使用,但是这并没有立即显示出一些使用 Twitter Bootstrap 的网站的规模。包括 Healthcare.gov、Virgin Active 和愤怒的小鸟星球大战 II 的 Tumblr 在内的品牌都在使用 Twitter Bootstrap,并且以非常不同的方式使用,这也表明了该框架是多么通用。

马克·奥托(Mark Otto)为 List Apart ( http://alistapart.com/article/building-twitter-bootstrap )写了一篇文章,谈到了 Twitter Bootstrap 开发背后的原因:

A year and a half ago, a small group of Twitter employees set out to improve our team's internal analysis and management tools. After some early meetings around this product, we set out with greater ambition to create a toolkit for anyone inside or outside Twitter. Therefore, we set out to build a system to help people like us build new projects on this basis, so Bootstrap came into being. 2

马克的这个更高的目标是试图建立一个每个人都可以使用的工具包,这个目标非常成功;Twitter Bootstrap 实现了 Twitter 团队的目标,即它是一个可用于各种项目的工具包,通过开源项目,它为更广泛的开发社区提供了这些好处。

当我们开始深入研究 Twitter Bootstrap 所提供的东西时,从基础开始是很重要的,Twitter Bootstrap 的基础是一个移动优先、响应迅速的网格系统。开箱即用的框架有一个 12 列的网格,分为超小型(移动)、小型(平板电脑/小型上网本)、中型(台式机/笔记本)和大型(大屏幕台式机),以便您能够根据不同的视窗大小完全调整站点。

Twitter Bootstrap 中一些最常用的组件如图 5-8 所示。

Navigation  

A978-1-4302-6695-2_5_Fig8a_HTML.jpg

Buttons  

A978-1-4302-6695-2_5_Fig8b_HTML.jpg

Forms  

A978-1-4302-6695-2_5_Fig8c_HTML.jpg

Typography  

A978-1-4302-6695-2_5_Fig8d_HTML.jpg

A978-1-4302-6695-2_5_Fig8_HTML.jpg

图 5-8。

Twitter Bootstrap components Thumbnails  

这是 Twitter Bootstrap 附带的组件的一个小样本,为了探究它们,您应该看一看 www.getbootstrap.com 来全面了解 Twitter Bootstrap 组件提供了什么。

除了内置组件,web 开发社区还用第三方组件扩展了 Twitter Bootstrap,这些组件可以简单地添加进来。一些流行的附加组件示例如下:

Fuel UX: ( http://exacttarget.github.io/fuelux/ ) Fuel UX extends Bootstrap by adding additional lightweight JavaScript components.   Bootstrap Image Gallery: ( http://blueimp.github.io/Bootstrap-Image-Gallery ) This component adds the ability to have a gallery with a light box that can navigate through a series of images.   Bootstrap Application Wizard: ( http://www.panopta.com/2013/02/06/bootstrap-application-wizard/ ) The Bootstrap Application Wizard component allows you easily to make multipart forms with Bootstrap. These are shown inside a modal that shows above your page.  

这种用其他开源组件扩展 Twitter Bootstrap 的能力使它非常强大。然而,与 jQuery 不同的是,jQuery 有一个用户定制插件的存储库,没有用于引导组件的存储库,这意味着你必须依靠像 Google 这样可靠的搜索引擎来找到这些组件。虽然这不是一个主要的缺点,但它会使找到推荐的组件变得更加困难。

作为开发人员,理解框架是如何构建的是很重要的,因为我们经常希望能够删除我们不使用的部分,这样他们就不会不必要地膨胀我们的站点。使用 Twitter Bootstrap,主项目的构建使用了更少的资源。然而,有一个官方的 SASS 端口,所以当涉及到您使用哪个版本时,您可以选择。我会在第七章单独讨论 CSS 预处理器。

如果你陷入困境,需要 Twitter Bootstrap 的帮助,你可以求助于一个大型的开发人员社区,很可能通过快速搜索,你会发现有人可能已经问过同样的问题,这意味着你可以快速解决你的任何问题。

Zurb 基金会

Zurb Foundation 是一个由 web 设计机构 Zurb 构建的 CSS 框架,于 2011 年 2.0 版首次成为开源。从这个初始版本开始,已经有了三个后续版本,其中 5.3.3 是撰写本文时的版本。

看看谁在使用 Zurb 基金会,我们可以看到许多大型网站都在使用它,包括 Dictionary.com、英国 HTC 在线商店和世界野生动物基金会。

Zurb Foundation 中的组件与 Twitter Bootstrap 中的组件非常相似。简单看一下其中的一些组件,就会发现两者提供的主要组件是相同的,如图 5-9 所示。

Navigation  

A978-1-4302-6695-2_5_Fig9a_HTML.jpg

Buttons  

A978-1-4302-6695-2_5_Fig9b_HTML.jpg

Forms  

A978-1-4302-6695-2_5_Fig9c_HTML.jpg

Typography  

A978-1-4302-6695-2_5_Fig9d_HTML.jpg

A978-1-4302-6695-2_5_Fig9_HTML.jpg

图 5-9。

Zurb Foundation components Thumbnails  

如果你想看看 Zurb Foundation 真正与众不同的地方,那就是它的 Interchange Responsive 内容(或简称 Interchange)。简而言之,Interchange 允许您为特定的媒体查询将 HTML 的不同部分加载到页面中。这意味着,当您构建 HTML 时,您不需要在主页中包含所有视窗宽度的 HTML,而是专注于提供移动优先的 HTML,然后使用 Interchange 加载不同视窗的附加 HTML。此外,Interchange 可用于根据视窗宽度加载不同的图像,因此您可以在较小的视窗中加载较小的优化图像,在较大的视窗中加载较大的图像。

Zurb 基金会不仅仅是 Zurb 开发的开源项目。它还提供付费支持,帮助您充分利用该框架以及培训和资格鉴定。尽管并非所有项目都负担得起这个选项,但它通常被认为对一些公司环境有益。

什么最适合我的网站?

看了 CSS 网格系统和 CSS 网格框架之后,您现在应该对两者的优缺点很熟悉了。当你开始构建一个站点的时候,决定使用哪一个框架或者网格系统是很重要的,因为一旦你的构建有了进展,就很难改变了。

很难改变框架或网格系统的原因是,您已经承诺了代码结构和命名约定,这些都是与您选择的框架或网格一起出现的,因此改变可能意味着需要进行大量的重构。在框架的情况下,您可能也使用了一些用户界面组件,因此改变框架将涉及到寻找替代框架的等价物或在其他地方寻找替代物。

当要在使用 CSS 网格和 CSS 框架之间做出决定时,问自己是否想要预构建用户界面组件是一个简单的问题。您还应该看看除了接口组件之外还提供了什么;像用于排版的基本 CSS 这样的东西可以节省你大量的时间,你可能会发现这会让你使用 CSS 框架而不是 CSS 网格。

重要的是要记住,没有一个放之四海而皆准的解决方案,尽管您可能选择在一个网站上使用网格系统或网格框架,但您可能会发现对于另一个网站,您会做出不同的决定。

CSS 框架经常受到很多批评,也许这是你过去不喜欢的一个原因,那就是它们的文件大小。文件大小背后的原因是 CSS 框架包括许多不同的组件,每个组件都会增加框架的文件大小。为了能够充分利用您选择的框架,您应该尽可能地使用它们。然而,这并不是忽视框架的理由,因为你可以选择在项目中使用框架的哪些部分,你可以简单地删除任何未使用的 CSS 选项,手动或使用自动工具,如后处理器uncss(这将在第七章的中介绍)。

选择 CSS 网格

在决定了网格更适合您,并且您希望能够构建自己的所有组件之后,看看可用的选项是很重要的:

选择网格时,您需要问自己一些问题:

Do you feel comfortable working with the grid? It is important that you feel comfortable with the grid, even small things like how classes are named can be an annoyance if it does not fit with the way you normally code, so it is important that you are 100 percent comfortable with the grid, especially because you may be maintaining the site for a number of years.   Is the grid suitable for your site? Your grid of choice should work for your site. This is especially important if you already have had the site designed without a prior discussion about grids. This means if you want to use a grid, it needs to fit the number of columns for which the site has been designed. Some grid systems will allow you to configure the number of columns they use, which can aid you in trying to get a design to fit into a grid. A better approach is to have chosen the grid before the site is designed and discuss this with the designer so you know your grid is suitable.  

选择 CSS 框架

在决定使用一个 CSS 框架后,确保你选择一个你乐意使用的框架是很重要的——记住你不太可能建立一个你不会再接触的网站,所以你需要做出一个你乐意的选择,因为你可能会在可预见的将来维护这个网站。

选择框架时,您需要问自己一些问题:

Do you like the grid the framework is built on? As previously discussed, the base of a CSS framework includes a grid system, so you have to be comfortable with the grid.   Are you happy with the selection of components that the framework comes with? The user interface components that the framework comes with are a core part of the framework, so it is important that you are happy with the selection. Although you can add your own, using the components that come with the framework will not only make your life easier it can also save you a significant amount of time.   Does the framework suit the way you work and the tools you use? Some frameworks might require you to use specific tools, and it is likely you already have a set of tools you know and love, so you will need to consider this when choosing a framework.  

既不选择网格也不选择框架

也有一些 CSS 网格系统和 CSS 框架都不合适的情况,例如:

The design uses uneven column sizes.   The design has uneven margins in between the columns.   The width of the design is not easily divisible.   The site content is placed on the page in a irregular manor (an example of this could be a parallax site).  

如果你的网站属于这些类别中的任何一个,你很可能会花费大量的时间试图让你的网站适应网格,而不是花时间在没有网格的情况下构建你的网站,但仍然遵循已经讨论过的移动优先的方法。

使用 CSS 框架构建网站原型

传统上,作为网站开发生命周期的一部分,用户经验丰富的设计师会将一系列静态线框放在一起,向客户、设计师和网站开发人员说明网站应该如何工作。连同解释功能的注释,这将是构建网站的基础。最近,已经开发了允许构建交互式线框的应用程序,然而,许多这些应用程序仍然非常局限于简单地将一系列静态图像与链接捆绑在一起。

这是传统网站开发之外的一个领域,使用 CSS 框架可以提供显著的改进。CSS 框架真正的亮点在于能够使用作为框架的一部分提供的组件快速构建网站原型。无需编写一行 CSS 代码,使用包含的组件快速模拟原型是非常容易的。

我们已经探索了一些不同的 CSS 框架,其中之一,Twitter Bootstrap,我们将用于模拟一个网站的原型。

首先,您需要为组件设置一个基本模板。为此,你需要包含 Twitter 的 CSS 框架,可以在 www.getbootstrap.com 下载。对于基本模板的 HTML,你只需要一些基本的 HTML,包括 jQuery、Twitter Bootstrap CSS 和 JavaScript。输入清单 5-1 中的代码。

清单 5-1。基本模板 HTML

<!DOCTYPE html>

<html>

<head>

<title>Prototype</title>

<meta name="viewport" content="width=device-width">

<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">

</head>

<body>

<script src="http://code.jquery.com/jquery-1.10.1.min.js

<script src="js/bootstrap.min.js"></script>

</body>

</html>

有了这些,现在可以开始用 Twitter 引导组件构建原型了。为此,您将从 Twitter Bootstrap 文档中提取模块的代码片段,并在适当的地方缩短它们。

您将包含的第一个元素是一个navbar。Twitter Bootstrap 文档中的navbar模块包括下拉框和搜索表单,然而,在本例中,您将包括一个简化版本,如清单 5-2 所示。

清单 5-2。原始资料改编自 http://getbootstrap.com/components/#nav 的文档

<header>

<nav class="navbar-default" role="navigation">

<div class="container">

<!-- Brand and toggle get grouped for better mobile display -->

<div class="navbar-header">

<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">

<span class="sr-only">Toggle navigation</span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

<span class="icon-bar"></span>

</button>

<a class="navbar-brand" href="#">Prototype</a>

</div>

<!-- Collect the nav links, forms, and other content for toggling -->

<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

<ul class="nav navbar-nav">

<li class="active"><a href="#">Link</a></li>

<li><a href="#">Link</a></li>

<li><a href="#">Link</a></li>

</ul>

</div><!-- /.navbar-collapse -->

</div>

</nav>

</header>

正如当你建立一个响应式网站时,你首先建立的是这个原型手机,所以第一站是在一个额外的小设备上测试导航,如图 5-10 所示。

A978-1-4302-6695-2_5_Fig10_HTML.jpg

图 5-10。

Testing the navigation on an extra small device

如果你现在在桌面浏览器中测试同样的导航,你会得到一个全幅导航,如图 5-11 所示。

A978-1-4302-6695-2_5_Fig11_HTML.jpg

图 5-11。

The navigation shown on a larger viewport, showing the full-sized navigation

无需编写任何 CSS 或 JavaScript,您现在就拥有了一个在移动设备上响应迅速、折叠自如的导航。

接下来,您要添加超大屏幕组件,它本质上是一个大的功能标题区域,有时被称为 hero。键入清单 5-3 中的代码来添加这个组件。

清单 5-3。原始资料改编自 http://getbootstrap.com/components/#jumbotron 的文档

<section class="jumbotron">

<div class="container">

<h1>Prototype</h1>

<p>This is our prototype</p>

<p><a href="#" class="btn btn-primary btn-lg" role="button">Learn more</a></p>

</div>

</section>

如果您现在在我们的超小型设备上再次测试,标题看起来更完整。通过简单地放入超大屏幕组件,你已经为页面添加了一个标题和一个主要的行动号召,如图 5-12 所示。

A978-1-4302-6695-2_5_Fig12_HTML.jpg

图 5-12。

The extra small viewport of the site featuring the jumbotron

当您查看原型现在如何显示在桌面上时,您可以看到 Twitter Bootstrap 超大屏幕组件以更大的版式响应更宽的视窗,如图 5-13 所示。

A978-1-4302-6695-2_5_Fig13_HTML.jpg

图 5-13。

The jumbotron viewed on a wide viewport

接下来,您将添加一些面板来展示您网站的产品。对于图像,您将使用一个名为lorempixel.com的服务,它将显示一个随机图像作为占位符。对于产品,使用缩略图组件,如清单 5-4 所示。

清单 5-4。原始资料改编自 http://getbootstrap.com/components/#thumbnails-custom-content 的文档

<section class="container">

<div class="row">

<div class="col-sm-4">

<div class="thumbnail">

<img src="http://lorempixel.com/400/200/

<div class="caption">

<h3>Product one</h3>

<p>...</p>

</div>

</div>

</div>

<div class="col-sm-4">

<div class="thumbnail">

<img src="http://lorempixel.com/400/200/

<div class="caption">

<h3>Product two</h3>

<p>...</p>

</div>

</div>

</div>

<div class="col-sm-4">

<div class="thumbnail">

<img src="http://lorempixel.com/400/200/

<div class="caption">

<h3>Product three</h3>

<p>...</p>

</div>

</div>

</div>

</div>

</section>

缩略图组件就绪后,您现在可以刷新浏览器,主页的原型现在看起来已经完成。为了让您能清楚地看到产品模块,我在图 5-14 中展示了这些模块在我们的超小型设备上的外观。

A978-1-4302-6695-2_5_Fig14_HTML.jpg

图 5-14。

The product panels viewed on a small device

同样,当你在桌面上查看原型时,你可以看到网站现在使用了三栏,而不是使用一栏来显示产品,如图 5-15 所示。

A978-1-4302-6695-2_5_Fig15_HTML.jpg

图 5-15。

Larger device showing the product panels alongside one another

之所以有三列,是因为您选择了使用列类col-sm-4,这意味着每一列跨越了组成网格的十二列中的四列(这是页面宽度的三分之一)。使用这些引导组件的好处是,您可以使用列类来定义它们在不同浏览器宽度下的外观。只需将类别更改为col-sm-3并添加一个额外的产品框,就会并排显示四个产品,如图 5-16 所示。

A978-1-4302-6695-2_5_Fig16_HTML.jpg

图 5-16。

Four product columns shown on larger device

正如刚才演示的那样,不需要编写任何 CSS,只需修改文档中的 HTML,使用 CSS 框架创建一个原型真的很容易。虽然这是一个非常简单的例子,但它确实突出了 CSS 框架必须提供的一些好处。构建原型比花时间创建线框有几个主要好处:

Those using the prototype can get a feel for how the site will work rather than relying on the notes attached to the wireframe.   By using a responsive CSS framework, your prototype is by default responsive, allowing you to show how the site will function on different devices.   Rather than starting from scratch when building the site, you might be able to build on top of the prototype.  

按照这里的第 2 点,已经使用响应式 CSS 框架构建了这个原型,您已经能够构建完全响应的原型。这使得这个原型的用户可以快速看到他们应该如何期望最终的网站能够跨各种设备工作。

摘要

本章研究了 CSS 网格系统和 CSS 框架,特别关注在哪里可以使用它们,以及它们可以给你的响应式设计项目带来的好处。

本章考察了选择最适合您的项目的网格或框架的重要性,而不是将其建立在对特定框架的忠诚感上。最重要的方面是网格或框架相对于您的需求的灵活性。

CSS 框架特别有用的一个领域是当你想要建立一个网站的原型时,这一章探讨了如何通过简单地改编来自 Bootstrap 网站的 HTML 例子并把它们放在一起制作一个页面来快速建立一个网站的原型。这是非常强大的,因为这意味着你可以构建一个工作原型,然后利益相关者可以自己测试交互,而不是构建平面的用户体验图,然后解释各种交互。这个原型可能会成为构建整个网站的基础。

在下一章中,我们将探讨如何使一个现有的网站具有响应性。

Footnotes 1

哈里·罗伯茨,2014 年 1 月 17 日,推特@csswizardry。

  2

马克·奥托,《与众不同的清单》, 2012。

六、改编现有网站

到目前为止,本书的章节已经讨论了如何从站点响应的角度出发,从头开始构建一个新站点。然而,从头开始构建可能并不总是一种选择,并且已经放弃了为移动使用构建单独的站点,很可能您会想要调整您现有的站点和代码库以做出响应。为此,有三个选项可供选择:

Adapt the current styles   Refactor the code to be mobile first   Do a full reskin  

在这三个选项中,您选择的方法取决于您站点的具体情况,因为每个选项都有自己的优缺点。本章将通过一个例子来研究每一种不同的方法,这样你就可以清楚地看到修改一个现有的站点使之具有响应性所涉及的步骤,之后你就可以选择最适合你的项目的方法了。

在这一章中,我为一个虚构的公司制作了一个没有响应的站点,我称之为没有响应的设计公司,我将用它来演示将一个现有站点转换为有响应的站点的不同方法。它包含在本书网站的代码包中( www.apress.com )。你可能想在你的电脑上按照我提供的说明进行操作。

改编现有的样式和脚本

调整站点的三种方法中的第一种是保留现有的 HTML,并调整现有的样式和 JavaScript,以便它们通过添加媒体查询来响应设备视口。

这种方法是一种桌面优先的方法,因此您会优雅地降低较小设备的体验。降低网站内容质量的方法有很多,第一种方法是简单地隐藏不太重要的内容,并重新排列剩余的内容,使其适合较小设备的屏幕,这两种方法都可以单独使用 CSS 来实现。这种方法的好处是可以相对快速地完成,但是,您认为不太重要的内容可能对您的一个或多个用户很重要。第二种方法是使用 CSS 来调整内容,使其在网站上更好地工作,并在适当的时候使用 JavaScript 来改变用户与内容的交互方式。这两种方法的总体目标都应该是提供比用户在较小的设备上直接使用桌面站点更好的体验。

通过采用调整当前样式的方法,您可以保持现有的样式不变,而不是使用媒体查询来定位在网站开始崩溃的地方覆盖现有样式的样式。

这种方法带来的一个好处是,现有的代码库可能已经过浏览器测试。这反过来会减少你遇到尚未修复的浏览器特有错误的可能性。在不支持媒体查询的浏览器中,网站看起来与修改前一样。在浏览器支持媒体查询的情况下,你可以集中精力在你添加的新断点上测试站点,而不是在重新换肤过程中引入的错误。

这种方法的一个主要缺点是,您正在调整的原始桌面站点可能已经有了臃肿的代码库,遗留或冗余的代码导致了效率低下。通过调整一个已经臃肿的网站,您可能会使问题变得更糟,并且可能会因为在连接速度较慢的设备上加载更多代码而面临性能问题。在这种情况下,您可能希望在着手提高站点的响应能力之前减少这些低效问题。实现这一点的方法之一是移除任何未使用的 CSS 选择器,这些选择器可能是站点的旧版本遗留下来的。有很多工具可以用来实现这一点,其中之一是 Firefox 插件 Dust-Me Selectors ( https://addons.mozilla.org/en-US/firefox/addon/dust-me-selectors/ ),它将扫描您的网站并找到任何未使用的 CSS。

采用这种方法的另一个问题是,在许多情况下,浏览器仍然会在较小的设备上下载较大的图像。蒂姆·卡德勒克进行了测试,看看在什么情况下浏览器会下载图像( http://timkadlec.com/2012/04/media-query-asset-downloading-results/ )。在他测试的几乎所有浏览器中,他发现对于包含在页面中的图片。img 元素,浏览器将下载图像,即使 CSS 指定它不应该显示。此外,他还发现,如果背景图像被设置为 CSS 中的元素,并且媒体查询指定该元素不应被显示,则图像仍然会被下载。但是,有一种方法可以防止背景图片加载。在进一步的测试中,Tim 发现如果在想要隐藏的元素的父元素上使用display: none,背景图片将不会被下载。因此,如果你想隐藏背景图像,这是你需要采取的方法。

就像简单地更新一个站点一样,当修改现有的样式时,确保您保持现有的编码样式是很重要的。这样做的原因是样式必须保持一致,包括类名使用相同的命名约定,字体大小使用相同的单位。

了解了为网站调整现有 CSS 和 JavaScript 的优缺点后,让我们来看一个例子,看看在构建一个响应式网站时如何做到这一点。第一步是看看现有的网站,并确定到底需要改变什么。我已经为我虚构的公司示例提供了一个基本模板的截图,这样你就可以开始看到改进它的可能方法(见图 6-1 )。

A978-1-4302-6695-2_6_Fig1_HTML.jpg

图 6-1。

The fixed width site that will be make responsive

定义断点

在查看了我想要修改以提高响应性的原始站点之后,我需要决定一组断点,使其能够在各种设备上工作。对于这个网站,我将添加两个断点:第一个是针对平板电脑等小型设备,第二个是针对手机等超小型设备。

对于第一个断点,我想尝试缩小现有的网站,以便它能舒适地适合小型设备。我想添加一个断点,以便当现有的网站不再适合在视窗中,它可以切换到网站的较小版本。为了实现这一点,断点需要在水平滚动条由于站点太宽而被迫出现之前中断。为此,我需要考虑到网站的宽度加上垂直滚动条的宽度。不幸的是,滚动条的宽度可以根据包括操作系统和浏览器在内的许多因素而变化,所以我将计算站点宽度加上20px的断点。这意味着,对于这个特定的站点,该站点将在1000px有一个断点。当我在这个例子的后面提到这个断点时,我将把它称为小断点。此断点的代码是:

@media screen and (max-width: 1000px){

}

下一个断点需要以移动设备为目标。由于设备种类繁多,尺寸和屏幕分辨率各不相同,很难说平板电脑尺寸的界限和移动设备尺寸的界限。因此,在使用媒体查询确定将什么归类为移动设备时,您需要做出判断。一个很好的起点是查看您希望支持的一些平板电脑的纵向宽度。最容易找到这些信息的地方是 www.viewportsizes.com ,它允许你找到关于不同视窗宽度的信息。使用这个站点,您可以查看一些最常见的平板电脑的视窗宽度,以确定您想要将什么定义为移动断点。你可能会看到苹果的 iPad,其纵向视窗宽度为768px,以及微软的 Surface,其纵向视窗宽度也为768px。因此,如果768px对于平板电脑来说很常见,您可以将移动设备的断点设置为767px,因为这比平板电脑少 1px。当我在这个例子的后面提到这个断点时,我将把它称为额外的小断点。此断点的代码是:

@media screen and (max-width: 767px){

}

排印

现有的排版对于大多数设备来说是一个很好的尺寸,但是,对于超小型设备来说就有点太大了,所以你需要给你的标题添加一些样式。为此,您需要查看已经使用的基本字体大小,以便能够正确计算字体大小值。这方面的代码应该是:

@media screen and (max-width: 767px){

h1{

font-size: 22px;

font-size: 1.571em;

}

h2{

font-size: 18px;

font-size: 1.286em;

}

}

包装材质

调整了字体大小后,现在需要调整包装的宽度,使其不会超出设备视窗的边界。为此,您需要决定您的站点应该如何跨越您定义的不同断点。第一个断点是小断点,它被定义为具有1000pxmax-width。如前所述,这是针对现有桌面站点和移动站点之间的设备的断点。对于这个断点,您可以将站点包装器的宽度设置为710px,因为站点需要在从768px1000px的视口中工作,这包括滚动条。你还需要考虑 20px 左右的填充。此断点的代码应该是:

@media screen and (max-width: 1000px){

.wrapper{

width: 710px;

}

}

当你下到额外的小视口时,让站点有一个流动的宽度是有意义的。这有几个原因,首先是在这些较小的设备上,您想要尝试利用浏览器视窗宽度的每个像素来显示内容,并且您不能承受在边缘周围有多余的空间。第二个原因是在320px767px之间,用于查看网站的屏幕宽度有很大的变化。因此,您需要尝试为所有这些宽度提供优化的体验。为了使您能够在这些额外的小视口设备上制作包装流体,您需要将宽度设置为 100%。设置后,您会注意到包装器仍然比视口宽。这是因为您对包装应用了填充。为移动站点保留这种填充是有意义的,因此与其删除它,不如使用box-sizing属性允许你在 100%宽度中包含填充。在第四章的中,我讨论了对通用(*) CSS 选择器应用盒子大小;不幸的是,因为这是一个现有的代码库,所以在全球范围内应用是不实际的,因为您可能会破坏一些现有的样式。这就是为什么当你修改现有的 CSS 时,你应该根据具体情况来调整盒子的大小。超小视口包装器的最终样式是:

@media screen and (max-width: 767px){

.wrapper{

width: 100%;

-moz-box-sizing: border-box;

-webkit-box-sizing: border-box;

box-sizing: border-box;

}

}

(电视机的)超大屏幕

如果在我进行的过程中,你和我一起测试过你的浏览器,你会注意到超大屏幕目前正在扩展到网站的包装之外。如果您查看大屏幕的现有 CSS 来了解为什么会发生这种情况,您将会看到大屏幕的宽度被设置为940px。显然,媒体查询需要根据不同设备上的大屏幕显示效果进行调整。

对于这个小断点,您只需要调整大屏幕的大小,使其适合包装器。因为包装器是710px宽,您需要使用以下代码调整大屏幕以匹配710px宽:

@media screen and (max-width: 1000px){

.jumbotron{

width: 710px;

}

}

然而,当遇到额外的小断点时,你需要做更彻底的改变,因为大屏幕的内容将不再适合现有的布局。您需要调整布局,以便在一个额外的小设备上观看时,大屏幕上的内容可以堆叠起来。要实现这一点,第一步是设置大屏幕,使其填充包装纸,让包装纸填充任一侧:

@media screen and (max-width: 767px){

.jumbotron{

width: 100%;

height: auto;

text-align: center;

padding: 20px 0;

}

}

如果你看一看大屏幕的原始位置,你会看到里面的元素都被绝对定位,这意味着在改变宽度和改变高度为auto之后,这个网站看起来真的很破。这可以通过重置元素的位置和宽度来解决:

@media screen and (max-width: 767px){

.jumbotron img,

.jumbotron p,

.jumbotron h2,

.jumbotron .roundal,

.jumbotron .roundal span{

position: static;

left: auto;

right: auto;

bottom: auto;

top: auto;

width: auto;

}

}

让超大屏幕在这些超小型设备上看起来合适的最后一步是调整标题文本,使字体大小更适合移动设备。此外,为了使标题文本不会靠近大屏幕的边缘,您可以在标题文本中添加填充:

@media screen and (max-width: 767px){

.jumbotron h2{

font-size: 22px;

font-size: 1.375em;

padding: 10px 20px;

}

}

如果你现在看着超小型设备上的大屏幕,你会看到信息更加清晰(见图 6-2 )。

A978-1-4302-6695-2_6_Fig2_HTML.jpg

图 6-2。

Our slimmed down site for the Jumbotron

制品

下一步是调整产品,使它们在各种断点处看起来都很棒。首先,你应该从决定它们在小型设备上的外观开始。要确定这一点,您需要考虑现有内容是否适合现有结构,或者您是否需要调整布局。调整布局可能很简单,只需将三列布局改为两列布局,也可能意味着将布局改为宽度可变的单列。然而,在这个例子中,在这个小的断点上,通过简单地将三个产品元素的宽度改为223px,现有的布局和内容可以很好地适应现有的三列结构:

@media screen and (max-width: 1000px){

.product{

width: 223px;

}

}

调整小型设备以继续使用三列,尽管宽度更小,下一步是研究如何调整产品元素以在超小型设备上工作。此时,视口变得太小,无法继续在三列中显示产品,当使用额外的小断点时,您使用的是一个流体宽度,因此有必要更改产品元素,使它们不再在列中,而是相互堆叠。为此,您需要将产品元素的宽度调整为 100%。此外,您可能希望确保产品之间有一个清晰的分隔线,这可以通过填充和边框来实现:

@media screen and (max-width: 767px){

.product{

width: 100%;

padding: 20px 0px;

border-top: 1px solid #ccc;

}

}

添加了填充和边框后,第一个产品现在在顶部有了一个额外的边框和额外的填充,因此您可以使用:first-child选择器来定位第一个产品并移除多余的填充和边框:

@media screen and (max-width: 767px){

.product:first-child{

border-top: 0px;

padding-top: 0px;

}

}

类似地,在最后一件产品下面显示了额外的多余填充,因此可以通过使用:last-child选择器瞄准最后一件产品并移除多余的填充来移除:

@media screen and (max-width: 767px){

.product:last-child{

padding-bottom: 0px;

}

}

如果你现在看看这些产品是如何堆叠的,你会注意到它们工作得相当好,如图 6-3 所示。

A978-1-4302-6695-2_6_Fig3_HTML.jpg

图 6-3。

Slimmed down product panels

结论

在对站点进行适应性修改后,您现在拥有了一个可以在各种不同设备上运行的站点。以这种方式修改网站既有好处也有坏处,我现在将讨论它们,这样当涉及到您自己的网站时,您可以决定简单地修改您现有的网站是否适合您的需要。

当你调整大屏幕时,你可能已经注意到了一个主要问题,那就是当你把网站降级到更小的设备上时,你有时需要覆盖大量的样式来为移动设备提供良好的体验。虽然在这个例子中它相对简单,但是一个更大的站点可能需要你做更多的样式覆盖。无论您是先在移动设备上工作,还是先在桌面上工作,您总是会覆盖上一个断点的一些样式。通常一个移动优先的站点是建立在每个断点已经存在的基础上的,但是像这样一个桌面优先的站点,有时必须将值重置回它们的浏览器默认值会使代码库更加臃肿。

在这个例子中,简单地修改站点的好处是桌面站点的样式不需要改变,这意味着焦点可以是正在添加的新断点。这不仅节省了开发时间,还有助于简化测试,因为我们知道,在大多数情况下,我们发现的错误会被引入到我们的媒体查询中。

重构

改造现有网站的第二种方法是首先重构现有的代码库,使其具有可移动性。这里的好处是,你不必从头开始的风格。您还可以对网站设计进行调整,并在重构过程中删除多余的代码。

定义断点

作为站点重构的第一步,您需要在面向大型设备的媒体查询中包装当前用于样式化站点的现有样式,例如站点已经支持的桌面浏览器。要为此选择合适的媒体查询,请查看网站的现有样式以确定其宽度。如果你看看我们正在制作的示例站点的代码,你会看到主包装器有940px宽,加上左右两边的20px填充,总共有980px宽。考虑到滚动条,因此您将设置媒体查询来检查最小宽度1024px:

@media screen and (min-width: 1024px){

}

使用这个媒体查询来包装现有的样式,没有样式被应用到宽度小于1024px的任何视口。从这一点开始,我将把这个断点称为中间断点。

您还希望能够调整站点,以在比站点当前支持的更大的视口尺寸上工作,在这种情况下,您需要添加一个针对这些更大视口的额外断点:

@media screen and (min-width: 1200px){

}

除了已经定义的较大媒体查询之外,您可能还想为小型设备(如平板电脑)添加一个额外的媒体查询。此媒体查询将使您能够利用平板设备提供的较大视窗,为此,您将把 iPad 的较小宽度作为这些小型设备的突破点:

@media screen and (min-width: 768px){

}

重构现有样式

定义了断点之后,现在可以重构现有的样式了。您已经将所有现有的样式移动到一个断点中,因此这意味着在小于1024px的设备上,将不会显示任何样式,如图 6-4 所示。

A978-1-4302-6695-2_6_Fig4_HTML.jpg

图 6-4。

No styles are shown on smaller devices

此时,您可以开始迁移当前针对较大州的样式,以便它们可以在全球范围内使用。您可以很容易地找出全球可用的样式,这些样式应用了不管断点如何都会使用的字体和通用间距。

在示例站点的情况下,站点使用默认的浏览器字体,所以不需要修改字体。该站点不对元素类型应用任何通用间距,但是有一个用于清除浮动的clearfix助手类。这对于在媒体查询之外可用是有意义的,因为在较小的设备上也需要它。

移动任何通用样式后,下一步是查看站点的不同部分,看看可以在哪里获取现有样式并将其应用到较小的视口,在此过程中重构它们。

让我们从站点的主包装器开始这个重构过程。应用的填充和边距可以很容易地从媒体查询中提取出来。其他样式特定于较大的视口尺寸,因此让我们将它们留在原来的位置:

.wrapper{

padding: 0 20px 20px;

margin: 0 auto;

}

页眉

下一步是查看标题样式,看看哪些样式可以用于较小的设备。在本例中,应用于页眉的现有样式只是间距和底部边框。将它们从媒体查询中移出是有意义的,这样它们就可以被其他视口大小访问。将要移动的样式如下所示:

.global-header{

margin: 0 0 20px;

border-bottom: 1px solid #ccc;

}

如果您在浏览器中查看标题,您会看到它现在已经应用了一些基本样式。但是,由于在此阶段没有对字体大小进行任何处理,标题文本显得相当大(如图 6-5 所示)。

A978-1-4302-6695-2_6_Fig5_HTML.jpg

图 6-5。

The site header, with no font sizes applied

为了纠正这一点,让我们向h1元素添加样式,以设置字体大小并使文本居中对齐:

h1{

font-size: 1.4em;

text-align: center;

}

现在,当你在浏览器中查看时,字体大小更适合较小的视窗,如图 6-6 所示。

A978-1-4302-6695-2_6_Fig6_HTML.jpg

图 6-6。

The site header, with the font size and alignment applied

(电视机的)超大屏幕

这个网站的下一个需要关注的元素是大屏幕。大屏幕的原始 CSS 有 35 行长,大部分只适用于较大的视窗宽度,所以仔细看看什么是合适的是很重要的。为此,我在下面包含了原始的超大屏幕 CSS,并突出显示了您可能想要用作较小设备上的超大屏幕的起点的行:

.jumbotron{

position: relative;

background: #f4a156;

width: 940px;

height: 250px;

margin-bottom: 20px;

}

.jumbotron img{

position: absolute;

left: 0px;

top: 0px;

}

.jumbotron h2{

position: absolute;

left: 260px;

top: 20px;

font-size: 3em;

width: 300px;

margin: 0px;

}

.jumbotron .roundal{

position: absolute;

right: 0px;

bottom: 0px;

}

.jumbotron .roundal span{

position: absolute;

right: 20px;

bottom: 20px;

font-size: 2em;

}

从上面选取 CSS 中突出显示的行,然后就剩下生成的 CSS:

.jumbotron{

background: #f4a156;

margin-bottom: 20px;

}

.jumbotron h2{

margin: 0px;

}

如果你现在在浏览器中查看大屏幕,你会看到你已经有了样式的开始,如图 6-7 所示。

A978-1-4302-6695-2_6_Fig7_HTML.jpg

图 6-7。

The Jumbotron with this base CSS in place

您将会注意到,大屏幕的橙色背景并没有像您预期的那样在整个视窗中延伸。这是因为您使用的包装器在站点的两侧应用了一致的间距。为了使您能够保持一致的间距,但将背景扩展为全幅,您可以使用负边距。要在大屏幕上添加一致的间距,只需应用填充即可。此外,您可能希望文本居中对齐。这显示在下面的 CSS 中:

.jumbotron{

background: #f4a156;

margin:  0 -20px 20px;

padding:  20px;

text-align: center;

}

字体大小也特别大。这是因为第二级标题的字体大小尚未针对较小的视窗进行设置,因此它们现在应该设置为适当的大小。既然一级标题设置为 1.4em,那么二级标题也应该设置为1.3em。您也不希望在超大屏幕中的第二级标题上方有额外的间距,所以专门为这个超大屏幕将页边距顶部设置为0px

h2{

font-size: 1.3em;

}

.jumbotron h2{

margin-top: 0px;

}

在这个位置,大屏幕现在看起来是完整的,如图 6-8 所示。

A978-1-4302-6695-2_6_Fig8_HTML.jpg

图 6-8。

The complete Jumbotron

产品面板

下一步是为产品面板构建样式。用于较大视口中这些面板的大多数样式也可以用于较小视口中这些面板的样式。和以前一样,我突出显示了下面的 CSS 代码行,这些代码行可用于简单地将其移出媒体查询:

.product{

float: left;

width: 300px;

padding-left: 20px;

text-align: center;

}

.product:first-child{

padding-left: 0px;

}

.product .roundal{

width: 100px;

height: 75px;

margin: 0 auto;

background: #f4a156;

border-radius: 50px;

padding-top: 25px;

}

.product .roundal span{

display: block;

font-size: 1.6rem;

}

.product ul{

padding: 0px;

}

.product li{

list-style: none;

font-size: 0.8rem;

color: #333;

}

.product a{

font-size: 0.9rem;

color: #000;

text-decoration: none;

display: inline-block;

background: #ccc;

padding: 5px 10px;

border-radius: 2px;

}

.product a:hover, .product a:focus, .product a:active{

background: #999;

color: #eee;

}

.product *:first-child{

margin-top: 0px;

}

.product *:last-child{

margin-bottom: 0px;

}

将突出显示的 CSS 移到媒体查询之外后,现在需要添加一些额外的填充和边框来完成产品面板。为了使边框两边都有间距,在每个产品面板的顶部和底部添加 20px 的填充。然后将边框应用到产品面板的底部:

.product{

text-align: center;

padding: 20px 0px;

border-bottom: 1px solid #ccc;

}

这样,确保你在第一个面板上没有太多的空间。仅移除第一个产品面板的衬垫,这将使用:first-child选择器进行定位:

.product:first-child{

padding-top: 0px;

}

准备好之后,看看产品面板在浏览器中的样子,如图 6-9 所示。

A978-1-4302-6695-2_6_Fig9_HTML.jpg

图 6-9。

The product panels on a smaller device

你需要看的 CSS 的最后一部分是页脚。让我们从查看当前应用于更大的媒体查询中的页脚的 CSS 开始。我突出显示了 CSS 中有意义的行,以便将其置于媒体查询之外,这样它就可以应用于额外的小视窗及以上:

.global-footer{

margin: 20px 0;

border-top: 1px solid #ccc;

}

.global-footer p{

text-align: center;

font-size: 0.8rem;

}

不需要为页脚再写任何 CSS,完成的页脚如图 6-10 所示。

A978-1-4302-6695-2_6_Fig10_HTML.jpg

图 6-10。

The finished footer on extra small devices

针对不同的断点

在这一点上,该网站在超小型设备上运行良好,但我们还没有考虑它在小型或大型设备上的外观。也有可能是因为添加了新的样式,我们打破了原来的(中等)布局。让我们先把浏览器的宽度增加到一个小设备的大小,看看网站看起来怎么样,如图 6-11 所示。

A978-1-4302-6695-2_6_Fig11_HTML.jpg

图 6-11。

The site shown on a small device

现在,在小型设备上看到网站的样子后,您会注意到堆叠的产品面板周围有很多空间,可以通过将产品一个接一个地排成一行来更好地利用这些空间。这与原始无响应站点的行为方式相同,但是,您可以应用一个流体宽度,而不是为产品面板设置一个固定的宽度。因为这里需要三列,所以可以将宽度设置为33.33%。要让面板并排放置,请应用一个浮动并移除元素顶部的填充。最终的代码如下所示:

.product{

width: 33.33%;

padding-top: 0px;

float: left;

}

如果你在你的浏览器中检查这个,面板现在应该是并排的,如图 6-12 所示。

A978-1-4302-6695-2_6_Fig12_HTML.jpg

图 6-12。

The product panels on a small device

如果您继续增加视窗大小,直到达到中等视窗宽度,您会注意到站点的页眉和超大屏幕都被破坏了。这是因为您应用于早期断点的样式。我已经在图 6-13 中展示了割台和大屏幕是如何损坏的。

A978-1-4302-6695-2_6_Fig13_HTML.jpg

图 6-13。

The medium breakpoint with the broken Jumbotron

作为重构的一部分,您可以选择对网站的设计进行修改,在本例中,您将对页眉和大屏幕都进行修改。第一步,看表头;目前 CSS 已经将样式应用于h1使其向左浮动,CSS 是:

.global-header h1{

float: left;

}

如果不想让它向左浮动,可以去掉这个样式。然而,你想增加字体大小,但是你用和移动站点一样的方式应用字体大小是有意义的,移动站点直接在h1上。更改字体大小的新样式如下所示:

h1{

font-size: 2rem;

}

有了这个地方,下一步是看大屏幕。首先,让我们看看当前应用于大屏幕的 CSS。第一部分是包含大屏幕主元素的 CSS,这个元素上的类是jumbotron。现有的 CSS 是:

.jumbotron{

position: relative;

width: 940px;

height: 250px;

}

正如你会注意到的,大屏幕有一个定义为940px宽的值集。因为我们希望大屏幕始终与包装一样宽,所以您可以简单地删除宽度,这样 CSS 现在看起来就像:

.jumbotron{

position: relative;

height: 250px;

}

下一步是定位图像。虽然您可以重构 HTML 来使用基本的网格并使用它来构建超大屏幕,但为了简单起见,让我们简单地使用绝对定位来定位超大屏幕的内容。现有样式当前定位图像,因此它绝对位于左上角:

.jumbotron img{

position: absolute;

left: 0px;

top: 0px;

}

但是我们想把图像放在大屏幕中心的左边。为此,您应该将选择器的 left 属性的值设置为 50%。然后,您可以使用与图像宽度相等的负边距将其向左拉。您还想将顶部向下凸起,给它一点额外的空间,所以让我们将顶部设置为 20px:

.jumbotron img{

position: absolute;

left: 50%;

top: 20px;

margin-left: -250px;

}

下一步是设计大屏幕的标题。它目前的样式绝对定位它,所以它坐在旁边的图像的原始位置。因为我们改变了图像的位置,所以您还需要调整标题的位置,使其仍然位于图像旁边。要做到这一点,请将标题放在大屏幕中心的右侧。当前的 CSS 是:

.jumbotron h2{

position: absolute;

left: 260px;

top: 20px;

font-size: 3rem;

width: 300px;

margin: 0px;

}

要获得想要的效果,只需更改左侧,使其为 50%:

.jumbotron h2{

position: absolute;

left: 50%;

top: 20px;

font-size: 3rem;

width: 300px;

margin: 0px;

}

下一步是在大屏幕上定位定价。您希望它出现在标题文本的下方,所以让我们使用相同的技术来使文本偏离中心。我们已经在使用绝对定位,所以你只需要改变位置。现有的 CSS 是:

.jumbotron .roundal{

position: absolute;

right: 0px;

bottom: 0px;

}

首先,将左侧的定位设置更改为 50%,然后将底部设置更改为50px。这将使文本直接位于标题下方。更新位置后,增加字体大小使其更加突出,在这种情况下,让我们将字体大小增加到2rem:

.jumbotron .roundal{

position: absolute;

left: 50%;

bottom: 50px;

width: 300px;

font-size: 2rem;

}

最后,您可以简单地删除下面的样式,这些样式最初定位在roundel内的跨度,但是不再需要:

.jumbotron .roundal span{

position: absolute;

right: 20px;

bottom: 20px;

font-size: 2rem;

}

调整了标题样式和大屏幕样式后,让我们在浏览器中查看它们,如图 6-14 所示。

A978-1-4302-6695-2_6_Fig14_HTML.jpg

图 6-14。

The completed header and footer

除了页眉和大屏幕,网站的页脚也有问题,因为它有一个额外的边框显示,如图 6-15 所示。

A978-1-4302-6695-2_6_Fig15_HTML.jpg

图 6-15。

The double border issue on the medium breakpoint

这是因为产品的底部添加了边框,但是较大的视窗的页脚顶部已经添加了边框。要解决此问题,只需从样式表中删除以下样式:

.global-footer{

margin: 20px 0;

border-top: 1px solid #ccc;

}

现在,如果你在浏览器中再次查看,你会看到这条线已经被删除,如图 6-16 所示。

A978-1-4302-6695-2_6_Fig16_HTML.jpg

图 6-16。

The fixed footer for the medium breakpoint

这完成了中等断点,但是作为使站点响应的一部分,您还想利用较大显示器上的可用空间。前面我讨论了用于实现这一点的媒体查询,但是现在让我们来看看调整站点所需的 CSS。

因为到目前为止构建的所有东西在固定宽度的包装器中都是流动的,所以只需改变这个包装器的宽度,就可以为更大的视口调整站点。在某些情况下,您可能想通过做更多的事情来利用额外的空间,但是对于这个例子,让我们简单地调整包装器。当大断点在1200px处中断时,您会希望将包装器的宽度设置为1170px宽,以便为滚动条留出空间。为此,只需将以下 CSS 放入大型媒体查询中:

.wrapper{

width: 1170px;

}

加载完成后的页面,视口大于等于1200px将显示新的更宽的站点,如图 6-17 所示。

A978-1-4302-6695-2_6_Fig17_HTML.jpg

图 6-17。

The completed refactored site shown on a large viewport

全 Reskin

修改现有网站的第三种方法是保留现有的大部分 HTML,但是抛弃现有的 CSS,重新开始。

选择使用完整的 reskin 方法有好处也有坏处,关键的好处是,通过重新启动 CSS 并根据需要重构 HTML,您可以克服在站点的生命周期中可能已经蔓延到 CSS 中的任何低效问题。此外,因为您将替换现有的 CSS,所以您可以采用移动优先、渐进增强的方法,首先为较小的移动设备构建站点,然后根据设备功能集和视口大小增强站点。

准备

作为一个完整的 reskin,第一步是清除原始样式,看看还剩下什么。通过删除核心样式,你只剩下简单的内容。如果你在浏览器中查看,你会看到文档的轮廓非常清晰,如图 6-18 所示。

A978-1-4302-6695-2_6_Fig18_HTML.jpg

图 6-18。

The initial site with the original styles removed

这仍然很容易理解的部分原因是正确地使用了标题标签,所以尽管网站只有浏览器默认样式,内容仍然有一个强大的、清晰的标题层次结构。当你看你自己的网站时,你可能会注意到你的一些标题似乎没有遵循一个适当的层次结构。这是一个很好的机会来看看如何重构你的标题,让它们为用户提供一个合适的页面层次结构。为了演示不恰当的层次结构可能会是什么样子,我整理了一个例子,如图 6-19 所示。

A978-1-4302-6695-2_6_Fig19_HTML.jpg

图 6-19。

An example of a page with an improper hierarchy

页面遵循清晰的层次结构非常重要,原因有很多,其中最重要的原因是这样可以让用户更容易访问页面,尤其是那些使用屏幕阅读器的用户,他们可能会依赖页面的层次结构来浏览内容。标题层次结构很重要的另一个原因是,它使我们能够轻松地应用与正确的标题元素相匹配的样式。

常规样式

在开始核心的编码之前,让我们首先改变元素的默认盒子模型。这是通过使用box-sizing CSS3 属性实现的,该属性在第四章中介绍过,并使用 CSS 通用选择器(*)将其应用于所有元素:

* {

-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */

-moz-box-sizing: border-box;    /* Firefox, other Gecko */

box-sizing: border-box;         /* Opera/IE 8+ */

}

通过将值设置为border-box,您将移动元素内部的边框和填充,允许您使用宽度的百分比值,同时仍然使用填充的px值。早先当我们修改 CSS 的时候,由于破坏现有风格的可能性,我们不能很容易地将这种技术应用到 CSS 中。当重新划分一个站点时,你不会有这个问题,因为你可以基于你选择实现的盒子模型来构建所有的样式。

定义断点

重要的是要计划在什么时候使用媒体查询来定义断点。因为您首先构建的是移动站点,所以您会根据设备视口的宽度在每个断点处逐步增强站点。因此,每个断点都应该尝试建立在前一个断点之上。首先构建 mobile 意味着不包含在任何媒体查询中的基本 CSS 是针对超小型设备的 CSS。考虑到这一点,您将需要定义三个断点,每个断点使用一个合理的最小宽度值。

要定义的第一个断点是最小宽度768px。这将允许您以从768px开始的视口宽度瞄准设备。这种选择背后的原因是,这通常是纵向平板电脑的起点,随着平板电脑获得更大的屏幕和更宽的视窗,您可以利用这一点来增强网站。当后面提到这个断点时,我称它为小断点:

@media screen and (min-width: 768px){

}

要定义的第二个断点是最小宽度1000px,目的是针对大量用户使用的非常流行的 1024×800 屏幕分辨率。虽然前面的断点可以假设大多数用户将使用某种平板电脑,但该断点在平板电脑和台式机之间共享,因此不能用于做出这种假设。以后提到这个断点时,我称之为中断点:

@media screen and (min-width: 1000px){

}

要定义的最后一个断点是最小宽度1200px。正如本书前面所讨论的,随着更大显示器的增长,利用额外的可用空间是有意义的。当稍后提到这个断点时,我将它称为大断点:

@media screen and (min-width: 1200px){

}

排印

一旦你对断点满意了,让我们开始对排版应用合理的默认尺寸。第一步是设置页面的基本字体大小。为此,一个合理的默认大小是14px,它在 HTML 标签上设置为百分比:

html{

font-size: 87.5%;

}

设置默认字体大小会影响网站上的所有文本,但是,您可能希望为标题设置自己的自定义字体大小:

h1{

font-size: 22px;

font-size: 1.571rem;

}

h2{

font-size: 18px;

font-size: 1.286rem;

}

您可能已经注意到,对于h1h2选择器,我已经定义了两次字体大小属性,第一次使用像素值,第二次声明使用rem中的值。这样做的原因是您想要使用rem(也称为相对 em),因为它们是相对于默认字体大小的。然而,这并不是所有的浏览器都支持的,所以作为一个后备,我用像素来定义字体大小。这种方法的缺点是,在不支持rem的旧浏览器中,基于文本大小的缩放将不起作用,然而,整页缩放仍将起作用,这意味着使用这些旧浏览器的人仍然可以使用该网站。

定义了移动 CSS 之后,让我们为更大的设备增加字体大小。您将通过向小型媒体查询添加增加的字体大小来实现这一点,因为您正在使用min-width,所以它将应用于所有大于它的断点:

@media screen and (min-width: 767px){

h1{

font-size: 28px;

font-size: 2rem;

}

h2{

font-size: 24px;

font-size: 1.714rem;

}

}

包装材质

您可能已经知道,HTML 包含一个带有类wrapperdiv元素,它封装了站点的 HTML。在被替换的站点的原始 CSS 中,这被用来定义站点的宽度并使其在页面上居中。但是,对于移动设备,您不希望设置宽度,因为您希望包装器是流动的。但是,您确实希望对站点的两侧应用一致的间距,因此您可以为此使用包装器。这可以通过在包装的左右两边增加空白来分隔页面来实现:

.wrapper{

margin: 0 20px;

}

在包装器中添加了页边距后,网站内容的左右两边将会有20px页边距。尽管流体宽度非常适用于超小型设备,但您希望在小型设备上设置固定的宽度,并且还希望在视口中居中固定的宽度设计,这可以通过使用边距来实现:

@media screen and (min-width: 767px){

.wrapper{

width: 740px;

margin: 0px auto;

}

}

为小型设备设置了宽度后,当到达中等断点时,您会发现为小型断点设置的宽度留下了大量的可用空间。因此,在这些中等尺寸的显示器上使站点更宽是有意义的:

@media screen and (min-width: 1000px){

.wrapper{

width: 980px;

}

}

最后,您希望能够利用更大显示器提供的额外空间,因此让我们再次增加包装的宽度。在这种情况下,我选择使用最小宽度的断点1200px。这是为了确保浏览器不显示水平滚动条。让我们将站点的宽度设置为1170px,以允许浏览器的滚动条:

@media screen and (min-width: 1200px){

.wrapper{

width: 1170px;

}

}

页眉

看了网站的版式和包装,让我们继续设计网站的标题。在超小型设备上,我们希望在标题底部有一个跨越视口宽度的边框。然而,当包装器的边距设置为20px时,页眉自然不会跨越 100%的视口。要解决这个问题,让我们使用负边距将标题的宽度拉至视窗的全宽。然后,您可以使用填充将此间距添加到页眉的内部,然后将边框添加到页眉的底部:

.global-header{

border-bottom: 1px solid #ccc;

margin: 0 -20px;

padding: 0 20px;

}

对于较大的视口,您可能需要删除这些额外的间距:

@media screen and (min-width: 767px){

.global-header{

margin: 0px;

padding: 0px;

}

.global-header h1{

text-align: left;

}

}

(电视机的)超大屏幕

标题的正下方是大屏幕,用来突出显示我们虚构的公司 responsive design inc .想要推广的最新产品。这个面板应该很突出,所以让我们添加一个橙色的背景色,同时拉出大屏幕,使其适合视窗的整个宽度:

.jumbotron{

background: #f4a156;

margin: 0 -20px;

padding: 20px;

text-align: center;

}

接下来,让我们为大屏幕中显示的标题元素添加一些样式,使其顶部没有任何边距:

.jumbotron h2{

margin-top: 0px;

}

最后,让我们来设计一下大屏幕上突出显示的这款产品的价格。为此,让我们简单地增加字体大小,使其更加突出:

.jumbotron .roundal{

font-size: 18px;

font-size: 1.286rem;

}

如果你现在在浏览器中加载网站,你将能够看到风格化的大屏幕,如图 6-20 所示。

A978-1-4302-6695-2_6_Fig20_HTML.jpg

图 6-20。

The newly styled Jumbotron

现在让我们将它应用到更大的设备上。要达到想要的效果,还是用绝对定位吧。为此,您需要将高度和元素设置为position: relative:

.jumbotron{

margin: 0px;

height: 290px;

position: relative;

}

下一步是定位图像。您希望大屏幕中的所有内容都在中央,所以让我们将其设置为左侧 50%,然后使用margin-left添加偏移。在这种情况下,图像的宽度为 250 像素,所以您希望它偏离中心 20 个像素,在这种情况下,偏移量为-270 像素:

.jumbotron img{

position: absolute;

left: 50%;

margin-left: -270px;

}

同样,标题需要居中,然后使用margin-left偏离中心。尽管图像向左偏离中心,但文本将向右偏离中心。让我们也增加字体大小:

.jumbotron h2{

position: absolute;

left: 50%;

margin-left: 20px;

width: 250px;

font-size: 42px;

font-size: 3rem;

text-align: left;

}

最后,我们来定位价格。这应该与标题对齐,但更靠近大屏幕的底部:

.jumbotron .roundal{

position: absolute;

left: 50%;

margin-left: 20px;

bottom: 40px;

font-size: 28px;

font-size: 2rem;

}

现在,如果你看看大屏幕是如何出现在更大的设备上的,它看起来会如图 6-21 所示。

A978-1-4302-6695-2_6_Fig21_HTML.jpg

图 6-21。

The Jumbotron as seen on larger devices

制品

产品是这个网站的核心部分,所以用一种清晰简洁的方式向用户展示它们是很重要的。已经有 HTML 列出了产品名称和规格的价格,但是,您需要对其进行样式化,以便它在超小型设备上运行良好。在这些设备上,产品可以堆叠在一起,这样用户就可以上下滚动来查看不同的产品。由于每个产品都是一个div,这是一个块级元素,所以每个产品自然都是全幅堆叠的。但是运用风格来分隔产品也很重要。最后,您可以将文本居中对齐,以与页眉和大屏幕的样式保持一致:

.product{

text-align: center;

margin: 20px 0;

border-bottom: 1px solid #ccc;

padding-bottom: 20px;

}

确定了产品之后,下一步是设计产品的价格。为此,您可以使用一个roundal。为了实现这一点,让我们将roundal的样式设为100px宽,高度将由70px的高度和30px的顶部填充组成。圆形效果将通过给它一个橙色的背景色和50px的边框半径来实现。最后,这将使用边距居中对齐。为了以更大的字体显示价格,将 span to be display 块(强制换行)的字体大小设置为1.6rem:

.product .roundal{

width: 100px;

height: 100px;

margin: 0 auto;

background: #f4a156;

border-radius: 50px;

padding-top: 30px;

}

.product .roundal span{

display: block;

font-size: 1.6rem;

}

接下来,您可能想要添加产品的样式规范。首先,让我们删除浏览器应用于列表的默认填充,然后删除项目符号,因为在列出规范时不需要它们:

.product ul{

padding: 0px;

}

.product li{

list-style: none;

}

下一步是设计 read-more 链接。这应该是一个按钮,所以让我们来设计一下:

.product a{

color: #000;

text-decoration: none;

display: inline-block;

background: #ccc;

padding: 0px 10px;

border-radius: 2px;

line-height: 40px;

}

声明了按钮之后,您还想为按钮添加悬停、聚焦和活动状态。虽然您的第一想法可能是小型触摸屏设备不具备悬停功能,因为它们通常都有触摸屏,但您需要确保覆盖 CSS 中的所有内容,因为您无法知道用户是否正在使用触摸设备:

.product a:hover, .product a:focus, .product a:active{

background: #999;

color: #eee;

}

最后,您会注意到产品周围出现了额外的间距。这是由 product 元素中第一个和最后一个元素的边距造成的。您可以使用first-childlast-child选择器快速移除它们。这样做而不是直接设置元素样式的原因是,元素的顺序可能会改变,或者可能会添加新元素,无论元素是什么,CSS 都仍然适用:

.product > *:first-child{

margin-top: 0px;

}

.product > *:last-child{

margin-bottom: 0px;

}

将产品构建成堆栈后,您会发现无论浏览器的宽度如何,它们都工作得很好(见图 6-22 ):

A978-1-4302-6695-2_6_Fig22_HTML.jpg

图 6-22。

Product stack works well regardless of browser

尽管流体宽度产品在所有视口尺寸下都工作良好,但在较大的视口中,您会注意到有很多空间。产品和其中元素的流动性意味着当指定产品元素的宽度时,它和其中的内容将继续以指定的宽度工作。这意味着,在较大的视窗上,您可以通过将产品放入栏中来利用额外的空间。要实现这一点,只需将产品元素的宽度设置为33.333%,这样产品就占据了可用宽度的三分之一:

@media screen and (min-width: 767px){

.product{

float: left;

width: 33.333%;

}

}

然后你可以看到这些列并排出现在浏览器中(见图 6-23 )。

A978-1-4302-6695-2_6_Fig23_HTML.jpg

图 6-23。

Products line up side by side in browser

如果你用百分比来表示产品元素的宽度,它们会随着站点宽度的增加而增加。

页脚

reskin 的最后一个样式是页脚。这真的很简单,因为产品已经在产品和页脚之间提供了一个分隔符,所以你需要做的就是居中对齐文本,并在下面添加一点点间距:

.global-footer{

text-align: center;

padding-bottom: 10px;

}

这些样式不需要任何媒体查询来扩展,因为它们在包装器中是流动的。

结论

使用新的 CSS 重新设计站点后,您已经了解了如何首先构建移动版本,并在移动版本的基础上使用每个断点来构建一个可以简化的站点。

您还了解到,通过在超小型设备上构建流畅的元素,您可以在不同的断点对它们应用固定的宽度,然后您只需要应用最少的额外样式。

重要的是要记住,当你重新构建 CSS 时,你不一定需要一个完全相同的站点作为最终结果。对于你自己的网站,在你着手一个 reskin 之前,最好和你的设计师和 UX 团队讨论他们是否想对网站做一些调整,因为 reskin 是做这件事的最好时机。

摘要

这一章解释了如何修改一个现有的站点来响应。您学习了三种不同的技术来使站点具有响应性。

第一种使站点具有响应性的方法是修改现有的 CSS。改编现有 CSS 的主要好处是,它比执行完整的 reskin 要快得多。通过修改现有的 CSS,您已经有了一个开始的基础。另一方面,这可能是一个缺点,因为它会导致代码变得更加臃肿,因为您可能必须用浏览器默认行为来覆盖您已经设置的值。一个非常简单的例子就是绝对定位,在较小的设备上,您不需要以某种方式改变元素的定位方式,甚至经常删除已经应用的绝对定位。

第二种使网站具有响应性的方法是重构现有的代码库,使其既具有响应性,又是从移动优先的角度构建的。这里的关键好处是,你可以先获得构建一个移动站点的性能和可用性的好处,而不需要做一个完整的皮肤。主要的缺点是,在一个大型网站上,您可能会面临一个大的代码库需要重构,并且很难隔离不再需要的遗留代码,因为可能有一个页面嵌入到使用它的网站深处。

使站点具有响应性的最后一种方法是对站点进行全面的重新换肤。做一个完整的网站皮肤的主要好处是,它使你能够从移动优先的角度来构建,使用渐进式增强来构建网站,这可以帮助代码库更加精简。使用这种以移动设备为先的方式来构建网站,可以让你在逐步增强网站的同时添加更多的样式。

前几章已经强调了使用移动优先的方法来构建网站的好处,所以修改现有网站的首选方法是做一个完整的 reskin,删除原始 CSS 并开始使用移动优先的方法。然而,如果时间是一个问题,你可能会发现你需要简单地修改现有的风格,虽然不理想,但你会实现一个可用的响应站点。如果你发现你还有一点时间,你可以考虑优化你的站点来减少桌面优先构建的一些缺点。

虽然这一章关注的是使网站具有响应性的 CSS 方面,但是你并不局限于此。如果有必要的话,你可以重构你的 HTML 的一部分,使你能够更好地适应你的网站。此外,如果站点的功能会受益,您可以编写响应式 JavaScript 来改变站点不同元素的工作方式。

下一章将着眼于如何改进我们在构建一个响应式网站时使用的工具和遵循的工作流程。

七、工具和工作流程

随着响应式设计的发展,开发一个网站所需的时间也在增加;原因是在开发网站的过程中有更多的变量需要考虑。考虑到这一点,找到优化我们工作流程的方法以使我们能够在其他开发领域节省时间变得越来越重要。随着响应式设计的增长,前端工具也在增长,这使我们能够更有效地编写代码。

本章将探讨:

Knowing your command line   Version control with Git   CSS preprocessors   Bower   Grunt   Gulp   Scaffolding   Other tools   Workflow  

了解您的命令行

一开始,你的操作系统的命令行界面可能非常吓人,但是,它也可能非常强大。学习如何使用命令行有很多好处:

A large number of web development tools now reside as command-line utilities.   It allows you to do batch file processing, such as the renaming of files, which may not be achievable using the normal graphical user interface (GUI).   The same interface is used when you secure shell (SSH) into servers, so the skills are transferable if you later want to manage your own hosting server.  

考虑到这些好处,让我们看看命令行,这样您就可以在您的网站开发中更多地利用它。

准备命令行

在我开始讨论命令行之前,您必须准备好一些基本工具。这在 Mac OS X 和 Windows 之间略有不同,所以我为每一个都提供了单独的说明。

Mac OS X

在第二章中,我讨论了安装 Xcode 来允许你使用 iOS 模拟器。Xcode 对前端开发人员有用的另一部分是命令行工具。安装命令行工具最简单的方法是从苹果开发者网站 https://developer.apple.com/downloads/index.action 下载。你需要使用苹果开发者账户登录,你可以免费注册,然后为你的特定操作系统下载最新的“命令行工具”。下载完成后,您可以简单地运行安装程序来加载工具。

安装完成后,您可以安装 Homebrew 软件包管理器,这是一个命令行工具,允许您安装 Node.js 等软件包。要安装 Homebrew,您需要运行以下命令:

ruby -e "$(curl -fsSLhttps://raw.github.com/Homebrew/homebrew/go/install

然后命令行会引导你完成家酿的安装。

Windows 操作系统

要在 Windows 上准备命令行工具,您需要安装 Git 和 Bash。这些可以从 http://msysgit.github.io/ 一起下载。下载 msysgit 包时,它会建议你下载最新版本。

在安装过程中,您可以使用默认安装选项。当询问您希望使用哪种安装方法时,选择“仅使用 Git Bash”安装完成后,您只需单击 Finish 即可。您将使用 Git Bash 作为命令行界面,而不是使用内置的 Windows 命令行。要打开 Git Bash,只需在开始菜单的 Git 文件夹中找到它。

命令您的命令行

确保命令行设置正确后,您现在可以了解如何使用命令行的一些基础知识。命令行为广泛的计算机功能提供了一个简单的界面,从简单的创建文件夹到递归地改变文件权限。

遍历目录

在命令行中工作时,您可能希望执行的一个基本操作是在目录之间导航并查看目录内容。您可以使用两个主要命令来实现这一点:lscd

限位开关(Limit Switch)

ls命令将允许您列出当前目录中的所有文件和目录。

激光唱片

cd命令允许你改变一个目录。你可以传递一个绝对路径(以/开头),例如/Users/jonathan/,或者你可以传递一个与你当前文件夹相关的路径,例如Users/jonathan

此外,还可以使用cd ..导航到父目录,或者使用倍数导航到多个父目录,比如../../

简单的文件操作

您还需要能够使用命令行操作文件,并且能够创建、复制、移动和删除目录和文件。

创建目录

mkdir命令允许你在当前目录下创建一个新目录。这是通过输入mkdir dirname实现的。如果您想为名为project_name的项目创建一个文件夹,您可以运行命令:

mkdir project_name

触控

有时,当您设置目录结构时,您可能希望在目录中创建占位符文件。不必打开文本编辑器并创建每个文件,您可以使用touch命令简单地创建它们。要创建名为index.html的空文件,只需使用命令:

touch index.html

丙酸纤维素

cp命令允许您复制现有文件。要使用该命令,您只需提供原始文件的相对或绝对路径,后跟您要将它复制到的位置的路径。使用该命令的语法如下所示:

cp original-file-path new-file-path

例如,如果您想要将文件复制到当前文件夹的子目录中。在这种情况下,您只需提供原始文件的路径以及要将其复制到的位置:

cp hello.jpg img/hello.jpg

平均变化

mv命令与cp命令的相似之处在于,您只需提供原始文件的相对或绝对路径,然后是您想要将它移动到的位置的路径。使用该命令的语法如下所示:

mv original-file-path new-file-path

例如,如果您想要将文件移动到当前文件夹的子目录中。在本例中,您只需提供原始文件的路径以及要将它移动到的位置。

mv hello.jpg img/hello.jpg

空间

如果你想删除你已经创建的文件,你可以使用rm命令。使用rm命令的语法是:

rm file-to-be-removed-path

因此,如果您想从 images 目录中删除文件hello.jpg,您可以使用以下命令:

rm img/hello.jpg

Note

rm命令不会将文件放入回收站,而是将它从系统中永久删除。

其他有用的命令

除了已经介绍的核心命令之外,在使用命令行时,还有一些额外的命令会很有用。

日本首藤

sudo命令用于以系统超级用户(通常称为 root)的身份运行任何命令,目的是如果您想要修改当前用户没有权限的文件,您可以使用sudo来完成。使用sudo命令的一个例子是删除一个您自己无权删除的文件,命令行是:

sudo rm protectedFile.jpg

cat命令允许你读取文件的内容。要使用cat命令,您可以运行该命令,然后运行您想要输出的文件:

cat error.log

除了允许您简单地读取文件,它还可以用来连接文件。这是通过运行cat,后跟一个您想要连接的文件名列表来实现的:

cat file1 file2 file3

在上面的示例中,连接的文件只是输出到屏幕上,但是,您可以通过使用大于号(>)后跟要输出的文件名来选择将其输出到文件中:

cat file1 file2 file3 > concatfile

尾巴

tail命令允许您简单地将文件的最后几行输出到命令行。要使用tail命令,您可以运行该命令,后跟您想要读取的文件名:

tail error.log

您也可以使用-n标志后跟您想要读取的行数来选择您想要查看的行数:

tail –n 5 error.log

进一步的文件

通过在您想要了解的命令前使用man命令,可以直接在您的终端中查看关于这些命令的更多文档,例如man rm

工具先决条件

在开始安装和使用这些工具之前,您需要安装它们所依赖的一些先决条件。您将在这里探索的工具需要的两个先决条件是 Ruby 和 Node.js。

红宝石

Ruby 是一种动态的、面向对象的编程语言,可用于多种用途。我们在这里对它感兴趣的原因是,它被你将在本章中探索的少量工具所使用。

装置

Mac OS X

Mac OS X 附带了一个版本的 Ruby。这将是您在本章示例中使用的版本。你可以选择安装一个像 RVM 这样的工具来升级到 Ruby 的新版本(关于这个的信息可以在 http://rvm.io 找到)。

Windows 操作系统

要在 Windows 上安装 Ruby,可以使用位于 http://rubyinstaller.org/ 的 RubyInstaller 包。这是一个自包含的 Windows 安装程序,它将安装 Ruby 语言以及执行环境和文档。

在安装过程中,你会被要求输入 Ruby 的目的地。在这个阶段,您需要选中复选框“将 Ruby 可执行文件添加到您的路径中”

Node.js

最重要的先决条件之一是 Node.js,它是 JavaScript 的服务器端实现,带有服务器端 API。这是本书示例中使用的许多工具所需要的,包括 Bower、Grunt 和 Serve。

装置

在 Windows 和 Mac OS X 上安装 Node.js 是非常不同的,所以我将分别详细说明每个步骤。

Mac OS X

要在 Mac OS X 上安装 Node.js,您将使用名为 Homebrew 的 Mac OS X 软件包管理器。安装相对简单,您只需打开终端并运行命令:

brew install node

这将为您下载并安装 Node.js。以这种方式使用 Homebrew 安装 Node.js 的好处是,您可以使用以下命令轻松更新到较新的版本:

brew update node

要测试 Node.js 是否已安装,只需安装以下工具之一。

Windows 操作系统

Node.js for Windows 可以通过 Windows installer 轻松安装,可从 http://nodejs.org/download/ 获得。

使用 Git 进行版本控制

Git ( http://git-scm.com/ )是版本控制系统(VCS),在大量开源项目中使用,使开发人员能够跟踪已经发生的变化。当您最初设置命令行时,您安装了 Git 源代码控制管理工具,因为它是您将使用的一些其他工具的先决条件。

使用 Git 的核心概念之一是它是一个分布式 VCS,这意味着在本地您将拥有一个存储库的副本,您可以使用它来执行所有主要的 VCS 操作,如提交、分支和合并。您可以继续简单地在本地使用 Git 来管理项目代码,但是,强大之处在于能够将您的代码从本地存储库推到远程存储库,您可以使用它来与其他开发人员协作。当您想要共享本地存储库中的代码时,您可以将本地提交推送到远程存储库。类似地,当您想要获得其他开发人员所做的最新变更时,您可以将它们从共享存储库中下载到您自己的存储库中。

如果你以前使用过像 Subversion (SVN)这样的集中版本控制系统,你会注意到这是非常不同的。然而,这种方法的好处是,即使没有互联网连接,您仍然可以提交,这允许您继续定期提交。

为了开始学习如何使用 Git VCS,让我们看看如何在命令行上使用它的基础知识。

初始化存储库

要在本地机器上初始化新的存储库,只需运行以下命令:

git init

这就产生了一个隐藏的。git 目录,Git 将使用它来管理目录中文件的版本。此时,存储库仍然是空的,因为没有任何文件添加到其中。

添加文件

当使用 Git 时,您需要告诉它您希望它对哪些文件进行版本控制。这是通过使用git add命令实现的。要添加单个文件,您只需运行命令git add以及您想要添加的文件名。添加 JavaScript 文件的一个例子是:

git add scripts/main.js

尽管以这种方式添加单个文件很容易,但是您可能需要添加大量文件,尤其是在进行初始提交时。这就是git add .发挥作用的地方,它告诉 Git 将当前目录下的所有文件添加到存储库中。

做出承诺

一旦添加了文件,就可以进行初始提交了。你可以通过使用git commit命令来完成。您可以使用-m标志来设置提交消息;因此,该命令将类似于:

git commit -m 'initial commit'

在您完成这个初始提交之后,您可以继续使用git commit来提交任何更改的文件。

添加遥控器

现在,您已经添加了一些文件并进行第一次提交,您可能希望将这些更改推送到远程存储库进行共享。要添加新的存储库,您需要使用git remote add命令,提供存储库的名称和 URL。这方面的一个例子是:

git remote add origin git@github.com:jonathan-fielding/repo.git

推动提交

要将提交推送到远程服务器,可以使用git push命令。第一次推送到远程服务器时,您需要设置刚刚添加的远程服务器的上游,为此您使用了-u标志。您将用于推送到远程服务器的命令是:

git push -u origin master

后续的推送可以简单地通过单独使用git push命令来实现。

拉动更改

使用git pull命令可以从远程服务器获取更改。

克隆存储库

到目前为止,您一直在开发自己的存储库;但是,在某些时候,您可能需要克隆一个远程存储库。这是通过使用后跟存储库 URL 的git clone命令来实现的。克隆 HTML5 样板文件库的一个例子是:

git clone git@github.com:h5bp/html5-boilerplate.git

克隆的存储库与本地初始化的存储库的工作方式完全相同。您可以添加新文件、删除文件、提交新文件,如果您对存储库有写权限,还可以提交您的更改。

CSS 预处理程序

CSS 预处理器背后的核心概念是,它是一种可以编译成普通 CSS 的语言。这个想法是,通过添加新的特性来扩展 CSS,您可以编写更少的代码。CSS 预处理器的一些主要特性是:

Variables   Nesting   Import external files   Extend existing styles   Mixins  

CSS 预处理器已经变得非常流行,因此,预处理器的一些特性已经被改编以提交给 W3C。这里的想法是变量、混合和嵌套都有可能成为 CSS 规范未来版本的特征。

在我讨论各个预处理程序之前,让我们先来看看它们的核心特性以及它们如何工作的例子。下面的例子是使用 Sass 编写的,但是,这些是适用于大多数 CSS 预处理程序的核心概念。

变量

在 CSS 中,如果你想在多个地方使用一个值,你必须把它硬编码到那些地方。如果您稍后想要更新该值,您将需要遍历并更新每个地方的值。这可能很耗时,而且很容易出错,错过您想要更新的事件。CSS 预处理程序通过允许您将值定义为可以在整个代码中使用的变量来缓解这种情况。通过更新变量,它将更新所有使用该变量的地方,使它不容易出错。如何在 CSS 预处理器中使用变量的一个例子是使用蓝色。在本例中,您希望将颜色存储为一个变量,在这里您将把它命名为$blue。当需要使用变量时,只需将变量放在通常放置属性值的位置:

$blue: #3bbfce;

p{

color: $blue;

}

嵌套

CSS 预处理程序的另一个特性是,它们允许你以一种允许你写更少代码的方式嵌套你的 CSS。举一个普通 CSS 的例子:

.class-name{

background: #000;

}

.class-name p{

color: #fff;

}

.class-name p span{

color: #eee;

}

如果您要使用 CSS 预处理器来重写,您可以选择嵌套 CSS 选择器,就像在 HTML 中嵌套元素一样。这意味着您可以编写更少的代码,因为您不再需要编写长的选择器。为使用 CSS 预处理程序而重写的 CSS 示例如下:

.class-name{

background: #000;

p{

color: #fff;

span{

color: #eee;

}

}

}

您会注意到您已经在类选择器中嵌套了p选择器,并且在这个选择器中有span。编译后,生成的 CSS 将与原始 CSS 相同;但是,您用更简洁的方式编写了这段代码。另外,如果你以后想把class-name改成another-class-name,你只需要在一个地方更新它:

.another-class-name{

background: #000;

p{

color: #fff;

span{

color: #eee;

}

}

}

导入

当编写一个普通的 CSS 文档时,对于一个大型网站来说,即使 CSS 文档是以一种优化的方式编写的,它变得相当长也是正常的。响应式设计增加了这个问题,因为我们现在将媒体查询添加到我们的 CSS 中。

使用 CSS 预处理器可以让您将代码分割成单独的文件,从而避免处理大文件。这样做有几个主要的好处,第一个是可以更容易地管理较小的文件,第二个是如果在源代码控制中出现冲突,它们更容易解决。

CSS 预处理程序允许你通过实现一个叫做 partials 的概念来分割文件,partials 是一个单独的文件,里面有一小部分你的代码。为了防止分部被单独编译,您需要用下划线(_)作为前缀来命名您的分部,这告诉预处理器它是一个分部,只能作为另一个样式表的一部分来编译。

通常你会有一个主文件用来导入你的部分;在这里,您可以使用@import将一部分导入到文档中:

@import "utilities/_reset.scss";

@import "utilities/_typography.scss";

当使用 CSS 预处理器进行编译时,部分代码被内联到编译后的 CSS 文档中。

扩展

针对特定元素编写了一些样式后,您可能会发现在站点的其他地方也有类似的元素。与其重新声明 CSS 规则集或将类名添加到现有的选择器中,您可以做的只是使用预处理器扩展现有的样式。为此,首先要定义第一个元素的样式;在本例中,您将为一个简单的按钮定义样式:

.button{

display: inline-block;

background: #ccc;

border-radius: 10px;

padding: 5px 50px;

}

然后,您可以为新元素定义样式;在这种情况下,您将定义一个填充较少的小按钮。要扩展一个现有的元素,您可以使用@extend,后跟您正在扩展的选择器:

.button-sml{

@extend .button;

padding: 5px 20px;

}

混入类

CSS 预处理程序最强大的特性是定义混合的能力。mixin 是一个可重用的代码块,一旦定义,就可以在 CSS 中的任何地方使用。它允许您声明代码,您可以将变量应用到代码中,以输出所需的结果。有几个地方使用 mixin 可以使编写 CSS 变得更容易。让我们来看几个这样的例子。

加前缀

第一个例子展示了如何使用 mixin 解决浏览器前缀的问题。在本书的前面我提到过,当新的 CSS 特性在浏览器中实现时,它们通常以浏览器前缀为前缀。因为您想要支持所有的浏览器,所以您需要确保您的代码输出所有正确的浏览器前缀,为此您可以使用 mixin。要编写一个能够为 CSS 属性border-radius生成前缀代码的 mixin,您需要编写一个接受一个参数(border-radius的值)的 mixin,并编写属性的每个前缀版本,其值设置为传递给 mixin 的参数:

@mixin border-radius($argument) {

-webkit-border-radius: $argument;

-moz-border-radius: $argument;

-o-border-radius: $argument;

border-radius: $argument;

}

如果你现在想要使用border-radius mixin,你可以使用@include border-radius(value),其中(value)等于你想要设置的border-radius:

@include border-radius(10px);

快捷指令

你可能想使用 mixin 的另一个领域是写快捷方式。一个例子是 mixin,它获取用于定位元素的值,然后输出 CSS。虽然这是一个简单的例子,但它展示了编写一个 mixin 来处理您可能经常编写的 CSS 输出是多么容易:

@mixin position($top, $right, $bottom, $left) {

top: $top;

right: $right;

bottom: $bottom;

left: $left;

}

功能

在一些 CSS 预处理器中,除了 mixins,还有函数。虽然 mixin 和函数之间有相似之处,但关键的区别是 mixin 将直接输出 CSS,而函数将返回一个值,然后您自己输出该值。

使用函数而不是 mixin 的一个例子是当你想计算一个值的时候。在本例中,您可能希望返回计算的结果,然后在其他地方使用它。您甚至可以使用 mixin 中的函数来执行您需要的计算。

这种计算的一个简单例子是,您希望将像素字体大小转换为 rems。这方面的一个例子是:

@function px-to-rem($font-size){

$baseline-px: 16 //This is the base font size used on our HTML element

$baseline-rem: $baseline-px / 1rem * 1;

@return $font-size / $baseline-rem

}

要使用这个函数,您只需调用它,传递您想要的字体大小:

p{

font-size: px-to-rem(12px);

}

不同的预处理程序可用

在探索了 CSS 预处理器的一些关键原理之后,让我们来看看几个流行的预处理器。我将解释为什么它们应该成为您的工具集的一部分,以及在构建一个响应式站点时它们将如何节省您的时间。

Sass +指南针

Sass ( http://sass-lang.com/ )是语法上令人敬畏的样式表的缩写。我之前解释了 CSS 预处理器通常会包含的一些不同特性,您会很高兴地了解到 Sass 包含了所有这些特性。Sass 也是许多开源项目选择的 CSS 预处理器,包括本书前面讨论的 Foundation。此外,甚至还有一个 Sass 版本的 Twitter Bootstrap。

Compass 是位于 Sass 之上的一个附加框架,为它增加了额外的功能。这种功能的例子包括混音和生成精灵的能力。

有各种各样的工具可以与 Sass 和 Compass 一起使用来编译代码,所以让我们从使用命令行工具开始。

装置

Sass 和 Compass 都是作为 Ruby gems 安装的。要安装它们,只需运行:

gem update --system

gem install compass

安装 Compass 时,它也会安装 Sass,因为它是一个依赖项。

使用

Sass 语法有两种风格:第一种是 Sassy CSS,它是 CSS3 语法的超集,第二种是缩进语法。我将把重点放在 Sassy CSS 语法上,因为它不仅比缩进语法更受欢迎,而且从该语言的版本 3 开始,它已经成为 Sassy 的主要语法。

因为在这里的例子中您将使用带有 Compass 的 Sass,所以让我们从使用 Compass 来设置这个项目开始。为此,您将使用compass create命令,该命令将创建项目目录以及基本的 Sass 文件和编译的 CSS。对于这个例子,您将告诉命令项目的名称是sass_project:

compass create sass_project

在运行上面的命令时,Compass 将为项目创建一个新文件夹,其中包含文件。此外,它还会给出如何将编译好的 CSS 添加到 HTML 文档中的说明(见图 7-1 )。

A978-1-4302-6695-2_7_Fig1_HTML.jpg

图 7-1。

Creating Sass project with Compass, with instructions to add to HTML highlighted

在这个阶段,您仍然在刚刚创建的项目的父目录中,因此您将使用cd命令移动到这个项目的目录中:

cd sass_project

现在您已经在目录中,可以编译 Sass 了。要检查编译是否正常工作,只需运行以下命令:

compass compile

命令行会告诉你编译成功了。

在命令行中设置了项目之后,您还需要编写自己的代码。让我们打开文本编辑器中生成的 screen.scss 文件 Compass。打开文件后,您会发现以下六行 Sass:

/* Welcome to Compass.

* In this file you should write your main styles. (or centralize your imports)

* Import this file using the following HTML or equivalent:

* <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" /> */

@import "compass/reset";

这段代码所做的是将默认浏览器重置导入到样式表的顶部。如果您想查看编译后的代码,只需查看样式表目录中的 screen.css 文件。

能够只使用一行代码添加 CSS 浏览器重置对于完整的站点构建非常有帮助;然而,对于这个例子,您将从头开始并清除这个 Sass 文件。

让我们从编写一些嵌套的 CSS 开始:

.class-name{

background: #000;

p{

color: #fff;

span{

color: #eee;

}

}

}

如果您随后在命令行中使用compass compile对其进行编译,并从样式表的目录中打开编译后的 screen.css 文件,您会发现编译后的代码如下所示:

/* line 1, ../sass/screen.scss */

.class-name {

background: #000;

}

/* line 3, ../sass/screen.scss */

.class-name p {

color: #fff;

}

/* line 6, ../sass/screen.scss */

.class-name p span {

color: #eee;

}

您会注意到,除了生成的 CSS 之外,每个选择器都有一个注释,告诉您可以在 Sass 文件中找到该选择器的行号和文件。

正如你可能已经意识到的,每次做出改变都运行compass compile并不实际。这就是compass watch命令的用武之地。compass watch命令的作用是监视你的 Sass 文件,所以如果你改变了元素的背景颜色,它会自动重新编译。这样,任何进一步的更改都会自动编译,您现在可以运行以下命令:

compass watch

前面我讨论了如何将几个片段(CSS 文档的一部分)导入到一个文档中。在这里我将解释这是如何与 Sass 一起工作的。

首先,您将为片段创建一个目录,在这种情况下我们称之为partials。在这个文件夹中,你将创建两个名为_layout.scss_typography.scss的 Sass 文件。在这些分部之前加上下划线的原因是告诉编译器这是一个分部,不应该单独编译。

Inside _layout.scss 您将把这些基本样式:

.container{

max-width: 960px;

margin: 0 auto;

}

Inside _typography.scss 您将把这些基本样式:

html{

font-size: 100%;

}

h1{

font-size: 3rem;

}

p{

font-size: 1.2rem;

}

然后,您可以使用@import将它们包含在 screen.scss 文件中。screen.scss 代码中的代码将如下所示:

@import "partials/typography";

@import "partials/layout";

您会注意到,尽管原始文件以下划线为前缀,并带有文件扩展名的后缀,但在导入部分文件时,这些都是不必要的。因为您在命令行中运行了compass watch命令,Compass 正在监视这些文件的变化,所以在保存 screen.scss 文件时,该文件将被重新编译为 css。如果您接下来查看 screen.css 输出文件,您会看到这两个文件现在包含在同一个 css 文件中:

/* line 1, ../sass/partials/_typography.scss */

html {

font-size: 100%;

}

/* line 5, ../sass/partials/_typography.scss */

h1 {

font-size: 3rem;

}

/* line 9, ../sass/partials/_typography.scss */

p {

font-size: 1.2rem;

}

/* line 1, ../sass/partials/_layout.scss */

.container {

max-width: 960px;

margin: 0 auto;

}

导入的 Sass 文件按照声明的顺序进行编译和插入。请注意,注释强调了代码的每一部分来自哪个部分。

看了 Sass 的一些基本用法后,希望您对如何使用这些工具编译 CSS 有了很好的理解。我已经介绍了 CSS 预处理程序的核心功能,记住这些也适用于 Sass 是很重要的。

较少的

另一个很受欢迎的 CSS 预处理程序是 LESS。我之前介绍了 CSS 预处理器通常会包含的一些不同的特性,不幸的是 LESS 不支持编写自己的自定义函数,然而,讨论的所有其他特性都是受支持的。

Twitter 的开发者已经发布了几个使用较少的开源项目,最流行的是 Bootstrap 然而,他们也发布了一个名为 recession 的代码质量工具,这是一个测试 LESS 和 CSS 文件代码质量的工具。

装置

使用 LESS 有几种不同的方法,这里我将重点介绍使用命令行工具。LESS 命令行工具是用 Node.js 编写的,所以您需要使用npm来安装它。您将使用的命令是:

npm install -g less

使用

要开始使用 LESS,你需要建立一个文件夹,你可以调用less:

mkdir less

一旦创建了这个文件夹,您将使用文本编辑器创建一个名为 screen.less 的 LESS 文件。让我们从向 LESS 文件添加一些嵌套代码开始:

.class-name{

background: #000;

p{

color: #fff;

span{

color: #eee;

}

}

}

有了这些,您现在可以使用lessc命令行工具将 LESS 文件编译成 CSS。您需要提供要编译的文件名以及编译后的文件名:

lessc screen.less screen.css

文件编译完成后,您可以查看 screen.css 文件中的输出:

.class-name {

background: #000;

}

.class-name p {

color: #fff;

}

.class-name p span {

color: #eee;

}

输出与没有预处理器的情况下的编码非常相似,但是,实际编写的代码要简单得多。注意,与 Sass 不同,LESS 不会在源代码中添加调试注释。

我在前面讨论了导入的概念,并解释了如何在 Sass 中这样做,在 LESS 中非常相似。您只需使用一个@import语句来包含几个不同的文件。

您首先需要为这些片段创建一个目录,在本例中,您可以将其命名为partials。在这个文件夹中,你将创建两个名为_layout.less_typography.less的小文件。为了使 LESS 不编译部分代码,可以在文件前加一个下划线。

_layout.less里面,你会把这些基本样式:

.container{

max-width: 960px;

margin: 0 auto;

}

Inside _typography.less,你会把这些基本样式:

html{

font-size: 100%;

}

h1{

font-size: 3rem;

}

p{

font-size: 1.2rem;

}

然后您需要更新 screen.less 来使用@import语句导入这两个文件。与 Sass 不同,您需要提供 LESS 文件的完整路径,包括文件扩展名:

@import "partials/_typography.less";

@import "partials/_layout.less";

要将 LESS 文件重新编译成 CSS,只需重新运行前面的命令:

lessc screen.less screen.css

然后将screen.less文件编译成 screen.css 文件。如果您现在查看screen.css文件,您会看到这两个文件现在在同一个文档中,其顺序与您用@import语句声明它们的顺序相同:

html {

font-size: 100%;

}

h1 {

font-size: 3rem;

}

p {

font-size: 1.2rem;

}

.container {

max-width: 960px;

margin: 0 auto;

}

命令行并不是减少使用的唯一方式。当你开发的时候,你可以选择直接使用 LESS 文件作为链接,就像你在页面中包含 CSS 一样。除此之外,您还包括了less.js,这是一个将在浏览器中解析 LESS 文件的库。您将添加到 head 元素中的代码如下所示:

<link rel="stylesheet/less" type="text/css" href="screen.less" />

<script src="less.js" type="text/javascript"></script>

这使您能够在开发时快速测试代码,但是,建议您不要以这种方式部署设置较少的实时代码,因为浏览器需要在呈现样式之前解析文件。另外,添加less.js解析器当然也会增加页面的权重。

使用 CSS 预处理程序的问题

正如我前面提到的,使用 CSS 预处理器可以为您的开发带来巨大的好处,但是,它们也有缺点。

使用 CSS 预处理器时,您可能会遇到的第一个问题是,它会导致 CSS 文件变得臃肿。这是因为当你写代码的时候,很容易嵌套你的选择器,直到你的选择器变得非常具体和非常长。尽管这不是预处理器的错误,但由于不断嵌套的诱惑,这是一个容易陷入的陷阱。一个很好的例子可能是你想设计一个按钮标签的样式。如果您过度嵌套 CSS 预处理程序代码,它可能看起来像这样:

.main

.container{

.row{

.column{

p{

button{

color: #000

}

}

}

}

}

}

该嵌套代码将编译成如下所示的 CSS:

.main .container .row .column p button{

color: #000

}

在可能的情况下,您可以简单地将目标指向p中的一个按钮,因为在这种情况下,父节点可能与正确定位锚点无关:

p{

button{

color: #000

}

}

看到这个例子后,你应该意识到意外地开始嵌套是多么容易。这实际上是很多开发人员第一次使用 CSS 预处理程序时犯的一个非常常见的错误,所以如果您以前犯过这个错误,请不要担心。一个很好的规则是永远不要让你的嵌套超过三个选择器的深度,这意味着生成的 CSS 将会有更短的选择器。此外,通过不过度嵌套您的代码,可以更容易地使 CSS 可重用。

使用 CSS 预处理程序的另一个缺点是使用它们有一个轻微的学习曲线。尽管嵌套和变量等一些更简单的东西确实很容易掌握,但学习如何编写混合和函数可能需要更长的时间。尽管我在这里讨论的一些预处理程序之间存在语法差异,但是许多核心概念是相同的,所以一旦您选择了一个,就很容易转移到不同的预处理程序。

最后一个缺点是,在项目中设置使用 CSS 预处理器可能需要您对工作流进行更改。您不仅需要在每次保存时编译预处理器代码,还可能需要在部署过程中添加额外的步骤,以便在生产模式下编译预处理器代码。

选择预处理程序

我已经讨论了两个最流行的 CSS 预处理器 LESS 和 Sass,您已经看到了两者之间的一些差异。

Sass 本身提供了很多功能,对函数的支持是一个特别突出的特性。如果您将 Compass 添加到等式中,那么选择 Sass 作为您的预处理器将会增加很多价值。首先,Compass 包括一个 mixins 库,允许您生成不同版本的前缀代码。这比自己定义所有前缀要简单得多。此外,如果您提供一个装满图像的文件夹,Compass 将为您生成图像精灵和 CSS,并在您的页面上显示它们。

然而,LESS 也提供 mixin 库,试图通过提供输出前缀代码的 mixin 来提供类似的功能。然而,没有什么比 Compass 更好的了。

凉亭

Bower 是 Twitter 开发者的一个包管理器,它允许你安装前端包。使用包管理器的主要好处是,不用从 GitHub 或 packages 网站手动下载包,只需从命令行将其添加到项目中。此外,在下载软件包的同时,Bower 将下载它可能拥有的任何依赖项。一个简单的例子是,如果您要下载一个 jQuery 插件,它会检查您当前是否安装了 jQuery,如果发现没有安装 jQuery,它也会为您下载 jQuery。

除了允许你安装软件包之外,Bower 还允许你将软件包更新到新的版本,这意味着用最新版本的库来更新你的项目要容易得多。

装置

Bower 是一个节点包,因此需要安装节点才能工作。可以使用节点程序包管理器通过以下命令安装它:

npm install –g bower

使用

使用 Bower 最简单的方法是简单地运行bower install <package-name>,所以如果您想将 jQuery 安装到这个项目中,您可以使用:

bower install jquery

但是,有时您可能希望指定要安装的软件包的版本。最可能的原因是最新版本缺乏对您需要支持的浏览器的支持。jQuery 就是一个例子,它的 2.x 分支不能在 Internet Explorer 8 和更早的版本中工作,所以如果你想支持这些浏览器,你需要使用 1.x 分支。安装一个特定版本的包可以通过在包名后使用#version-number来实现。对于 jQuery,安装 1.10 版需要以下命令:

bower install jquery#1.10

使用 Bower 的好处之一是,您不需要在自己的源代码控制库中保存依赖项的副本。事实上,我们鼓励您在 bower.json 文件中简单地保存一个依赖项列表。为了能够以这种方式使用 Bower,首先需要初始化项目,这可以通过运行以下命令来实现:

bower init

这是启动一系列关于您的项目的问题,然后用这些信息生成一个 bower.json 文件。然后,您可以开始添加依赖项。有两种类型依赖关系:

General dependencies: These are the core dependencies used by your web site or web application in production. It is also assumed you will use these dependencies in production as well.   Development dependencies: These are the dependencies used specifically when you are developing your site, which might include unit testing, packaging scripts, and documentation generation.  

如果您想将依赖项保存为开发依赖项,您可以简单地将—save-dev标志附加到命令的末尾:

bower install jquery#1.10 –save-dev

类似地,如果您想将依赖项保存为普通的依赖项,您可以简单地将--save标志附加到命令的末尾:

bower install jquery#1.10 --save

将依赖项保存到 bower.json 文件后,另一个想要建立项目的开发人员可以从存储库中下载项目,然后只需在项目的根目录中运行bower install即可自动下载所有需要的依赖项。

咕哝

Grunt ( http://gruntjs.com/ )是另一个使用 Node.js 构建的工具。它有时被称为构建工具,但是,这有点不准确,因为构建工具的唯一目的是将一些源代码转换成最终产品。相反,Grunt 是一个任务跑步者;关键的区别在于,虽然其中一个任务可能是构建您的代码,但它也可以用于运行您想要自动化的任何一系列任务,包括单元测试、回归测试和代码质量检查。对于一个大型项目,拥有一个任务运行器是非常宝贵的,因为它使您能够优化您的工作流程。

使用像 Grunt 这样的任务运行器有几个主要的好处,最明显的是,它可以自动完成你原本需要手动完成的任务,从而节省你的时间。另一个好处是它减少了人为错误的机会——我的意思是,一旦任务被设置,它们每次都以相同的方式运行。如果这是一个手动过程,出错的可能性会更大。

一个大型的开发人员社区已经围绕 Grunt 走到了一起,帮助构建一个令人惊叹的可插入任务生态系统,这些任务可以添加到您的 Grunt 构建中。这意味着有插件可以处理从构建 Sass 到在构建任务完成时通知您的所有事情。

装置

Grunt 接口分为两个组件:第一个是命令行接口组件,它是全局安装的。第二个组件是安装在您的项目上的本地 Grunt 安装。让我们从安装命令行接口组件开始,它是使用命令中的npm安装的:

npm install –g grunt-cli

使用

要开始使用 Grunt,您需要首先建立一个 package.json 文件(如果您还没有的话),只需运行以下命令:

npm init

运行此命令后,将会询问您一些有关项目的信息,这些是您将会被问到的问题:

Name: This is the name of your project, which should not contain spaces or any special characters.   Version: The current version of your project.   Description: The description of your project (optional).   Entry point: This is not applicable if you are just using Grunt on a project. It is used when you are writing a Node.js package (optional).   Test command: A command used to run tests on your project, for a Grunt project you can point this to a Grunt task (e.g., grunt test --verbose) (optional).   Git repository: The URL to the repository used for your project (optional).   Keywords: The keywords about your project.   Author: Your name.   License: If you are distributing the code, what license does it fall under.  

一旦您回答了这些问题,您将看到 package.json 文件的代码。如果没问题,只需按回车键。该项目的 package.json 如下所示:

{

"name": "gruntproject",

"version": "1.0.0",

"description": "First Grunt Project",

"scripts": {

"test": "grunt test --verbose"

},

"author": "Jonathan Fielding",

"license": "MIT"

}

您现在需要在您的项目上执行本地 Grunt 安装,这是通过使用命令npm再次完成的:

npm install grunt --save-dev

这会下载 Grunt 及其依赖项,并将它安装在 node_modules 文件夹中。除此之外,通过使用--save-dev标志,您还可以将它添加到存储在 package.json 中的依赖列表中。因此,下一步是创建一个 Gruntfile。

Gruntfile 是决定您能够运行的任务的文件。要开始使用 Gruntfile,您需要首先创建 Gruntfile.js,并在其中设置基本配置,如下所示:

module.exports = function(grunt) {

//Grunt configuration goes here

grunt.initConfig({

pkg: grunt.file.readJSON('package.json')

});

};

Grunt 配置将加载您之前创建的 package.json 文件,并将其存储在 Grunt 的配置中,这意味着您可以访问有用的信息,如项目名称和当前版本号,而不必再次声明这些信息。准备好这个基本文件后,您现在可以找到一些对这个项目有用的简单任务。要查找插件,只需在 http://gruntjs.com/plugins 进行搜索。Grunt 网站的这个页面允许您搜索所有不同的可用 Grunt 插件。在这一章的前面,我讨论了 CSS 预处理器的使用,所以你可以寻找一个将 Sass 编译成 CSS 的任务。如果您在 Grunt 网站上搜索 compass,您可以找到一个名为 contrib-compass 的 Grunt 插件,这就是您将在下面的示例中使用的任务。

要安装 contrib-compass 插件,您需要再次使用npm,在插件名称前加上grunt-。您还需要使用--save-dev标志将其作为依赖项保存在 package.json 文件中。安装插件的完整命令是:

npm install grunt-contrib-compass --save-dev

下载完成后,您可以将 Grunt compass 插件的配置添加到 Grunt 文件中。您需要做的第一件事是提供配置选项,通过添加到传递给initConfig方法的对象中来完成。对于 Compass 插件,您需要添加一个名为compass的属性,在这个属性中,您可以定义不同的目标,并为每个目标包含不同的选项。对于这个例子,您将简单地建立一个名为dev的开发目标,并提供一些简单的选项来告诉 Compass 文件的位置以及您正在使用的开发环境:

grunt.initConfig({

pkg: grunt.file.readJSON('package.json'),

compass: {

dev: {

options: {

sassDir: 'sass',

cssDir: 'css',

imagesDir: 'images',

environment: 'development',

httpGeneratedImagesPath: ' images'

}

}

}

});

准备就绪后,您现在需要设置任务,您将通过加载您希望能够使用的任务来完成。在这种情况下,您希望能够使用 Compass 任务。这是使用grunt.loadNpmTask方法加载的。您将这些命令放在配置选项之后,因此对于 Compass 插件,命令应该是:

grunt.loadNpmTasks('grunt-contrib-compass');

在测试之前,您需要编译一些文件。让我们使用您在前面学习 CSS 预处理程序时使用的 Sass 文件。准备就绪后,您可以返回到终端并运行命令grunt compass,它将把 Sass 编译成 CSS。如果你现在检查 CSS 文件夹,你会发现 Sass 已经按照你的预期编译好了。

Grunt 的强大之处不仅仅在于你可以单独运行单个任务,而是在于定义任务,这些任务本身运行一系列不同的任务。为此,您可以使用方法grunt.registerTask,该方法允许您定义一个任务名称以及将由该任务运行的一组任务。对于这个例子,数组中只有一个任务,它是指向您定义的dev目标的 Compass 任务:

grunt.registerTask('default', ['compass:dev']);

在上面的例子中,您为任务使用了名称default,这很特别,因为它不像其他任务那样作为参数在命令行中传递,默认任务只是在您运行grunt命令时运行。

到目前为止,我一直专注于使用 Grunt 来编译 Sass 代码,虽然您以前可以简单地通过使用compass命令行工具来完成这项工作,但是通过使用 Grunt,您可以让它更多地成为您工作流程的一部分。已经有超过 3000 种不同的 Grunt 插件可用,其中一些最流行的包括:

grunt-contrib-watch: Allows you to watch files for changes and run tasks based on what has changed.   grunt-contrib-uglify: Allows you to minify and concatenate your JavaScript files.   grunt-contrib-copy: Copies files and folders.   grunt-contrib-jshint: Checks your JavaScript for common errors and mistakes.  

你应该从中吸取的是,Grunt 是一个非常强大和灵活的工具,虽然最初设置它可能会令人望而生畏,但一旦你设置好了任务,它将为你节省大量的时间。有一个巨大的社区正在开发插件和扩展 Grunt,所以随着时间的推移,它的有用性将会继续增长。

吞咽

Gulp ( http://gulpjs.com/ )是一个类似 Grunt 的工具,它是一个任务运行器,可以用来运行一系列任务。任务本身是通过向 Gulp 添加插件来添加的。与 Grunt 采用的基于配置的方法不同,Gulp 采用的方法是您编写代码来完成您的任务。它这样做的方式是,它可以获取一些文件,然后您可以通过需要运行的不同任务来处理这些文件。一个例子是一系列 JavaScript 文件,您可能首先想要连接这些文件,然后将其缩小,要实现这一点,您只需在将最终文件保存回磁盘之前,通过一个“concat”任务,后跟一个“uglify”。这与 Grunt 的工作方式非常不同。

Gulp 采用的这种基于流的方法非常快,这在詹德·马蒂诺( http://labs.tmw.co.uk/2014/01/speedtesting-gulp-and-grunt/ )的测试中得到了证明,他发现在编译 Sass 时,Gulp 比 Grunt 快一秒多。Zander Martineau 还表示,预计随着时间的推移,用于 Gulp 的 Sass 插件将进一步优化,从而使编译速度更快。

安装 Gulp 是一个两步过程,第一步是在您的系统上全局安装 Gulp,这是通过以下命令实现的:

npm install –g gulp

下一步是将 Gulp 安装到您的项目中。为此,您需要使用命令npm:

npm install --save-dev gulp

然后您需要创建一个名为 gulpfile.js 的文件,它是决定您想要运行的任务的脚本文件。在其中,您将首先设置基本代码:

var gulp = require('gulp');

然后,您需要开始添加插件。为了比较 Gulp 和 Grunt 的工作原理,让我们用同样的例子来编译 Sass。为此,您需要使用npm将 gulp-sass 插件安装到项目中:

npm install gulp-sass

然后需要将 gulp-sass 插件放入 gulpfile.js 文件。因为 gulpfile.js 是在 Node 中编写的,所以只需使用require将模块加载到一个变量中:

var sass = require('gulp-sass');

下一步是为 Sass 添加任务,以便它能够将 Sass 文件编译成 CSS。通过使用gulp.task方法,将任务的名称作为第一个参数传递,将函数作为第二个参数传递,可以做到这一点。与 Grunt 类似,如果您将名称设置为default,那么当您在命令行中简单地运行gulp命令时,这个任务就会运行:

gulp.task('default', function() {

});

设置好该任务后,您现在可以开始向该任务添加功能。首先,您需要使用gulp.src方法获取您想要处理的源文件,在 Sass 的情况下,这是您想要编译的原始scss文件。您可以使用pipe方法将文件传输到 S ass方法,它会告诉 Gulp 您想要编译这些文件。最后,您可以使用pipe将编译后的输出传递给gulp.dest,?? 将输出编译后的源文件:

gulp.task('default', function() {

gulp.src('./scss/*.scss')

.pipe(sass())

.pipe(gulp.dest('./css/'));

});

这个例子突出了 Gulp 的关键特性,即如何通过管道将文件从一个方法传递到另一个方法,并在传递过程中对它们执行任务。gulp 插件的一个关键原则是,每个插件处理一件事情,通过组合这些插件,您可以灵活地构建完全符合您需求的任务。

有各种不同的插件可以与 Gulp 一起使用。一些受欢迎的是:

gulp-uglify: The Uglify plug-in can be used to minify JavaScript files.   gulp-concat: The Concat plug-in allows you to concatenate multiple files into a single file.   gulp-jshint: The JSHint plug-in allows you to lint your JavaScript files for common errors.  

Gulp 的主要弱点是,在撰写本文时,它没有 Grunt 那么成熟,这意味着它没有那么多插件,社区仍在学习如何最好地使用它。这并不意味着你不应该使用 Gulp 围绕它有一个快速发展的社区,你只需要确保你的项目需要的插件是可用的。

脚手架

开始一个新项目时,整合初始模板可能非常耗时,因为它通常包括:

Putting together the base HTML   Pulling together any JavaScript libraries you want to use   Adding any CSS frameworks or CSS grids you want to use.  

幸运的是,已经发布了许多不同的工具,允许您生成这些起始模板。让我们来看看其中的一些工具,看看如何将它们集成到您的工作流程中。

自耕农

约曼( www.yeoman.io )是一个项目搭建工具,允许你快速搭建一个基于预定义生成器的项目。有各种各样的生成器可用,尽管如果没有一个符合您的需要,您甚至可以自己编写一个。

一些可用的发电机包括:

webapp   angular   ember   backbone   chromeapp   chrome-extension   bootstrap  

当使用这些生成器时,Yeoman 将搭建文件夹结构和一些特定于生成器的文件。生成器还会在 bower.json 文件中设置任何依赖项,然后运行 Bower install 来下载所有需要的依赖项。

装置

要开始使用 Yeoman,您需要使用npm安装节点包。Yeoman 的节点包叫做yo,它需要在全球范围内安装,这样你就可以在命令行的任何地方访问它来启动你的项目。要在全球范围内安装 Yeoman,您需要使用–g旗帜。因此,安装 Yeoman 的完整命令是:

npm install -g yo

安装 Yeoman 可能需要相当长的时间,因为它需要安装许多依赖项。一旦安装了 Yeoman,只需使用以下命令就可以测试它是否安装正确:

yo

使用

要使用 Yeoman 搭建项目,您需要为您的项目创建一个目录。这可以通过 Finder/Windows 资源管理器或直接从命令行完成。对于此示例,让我们直接在命令行中创建文件夹目录:

mkdir project_directory

cd project_directory

一旦进入目录,就可以开始使用 Yeoman 来搭建项目了。第一次安装时,约曼没有配备任何发电机,因此,要开始安装,你需要安装一台发电机。您可能使用的最常见的生成器是 webapp 生成器,所以让我们首先安装它。第一步是运行yo命令。

然后,您需要使用箭头键选择“安装发电机”并按 Enter 键。然后,您将能够通过输入术语 webapp 来搜索 webapp 生成器(参见图 7-2

A978-1-4302-6695-2_7_Fig2_HTML.jpg

图 7-2。

Yeoman shows a list of generators it finds

然后,您需要使用箭头键向下滚动到“generator-webapp”,选择它后,您只需按 Enter 键。Yeoman 现在将为您下载并安装 webapp 生成器。

您现在应该会看到一个名为“运行 Webapp 生成器”的附加命令在括号中,它将给出您当前安装的发电机的版本。如果列表没有更新,只需选择“让我离开这里”并再次运行yo命令。要运行生成器,只需选择它并按回车键。

有些生成器允许您在设置模板之前选择选项,从而额外配置正在设置的脚手架。webapp 就是这样一个生成器,它将为您提供一系列可配置的选项(参见图 7-3 )。

A978-1-4302-6695-2_7_Fig3_HTML.jpg

图 7-3。

Yeoman gives a list of configurable options

要选择/取消选择这些选项,只需使用箭头键上下移动,并使用空格键来选择/取消选择。对于选定的选项,圆圈填充为绿色,对于未选定的选项,圆圈为空。

当您现在按下回车键时,Yeoman 将首先搭建您的项目,包括为 Grunt 和 Bower 准备配置文件,然后运行npm install 和 Bower install 命令,这将下载所有需要的依赖项。这部分过程可能需要一段时间,取决于您的互联网连接速度。

然后,约曼将确认你的项目已经全部设置好了。

如果在任何时候您发现事情不像您预期的那样工作,您的安装可能有问题。为了对此进行诊断,Yeoman 有一个名为yo doctor的命令,它将检查一切是否按预期工作。只需运行这个命令,Yeoman 就会告诉您是否有任何需要解决的问题。

在这一阶段,你将有一个完全脚手架项目,所以你可以继续建设网站。然而,需要注意的是,许多生成器都会附带预定义的繁重任务。因此,让我们来看看用 webapp generator 设置的简单任务:

grunt: Runs jshint on the JavaScript following by the test and build commands.   grunt build: Compiles the projects, including minifying/concatting js, building the Sass into minified CSS, and compressing and renaming images (for cache busting).   grunt watch: Watches the JavaScript, CoffeeScript, Sass, and style sheets to detect any changes and recompiles if they change.   grunt server: Creates a Node server for running the project, watches for any file changes, and refreshes browser on file change.   grunt test: Runs any tests set up for the project.  

您现在已经看到了使用 Yeoman 搭建项目是多么容易。它是快速开始项目的一个很好的工具,并且有各种各样的生成器可用,很容易找到一个适合你的。

如果您想进一步使用 Yeoman,您可以选择编写您自己的生成器,该生成器专门针对您希望如何搭建您的站点。一旦你编写了自己的生成器,你就可以一次又一次地使用它,并在使用过程中不断完善它。当然,你可以开源,这样其他人也可以使用它。

咕哝初始化

替代的命令行工具 grunt-init(gruntjs.com/project-scaffolding)使您能够快速搭建您的项目。

装置

要开始使用 grunt-init,请运行命令行:

npm install -g grunt-init

使用

尽管 grunt-init 与 Yeoman 有很多相似之处,但是安装模板的方式却非常不同。使用 grunt-init,您需要将生成器添加到一个名为。用户主目录中的 grunt-init。

将它们安装到正确目录的一个简单方法是使用 Git 将它们克隆到。grunt-初始化文件夹。Pascal Duez 开发的 web app grunt-init web app 模板可以在 https://github.com/pascalduez/grunt-init-webapp 找到。您可以使用以下命令行通过克隆来安装此模板:

git clonehttps://github.com/pascalduez/grunt-init-webapp.git

一旦模板存储库的 Git 克隆完成,您就可以使用 webapp 模板来搭建新项目。

要开始,您需要创建项目目录,这可以通过 Finder/Windows Explorer 或直接从命令行完成。对于此示例,让我们直接在命令行中创建文件夹目录:

mkdir project_directory

cd project_directory

现在,您可以使用 grunt-init 为 web 应用程序生成脚手架,这可以通过运行命令并向其传递您之前下载的模板的名称来实现:

grunt-init webapp

运行此命令后,将会询问您以下问题:

Please answer the following:

[?] WebApp package and root directory. (project_directory)

[?] WebApp name. (A human-readable name for the app: Project Directory)

[?] WebApp description. (A human-readable description of the app.)

[?] Version (0.1.0)

[?] Project git repository (git://github.com/jonathan/project_directory.git)

[?] Project homepage (https://github.com/jonathan/project_directory

[?] Author name (Jonathan Fielding)

[?] Author url (none)

[?] Licenses (MIT)

[?] Do you need to make any changes to the above before continuing? (y/N)

回答完这些问题后,grunt-init 将下载并安装脚手架所需的组件。

与 Yeoman 类似,grunt-init 将预配置 grunt file—在 webapp 模板的情况下,它将具有以下命令:

grunt: Runs jshint on the JavaScript.   grunt server: Creates a Node server for running the project, watches for any file changes, and refreshes the browser on file change.  

您现在已经看到了使用 grunt-init 是多么容易。Grunt-init 使安装新模板变得非常简单,因为您可以简单地将它们放入{/中。grunt-init/目录。在本例中,您从公共 Git 存储库中克隆了一个模板,但是,您可以在私有存储库中维护自己的模板,这样您就可以与朋友或同事共享它们。或者,您可以简单地编写自己的生成器并将其放在目录中,不需要源代码控制。

初始化

Initializr ( http://www.initializr.com/ )与 Yeoman 和 grunt-init 非常不同,它是一个基于 web 的工具,可以生成一个可以下载为 zip 存档的脚手架。

使用

要开始使用 Initializr,只需访问 Initializr 网站,之后您将看到该模板的三个起点选项(见图 7-4 )。

A978-1-4302-6695-2_7_Fig4_HTML.jpg

图 7-4。

Initializr web site allows you to choose what type of site you want

选择一个选项后,您将看到配置模板的更多选项。一旦你对你的选择感到满意,你可以简单地点击下载它!按钮(见图 7-5 )。

A978-1-4302-6695-2_7_Fig5_HTML.jpg

图 7-5。

Initializr provides you with the option to fine-tune your template

一旦你下载了搭建好的模板,你就可以马上开始编码了。

如您所见,Initializr 对于快速获得项目模板非常有用,但是,它也有其局限性。关键的限制是所提供的 CSS 只是普通的 CSS,没有提供预处理程序的设置,所以你必须自己做。如果你不打算在你的项目中使用 CSS 预处理器,那么你应该没问题,但是意识到这一点很重要。

脚手架工具概述

我已经讨论了搭建项目的三种不同的工具,其中两种是命令行工具,一种是基于 web 的工具。

首先,Initializr 是一个非常好的工具,可以非常快速地生成脚手架,但是它在创建定制模板的能力上有所欠缺,这一点在易用性上得到了弥补。如果你想要一个快捷、易用的模板,你绝对应该考虑使用 Initializr 然而,如果你需要一个更具体的模板,那么你需要看看约曼或格朗特。

如果你打算主要使用你自己的模板而不是下载预置模板,那么 grunt-init 可能是你唯一的选择。然而,如果你希望能够搜索大量不同的模板,那么 Yeoman 将为你提供额外的灵活性。

其他有用的工具

杰林特

jslint 工具使您能够从 JavaScript 代码中检测错误和潜在问题。包括 Mozilla、脸书和 Twitter 在内的世界各地的开发人员都依赖它来确保它检测到的问题不在它的代码库中。

jshint 能够检测的问题类型是语法错误、泄漏变量和与隐式类型转换相关的错误,它确保您的代码遵循定义的编码约定。

使用 jshint 的主要好处是:

Shows you any simple errors or mistakes in your JavaScript code   Enables you to enforce your team’s coding conventions   Fully configurable so you are not forced to follow someone else’s standards  

我之前讨论过在 Grunt 中使用 jshint,但是,您也可以很容易地将它作为一个独立的命令行工具来快速检查代码的质量。

装置

jshint 工具是一个命令行工具,可由节点包管理器安装。要安装 jshint,只需运行以下命令:

npm install jshint -g

使用

使用 jshint 非常简单——您只需将您想要 lint 的 JavaScript 文件的路径传递给jshint命令:

jshint jsfile.js

然后,jshint 将在您的 JavaScript 文件中查找任何问题,这些问题将与导致问题的行号和字符位置一起输出(参见图 7-6 )。

A978-1-4302-6695-2_7_Fig6_HTML.jpg

图 7-6。

Any issues found by jshint are output to the command line

服务

服务器 serve 是一个简单的节点服务器,它将为您在终端中使用的当前文件夹提供服务。这意味着,如果您需要在本地机器上的服务器上快速抛出一些东西,您可以使用 serve,然后在浏览器中导航到 localhost:3000 来查看您的站点。

装置

要安装服务器,请运行以下命令:

npm install serve -g

使用

开始使用 serve 的最简单方法是导航到您希望为您的浏览器提供服务的目录,然后简单地运行命令:

serve

这将为 localhost:3000 提供当前目录,此外,您还可以指定其他选项:

-F, --format <fmt>: Specify the log format string   -p, --port <port>: Specify the port [3000]   -H, --hidden: Enable hidden file serving   -S, --no-stylus: Disable stylus rendering   -J, --no-jade: Disable Jade rendering   --no-less: Disable less CSS rendering   -I, --no-icons: Disable icons   -L, --no-logs: Disable request logging   -D, --no-dirs: Disable directory serving   -f, --favicon <path>: Serve the given favicon   -C, --cors: Allows cross origin access serving   –compress: Zip or deflate the response  

这些选项使用起来非常简单。如何更改端口的一个示例是使用以下命令:

serve --port 2000

-是啊

关于苹果 iOS 模拟器的一个主要抱怨是打开它需要多少努力。首先,你必须打开 Xcode,然后进入菜单栏,从开发者工具中选择模拟器。幸运的是,有人开发了一个小工具,可以让我们快速、轻松地从命令行打开 iOS 模拟器,这个工具叫做 ios-sim。

装置

ios-sim 是使用npm安装的,要安装它,您需要运行:

npm install ios-sim -g

使用

要使用 ios-sim 命令行工具启动 iOS Simulator,只需运行:

ios-sim start

然而,您可以通过传递--family参数来选择您想要使用的设备:

ios-sim start --family ipad

如果你想加载 retina iPhone,你可以在命令后面加上--retina:

ios-sim start --retina

混合

Mixture ( http://mixture.io/ )是一个将搭建、预处理、测试、模板化、构建和部署整合到一个界面中的工具。

当您第一次打开 Mixture 时,会出现一个窗口,您可以在其中选择想要用来搭建项目的样板文件(参见图 7-7 )。

A978-1-4302-6695-2_7_Fig7_HTML.jpg

图 7-7。

Mixture allows you to select from a variety of popular templates

你可以通过点击你想要的来选择一个样板文件,然后你会被要求提供一个项目的目录。选择目录后,Mixture 将从 GitHub 下载样板文件所需的文件。

设置完成后,您可以点击本地查看(见图 7-8 )直接在浏览器中查看您的项目。

A978-1-4302-6695-2_7_Fig8_HTML.jpg

图 7-8。

A project shown in Mixture

Mixture 会监视你的文件,如果你做了任何修改,它会从 CSS 预处理器处理 CSS 的编译,并自动为你重新加载页面。这意味着您可以并排使用您的文本编辑器,并在进行更改时快速查看所做的更改。

Mixture 是一个非常强大的工具,虽然它缺乏使用 Yeoman、Grunt 和 Bower 的灵活性,但它使用起来要简单得多,因为只需点击几下鼠标,您就可以配置好一个项目并开始工作。当您的项目完成后,您可以轻松地将它部署到一个活动服务器上。

工作流程

到目前为止,我已经讨论了一些很棒的工具,然而,当你建立一个网站时,它们本身只是解决方案的一部分。当你开始将它们整合到一个工作流程中时,它们就会变得非常强大,帮助你更高效地构建网站。

当你开始看开发工作流程时,你可以把它分成五个独立的步骤,如图 7-9 所示。

A978-1-4302-6695-2_7_Fig9_HTML.jpg

图 7-9。

The five steps of the development workflow

更详细地了解这些步骤将有助于您准确理解每个步骤所涉及的内容。

脚手架

当您第一次启动一个新项目时,您通常会花时间设置项目目录和基本文件,并下载标准库,如 jQuery 和 respond.js。这个过程称为搭建,通常是开发过程的第一步。

在本章的前面,我讨论了三种可以用来搭建项目的工具:Initializr、Yeoman 和 grunt-init。这些工具本质上允许您通过自动化更快地完成构建的初始步骤,因此您只需告诉他们您需要什么。

抽象

在开发时,抽象是一种编写代码的方式,这些代码最终会被编译成另一种形式。在这一章中,我讨论了 CSS 预处理程序,它是你以前编写的 CSS 的抽象。然而,CSS 预处理程序并不是您可能在项目中使用的唯一抽象工具。有针对 JavaScript 的抽象工具,包括 CoffeeScript、Dart 和 Typekit,也有针对 HTML 的抽象工具,包括 HAML、Markdown 和 Emmet。

所有这些抽象的目的是让你的开发更有效率。他们通过多种方式做到这一点,包括添加功能,有时甚至简化原始形式。这是工作流的一部分,因为你是在抽象中开发,而不是在原始形式中。

循环

当你建立一个站点时,你通过定期在文本编辑器和浏览器之间切换来迭代,检查你所做的改变。这通常包括切换到浏览器、刷新、检查更改、返回到文本编辑器、进行更改,然后重复。此外,如果您正在使用某种抽象,您需要构建抽象,以便它可以在浏览器中显示。

这是迭代工具让我们的生活变得更容易的地方;它们是允许我们自动构建抽象的工具,当我们做出改变时自动刷新我们的浏览器,等等。

在这一章中,我介绍了几个不同的迭代工具,第一个是compass watch命令,每当 Sass 文件改变时,它将重建 CSS。这真的很重要,因为你不希望每次刷新浏览器页面时都需要手动重建。然而,这是一个单一目的的迭代工具,当你迭代你的项目时,你可能经常使用多个抽象或者想要更多的自动化。这样做的问题是,您不希望必须运行多个单一目的的工具,因为这不仅难以管理,而且还可能存在工具试图同时使用相同文件的潜在冲突。

我之前讨论的另一个工具是 task runner Grunt,正如您所了解的,它非常适合运行多个任务,因此将其用作迭代工具是有意义的,因为在每次迭代中,您都可以使用它来运行一系列任务。grunt 本身并不监视文件,但是,您可以使用 grunt-contib-watch 插件来添加这一功能,您可以像使用 Grunt 插件一样使用和配置该插件。不过,这意味着你可以让 Grunt 监视一个目录,当你对文件进行修改时,你可以让它自动运行你定义的一系列任务。这意味着您可以在单个工具中编译多个抽象,此外还有一些插件,允许您运行诸如重新加载浏览器和运行单元测试之类的任务,以检查您没有破坏任何东西。

除了 Grunt 之外,我还讨论了 Mixture,它是一个 GUI 工具,允许您为站点设置迭代工作流。Mixture 允许你编译一个抽象列表,它可以缩小你的 CSS/JS,这样当你做了一个文件改变时,两者都会为你重新加载浏览器。该工具的缺点是您不能添加任何自定义任务,因此,如果您发现有一个您想要的功能是该应用程序不支持的,您就不能添加它。

构建的迭代阶段是您花费大量时间的地方,因此在这里获得合适的工具非常重要。有许多工具可以帮助您改进处理迭代的方式,投入时间正确设置这些工具可以在以后节省您更多的时间。需要记住的一点是,您的迭代工作流可以按照您认为合适的方式发展,因此,如果您发现某些部分并不真正适合您的项目,您可以调整它以更好地满足您的需求。

建设

在您构建了您的站点之后,您将希望能够为实时部署构建您的代码。这可能包括运行单元测试、构建抽象、缩小 CSS 和 JS 以及压缩图像。

手动执行这些构建任务可能很耗时,因此这就是设置构建工具的重要之处。正如我前面所解释的,您可以使用 Grunt 来定义本身执行多个任务的任务,这意味着您可以为 Grunt 定义一个构建任务,它将运行您已经定义的一系列任务。当我讨论使用 Grunt 编译 Sass 时,我提到了如何为任务定义目标,以及为每个任务定义不同的选项。在编写构建任务时,您应该考虑在您的任务中使用这些目标,以允许您告诉 Compass 等任务您正在部署到生产中。

除了使用 Grunt 来建立你的网站,你也可以使用 Mixture。然而,类似于您如何在迭代阶段使用它的限制,您不能容易地在它们已经支持的基础上向构建过程添加额外的功能,这意味着您受限于 Mixture 支持的构建功能。

了解了如何优化您的构建工作流之后,很容易看到自动化构建过程是多么简单。因为您可能会一次又一次地使用这个构建过程,所以正确地使用它是很重要的。因此,确保您能够在这上面花费足够的时间,并且类似于您的迭代工作流,不要害怕对您的过程进行更改,并继续发展它以适应您的需求。

部署

站点开发的最后一步是将其部署到生产环境中;从历史上看,这可能是一个非常手动的过程,尤其是在只能通过 FTP 访问的服务器上。

您的部署方式很可能因您的服务器设置而异,因此您的工具需要允许您根据您的设置对其进行定制,而不是改变您的工作方式来适应工具。这就是为什么像 Grunt 这样的任务运行器对您的部署工作流是一个很好的补充,因为您可以定义自己的部署任务,该任务将执行您的特定设置所要求的步骤来部署站点。Grunt deploy 任务可以从可插拔任务中构建,这意味着构建适合您的工作流非常容易。

另一个能够自动化部署过程的工具是 Mixture。Mixture 能够将站点部署到两个 FTP 服务器上,对于开源站点,它能够部署到 GitHub 页面上。这意味着一旦配置完毕,您只需点击一个按钮就可以快速部署构建好的站点。主要问题是 Mixture 仅限于部署到 Mixture.io、FTP 服务器和 GitHub 页面,所以如果你的部署过程需要涉及到其他任何东西,那你就倒霉了。

工作流摘要

了解了开发人员工作流程中涉及的不同步骤后,您应该看看本章中讨论的每个工具是如何适应这些步骤的(参见图 7-10 )。

A978-1-4302-6695-2_7_Fig10_HTML.jpg

图 7-10。

How tools fit into the different parts of your workflow

值得注意的是,一些工具本身包含一个工作流,例如 Mixture。如您所见,Mixture 将直接将您从搭建阶段带到部署阶段。这意味着,如果您愿意,您可以在整个项目工作流程中使用单一工具(除了代码编辑器之外)。这样做的局限性在于,你没有足够的灵活性来按照你想要的方式工作。

或者,像 Grunt 这样的工具可以用来帮助你管理工作流程的重要部分;它可以将其他工具作为任务包含在内,为您提供一个通用的界面,供您在迭代代码、构建和最终部署时使用。以这种方式使用 Grunt 确实需要时间来正确设置,所以你需要花时间来充分利用 Grunt。一些工具只是单一用途的工具,它们都服务于特定的目的,但是对于大多数这些工具,有一个简单的插件来包装功能,并使其作为简单的任务可用。这使得它们更易于使用,并允许您将它们更好地集成到您的工作流程中。

一般来说,你需要确保你的工作流程是最适合你的。本章试图介绍各种可以用来改进工作流程的工具,但它们的帮助程度取决于您的工作方式。我建议您查看每种工具并尝试一下——有些您可能喜欢,有些您可能讨厌,但最重要的是了解可能对您有益的工具。

摘要

我们使用的工具可以对我们的开发工作流程产生巨大的影响,因为它们可以使我们以更高效的方式工作,允许我们在完成时交付一个更好的网站。

在本章的前面,我解释了如何使用命令行。理解如何使用命令行非常重要,所以我解释了一些基本的命令来帮助您入门。了解了命令行之后,我接着探索了如何使用版本控制来管理 web 站点的源代码。虽然这在团队中工作时特别重要,但在处理个人项目时也很有用,因为它允许您查看随着时间的推移您做了哪些更改,如果引入了 bug,它将允许您查看引入它的更改。

当设计你的网站时,也有一些工具可以让你的生活变得更简单。我解释了 CSS 预处理程序,它允许您使用 CSS 的抽象来编写样式,然后将抽象编译成 CSS,从而允许您以更快、更灵活的方式编写样式。

管理、安装和升级站点中的依赖项可能是一个乏味的过程,尽管已经讨论了 Bower 的使用,您可以看到有更简单的方法来实现这些目标。我还探讨了流行的任务运行器的优点和缺点,所以现在您应该知道在处理典型的繁重任务时如何利用它们。

最终,你的工作流程真的很重要,它可以是一件非常个性化的事情,所以选择适合你的工作流程很重要。然而,不要害怕随着时间的推移而改进你的工作流程,因为新的工具总是在开发,你的需求可能会随着时间的推移而改变。

在下一章,我们将看看如何通过管理用户旅程来优化我们的响应网站的用户体验。