概要:将介绍Compass如何让你从本地开发原型轻松转移到生产环境的网址或Web应用中。
本章内容:
● 生成资源URL的最佳实践
● 撰写无需Web服务器的样式表
● 在浏览器中进行设计的技巧
● 如何为产品编译并构造样式表
1. 绝对URL
1.1 生成URL资源
CSS提供了url函数用来解码URL:
background-image : url(‘/logo.png’) ;
URL标识了资源在互联网上的位置,但是当你对照自己的资源时,你常常使用相对URL,且浏览器会根据其对当前请求的了解补齐别的信息。
在CSS中,根据可省略的部分,URL可以按四种方式进行设定:
示例 |
类型 |
描述 |
url(‘http://www.example.com/logo.png’) |
绝对URL |
与请求来源无关 |
url(‘logo.png’) |
相对URL |
浏览器相对于请求的来源补齐URL,这里的来源指的是CSS样式表而不是网页。 |
url(‘/logo.png’) |
相对于根目录的URL |
浏览器相对于CSS样式表的协议和域名补齐URL |
url(‘//www.example.com/logo.png’) |
相对于协议的URL |
浏览器通过指定的域名补齐URL,但采用和CSS样式表原始请求相同的协议。 |
虽然在Sass里可以使用其中任何类型的URL,但Compass提供了三个资源辅助器,每个辅助器都需要你传入相对于资源类的目录的路径:
● image-url(‘logo.png’)——引用保存于图片根目录的logo.png文件;
● font-url(‘arial.ttf’)——引用保存于字体根目录的arial.ttf文件;
● stylesheet-url(‘randomfile.xml’)——引用保存于CSS根目录的randomfile.xml文件
1.2 避免出现死链
当你使用image-url($path)辅助器函数引用一张图片时,Compass会确认这个文件是否存在;如果不存在,则会在编译时从命令行打印出一个警告。同理,使用font-url($path)辅助器找不到字体文件时也会有警告出现。
观察下面这个找不到图片的Compass编译输出。在你的命令行里,WARNING这一行应该是红色的:
[~/Projects/my_compass_project] compass compile
directory stylesheets/
create stylesheets/ie.css
WARNING :‘missing.png’was not found (or cannot be read) in images/
create stylesheets/main.css
create stylesheets/print.css
当然,Compass实际上并不能保证你不会有损坏的链接。配置错误或编译后发生的改变还是会破坏你的站点,但是这项简单的检查已经为苦于调试开发时的常见错误的你节省了不少的时间。
1.3 通过缓存清理避免旧图片
为了重复利用,浏览器会将图片以及其他资源缓存起来。对于用户来说这很棒,它提升了浏览器的体验效果。但是对于Web开发者来说,这很痛苦。你改变了一张图片,但那些近期下载过它的用户却不会看到。为了解决这方面的问题,Compass在每个资源末端增加了修改时间,并将其作为查询参数。这样Web服务器就能够正常工作了,当查询参数改变时,图片会被浏览器重新请求。
举个例子:
#logo { background-image : image-url(‘logo.png’) ; }
会被编译为:
#logo { background-image : url(‘/images/logo.png ? 1298578273 ’) ; }
如果你觉得将时间戳作为缓存清理的参数并不是一个好方案,那么你也可以通过配置把它改成别的。举个例子,在你的Compass配置文件里写入这些内容:
# Increament the deploy_version before every
# release to force cache busting.
asset_cache_buster do |http_path , real_path | “v=1”
end
会使Compass为你的logo图片生成下面这段代码:
#logo{ background-image : url('/images/logo.png ? V=1') ; }
使用一个查询参数作为缓存清理的策略可能会干扰一些缓存资源的代理功能。如果这对你来说是一个问题,你也可以通过这一行Compass配置禁用它:
asset_cache_buster : none ;
但是,如果你想要最大可能缓存你的资源并且又可以清理,那么最好的办法就是重写资源的路径。通过一些相关的Web服务器配置,你可以生成类似这样的URL:
#logo { background-image : url('/images/logo-1307943914.png') ; }
你需要配置你的Web服务器,这样它会知道如何把时间戳路径对应到真实路径。
2. 用Sass和Compass做原型
不论你是基于一个新概念还是用一些新鲜的模型或框架开始新项目,在项目的生命周期中,Sass和Compass真正大放异彩的时间点都是项目的最开始。
2.1 简化你的开发环境
对于你的新站点或新应用来说,相对于样式表的URL是一个不错的起点。它们可以脱离Web服务器工作。这种URL也面临一个挑战:对CSS开发者来说,你的样式表变得很难分辨。但是因为Compass,你再一次被解放了,你可以通过启用相对资源来使用本地文件。为了使用相对资源,只需要在Compass配置中添加下面的代码:
relative_assets = true
当它启用时,不管使用image-url($path)、font-url($path)还是stylesheet-url($path),Compass都将生成相对路径。值得注意的是,生成的路径是相对于编译好的样式表的(而不是Sass样式表)。意思是说,如果你在多个不同的CSS文件中有共享部分,则图片引用的相对路径在所有的情形下都会准确无误。
3. 发布成产品
将CSS发布成产品实际上比发布Sass文件更容易。毕竟CSS是一个简单的文件,所以你只需要把文件复制到你的Web服务器上然后就可以收工了。
3.1 想不到吧!该挪窝了
当你建立的原计划发布在http://example.com/fancy-app/的应用现在要重命名为http://example.com/super-fancy-app/。毫不夸张地说,在你的样式表里有上百个URL。如果你得手动修改并测试所有的URL,估计至少需要一个小时的体力劳动加测试。但现在你是Compass用户了,它用到了提供的所有URL辅助器,所以你知道这只是个简单的配置改动。你只需要在配置文件里修改一行代码:
http_path = '/fancy-app'
将其修改成下面的样子,然后重新编译:
http_path = '/super-fancy-app'
3.2 为生产环境编译
在Compass中,你可以通过两种不同模式来管理自己的样式表,即开发时和服务于产品时。通常情况下,Compass使用的是development环境。如果想使用production环境,你需要像按如下方式编译你的样式表:
compass compile --force -e production
Compass默认使用产品样式表。你的输出将会被压缩,且大部分的注释会被去掉。我们也可以为当前模式设置一个特殊的配置。比如,如果你想在生产环境下以紧凑型输出,你可以在Compass配置中添加这个条件设置:
if environment == :production
output_style = :compact
end
3.3 生成相对于域名的资源
默认情况下,Compass生成相对于域名的URL以假定你在通过一台Web服务器浏览网页。现在你将要发布自己的网站了,你需要考虑一些Compass的配置设置以正确生成URL。第一个要考虑的设置是项目的http_path——这个默认值是/,但是如果你的站点承载在一个子目录中,你就需要改变这个Compass配置:
http_path = 'my-app'
如果你已经启用了相对资源,你应该禁用它们,因为你不想生成相对于CSS文件的URL,而relative_assets设置会优先:
relative_assets = false
再次编译之后,logo的URL变成了:
#logo {
background : url('/my-app/images/logo.png?1240702589') ;
}
设想一下,在部署时你的图片被复制到了一个相对于站点根目录的叫做imgs的文件夹。这种情况下,你需要为你的项目设置http_images_dir:
http_path = '/my-app'
relative_assets = false
images_dir = 'images'#locally it's the images folder
http_images_dir ='imgs' #on the webserver it's different
再次编译之后,logo的URL变成了:
#logo{
background : url('/my-app/imgs/logo.png ? 1240702589') ;
}
但如果你的网站很奇葩,它决定把它的图片放到一个完全不同于HTML的地方,那么你就要转而设置http_images_path :
htto_path = '/my-app'
relative_assets = false
images_dir ='images'
http_images_path = '/somewhere-else/imgs'
再次编译之后,logo的URL变成了:
#logo{ background:url('/somewhere-else/imgs/logo.png?1240702589') ; }
Compass有一大堆和资源相关的可能的配置选项。它们通常容易被忽略。
3.4 添加版权提示
有些站点选择为它们的样式表注明版权。如果你也要这样做,你可能会因为Sass在压缩样式表时去掉了CSS的注释而郁闷。为了解决这个问题,Sass提供了大声的注释。大声的注释以一个感叹号标记开始,紧跟在一段CSS注释的星号后面:
/*!
Copyright © 2012, Example Inc. All Rights Reserved.
*/
这里值得注意的是,大声的注释会识别Sass脚本,所以他们可以将你的版权提示设置为变量并在站点之中重用:
$copyright-year : unquote("2012") ;
$company-name : unquote("Example , Inc. ") ;
/* !
Copyright © #{$copyright-year}, #{$company-name}
All Rights Reserved.
*/
3.5 发布CSS很简单
如果你的CSS发布系统是复制样式表到你的Web服务器,那么这件事对你来说不会改变太多。当你为生产环境重新编译你的样式表之后,你还是得到了普通的原来的CSS文件。从这一点出发,你的流程和之前没有区别。关键在于你从服务于用户的地方得到了你的样式表。
3.6 跟源码控制、发布流程配合在一起
源码控制最佳实践表明非手工编辑的生成文件不应该出现在源码控制中。相反,你应该忽略生成的CSS文件,在发布时或发布之前用一个可重用的流程来准备样式表,将其作为构建工作中的一步。
但是很多网站并没有也不打算增加这样的步骤,因为它们已经有Sass了。在这些情况下,许多用户把它们编译的CSS嵌入源码控制系统。如果你这样做了,那么合并冲突时有发生。这时最好的建议就是删掉你生成的样式表,在源码控制系统里面解决合并冲突,重新比编译。
如果你应用了这个构建步骤,它可能足以靠一条命令编译整个项目,但是有些构建系统可能希望通过make这样的工具一次只编译一个文件。在这种情况下,你可以传递单个文件给Compass编译器或Sass命令行编译器,它们都有此工具的传统界面:
这句命令编译了一个单独的文件:
compass compile my_sass_dir/application.scss
要用Sass命令行编译一个单独的文件,你需要传递--compss参数:
sass --compass my_sass_dir/application.sass my_css_dir/application.css
3.7 和预发服务器一起工作
有些站点有一个预发环境,那里的代码都需要进行最终测试并将要发布上线。有些网站甚至有三层预发环境(边缘、集成、预发),用来测试并集成不同成熟度的功能。
其实有的时候把生产环境的样式表提前放入预发环境就已经足够了。但是预发环境可能会稍有不同——通常是主机名不一样,或者你可能没有使用产生环境的CDN。在这些情况下,你需要调整相应的配置。针对这种情形,我们有两个建议。一是在编译时设置环境变量:
STAGING = true compass compile --force -e production
然后在配置文件里,你可以使用Ruby检测这个环境变量并改变相应的设置:
if ENV[‘STAGING’] relative_urls = true output_style = :compact elsif environment == :production relative_urls = false output_style = :expanded end
如果你针对每个环境的配置是明显不同的,那么你也可以创建不同的配置文件:
compass compile --force -c staging_config.rb -e production
为了保持一致性并避免重复代码,staging_config.rb文件应该包含一般环境的配置文件,然后在这个基础上进行改动:
eval(File.read(“#{File.dirname(_FILE_)}/config.rb”) ) relative_urls = true output_style = :compact
发布到预发服务器对复杂站点来说是一个很棒的实践,虽然没有原生支持,你还是可以看到作者选择一个Ruby文件进行配置的原因:它允许小概率的特殊情况也能被轻松支持。