精通响应式Web设计全绝不原创的飞龙|魔智logo设计在线生成_在线设计_爱学大百科
在响应式Web设计之前,网页设计师和前端开发人员的工作主要集中在将印刷布局转化为网站和应用程序。元素和尺寸是固定的,它们需要适应和缩放的需求并不是我们今天必须考虑的概念的一部分。
设备有各种形状和大小。针对支持(或不支持)某些HTML、CSS和JavaScript技术、UX原则、可用性最佳实践的操作系统和浏览器,以及了解移动设备如何影响我们生活的世界,现在是作为网页设计师和前端开发人员所做的工作的“复杂”部分。
在这本书中,我提供了大量关于RWD如何为更好的网站和Web应用程序提供路径的技术和概念信息。安装和使用Sass,处理图像和视频,以及创建稳健的排版比例来构建响应式电子邮件是本书中您将能够阅读到的一些内容宝石。
升级的时候到了!
第一章,“利用Sass的力量进行响应式Web设计”,从安装Sass的最简单的步骤开始;然后我们学习如何让Sass“监视”我们的SCSS文件。然后,有关基本Sass概念的易于理解的解释,如变量、混合、参数、嵌套、部分文件、@import指令、源映射和Sass注释。我们还学会了自动添加供应商前缀并使用Prepros自动编译我们的SCSS文件。我们讨论了创建混合以尽可能轻松地处理媒体查询,考虑内容如何定义断点。
第二章,“使用HTML5标记我们的内容”,澄清了HTML是一种标记语言,而不是代码。然后,我们讨论了最常用的HTML5元素,这些元素允许我们语义化地标记我们的内容。以简单的方式改善我们构建的可访问性与ARIA角色也是我们要解决的问题。我们还讨论了RWD所需的不同元标记,然后有一个将所有内容整合在一起的示例。
第三章,“移动优先还是桌面优先?”,揭示了为什么以及何时应该使用移动优先或桌面优先。通过示例,我们将学习如何使用自适应Web设计和响应式Web设计来改造网站。我们将了解Respond.js和条件类,以支持在构建移动优先时的旧版浏览器。
第四章,“CSS网格、CSS框架、UI工具包和Flexbox用于响应式Web设计”,帮助我们理解什么是网格,如何使用它以及为什么。有了这个理解,我们在构建网站或Web应用程序时可以做出明智的决定。我们还使用浮动技术和Flexbox创建自定义CSS网格。我们将再次使用条件类来解决旧版浏览器的问题,并借助一个小脚本,我们可以使用.ie10特定选择器来处理IE10的怪癖。
第五章,“设计由大手指驱动的小型UI”,展示了可用性和可访问性在本章中起着重要作用。我们还找到了关于目标区域的不同大小、控件的位置(链接、按钮、表单字段等)以及不同设备上的触摸区域的解释。还有三个关于如何创建菜单按钮的示例,以及三个关于移动导航模式的示例。
第六章,响应式网页设计中的图像和视频处理,是本书中最有趣的章节之一,因为RWD中的图像是一个“事物”。我们将讨论使用元素和srcset属性为不同的图像提供不同的方式。本章还介绍了使用CSS、jQuery和JavaScript使视频具有响应性。我们还将学习使用基于矢量的文件,如图标字体和SVG。
第八章,响应式电子邮件,表明电子邮件在移动设备上的打开次数比在台式机上更多;响应式电子邮件在移动设备上的参与度比非响应式电子邮件更高;人们在台式机上点击电子邮件的次数比在移动设备上更多。我们还将创建一个电子邮件模板作为示例。我们将学习使用CSS重置块来规范那些古怪的电子邮件客户端,并了解到电子邮件的最佳宽度不超过600像素。
所有这些章节都有CodePen演示。
在阅读本书的示例时,需要考虑以下几点:文本编辑器或IDE(本书中使用SublimeText),互联网访问和在您的计算机上安装应用程序的管理员权限。
您可能还需要图像编辑软件,如Photoshop、Fireworks或GIMP。如果您使用其他软件,也完全可以。
如果可能的话,您可以使用一种或两种真实的移动设备来体验示例和演示的正确环境。否则,使用Chrome的DevTool的设备模式功能也可以。
如果您已经了解一些HTML和CSS,并且理解响应式网页设计的原则,那么这本书适合您。无论您是网页设计师还是网页开发人员,无论您是初学者还是经验丰富的网络专业人士,这本书都有您需要学习的内容。
对HTML和CSS的良好理解是必需的,因为RWD在很大程度上依赖于这些技术。对jQuery的一些了解也是推荐的,但不是强制的。
在本书中,您会发现一些文本样式,用于区分不同类型的信息。以下是一些这些样式的示例,以及它们的含义解释。
文本中的代码单词、文件夹名称、文件名、文件扩展名、路径名、虚拟URL、用户输入和Twitter句柄显示如下:“sizes属性也可以与元素一起使用,但我们将专注于使用sizes属性与 标签。”
代码块设置如下:
*,*:before,*:after{box-sizing:border-box;}//Moble-firstMediaQueriesMixin@mixinforLargeScreens($width){@media(min-width:$width/16+em){@content}}任何命令行输入或输出都会以以下方式书写:
geminstallsass新术语和重要单词以粗体显示。您在屏幕上看到的单词,比如菜单或对话框中的单词,会以这种方式出现在文本中:“点击下一步按钮会将您移动到下一个屏幕”。
警告或重要提示会以这样的方式显示在一个框中。
提示和技巧会以这样的方式出现。
在我们深入掌握使用HTML5和CSS3进行响应式网页设计之前,我们需要就技术达成共识,就我们的情况而言,CSS预处理器,特别是Sass。
在本书中,所有的CSS都将以SCSS格式写成Sass。我们编写CSS的方式已经改变,改进非常大。
CSS预处理器如Sass、LESS和Stylus为网络/移动设计师和开发人员提供了新的超能力。是的,我用了超能力这个词,因为这正是我第一次使用Sass仅仅几个小时后的感受,而我使用的只是最基本的东西:
.navigation-bar{display:flex;li{padding:5px10px;}}看到嵌套的li选择器了吗?是的,那就是Sass在起作用。当前面的代码被编译时,就会变成这样:
.navigation-bar{display:flex;}.navigation-barli{padding:5px10px;}提示下载示例代码
让我们来看看本章给我们带来了什么:
了解Sass的工作原理涉及理解几个基本的技术概念:
监视一个SCSS文件意味着Sass监视器在后台监视SCSS文件的任何更改。
以下是我们将要遵循的步骤:
Windows:从以下链接下载Ruby安装程序:
Mac:Ruby预装在所有的Mac上,所以不需要下载任何东西。
Windows和Mac:打开命令行。
Windows提示!
按下Windows+R,输入CMD,然后按Enter。
在命令提示符中键入以下命令(无论您在哪个文件夹中都可以):
Windows,使用以下命令:
geminstallsassMac,使用以下命令:
在撰写本文时,Sass的最新版本是3.4.14。版本/修订可能在书出版时有所不同。
就是这样!Sass现在已经安装在您的计算机上。
我将要向您展示的内容与其他任何Sass教程告诉您要做的完全不同。大多数教程都把事情复杂化了。这是您将阅读到的使用Sass的最简单的方法。
以下的屏幕截图是在Windows上的,但是这个过程可以在任何平台上完全相同地应用。
在接下来的步骤中,您将看到创建后的必要文件夹和文件的示例,而不是如何创建它们:
注意文件扩展名.scss?这是你的Sass文件。是的,现在里面什么都没有,它是空的。
sass--watchscss:css-就是这样!你现在正在使用Sass!
首先,Sass是一种编程/脚本语言。我打赌你没有想到。是的,它是一种专注于提高网页设计师和开发人员创建CSS效率的编程/脚本语言。在本书中,我们将专注于Sass的简单部分,这些部分可以帮助我们更有效地编写CSS,更重要的是,我们会在其中获得乐趣。
实施RWD是耗时的:编码、测试、创建资产、浏览器故障排除,然后再进行更多测试。我们简化编码过程的程度越高,重复性工作越少,我们就变得越有效率,为项目、团队、业务甚至最终用户增加的价值也就越多。Sass将会做到这一点——帮助我们简化CSS的编码。
让我们先讨论以下概念:
我们可以用两种方式编写Sass风格的CSS:Sass语法和SCSS语法。
不要误解;Sass是大写S,其余都是小写,而SCSS全部大写。
Sass语法,也被称为缩进语法,是最初和唯一的编写Sass的方式。但它看起来与常规CSS有些不同,使学习曲线比实际需要的更陡峭。
这种语法没有使用任何大括号或分号。在某些情况下,它使用等号而不是冒号。与SCSS不同,缩进非常严格且是强制性的。许多开发人员对Sass语法的这些方面并不太喜欢。
这是一个基本的例子:
.selector-afloat:left.selector-bbackground:orange这将编译成以下代码:
.selector-a{float:left;}.selector-a,.selector-b{background:orange;}SCSS语法当SCSS在Sass的第3个版本中引入时,对于我们这些不是程序员但想要利用Sass功能的人来说,事情变得更容易了。
SCSS代表SassyCSS。
如果你已经写CSS,那么你已经写了SCSS。我们在编写CSS时已经使用的所有东西,在使用SCSS语法编写Sass时也是一样的。因此,学习曲线最初是不存在的。
然后,你会意识到你还可以使用一些增强你已经知道的Sass功能,这使得学习Sass成为一种很棒的体验,因为你可以相当快地变得擅长它。说实话,这感觉就像你正在获得超能力。我不是在开玩笑。
以下是我们之前看到的相同示例,使用SCSS语法:
.selector-a{float:left;}.selector-a,.selector-b{background:orange;}等一下!那是CSS!是的,它也是SCSS。
让我们以不同的方式使用SCSS语法看同一个例子:
.selector-{&a{float:left;}&a,&b{background:orange;}}在SCSS中,&符号允许我们将父选择器的名称添加到嵌套选择器中,而无需输入整个内容,使我们保持DRY的状态。
DRY表示不要重复自己。
这两个SCSS示例编译为以下代码:
.selector-a{float:left;}.selector-a,.selector-b{background:orange;}Sass变量首先让我们了解一些事情:
在列出多个变量时,每个变量的末尾应该有一个分号(;)。如果只有一个变量,则不需要分号。然而,即使只有一个变量,最好也以分号结束变量,这是一个好习惯。
以下是Sass变量的一个例子:
$brandBlue:#416e8e;提示我建议您使用驼峰命名法来命名变量,以便将它们与以破折号分隔的类名和CSS属性区分开。在扫描SCSS文档时,这非常有帮助,因为变量更容易检测到。
正如我们所看到的,我们正在存储一个颜色值。我们使用的名称brandBlue肯定比#416e8e更用户友好。此外,我们使用了美元符号($)并以分号(;)结束,以防我们需要添加更多变量。现在,如果以后需要更改值,我们只需要在一个位置进行更改。
变量应始终包含在SCSS文件的顶部,以便Sass知道在使用它们时应该去哪里。您还可以通过部分文件包含它们,但我们将在本章后面讨论部分文件是什么。
以下是如何使用SCSS变量的示例:
$brandBlue:#416e8e;body{background:$brandBlue;}上述代码编译为以下内容:
关于Sassmixin需要考虑的几件事情如下:
我们还没有看到参数是什么,但现在提到这个词很重要,这样你就可以开始熟悉不同的Sass术语。我们将在下一节中介绍Sass参数。
让我们看一个mixin的例子:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}我们在SCSS文件中调用mixin如下:
.selector-a{@includegenericContainer;}编译后,在CSS中看起来像这样:
.selector-a{padding:10px;border:#416e8e1pxsolid;background:#cccccc;box-shadow:1px1px1pxrgba(0,0,0,0.3);}让我们回顾一下我们在mixin中所做的事情。
我们使用了@mixin指令:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}我们使用驼峰命名约定来区分mixin的名称和以破折号分隔的类名和CSS属性:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}我们在mixin中使用了Sass变量:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}在box-shadow颜色属性中使用关键字black,而不是使用十六进制#000或rgb(0,0,0)值:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}为此,我们也可以像这样使用我们的变量名:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba($brandBlue,.3);}我们还省略了alpha值中的0(.3)。这实际上不是Sass的特性;这是CSS的特性:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer{padding:10px;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba($brandBlue,.3);}提示在以零开头的小数值上,零可以被省略。
同样,上述mixin编译为以下CSS:
.selector-a{padding:10px;border:#416e8e1pxsolid;background:#cccccc;box-shadow:1px1px1pxrgba(65,110,142,0.3);}Sass参数在我们的第一个mixin示例中,我们没有任何参数。这实际上并不理想,因为它不允许我们在相同的属性中使用不同的值。实际上,在mixin中不使用任何参数并不比每次需要它们时键入相同的属性和值有任何不同。我们并没有真正做到DRY。
参数是mixin的一部分,您可以根据需要放入自己的值。参数使mixin值得创建。
在前面提到的mixin示例中,让我们添加一个参数:
$brandBlue:#416e8e;$supportGray:#ccc;@mixingenericContainer($padding){padding:$padding;border:$brandBlue1pxsolid;background:$supportGray;box-shadow:1px1px1pxrgba(black,.3);}padding参数允许我们设置任何我们想要的值。我们并不强制每次都将填充设置为10px。
这是我们如何设置参数的值:
.selector-a{@includegenericContainer(10px);}这编译为以下内容:
.selector-a{padding:10px;border:#416e8e1pxsolid;background:#cccccc;box-shadow:1px1px1pxrgba(0,0,0,0.3);}但是,参数存在潜在问题;如果我们不为padding设置值,编译时会出现错误。
因此,这里的解决方案是设置一个默认值;如果由于某种原因我们没有为padding定义一个值,Sass将采用默认值并在编译时使用它而不会抛出错误。
以下是如何设置参数的默认值:
.selector-a{@includegenericContainer;}编译后的CSS如下:
.selector-a{padding:8px;border:#416e8e1pxsolid;background:#cccccc;box-shadow:1px1px1pxrgba(0,0,0,0.3);}如何在同一个mixin中使用多个参数在前面的mixin基础上,让我们添加一些更多的参数,使其更加健壮和可扩展:
.selector-a{@includegenericContainer(2%,$brandBlue,#ccc,black);}我们可以使用相同的mixin并获得不同的样式,而无需重复输入所有属性。
前面的mixin及其参数编译为以下代码:
以下是我们如何在参数中设置默认值:
.selector-a{@includegenericContainer(25px);}这编译为以下内容:
.selector-a{padding:25px;border:orange1pxsolid;background:#999999;box-shadow:1px1px1px#333333;}提示某些Sass编译器将简写的颜色十六进制值#333转换为长格式值#333333。
Sass中的嵌套是使我们的SCSS更易读的完美方式。就像在HTML中,标签基于其父元素进行嵌套一样,Sass使用完全相同的结构。
以下是导航栏的两级选择器嵌套示例:
$brandBlue:#416e8e;nav{ul{display:flex;margin:0;padding:0;list-style:none;}li{margin:5px;background:#000;}a{display:block;padding:5px15px;text-decoration:none;color:$brandBlue;}}提示注意深层嵌套!最佳实践建议最多嵌套三个级别。否则,我们将在未来遇到选择器特异性和可维护性问题。
您是否注意到我再次使用了$brandBlue颜色变量?前面的导航栏的SCSS编译为以下CSS:
navul{display:flex;margin:0;padding:0;list-style:none;}navli{margin:5px;background:#000;}nava{display:block;padding:5px15px;text-decoration:none;color:#416e8e;}Sass中的局部文件(partials)局部文件是我们创建的用于存放SCSS片段的SCSS文件。局部文件允许我们模块化我们的文件,例如,_variables.scss。局部文件以下划线符号(_)开头,并以扩展名.scss结尾。下划线符号告诉编译器,这个文件及其内容不需要编译成单独的CSS文件。
局部文件使用@import指令调用,就像在CSS中一样。主要区别在于无需指定下划线符号和文件扩展名。
让我们创建一个局部文件,并把这些颜色变量放在里面。我们将称这个局部文件为_variables.scss。_variables.scss局部中的变量(片段)如下:
$brandBlue:#416e8e;$brandRed:#c03;$brandYellow:#c90;然后我们假设我们的主SCSS文件名为styles.scss。现在我们有两个文件:styles.scss和_variables.scss。
项目的主SCSS文件不以下划线符号开头。
我们使用@import指令将_variables.scss调用到styles.scss中:
@import"variables";注意,在引用局部文件时,下划线符号和文件扩展名是不需要的;它们可以被省略。但是,如果你想添加它们,也可以。省略它们可以使代码更清晰。
许多专业人士说,扩展或继承是Sass最有用的功能之一。其他人实际上建议远离它。本书的建议是:尽可能多地使用Sass,并尝试不同的功能,这样你就可以形成自己的观点。当你有足够的经验时,你可以决定加入哪一方。
在Sass中扩展意味着我们可以在另一个选择器中使用选择器的属性,而不必再次输入所有这些属性。这就是所谓的继承。我们使用@extend指令来实现这一点。
例如,考虑以下选择器:
$brandBlue:#416e8e;.generic-container{padding:10px;border:$brandBlue1pxsolid;background:#ccc;box-shadow:1px1px1pxrgba(black,.3);}假设我们想要在不同的选择器上继承这个选择器的所有属性。我们还要修改一个属性,因为它们几乎是相同的,使用@extend指令在第二个选择器中重用第一个选择器的样式:
.box-customer-service{@extend.generic-container;padding:25px;}这编译成以下内容:
由于我们知道CSS文档是有效的SCSS文档,因此使用CSS注释语法也是有效的:
/*ThisisatraditionalCSScomment*/在Sass中,还有另一种方法。我们可以在开头使用双斜杠(//)进行注释。
//ThisisaSass-stylecomment两种样式之间的区别在于使用/**/语法的传统CSS注释会添加到编译后的文件中,而使用//的Sass注释则不会添加。
Sass语法中的注释非常有用,可以在不必担心所有这些注释被编译并使最终的CSS文件变得臃肿的情况下记录我们的SCSS文件。以下示例中的Sass注释不会被编译:
$brandBlue:#416e8e;//Mixinforgenericcontaineracrosstheapp.generic-container{padding:10px;border:$brandBlue1pxsolid;background:#ccc;box-shadow:1px1px1pxrgba(black,.3);}然而,传统的CSS注释确实被编译了:
$brandBlue:#416e8e;/*Mixinforgenericcontaineracrosstheapp*/.generic-container{padding:10px;border:$brandBlue1pxsolid;background:#ccc;box-shadow:1px1px1pxrgba(black,.3);}提示现在,根据编译器上设置的选项,最终的CSS可以被最小化。因此,传统的CSS注释将被剥离以优化文件大小。
供应商前缀基本上是为尚未被广泛使用或最终包含在CSS3规范中的CSS3属性或值添加特定的标签。
供应商部分指的是代表创建浏览器的公司名称的缩写标签:Mozilla、Opera和Microsoft。
不过,有一个例外,苹果。尽管苹果创建了Safari,但供应商前缀是基于浏览器的布局引擎而不是公司名称。
前缀部分指的是在CSS属性或CSS值之前添加供应商标签的描述。每个供应商前缀只在自己的浏览器中有效,因此对于上述列表,这里是它们所属的浏览器:
如果你想知道谷歌Chrome在这一切中的位置,这有一个简单的解释。
尽管谷歌创建了Chrome,但Chrome没有特定的前缀。起初,Chrome使用与Safari相同的布局引擎:Webkit。因此,基于Webkit的前缀不仅影响了Safari,还影响了Chrome和其他基于Chromium的产品。
然而,谷歌浏览器不再使用Webkit;它现在使用自己的布局引擎称为Blink。然而,为了保持兼容性并避免进一步分裂网络,Chrome仍然支持-webkit-前缀。
Opera有一个类似的故事,他们有自己的布局引擎Presto,然后切换到Webkit。现在它使用Blink。除了之前提到的浏览器供应商之外,还有其他浏览器供应商,他们也使用自己的前缀,比如Konqueror浏览器的前缀-k-。
这是一个带有供应商前缀的CSS属性的例子:
-moz-box-sizing:border-box;这里有一个带前缀的CSS值的例子:
background-image:-webkit-linear-gradient(red,blue);供应商前缀的顺序事实上,我们列出供应商前缀的顺序并不重要;重要的是我们总是将非供应商前缀的版本放在最后。
以linear-gradient属性为例,我们应该这样做:
*,*:before,*:after{background-image:-webkit-linear-gradient(red,blue);background-image:-moz-linear-gradient(red,blue);background-image:-ms-linear-gradient(red,blue);background-image:-o-linear-gradient(red,blue);background-image:linear-gradient(red,blue);}提示如果你喜欢,你也可以使用background:linear-gradient(red,blue);。
现在,许多CSS3属性和值不需要所有供应商前缀。大多数情况下,它们只需要一些供应商前缀,其他时候非供应商前缀的属性或值就足够了。
但是,我们如何知道哪些CSS3属性和值可以加前缀,哪些不需要,这样我们就可以创建受某些旧浏览器支持的样式,而不必记住太多信息?
答案是自动化供应商前缀的过程。
供应商前缀带来了一些问题,如果我们希望一些CSS3属性在当前浏览器和/或某些旧浏览器中工作,我们就无法摆脱这些问题。供应商前缀是肮脏的工作,我们不必须这样做。
那么,我们如何在尽可能保持DRY的情况下自动化供应商前缀的过程呢?有几种方法。
Compass是一个帮助我们更有效地编写CSS的Sass框架。Compass有一个庞大的mixin库,我们可以使用它来处理供应商前缀。
一旦我们安装了Compass,我们需要导入包含我们需要的mixin的特定模块。
继续使用之前使用的线性渐变示例,让我们将Compass的images模块导入到我们的SCSS文件中。将其放在主SCSS文件的顶部:
@import"compass/css3/images";然后,我们可以使用相应的mixin:
header{@includebackground-image(linear-gradient(red,blue));}这将编译为以下内容:
header{background-image:url('data:image/svg+xml;base64,…');background-size:100%;background-image:-webkit-gradient(linear,50%0%,50%100%,color-stop(0%,red),color-stop(100%,blue));background-image:-moz-linear-gradient(red,blue);background-image:-webkit-linear-gradient(red,blue);background-image:linear-gradient(red,blue);}这里有一些新东西。
header{background-image:url('data:image/svg+xml;base64,…');background-size:100%;background-image:-webkit-gradient(linear,50%0%,50%100%,color-stop(0%,red),color-stop(100%,blue));background-image:-moz-linear-gradient(red,blue);background-image:-webkit-linear-gradient(red,blue);background-image:linear-gradient(red,blue);}正如我们所看到的,Compass是一个非常方便的工具,它允许我们自定义输出。然而,这可能会变得比必要的工作更多。
在得出Compass是否是我们的最佳解决方案之前,有一些事情需要考虑:
-prefix-free是由LeaVerou创建的JavaScript文件。当浏览器调用该脚本时,它会检测到,然后将该浏览器特定的前缀添加到CSS中。-prefix-free文件足够智能,可以确定需要哪些前缀,并且只注入那些前缀。
使用-prefix-free很简单。只需调用JavaScript文件。根据LeaVerou的建议,最好在样式表之后包含此脚本,以减少未样式内容的闪烁(FOUC)。
由于我们的HTML代码如此简短,我们可以遵循之前提到的提示:
让我们看一下在决定使用-prefix-free之前需要考虑的事项的简短列表:
有了这个列表,我们现在可以更好地做出一个更明智的决定,这将使项目、我们自己和我们的用户受益。
Autoprefixer是一个CSS后处理器,它使用CanIUse.com数据库为已编译的CSS文件添加供应商前缀。
术语后处理器意味着它在创建CSS之后(后)处理它。换句话说,如果我们有一个名为styles.scss的SCSS文件,当我们保存它时,该文件会被编译为styles.css。在那一刻,Autoprefixer获取生成的styles.css文件,打开它,为每个属性和值添加所有必要的供应商前缀,保存文件,并关闭它。此外,您还可以配置它创建一个新的单独文件。完成后,我们可以在我们的网站/应用程序中使用此文件。
这种方法相对于任何其他自动供应商前缀方法的主要优势是它使用CanIUse.com数据库;这意味着一旦浏览器供应商不再需要其前缀用于CSS属性或值,我们只需通过Autoprefixer运行我们的CSS文件,它将在几秒钟内更新。
Autoprefixer的主要缺点是它有太多的使用方式,对一些人来说可能有点压倒性。举几个例子,我们可以通过命令行使用它,但首先需要安装Node.js:
npminstall--globalautoprefixerautoprefixer*.css我们也可以在Compass中使用Autoprefixer,但首先需要安装Ruby:
geminstallautoprefixer-rails我们可以在Mac上使用CodeKit,在Windows/Mac/Linux上使用Prepros或KoalaApp。我们还可以为SublimeText、Brackets或AtomEditor安装插件。还有Grunt和Gulp插件。
在决定使用Autoprefixer之前,让我们看一下需要考虑的事项的简要清单:
是的,它是三个e的Pleeease。Pleeease也是一个类似Autoprefixer的CSS后处理器,它也依赖于已安装的Node.js。它只能通过命令行运行,但实际上非常简单。Pleeease使用Autoprefixer,这意味着它也使用CanIUse.com数据库来定义哪些CSS属性和/或值需要前缀。
安装Pleeease后,我们需要创建一个配置文件(JSON文件),其中我们需要定义的最重要的事情是源CSS文件和目标CSS文件:
{"in":"style.css","out":"styles.fixed.css"}一旦我们设置了配置文件,我们在命令行中运行这个命令:
pleeeasecompilePleeease获取style.css文件,添加所有必要的供应商前缀,并创建styles.fixed.css,这是我们在生产中使用的文件。
在这一点上,Pleeease还有其他重要的事情:
如果您习惯使用命令行和JSON文件,Pleeease可以成为您工具库中非常有用的一部分。如果您更喜欢远离命令行,也没关系;还有其他更友好的方法来自动添加供应商前缀。
在决定是否使用Pleeease自动添加供应商前缀之前,有一些需要考虑的事项:
Emmet使我们能够更快地编写CSS和HTML。它是文本编辑器的插件,如SublimeText、Coda、TextMate,甚至Dreamweaver。
Emmet以前被称为ZenCoding。
一旦Emmet插件安装在我们喜爱的文本编辑器中,我们在SCSS文件中输入以下内容:
.selector-a{-trf}提示-trf是CSS3属性transform的缩写。
然后我们在键盘上按下Tab,代码会自动更改为这样:
.selector-a{-webkit-transform:;-ms-transform:;-o-transform:;transform:;}我们只需要在缩写的开头加一个破折号(-)来添加供应商前缀。这告诉Emmet在按下Tab键时需要添加必要的供应商前缀。
在上一个例子中未定义变换值,因为我们想展示使用Emmet的结果。显然,我们最终需要添加这些值。
在决定是否使用Emmet自动添加供应商前缀之前,有一些事情需要考虑:
正如我们所见,以前用于自动添加供应商前缀的方法是各种各样的,从通过命令行使用的方法到让您在使用JavaScript解决方案之前找到特定模块导入的方法。
提到的所有功能中最重要的是Autoprefixer使用CanIUse.com数据库。这基本上是我们想要使用的,因为我们只需要编写CSS3属性和值,然后完全忘记供应商前缀,让Autoprefixer和CanIUse.com为我们添加它们。
幸运的是,已经有第三方应用程序安装了Autoprefixer。这意味着我们不需要通过命令行设置任何东西,也不需要安装插件,或者类似的东西。只需安装应用程序,激活Autoprefixer复选框,然后开始使用!
之前我们提到了几个应用程序:CodeKit、Prepros和Koala应用。它们基本上都做同样的事情,但它们在两个方面表现出色:
这两个功能对我们的工作流程有很大影响,使我们能够将精力集中在重要的事情上,比如RWD和更好的用户体验。
在决定使用第三方应用程序是否是添加供应商前缀的最佳解决方案之前,有一些事情需要考虑:
本书建议您使用CodeKit、Prepros或Koala应用程序来处理供应商前缀。这些应用程序不仅可以编译SCSS文件,还可以在保存这些SCSS文件时自动通过Autoprefixer运行它们。
所以让我们来看看Prepros,它可以在Windows、Linux和Mac等最流行的操作系统上运行。
使用命令行编译我们的SCSS文件真的并不那么困难:
--sasswatchscss:css这就是我们在命令行中需要做的一切,以便Sass监视/scss文件夹中的SCSS文件,并将它们编译到/css文件夹中。真的就是这么简单。
以前的情况是,每次我们需要在不同的项目上工作时,都需要运行这个命令。虽然我们可以用许多不同的方式来自动化这个过程,但有些人觉得使用命令行要么令人生畏,要么只是不必要的。
Prepros是一个面向网页设计师和开发人员的工具,涉及到常规工作流程的许多部分:编译、CSS前缀、实时刷新、JavaScript合并、文件最小化、图像优化、浏览器测试同步、为编译文件创建源映射、内置服务器、FTP等等。
在本书的范围内,我们将重点介绍它如何帮助我们在自动添加供应商前缀的同时编译我们的SCSS文件。
还有一种方法可以免费使用Prepros并享受应用程序的所有功能。不过,这是以不得不每5分钟左右关闭购买应用程序弹出窗口为代价的。
这是Prepros的当前欢迎界面(可能已经改变):
还记得安装Sass时的步骤吗?我们创建了一个/Demo文件夹,并在其中创建了两个子文件夹/scss和/css?我们将把/Demo文件夹拖放到Prepros界面上:
一个悲伤的表情出现了,让我们知道项目是空的。这是真的,因为我们还没有向/scss文件夹中添加任何文件:
所以,让我们在/scss文件夹中创建一个.scss文件:
Prepros将自动检测新的styles.scss文件并将其编译为styles.css文件,保存在/css文件夹中。
单击styles.scss文件将显示文件的默认设置:
让我们修改一些设置,以便Prepros可以自动执行以下操作:
sourcemap是一个带有.map扩展名的文件,它与我们的CSS文件一起生成。这个映射文件包含了将我们的CSS文件的每一行链接到我们的SCSS文件和局部文件中相应行的必要信息。当我们需要通过任何现代网页浏览器的DevTools检查元素的样式时,这一点至关重要。
在输出样式部分,我们将把设置保留为Expanded。
四种输出样式之间的区别很简单:
这是传统的CSS样式,其中每个选择器、属性和值都在单独的一行上:
header{background:blue;}header.logo{float:left;}.container{float:right;}嵌套输出你可以看到第二个规则是缩进的,这意味着它属于header选择器:
header{background:blue;}header.logo{float:left;}.container{float:right;}紧凑输出所有规则都在一行中,如下所示:
header{background:blue;}header.logo{float:left;}.container{float:right;}压缩输出这是被压缩的版本,这是我们在生产中应该使用的版本:
header{background:blue;}header.logo{float:left;}.container{float:right;}就是这样。我们现在让Prepros运行。它将添加所有供应商前缀,并在我们保存时编译SCSS文件。让我们看看它的运行情况。
每次我们点击保存,Prepros都会在屏幕右下角显示以下对话框中的一个。
成功将给我们以下输出:
错误将给我们以下输出:
让我们拿出我们的styles.scss文件,然后添加一个需要一些供应商前缀的简单CSS规则。
当我们保存styles.scss文件时,Prepros会显示绿色/成功的对话框,并将我们的SCSS文件编译成styles.css。
这是编译后的文件,自动添加了所有前缀:
随着浏览器的发展,CSS3属性和值被标准化,越来越少的属性需要供应商前缀。我们的CSS文件应该反映这一点,这样我们就不会在样式表中填充不必要的前缀。
Prepros允许我们定义在应用前缀时要支持多少个旧版浏览器版本。步骤如下:
如果你看不到线性渐变属性在开头被加上前缀,尝试将值更改为非常高的值,比如40,这样它就会显示最后40个版本。保存你的SCSS文档,然后再次检查你的CSS文件。
就是这样。
在我们继续之前,有一点非常重要的说明。到目前为止,我们已经讨论了通过--watch标志使用命令行以及使用Prepros来编译我们的SCSS文件。请注意,只需要运行一个编译器。同时运行CMD和Prepros编译相同的SCSS文件是不必要的。
有许多方法可以创建一个Sassmixin来存放媒体查询:只有变量的mixin,为不支持媒体查询的旧版浏览器提供NoQueries回退的mixin,以及(对于Compass)插件,比如Breakpoint。还有其他技术,比如命名媒体查询。另一种技术是一个简单的三行mixin,可以用于我们想要的任何东西。
它们都很好,而且非常强大。然而,在本书的范围内,我们将专注于两种简单的方法,这将使我们能够高效,保持简单,并利用mixin的功能。
到目前为止,你学到的关于Sass的一切,特别是关于mixin的部分,都体现在创建一个用于存放RWD媒体查询的部分文件中。
请记住,部分文件是我们创建的用于存放SCSS片段的SCSS文件。它们的文件名以下划线符号开头,以.scss扩展名结尾。
命名媒体查询和断点的方法和网页设计师和前端开发人员一样多。每个人都有自己的方式和风格。
无论您使用哪种方法,重要的是开始使用Sassmixin来自动化这个过程。随着我们构建站点或应用程序并成为更好的网页设计师/前端开发人员,我们会发现其他解决方案可能效果更好。
有几种方法可以命名您的媒体查询mixin:
由于我们不知道我们的内容会在哪里中断,我们需要一个初始mixin,我们可以在构建响应式站点/应用程序时添加值,我们将从一些已知的、特定宽度的值开始。请理解这些值很可能会改变,并且会向这个mixin添加许多其他值。
我们将把这个文件命名为_mediaqueries.scss。媒体查询mixin看起来像这样:
//Mobile-first@mixinminw($point){@if$point==320{@media(min-width:20em){@content;}}@elseif$point==640{@media(min-width:40em){@content;}}@elseif$point==768{@media(min-width:47.5em){@content;}}}这是我们在主SCSS文件中使用mixin的方法:
header{width:50%;//Propertiesforsmallscreensbackground:red;@includeminw(640){width:100%;//Propertiesforlargescreensbackground:blue;}}这是mixin编译的结果:
首先,我们看到Sass风格的注释,描述这个mixin是为移动优先方法而设计的:
//Mobile-first然后,我们有开放的@mixin指令。这个指令包含mixin的名称minw,它是minimum-width的缩写。我们将保持这个名称简单,因为我们将经常输入它,所以输入minw比输入minimum-width更快,同时仍然保持有意义的术语。
括号中,我们有($point)参数,它将存储我们在定义要使用的断点时指定的值:
@mixinminw($point)然后,我们有一个开放的@if语句。记住我们说过Sass是一种编程/脚本语言吗?有什么比if-else语句更能代表编程语言呢?
@if语句后面是等于(==)320像素宽度的$point变量。两个等号(==)表示它绝对等于值,即320:
@if$point==320之后,我们有CSS@media指令,我们以前见过很多次。在这个指令中,我们以em为单位指定宽度,在这个例子中是20em。
@media(min-width:20em)然后,我们有@content指令,允许我们在括号之间放任何内容:
@media(min-width:20em){@content;}接下来是带有@else语句的$point变量,两个等号(==)和值640。如果定义的值是640而不是320,那么mixin可以继续使用这个特定的媒体查询,适用于640像素宽度。
@elseif$point==640这意味着640像素是40em:
@media(min-width:40em){@content;}最后,我们有相同的媒体查询结构,适用于768像素宽度。768像素等于47.5em。
在选择让内容定义断点的方法之前,请考虑以下几点:
这是许多前端开发人员喜爰的。这个mixin几乎与我们刚刚看到的那个相同;不同之处在于,它不是使用特定的宽度并知道这些宽度将改变并添加其他宽度,而是使用设备特定宽度的抽象名称,通常已经定义了断点列表。
这是这个mixin的样子:
//Mobile-first@mixinbreakpoint($point){@if$point==small{@media(min-width:20em){@content;}}@elseif$point==medium{@media(min-width:40em){@content;}}@elseif$point==large{@media(min-width:48em){@content;}}}这是我们如何使用它的方式:
header{width:50%;//Propertiesforsmallscreensbackground:red;@includebreakpoint(medium){width:100%;//Propertiesforlargescreensbackground:blue;}}这是编译后的样子:
header{width:50%;background:red;}@media(min-width:40em){header{width:100%;background:blue;}}在选择命名媒体查询方法之前,请考虑以下几点:
这是在处理媒体查询时推荐使用的mixin,它具有以下优点:
现在,考虑到我们的建议是让内容定义断点,这里是mixin:
@mixinmobileFirst($media){@media(min-width:$media/16+em){@content;}}就是这样——一个仅有三行的mixin。这是我们如何使用它的方式:
header{width:50%;//Propertiesforsmallscreensbackground:red;@includemobileFirst(640){width:100%;//Propertiesforlargescreensbackground:blue;}}这是它编译成的样子:
header{width:50%;background:red;}@media(min-width:40em){header{width:100%;background:blue;}}现在,你可能会问自己,“em值是从哪里来的?”
这很简单。我们将期望的宽度除以16。我们除以16的原因是因为16px是所有浏览器的默认字体大小。通过这样做,我们得到了以em单位为单位的值。
如果你想使用16px作为默认字体大小,请考虑以下示例:
如果你决定你的默认字体大小不是16px而是18px,那么同样的过程适用。将期望的宽度除以18px:
选择权在你手中。
我们所有的示例都将基于16px的默认字体大小。
在本章中,我们涵盖了很多内容,但最好的还在后面。我们学会了如何安装Sass以及如何让它监视我们的SCSS文件。我们还了解到有两种不同的语法:Sass和SCSS。我们现在知道任何CSS文件都是有效的SCSS文件,如果我们现在知道如何编写CSS,我们也知道如何编写SCSS。我们讨论了Sass的不同基本概念,如变量、mixin、参数、嵌套、部分文件、@import指令、源映射和Sass注释。
我们还学会了什么是供应商前缀和帮助自动化这个过程的不同方法。我们决定使用Prepros来执行以下任务:监视、编译SCSS文件和自动添加前缀。我们学会了创建一个部分文件来容纳我们的媒体查询mixin,名为_mediaqueries.scss。我们还学会了使用基本mixin来命名媒体查询的不同方法,这个mixin向我们展示了如何简单地处理媒体查询,同时遵循让内容定义断点的最佳实践。
在下一章中,我们将深入研究HTML5以及如何标记我们的内容以准备进行RWD。准备好你的浮潜装备!
许多人认为HTML是代码。嗯,不是的。HTML——任何版本的HTML——都是标记语言。
标记语言是一种可以被人类阅读和理解的计算机语言。它使用标签来定义内容的各个部分。HTML和XML都是标记语言。
为了更好地区分,编码语言涉及更复杂的抽象、脚本、数据库连接、通过复杂协议以某种形式传输数据等等。编码确实是一个神奇的世界。
HTML可以做到这一切,但它远没有那么复杂,更容易理解。
在本章中,我们将专注于标记内容背后的科学。内容可以以许多不同的形式呈现:文本、图像、视频、表单、错误消息、成功消息、图标等等。此外,特定类型的内容在浏览器中的行为或用户与之交互的方式将告诉我们应该将特定内容标记为什么类型的HTML元素。
我们的目标是尽可能地保持语义标记。语义标记基本上意味着我们使用HTML标签来描述特定内容是什么。保持语义标记有很多好处:
我可以给你的最好建议是在标记内容时倾听内容;它会和你交流。真的会。
我们将在本章中涵盖以下主题:
那么,现在我们可以使用哪些HTML元素,以确保我们的网站/应用在所有浏览器中都能正常显示呢?答案是所有元素。
2014年10月28日,W3C完成了HTML5标准。然而,所有主要浏览器多年来一直支持HTML5元素。
对我们来说,这意味着即使在W3C完成HTML5标准之前,我们已经可以使用任何HTML5元素。所以,如果你一直在使用HTML5构建网站/应用,继续使用吧;如果你还没有因为任何特定原因开始使用HTML5,那么现在是开始的时候了。
根据MozillaDeveloperNetwork(MDN)的定义:
以下是关于元素的几个重要要点:
考虑以下例子:
Contentgoeshere提示为了谨慎起见,使用HTML实体表示特殊字符,例如,和字符(&)是&,省略号字符(…)是…。根据MDN的定义:
以下是关于元素的几个重要要点:
“自包含”意味着如果我们将元素及其内部内容移到另一个上下文中,所有内容都是不言自明的,不需要其他东西来理解。
Contentgoeshere元素根据MDN的定义:HTML节元素()代表文档的一个通用部分,即内容的主题分组,通常带有标题。每个
以下是关于
AspertheMDNdefinition:
TheHTMLMainElement(<main>
)represents…
元素根据MDN的定义:以下是关于
AspertheMDNdefinition:
TheHTMLMainElement(<main>
)represents…
WhatDoes"SemanticHTML"Mean SemanticmarkupbasicallymeansthatweuseHTMLtagstodescribewhataspecificpieceofcontentis.
提示切题内容意味着内容涉及手头的主题,但不是主要信息的一部分。如果元素内的内容被移除,主要信息不会受到影响。通常,我们认为网站/应用的顶部部分是页眉,这是正确的。该顶部部分的编辑名称是标志。
然而,从HTML5的角度来看,标志和页眉之间有区别。
标志是网站/应用的主要页眉,只能有一个。它通常包含标志、一些导航,可能还有搜索字段等。页眉可以被认为是任何部分的顶部区域,可以有多个页眉。
请注意,我们还没有讨论
标志可以使用
以下是MDN的定义:
HTML元素代表一组介绍性或导航辅助信息。它可能包含一些标题元素,还可能包含其他元素,如标志、包装部分的页眉、搜索表单等。
以下是关于
在以下示例中,有两个突出显示的
MasteringRWDwithHTML5&CSS3 AspertheMDNdefinition:
TheHTMLMainElement(<main>
)represents…
WhatDoes"SemanticHTML"Mean SemanticmarkupbasicallymeansthatweuseHTMLtagstodescribewhataspecificpieceofcontentis.
元素根据MDN的定义:以下是关于
HTML导航元素()代表页面中链接到其他页面或页面内部部分的部分:一个带有导航链接的部分。
以下是关于元素的几个重要要点:
在本章中,我们将介绍WAI-ARIAlandmarkroles是什么,以及如何在我们的标记中轻松实现它们,以增强我们文档的语义,为那些使用辅助技术的用户在任何现代浏览器上使用键盘浏览我们的网站/应用程序时提供更好和愉快的体验。
WAI-ARIA代表WebAccessibilityInitiative–AccessibleRichInternetApplications。
WAI-ARIAlandmarkroles也可以称为ARIAroles,所以这是我们将使用的术语。
当在HTML5元素中实现ARIA角色时,它看起来像这样:
我们可以使用多个ARIA角色,但在本书中,我们将专注于那些更容易实现并且能够有效增强我们网站/应用程序可访问性的角色。
以下是一些重要的要点需要记住:
考虑以下示例:
MasteringRWDwithHTML5&CSS3
导航角色以下是一些重要的要点需要记住:考虑以下示例,其中角色应用于主要的元素:
Contentgoeshere 内容信息角色以下是一些重要的要点需要记住:考虑以下示例,其中角色应用于站点的搜索
表单角色以下是一些重要的要点需要记住:补充角色以下是一些重要的要点:
WhatDoes"SemanticHTML"Mean SemanticmarkupbasicallymeansthatweuseHTMLtagstodescribewhataspecificpieceofcontentis.
注意WAI-ARIA角色解释
网页设计师和开发人员使用元标记的方式有很多,但这些广泛的解释超出了本书的范围,所以我们将专注于对RWD有用且按预期工作的一些要点。
以下元标记对我们的响应式网站/应用非常重要。这些元标记不仅适用于HTML5页面,它们也适用于任何HTML版本。
让我们开始吧。
viewport元标记是RWD中最重要的元标记。它是由苹果在其移动Safari浏览器中引入的。现在,其他移动浏览器也支持它。奇怪的是,这个元标记并不属于任何网页标准,但如果我们希望我们的响应式网站/应用在小屏幕上正确显示,它是必不可少的。
这个元标记的推荐语法如下:
以下是一些重要的要点:
本书强烈不建议使用以下viewport属性:maximum-scale=1和user-scalable=no。通过使用这些viewport属性,我们剥夺了用户在我们的网站/应用中进行缩放的能力。我们永远不知道缩放对任何人都可能很重要,所以最好远离包含这些viewport属性。
为了帮助尚未响应式的网站在小屏幕上显示得更好,添加网站构建时的特定像素宽度。例如,如果一个网站宽度为960px,就给它添加这个viewport元标记:
X-UA-Compatible元标记仅针对InternetExplorer及其兼容性视图功能。众所周知,Microsoft在IE8中引入了兼容性视图。
不再需要使用chrome=1值,因为ChromeFrame在2014年2月被停用了。
GoogleChromeFrame是一个针对旧版本IE的插件。安装后,它会替换IE中的某些模块,如渲染和JavaScript引擎,从而改善用户体验。换句话说,它就像在IE上安装了一个小版本的GoogleChrome。
charset元标记告诉浏览器使用哪种字符集来解释内容。有人说包含它并不那么重要,因为服务器本身会通过HTTP头将字符集发送给浏览器。但在我们的页面中包含它总是一个好的措施。
在HTML5中,这个元标记的推荐语法是这样的:
以下是一些重要的要点需要记住:
现在我们已经了解了一些基本的HTML5元素,它们可以应用的ARIA角色,以及适合显示的正确元标记,让我们在一个完整的HTML5页面中将它们可视化:
以下的SCSS代码是使用桌面优先的方法构建的,因为我们将会逐步进入移动优先的方式。
这是SCSS:
在线框截图中,白色轮廓和不同色调的灰色背景基本上是视觉提示,帮助你理解每个元素的边界在哪里,而不必使用浏览器的开发工具。
另一方面,样式化截图向你展示了用少量CSS可以实现什么。线框和样式化页面都使用完全相同的标记。
页面的演示可以在这里看到:
让我们看看截图。
桌面输出[线框]如下:
桌面输出[样式化]如下:
移动设备的输出[线框]如下:
移动设备的输出[样式化]如下:
这是一个简短的章节,但它肯定充满了重要信息。
我们学到了HTML是标记而不是代码。我们还看到了各种HTML5元素的作用。这将帮助我们理解可以用哪些HTML5元素来标记我们提供的内容。
我们还学会了如何使用ARIA角色标记HTML,以使我们的站点/应用对使用辅助技术的用户更加可访问。
我们还讨论了一些重要的元标记,这些标记将帮助您的页面和标记在不同设备上正确显示,并触发InternetExplorer中的最新HTML和JavaScript引擎。
最后,我们看到所有上述主题在一个实际的完整HTML5示例中实现,以及它的SCSS。该示例是使用桌面优先方法构建的;这将使我们能够有条不紊地将我们的思维模式转变为移动优先技术。
下一章将讨论何时以及如何使用移动优先和/或桌面优先方法,以及如何使用每种方法论。拿出你的水晶球!
在我多年的响应式网站设计和构建经验中,我发现为了更好地查看内容和消息,在线框和设计阶段使用桌面优先方法更容易可视化事物。
由于桌面优先方法允许我们在给定布局中看到更多内容,因此我们可以将提供给我们的内容的层次结构转化为代表该层次结构的布局。在320像素宽的小画布上进行此操作比需要更困难。
当您完成了这种层次结构,它将在小屏设备上保持不变,唯一改变的是布局。
最佳实践建议首先构建移动,但许多网络专业人员实际上并不知道为什么我们首先构建移动。双关语。
考虑以下几点:
现在您有了最终设计,现在您需要将该设计实施到HTML、CSS和JavaScript中。在这个阶段,您应该使用移动优先方法,并考虑我们之前提到的三个原因:
在本章中,我们将涵盖以下主题:
让我们看看一些术语,以便我们在同一页面上:
术语明确后,让我们继续。
以桌面优先的方式创建设计的原因很简单:房地产(空间)。
作为设计师,我们需要以视觉方式反映内容的层次结构。为了实现这一点,我们使用许多设计原则,如节奏、接近性、空白、模式、对比、平衡、网格、对称等等。
当我们创建线框或设计/构图的画布足够大,可以尝试不同的排列和布局,我们就有了必要的灵活性来探索可以代表所述内容层次结构的不同方式。
例如,我们正在使用一个12列网格,我们提供的内容决定了以下内容层次结构:
有了前面的内容层次结构,我们可以立即开始构想不同的布局来传达这个层次结构:
以移动优先的方式创建这样一个布局几乎是不可能的。小型房地产屏幕非常受限制和有限。但当事情开始增长时,我们需要每次考虑特定断点时进行这个探索过程。
实际上,我们在这一点上不应该考虑断点(无意冒犯),因为内容而不是特定的设备宽度决定了需要添加新断点的位置。
一旦我们定义了反映内容层次结构的布局,我们就会处于一个良好的位置,因为当这些内容在较小的屏幕上重新排列时,无论宽度是多少,层次结构都将保持完整。
首先澄清一个术语:implement意味着根据线框图或设计/构图创建一个带有CSS和必要时JavaScript的HTML模型。
本章开头提到的原因是回答“为什么要首先使用移动设备实施?”记住:移动设备正在爆炸(实际上已经爆炸了),移动设备迫使你集中注意力,并扩展了你的能力。
除了第二个前提(这是一个巨大的也许)之外,这些原因都无法通过桌面优先实现。
让我们换个话题,转向一个更加技术性的主题,这将帮助我们了解Sassmixin如何帮助我们掌握移动设备优先和桌面优先方法。
因此,让我们回顾一下。使用桌面优先来创建你的设计和线框图。有一个大画布可以让我们探索不同的布局,并正确安排内容的层次结构。当需要实施(创建HTML模型)时,使用移动设备优先。
对于我们的示例,在本书中我们将使用两种类型的Sassmixin:一种使用min-width属性的移动设备优先mixin,另一种使用max-width属性的桌面优先mixin。我们已经在第一章中看到了以下mixin及其工作原理,利用Sass实现响应式网页设计的强大功能,但这里是一个复习。
我们将使用以下移动设备优先mixin:
@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content;}}这就是我们使用它的方式:
header{//Propertiesforsmallscreenswidth:50%;background:red;@includeforLargeScreens(640){//Propertiesforlargescreenswidth:100%;background:blue;}}这编译成以下内容:
header{width:50%;background:red;}@media(min-width:40em){header{width:100%;background:blue;}}桌面优先mixin这是我们将要使用的桌面优先mixin:
@mixinforSmallScreens($media){@media(max-width:$media/16+em){@content;}}这就是我们使用它的方式:
header{//Propertiesforlargescreenswidth:100%;background:purple;@includeforSmallScreens(640){//Propertiesforsmallscreenswidth:50%;background:yellow;}}@includeforSmallScreens这编译成以下内容:
header{width:100%;background:purple;}@media(max-width:40em){header{width:50%;background:yellow;}}提示使用这些mixin的好处是,非常容易找出正在使用的方法,因为我们可以在整个SCSS文件中看到forLargeScreens或forSmallScreens这个术语被重复使用。如果其他人要编辑我们最初做的任何工作,他们将清楚地了解我们用哪种方法构建了我们的站点/应用,只需扫描SCSS文件。
在“移动设备优先还是桌面优先?”的问题中,有一个领域我们需要涵盖一下,那就是旧版浏览器。每个项目,每个客户及其相应的分析(如果有的话,他们应该有),都有不同的要求,影响我们应该如何处理那些旧版浏览器。
如果你是用桌面优先的方法构建的,你当前的工作流程应该保持不变,因为这几乎就是在响应式网页设计变得几乎是强制性之前我们一直在做的事情。
这意味着你仍然会使用类似这样的东西:
header{//Desktop-firstdeclarationwidth:50%;@includeforSmallScreens(768){//Targetsmallscreens(mobiledevices)width:100%;}}这编译成以下内容:
header{width:50%;}@media(max-width:48em){header{width:100%;}}IE7和IE8不支持媒体查询,但前面的代码将正常工作,因为header{width:50%;}规则不在媒体查询内。
然而,如果你是以移动设备为先,那么header{width:50%;}将在媒体查询内,因此IE7和IE8将无法看到该规则:
.article{//Mobile-firstdeclarationwidth:100%;//IE7andIE8won'tbeabletoseethisrule.@includeforLargeScreens(768){width:50%;}}这编译成以下内容:
header{width:100%;}@media(min-width:48em){header{width:50%;}}那么你该怎么办?解决方案非常简单:使用Respond.js脚本。
Respond.js是一种称为polyfill的脚本。根据最初提出这个术语的人RemySharp的说法,polyfill是一段代码,提供了我们,网页开发人员,期望浏览器本地提供的技术。
在网页设计和开发中,polyfill比JavaScript实现更丰富,例如ScottJehl的Respond.js。但我们也可以说CSS中也有polyfill,例如EricMeyer的著名的reset.css和NicolasGallagher和JonathanNeal的Normalize.css。
Respond.js脚本是一种polyfill,使旧版浏览器(IE6/7/8)支持它们从未支持过的特定CSS功能:媒体查询。
尽管我建议使用polyfill,但我们需要注意网站/应用程序需要进行额外的HTTP请求以获取此JavaScript文件。我们的网站/应用程序发出的请求越少,它们就会越快,从而带来许多好处,如改善用户体验和积极的SEO影响。
因此,您需要做以下事情:
性能最佳实践建议将非必要的脚本放在标记的底部,就在关闭的
标签之前。由于Respond.js针对的是旧版浏览器,让我们继续这样做。将脚本放在标记底部的另一个好处是有助于避免阻塞页面的渲染。
这是我们的示例HTML:
//Mobile-firstdeclarationarticle{background:red;//Targetscreens640pxwideandlarger@includeforLargeScreens(640){&{background:green;}}}这编译为以下内容:
article{background:red;}@media(min-width:40em){article{background:green;}}因此,当您调整IE7或IE8浏览器窗口大小时,如果窗口宽度为640像素或更小,则它将能够显示红色背景,如果窗口为641像素或更大,则显示绿色背景。
自从我开始编写CSS以来,我一直避免创建IE特定的样式表。这样做的原因很简单:
在旧版浏览器中,当它们尝试下载IE特定的样式表时,页面渲染不会被阻塞。此外,故障排除更容易。那么我们该使用什么呢?
有几种方法可以通过将所有内容放在一个样式表中来处理IE:
让我们再谈谈一个流行的方法,使用条件类。
这是我使用的一个:
提示IE10及以上不再支持条件注释,这就是条件类标记中没有提及IE10的原因。
有了前面的条件类,针对特定IE(此示例中为IE7)的定位如下:
.ie7navli{float:left;}如果我们需要针对所有IE进行定位,我们会这样做:
.ie7,.ie8,.ie9{navli{float:left;}}这编译为以下内容:
.ie7navli,.ie8navli,.ie9navli{float:left;}对于所有其他浏览器,我们会这样做:
nav{display:flex;}无论您使用哪种方法,Modernizr.js或条件类,都是个人偏好。使用这两种方法中的任何一种都是正确的做法。
记住,无论如何都要避免CSShack。作为网页设计师和网页开发人员,我们有责任为每个人创造一个更好的网络。
像SVG、图标字体或常规字体这样的矢量是数学方程的视觉表示,因此无论它们的大小如何,它们永远不会失去质量。
为了使位图图像在高密度屏幕上显示良好,我们必须导出正常质量图像的高分辨率版本。这意味着我们需要为我们计划使用的每个位图图像创建两个文件(或更多):一个用于非高密度屏幕(标准液晶显示器,旧TFT监视器,一些电视等)的正常质量图像,以及一个(或更多)用于高密度屏幕(例如任何视网膜设备和SuperAMOLED显示器)的高质量图像。
这就是良好的设计判断发挥作用的地方,因为有时我们可能并不一定需要每次都导出两个(或更多)位图图像。
当我们必须考虑高密度屏幕时,有几种技术可以用来处理图像。这些技术在《第六章》响应式网页设计中的图像和视频处理中有详细解释。
例如,大多数旅行网站的预订部分。这类网站管理的大量信息和类型使得响应式网站变得非常困难。当访问谷歌搜索结果中排名前八的旅行网站时,我看到了以下情况:
以下是我们的一些发现的简要列表:
我们可以得出结论,最受欢迎的旅行网站尚未完全采用RWD,但有些是固定宽度和响应式布局的混合体。这就是为什么所有这些网站都有单独的移动应用程序。对于它们来说,RWD可能不是优先考虑的,因此它们依赖于它们的移动应用程序来弥补这一不足。
尽管这在今天已经非常罕见,但有时我们可能需要构建一个不响应的网站或页面。实际上,今天有一些页面是不响应的。
CodePen是最受欢迎的前端沙箱之一,而CodePen的编辑器不是响应式的。为什么?因为它不需要。开发人员很少会使用手机去CodePen编写HTML、Sass和JavaScript。
话虽如此,如果您需要构建一个不需要响应的站点/页面,就CSS网格系统而言,有两个很好的选择:
有几件事需要考虑:
因为我一直认为960网格系统左右各有10px的填充使内容离主容器的边缘太近,我在每一侧增加了10个像素,将填充增加到20px,将960网格系统变成了980网格系统。从现在开始,我们将称其为980GS。
如果有必要,我们需要准备使非响应式或固定宽度的站点/应用程序变得响应式。
有两种改装非响应式或固定宽度的站点/应用程序的方法。一种是使用自适应Web设计(AWD)技术,使用绝对单位(即像素)。另一种是使用RWD,并使用非常简单的公式将所有像素值转换为百分比。
无论我们使用哪种技术,我们都必须使用桌面优先的方法,因为我们处理的站点只适用于宽屏。这意味着我们将在媒体查询中使用max-width属性。
在我们查看两种改装技术之前,我们需要一个基础页面来开始。
您在此处看到的图形与12列980GS布局成比例。浏览器窗口宽度为1024px,页面宽度为980px:
我们灰色的主容器宽度为980px,左右已经有10px的填充。这意味着内部的部分总是需要加起来等于960px。
以下是容器的组件:
这是代表我们基础页面的标记:
然后,我们将创建一个styles.scss文件,我们将执行以下操作:
_980gs.scss文件包含基本网格,如下所示:
在AWD中,我们几乎每个宽度都使用像素,甚至我们的媒体查询也是如此。
我们要做的第一件事是在styles.scss文件中导入部分_980gs.scss文件:
//RetrofittingwithAdaptiveWebDesign@import"980gs";然后,我们将包含我们简单的桌面优先mixin来处理媒体查询。然而,请记住我之前提到过这个mixin是可扩展的,如果我们想要的话,我们可以使它编译基于像素的值?我们所需要做的就是从除法$media/16+em中移除值/16+em:
//RetrofittingwithAdaptiveWebDesign@import"980gs";//Desktop-firstMediaQueryMixin@mixinforSmallScreens($media){@media(max-width:$media){@content;}}以下规则仅用于样式目的,以实现我们在之前截图中看到的相同设计:
//RetrofittingwithAdaptiveWebDesign@import"980gs";//Desktop-firstMediaQueryMixin@mixinforSmallScreens($media){@media(max-width:$media){@content;}}//Basicstyling.container_12{background:#aaa;font-size:30px;text-shadow:01px1pxrgba(black,.5);}header{background:#429032;}nav{background:#2963BD;}section{background:#c90;}footer{background:#c03;}//Giveheightstoelementsforbetterperceptionofsectionsheader,footer{height:150px;}nav,section{height:440px;}此时,我们的页面宽度为980px,看起来和最初看到的截图一样。
让我们定义基本页面捕捉的宽度:
这就是乐趣开始的地方。让我们通过为每个部分创建媒体查询来开始改造这个页面。
以下媒体查询针对768px:
.container_12{@includeforSmallScreens(980px){width:768px;}.grid_12{//HeaderandFootersections@includeforSmallScreens(980px){width:728px;}}.grid_3{//Navsection@includeforSmallScreens(980px){width:200px;}}.grid_9{//Contentsection@includeforSmallScreens(980px){width:508px;}}}诚然,从980px到768px,书中的差异有点难以察觉,但相信我,以下截图完全代表了浏览器窗口宽980px,页面宽768px:
正如你所看到的,一旦屏幕宽度达到980px,我们的主容器(.container_12)的宽度就从980px变为768px。我们的主容器左右各有10px的填充,因此所有其他部分的宽度应该加起来匹配748px。
让我们来看看。
我们的Header和Footer使用相同的类.grid_12,现在宽度为728px。因此,如果我们加上:728px+10px左边距+10px右边距=748px。
如果我们将Nav(.grid_3)和Content(.grid_9)部分的宽度相加:
跟着我,我保证这会非常有趣。
以下媒体查询针对640px:
.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}.grid_12{//HeaderandFootersections@includeforSmallScreens(980px){width:728px;}@includeforSmallScreens(768px){width:600px;}}.grid_3{//Navsection@includeforSmallScreens(980px){width:200px;}@includeforSmallScreens(768px){width:160px;}}.grid_9{//Contentsection@includeforSmallScreens(980px){width:508px;}@includeforSmallScreens(768px){width:420px;}}}好的,这个布局现在是单列页面。我们开始看到一些结果了。不错!
再次,请记住,我们的主容器左右各有10px的填充,因此所有其他部分的宽度应该加起来匹配620px。
让我们确保我们的数字加起来:
我们的Header和Footer使用相同的类.grid_12,现在宽度为600px。因此,如果我们加上:600px+10px左边距+10px右边距=620px。
让我们把这个页面变得更小!
以下媒体查询针对480px:
.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}.grid_12{//HeaderandFootersections@includeforSmallScreens(980px){width:728px;}@includeforSmallScreens(768px){width:600px;}}.grid_3{//Navsection@includeforSmallScreens(980px){width:200px;}@includeforSmallScreens(768px){width:160px;}}.grid_9{//Contentsection@includeforSmallScreens(980px){width:508px;}@includeforSmallScreens(768px){width:420px;}}.grid_3,.grid_9,.grid_12{@includeforSmallScreens(640px){width:440px;}}}我们取得了一些应得的进展!在这里,浏览器窗口宽640px,页面宽480px:
请记住,我们的主容器左右各有10px的填充,因此所有其他部分的宽度应该加起来匹配460px。
现在,我们将从2列布局更改为1列布局。这意味着所有部分现在具有完全相同的宽度。
这也意味着在我们的SCSS文件中,我们可以为所有三个类创建一个单一的媒体块:
.grid_3,.grid_9,.grid_12{@includeforSmallScreens(640px){width:440px;}}现在,让我们确保我们的数字加起来:
我们的Header,Nav,Content和Footer部分现在宽度为440px,依次堆叠在一起。因此,如果我们加上:所有部分的440px+10px左边距+10px右边距=460px。
我们来了,这个谜题的最后一块!
以下媒体查询针对320px:
.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}@includeforSmallScreens(480px){width:320px;padding:0;}.grid_12{//HeaderandFootersections@includeforSmallScreens(980px){width:728px;}@includeforSmallScreens(768px){width:600px;}}.grid_3{//Navsection@includeforSmallScreens(980px){width:200px;}@includeforSmallScreens(768px){width:160px;}@includeforSmallScreens(640px){height:50px;//Thisisonlyforstyling}}.grid_9{//Contentsection@includeforSmallScreens(980px){width:508px;}@includeforSmallScreens(768px){width:420px;}}.grid_3,.grid_9,.grid_12{@includeforSmallScreens(640px){width:440px;}@includeforSmallScreens(480px){width:300px;}}}我们来了!在这个屏幕截图中,浏览器窗口宽度为320px,内容也是320px宽,非常合适:
我们已经知道我们的主容器左右各有10像素的填充。在这种情况下,我们将去掉填充以获得这20像素,因为我们的屏幕空间现在非常小:
@includeforSmallScreens(480px){width:320px;padding:0;}左右各10像素的间距现在将由其他部分的左右边距创建。这意味着每个部分的宽度应为300像素。
添加新的320像素断点很容易:
.grid_3,.grid_9,.grid_12{@includeforSmallScreens(640px){width:440px;}@includeforSmallScreens(480px){width:300px;}}现在,让我们确保我们的数字加起来:
我们的标题、导航、内容和页脚部分现在都是300像素宽,依次堆叠在一起。所以如果我们加上:所有部分的300像素+10像素左边距+10像素右边距=320像素。
就是这样。我们现在已经使用AWD技术将固定宽度页面改为响应式。
最终的SCSS如下:
.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}@includeforSmallScreens(480px){width:320px;padding:0;}.grid_12{//HeaderandFootersections@includeforSmallScreens(980px){width:728px;}@includeforSmallScreens(768px){width:600px;}}.grid_3{//Navsection@includeforSmallScreens(980px){width:200px;}@includeforSmallScreens(768px){width:160px;}@includeforSmallScreens(640px){height:50px;//Thisisonlyforstyling}}.grid_9{//Contentsection@includeforSmallScreens(980px){width:508px;}@includeforSmallScreens(768px){width:420px;}}.grid_3,.grid_9,.grid_12{@includeforSmallScreens(640px){width:440px;}@includeforSmallScreens(480px){width:300px;}}}它编译成以下CSS:
现在,让我们看看使用百分比和RWD改装相同页面的样子。
我们刚刚看到了如何使用像素来实现AWD。通过RWD和一个非常简单的方程,我们可以使用相对单位(在我们的情况下是百分比)来改装网站。更不用说这将比使用AWD要容易得多。
由EthanMarcotte发现/创造,他创造了响应式网页设计这个术语,RWD的魔法公式是一个非常简单的方程:
(目标÷上下文)x100=结果%
在我们开始将像素转换为百分比之前,我们需要看看我们的上下文将是哪个宽度。
我们的上下文将是页面的主容器.container_12,最大宽度为980像素。然而,主容器和列之间存在一个问题,将这个980像素的上下文变成960像素。请注意.container_12部分的左右10像素填充和.grid规则中的左右10像素边距:
.container_12{width:980px;padding:010px;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:010px;}}.grid规则中的10像素左右边距意味着所有列的宽度都增加了20像素。所以,例如,宽度为940像素的标题和页脚实际上是960像素宽。box-sizing:border-box;属性只考虑减去盒模型内部的内容(填充),而不考虑外部的内容(边距)。
一个解决方案是去掉.container_12的左右10像素填充,并在.grid规则中增加左右边距为20像素,以保持间距;否则,列会相互接触。
现在,间距变得更宽,这可能不是出于设计目的,而且——信不信由你——在最宽的容器中会多出1像素。在我们的情况下,它会添加到标题和页脚中。
作为设计师,我知道如果不得不处理这些问题,我是不想要的。
第二种解决方案更简单:将上下文设为960像素。这样,我们可以全局去掉多余的10像素,而不会影响主容器和列的完整性,由于我们得到的是百分比,所以结果几乎相同。
换句话说:(960像素÷980像素)x100=97.95918367346939%(97.95%)
这实际上等同于:(940像素÷960像素)x100=97.91666666666667%(97.91%)
在第二种解决方案中,1像素的问题确实会发生,但是在调整浏览器宽度时会在随机宽度时发生。然而,在第一种解决方案中,1像素的问题是永久性的,无论浏览器的宽度如何。
弄清楚这一点后,我们将把所有基于像素的宽度转换为使用960像素作为上下文的百分比。
Header和Footer部分的宽度都是940px。知道它们的上下文是960px,让我们继续使用魔术公式找到它们的百分比宽度:(940px÷960px)x100=97.91666666666667%。
你可能会问自己,“这么多小数点有必要吗?”不是所有的小数点,但至少建议使用两位。
所以我们最终得到Header和Footer部分为97.91%。
一些开发人员建议使用所有小数,并让浏览器决定要使用多少。过去,我决定挑战这个建议,只使用两位小数来看看会发生什么。自从我开始使用两位小数以来,在任何浏览器中都没有遇到任何不良行为或宽度问题。
Firefox和IE11会将多余的小数点截断为两位。另一方面,Chrome会保留所有小数点。我建议至少使用两位小数,这也是我们在书中使用的方式,以保持简单和简洁。但是,如果您更喜欢使用所有小数点,那就尽管去做!这在这一点上是个人偏好的问题。
避免四舍五入值,并让浏览器处理小数点。这样做也可以让您专注于最重要的事情:高效并尝试为用户创造令人难忘的体验。
为了找到Nav部分的百分比宽度,我们同样使用960px作为上下文:(220px÷960px)x100=22.91666666666667%。
使用两位小数,我们最终得到Nav部分为22.91%。
为了找出Content部分的百分比宽度,我们的公式看起来几乎一样。唯一的区别是我们正在改变第一个值,即Content部分的宽度(以像素为单位):(700px÷960px)x100=72.91666666666667%。
仅使用两位小数,我们最终得到Content部分为72.91%。
这就是我们初始的改装RWDSCSS文件的样子:
.container_12{.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;}.grid_9{//Contentsectionwidth:72.91%;}}现在,让我们退一步,先处理一些其他基于像素的宽度。还记得主容器.container_12左右各有10px的填充吗?我们也需要将这10px转换为百分比。
使用我们的魔术公式,我们这样做:
(10px÷960px)x100=1.041666666666667%。
仅使用两位小数,我们最终得到左右填充为1.04%。
让我们将这个值添加到我们的SCSS中:
.container_12{width:980px;padding:01.04%;margin:auto;}.container_12{.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;}.grid_9{//Contentsectionwidth:72.91%;}}此外,我们所有的列左右各有10px的边距。由于我们已经知道10px等于1.04%,让我们将这个值添加到我们SCSS中的所有列中:
.container_12{width:980px;padding:01.04%;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:01.04%;}}.container_12{.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;}.grid_9{//Contentsectionwidth:72.91%;}}现在,我们有一个宽度为1024px的浏览器窗口,一个宽度为980px的布局,以及所有列都具有相应的百分比值。实际上,这几乎是不可能的,除非查看代码以在固定宽度和基于百分比的布局之间进行视觉区分。
我们做得很好!
让乐趣开始吧。让我们添加我们的第一个媒体查询。
当我们调整浏览器窗口大小时,Header、Footer、Nav和Content部分会自动响应,按比例缩小,正确对齐,并适应主容器.container_12的新宽度,而不会破坏布局。如下截图所示:
太棒了!
让我们添加另一个断点。
在以下断点(640px)中,我们的布局将变为单列。因此,我们将添加一个新的媒体查询,使Nav和Content部分与Header和Footer部分一样宽,并使它们堆叠在一起。
以下媒体查询针对640px,并使Nav和Content部分全宽:
.container_12{width:980px;padding:01.04%;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:01.04%;}}.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;}.grid_9{//Contentsectionwidth:72.91%;}.grid_3,.grid_9{//NavandContentsections@includeforSmallScreens(640px){width:97.91%;}}}好的,我们现在有了单列布局。还不错,还不错!
现在我们的宽度已经缩小到480px,单列布局不会改变,只有所有容器的宽度会改变。
.container_12{width:980px;padding:01.04%;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:01.04%;}}.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;@includeforSmallScreens(640px){height:50px;//Thisisonlyforstyling}}.grid_9{//Contentsectionwidth:72.91%;}.grid_3,.grid_9{//NavandContentsections@includeforSmallScreens(640px){width:97.91%;}}}我们的布局变窄了,我们需要做的就是添加一个新的媒体查询,就这样!不需要在其他容器上瞎折腾;它们都完美地适应了我们定义的任何宽度。
最后,我们解决了320px的宽度,而不修改单列布局。我们去掉了.container_12上的填充,以利用所有可用的屏幕空间。
.container_12{width:980px;padding:01.04%;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:01.04%;}}.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}@includeforSmallScreens(480px){width:320px;padding:0;}.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;@includeforSmallScreens(640px){height:50px;//Thisisonlyforstyling}}.grid_9{//Contentsectionwidth:72.91%;}.grid_3,.grid_9{@includeforSmallScreens(640px){width:97.91%;}}}再次,我们不必添加任何内容到Header、Footer、Nav和Content部分,因为它们现在都是97.91%宽。这使它们具有响应性,我们不必担心其他任何事情。
最终的SCSS,结合所有断点和宽度,如下所示:
.container_12{width:980px;padding:01.04%;margin:auto;}.grid{&_1,&_2,&_3,&_4,&_5,&_6,&_7,&_8,&_9,&_10,&_11,&_12{float:left;margin:01.04%;}}.container_12{@includeforSmallScreens(980px){width:768px;}@includeforSmallScreens(768px){width:640px;}@includeforSmallScreens(640px){width:480px;}@includeforSmallScreens(480px){width:320px;padding:0;}.grid_12{//HeaderandFootersectionswidth:97.91%;}.grid_3{//Navsectionwidth:22.91%;}.grid_9{//Contentsectionwidth:72.91%;}.grid_3,.grid_9{//NavandContentsections@includeforSmallScreens(640px){width:97.91%;}}}它编译成以下CSS:
.container_12{width:980px;padding:01.04%;margin:auto;}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12{float:left;margin:01.04%;}@media(max-width:980px){.container_12{width:768px;}}@media(max-width:768px){.container_12{width:640px;}}@media(max-width:640px){.container_12{width:480px;}}@media(max-width:480px){.container_12{width:320px;padding:0;}}.container_12.grid_12{width:97.91%;}.container_12.grid_3{width:22.91%;}.container_12.grid_9{width:72.91%;}@media(max-width:640px){.container_12.grid_3,.container_12.grid_9{width:97.91%;}}正如你所看到的,使用RWD比AWD来改造站点的代码要少得多。当然,这些例子是对站点/应用布局的极端简化,但现在你已经了解了在使用AWD或RWD时做出决定的基本概念。
在本章中,我们讨论了很多有趣的内容。我们看到,使用桌面优先来创建设计和线框图是有益的,因为拥有一个大画布可以让我们探索不同的布局,并正确安排内容的层次结构。
在创建HTML模型时,使用移动优先更好,因为移动友好的站点将具有更广泛的覆盖范围,允许专注的内容,并利用移动设备的技术。
我们能够使用魔术公式对固定宽度的站点进行AWD和RWD的改造。我们还讨论了RWD的好处,因为它需要的代码要少得多。然而,对旅行网站的分析清楚地告诉我们,RWD有时并不是正确的解决方案。
我们还看到了Respond.js如何用于使旧版浏览器支持媒体查询,如果我们采用移动优先的方法构建。使用条件类是一种很好的技术,因为它不会侵入,很容易实现,并且没有JavaScript依赖。
在下一章中,我们将讨论RWD世界中一些最有趣的主题:CSS网格、CSS框架和Flexbox的强大。
让我们开始吧!
响应式网页设计(RWD)为所有构建响应式网站和应用程序的人引入了一层新的工作。当我们必须在不同设备和不同尺寸上测试我们的工作时,无论内容在哪里中断,我们都需要添加一个断点并重新测试。
为了使事情更有趣,作为网页设计师和开发人员,我们需要注意内容在不同尺寸上的布局以及网格如何帮助我们将内容结构化到不同的布局中。
既然我们提到了网格,你有没有问过自己,“我们到底用网格做什么?”
借用设计行业的一些术语来回答这个问题,我们使用网格来让内容具有节奏、比例和平衡。目标是让使用我们网站/应用的人对我们的内容有更愉快的体验,因为它将更容易扫描(节奏)、更容易阅读(比例)和有组织(平衡)。
为了加快设计和构建过程,同时保持所有内容在不同尺寸下正确格式化,许多作者和公司创建了包含网格以及许多其他功能和样式的CSS框架和CSS网格,可以通过使用简单的类名来利用。
让我们看看CSS网格、CSS框架、UI工具包和Flexbox是什么,以及它们如何帮助我们实现RWD。
网格是一组视觉指南(垂直、水平或两者兼有,因此称为网格),它们有助于定义元素的放置位置。一旦元素被放置,我们就得到了一个布局。
使用网格的好处是放置在上面的元素将在页面上具有和谐的流动,增强用户体验,提高可读性、布局一致性和元素之间的良好比例。
CSS网格基本上是由形成列的垂直指南的组合。这些列的属性在CSS文件中定义。该文件包含一个具有特定宽度的类列表,与特定网格构建的列数相匹配。
我们在第三章中已经见过了,当时我们使用980GridSystem(980GS)来改造一个旧的固定宽度站点。这是SCSS文件:
因为我们正在使用HTML5和CSS3掌握RWD,让我们看看相同的980GS,使用百分比使其流动起来。
RWD的魔法公式是(目标÷上下文)x100=结果%。
在这种情况下,我们的上下文是980px,如下所示:
还有其他用于网页设计的网格,它们没有定义的框架宽度或列数,而是可以有无限数量的列,比如基于自适应Web设计(AWD)的无框网格。这意味着主容器的宽度捕捉到由它容纳的列数计算出的特定断点。
优点如下:
缺点如下:
CSS框架是一组预构建功能,基本上帮助加快Web前端开发。这些CSS框架的作者已经处理了许多重要但细微的细节,因此决定使用它们的人可以专注于手头的任务,同时将许多决定留给CSS框架本身。
许多开发人员和设计师相信(我也是)任何CSS框架的真正价值在于它们的CSS网格,有时我们会不遗余力地提取CSS网格并自定义它以满足我们的需求。
在本书中,我们将专注于CSS网格来掌握RWD,而不是从CSS框架或UI工具包中剥离一个(如果它确实提供一个)。我们很快就会谈到这一点。
以下列表描述了一些CSS框架的特点和特征:
与CSS框架类似,还有另一种称为UI工具包的前端框架。然而,UI工具包可以是一种独特的类型。
说实话,有时很难区分CSS框架和UI工具包。但不要过多地深究哪一个是哪一个,重要的是要理解我们首先为什么使用它们以及它们如何帮助我们构建更好、更快速的响应式网站和应用程序。
以下列表描述了一些UI工具包的特点和特征:
以RWD作为我们在布局与屏幕房地产方面做出的任何决定的主要驱动力,让我们来看看CSS框架的优点和不足之处:
现在我们已经看到了CSS网格、CSS框架和UI工具包的优缺点,是时候做出决定并回答这个问题了:哪种方法对RWD最好?
答案并不是最令人鼓舞的,我承认,但这是事实:这取决于情况。
但如果我们在一个庞大的团队中工作,一个由内部和离岸资源组成的网络专业人士的大熔炉,也许使用框架会有所帮助。这是因为每个人都需要遵守框架的结构,以确保一切都是一致的。
由于我们正在掌握RWD,我们有奢侈的创造我们自己的CSS网格。然而,我们需要聪明地工作,而不是努力地工作。所以我们要做的是利用可变网格系统应用程序,并将其结果与我们自己的方法相结合,制作一个移动优先、流动、自定义构建和坚实的CSS网格,从中我们可以创建强大的响应式设计。
让我们列出我们的CSS网格需求:
这就是我们的1200像素宽和12列宽20px的网格的样子:
左右两侧的填充都是10px。我们将在此过程结束时将这10px转换为百分比。
我们将使用RWD魔法公式:(目标÷上下文)x100=结果%。
我们的上下文将是1200px。所以让我们转换一个列:80÷1200x100=6.67%。
对于两列,我们必须考虑20px的间距。换句话说,我们不能说两列确切地是160px。这并不完全正确。
两列分别是:80px+20px+80px=180px。
现在让我们转换两列:180÷1200x100=15%。
对于三列,现在我们必须考虑两个间距:80px+20px+80px+20px+80px=280px。
现在让我们转换三列:280÷1200x100=23.33%。
现在你能看到模式了吗?每次我们添加一列,我们只需要将值增加100。这个值也包括了间距!
检查我们刚才看到的网格的屏幕截图,你可以看到列的值递增100。
所以,所有的方程式如下:
1column:80÷1200x100=6.67%2columns:180÷1200x100=15%3columns:280÷1200x100=23.33%4columns:380÷1200x100=31.67%5columns:480÷1200x100=40%6columns:580÷1200x100=48.33%7columns:680÷1200x100=56.67%8columns:780÷1200x100=65%9columns:880÷1200x100=73.33%10columns:980÷1200x100=81.67%11columns:1080÷1200x100=90%12columns:1180÷1200x100=98.33%让我们为12列网格创建SCSS:
//Grid12Columns.grid{&-1{width:6.67%;}&-2{width:15%;}&-3{width:23.33%;}&-4{width:31.67%;}&-5{width:40%;}&-6{width:48.33%;}&-7{width:56.67%;}&-8{width:65%;}&-9{width:73.33%;}&-10{width:81.67%;}&-11{width:90%;}&-12{width:98.33%;}}提示使用连字符(-)来分隔单词可以更容易地选择代码编辑时的术语。
不要忘记在文件顶部包含UTF-8编码指令,让浏览器知道我们正在使用的字符集。让我们通过在顶部添加一个Credits部分来装饰我们的代码。代码如下:
@charset"UTF-8";/*CustomFluid&ResponsiveGridSystemStructure:Mobile-first(min-width)Syntax:SCSSGrid:Float-basedCreatedby:YourNameDate:MM/DD/YY*///Grid12Columns.grid{&-1{width:6.67%;}&-2{width:15%;}&-3{width:23.33%;}&-4{width:31.67%;}&-5{width:40%;}&-6{width:48.33%;}&-7{width:56.67%;}&-8{width:65%;}&-9{width:73.33%;}&-10{width:81.67%;}&-11{width:90%;}&-12{width:98.33%;}}提示注意Credits是用CSS样式注释注释的:/**/。这种类型的注释,取决于我们如何编译我们的SCSS文件,不会被剥离。这样,Credits总是可见的,这样其他人就知道谁编写了文件。这对团队可能有用,也可能没有。此外,显示Credits对文件大小的影响是微不可见的。
包括box-sizing属性允许浏览器的盒模型考虑容器内的填充;这意味着填充被减去而不是添加,从而保持了定义的宽度。
由于我们的自定义CSS网格的结构将是移动优先的,我们需要包括处理这一方面的mixin:
@charset"UTF-8";/*CustomFluid&ResponsiveGridSystemStructure:Mobile-first(min-width)Syntax:SCSSGrid:Float-basedCreatedby:YourNameDate:MM/DD/YY*/*,*:before,*:after{box-sizing:border-box;}//Moble-firstMediaQueriesMixin@mixinforLargeScreens($width){@media(min-width:$width/16+em){@content}}//Grid12Columns.grid{&-1{width:6.67%;}&-2{width:15%;}&-3{width:23.33%;}&-4{width:31.67%;}&-5{width:40%;}&-6{width:48.33%;}&-7{width:56.67%;}&-8{width:65%;}&-9{width:73.33%;}&-10{width:81.67%;}&-11{width:90%;}&-12{width:98.33%;}}主容器和将10px转换为百分比值由于我们使用移动优先方法,我们的主容器默认情况下将是100%宽;但我们还将给它一个最大宽度为1200px,因为要求是创建这样大小的网格。
我们还将把10px转换为百分比值,所以使用RWD魔法公式:10÷1200x100=0.83%。
然而,正如我们之前看到的,10px,或者在这种情况下0.83%,不足够的填充会使内容看起来离主容器的边缘太近。所以我们将填充增加到20px:20÷1200x100=1.67%。
我们还将使用margin:auto;来水平居中主容器。
现在让我们包括这些值:
@charset"UTF-8";/*CustomFluid&ResponsiveGridSystemStructure:Mobile-first(min-width)Syntax:SCSSGrid:Float-basedCreatedby:YourNameDate:MM/DD/YY*/*,*:before,*:after{box-sizing:border-box;}//Moble-firstMediaQueriesMixin@mixinforLargeScreens($width){@media(min-width:$width/16+em){@content}}//MainContainer.container-12{width:100%;//ChangethisvaluetoANYTHINGyouwant,noneedtoeditanythingelse.max-width:1200px;padding:01.67%;margin:auto;}//Grid12Columns.grid{&-1{width:6.67%;}&-2{width:15%;}&-3{width:23.33%;}&-4{width:31.67%;}&-5{width:40%;}&-6{width:48.33%;}&-7{width:56.67%;}&-8{width:65%;}&-9{width:73.33%;}&-10{width:81.67%;}&-11{width:90%;}&-12{width:98.33%;}}提示在padding属性中,如果我们输入0.83%或.83%都是一样的。我们可以省略零。保持我们的代码尽可能简洁是一种良好的实践。这与当我们使用十六进制简写值时的原理相同:#3336699和#369是一样的。
我任意选择了40em(640px)作为起点。记住要创建基于内容而不是设备的断点。
代码如下:
我们还为行添加了一个底部间距为10px的规则,以便将它们彼此分开,同时从最后一行中去除该间距,以避免在底部创建不必要的额外间距。最后,我们为旧版IE添加了清除规则。
现在让我们包括这些规则:
这是我们在这个例子中将要使用的HTML:
嵌套列是任何网格系统的主要优势。在这本书中,我们正在利用这种力量,以便不会以任何方式限制设计。
我们使用HTML5Shivpolyfill为IE8及以下版本添加HTML5支持。
在小屏幕上(320px宽),容器如下所示:
在宽度为40em(640px)及以上的大屏幕上,布局如下:
我打赌你没有看到这一点,哈!
事实上,Flexbox是一种令人惊奇的CSS属性,它为布局提供了新的可能性。以下是关于Flexbox的一些事情:
让我们开始吧,好吗?
在下面的示例中,我们将使用Flexbox属性构建与使用自定义CSS网格构建的相同布局。这将帮助我们更好地理解Flexbox的强大之处,并最终摆脱完全使用CSS网格,同时在我们的HTML中保持更语义化的结构。
关于示例页面的一些注意事项:
这是小屏幕(320px宽)上Flexbox布局的样子:
这是大屏幕上的样子。这个屏幕宽度为768px,但内容为40em(640px):
这是我们将在示例页面中使用的标记:
让我们来分析一下。
我们将从创建Credits部分开始,box-sizing:border-box;参数用于考虑容器内部而不是外部的填充,首先是移动优先的mixin和主容器属性:
/*CustomFluid&ResponsiveGridSystemStructure:Mobile-first(min-width)Syntax:SCSSGrid:Flexbox-basedCreatedby:YourNameDate:MM/DD/YY*/*,*:before,*:after{box-sizing:border-box;}//Moble-firstMediaQueriesMixin@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content}}//Maincontainer.main-container{width:100%;//ChangethisvaluetoANYTHINGyouwant,noneedtoeditanythingelsemax-width:1200px;//Anyvalueyouwantpadding:01.67%;margin:auto;}添加Flexbox容器现在,让我们为Flexbox容器添加属性,该容器在某种程度上类似于CSS网格中的.row。代码如下:
/*CustomFluid&ResponsiveGridSystemStructure:Mobile-first(min-width)Syntax:SCSSGrid:Flexbox-basedCreatedby:YourNameDate:MM/DD/YY*/*,*:before,*:after{box-sizing:border-box;}//Moble-firstMediaQueriesMixin@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content}}//Maincontainer.main-container{width:100%;//ChangethisvaluetoANYTHINGyouwant,noneedtoeditanythingelsemax-width:1200px;//Anyvalueyouwantpadding:01.67%;margin:auto;}//Flexboxcontainer.flex-container{margin-bottom:10px;//Removethemarginfromthelastflexboxcontainer&:last-of-type{margin-bottom:0;}@includeforLargeScreens(640){display:flex;}}正如你所看到的,我们添加了margin-bottom:10px;来分隔内容行。然而,我们在最后一个Flexbox容器上移除了该边距,以防止在末尾产生不必要的额外填充。
然后,我们将包含针对640px(40em)屏幕宽度的移动优先mixin。这意味着我们只会在大屏幕上使用Flexbox,但在小屏幕上,我们不会使用它。
如果所有列的宽度相等,则无需使用Flexbox。在我们的示例中,小屏幕上的列宽度为100%。
现在,让我们在大屏幕上为列添加.83%的左右边距。在小屏幕上,列没有边距。记住10px=0.83%。
我们将使用带有星号/星号的属性选择器,以便可以针对所有包含类名中至少一个值为level-的DIV进行定位。我们还将删除第一个容器的左边距和最后一个容器的右边距,以便我们的DIV与其父容器的边缘对齐。代码如下:
在小屏幕上,导航和部分容器的宽度为100%,而在大屏幕上它们并排显示;导航容器在大屏幕上宽度为33%,右边距为1.67%(相当于20px)以创建间距。部分容器在大屏幕上宽度为65.33%。这里是公式:33%+1.67%+65.33=100%。
让我们继续为导航和部分容器定义这些属性:
基本上,我们正在为该行的第一个和第三个内容区域.content-a和.content-c分配特定但不同的宽度。除非我们想要,否则不需要为第二个内容区域分配宽度。Flexbox将使第二个容器完全占据第一个和第三个内容区域之间的所有剩余空间。
IE10在计算嵌套容器值时存在问题,因此我们需要为这些容器创建特定的宽度。我们将在为IE8和IE9创建的同一规则中包含IE10的宽度。
我使用任意值如30%和42%是为了向你展示,我们可以随意调整这些值,而Flexbox会尽量保持这些比例,只要有空间可用。
现在让我们为不同的嵌套容器添加这些属性:
与传统浏览器一样,调整数值并进行测试是获得最佳结果的关键。记住,网站在每个浏览器中不必看起来完全相同。
让我们澄清一些事情。类.ie8和.ie9来自元素中的条件类。类.ie10来自IE排除条件注释中的脚本。因此,IE8和IE9无法运行此脚本。但不用担心,解决方案很简单,你会看到的。让我们来看看它们。
这就是那条规则……好吧,支配它们所有:
我们给Nav部分设置宽度和右边距为1%,以保持简洁。我们也给Content部分分配了宽度。然后,我们使用Footer来清除浮动的Nav和Content部分,使用clear:both;和zoom:1;参数以确保。
以下是IE8/9的SCSS:
对于IE9,我们将把嵌套容器浮动到左侧。
让我们来看看这两条规则:
然而,我们现在知道什么是网格,以及它的用途,这是我们许多人以前从未真正质疑过的东西。我们还更加了解CSS网格、CSS框架和UI工具包;尽管你愿意使用它们,只要你清楚它们如何帮助我们在构建响应式网站和应用程序时更加高效。
使用传统的浮动技术创建我们的自定义CSS是一种识别模式的问题,其中添加新列只是通过增加100的值。现在,我们可以在任何宽度上创建一个12列网格。
借助Flexbox,我们现在明白了响应式和流动布局的未来在哪里。由于有如此出色的浏览器支持,毫无疑问Flexbox是传统CSS网格的一个重要竞争者。在旧版浏览器中,使用条件类是支持复杂布局的一个不错的选择。此外,对于IE10,我们需要使用条件编译脚本,只有IE10才能看到。因此,我们可以使用.ie10特定选择器来针对IE10。
在下一章中,当我们谈论为小屏幕上的大手指构建响应式界面时,我们将深入了解可用性和用户体验的世界。是时候来测试那些大手指了!
触摸屏设备的普及并不新鲜,对于我们——网络/移动设计师和开发人员来说。因此,我们不会谈论市场份额、统计数据或分析数字。相反,我们将讨论我们需要考虑的事项,如目标大小、导航模式、导航图标、最佳实践和移动设备人体工程学。
所有供应商对小屏幕设备上理想目标大小的规则和指南都有不同的集合。其中一些是以像素表示这些尺寸,其他的是以点表示,还有一些是以英寸、毫米或厘米为单位。
显然,作为网页设计师,我们必须注意在我们的设计中大意味着什么,因此我们需要平衡目标大小的建议与良好的设计原则。我们的目标是让消息传达给用户,并且他们应该能够舒适地使用我们的界面。
需要记住的一件事是,RWD的目标大小指南大多基于移动应用程序设计模式。让我们直奔主题。
成年人食指的平均宽度约为16毫米至20毫米。这接近45px至57px。
根据苹果的iOS人机界面指南,推荐的最小目标大小为44ptx44pt。
一些用户界面指南使用点和毫米作为测量单位的原因是为了提供一个与设备无关的一致比例尺。这是因为一个设备中的1px在另一个设备中不一定意味着确切的1px。尽管如此,一些供应商确实提供了像素的指南,但主要是为了让我们了解元素的比例关系。
在过去,苹果确实建议他们的目标大小以像素为单位,44pxx44px,但当引入视网膜显示屏时,iPhone3的1像素变成了iPhone4上的4像素。不再是1:1的比例。
这意味着在非视网膜设备上,44ptx44pt实际上是44pxx44px,但在视网膜设备上是88pxx88px。每次苹果发布具有更高密度屏幕的新设备时,这些像素值都会再次改变。
在RWD世界中,对于苹果设备或任何设备的屏幕密度有很好的理解是必不可少的。这样,我们在创建设计时总是可以考虑到这些技术细节,以免妨碍用户体验和我们网站和应用的可用性。
另一方面,微软的Windows8触摸指导文档建议理想的目标大小为7毫米x7毫米(40pxx40px)。如果准确性至关重要,例如关闭或删除,Windows8触摸指导指南建议目标大小为9毫米x9毫米(50pxx50px)。此外,当屏幕空间有限且需要适应时,最小推荐的目标大小为5毫米x5毫米(30pxx30px)。
这些尺寸适用于非高密度屏幕。
Windows8触摸指导指南甚至建议元素之间的最小填充:2毫米(10px),无论目标大小如何(这很好)。
Android开发者指南建议最小目标大小为48dp,约为9毫米。推荐的最小和最大目标大小分别为7毫米和10毫米。
Android开发者指南还建议元素之间的最小间距为8dp。
在这里,dp表示密度无关像素。这意味着在正常密度屏幕上,1dp与1px相同。就像苹果使用点(pt)一样,他们试图定义一个全球和屏幕密度无关的单位。
还有Ubuntu文档建议界面元素不应小于1厘米(约55px)。
正如我们所看到的,推荐的最小和最大目标尺寸因供应商而异。但它们之间的差距并不大。
我们可以从提到的所有目标尺寸中得出结论,即适当的尺寸为(在低密度屏幕上):
无论我们的触摸目标的尺寸有多可用,如果它们没有放置在正确的位置,我们所有的努力基本上都是无用的。
这些模式使我们能够定义布局内容的最佳方式,以便易于使用和访问。
了解用户的姿势模式将使我们能够了解我们的目标何时可以是正确的大小,甚至如果屏幕空间不足,则可以略小一些,或者如果需要精度,则可以略大一些,因为当有人使用大拇指时与使用食指时是不同的。
Luke还谈到了“触摸区域”,基本上是设备上易于或难以触及的区域,这取决于姿势。
在所有主要类型的设备(智能手机、平板电脑和触摸笔记本电脑)中,理想的触摸区域为深绿色,ok触摸区域为浅绿色,难以触及的区域为黄色:
在RWD中,要彻底改变单个页面的布局,更不用说许多页面(至少目前还没有)像独立的应用程序那样,需要大量的工作。此外,有很高的可能性会对用户体验产生负面影响,并保持内容层次结构。
现在,在RWD中非常多用途的一个网站/应用程序元素是菜单按钮。
为了触发导航,有一个非常特殊的元素,UX社区对此有非常强烈的意见:汉堡图标(≡)。目前,我们将称其为更通用的名称:导航图标。我将其称为导航图标,因为它不一定是汉堡图标/图形,它可以是另一种类型的图标或一个词。
导航图标的位置、行为和设计以及导航项本身的变化与设计师的数量一样多。对其他人有效的方法未必对我们有效,反之亦然。因此,测试成为决定用户感觉舒适的方法。
尽管如此,有一些导航图标的UX指南值得一提,我们将在接下来看到。
导航图标可以用许多方式表示。响应式网页设计从移动应用中借鉴了模式,因为小屏幕应用和网站有许多相似的隐喻。
让我们来看看常见的导航图标模式:
这是迄今为止最流行的用于表示导航按钮的图标:≡。
换句话说,汉堡包图标的真正名称是“列表”图标。
现在,如果我们想一想,汉堡包图标在语义上是正确的,因为它确切地代表了触发时显示的内容:一系列项目。然而,一些用户体验研究表明,汉堡包图标并不像我们想象的那么有效,但我们在响应式网站和移动应用中随处可见它。
尽管汉堡包图标有一些缺点,但几乎每个人都能在不久的将来认出这个图标代表导航。
关键是,只要我们遵循目标大小建议,并使导航栏内的链接在小屏幕上易于点击,使用汉堡包图标并没有什么问题。
如果您打算使用汉堡包图标,不要使用任何类型的图像或任何带有边框或框阴影的CSS技术。保持简单。您只需要使用Unicode字符2261(≡)。
在接下来的示例中,我们将使用一个众所周知的技术来隐藏内容(有一些变化以适应我们的演示):凯勒姆方法。这种方法绝不是任何欺骗或类似的东西;我们并不打算用这种方法欺骗我们的用户或搜索引擎。我们实际上非常注意通过将文本留在标记中来提高导航图标的可访问性,以便使用辅助技术的用户仍然可以访问菜单。考虑以下示例。
HTML如下:
Menu SCSS//HamburgerIcon.hamburger-icon{//Basicstyling,modifyifyouwantfont-size:40px;color:#666;background:#efefef;padding:010px;border-radius:3px;cursor:pointer;//HamburgerIcon&:before{content:'≡';}//HidethetermMenufromdisplayingwithoutsacrificingaccessibilityspan{display:inline-block;width:0;height:0;text-indent:-100%;overflow:hidden;white-space:nowrap;}}结果如下:
出于可访问性原因,单词“菜单”应始终包含在标记中。当使用辅助技术(AT)的用户将焦点放在汉堡包图标上时,屏幕阅读器将朗读单词“菜单”。此外,将单词“菜单”包含在标记中允许我们隐藏单词,而不会损害链接的可访问性。
网上一些非正式测试表明,使用单词“菜单”是解决汉堡包图标缺点的最可信赖的解决方案。
然而,需要注意的是,许多作者进行的研究和测试,比较了汉堡包图标和单词“菜单”,可能会产生误导,因为它们测试的是不同的视觉语言:图标与单词。
要使这些测试完全可靠,它们必须测试图标与图标,单词与单词。例如,测试汉堡包图标与向下指的箭头或单词“菜单”与单词“导航”。
让我们来看看单词“菜单”的优缺点。
考虑以下示例。
这是HTML:
Menu这是CSS:
//Word"Menu".word-menu{//Basicstyling,modifyifyouwantdisplay:inline-block;padding:16px8px;color:#666;font:12pxArial,"HelveticaNeue",Helvetica,sans-serif;background:#efefef;border-radius:3px;cursor:pointer;}这就是结果:
在这个例子中,我使用了类名.word-menu来明确表示我对这本书的意图,但这不是为生产命名元素的正确方式。使用更有意义和通用的命名约定,例如.menu-trigger可能是一个替代方案。使用通用类名将允许我们在不改变标记的情况下使用任何导航图标设计。
汉堡图标与单词菜单讨论的一个替代方案是同时使用两者。一些人认为这样做可以兼顾两全。
优点是:
缺点是:
让我们看看我们可以用来表示这种模式的两种样式。
MenuSCSS如下:
//HamburgerIconPlusWord"Menu"–Style1.hamburger-icon-plus-menu{//Basicstyling,modifyifyouwantdisplay:inline-block;font-family:Arial,"HelveticaNeue",Helvetica,sans-serif;background:#efefef;color:#666;border-radius:3px;cursor:pointer;}.style-1{padding:16px8px;font-size:16px;//HamburgerIcon&:before{content:'≡';}}结果如下:
注意在≡后面的空格,这样可以在不使用任何边距的情况下将图标与单词“菜单”分开。
HTML是:
MenuSCSS是:
//HamburgerIconplusWord"Menu"–Style2.hamburger-icon-plus-menu{//Basicstyling,modifyifyouwantdisplay:inline-block;font-family:Arial,"HelveticaNeue",Helvetica,sans-serif;background:#efefef;color:#666;border-radius:3px;cursor:pointer;}.style-2{padding:4px12px6px;font-size:10px;line-height:.8;text-align:center;//HamburgerIcon&:before{display:block;content:'≡';font-size:40px;}}这就是结果:
RWD最令人费解的特点之一是导航。它可以简单也可以复杂,取决于我们的需求。
在这一部分,我将向您展示如何构建三种常用的导航模式:
在我们查看每个细节之前,让我们澄清一下关于上述模式的一些特点:
在小屏幕上,所有导航模式都使用汉堡图标作为触发器,除了基于Flexbox的导航。在大屏幕上,所有示例中的导航栏都是水平链接组,链接居中。
为了改善切换和侧边导航的可用性,汉堡图标会添加/删除类.active,以提供视觉提示,显示该项目已被点击。这是通过一点jQuery完成的。
包括jQuery是这些演示的一部分,因此需要调用它才能使它们工作。
所示的标记仅用于菜单本身,元素和指令,如标记和HTML5Doctype已经被故意省略。
这些示例适用于所有主要浏览器,这些浏览器支持相对先进的CSS3属性。它们不使用FastClick脚本来消除移动设备默认的300毫秒延迟。
供应商前缀已被省略;毕竟,我们应该使用Autoprefixer来处理这些问题。
由于没有必要重复造轮子,以下示例基于其他作者的演示,例如BradFrost和AustinWulf的演示。
然而,所有原始演示都已被分叉并大幅缩放、增强、清理、优化、重新设计和移植到Sass,以适应本书的范围和风格。换句话说,您将看到的标记和代码已经专门为您进行了大量定制。
这是迄今为止在RWD和移动应用中最常用的导航模式。它使用汉堡图标作为菜单的触发器,当点击时触发菜单。这时,主容器向右滑动以显示左侧的菜单,再向左滑动以隐藏它。
这个示例不依赖于JavaScript来工作。但是,它使用了一些非语义元素来使其工作: 和元素。为了支持这种方法,它使用了:checked伪类,在各方面都有完美的支持。
这是我们的HTML:
$(function(){//Setuptheclickbehavior$(".label-trigger").click(function(){//Toggletheclass.activeonthehamburgericon$(this).toggleClass("active");});});让我们来看一下截图。
这是在折叠状态下小屏幕上的样子:
这是在展开状态下的样子:
这是在大屏幕上的样子:
在切换模式中,当点击汉堡图标时,导航栏会下滑,链接会堆叠。再次点击汉堡图标时,导航栏会折叠。
$(function(){//Addclass.jstothebodyifJSisenabled$("body").addClass("js");//Setuptheclickbehavior$(".menu-link").click(function(){//Toggletheclass.activeonthehamburgericon$(this).toggleClass("active");//Toggletheclass.activeonthemenutomakeitslidedown/up$(".menu").toggleClass("active");});});让我们来看一下截图。
这是在小屏幕上折叠状态下的样子:
这是展开状态下的样子:
这个使用Flexbox的自定义解决方案非常灵活,不一定需要使用媒体查询。另外两个菜单解决方案(切换导航和侧栏导航)需要媒体查询。
使用这个解决方案,菜单项会适应可用空间,使目标区域尽可能大,自动增强菜单的可用性。这个基于Flexbox的解决方案的另一个主要优点是它不依赖于JavaScript。
*,*:before,*:after{box-sizing:border-box;}//Mobile-firstMediaQueryMixin@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content;}}//Menuitself.menu{display:flex;flex-wrap:wrap;justify-content:space-around;max-width:980px;margin:auto;padding:2px;list-style:none;border:#9991pxdotted;//Listitemsli{//Expandtouseanyavailablespaceflex-grow:1;margin:3px;text-align:center;flex-basis:100%;@includeforLargeScreens(320){flex-basis:30%;}@includeforLargeScreens(426){flex-basis:0;}//Linksthemselvesa{display:block;padding:1em;color:#2963bd;text-decoration:none;background:#eee;@includeforLargeScreens(426){background:none;}}}}//MainContainer.main-container{max-width:980px;margin:auto;padding:20px;background:#eee;}//Stylingstuffnotneededfordemobody{margin:8px;font-family:Arial,"HelveticaNeue",Helvetica,sans-serif;}p{line-height:1.5;}h1{margin:0;}让我们来看一下截图。
这是在小屏幕(320px)上的样子:
这是在小屏幕(426px)上的样子:
这是在大屏幕(980px)上的样子:
我们现在已经掌握了使用HTML5和CSS3进行RWD的一半。这是一个巨大的里程碑!非常感谢您走到这一步!
RWD显然不仅仅是媒体查询、Sass混合和CSS网格。它还涉及理解我们目标区域的不同尺寸,控件的位置(链接、按钮、表单字段等),以及不同设备中的触摸区域。
创建菜单按钮总会有不同的方法,只要确保功能在任何屏幕尺寸上都不会出现问题。一旦我们定义了菜单按钮的样式,我们就可以确定哪种导航模式最适合我们的内容和用户。
在菜单按钮或导航模式方面,实际上并没有一个单一的、最佳的解决方案;一切都取决于每个项目的具体条件。我建议的是,无论你构建什么,都要确保始终保持高水平的浏览器支持、可扩展性和性能,这样用户就可以获得很好的体验,客户/公司也可以实现其目标。
现在我们谈论性能,下一章我们将讨论RWD的“丑孩子”:图片。
让我们跳舞吧!
我一直把图像称为RWD的“丑陋之子”。为什么?直到最后一刻,我总是试图避免处理它们。我要使用图像精灵吗?如果是的话,我应该将我的透明PNG导出为8位还是24位,或者32位?一些旧版IE不支持带有alpha通道的PNG,所以我必须导出一个GIF精灵。我可以使用SVG,但IE8及更早版本不支持SVG。我可以使用图标字体,但如果图标字体加载失败会怎么样?那我就得查一些分析数据。有一种新的高密度屏幕的iDevice?现在我每次都得导出两个(或更多)图像。太好了!但我不能为小屏设备提供超过正常尺寸图像两倍大小的高质量图像!是的,它可能看起来很好,但下载速度会很慢,他们甚至在第一个H1加载之前就可能离开网站。
你明白了。这只是刚刚开始涉及响应式网页设计中媒体工作的冰山一角。
其中一些想法今天仍然非常活跃,但多年来我学到了一些常识,并且紧跟解决所有这些问题的技术,拥有一个简单直接的处理图像(和视频)的系统可以走得更远。
在本章中,我们将讨论以下主题:
现在,这是我们在示例中要使用的图像:
这些了不起的人物是中国少林寺的两位功夫大师。他们的名字是释德如和释德阳。
由于我们还在用HTML5和CSS3精通响应式网页设计,我觉得这张照片与我们的使命非常契合。
我将要描述的功夫大师的原始图像的属性将有助于理解为响应式网页设计优化图像前后效果设定基线。
以下是原始图像的属性:
在本书结束时,我向你保证两件事。一,你将绝对准备好构建响应式网站和应用。二,当是时候开始一个新项目时,你将从座位上站起来,并摆出这些大师们正在做的同样的姿势。
图像编辑超出了本书的范围,以下步骤将需要某种形式的图像处理。在这一点上,您可以使用您喜欢的图像编辑器。我个人使用AdobeFireworks(确实如此),但绝大多数人使用Photoshop。
如果您不使用其中任何一个,您可以随时使用GNU图像处理软件(GIMP)或Paint.NET-两者都是免费的。您可以从这里下载它们:
您还可以使用在线图像编辑工具。但是,我必须承认,我从未使用过其中任何一个,所以我无法推荐任何一个。在这一点上,我可以说的是尝试其中一些,并选择最适合您需求的那个。
在设计中,创建图像副本的经验法则是从大到小进行,而不是相反。换句话说,图像越大,其后续副本的质量就越好。
仅通过将图像从2496x1664像素调整为1024x683像素,文件大小现在为331KB。与556KB相比,这几乎是文件大小的40%减少。这是一个巨大的改进,但我们还没有到达目标。
模糊背景实际上本身就非常有效,但从艺术指导的角度来看,它还有另一个好处:它有助于吸引对图像的重要部分的注意力。
在模糊背景之后,文件现在重量为185KB。与556KB相比,文件大小减少了约67%。我们开始有所进展了。
这是带有模糊背景的新图像:
优化的巨大胜利!
暗化或变亮不重要的区域非常主观,许多人可能不一定同意。在特殊情况下,这个过程-就像背景模糊技术一样-可以帮助减小文件大小并突出图像的重要部分。
我们基本上试图通过暗化或变亮图像来减少颜色的数量,从而创建纯色区域,或者至少尽可能纯色。换句话说,我们正在减少对比度。谨慎使用这个技巧。
在我们的功夫宗师的情况下,在暗化背景中不重要的部分后,图像现在重量为178KB。诚然,这与以前的过程没有太大不同(只有7KB的差异),但是我们可以从图像中提取的每一个千字节而不影响质量都是一件好事,178KB大约是文件大小的68%减少。
这是在稍微暗化背景后图像的外观:
每一个千字节都很重要。
这是过程的最后一步。这一步实际上可以分为两个较小的步骤。
保存一个在质量与文件大小之间平衡的JPG。没有确定的值可以始终应用于每个单独的图像。这一切都是即兴发生的。在执行此步骤时,您不希望以太低的质量保存图像,因为图像将经历另一个优化步骤。
我实际上要使用的是Adobe在2013年5月停止开发的软件:Fireworks。
从Fireworks以80%的质量导出图像后,功夫宗师的图像现在只有71KB。与原始的556KB相比,文件大小减少了约87%。
如果你没有先通过Fireworks运行图像,不要担心。即使您的图像可能会稍大一些,它仍然会被极大地优化,这是我们的目标。
这是556KB图像和最终52KB图像之间的前(左)后(右)比较:
我们必须承认,如果手动优化图像的过程在需要调整大小和优化许多图像的情况下可能会非常乏味和耗时,那么手动操作可能不是最佳选择。
有一些第三方和服务器端服务可以自动为我们完成这个过程。我们将把如何实现这些服务的教程留给另一本书。但是,我们将列出一些最受欢迎的服务,以便您在需要深入了解时有一个参考。
以下是一些第三方图像调整大小服务的示例:
以下是一些服务器端(.htaccess和/或.php)图像调整大小服务的示例:
然而,这种解决方案非常冗长。如果你必须处理许多图像,这种解决方案可能不是最佳选择,允许双重下载开始变得更有意义。每个项目都是不同的,因此尽可能做出最明智的决定非常重要。
一旦浏览器供应商决定完全支持这里提到的任何解决方案,就不需要担心双重下载或任何类型的polyfill了。
元素和srcset和sizes属性由响应式图像社区组(RICG)维护,现在已成为HTML规范的一部分。换句话说,我们可以在没有任何类型的polyfill的情况下使用它们,并且可以确信现代浏览器将支持它们。至少在某种程度上是这样。
我们需要使用polyfill的唯一原因是为了支持那些(传统和现代的)尚未实现对它们的支持的浏览器。
现在有很多polyfill,这里是我们今天可以使用的一些简要列表:
在Web设计和Web开发社区中,一些人强烈认为,考虑到新的HTML元素()并不是解决我们在RWD中遇到的图像问题的解决方案。他们认为解决方案应该来自已经存在的 标签。
sizes属性也可以与元素一起使用,但我们将专注于在 标签中使用sizes属性。
对我们来说很好,解决方案有两种。使用哪种方法来负责负责您的图像并不重要,重要的是您应该使用其中一种方法。如果您已经在使用,那太棒了。如果没有,不要担心。以下的解释将帮助您解决任何关于这个问题的疑问。
,何时使用srcset何时使用,何时使用srcset?这是一个非常合理的问题,我自己在第一次听到这些术语时也无法理解。所以我决定在俄亥俄州戴顿市的一次布拉德·弗罗斯特(BradFrost)的研讨会上向他请教。
推荐的方法归结为这个概念:艺术指导。在响应式图像中,艺术指导基本上意味着您有不同的图像,以某种方式裁剪,以便图像的不太重要的部分被剔除,从而专注于重要的部分。
这与只调整相同的图像不同。当然,您可以使用任何您想要的方法,但为了保持简单,当您想要提供艺术指导图像时,可以使用元素,当您只想提供相同图像的调整版本时,可以使用srcset属性。
在我们深入标记之前,让我们看一个关于艺术指导图像与使用功夫宗师照片的调整图像的视觉示例:
让我们看看这里发生了什么。原始图像周围有很多空间,我们可以看到后面的树和建筑物。调整大小的版本保持了原始图像的所有方面和比例1:1。
现在,让我们看看Picturefillpolyfill/script的实际效果。
然后,我们需要做的就是将它包含在文档的
部分中:
这是一个基本的片段的样子:
即使使用了polyfill,IE9对元素也存在问题。尽管听起来很奇怪,但我们需要在IE9中插入一个标签以正确工作。
这是为IE9修改后的标记样式:
正如您所看到的,我还突出显示了标签。这是那些不支持元素的浏览器的回退图像。
请记住的一件事是,不久之前,这个回退图像在一些现代浏览器中导致了双重下载。我的最后测试显示,在Chrome和Firefox中并非如此,它们支持元素。因此,请确保您运行所有必要的测试,以查看您的情况,然后考虑解决方案,如果您需要支持那些旧版浏览器。
srcset和sizes属性实际上来自规范,但在 元素中实现。使用srcset和sizes属性时,浏览器会决定在每种特定情况下使用哪个图像。如果需要,您还可以使用媒体查询,尽管不是必需的。单词vw表示视口宽度,用于让浏览器知道它应该根据视口宽度的百分比显示图像。如果看到类似80vw的东西,这意味着图像应该是当前视口宽度的80%。
w描述符表示图像的宽度。如果看到类似255w的东西,浏览器将了解特定图像的宽度为255px。
让我们看看带有srcset和sizes属性的 标签:
rsz这几个字母是resize一词的缩写。这是因为对于在RWD中只会被调整大小的图像,srcset属性使事情变得简单一些。
以下标记被截断,以便更容易专注于特定的解释。
我们首先看到的是已知的src属性,它充当回退图像:
这就是魔术开始发生的地方:
srcset="images/grandmasters-small-rsz.jpg255w,images/grandmasters-medium-rsz.jpg511w"在这个例子中,我们的计划是在支持srcset的浏览器中显示两个不同的图像文件。这是通过用逗号分隔的图像列表来实现的。此外,每个图像后面定义的值是图像的宽度:
images/grandmasters-small-rsz.jpg255w提示我们也可以使用高度:
grandmasters-small-rsz.jpg170h然而,最常见的用例是处理宽度并允许高度按比例调整,这样作者对图像有更多的控制。
向浏览器提供图像的大小将使其能够根据sizes片段中的媒体查询更明智地决定使用哪个图像:
sizes="(min-width:30em)80vw,100vw"记住,30em等同于480px。使用媒体查询min-width:30em,浏览器经历以下过程:
sizes属性的最后部分是视口宽度:80vw,100vw。
sizes="(min-width:30em)80vw,100vw"这意味着如果视口是30em(480px)或更小,浏览器将以80%的宽度显示图像。如果超过30em(480px),它将以100%的宽度显示图像。
最后,我们有alt属性:
alt="MasteringRWDwithHTML5andCSS3">为图像添加alt属性对于使用辅助技术的用户来说总是一个良好的可访问性实践。此外,如果图像没有加载,浏览器可以显示这个文本。
属性的顺序并不重要。换句话说,你可以先使用srcset,然后是alt,然后是sizes,然后是src属性(或者反之亦然)。
高密度屏幕将永远是RWD世界中我们无法摆脱的东西。所以如果你无法打败它们,就加入它们。
这是一个解决普通和高密度屏幕的片段:
正如你所看到的,这是一个更短更简洁的标记。它真的很简单明了:在没有srcset支持的情况下使用备用图像。如果有支持,那么如果设备具有普通密度显示,则使用1x图像。如果设备具有高密度显示,那么必须使用2x图像。如果我们支持的设备密度甚至更高,就应该添加一个3x后缀。
sizes属性是不是必需的。如果你的设计或条件需要使用sizes属性,你可以自由使用它。
正如我之前提到的,其他人认为新的HTML元素是不必要的,任何解决方案都应该基于增强和扩展已经存在的元素,比如 标签。
我只能说,在最后,这一切都无关紧要。重要的是,作为网页设计师和开发人员,我们应该利用我们手头的一切资源来让用户满意,创造令人难忘的体验,同时遵循持久实施的最佳实践。
Retina.js脚本是那些使事情变得更简单的脚本之一,有时你会想为什么响应式图像如此困难。
如果你还没有准备好处理和/或srcset和sizes属性,我不怪你。这很可怕,但我建议你继续努力理解这些工具,因为这是响应式图像的最新技术。
让我们先看一下JavaScript解决方案。
然后,我们将脚本放在HTML的底部,就在闭合的
标签之前:然后,我们在我们的标记中添加一个图像:
Retina.js的JavaScript解决方案的基本功能是查找页面中的图像,并在服务器上存在高分辨率版本时用高分辨率版本替换它们。
您需要在高分辨率图像的名称末尾加上@2x修饰符。
换句话说,如果您有以下图像:
Retina.js用以下内容替换它:
.jpg"alt="">只要服务器上存在@2x图像,Retina.js就会替换它。如果图像不存在,它就不会替换。
如果您已经排除或希望排除图像被Retina.js替换,您可以为图像添加data-no-retina属性:
Retina.js——Sassmixin解决方案嗯,这很奇怪——一个JavaScript解决方案,竟然也有CSS解决方案?太棒了!请注意,这个Sassmixin是用于应用背景高分辨率图片的。
Sassmixin如下所示:
@mixinat2x($path,$ext:"jpg",$w:auto,$h:auto){$at1x_path:"#{$path}.#{$ext}";$at2x_path:"#{$path}@2x.#{$ext}";background-image:url("#{$at1x_path}");@mediaalland(-webkit-min-device-pixel-ratio:1.5),alland(-o-min-device-pixel-ratio:3/2),alland(min--moz-device-pixel-ratio:1.5),alland(min-device-pixel-ratio:1.5){background-image:url("#{$at2x_path}");background-size:$w$h;}}使用方法非常简单:
使用background-size:100%auto;,背景图像将拉伸到其父容器的最大宽度。但是,如果容器更宽,图像将被重复。
我们要讨论的视频是嵌入在我们的好朋友
YouTube是一个令人惊叹的视频服务,使视频作者、网页设计师和开发人员的生活更加轻松。YouTube负责视频的托管、流媒体和技术条件,这些条件包括不支持Flash(iOS)或不支持标签(旧版浏览器)的浏览器,这真是太棒了。
我们需要做的第一件事是创建一个容器来容纳视频。这个容器是我们将要操作的,以便在保持其宽高比的同时给视频所需的宽度:
然后,我们创建一个用于嵌入视频的容器:
然后,我们嵌入视频,视频位于
好了,这就是我们的标记。现在,让我们从内到外处理CSS。
让我们给
.embed-containeriframe{position:absolute;top:0;left:0;width:100%;height:100%;}然后,让我们给.embed-container包装器添加一些上下文:
.embed-container{position:relative;padding-bottom:56.25%;padding-top:35px;/*ThispaddingisonlyneededforYouTubevideos*/height:0;overflow:hidden;}现在
对于16:9宽高比的视频,请使用padding-bottom:56.25%;。
对于4:3宽高比的视频,请使用padding-bottom:75%;。
现在我们需要做的就是定义整个东西的宽度。我们通过为外部容器.video-container添加宽度来实现这一点:
然后,在文档的
中调用jQuery和FitVids.js文件。最后,在我们的标记底部添加一个脚本来调用fitVids函数。基本上就是这样。FitVids.js的实际文件名是jquery.fitvids.js。这是我们将在示例中看到的文件名。
这是一个包含两个视频的HTML片段,分别来自YouTube和Vimeo的
提示文档对象模型(DOM):当你读到或听到有人说修改DOM时,基本上意味着修改生成的HTML。
如果你不使用jQuery或不想要任何框架依赖,但仍需要一个简单的JavaScript解决方案,最好的选择是使用ToddMotto开发的脚本:Fluidvids.js。
然后,我们需要在文档的
元素中调用fluidvis.js文件。一旦我们完成这一步,我们在标记底部添加一个小的脚本片段。就是这样。脚本将阅读标记,修改DOM,并使它找到的任何视频响应式。确保始终为
这是你需要使其工作的HTML片段:
.embed-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%;}.embed-containeriframe,.embed-containerobject,.embed-containerembed{position:absolute;top:0;left:0;width:100%;height:100%;}然而,使用以下片段,视频的容器看起来比应该高得多。为了使前面的片段正常工作,我们需要将嵌入容器包装在外部容器内。这是修改后的标记和CSS。
.video-container{width:100%;}.embed-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden;background:red;}.embed-containeriframe,.embed-containerobject,.embed-containerembed{position:absolute;top:0;left:0;width:100%;height:100%;}.video-container包装器是我们操纵的,以便定义任何我们想要的宽度,同时保持视频的纵横比。现在,我们只需要将标记放在我们的HTML文档中,将CSS片段放在我们的SCSS文件中。
我们将看到一些HTML和CSS/SCSS片段,以了解如何使用图标字体和SVG,但我们不会详细介绍这些资产的创建过程,因为这个过程超出了本节的范围。
当人们询问矢量和位图/光栅图像之间的区别时,我经常听到的答案通常围绕着“如果你放大它,它不会失去质量。对移动设备也不用担心。”虽然这是真的,但它并没有完全回答这个问题。所以这里是区别:
矢量图像是由数学方程组成的文件。这些方程的结果由图形(线条、形状、颜色)表示。如果图像的大小以任何方式改变,这些方程的值将被重新计算,生成的图形将被重新绘制。
位图或光栅图像是由像素组成的文件。这些像素具有特定/定义的宽度、高度和颜色。如果图像被放大,像素就会被拉伸,这就是为什么图像看起来模糊或呈像素化的原因。
有了这些定义,让我们来谈谈用于RWD的一些矢量格式。矢量格式包括:
让我们看看如何快速实现图标字体和SVG;Web字体将在下一章中讨论。
图标字体基本上是一个字体文件,但它不是字母,而是图标。有些人喜欢图标字体(我喜欢),有些人对它们并不太喜欢,特别是因为SVG变得如此受欢迎。
让我们看看图标字体的优缺点。
一些优点是:
一些缺点是:
在使用图标字体时,我可以给你一些建议:
然后我们来实现一个图标字体。
获取图标字体文件的最快方法是使用像IcoMoon.io或Fontello.com这样的第三方网络应用程序。您也可以获得FontAwesome的副本。
在考虑使用FontAwesome时要小心。使用一个包含数十个图标的完整字体文件,只使用其中的一小部分是浪费带宽的。如果你只打算使用少量图标字体,使用IcoMoon.io或Fontello.com进行自定义图标选择是一个更好的选择。
一旦你能解压提供的文件,你唯一需要的文件就是.woff文件。你只需要这个文件的原因是因为浏览器对.woff文件的支持一直可以追溯到IE9。除非你想/需要支持旧版浏览器(桌面和移动端),你可以使用.eot、.ttf和.svg文件。
我建议你保持简单,避免在尝试支持旧版浏览器中出现不必要的麻烦。他们只会得到文本而不是图标,或者在title=""属性中显示文本。
让我们将图标字体文件命名为icon-font.woff。创建一个/fonts文件夹,并将icon-font.woff文件保存在其中。这是我们要尝试实现的:一个带有左侧图标的浅蓝色链接,没有下划线,以及40pxArial/Helvetica字体:
使用伪元素的好处是我们的源标记始终保持清晰。在这种情况下,我们将使用:before伪元素,但这种技术也适用于:after伪元素。
让我们来看一下构建。
这是HTML片段:
//Webfontmixin@mixinfontFace($font-family,$file-path){@font-face{font:{family:$font-family;weight:normal;style:normal;}src:url('#{$file-path}.woff')format('woff');}}提示注意font:{…}块中的嵌套属性。通过这样做,我们保持代码的DRY,并避免重复术语font用于以下实例:font-family、font-weight和font-style。
然后,我们使用属性选择器创建一条规则来处理图标字体的基本样式属性:
//IconFontspecificrule[class^="icon-"],[class*="icon-"]{font:{family:icon-font,Arial,"HelveticaNeue",Helvetica,sans-serif;weight:normal;style:normal;variant:normal;}text-transform:none;line-height:1;speak:none;//ImproveFontRendering-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}提示注意属性选择器中的^和*字符。第一个意味着选择以术语icon-开头的元素,第二个选择包含术语icon-的元素。
然后,我们需要调用fontFacemixin来将字体引入编译后的CSS文件中:
这将编译为:
@font-face{font-family:icon-font;font-weight:normal;font-style:normal;src:url("/fonts/icon-font")format("woff");}这是使用:before使魔法发生的规则:
.icon-headphones:before{content:"\e601";margin-right:10px;}为了基本的样式增强,我们创建了另外两条规则。但是,它们并不是必需的。代码如下:
.icon{font-size:40px;}a{padding:5px;text-decoration:none;color:#2963BD;transition:.3s;&:hover{color:lighten(#2963BD,20);}&:focus{outline:2pxsolidorange;}}最终编译的CSS如下:
老实说,使用额外的HTML元素有点违背了将内容与样式分离的原则,因为出于样式原因添加额外的HTML元素并不是一些开发人员推荐的做法。然而,我们也可以说图标本身确实是内容,而不是样式。无论如何,这是概述。
//Webfontmixin@mixinfontFace($font-family,$file-path){@font-face{font:{family:$font-family;weight:normal;style:normal;}src:url('#{$file-path}.woff')format('woff');}}//IconFontspecificrule[class^="icon-"],[class*="icon-"]{font:{family:icon-font,Arial,"HelveticaNeue",Helvetica,sans-serif;weight:normal;style:normal;variant:normal;}text-transform:none;line-height:1;speak:none;//ImproveFontRendering-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}@includeiconFont(icon-font,'/fonts/icon-font');.icon-headphones:before{content:"\e601";margin-right:10px;}a{font-size:40px;//Stylingstuffpadding:5px;text-decoration:none;color:#2963BD;transition:.3s;&:hover{color:lighten(#2963BD,20);}&:focus{outline:2pxsolidorange;}}编译后的CSS如下:
SVG图形非常快速地获得了令人难以置信的流行。浏览器支持度为100%,甚至OperaMini也支持SVG图像。让我们讨论一些SVG图像的优缺点:
SVG的优点:
SVG的缺点:
SVG文件基本上是一个XML格式的文件。这是耳机图形的标记样式:
有许多使用SVG图像的方法:通过 、、或标签内联;作为CSS的背景图像;使用Modernizr在条件类中使用回退;或者使用jQuery或纯JavaScript,使用第三方服务如grumpicon.com等。
为了保持简单,我们将专注于两种方法:
内联SVG是许多网页设计师和开发人员的首选方法。我们可以使用CSS和JavaScript控制SVG的各个部分,这使得它非常适合动画效果。
内联SVG标记的一个缺点是图像不可缓存。换句话说,每次图像出现时,浏览器都必须读取SVG的XML。如果页面上有太多的SVG,这可能对页面速度和最终用户体验造成潜在的危害。因此,请注意页面的目标和使用您的网站/应用程序的访问者类型。
这是SVG耳机的HTML片段,内联在链接标签中:
svg{width:40px;height:40px;margin-right:10px;fill:#2963BD;}a{font-size:40px;text-decoration:none;color:#2963BD;}提示通过 标签调用的SVG文件不受CSS的影响。如果要对其进行任何样式更改,必须在实际的SVG文件中进行更改,或者将SVG标记内联。
然而,这个标记有一个问题。它没有为旧版浏览器提供回退,特别是IE8及以下版本。让我们试着解决这个问题。
为内联SVG提供回退图像的两种方法。
在标签内创建一个元素,并包含调用回退图像的 标签:
SVG的特点是标签是SVG世界中的有效元素。现在,尽管听起来很奇怪,但所有浏览器都将标签视为一个超出标准的标签,类似于HTML中的 标签。
在整本书中,我已经删除了自闭合标签的尾部斜杠/>,比如
或 元素。在HTML5中,可以选择带或不带。然而,在SVG的path元素中,尾部斜杠是必需的,这就是为什么你在这些示例中看到它们的原因。我刚刚提到的这些方法都不会在支持SVG的浏览器上导致双重下载。如果你问我,这是一个双赢的局面。
SVG是一种图像文件,因此在 中调用它是完全有效的:
我们知道SVG在现代浏览器中有无缺的支持,但在旧版浏览器(IE8及以下)中不显示先前的图像。
这个聪明的技巧是由AlexeyTen创建的。这是标记:
如果这种双重下载对你来说是可以接受的,并且你理解后果,那就去做吧。尽管如此,记住在下一个项目中可以改进这样的事情。
这是我在CodePen上为此创建的演示:
**#总结
在这里,我们正在看着地平线,思考着srcset或?调整大小还是艺术方向?Retina.js还是Sassmixin?FitVids还是FluidVids?图标字体还是SVG?内联SVG还是基于文件的SVG?什么是为我们的访客提供最佳体验的最佳方式?
是的,我知道这种感觉。你知道吗?这是一个好问题。否则,我们就不会学习如何掌握RWD了。
让我们换个话题,谈谈一个迷人的主题,它可以决定你的响应式设计成败:排版。
让我们出发吧!**
正如我在DaytonWebDevelopers会议上的一次演讲中所说的:
"有了稳固的排版比例,甚至可能不需要在网站上使用任何图片。"
排版的力量一定是网页设计中最被低估的资产之一。诚然,我们看到越来越多的设计中,排版已经得到了充分考虑,在创建网站或应用程序预期氛围方面发挥了重要作用。
在本章中,我们的重点将放在从排版角度考虑RWD所需考虑的一些方面、技巧和窍门上。
我们将讨论:
在设置像素字体大小方面的问题基本上出现在旧版IE上,如果用户因为任何原因想要放大页面,文本将保持在给定的像素大小不变。
现在,对于现代浏览器来说,这已经是过去的事情了。当你在任何现代浏览器中放大,如果放大到足够大,它将触发媒体查询,因此显示站点的移动版本。
另一方面,我们有相对单位,ems和rems,这基本上是设置我们的字体大小的推荐方式。
然而,ems的问题在于我们必须跟踪(在脑海中、在CSS/HTML注释中或在某个文本文件中)父容器的大小,这很容易变成字体管理的噩梦。ems中的字体大小取决于其父容器的字体大小。因此,如果我们有不同级别的嵌套容器,情况可能会变得非常复杂,因为跟踪父容器的字体大小并不容易。
但后来出现了rem。Rem代表根em。根是元素。
但在尝试任何Sass技巧之前,让我们先从本章的核心策略开始。
还记得我们在第三章中提到的RWD魔法公式吗,Mobile-firstorDesktop-first:
还有另一个类似的魔法公式,用于计算相对字体大小(ems),当字体大小已经以像素设置时。唯一的区别是我们不乘以100。
这就是那个公式:
目标÷上下文=结果
目标是以像素定义的字体大小。上下文是在父容器中定义的字体大小。结果是以ems定义的值。
以下是一个示例,假设父容器中的字体大小,在这个例子中是body,为16px:
header{font:30pxArial,"HelveticaNeue",Helvetica,sans-serif;}要计算相对字体大小,我们使用以下公式:
30px÷16px=1.875em。
因此,我们的CSS规则将如下所示:
header{font:1.875emArial,"HelveticaNeue",Helvetica,sans-serif;}我们需要为设计中的每个字体大小都这样做。
在理解数学方面是可以的。然而,真正的价值在于创造这些基于像素的值的思考过程。这就是模块比例的价值所在。
模块比例是由TimBrown创建的。有不同的方法来创建用于排版的模块比例。在我们的例子中,我们将使用两个基本数字和一个比例来创建一个模块比例。这些数字的乘积创建了一个在所有值之间和谐和成比例的比例。
最著名的比例是黄金比例,也被称为黄金分割,神圣比例等等。它的值是1.618。
现在,为了避免不必要的数学计算,黄金比例是基于斐波那契数列的:1,1,2,3,5,8,13,21等等。
这些数字有以下的模式:下一个数字是前两个数字相加的结果。例如:
0+1=1+1=2+1=3+2=5+3=8+5=13+8=21…
这里的想法是理解创建一组数字的意图,当它们一起使用时是和谐的。我们将使用相同的方法来创建一个排版比例,以便在我们的项目中使用模块比例网页应用程序,并忘记手动计算项目的相对字体大小。
一旦网页应用程序打开,我们需要按照以下三个步骤来创建我们的模块比例:
模块比例可以用于任何使用某种值的东西,不仅仅是排版。它可以用于填充,边距,行高等等。然而,我们在本章的重点是排版。
定义第一个基本数字的推荐方法是使用正文文本大小,也就是段落中使用的字体大小。但请记住,使用正文文本大小作为第一个基本数字并不是强制性的。我们可以使用我们字体的x高度,或者在该字体中的其他长度,我们认为可能是一个很好的起点。
虽然我们可以选择任何字体大小,但让我们从我们都知道所有浏览器使用的默认字体大小开始,即16px。所以我们在第一个基本字段中输入16px。
点击加号图标并添加第二个基本字段。
暂时不用担心应用程序的字体大小预览,因为你可以看到,当我们为我们的基本值输入数字时,右侧预览窗格中的字体大小会改变。我们将在下一步中介绍这一点。
这个魔术数字可以是我们想要的任何东西,但它与我们的项目有直接关系。在这个例子中,假设我们的目标是针对最大宽度为1280px的屏幕,所以我们的主容器将具有最大宽度为1140px。所以让我们在第二个基本字段中输入1140px。
这些比例是基于音乐音阶的,列表中还包括黄金比例(1.618),如果我们决定使用它的话。从比例下拉菜单中,选择1:1.618-黄金分割比例。
就是这样!我们现在已经创建了我们的第一个模块比例。
我们的排版现在有了坚实的模块基础,让我们使用它。
如果您点击表格视图,所有文本现在都消失了,我们只剩下一系列字体大小,范围从非常小的值到非常大的值。但没关系。这就是模块比例的力量。
这是我们看到的:
如前面的图像所示,有三列:
我们需要专注于第一列和第二列。突出显示的16px,或1em的行,将成为我们段落的字体大小。16px是大多数浏览器中的默认字体大小。
然后,我们定义我们的标题元素。假设我们只定义h1,h2和h3。这意味着我们将选择大于16px的行,具有更大的字体大小:
:9.889px,即0.618em
就是这样!模块比例中的所有数字都是和谐的,当一起使用时将提供清晰的视觉层次结构,以及通过其他方法难以获得的关系。
这里有一个例子。
MeaningfulTypographyforRWD "Withasolidtypographicscaleyoumightevengetawaywithnotusingasingleimageonyourwebsite."
—RicardoZea
CreatingaModularScaleforaHarmoniousTypography AModularScaleisacombinationofaratiooftwoormorenumbers,andabasenumber.
TheGoldenRatio Themostwell-knownratioistheGoldenRatioalsoknownastheGoldenSection,DivineProportion,etc.It'svalueis1.618.
这是SCSS://Mobile-firstMediaQueryMixin@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content;}}body{font:16px/1.4Arial,"HelveticaNeue",Helvetica,sans-serif;@includeforLargeScreens(640){font-size:20px;}}h1{font-size:2.454em;}h2{font-size:1.618em;}h3{font-size:1.517em;}提示注意我也包含了移动优先的Sassmixin。
这是编译后的CSS:
body{font:16px/1.4Arial,"HelveticaNeue",Helvetica,sans-serif;}@media(min-width:40em){body{font-size:20px;}}h1{font-size:2.454em;}h2{font-size:1.618em;}h3{font-size:1.517em;}在小屏幕上(宽510px)模块比例如下:
在大屏幕上(宽850px)也是这样:
我们在这里唯一可能遇到的问题是我之前提到的关于使用em的问题:跟踪父元素的字体大小可能会变成字体管理的噩梦。
使用像素是不可取的,因为在传统浏览器中存在可伸缩性问题。然而,使用rems可以保持在“相对字体大小”领域,同时提供基于像素的思维方式,但没有可伸缩性问题。这使我们能够支持不支持rems的传统浏览器。
这是我在CodePen为此创建的演示:
我们只需要一个Sassmixin,允许我们设置没有特定单位的字体值,mixin会负责为现代浏览器添加rem单位的字体大小,为传统浏览器添加像素单位的字体大小。
这是由ChrisCoyer创建的Sassmixin:
//PixelstoRemsMixin@mixinfontSize($sizeValue:1.6){font-size:($sizeValue*10)+px;font-size:$sizeValue+rem;}提示我对mixin的原始名称进行了小修改,从使用破折号分隔改为驼峰命名法。我这样做的原因是因为在扫描文档时,从类名中更容易找到mixin的名称。
用法如下:
@includefontSize(2);这个示例使用了前一章节中使用的相同标记,所以我只会展示SCSS和一些截图。
SCSS如下:
//Mobile-firstMediaQueryMixin@mixinforLargeScreens($media){@media(min-width:$media/16+em){@content;}}//PixelstoRemsMixin@mixinfontSize($sizeValue:1.6){font-size:($sizeValue*10)+px;font-size:$sizeValue+rem;}//Base-10modelhtml{font-size:62.5%;@includeforLargeScreens(640){font-size:75%;}}h1{@includefontSize(3.9269);}h2{@includefontSize(2.5888);}h3{@includefontSize(2.457);}p{@includefontSize(1.6);}考虑以下几点:
编译后的CSS如下:
html{font-size:62.5%;}@media(min-width:40em){html{font-size:75%;}}h1{font-size:39.269px;font-size:3.9269rem;}h2{font-size:25.888px;font-size:2.5888rem;}h3{font-size:24.57px;font-size:2.457rem;}p{font-size:16px;font-size:1.6rem;}这是在小屏幕上(510像素宽)使用rems-to-pixelsmixin的模块化比例的样子:
这是在大屏幕上(850像素宽)的样子:
这是我在CodePen上创建的演示:
我们刚刚看到的示例使用了系统字体Arial。让我们继续使用一些网络字体来提升这些示例的特色。
现在几乎必须使用网络字体,我说几乎是因为我们需要注意它们对我们项目的影响,如果必要,我们实际上可能根本不使用它们。
在深入研究如何使用网络字体之前,以下是一些可能对你们许多人有帮助的网络字体资源:
现在,让我们看看使用网络字体的利弊:
优点包括:
缺点包括:
还有其他不值得深入的,比如备用文本的闪烁和伪文本的闪烁(FOFT)。
要实现网络字体,我们需要在我们的CSS中使用@font-face指令...嗯,SCSS。
网络字体在文件大小和服务器请求方面都很昂贵,因此请适度使用网络字体。您使用的越多,您的网站/网络应用程序就会变得越慢。
是的,处理网络字体的CSS代码相当庞大,哦天啊。
@mixinfontFace($font-family,$file-path){@font-face{font:{family:$font-family;weight:normal;style:normal;}//IE9CompatModessrc:url('#{$file-path}.eot');//IE6-IE8src:url('#{$file-path}.eot#iefix')format('embedded-opentype'),//ModernBrowsersurl('#{$file-path}.woff')format('woff'),//Safari,Android,iOSurl('#{$file-path}.ttf')format('truetype'),//Safari,Android,iOSurl('#{$file-path}.svg')format('svg');}}使用一行代码调用字体文件。让我们使用Oswald字体:
@includefontFace(oswald-light,'../fonts/oswald-light');在任何元素上使用它只需在字体堆栈的开头添加字体名称,如下所示:
p{font:2.2remoswald-bold,Arial,"HelveticaNeue",Helvetica,sans-serif;}如果我们需要包含多个字体文件,只需添加另一行调用mixin,但指定其他字体名称:
@includefontFace(oswald-light,'../fonts/oswald-light');@includefontFace(oswald-regular,'../fonts/oswald-regular');前两行代码将编译为以下CSS:
@font-face{font-family:oswald-light;font-weight:normal;font-style:normal;src:url("../fonts/oswald-light.eot");src:url("../fonts/oswald-light.eot#iefix")format("embedded-opentype"),url("../fonts/oswald-light.woff")format("woff"),url("../fonts/oswald-light.ttf")format("truetype"),url("../fonts/oswald-light.svg")format("svg");}@font-face{font-family:oswald-regular;font-weight:normal;font-style:normal;src:url("../fonts/oswald-regular.eot");src:url("../fonts/oswald-regular.eot#iefix")format("embedded-opentype"),url("../fonts/oswald-regular.woff")format("woff"),url("../fonts/oswald-regular.ttf")format("truetype"),url("../fonts/oswald-regular.svg")format("svg");}这是一种非常巧妙的方式,只需两行代码就可以创建所有这些CSS,是吧?然而,如果我们想做正确的事情,让我们分析一下我们在这里做什么:
因此,问题是:我们是否可以优雅地降级旧版浏览器和操作系统的体验,并让它们使用系统字体?
当然可以!
在优化mixin以仅使用.woff字体后,它看起来是这样的:
@mixinfontFace($font-family,$file-path){@font-face{font:{family:$font-family;weight:normal;style:normal;}//ModernBrowserssrc:url('#{$file-path}.woff')format('woff');}}使用方式完全相同:
@includefontFace(oswald-light,'../fonts/oswald-light');@includefontFace(oswald-regular,'../fonts/oswald-regular');编译后的CSS要短得多:
@font-face{font-family:oswald-light;font-weight:normal;font-style:normal;src:url("../fonts/oswald-light.woff")format("woff");}@font-face{font-family:oswald-regular;font-weight:normal;font-style:normal;src:url("../fonts/oswald-regular.woff")format("woff");}在几个元素上使用它看起来像这样:
h1{font:4.1remoswald-regular,Arial,"HelveticaNeue",Helvetica,sans-serif;}p{font:2.4remoswald-light,Arial,"HelveticaNeue",Helvetica,sans-serif;}仅提供.woff字体可以减少我们的文件管理工作量,有助于解放我们的大脑,让我们专注于最重要的事情:构建一个令人难忘的体验。更不用说,它使我们的CSS代码更加简洁和可扩展。
但等等,我们让旧版浏览器优雅地降级到系统字体,我们仍然需要为它们定义像素字体大小!
像素到remsSassmixin来拯救!
记得在标签中查看十进制模型以便更容易计算:
h1{@includefontSize(4.1);font-family:oswald-regular,Arial,"HelveticaNeue",Helvetica,sans-serif;}p{@includefontSize(2.4);font-family:oswald-light,Arial,"HelveticaNeue",Helvetica,sans-serif;}编译后的CSS如下所示:
因此,通过利用两个简单的Sassmixin的超能力,我们可以轻松嵌入网络字体,并为我们的字体大小使用rems,同时为旧版浏览器提供基于像素的字体大小。
这是一个强大可扩展性的很好的例子。
在不失去任何动力的情况下,让我们转变思路,谈谈如何通过使用SimpleFocus的强大FlowType.jsjQuery插件来实现最小行长,从而提高页面的可读性。
最具说服力的编辑原则之一是,最易读的排版的理想行长在45到75个字符之间。
如果你问我,这是一个相当不错的范围。然而,实际上让你的段落足够长,或者足够短,就像一个“盲人引导盲人”的游戏。我们怎么知道容器的宽度和字体大小的组合是否真正符合45到75个字符的建议?此外,在小屏幕或中等屏幕上,你怎么知道情况是这样的?
棘手的问题,对吧?
好吧,不用担心,因为有了FlowType.js,我们可以解决这些问题。
我们需要的第一件事是HTML,所以这是我们将要使用的标记:
好吧,我们确实需要设置字体大小,因为如果FlowType.js没有加载,我们将受制于浏览器的默认样式,而我们设计师不想要这样。
//PixelstoRemsMixin@mixinfont-size($sizeValue:1.6){font-size:($sizeValue*10)+px;font-size:$sizeValue+rem;}//Base-10modelhtml{font-size:62.5%;}h1{@includefontSize(3.9269);}p{@includefontSize(1.6);}这将编译成以下CSS:
html{font-size:62.5%;}h1{font-size:39.269px;font-size:3.9269rem;}p{font-size:16px;font-size:1.6rem;}这就是魔法发生的地方。我们创建一个jQuery函数,可以指定要定位的元素。这个函数可以放在一个单独的JavaScript文件中,也可以放在标记中。
在我们的示例中,我们告诉FlowType.js将字体的调整应用到元素上。由于我们使用相对字体大小单位rems,所有文本将在任何屏幕宽度下自动调整大小,保持理想的行长度。
这是jQuery函数:
$(function(){$("html").flowtype();});定义阈值我们刚刚看到的解决方案存在潜在问题:FlowType.js将无限期地修改段落的字体大小。换句话说,在小屏幕上,文本将变得非常小,在大屏幕上,文本将变得太大。
我们可以用两种不同的阈值方法或两者结合来解决这个问题。
现在,我们需要澄清的一件事是,这部分需要一些调整和调整,以获得最佳结果,没有特定的值适用于所有情况。
我们将采用以下方法:
定义最小和最大宽度将告诉FlowType.js在哪些点停止调整大小。
让我们定义宽度阈值:
$(function(){$("html").flowtype({//Maxwidthatwhichscriptstopsenlargingmaximum:980,//Minwidthatwhichscriptstopsdecreasingminimum:320});});提示我选择的阈值专门适用于这个示例,可能不适用于其他情况。调整和测试,直到你得到适合推荐的每行45-75个字符的理想宽度。
就像宽度阈值一样,定义最小和最大字体大小将告诉FlowType.js应该将文本缩放到的最小和最大字体大小。
调整fontRatio值是一个凭感觉的练习,所以像没有明天一样调整和测试。
让我们看一下字体大小的值:
$(function(){$("html").flowtype({//Maxwidthatwhichscriptstopsenlargingmaximum:980,//Minwidthatwhichscriptstopsdecreasingminimum:320,//MaxfontsizemaxFont:18,//MinfontsizeminFont:8,//Defineownfont-sizefontRatio:58});});提示在列表中的最后一个值后面不需要包含逗号。
FlowType.js真的很棒!
所以在这里,我们在RWD的排版上升了一个层次。排版还有更多内容吗?当然有!这个令人惊叹的主题本身就是一个完整的行业,没有它我们就不会读到这本书。
现在我们可以说,我们明白为什么使用相对单位进行排版是一个好方法:可伸缩性。此外,使用我们的小魔法公式,我们可以计算设计中每个文本元素的相对字体大小,但为什么要经历这么多麻烦呢?排版的模块化比例在这方面拯救了我们,并为我们的项目注入了令人惊叹的排版和谐。谁知道,也许我们根本不需要使用图片!
品牌现在可以通过网络字体扩展到网络上,但我们需要谨慎考虑它们对我们网站/应用的影响。另外,就现代浏览器而言,我们只需要使用一种文件类型(WOFF字体文件),这样可以更容易地管理——对于浏览器下载和用户享受都更方便。
FlowType.js增强了我们的标题和正文文本,同时保持了良好的可读性水平。
现在,RWD的一个重要部分是(信不信由你)做一些我们多年前做过的事情。在下一章中,我们将保持简单,讨论电子邮件中的RWD。
是时候回到过去了!
在我们回到过去之后,我们来想一想90年代末使用表格进行设计;是的,你没看错,使用表格进行设计。
今天,在创建电子邮件方面并没有任何不同:我们必须使用表格进行布局。为什么?很简单。没有任何战争。那就是电子邮件客户端之间的竞争。
与1995年的浏览器之战不同,当时Netscape和InternetExplorer为市场霸权而战,电子邮件客户端自从有记忆以来就一直过着各自独立的生活,几乎对彼此毫不在意。
由于浏览器之战,我们现在拥有了这样一些非常棒的符合标准的浏览器,它们充满了功能、定制能力、不断的更新等等,使每个人的在线生活变得更加轻松。
另一方面,电子邮件客户端以自己的步伐发展,而且步伐很慢,因为实际上没有任何竞争。此外,绝大多数公司已经与微软的Outlook绑定在一起。在Office的最新版本中,Outlook实际上比早期版本更糟糕,因此并没有真正帮助电子邮件领域支持更现代的技术。
此外,有一些相对较新的电子邮件客户端彻底拒绝支持标签之后。
这是它的样子:
此电子邮件已在以下电子邮件客户端和平台上进行了测试:
以下是电子邮件在各种桌面和移动客户端上的图像:
在这里,一些电子邮件客户端,无论是桌面还是移动设备,实际上都能够使用我们使用的网络字体Roboto。其余的使用了字体堆栈中的Arial,这正是我们的计划。
令人惊讶的是,在桌面上,Outlook2010是唯一能够呈现Roboto的电子邮件客户端,尽管字体看起来比实际粗,但它仍然是唯一的。
在移动设备上,iPhone的邮件应用和Android上的Gmail是能够使用Roboto的。
在构建响应式电子邮件时,我们必须补充我们的技巧、黑客和对电子邮件客户端的怪癖和故障的广泛理解,以及可以让我们更快地测试、优化我们的工作流程、提高我们的效率并学习更多现代技术的工具。
我必须承认,这个工具的名称并不是很描述性,也没有提到这个工具有多有用。使用Litmus'sPutsMail,我们可以将电子邮件发送到任何我们想要进行测试和调试的账户。只需点击一个按钮,PutsMail就可以将电子邮件发送到几乎任意数量的电子邮件账户。
PutsMail允许我们做以下事情:
我使用这个工具发送了您在前面几段中看到的所有电子邮件客户端屏幕截图的图像。
编写内联CSS是一项相当繁琐的任务:如果我们的段落具有font-family:Arial,Helvetica,san-serif;font-style:italic;font-weight:bold;font-size:18px;,那么我们必须将所有这些属性复制并粘贴到每个段落中。或者,我们必须复制并粘贴相同的段落,并更改其中的文本。
使用CSS内联工具,我们可以在电子邮件模板的
部分中的CSSinliner将执行以下操作:CSSinlinersareanawesometool!
优点如下:Litmus的PutsMail是一个例外,因为它在发送测试电子邮件时有内联CSS的选项。
一些最受欢迎的CSSinliner如下:
谁说我们不能使用Sass、Grunt和Node.js等现代和更先进的技术构建电子邮件?
对于那些有点更懂技术并且热爱前端开发的人来说,这些电子邮件框架可以极大地加快速度。
一些电子邮件框架如下:
它使用以下内容:
加快速度的方法是使用第三方电子邮件模板,因为作者已经至少在很大程度上为我们做了繁重的工作。让我们来看看使用第三方响应式电子邮件模板的利弊。
一些常见的响应式电子邮件模板如下:
以下是拖放电子邮件构建服务:
BEE是BestE-mailEditor的缩写
这个工具肯定是电子邮件开发和学习中最令人惊奇和有用的工具之一。Litmus的Scope书签允许我们从任何网络邮件客户端中查看电子邮件模板的构建方式。
bookmarklet是一个JavaScript组件,你可以存储在书签中,通常是在书签栏中。当你点击这个bookmarklet时,会显示特殊功能。bookmarklet本身并不是一个书签;它恰好存储在书签中,但提供的功能与常规书签非常不同。
Scope的工作方式非常简单:
这对于了解其他人是如何在电子邮件中实现视频、渐变、响应等惊人的事情非常有用。这是一个截图,向我们展示了我们刚刚构建的响应式电子邮件模板在发送到我的Gmail帐户并且使用书签工具scope后的样子。
在左边是Litmus网站上的Scope侧面,右边是在SublimeText中打开的文件。它们完全相同...甚至格式都是相同的。令人惊讶的工具!
使用Litmus的Scope的电子邮件模板
哇,我们成功了!
在关于响应式电子邮件的最后一章中,我们讨论了一些重要的事情,除了构建实际的电子邮件。
我们现在明白了为什么电子邮件在任何营销活动中如此重要,因为越来越多的电子邮件在移动设备上被打开。然而,人们更喜欢在他们的桌面上与电子邮件互动——这是使我们的电子邮件响应式的非常充分的理由。
像CSS重置、将内容放在100%宽的表格中,以及创建内部表格这样的事情,基本上是任何电子邮件设计的常用流程。我们现在知道,电子邮件的最大宽度应该是600像素。
微软的Outlook2007/2010/2013版本是电子邮件客户端的IE6:它们对现代HTML和CSS的支持非常差,但它们是桌面上最流行的电子邮件客户端。因此,使用条件注释来实现漂亮的CTA和背景是一个好方法。
此外,为了尽可能高效,使用第三方电子邮件模板和拖放电子邮件构建服务始终是一个选择。
我们现在可以摆出少林寺的功夫宗师释德如和释德阳在第六章中所做的相同姿势了,在响应式Web设计中使用图像和视频。
THE END
1.魔智科技在线生成logo魔智科技提供在线生成logo的服务,使您能够快捷、免费地获取高质量的logo设计。本文从三个方面详细介绍了魔智科技在线生成logo的优势,包括操作简便、多种定制化选择、高质量设计保障,旨在帮助读者了解并使用该服务。 一、操作简便 魔智科技在线生成logo的操作非常简便,即使您没有任何设计经验也可以轻松上手。首先,您需要http://www.chinauci.cn/news/webnews/26560.html
2.魔法豆豆logo设计生成器魔法豆豆logo免费设计在线生成免费制作你的魔法豆豆logo设计 1.选择 只需输入品牌名称,让我们的AI设计引擎自动生成无限logo创意供您挑选。 2.编辑 找到喜欢的logo创意后轻松在线编辑logo布局,字体和logo图标。我们的智能配色功能还能为您搭配不同的logo配色直到发现您的完美logo设计。 https://www.logosc.cn/biaozhi/?s=%E9%AD%94%E6%B3%95%E8%B1%86%E8%B1%86
3.2021年策划人必备的241个策划工具20. 二维码生成 21. 企业信息查询 22. 上市公司财报查询 23. 其他工具 1.淘系后台数据平台&电商插件 01. 生意参谋 https://sycm.taobao.com/ 生意参谋是阿里商家后台的数据管理平台,是TP的生意参谋,也是策划的策略参谋。 那么,策划人可以用生意参谋来做什么呢? https://www.niaogebiji.com/article-69353-1.html
4.www.nbxinxi.com/xxxr73766207.htm巴啦啦小魔仙被操 70.41MB 1223好评 xx美欧xⅩ 黑料网155.fnn 蓝鲸激情性爱电影 496.61MB 妈妈logo设计_证券时报 精品少妇内射 饥渴少妇激情视频在线观看 36.52MB 73%好评70人) 少女粉鲍图转生成魅魔每天榨牛奶漫画免费下拉式_转生成魅魔每天榨牛_慧聪网 校园欧美小说图片在线阅读 黄色视频一http://www.nbxinxi.com/xxxr73766207.htm
5.一个月超3万个GPTs!深扒全球Top50GPTs,谁是民间GPT王者?智东西发现,多个GPT商店的榜单来自于GitHub用户1mrat发布的/gpt-stats项目,基于Similar Web平台定期抓取的GPTs访问量数据生成。 下表展示了自GPTs发布至2023年11月29日期间,全球流量排名Top50的GPT助手,覆盖设计、营销、科研、教育、生活、办公、游戏、编程等各个领域。虽然这不是官方数据,但也能为产业提供一些参考https://www.eefocus.com/article/1646826.html
6.魔搭社区ModelScope新榜AI设计工具 魔搭社区ModelScope 魔搭社区ModelScope是一个模型开源社区及创新平台,致力于通过开放的社区合作,构建深度学习相关的模型开源社区,并开放相关模型创新技术,推动基于“模型即服务”(Model-as-a-Service)理念的模型应用生态的繁荣发展。 访问官网魔搭社区 ModelScope 是一个专注于模型开源及创新的社区平台。它https://nav.newrank.cn/site/1017
7.重磅!阿里巴巴所有产品未来将接入大模型全面升级·阿里云智能logo设计 阿里云智能logo设计是一款基于人工智能技术的logo设计工具。它结合了大数据分析、机器学习、图像识别等多种先进技术,能够根据用户提供的关键词、行业、品牌等信息,自动生成符合用户需求的独特logo设计方案。它不仅具有自动生成logo的功能,还提供了丰富的设计元素、字体库和颜色搭配方案,帮助用户快速制作https://developer.aliyun.com/article/1193269
8.企业快速建站个人自助模板建站高端网站定制设计逐浪设计餐饮品牌设计logo设计品牌VI设计美食摄影菜单设计6PC+手机站含8G空间,可自定义导航及页面、首页模块可显示/隐藏、拖拽排序、视差动效等功能,并同步生成手机站,也可绑定微信公众账号。目前已有数万家企业及个人成为UEmo的忠实用户,并得到了极高的用户满意度。超百个城市代理伙伴与UEmo魔艺携手共进。我们的客户https://www.ed4.cn/links/7485aa6e90cba96637cf.html
9.巴啦啦小魔仙logo设计理念说明巴啦啦小魔仙 logo设计简约大气、识别性强,不仅很好地实现了巴啦啦小魔仙品牌识别与传播价值,而且还传递了巴啦啦小魔仙 logo设计理念、内涵,因此,深圳vi设计公司认为巴啦啦小魔仙 logo设计非常优秀。 本文关键词 巴啦啦小魔仙 logo,巴啦啦小魔仙 logo设计理念,巴啦啦小魔仙 logo设计含义,巴啦啦小魔仙 logo设计http://www.sz4a.cn/news/20230111210030.html
10.魔方logo设计魔方logo素材魔方logo图片觅知网为您找到129个原创魔方logo设计图片,包括魔方logo图片,魔方logo素材,魔方logo海报,魔方logo背景,魔方logo模板源文件下载服务,包含PSD、PNG、JPG、AI、CDR等格式素材,更多关于魔方logo素材、图片、海报、背景、插画、配图、矢量、UI、PS、免抠,模板、艺术字、Phttps://www.51miz.com/so-sucai/3419454.html
11.欢迎体验Motiff妙多:AI时代设计工具优设网对于新创立的项目:设计师只有一个模糊的“意图”。在进行设计之前,设计师需要更多的灵感来参照,此时让 AI 快速提供一些“呈现”是有价值的。 对于已经运转的项目:此时的设计师“意图”更加具体。这些“意图”可能是描述,也可能是线框图,或直接是图文并茂的产品需求文档。如果让 AI 基于此生成界面,设计师更需要的https://www.uisdc.com/motiff
12.全文)msi微星GT802QE035CN(i74720)笔记本评测在键盘区的左上角印有steelseries(赛睿)和Cherry的LOGO,显然已经为这款内置键盘标明了身份。GT80 Titan的触控板为了保证手感,还是分体式设计,两个按键布置在小键盘下方,清脆有力,回弹很强。https://nb.zol.com.cn/504/5044161_all.html
13.教育部公布多个LOGO方案,每一个都有你想要的设计说明。术心为提升国家智慧教育公共服务平台的传播力和影响力,教育部组织开展了智慧教育门户LOGO设计征集活动。征集活动累计提交设计作品347件。经专家评审委员会对参评作品进行认真、严格的评选,共评出20件入围作品。 昨天,教育部“微言教育”(微信号:jybxwb)面向社会公布了20件入围作品开展网络投票。作品的具体内容如下: https://www.shangyexinzhi.com/article/5018621.html
14.web.hzaqdq.com/nodenews/725368.htm原神罗莎莉亚含果体版3d打印模型图纸stl设计素材 metcn人体模特瑞木云 欧美极限扩肛 亚洲码和欧洲码班长哭着说会坏掉视频 魅魔榨魔乳の馆在线观看樱花动漫 多毛BGMBGMBGM胖老年人 漂亮美女一级毛片 转生成魅魔每天榨牛奶漫画尽在手机漫画网在线观看_光明网 优贝平台 雀7IIII2扣长久 777米奇自拍视频http://web.hzaqdq.com/nodenews/725368.htm
15.新闻中心——驱动之家:您身边的电脑专家压榨剩余性能是一件专精的工作,要求每一位玩家了解CPU、内存超频的每一个参数并不合理,更多时候以来软件本身的基础超频设计已经足够。以技嘉Z390 AORUS PRO WIFI主板为例,从定位到设计完全奔着游戏PC而去,没有过多的累赘设计,并且最关键的CPU供电部分使用了12+1相数字供电设计,包括数字PWM 控制芯片及DrMOS晶体管,https://news.mydrivers.com/blog/20191231.htm
16.web.gz天堂妖精18精神出生有多少魔 60.89MB 5817好评 国产埃及毛片儿 入禽太深视频免费神马 狂操空姐被亲妺妺夹得我好爽高和g视频 柚子猫糖心logo婚纱新娘 翁熄乱叫 性变态暴力整夜惨叫小说 天天番号转生成魅魔每天榨牛奶漫画免费下拉式_转生成魅魔每天榨牛_楚天都市报 美女被男人草出水的,软件 中国http://web.gz-guangju.com/nodenews/57692229.shtml
17.不能错过的国内AI工具,让工作变得轻松又有趣在线作图工具,支持思维导图、流程图等,AI辅助设计让作图更简单。 亿图脑图: https://www.edrawsoft.cn/mindmaster 提供多功能的思维导图制作工具,AI辅助设计,提高创意和规划的效率。 GitMind思乎: https://gitmind.cn/ 在线思维导图软件,AI技术辅助快速生成脑图,支持团队协作。 https://m.douban.com/note/865014309/
18.魔方创意图片图片合成平面设计魔方创意设计枫叶魔方 魔方大赛 魔方创意 魔方矢量 玩魔方 二阶魔方 九魔方素材 理财魔方 魔方插画 魔方素材设计 魔方素材透明 魔方元素 魔方背景素材 魔方立体素材 魔方透明素材 魔方砖素材 神秘宇宙魔方 透明魔方素材 宇宙魔方 3d魔方 魔方公寓 魔方比赛 水晶魔方 科幻魔方 彩色魔方玩具 ps魔方素材 儿童魔方 彩色魔方 创意魔方空https://699pic.com/tupian/chuangyi-mofang.html
19.Ideogram:轻松搞定文字数字类LOGO的AI绘画新星,无需魔法免费自定制图像中的文本效果: 用户可以在其网站ideogram.ai上使用多个预设样式生成图像,其中“排版”样式最显着,可以自定制图像中的文本效果。 Ideogram的使用场景 平面设计师: Ideogram的文本生成优势可能吸引那些需要高质量带文本图像的平面设计师等用户。 创意产业: Ideogram的可靠排版功能在市场上脱颖而出,有望在平面设https://www.ayxayx.com/4449.html
20.魔方LOGO设计RUBIKS鲁比克品牌logo设计GANCUBE,由中国魔方速拧知名人物——江淦源先生创立于2014年,具备研发设计、生产制造、营销推广魔方产品的全产业链营运能力,是一家拥有多项发明专利的新兴科技型企业。 MoYu魔域文化-商标logo设计理念 魔域文化有限公司位于有中国"玩具礼品城"美称的澄海市区,得天独厚的地理与资源优势,开启了魔域文化追求梦想的序幕。 https://www.3wen.com/wenzhang/id/4072.html
21.这13个趣味网站好玩到炸裂!90%都没听过!一玩就停不下来1. 图片创意设计网页-WeaveSilk 一个有趣且有创意的网页,通过调整对称点,调整颜色,将你的鼠标轨迹进行你会发现这个网站和Google看上去非常相似,除了在谷歌Logo边增加了一些戏剧性的词句。然后这个时候你的朋友这时候该网站会自动生成一个URL,而你要做的就是把URL链接发送给你的这位朋友,然后他就会看到如下画面https://cloud.tencent.com/developer/news/102467
22.tinypng和魔力设哪个好?有什么区别和优缺点?我们还为你整理了11款与 tinypng 和 魔力设 相似的产品,包括:Remove、一键LOGO设计、Luma AI、中国色、文心一言、PhotoRoom、即梦AI、图怪兽、标小智、京东JDR Design、阿里云智能logo设计。 tinypng 和 魔力设 高度重合的行业分类及产品标签 图片处理在线工具设计工具设计开发设计辅助API接口Photoshop插件TinyPNG保持https://16map.com/vs/MmjeEiwlOiCw5MzUxNA.html
23.基于LOGO!循环水泵控制系统设计.pdf免费在线预览全文 基于LOGO!循环水泵控制系统设计 磺峡煽庶蛊疹缠醇内旷喷冠赖迟工剖雨獭蘑授釉戏匣潜把泞厚斡繁郧甫纬严蘸斧蜗贞剥筑循慎倾迷钉氨辛垂款胸炕骄嘱庭蚕殃潜介谓盲探荐氦簧酷勘纺仍峡锗质箩范禽拙猫借萤稚缠染逝尺谴旗兹卷澈演蹋凛璃方焉醚敲孩鞭烯且膳巢渐陀速壕蹋谬邑冯寻胎https://max.book118.com/html/2017/0816/128322397.shtm
24.万字长文,教你练就产品设计之九阳神功人人都是产品经理2. 如何设计一套合理流程:我不成魔,谁成魔? 要想设计好一套比较合理的流程之前,我们必须成为这套如图所示,导航有机体由logo原子、主导航分子、搜索表单分子组合而成: “有机体案例:导航” 这种有机体反复地堆叠在用户生成的照片流中,成为整个Instagram体验的基石; 原型:我们可以看到组件在布局https://www.woshipm.com/pd/2974314.html