阅读更多

背景

Meta CSS是一个很简单的CSS框架。可以点这里(下载)先一睹为快。

 

在深入介绍之前,我们来考虑几个web开发者非常容易遇到的问题:

 

  • 同样的一个款式的按钮,有些页面它要在左边,但是有些页面要在右边
  • 同样作用的一段提示文字,有些地方字体要大号,有些却要小号
  • 同样风格的一段文字,有些要红色,有些却要绿色

这样的状况是相当频繁的。对此,通常有4种解决方法:

 

  1. 每种不同款式,定义一个css。按钮A一个css,按钮B虽然长得跟A一样,但是在右边,那就copy下A的css代码,然后改成在右边。
    .a{/* 很多样式定义 */}
    .b{/* 很多样式定义 */ text-align:center;}
    .c{/* 很多样式定义 */ text-align:right;}
    <div class="a">按钮A</div>
    <div class="b">按钮B</div>
    <div class="c">按钮C</div>
  2. 针对不同地方,利用css层级覆盖来实现。比如按钮A设定css,然后对于特别的页面,设定特别的css来覆盖
  3. .a{/* 很多样式定义 */}
    #s1 .a{text-align:center;}
    #s2 .a{text-align:right;}
    <div class="a">按钮A</div>
    <div id="s1"><div class="a">按钮B</div></div>
    <div id="s2"><div class="a">按钮C</div></div>
  4. 利用css组合来实现。如上面的代码片段,设定css基础类,然后进行组合。对于按钮A,它的class为x,在右边的按钮B,它的class为x tar,对于B来说,它的样式就是x与tar组合起来的。
    .a{/* 很多样式定义 */}
    .tac{text-align:center;}
    .tar{text-align:right;}
    <div class="a">按钮A</div>
    <div class="a tac">按钮B</div>
    <div class="a tar">按钮C</div>
  5. 直接内嵌style来解决。
    .a{/* 很多样式定义 */}
    <div class="a">按钮A</div>
    <div class="a" style="text-align:center">按钮B</div>
    <div class="a" style="text-align:right">按钮C</div>

再来分析下4种方式各自的优缺点:

  1. 每种不同款式,定义一个css。随着代码量变大,css将会变得越来越难维护。当你需要修改一个按钮风格的时候,所有同样风格的按钮都要改过。你copy到那里,哪里就得改,很容易遗漏。并且代码量也会相对更大,很多可重复利用的资源没有利用起来。
  2. 利用css层级覆盖来实现。利用css选择符的优先级来覆盖是很好的做法,也是很常用的做法。不过在很多情况下,例如大量的动态页面,我们没有办法完全预知定义的css的id或者类名,而无法定义特别样式。在一些可以控制的情况下,定义太多特殊类名用来区分,又会造成大量后期维护的困难。
  3. 良好的运用css组合方式,可以比较妥善的解决上面的2个问题。首先,公用样式都被提取了,你修改一个按钮,只需要改公共的部分。其次,不需要绞 尽脑汁去想一个不会冲突的css类名,遵循组合的规则就可以了。当然,这种方法也有缺点,较为复杂的组合需要代码作者自己熟悉覆盖的规则,在css代码里 面并不知道html页面拿哪一些规则拿来进行组合,修改一个规则可能导致调用css的地方出问题。
  4. 内嵌style优点就是简单快速。缺点也很明显,不仅写起来有点麻烦,代码也难看,维护性也不好。很重要的一点,到处都是style会让人BS的,觉得你这前端div+css用得也忒不好了。所以代码洁癖的人往往宁可定义一个新样式,也不愿意页面有一个style。

我们来看看一些大型站点是如何来解决这个问题的:

 

