zoukankan      html  css  js  c++  java
  • 面向对象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下每套皮肤一个文件夹,最终目录结构大致如下。

    复制代码
     1 Common/Skins
     2 Common/Skins/Green
     3 Common/Skins/Green/Common.css
     4 Common/Skins/Green/List
     5 Common/Skins/Green/List/list.css
     6 Common/Skins/Green/List/Images/
     7 Common/Skins/Green/List/Images/imgxxxx.gif
     8 Common/Skins/Green/AddEdit/AddEdit.css
     9 Common/Skins/Green/AddEdit/Images/
    10 Common/Skins/Green/AddEdit/Images/imgxxxx.gif
    11 
    12 Common/Skins/Blue
    13 Common/Skins/Blue/Common.css
    14 Common/Skins/Blue/List
    15 Common/Skins/Blue/List/list.css
    16 Common/Skins/Blue/List/Images/
    17 Common/Skins/Blue/List/Images/imgxxxx.gif
    18 Common/Skins/Blue/AddEdit/AddEdit.css
    19 Common/Skins/Blue/AddEdit/Images/
    20 Common/Skins/Blue/AddEdit/Images/imgxxxx.gif
    复制代码

    共定义有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,谢谢!
        推荐相关阅读:走走停停看看的《从模块化CSS到面向对象的CSS》

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 回形取数
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    Java实现 蓝桥杯VIP 基础练习 报时助手
    block的是发送信号的线程,又不是处理槽函数的线程
  • 原文地址:https://www.cnblogs.com/shazhou-blog/p/5890108.html
Copyright © 2011-2022 走看看