上周我在盐湖城为 Deseret Digital 做了一个研讨会。 就像我的 上次研讨会 一样,我们利用这段时间从头开始构建一个网站。 我认为这种现场编码风格是进行研讨会的一种不错的方式,因为它反映了真实的 Web 开发过程。 没有理论,都是实际的工作代码。 以下将是我们所涵盖内容的基本笔记以及我们构建的模板。 虽然这肯定不如亲自参加研讨会那样具有学习体验,但我认为与大家分享它仍然是一件有用的事情。
模板
我们构建了一个简单的网站。
它并不美观,但请随意使用它。 它更多的是关于涵盖许多现代 Web 设计技巧之类的东西。
笔记
徽标是 SVG。 SVG 基于矢量,因此它可以在任何尺寸下保持其质量(尤其对于像这样的简单形状)。 它在我的视网膜笔记本电脑以及我们使用的低分辨率投影仪上看起来都清晰锐利,无论我们将其缩放至任何尺寸。 更不用说 SVG 文件尺寸通常很小并且压缩效果很好。
SVG 是 Adobe Illustrator 的原生格式,因此 logo.svg
不是从主文档导出的某些文件,它就是主文档(与 png/jpg 的常规工作方式相反)。 使用 SVG 就像 <img src="file.svg">
或 background: url(file.svg);
一样简单。 与图标字体不同,单个 SVG 可以有多种颜色等等。
并非每个浏览器都支持 SVG。 我们在 Browserstack(它在浏览器中运行真实的虚拟机中的真实模拟器)中查看了 IE 8 和三星 Galaxy Tab,并发现 SVG 失败了。 因此,我们制作了一个 PNG 备用图形。 然后,我们下载了 Modernizr 的自定义版本,并在不支持 SVG 的情况下交换了图像的 src。
if (!Modernizr.svg) {
$(".logo img").attr("src", "images/logo.png");
}
我们将 box-shadow
应用于徽标图像,这会在图像框的边缘周围应用一个方形阴影。 这不是我们想要的——我们希望阴影沿着星星的边缘延伸。 我们可以通过 filter: drop-shadow();
来实现。 了解 这一重要区别。 使用 SCSS
.logo {
img { // SVG
@include filter(drop-shadow(2px 2px 2px rgba(black, 0.5)));
}
}
从一开始,我们就
- 通过 MAMP 创建了一个本地域名来使用
- 为我们自己提供了一个简单干净的目录结构来使用:index.html、/scss/、/css/、/js/、/images/
- 我们使用 CodeKit 监视该本地文件夹,以便我们可以使用 Sass 和 Compass 以及进行样式注入,这是工作流程中一个不错的部分。
导航在桌面尺寸下为 8×1,在平板电脑尺寸下为 4×2,在手机尺寸下为 2×4。 我们通过 CSS 中的媒体查询轻松实现了这一点。
为了尽可能聪明地使用媒体查询,我们基本上使用自定义用户 @mixin 如本文所述 为它们“命名”。 然后我们可以在任何地方使用它们而无需重复自身,以及将它们与其他样式块声明“嵌套”。 这使我们正在更改的属性彼此靠近,这对于我们的大脑来说有利于跟踪所有内容。
@mixin mq($mq) {
@if $mq == mama-bear {
@media (max-width: 1250px) { @content; }
}
@if $mq == baby-bear {
@media (max-width: 800px) { @content; }
}
// etc
}
因此,导航更改最终如下所示
.main-nav {
font-size: 0;
a {
display: inline-block;
font-size: 1em;
width: (100% / 8);
@include mq(mama-bear) { width: (100% / 4); }
@include mq(baby-bear) { width: (100% / 2); }
}
}
在我们的手机媒体查询(小熊)中,我们默认不显示导航(它太大且过于冗余)。 相反,我们显示一个链接来显示导航。 我们完全没有使用任何 JavaScript,而是通过在 CSS 中使用 :target
选择器并在需要时隐藏/显示内容来实现这一点。
@include mq(baby-bear) {
.main-nav {
display: none;
}
#main-nav:target .main-nav {
display: block;
}
}
我们将内容构建成网格。 我们使用了 不要过度思考网格 的原则。 该网格完全基于百分比,因此它本质上是灵活的。 我们还在小熊媒体查询中停止了列的浮动并使其成为全宽。
.grid {
padding: $pad 0 $pad $pad; // $pad is a global spacing variable
@extend .group; // clearfix w/o needing a class
background: rgba(white, 0.2); // fun little rgba/sass trick
}
.col-2-3 {
width: 66.66%;
}
.col-1-3 {
width: 33.33%;
}
.col-1-2 {
width: 50%;
}
.col-1-4 {
width: 25%;
}
.col-1-8 {
width: 12.5%;
}
.col {
float: left;
padding-right: $pad;
@include mq(baby-bear) {
width: 100%;
}
}
这是创建“响应式”设计的良好开端。
在我们的主要内容区域中,我们使用了一些媒体:Flickr 照片和 YouTube 视频。 在这两种情况下,我们都使用了这些服务提供的复制粘贴代码。 在我们的灵活设计中,图像和视频都存在问题。 在窄宽度下,它们会超出父容器。 我们使用一些简单的 CSS 修复图像
img {
max-width: 100%;
height: auto;
}
视频则没那么容易,它以 iframe 的形式出现,因此没有固有的纵横比。 我们在这里使用 FitVids.js 来帮助我们。
$("article").fitVids();
我们现在有相当多的 JavaScript 代码:jQuery、Modernizr、FitVids,以及我们编写的用于使用这些内容的自定义 JS。 那是四个 JavaScript 文件,太多了。 我们到目前为止编写的所有内容都可能是“全局的”,因为网站的任何页面都应该运行它。 因此,我们制作了一个 global.js 文件,并让 CodeKit 将我们正在使用的所有库预先添加到其中(即 // @codekit-prepend "jquery.js"
)。 现在我们每个页面只加载一个 JS 文件(global-ck.js
),这对性能很有帮助。
这类似于我们已经在 SCSS 中所做的——将文件分解成小块并将其 @import 到 global.css 中。 最终,我们的 global.scss 文件只是一堆导入和一些通用的全局代码。
@import "compass/css3";
@import "bits";
@import "normalize";
@import "toolbox";
@import "grid";
@import "module";
@import "fonts";
@import "typography";
* {
@include box-sizing(border-box);
}
// Structure and basics
在我们的侧边栏中,我们希望有一个指向我们位置的地图。 Google 地图提供代码,可以轻松地在网站上嵌入交互式地图。 它们可以在移动设备上使用,但 1)它们是 iframe,因此速度较慢,并且 2)它们的使用体验不如原生应用或 maps.google.com。
这是一个适合条件加载的候选对象。 移动设备:加载一个小图形并链接到原生应用。 桌面:加载交互式 iframe。 我们使用 Enquire.js 来帮助我们实现这一点。 Enquire.js 在我们声明的媒体查询匹配或不匹配时运行 JavaScript 函数。 因此,对于我们来说,我们可以通过 jQuery 以 Ajax 方式加载相关媒体查询的正确内容片段。
enquire
.register("(min-width: 800px)", { // mama or bigger
match: function() {
$("#map").load("parts/papa-map.html");
}
})
.register("(max-width: 799px)", { // baby
match: function() {
$("#map").load("parts/baby-map.html");
}
})
.listen();
网站的纹理来自 Subtle Patterns。 它们的下载现在附带了用于视网膜显示屏的 2x 版本。 我们利用了这一点,但仅在 视网膜媒体查询 中引用 2x 版本,以便它覆盖原始版本。 我们通过 Chrome 开发者工具的“资源”选项卡确认它只下载其中一个。
我们使用了来自 Google 字体的 Open Sans。 而不是像他们建议的那样链接另一个 CSS 文件,我们打开该 CSS 文件并提取 @font-face 规则并将它们放入我们自己的排版 CSS 文件中。
本文非常有价值,因为它一次性涉及到许多现代最佳实践。 我以为我了解了所有这些内容,但仍然发现了一个新的宝石:Enquire.js。 我现在在一个项目中需要用到它。
我对响应式混合有一些意见:在我看来,它们有点乱。 我绝对更喜欢将所有特定于“智能手机”的样式放在一个位置,而不是分散到各处。 我认为它更容易维护并导致编译后的 CSS 文件更小。 也许只是我个人偏好,我想这是一种风格的选择。
Google 网页字体会嗅探用户代理,因此您的漂亮字体不会显示在“不太现代”的浏览器中。
这让我想起了几个月前你发布的一个视频,你在其中用很多颜色制作了基本上相同的东西。
一篇很棒的非教程文章,解释了如何构建一个基本的响应式/网格/SVG/网页字体/灵活等网站。
很高兴看到您使用 SVG 作为徽标图像。 我认为 SVG 非常方便——您可以比光栅图像更容易地编辑它,它可以根据需要放大或缩小,并且占用更少的磁盘空间。
我在我的博客上写了一篇关于 SVG 入门的文章。 在这里阅读
SVG 入门
很高兴看到您将 enquire 集成到您的响应式工具集中,Chris,这让我感到像一个自豪的父亲! 我还没有使用它来切换内容的进出,就像您在这里做的那样,所以很高兴看到它按预期工作。
这里有一个小技巧:由于缺少媒体查询支持,当前地图不会显示在 IE <9 中。
register
可以接受第三个参数shouldDegrade
,它会导致回调 *始终为不支持的浏览器触发*(但仍然有条件地为支持的浏览器触发)。因此,您为目标是桌面浏览器的媒体查询传递
true
,这将允许地图传递到 IE <9 :)Chris,我是这次研讨会的参与者! 在过去的几天里,我一直在消化我的笔记,它 *真的* 改变了我的工作流程。 我成为了 Compass 的忠实粉丝,以及您分享的其他一些宝石。
再次感谢!
这太棒了,我以前不知道 Sass 中存在 @content 块。 我非常喜欢这个!
我还尝试从 Google 字体中剥离 font-face 规则,但在测试时我注意到字体根本没有在 IE8 中显示。 正如 Alexey 提到的,Google 似乎在提供 CSS 之前会嗅探浏览器,并根据 浏览器 返回不同的内容。 切换回使用标准链接使字体再次按预期工作。
这可能不是问题,具体取决于您在做什么,但需要注意这一点。
谢谢: )
关于SVG
几周前我尝试过做一个像样的SVG后备方案,部分基于你在Smashing Magazine上发布的内容,但在Firefox(移动端和桌面端)上使用SVG作为背景图片效果很糟糕,而且必须小心只加载一个资源,但在没有JS的情况下始终要有后备方案。
所以这是我的方法
https://github.com/baamenabar/svgfall
它速度很快,并且独立于库。
由于我一直在使用picturefill,所以我借用了它的语法……以及大部分代码,我相信它可以做得更好。实际代码非常短,并且易于根据您的需求进行调整。
我不想这么说,但是
font-size: 0;
会被此处的最小字体大小覆盖。菜单栏折叠了!Opera 12.10在Mac OS 10.8.2上,仅供参考。