/* 一段摘抄自开心网kaixin001.com的css代码 */
.l{float:left;}.r{float:right; clear:right;}.c{clear:both;}
.tal{text-align:left;}.tar{text-align:right;}.tac{text-align:center;}
.c0,a.c0{color: #000; font-family:Arial;}
.c6,a.c6{color:#666; font-family:Arial;
/* 一段摘抄自163.com的css代码 */
/* Font  */
.fB {font-weight: bold;}
.f12px{ font-size:12px;}
/* Other */
.left{ float: left;}
.right{ float: right;}
.clear{ clear: both; font-size:1px; width:1px; height:0; visibility: hidden; }
.clearfix:after{content:"."; display:block; height: 0; clear: both; visibility: hidden;} /* only FF */
.hidden {display: none;}
.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

经常做前端开发的童鞋自己的开发也经常有这样的做法,但是也许并没有总结跟提取。不了解前端开发的人可能就比较纳闷,就这样一大堆属性的css定义,有什么用啊?跟用style有什么区别吗?

 

从上面2份css代码中,我们可以看到前端设计师经常会提取一些只有一个属性的css类,用来做组合。以163的为例,它有一个left的类,是左 浮动,开心网更简单,是l。如果一个按钮正常情况下是不浮动的,但是有些地方它要左浮动,就只要在元素的class上面加一个left或者l,通过这样的 组合来达到目的。

 

Meta CSS框架,就是为了满足这样的一个需求而设计的一个框架。

 

Meta CSS框架的实现参考了不少大型站点的css代码,分析代码里的共性而总结出来的,该框架可以整合yui css框架或者blueprints框架来使用。它的作用在于以一个明确的命名规则,提供一个通用的css类集。正如这个框架的名字Meta,它规划出最小的最通用的"元定义"。可以与目前了解的各类css框架共存。

 

框架的意义,其实就是提供一个良好的可遵循的规范以及底层功能,规范代码的开发,提高开发的效率。Meta CSS也是遵循这样的一个理念,查看完整版本,先来看一个Meta CSS框架的代码片段:

 

/* Font  */
.fwb {
 font-weight: bold;
}
.fwn{
 font-weight: normal;
}
.tdn{
 text-decoration: none;
}
.tdu{
 text-decoration: underline;
}
.tdl{
 text-decoration: line-through;
}
.fs10p{
 font-size: 10px;
}
.fs11p{
 font-size: 11px;
}

Meta CSS框架的命名规则

Meta CSS框架提供了一个简单而有规律的命名。

 

规则1:定义尺寸的css定义,以css属性名的首字母+属性值的首字母组合而成。例如font-weight:bold,css类名就是fwb。text-align:center,css类名就是tac。float:left,css类名就是fl。

 

规则2:定义尺寸的css,以css属性名的首字母+属性值+属性值单位的首字母。例如font-size:10px,css类名就是fs10p。border:1px solid #cccccc; css类名为b1sc。特别的,%的数值,采用percent的首2个字母pe。

 

规则3:多个属性的定义,命名参考规则1与规则2,中间用-连接。例如font-size:10px,font-weight:bold。css类名就是fs10p-fwb。

 

为什么要这样定义呢?有些人可能比较偏好开心网的,极致简单的,float:left,css类名是l,float:right,css类名就是 r,非常简单。简单是非常简单,但是问题在于这样的定义显得很随意,没有规则。假设它定义的font-weight:bold的css类名是fb,那么新 的开发者一定要去看代码才知道定义的名称叫fb,它没办法通过一个明确的规则来知道想要的属性是什么名称,有时候他还会很干脆的另外定义一个。

 

而我们规定的这个命名规则,如果想要左浮动,就可以马上得知是:fl。font-weight:bold,可以马上知道是fwb,毫无疑惑。敏捷开发的一个很重要的思想,就是约定胜于配置,meta css框架中很多css类名看起来很不优雅,甚至显得怪异,但是只要所有协同开发者了解这个约定,就可以大大减少记忆的工作量,所有的开发者都可以轻松的记住它。

Meta CSS框架的组成

对照w3c的手册,Meta CSS将css定义分成了几个部分,分别是:font字体,text文本,background背景,position位置,dimension元素尺 寸,layout布局,margin外边距,border边框,padding内边距,other其他以及combine联合定义。

 

具体的内容可以查看:metacss.css,这里概况下各个部分的定义:

  • font字体:定义了font-weight,text-decoration,font-size,color。
  • text文本:定义了text-align,text-indent
  • background背景:定义了background-color
  • position位置:定义了z-index
  • dimension元素尺寸:定义了width,height
  • layout布局:定义了float,overflow,display。特别的,有一个额外定义的css类c,可以在多浏览器环境下实现清除浮动。常常可以在一些css代码中见到,常常也命名为clearfix。
  • margin外边距:定义margin
  • border边框:定义了border
  • padding内边距:定义了padding
  • other其他:定义了cursor
  • combine联合定义:用户自行扩展定义。联合定义规定了多个属性的定义方法,比如font-weight加上font-size,定义的css类名为fs10p-fwb。

Meta CSS框架扩展与裁减

Meta CSS说白了本质上就是一个css文件而已,要进行改动是一件很容易的事情,任何开发者都可以随意的往这个css文件里面添加或者删除任意属性与定义。随意的添加或删除当然不是我们希望看到的结果,遵循框架的约定进行增删改,才是真正意义上的扩展与裁减。

 

注意:根据你自己的项目,对Meta CSS进行扩展与裁减是非常正常的也是很有必要的。

 

扩展Meta CSS的方式很简单,就是遵循命名规则,添加新的css类定义。假设你要增加一个margin是20px的定义,默认框架中是margin:10px,你就可以添加一个m20p的css类就可以了。具体可以查看Meta CSS文件中的注释。

 

裁减Meta CSS同样简单,删除文件中你确实不需要用到的属性就可以了。大部分时候,默认的一些字体,内外边距之类的定义往往不一定符合你的需求。

Meta CSS 使用方法

从语法上,你当然可以通过class="fwb tar mr10p pt20p"来创建一个加粗的,右对齐的,右内边距10px,上外边距20px的元素,但是从框架本身的意义来说,这不是最佳的适用环境。Meta CSS框架适用的环境是:

  1. 的确是单一属性的定义。例如只是 class="fwb",加粗一个元素。
  2. 对某一个css定义给出特殊情况的补充。参考开头部分提到的例子3

代码中使用的范例:

<style type="text/css">
	.fwb{
		font-weight:bold;
	}
	.tar{
		text-align:right;
	}
	.div1{
		border:1px solid #ccc;
		padding:15px;
		color:green;
		width:200px;
		margin-bottom:20px;
	}
</style>
<div id="d1" class="div1">
	第一个div
</div>
<div id="d2" class="div1 fwb">
	第二个div,字体加粗
</div>
<div id="d3" class="div1 tar">
	第三个div,右对齐
</div>

基本使用方法:下载metacss文件,放到你的css文件夹中,可以采用形如

 

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

这样的css引用语句。你可以将metacss中所有的css定义copy到你的css文件中合并到一起,所有的css文件可以怎么做,你都可以怎么做。

Meta CSS框架的局限性

css优先级的影响,你不能保证定义总会生效,如果之前的css类已经包含某些要覆盖的定义,则有可能因为优先级的关系,不能生效。我们稍微修改下上面的例子:

<style type="text/css">
	.fwb{
		font-weight:bold;
	}
	.tar{
		text-align:right;
	}
	.div1{
		border:1px solid #ccc;
		padding:15px;
		color:green;
		width:200px;
		margin-bottom:20px;
		text-align:left; /* 更高优先级,无法被tar覆盖 */
}
</style>
<div id="d1" class="div1">
	第一个div
</div>
<div id="d2" class="div1 fwb">
	第二个div,字体加粗
</div>
<div id="d3" class="div1 tar">
	第三个div,预期右对齐,但是事实上不会生效。
</div>

 

像这个例子里,.div1的text-align有比tar更高的优先级,所以用css组合这种方式就会不起作用。所以在应用框架的时候需要注意这一点。关于css优先级的讨论超出本文的范围,可以自己google一番。

34
9
评论 共 33 条 请登录后发表评论
33 楼 shawnfree 2010-10-28 14:04
如何解决跨浏览器啊。
32 楼 test01test01 2009-10-21 17:16
明显是给外行看的
31 楼 carffuca 2009-10-21 15:18
实在是没有太多意义的框架
html class的语义全无
没有带来什么好处,只增加了记忆负担
30 楼 playfish 2009-10-21 14:22
hite 写道
hite 写道
.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

这个是我见过最挫的命名。。。

那我要这个class高设为3咋整,是换classname还是改height???
命名方面还不如我呢


太鸡东了——

应该是“.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

这个是我见过最挫的命名。。。

那我要这个class高设为4[color=red][/color]咋整,是换classname还是改height???
命名方面还不如我呢”



呵呵,我这里引用的163的css文件比较短,它还有blank6,blank9等一系列的命名,适用于它自己需要空白区域的场合。
29 楼 hite 2009-10-21 13:47
hite 写道
.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

这个是我见过最挫的命名。。。

那我要这个class高设为3咋整,是换classname还是改height???
命名方面还不如我呢


太鸡东了——

应该是“.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

这个是我见过最挫的命名。。。

那我要这个class高设为4[color=red][/color]咋整,是换classname还是改height???
命名方面还不如我呢”

28 楼 hite 2009-10-21 13:46
.blank3{ height:3px; clear:both;display:block; font-size:1px;overflow:hidden;}

这个是我见过最挫的命名。。。

那我要这个class高设为3咋整,是换classname还是改height???
命名方面还不如我呢
27 楼 playfish 2009-10-21 11:09
black.angel 写道
CSS 应该是为 HTML 服务的吧?怎么现在为了一个 CSS 框架要反复频繁的修改 HTML 了?是不是搞反了?


汗。。文档什么地方让你理解为反复频繁的修改html。。? css还是css,本质还是一样没变化,只是提供了一些实用的类而已。
26 楼 black.angel 2009-10-21 08:46
CSS 应该是为 HTML 服务的吧?怎么现在为了一个 CSS 框架要反复频繁的修改 HTML 了?是不是搞反了?
25 楼 playfish 2009-10-20 23:43
fins 写道

hax 写道
我很遗憾,因为这个meta css只是集合了那些网站对css的错误使用。也就是他不是集best practice之大成,而是集反面案例于一身。


+1


呵呵,能博得2位的一句中肯的评价可以受益不少。的确,这是一个很容易意识到的问题,这样的css定义,不语义化,css不应该是这样用的。并且,这并不能提高可维护性

但是我们也可以来考虑下,既然不是best practice,为什么会有这么多站点采用这种模式呢?

除了开心网跟163,腾讯,淘宝,新浪,几乎我们所熟知的大部分大型站点,都会有一部分这样的css代码。这么多的前端开发人员采用这种方式为啥?我觉得本质的原因在于它可以提高开发效率,我之前另外的一篇帖子http://www.javaeye.com/topic/467394也提到了自己做开发的一个观点:所谓的技术与标准,都是为现实需求服务的,只要能实现需求,综合考虑时间效率与成本,都是可以拿来用的。

在面对一个页面庞大而复杂的情况,而上面又催着你赶快完成的时候,什么东西可以最有效率的实现需求,才是开发者最关心的事情。

整理这个css框架的目的就是在此。希望hax与fins二位愿意再细看下这篇完整的介绍,提出更多的意见。
24 楼 fins 2009-10-20 22:02

hax 写道
我很遗憾,因为这个meta css只是集合了那些网站对css的错误使用。也就是他不是集best practice之大成,而是集反面案例于一身。


+1
23 楼 whaosoft 2009-10-20 20:34
就是封装了一下
22 楼 hax 2009-10-20 19:40
我很遗憾,因为这个meta css只是集合了那些网站对css的错误使用。也就是他不是集best practice之大成,而是集反面案例于一身。
21 楼 hax 2009-10-20 19:36
It's totally a bad idea!!!
20 楼 playfish 2009-10-20 15:35
raiha 写道
就是把style="xx xx xx" 换成class="xx xx xx"
真正修改样式时,还要挨个标签修改,怎么就提高维护性了?

开心跟163那样定义css的道理也没有说清楚


跟style相比,确实没提高维护性。只是比style更方便而已。
但是4种css应用的方式的比较,请仔细参考在开头提出的应用场合,以及优缺点比较。

开心网跟163定义这样的css的道理,就是如开头提到的解决几个场景的问题:

    * 同样的一个款式的按钮,有些页面它要在左边,但是有些页面要在右边
    * 同样作用的一段提示文字,有些地方字体要大号,有些却要小号
    * 同样风格的一段文字,有些要红色,有些却要绿色

这些状况,只要经常接触div+css设计的人肯定是会经常碰到的。这样的css定义就是一种解决方案。
19 楼 holyzfy 2009-10-20 15:18
简单看了下metacss.css
字号竟然有.fs10p,.fs11p,.fs13p...这些能用来显示中文字体么?
18 楼 raiha 2009-10-20 14:55
就是把style="xx xx xx" 换成class="xx xx xx"
真正修改样式时,还要挨个标签修改,怎么就提高维护性了?

开心跟163那样定义css的道理也没有说清楚
17 楼 caiceclb 2009-10-20 12:47
没用,增加记忆负担及使用难度,出了问题还瞎难调整
16 楼 boobmoom 2009-10-20 12:34
skyblue1984 写道
不知道说是倒退还是回归好..
最早接触div css布局的时候,
大肆宣扬的是完全的样式分离,可以在不改动html的情况下给网站改头换面.
然后现在反过来,是在不改动css的情况下,改动html还更换样式...........
无解...............

最初的想法是好的
但后来又遇到了具体问题
所以需要解决这个问题
具体在这里讨论的话
我觉得应该是
如何解决遇到的问题
此方法优缺点、适用场景
有没有更好的解决方法
15 楼 dogstar 2009-10-20 12:29
skyblue1984 写道
不知道说是倒退还是回归好..
最早接触div css布局的时候,
大肆宣扬的是完全的样式分离,可以在不改动html的情况下给网站改头换面.
然后现在反过来,是在不改动css的情况下,改动html还更换样式...........
无解...............

话是不错,但是绝大多数的情况是,页面但凡有布局风格的改变,必然有html结构的变动,不能单纯的靠css控制html达到效果.为了更快的,流水线式的前端开发,采用css框架还是很必须的.
14 楼 boobmoom 2009-10-20 12:28
多谢作者提醒

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 捡金豆

    捡金豆 (Bantuni) TG    捡金豆是我编的第一个游戏。   本游戏是Nokia 3310中的捡金豆的PC版, 以前我总是看不懂此游戏规则。这还是我五 一回家时看哥哥玩才知道的 :把小碗中的 豆子放入后面的碗中,如果最后的豆子落入 你的大碗。你将得到一次新的机会。如果最 后的豆子落入你的空碗,你将从对手对立的 小碗中得到豆子。豆子多者胜。   后来玩玩,觉得此游戏挺不错的。我就 没日没夜地玩,玩得手机没电了,边充电边 玩!眼睛痛得睁也睁不开--嗚,好可怜 哦!在此游戏中你必须考虑到后面好几歩, 要不一失足成千古恨,这儿可没有反悔功能 的呀!它的动画显示功能,刚开始时觉得 挺不错的,但久了就觉得速度实在是太慢 了!要等上老半天。第五级别(最高级别)与 第一级别的步法似乎没什么区别,但速度实 在是慢得让人无法忍受!有时明明可以得分 的,它偏偏不走。还有,在第一级别时好像 有一BUG ,你可以在十步之内取胜,而且得 分很高。(41:7这几乎是最高分了)。   所以我就想把它改成PC版(我是不是不 知天高地厚呀!而我又没有类似的源码!!) 我本写了个C语言版,现在刚好在学Delphi, 那就干脆改成Delphi版吧!反正C语言版也没 有调试完毕!(11:59 2001-6-13)    最佳运行环境:windows me 1152*840P 新增功能:右鍵菜单,单人游戏,(现在只有三个级别)  和手机的相比:这儿速度快,增加的反悔功能只 有在双人游戏中有效。没有动画显示功能。我还是没能修正 那BUG。结束时的奖励太少了。   历史:2001/7/4 :捡金豆(V1.1)完成;      2001/6/13:捡金豆(V1.0)完成。 (new 12:00 2001-7-4)   快要考试了,我再也没有时间做游戏了。考完了, 我会完善本游戏的功能的。走走停停,我很迷惑。 本想等考试这后再编的。但总是没法静心读书。那干脆 先编完再说吧!现在总算完成了。(12:07 2001-7-4) 我今天突然发现我忘了一个功能:在你选择了新的级别 后不会自动开始新游戏。本来是有这功能的,不知在什 么时候修改时被我去掉了。那只能由你自己选择是否重 新开始了。(10:15 01-07-11)           使用说明: 1.NEW:开始新游戏;;;; 2.HELP:显示本文件;;;; 3.你只需用鼠标点击你要走的网格;;;; 3.主界面是下面的那网格。第一行表示对方的小碗。 第二行第一个是对方的大碗。最后一个是你的大碗。 第三行是你的小碗。目的就是把豆子捡入你的大碗。 不好意思,大碗和小碗一样大! 4.右键功能。 游戏规则: 把小碗中的豆子放入后面的碗中,如果最后的豆子落入你的大碗。 你将得到一次新的机会。如果最后的豆子落入你的空碗,你将从对 手对立的小碗中得到豆子。豆子多者胜。 (To drop beans into next pots,Finish in your big pots and get a new go . Finish in your empty pot and get beans from opponents pot . most beans win.) 若需源代码,E-Mail to :atowngirl@sina.com

  • 捡金豆游戏源代码

    捡金豆游戏  Nokia 手机中游戏的PC版。 http://www.csdn.net/cnshare/soft/12/12098.shtm 我是用Delphi编的。 需源代码E-Mail to : cxz0231@sina.com 我希望有誰能把它改成一控件。 我只写了三个级别的。 有誰可以多写几个级别的?

  • C语言:捡金豆

    题目:捡金豆游戏,第一关有两个出口编号为1,2。从门1出去会进入第二关的场景一,该场景有出口3,4,从门2出去会进入第二关的场景二,该场景有出口5,6。每一门的门口都放有若干个金豆,从该门出去就会获得这些金豆。在二选一的情况下每次都会从金豆数多的门走(保证两个门口金豆数不同),进入下一关,请问闯关后捡到多少金豆? #include &amp;lt;stdio.h&amp;gt; int main() { ...

  • 吃金豆游戏的源代码

    想要一个用C#编写的简单的吃金豆游戏,实在是不会做,望有人给予帮助,把详细的源代码发到我邮箱,不胜感激!1534062534@qq.com我的邮箱,谢谢!

  • CSUST 1526 拣金豆

    1526: 拣金豆 Time Limit: 1 Sec  Memory Limit: 256 MB Submit: 20  Solved: 5 Submit Status Web Board Description 最近小明非常喜欢玩捡金豆游戏。有一个n*m的方格棋盘,每一个格子中有一个金豆或者没有。如果两个相邻的格子都有一个金豆,则可以捡起金豆,

  • 吃金豆游戏

    PACMAN.C代码 是一个可以吃金豆的游戏,可以让用户娱乐一下。

  • 接金币游戏源代码

    Flash小游戏接金币源代码,详细明function Game():void { txtScore.text=score.toString (); stage.addEventListener(Event.ENTER_FRAME ,onFrameHandler); stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDownHandler); myTimer.addEventListener(TimerEvent.TIMER ,onTimerHandler); myTimer.start(); gameTimer.addEventListener(TimerEvent.TIMER ,onGameTimerHandler);了,

  • java吃金豆游戏源代码

    源代码,java实现,里面包括图片资源,还有可执行程序

  • UNITY3D 2D游戏关卡拾取之金币动画创建调用销毁

    废话不说直接开始 1)创建金币的动画 然后将这个图片拖拽到这里 windows-Animation-animation,打开动画编辑器将这些处理好的精灵图片拖进去,采样率设置(Samples)设置12帧 (2)创建拾取后的动画,步骤和上面的一样的,我就不重复了 (3)打开状态机 windows-Animation-animator。设置参数Trigger类型 (4)为coin添加...

  • java毕设项目之ssm基于SSM的高校共享单车管理系统的设计与实现+vue(完整前后端+说明文档+mysql+lw).zip

    项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7

Global site tag (gtag.js) - Google Analytics