CodePen的css技术细节MarkOtto和lanFeather分别分享了GitHub和LonelyPlanet这两个网站中如何应用CSS,我觉得我也应该参与到这个有趣的活动之中,谈谈我们在CodePen中是怎么应用CSS的。概览预处理器使用了SCSS我们使用Autoprefixer我们使用RailsAssetPipeline实际加载的那些可解释为CSS的SCSS文件其实就是一个包含各模块的目录我们有一个统一样式,主要原因是这样看起来一致性更好我们不使用任何特别的“CSS架构”,只使用类每一个网页中不超过2-3个CSS文件媒体查询我们使用可以关掉的@mixin我们鼓励注释一些统计数据在本文中“我们”这个词大多数只代表我一个未来展望和期待预处理器人们对于预处理器褒贬不一,但是我觉得如果做一个比较大的网站项目,没有预处理器是非常困难的。若你认为我这是在过度依赖工具,会让我效率变低,那么请允许我嘲笑你。我更喜欢SCSS是因为我喜欢它的社区,同时我也认为它更好。但实话说,所有这些主流的预处理器(Sass,LESS,Stylus)都基本可以满足我的需求。这里是一些我觉得有用的特性(按照实用性递减排序):@import@mixinNesting(嵌套)Variables(变量)@extendMath(数学运算)Loops(循环)长时间用它们工作,帮助我理解那些炫酷的小例子不用预处理器我无法想象要花多大的精力才能取代这些特性。在CSS属性中加与浏览器相关的前缀因为有Autoprefixer这个工具,我在工作中几乎不需要记CSS中属性或者值。我特别喜欢它对flexbox(伸缩布局盒)回退的处理方式。我以前用Compass比较多,但我发现95%的情况下都是用它处理CSS3的@mixin。我更喜欢“所见即所得”这种方式,而不是只为标前缀而到处放@include。不用Compass之后我比较怀念的一个功能是生成SVG渐变,但对于仅在IE9才需要的功能来说它也显得过于重型了,所以总体上我也没什么大损失。Rails我是RailsAssetPipeline的粉丝,它实在太好用了。举个例子:我把句话放在视图中:<%=stylesheet_link _tag”about/about”%>
1<%=stylesheet_link _tag"
about/about"%>
然后它会产生一个我需要的CSS文件:<link href=”http://assets.codepen.io/assets/about/about-a05e4bd3a5ca76c3fb17f2353fedbd99.css”
media=”screen”
rel=”stylesheet”
type=”text/css”/>1<link href=”http://assets.codepen.io/assets/about/about-a05e4bd3a5ca76c3fb17f2353fedbd99.css”
media=”screen”
rel=”stylesheet”
type=”text/css”/>我们在资源里把终止时间写得离现在远一点。我们每一次部署的时候,它都会通过重新生成随机数来重新缓存,所以这是一个非常棒的缓存机制。我们在CodePen中只是对JavaScript使用Sprockets。有了它我们可以这么干:=requirecommon/whatever.js=require_tree./../hearting/12=requirecommon/whatever.js=require_tree./../hearting/你也可以在CSS这么做,但何必自寻烦恼呢,因为:1.Sass能够实现这个功能2.如果你用Sass实现这个功能,那依赖性表现更好。像$variables和@mixin都能够在文件之间应用了。我们并不会把CSS文件上传到Git仓库中,这样对Git很好,所有的资源都在部署的时候进行解释编译。文件组织结构被加载的CSS文件会有一份对应的SCSS,这个SCSS文件中没有任何实际的CSS代码,而是用来描述CSS文件中的内容。举个例子,这是我们现在的global.scss:GeneralDependencies@import”global/colors”;
@import”global/bits”;
Base@import”global/reset”;
@import”global/layout”;
Areas@import”global/header”;
@import”global/footer”;
Patterns@import”global/typography”;
@import”global/forms”;
@import”global/toolbox”;
@import”global/buttons”;
@import”global/modals”;
@import”global/messages”;
@import”global/badges”;
第三方组件(目前没有)1234567891011121314151617181920212223GeneralDependencies@
import"
global/colors";
@
import"
global/bits";
Base@
import"
global/reset";
@
import"
global/layout";
Areas@
import"
global/header";
@
import"
global/footer";
Patterns@
import"
global/typography";
@
import"
global/forms";
@
import"
global/toolbox";
@
import"
global/buttons”;@import”
global/modals";
@
import"
global/messages";
@
import"
global/badges";
第三方组件(目前没有)我试着坚持这样做,但每当我向一个本应被全部导入的文件中添加代码时,老是会抛出一堆异常。我应该弄个通告文件然后写上:@import”shame”;
注意有点条理啊,里面这几个魂淡。1@import”shame”;
注意有点条理啊,里面这几个魂淡。代码的组织结构我写代码时一定会遵循的规范:【译者注:作者在原文中说是一种强迫症,表示这些规范是他一定会遵循的】属性和嵌套有2个空格的缩进在选择器(selectors)之后或”{“
前面加一个空格一行一个属性声明在”:”(冒号)后面加一个空格尾部的”
}”
符号另起一行,并与选择器同等缩进0作为长度的时候不加单位作为长度的时候不加单位名称中使用连字符”-”而不用下划线”_”我写代码时大多会遵循的规范:两个联系密切的类中间不加空行:.thing{}.related-thing{}
123456.thing{}.related-thing{}
有一点联系的两个类之间加一个空行:.thing{}.another-thing{}
1234567.thing{}.another-thing{}
没什么联系的内容留两空行:.thing{}.totally-different-thing{}
1234567.thing{}.totally-different-thing{}
我不太关心的规范:属性的顺序。相关的属性(如height/width)一般会放一起,但不会特别在意这个。注释方式。两种都可以用模式我写的代码几乎会给所有的元素一个类,我不知道这是不是遵循了SMACSS,OOCSS,BEM等等,不是很在意这些。这并不意味着我从不写嵌套(比如创建组合选择器),或者说我对嵌套的层数要求苛刻,只是我一般不会写太深的嵌套。我一般会这样写:.box{
h2{&:after{}
}
}
123456.box{
h2{&:after{}
}
}
但是我会想:要不要给h2一个类呢?应不应该给这种头类型创造一个可以重用的样式呢?然后我会停止这么想了,因为我意识到如果这个样式出现得足够频繁,那么我能在之后很容易更改掉,换成可重用的方式。总体的原则就是降低特异性。无论你代码重用做得多好,还是经常会有需要重写的情况,所以特异性越少,重用就会变得更容易。不仅如此,以这种方式重写,你甚至能够在不用id选择器或者!important的时候进行重写。一般来说,Rem是我选择字体大小时候的单位,px是其他元素的大小单位。请求文件我尽力在每个页面上请求2个或3个CSS文件:global.csspage.css(如果不是编辑器的页面)(如果不是编辑器的页面)section.css(如果需要)思想是尽量让请求数少一些,但是又不是极端地把所有东西塞到一个文件里。我感觉在CodePen上,有太多页面特定的样式,如果把这些都放到一个文件里,那么global.css这个文件就会变得非常大。我从来没有这么尝试过,也许有一天尝试一下也会很有趣。我会为它新建个分支叫:squiCSSh_it_real_good(高压版CSS)媒体查询(MediaQueries)我使用@mixin做媒体查询。有时我会想“这个宽度或更大”,有时会想“这个宽度或更小”(就是媒体查询的逻辑呀!)。这样写出来有点啰嗦:@mixinbreakpoint($point){
@if($MQs==true){
@if$point==baby-bear{
@media(max-width:500px){
@content;
}
}
@if$point==mama-bear{
@media(max-width:700px){
@content;
}
}
@if$point==papa-bear{
@media(max-width:800px){
@content;
}
}
@if$point==super-bear{
@media(max-width:1280px){
@content;
}
}
@if$point==reverso-baby-bear{
@media(min-width:501px){
@content;
}
}
@if$point==reverso-mama-bear{
@media(min-width:701px){
@content;
}
}
@if$point==reverso-papa-bear{
@media(min-width:801px){
@content;
}
}
@if$point==reverso-super-bear{
@media(min-width:1281px){
@content;
}
}
@if$point==exclusive-baby-bear{
@media(max-width:500px){
@content;
}
}
@if$point==exclusive-mama-bear{
@media(min-width:501px)and(max-width:800px){
@content;
}
}
@if$point==exclusive-papa-bear{
@media(min-width:801px)and(max-width:1280px){
@content;
}
}
@if$point==iOS{
@media(min-device-width:768px)and(max-device-width:1024px),(max-device-width:480px){
@content;
}
}
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445@mixinbreakpoint($point){
@
if($MQs==true){
@
if$point==baby-bear{
@media(max-width:500px){
@content;
}
}
@
if$point==mama-bear{
@media(max-width:700px){
@content;
}
}
@
if$point==papa-bear{
@media(max-width:800px){
@content;
}
}
@
if$point==super-bear{
@media(max-width:1280px){
@content;
}
}
@
if$point==reverso-baby-bear{
@media(min-width:501px){
@content;
}
}
@
if$point==reverso-mama-bear{
@media(min-width:701px){
@content;
}
}
@
if$point==reverso-papa-bear{
@media(min-width:801px){
@content;
}
}
@
if$point==reverso-super-bear{
@media(min-width:1281px){
@content;
}
}
@
if$point==exclusive-baby-bear{
@media(max-width:500px){
@content;
}
}
@
if$point==exclusive-mama-bear{
@media(min-width:501px)and(max-width:800px){
@content;
}
}
@
if$point==exclusive-papa-bear{
@media(min-width:801px)and(max-width:1280px){
@content;
}
}
@
if$point==iOS{
@media(min-device-width:768px)and(max-device-width:1024px),(max-device-width:480px){
@content;
}
}
}
}
我只是喜欢它的命名规范,平时一般都不会用上,只是想让自己在需要的的时候知道怎么做。注意在上面代码第二行处@if($MQs==true){,
我在所有包含内容列表的SCSS文件中设置了开关变量。这是因为在有的页面是自适应的,有的不是,但它们经常会用到同一个组件。如果这个页面设计初衷不是自适应的(一些只是为了在电脑桌面环境中应用的页面,比如说我们设计的一个拖放工具,还不能在触摸设备上使用),或者这个页面在移动设备使用环境下会重定向到专门的版本上。在这些页面的CSS文件中不需要含有媒体查询(MediaQueries),它们也用不上。注释我的注释风格十分自由。在大多数情况下我从来不会修改它,如果在之后我读这些注释发现我不懂它什么意思了,或者它和代码描述得驴头不对马嘴了,我就会删掉它。.drag-from-pen-grid{
padding-bottom:52px;/*addingthistomakeroomforpagination.Alittlemagic-numbery…*/
}
123.drag-from-pen-grid{
padding-bottom:52px;/*addingthistomakeroomforpagination.Alittlemagic-numbery…*/
}
统计数据CodePen一共大概有160个独立的SCSS文件,find/stylesheets!-name”*.scss”|wc-l但是从来不会出现我找不到我要找的文件这种情况。原因如下:在Sublime编辑器中寻找一个项目里的文件很容易它们有良好的组织和命名,我只需要用command–t便可以直接跳到我要找的文件SCSS文件里一共有13,345行代码。findstylesheets/-name’*.scss’|xargswc–lglobal.css大小:11.8k大小:11.8kpage.css(除了编辑器,几乎所有页面都有用到)大小:5.5k(除了编辑器,几乎所有页面都有用到)大小:5.5keditor.css大小:6.2kCSS文件并不是我们决定性能的关键因素。我们的字体大小是它的4倍,JavaScript文件大小是它的10倍。
评论前必须登录!
注册