面向对象的CSS--OOCSS

 

      新版 OOCSS 请关注 http://www.oocss.cc/


      时下流行面向对象,那么有没有可能把样式表也面向对象一下呢,将现在的CSS(Cascading Style Sheets层叠样式表)进

化一下,演变成面向对象的样式表给套了个概念上去,以下叫“OOCSS”,即 Object Oriented Cascading Style Sheets。

 

 ◆ 为什么会这样想?

      没办法,被逼的, 俺们公司的美工只做图片,其它的是啥都不管,近来弄个WEB项目,都做差不多了,老总说要能换肤。呵呵

还好之前有所考虑,三两天就搞定了。

      我的方法是,页面全部用CSS控制,主要有 common.css、list.css、addedit.css等10来个css文件和图片,全部放一个叫

Common/Skins的目录下 ,Common/Skins下每套皮肤一个文件夹,最终目录结构大致如下。

Code

 

      共定义有5、6套皮肤,CSS和图片文件急剧上涨,由原来的10来个一下子上升到了7,8十个,虽然数量是有点吓人,不过每套

皮肤,CSS和图片都大部分差不多,也没花多少功夫就搞定了,不管了,甩一边。

      几天后的某一天早晨,好大的台风,呼呼的,雨也不小,让人觉得很不爽,就像出事前的预兆 !

      果然,没坐下多久,老总过来说“和美工讨论了下,有几个地方,布局要变下......”。

      一阵的嘻哩哗啦之后,我心里除了佩服老总口才不错之外,觉得自己命好苦呀!

      那么多CSS,得改多久呀,以后要再变的话不还得改吗!

      仔细分析下CSS,其实每套皮肤都大体差不多,不同的地方一般都是边框、文字的颜色和背景色,还有图片、字号,于是我决定

所有的皮肤都用同一套公共的CSS文件,另外,每套皮肤再加一个独立CSS文件(Settings.css),而该CSS中只定义基本的样式,

相当于配置文件一样的,然后作用于其余几个公共的CSS文件。

      我坚信这样的思路是对的,可是怎么实现呢?

      首先想到的,当然是用CSS的组合,将之前部分CSS规则分离,公共部分提取出来放在 Settings.css中定义,如:

      将List.css中规则 
               .ToolBar{color:#f0e000;border:1px solid gray;} 
          分离为
               .DefaultColor{color:#f0e000;}定义在Settings.css中
               .ToolBar{border:1px solid gray;}仍然保留在List.css中

          然后将HTML中对 .ToolBar 的引用“class='ToolBar'”改为“class='DefaultColor ToolBar '”

      再将其它color属性相同的CSS规则进行同样的分离。这样每套皮肤不同的地方就只是 settings.css文件里.DefaultColor类型

的规则。

      而这样做又引发的新的问题,必须得每个页面改HTML中的class属性,而背景图片只能依靠 expression 来解决,expression

又常常造成页面的死锁,无奈之下只有另谋出路。

      

 ◆ 面向对象的CSS: OOCSS 基本构思

      继承:

            OOCSS中,类(样式规则)可以继承自另一类,如

例一

            .Base{font-size:20pt;}
            .Sun{color:red;}

            假如用如下语法可以实现继承

            .Base{font-size:20pt;}
            .Sun (inherit .Base)
            {
                    color:red;
            }

 

            而现在类 .Sun 则不单单拥有 “color:red;”属性,应该拥有从基类 .Base 中继承的 “font-size:20pt”属性 ,

     cssText应该是 “font-size:20pt;color:red”。

      覆盖:

           将上例中的 .Sun 更改如下:

            .Base{font-size:20pt;}
            .Sun (inherit .Base)
            {
                    font-size:10pt;
                    color:red;
            }

            则实现了对基类“font-size:20pt”的覆盖,.Sun中的font-size则为10pt。

 

     子类访问基类

例二

            .Base
            {
                    v:20;
                    font-size:20pt;
            }


            .Sun (inherit .Base)
            {
                    padding : (base.v+10)px;
                    font-size:(base.fontSize/2)pt;
                    color:red;
            }

            .Sun2 (inherit .Base)
            {
                    padding : (base.v+20)px;

            }

 

           在基类 .Base 中定义了变量 “v:20”和style属性“font-size:20pt”,子类 .Sun和.Sun2中style属性padding和

     font-size通过访问基类变量和属性计算而来,而最终 .Sun 中 padding等于30px,.Sun2中padding等于40px;.Sun中

     fong-size等于10pt,.Sun2没有覆盖基类中的font-size,所以font-size继承基类,值仍为20pt。

 

     多继承

例三

            .Base{font-size:20pt;}

            .Base2{color:red;}

            .Sun (inherit .Base,.Base2)
            {
                    padding:20px;
            }

            .Grandson (inherit .Base)
            {

            }

 


          类.Sun继承自两个基类.Base和.Base2,所以.Sun的cssText为“font-size:20pt;color:red;padding:20px;”,而

     .Grandson继承自.Sun,本身没有任何自定义属性,因此cssText和.Sun一样,仍为“font-size:20pt;color:red;

     padding:20px;”。

      

     私有(假如用private作为关键字)

例四
            .Base
             {
                    font-size:20pt;
                    private color:red;
             }

            .Sun (inherit .Base)
            {
                    padding:10px;
            }

 

          子类 .Sun 继承基类 .Base 中的fontSize属性,因为 .Base中color属性受private(私有)限制,不能被.Sun继承,最终

     .Sun的cssText是“font-size:20pt;padding:10px”。

 

     更多特性待琢磨......

 

 

  ◆ 这样做有意义吗?

       我的回答是“有”     !

       1.  CSS的优点之一“一处定义,多处使用”

               目前的CSS多处使用指的是,一个CSS规则可以由多个HTML元素引用。可CSS规则间不能互操作。

       2.  CSS的继承

               CSS的继承不是真正意义上的继承,而是HTML元素对外层元素Style属性的继承,且部分Style属性、HTML元素是不能

          继承的,如backgroundColor属性、border属性、padding属性、table元素等等(当然,部分不支持继承也是合理的)。

      3.  CSS优先级

               当多个CSS规则作用于同一个HTML元素时,CSS将根据CSS规则权重 、规则定义的先后配合HTML元素的层次关系决

          定最终的有效值,这样的解决方案有时很巧妙,可当HTML层次结构过深、而作用于同一个HTML元素的CSS规则过多时,

          CSS规则的优先级控制是相当的不容易,有时候不得不用蹩脚的“! important”来解决问题,可“! important”不符合标

          准,支持的浏览器很少。

      OOCSS在保留CSS特性(或者说是优点)的前提下,将从某种程度上解决以上问题

     1.  OOCSS中,类可以访问基类甚至没有依赖关系的其他类,应用灵活......。

     2.  OOCSS中,继承是类对基类属性的继承,不同于CSS中的继承(HTML元素对上层元素Style属性的继承),子类直接继承

          基类不受private(私有)关键字修饰的属性。

     3.  OOCSS实现继承后,就会在一定程度上避免CSS组合的应用,便会减少意外的HTML元素匹配,同时HTML元素在class属

          性中应用子类时,权重跟基类无关,和子类一致,如例三中,子类 .Sun 的权重跟基类 .Base1、.Base2无关 。

 

 

 ◆ 我认为OOCSS很有趣,也有用,想了解一下!

           上面的想法都是建立在假如的基础上的,都只是我一种猜想而已

            .Base
             {
                    font-size:20pt;
                    private color:red;
             }

            .Sun (inherit .Base)
            {
                    padding:10px;
            }

            这样的代码各位都不认识,浏览器又怎么会认识呢,那么是不是就不能实现呢?不是的,我们可以通过一些其他方法模拟,

       虽然有些尴尬!

            我的做法是,写个JS解析,基本实现以上想法,代码太多,不方便贴出来,供下截

                 下载:http://oocss.66s.net.cn:81/oocss/OOCSSDemo.rar
                         http://files.cnblogs.com/kuiyouli/OOCSSDemo.rar

                 演示:http://oocss.66s.net.cn:81/oocss/?Skin=1

                 有兴趣的朋友可进入QQ群:15774494

                 注:仅作为一种新方法的尝试,目前只支持IE浏览器

       实现功能如下:

       1.  继承 

                因为浏览器不支持 .Sun (inherit .Base) 这样的语法,所以改为如下形式:

                    .DefaultColor{color:red;}
                    .Sun
                    {
                         base: .DefaultColor;
                         font-size:9pt;
                    }
                用 “base”关键字指定基类,注意是“.DefaultColor”,而不是“DefaultColor”,基类必须是类全称,可以指定多个基

          类,如:

                    .BaseHeight{height:30px;}
                    .DefaultColor{color:red;}
                    .Sun
                    {
                         base: .DefaultColor,.BaseHeight;
                         font-size:9pt;
                    }          

 

       2.  附加

                跟继承类似,实现的却是CSS的组合功能。

                    .BaseHeight{height:30px;}
                    .DefaultColor{color:red;}
                    .Sun
                    {
                         append: .DefaultColor,.BaseHeight;
                         font-size:9pt;
                    } 

               当HTML元素引用类 .Sun 时,OOCSS会自动将 .DefaultColor、.BaseHeight附加到HTML元素的class属性,如:

                    <div class=".Sun"></div>

               则该div最后的class属性值为“.Sun .DefaultColor .BaseHeight”。因此,.DefaultColor、.BaseHeight中的属性受

          其优先级的影响,跟.Sun的优先级无关。

      3.   eval表达式

               eval表达式类似expression表达式,不同之处在于,eval只在初始化时执行一次。

                     .TestEval
                    {
                         E-height: eval(20+30);
                    }

               相当于:

                     .TestEval
                    {
                         height: 50px;
                    }

 

               可以在eval中访问脚本变量,如:

                    <script>
                         var skin={color:'red', defaultSize:'9pt'}
                    </script>

                    <style>
                         .TestEval
                         {
                              E-color: eval(skin.color);
                              E-font-size: eval(skin.defaultSize);
                         } 

                         .LargeFont
                         {
                              e-font-size:eval(     (parseInt(skin.defaultSize)+3)+"pt"     )
                         }
                    </style>

               以上代码相当于:

                    <style>
                         .TestEval
                         {
                              color: red;
                              font-size: 9pt;
                         }
 

                         .LargeFont
                         {
                              font-size:12pt;
                         }
                    </style>                    

     4.  .Global或.Init初始化

          可以类名为 .Global或 .Init的类配合eval关键字初始化。

                   <style>

                         .Global
                         {
                              E-init: eval(     window.skin={color:'red', defaultSize:'9pt'}     );
                         }


                         .TestEval
                         {
                              E-color: eval(skin.color);
                              E-font-size: eval(skin.defaultSize);
                         }
                    </style>

               以上代码相当于:

                    <style>
                         .TestEval
                         {
                              color: red;
                              font-size: 9pt;
                         }
                    </style> 

 

 

     5.  访问基类

          通过eval关键字和base关键字,访问基类对象。

                    .DefaultHeight{height:30px;}
                    .Sun
                    {
                         base: .DefaultHeight;
                         E-height: eval(parseInt(base.height)+20);
                    }

           相当于:

                    .Sun
                    {
                         height: 50px;
                    }

           当有多个基类时,则可以这样访问:

                    .DefaultColor{color:red;}                    
                    .DefaultHeight{height:30px;}
                    .Sun
                    {
                         base: .DefaultColor ,.DefaultHeight;
                         E-height: eval(parseInt(base[1].height)+20);
                    }

           也可以这样访问

                    .DefaultColor{color:red;}                    
                    .DefaultHeight{height:30px;}
                    .Sun
                    {
                         base: .DefaultColor ,.DefaultHeight;
                         E-height: eval(parseInt(base[DefaultHeight].height)+20);
                    }

           相当于:

                    .Sun
                    {
                         color: red;
                         height: 50px;
                    }

  

     6.  私有成员

          下一版本实现......

 

     转载请注明出自http://www.cnblogs.com/kuiyouli/archive/2008/10/14/1295572.html,谢谢!

 

 

posted @ 2008-10-14 22:08 吾跃乾坤 阅读(4192) 评论(52) 编辑 收藏

 回复 引用   
#1楼2008-10-14 22:13 | w3c==garbage[未注册用户]
你能说下啥叫OO么
 回复 引用 查看   
#2楼[楼主]2008-10-14 22:23 | 吾跃乾坤      
噢...
我所理解的OO就是面向对象,当然OO不单指继承性一方面,还有什么多态等!


 回复 引用   
#3楼2008-10-14 22:25 | kkk-_-!!![未注册用户]
哈哈,有独到见解!!
 回复 引用 查看   
#4楼[楼主]2008-10-14 22:32 | 吾跃乾坤      
太多不当之处,欢迎斧正
 回复 引用 查看   
#5楼2008-10-14 22:32 | 金色海洋(jyk)      
原来CSS也能这样用呀,好,支持。

如果说不能叫做“面向对象”的话,那么就叫做“基于对象”好了。

我觉得这些只是一个名称,不是重要的,重要的是,你实现了老板的要求,然后你有共享的你的思路和方法!

好样的。

 回复 引用 查看   
#6楼[楼主]2008-10-14 22:39 | 吾跃乾坤      
谢谢楼上的,得颗糖吃了!
 回复 引用   
#7楼2008-10-14 23:17 | C+++[未注册用户]
网页设计师还要懂得OO?还是程序员开始蚕食网页设计师的饭碗?
 回复 引用 查看   
#8楼[楼主]2008-10-14 23:27 | 吾跃乾坤      
我认为这不是问题,我想的话,一开始,大部分的美工都只懂处理图片,而后会HTML、CSS,虽然变化不如程序方面快,但也总是在进步的,也应该寻求一总更合理,更有效的处理方法。
 回复 引用 查看   
#9楼2008-10-14 23:53 | 代码乱了      
想法非常不错,赞一个
 回复 引用 查看   
#10楼2008-10-15 01:09 | 爆牙齿      
对css编程,很好的想法,但是我提醒你,它基本上也就只是一个想法。就像张艺谋说的:“凤凰还巢的构思和效果图都很漂亮,所以它也就只是一张图。”

对css编程处理,可实现但难使用。主要障碍在于css这项技术虽然是代码,但是基本上是和界面设计相关而不是程序。程序和设计有丝连,但是根本理念上,思维方式上是平行线。

尝试是好的,我也尝试过,只是我觉得时间浪费了,不值得。

PS:你的副标:不怕做不到,只怕想不到。对我来说是正好相反:不怕想不到,只怕做不到,呵呵。

 回复 引用 查看   
#11楼2008-10-15 01:20 | 怪怪      
@爆牙齿
然~

 回复 引用 查看   
#12楼2008-10-15 05:08 | 斯克迪亚      
想法绝对值得鼓励,新事物总是通过总结和改进前人的成果而产生的,支持你!
如果解析起来不太方便的话,也可以考虑让CSS文件由XML配置文件转换而来哦,XML用来描述这些可说是绰绰有余的,编辑好之后通过程序解析并输出为CSS就可以了。

 回复 引用   
#13楼2008-10-15 07:23 | 路过的[未注册用户]
那你需要写新的CSS解析器了
 回复 引用 查看   
#14楼2008-10-15 08:28 | 丁学      
不敢奢望~~~~~~~
 回复 引用 查看   
#15楼2008-10-15 08:38 | 大门      
不知道有没有CSS框架是否能让大家做出更利于重用的CSS
 回复 引用   
#16楼2008-10-15 08:47 | zjfeiye[未注册用户]
.ToolBar{color:#f0e000;border:1px solid gray;}
分离为
.ToolBar{color:#f0e000;}定义在Settings.css中
.ToolBar{border:1px solid gray;}仍然保留在List.css中

即可,不用修改HTML

 回复 引用 查看   
#17楼[楼主]2008-10-15 08:48 | 吾跃乾坤      
我个人觉得,不一定要把界面和程序完全分开,只要不在CSS里面作复杂的逻辑处理便可
 回复 引用 查看   
#18楼[楼主]2008-10-15 08:56 | 吾跃乾坤      
@zjfeiye

这样分离也有尝试过,这样一来如果要把不同规则里面公共部分提取出来集中定义的话 ,CSS规则名称就要用“,”分隔,对应被分离的规则名称,规则很多的时候,CSS规则名称长度很壮观

 回复 引用 查看   
#19楼2008-10-15 09:20 | jowo      
想法不错
 回复 引用 查看   
#20楼2008-10-15 09:22 | 随机      
设计也需要一种思想,不管是美工设计还是程序设计,OO就是种思想,为的是让设计人员写的代码更易于理解,更符合人类的思维方式。
顶楼主~~~

 回复 引用 查看   
#21楼2008-10-15 09:45 | Kevin-moon      
这样也行... 想法很好 顶楼主
 回复 引用 查看   
#22楼[楼主]2008-10-15 09:46 | 吾跃乾坤      
谢谢
 回复 引用 查看   
#23楼2008-10-15 10:08 | 夜‰叛逆      
学习!
 回复 引用 查看   
#24楼2008-10-15 10:30 | 极地雪狼      
想法不错。东西也不错。有可借鉴的地方,不过你的OO确实没有体现出来。
 回复 引用 查看   
#25楼2008-10-15 10:32 | 宇宙骄龙      
楼主太强了! 顶一个先... 之后悄悄的学习^_^
 回复 引用 查看   
#26楼2008-10-15 10:47 | 卡索      
楼主写的很不错!值得学习学习啦!先收藏先!
不过貌似类似的文章有个叫aoao曾经在一年前吧写过!!

 回复 引用 查看   
#27楼[楼主]2008-10-15 10:55 | 吾跃乾坤      
@卡索

你说的那个aoao的,可以贴出来看一下吗,想参考一下别人的思路

 回复 引用 查看   
#28楼2008-10-15 11:59 | 簡簡單單..      
兼容性呢?
 回复 引用 查看   
#29楼[楼主]2008-10-15 12:47 | 吾跃乾坤      
@簡簡單單..

目前这只是一种设想,不是一种成熟的供使用的技术,各方面的问题都还在考虑中

希望能得到大家宝贵的意见

 回复 引用 查看   
#30楼2008-10-15 13:16 | 痴情客      
你看你就是个菜鸟,是个偏后端的程序员。

css不是你这样用的,并且你的还是只兼容IE的,没有什么技术含量。

你的所有样式都是用.***这样去引用的,复用效率极低,并且代码比较臃肿。

你好好研究研究我的个人网站上的css,你就知道什么叫做前端开发了。

http://www.scriptlover.com/css/html.css
http://www.scriptlover.com/css/layout.css

 回复 引用 查看   
#31楼[楼主]2008-10-15 13:28 | 吾跃乾坤      
楼上的批评得是。。。。。

受教了

 回复 引用   
#32楼2008-10-15 14:20 | amenamen[未注册用户]
@痴情客
毫不留情的批评?
留点面子嘛~

 回复 引用 查看   
#33楼2008-10-15 15:26 | 痴情客      
看了你的CssInterpreter.js,写的相当有水平,从javascript角度考虑写的很不错了,不过注释太少了,这个可能是个人习惯而已。。

但我们都知道:
1.html是负责结构
2.css是负责表现
3.javascript是负责行为

你这样表现却需要行为层的支持,解释,你觉得这样恰当吗?

不过很喜欢楼主对web开发的热爱,以及钻研精神,我这人有什么就说什么的,不当的地方还请海涵。

 回复 引用 查看   
#34楼[楼主]2008-10-15 15:44 | 吾跃乾坤      
有什么说什么,好!

这只是一个设想,太多的不合适,很愿意听大家的意见!

 回复 引用 查看   
#35楼[楼主]2008-10-15 15:48 | 吾跃乾坤      
如果表现层能很好的,很方便的实现功能,当然不跟行为层达上关系最好

可是当这样的完全分离给我带来麻烦的时候,为什么不用行为层辅助一下呢!

 回复 引用   
#36楼2008-10-15 15:53 | 不错不错[未注册用户]
想法不错,挺有趣的
css最好以后直接和javascript合并了
就什么都有了

 回复 引用 查看   
#37楼2008-10-15 20:16 | 蛙蛙池塘      
很强悍。。。。
 回复 引用 查看   
#38楼2008-10-15 20:28 | 随风流月      
@痴情客
此言太狂. 少用为妙.
稍微浏览了一下代码, 居然还用 <br/> :)

 回复 引用 查看   
#39楼2008-10-15 20:28 | 随风流月      
@吾跃乾坤
我现在的做法是用 XML, 程序读取 XML 后输出 CSS 文档. 一切解决.

 回复 引用 查看   
#40楼[楼主]2008-10-15 21:56 | 吾跃乾坤      
@随风流月
诚请你加入QQ群 15774494 一起交流交流

 回复 引用 查看   
#41楼2008-10-15 22:01 | 卡索      
很不好意思!他的最先写的文章没能找到!只在他的blog中找到了
http://www.aoao.org.cn/blog/2008/01/oo-style/这篇文章!
这里只看到了他的只言片语!
望见谅!

 回复 引用 查看   
#42楼2008-10-15 22:04 | 小华子      
想法令人非常受益非浅,大大的受用了,李大哥真的是很厉害呀,哈哈,学习了...
 回复 引用 查看   
#43楼2008-10-15 22:17 | 代码乱了      
@痴情客
人不能太狂妄了。。。
作为技术人,大家都是抱着交流的心态

哈哈,认真看别人的东西,还是很有创意的,不要了解一点点就下结论
 回复 引用   
#45楼2008-10-17 02:30 | xmlcss[未注册用户]
如果不考虑 eval 相关的部分,那么可以用 .net 做个东西自动吧OOCSS 编译成普通的 CSS。

 回复 引用   
#46楼2008-10-22 20:00 | [3.7.2.][未注册用户]
很好(虽然,我其实看不懂),继续努力吧!
呵呵....实在看得...我毕竟是做美工的!

 回复 引用   
#47楼2009-05-18 22:14 | PHPer[未注册用户]
@痴情客
一看就是SB 高手是不鄙视而你....,先不讲了 你的代码我看了,我做为一个开发者 CSS都比你 (无鄙视性)

 回复 引用   
#48楼2009-07-04 17:38 | works07[未注册用户]
请问怎么引用基类的样式表?
 回复 引用   
#49楼2009-07-04 21:04 | a b cdefg[未注册用户]
基类样式表引用,按传统方式
 回复 引用 查看   
#50楼2009-08-19 09:26 | Justin      
楼上各位推荐本CSS的经典书吧
 回复 引用   
#51楼2009-10-04 21:36 | jiahut[未注册用户]
我建议楼主写个更强悍的css引擎(js实现)完全可以抛弃现在有的css的语法,像这样
css () {
var a=#f00000;
ToolBar.color=a;
....
}
解析后成了:

.ToolBar{color:#f0e000 } ;


 回复 引用 查看   
#52楼[楼主]2009-10-05 01:48 | 李子哥哥      
@jiahut

你这建议不错

新版 OOCSS 请关注 http://www.oocss.cc