W3C home > Mailing lists > Public > www-style@w3.org > July 2008

Variables, Heritage, CSS!, .... : old proposals but compared with new requests

From: Francois Remy <fremycompany_pub@yahoo.fr>
Date: Wed, 2 Jul 2008 13:27:05 +0200
Message-ID: <01D408ED9CB140BA887EE75439523695@FremyCompany1>
To: "CSS 3 W3C Group" <www-style@w3.org>
Here are some old proposals I made (some were not realist, I know) but seen in a more global aspect :
- Comparaison with proposal currently discussed 
    - I give then ideas to advance in these specs
    - Positives and negatives points of these specs
    - Proposed changes that I already have seen for this proposals

I've also putted in green sections of samples that have no more sense :
- Already better defined in a new spec
- In relation with a idea that have not been retained

Please not that some proposals are too complex to be implemented but some other ones are easy to implemend and very useful

Fremy


From: Francois Remy 
Sent: Saturday, April 19, 2008 7:16 PM
To: www-style 
Subject: Proposed evolutions to CSS 4 : @res (generalisation of @font-face), CSS Conditional values, ...

[...]

  a.. My first idea is to generalise @font-face into an @res rule.
Why ? 
Because when you're developper, you use several times the same color, and it would be great to "give a constant name" to the color 
- It's easier to retain names than color values ("bgColor" vs "#e4cedd")
- You can swicth themes keeping the main CSS file, just updating your constants.
- ...

Current closest proposal : Variables

    Positive points of @variables :
        - One block is sufficient to declare more than one variable
        - The syntax matches some other already-existing syntax

    Negative points of @variables :
        - I see none currently (type inference is a good idea, in fact)

    Proposed changes :
        - Heritage by defining variables-like objects 
                My ideas about it :
                   - My prefered syntax is :
                  @style-set redColored { color: red; }; 
                  selector1 { extends: redColored; }

        - Selector heritages
                My idea about it :
                - Is this really needed ?
                - My prefered syntax is :
                
        - Constants 
                My ideas about it : 
                  It seems difficult to implement in CSS

        - Different propagation levels (public / friend / private)
                My ideas about it:
                  It seems great but it's probably difficult to be implemented by UAs

  a.. My second idea is to give more decisional power to CSS.
Why ?
Currently, we can't check browser name nor version in CSS, we must use hacks or IE conditionnals comments in HTML.
Based on this, I think CSS should be able to give more "programatic" responses to the browser with functions like "IIF", "firstOf", ...

How ?
By adding some functions that can be computed by the browser in CSS values.
  property: iif(
      !support("CSS", "5"),
      "CSS4-Value",
      "CSS5-Value"
  );
Current closest proposal : CSS!

    Positive points of CSS! :
        - Event handling (like -on-leave-ocus / on-get-focus)

    Negative points of CSS! :
        - Break some current CSS specs
        - Define a insufficient number of functions (but we can merge specs)

    Proposed changes :
        - No proposed changes that I can notice here
  a.. My 3st idea is to be able to add sub-rules into a rule
Why ?
If we want to use inline style for an element, we can't specify style for the child elements. It would be great to add a way to do this. 
Also, it can be a save-time for developpers because we don't need anymore to retype 100 times the same selector.

How
By adding some @rule rule to each CSS Rule.

Current closest proposal : None but I juste have seen a mail that talk about something so

    Positive points of the mail's proposal :
        - Reusability without needing defining a style-set (see proposal 1 > proposed changes > inheritage)

    Negative points of the mail's proposal :
        - Not usable in inline styles
        - More long to write


Here's a documentation and some samples about my ideas (I know it's not so that a W3C must be done, but I think my documentation is easy to understand, which is a good start) :

All things in green are supposed to be deleted
  /* Constants */
  @res {
      /*
          - CSS-Type : Specify the type of the constant.
          If you specify a CSS-Type (or typeof(CSS-Property)), the value property must match the choosed type.
          If the value is not matching the choosed type, the constant should be ignored.
          CSS-Type {
              font;
              color;
              url;
              length;
              angle;
              ...;
          }
          
          - value : Replace a whole CSS Property value.
          You can't combine a value constants with another constant.
      */
      type: [CSS-Type, 'value'];
      /*
          Name of the constant.
          To use the constant later in code, you should type @constant_name.
      */
      name: CSS-String;
      /*
          Value of the constant.
          If value is not of the good type, constant must not be defined.
      */
      value: CSS-Value;
  Now redefined by variables
      
      /*
          DOM Implementation of constants
          --------------------------------
          document.CSSConstants : {
              /*
                  Parse CSS-Value in regard to CSS-Type (2)
                  If a constant already exists with the same name:
                      If old constant and new constant have the same type : update the old constant. (3)
                      Otherly : an error should be thrown (1).
                  Otherly, add a new constant.
                  
                  Exceptions: "TYPE_IS_WRONG" (1), "WRONG_DATA" (2), "READONLY_CONSTANT" (3)
              */
              [function:void] add(constantName:String, constantType:CSS-Type, constantValue:CSS-Value);
              
              /*
                  Exceptions: "CONSTANT_DOES_NOT_EXISTS", "READONLY_CONSTANT"
              */
              [function:void] remove(constantName:String);
              
              /*
                  Read:
                      If constant doesn't exists, return undefined
                  Write:
                      If constant doesn't exists, it should be added
                      Exceptions: "READONLY_CONSTANT", "WRONG_DATA"
              */
              [default/r/w]   item(constantIndex:Number):CSS-Constant;
              [default/r/w]   item(constantName:String):CSS-Constant;
              
              [r]             length:Number;
          }
          
          CSSConstant : {
              [constructor]   new(name:DOMString, type:CSS-Type, value:CSS-Value):CSSConstant
              [r]             name:DOMString;
              [r]             type:CSS-Type;
              /*
                  Some browsers constants (@browser, ...) can be readonly.
              */
              [default/r/w]   value:CSS-Value;
          }
      */
  };

  Redefined in another mail to be closer of the variable syntax
  We also have the David's proposal about a getComputedVariableValue() function

  /* Conditional values */
  CSS-Conditional-Values-API {
      /*
          Useful to define constants if type's name is not known or differs between browsers
      */
      typeof(CSS-Property) : CSS-Type {
          If CSS-Property doesn't exists, is complex (more than one type) or has no predefined type
              Return 'value';
          Else
              Return the CSS-Type of CSS-Property
          End if
      }

  Was only needed because of constants/variables' types declaration. Now unecessary (variable type inference)

      
      defined('constantName') : Boolean {
          If an @constantName constant is defined
              Return true;
          Else
              Return false;
          End if
      }

  So we can check if a variable is defined or not.
  Sample : selector { color: iif(defined('bgColor'), bgColor, black); }
      
      A = B, A == B,
      equals(A:CSS-Value, B:CSS-Value) {
          Return A == B;
      }

  The simple '=' should be keeped for setting value of variables, if we implement CSS! or something so
  Sample : selector { color: iif(@browser == 'IE', 'xxx', 'yyy'); }

  Please not that I've given two name for each operators : 
  - a programatic operator (a + b; a = b; ...);
  - a functionnal opearator (add(a,b) , equals(a,b) , ...)

      
      /*
          If the ">" operator is not supported for the CSS-Value type, return false.
          Notes: 
              - %, cm, mm, em, ... must be converted to px before comparing (length type).
              - Same for angles and others unit systems.
      */
      A > B,
      greater(A:CSS-Value, B:CSS-Value) {
          Return A>B;
      }

      /*
          If the "<" operator is not supported for the CSS-Value type, return false.
          Notes: 
              - %, cm, mm, em, ... must be converted to px before comparing (length type).
              - Same for angles and others unit systems.
      */    
      A < B,
      smaller(A:CSS-Value, B:CSS-Value) {
          Return A<B;
      }
      
      /*
          If the ">" operator is not supported for the CSS-Value type, return A.
          Notes: 
              - %, cm, mm, em, ... must be converted to px before comparing (length type).
              - Same for angles and others unit systems.
      */
      min(A:CSS-Value, B:CSS-Value) {
          If A > B
              Return B
          Else
              Return A
          End if
      }
      
      /*
          If the ">" operator is not supported for the CSS-Value type, return A.
          Notes: 
              - %, cm, mm, em, ... must be converted to px before comparing (length type).
              - Same for angles and others unit systems.
      */
      max(A:CSS-Value, B:CSS-Value) {
          If A > B
              Return A
          Else
              Return B
          End if
      }
      
      !Bool, 
      not(Bool:Boolean) {
          Return !Bool;
      }
      
      B1 & B2, B1 && B2,
      and(B1:Boolean, B2:Boolean) {
          Return B1 & B2;
      }
      
      B1 | B2, B1 || B2,
      or(B1:Boolean, B2:Boolean) {
          Return B1 | B2;
      }
      
      @browser:CSS-String {
          Short name of the browser.
          Multiples browsers can have the same @browserName if they use the same render agent
          Samples : IE, FF, OP, SF, KQ, ...
      }
      
      @browserVersion:Number {
          Version of the browser
          @browserVersion must be the same for each browser using the same @browserName and @renderAgentVersion
      }
      
      @renderAgent:CSS-String {
          Name of the render agent
          Samples: Trident, Gecko, Presto, WebKit, ...
      }
      
      @renderAgentVersion:Number {
          Version of the render agent.
          @renderAgentVersion must be the same for each browser using the same @browserName and @browserVersion
      }
  Browser detection. To avoid hacks in CSS.

      
      support(Something:CSS-String) {
          If UA support "Something" (CSS, XHTML, DOM)
              Return True
          Else
              Return False
          End if
      }
      
      support(Something:CSS-String, Version:Number) {
          If UA support "Something" in version Version (CSS-4, XHTML-2, DOM-3)
              // UserAgent should not return true if "Something" is not fully supported yet.
              // UserAgent should not return true if the W3C State of the property is not "RC" or more because changes can be apported to the specs.
              
              // If UserAgent are wanting to claim support for properties that are not yet RC, they can use prefixes.
              // The prefix can match the @browserName value, but it must not.
              // Samples: support('MS:DXTransitions',1), support('MOZ:JS',1.8), ...
              
              // If an UA support 'DOM' and "Something" is like 'MOZ:DOM', UA can return True.
              // It's usefull if a propriatory function become a W3C Standard. 
              // Older codes could use the prefix to find if the function is implemented.
              Return True
          Else
              Return False
          End if
      }
      
      iif(Condition:Boolean, ValueIfTrue:CSS-Value, ValueIfFalse:CSS-Value) : CSS-Value {
          If Condition is evaluated to True
              Return ValueIfTrue;
          Else
              Return ValueIfFalse;
          End if
      }
      
      firstOf(Values:CSS-Values[]) {
          For Each Value:CSS-Value in Values
              If Value can be used in the property context (ex: a color for the background-color property)
                  Return Value;
              End if
          Next Value
          Return CSS-Undefined-Value; // Property is considered as not set
      }
  }

  Please not that all of this is a little utopic because it need a lot of work to be implented by UAs.
  I leaved these section to preserve my original mail and give some ideas to CSS! supporters but I don't beleave that
  all these things will be implemented in a middle/short future.

  /* Cascading-Rules */
  s1:CSS-Selector {
      [CSS-Property: CSS-Value]*
      /* Computed as 's1 s2' */
      @rule(s2:'CSS-Selector') { 
          [CSS-Property: CSS-Value]*
      };
  }

  Was only needed because of constants/variables' types declaration. Now unecessary (variable type inference)

  /*
      Exemple :
      ----------------
      
      @res { type: color; name: 'color1'; value: #abcdef; }
      @res { type: url; name: 'image1'; value: '/images/bg.png'; }
      @res { type: typeof(background-repeat); name: "both"; value: repeat; }

      @res { type: value; name: 'headerBg'; value: @color1 @image1 @both ; }

      #someObject {
          background: @headerBg;
      }
      
      #someObject2 {
          background: iif(
              @browser='FF' & @browserVersion<4,
              'url(\'xxx.svg\')',
              'url(\'xxx.svg2\')'
          );
      }
      
      #someObject2b {
          max-width: min('50%', '500px');
          width: fit-content;
      }
      
      #someObject2c {
          background: firstOf(
              /* Wrong values */
              'Arial, serif',
              'red solid 3px',
              /* If browser support RGBA */
              'rgba(171,205,239,0.75)',
              /* Else If constant is defined and supported */
              '@color1',
              /* Else If constant is not defined or not supported */
              'red'
          );
      }
      
      #someObject3, #someObject3b {
          background: green;
          
          /* #someObject3 *, #someObject3b * */
          @rule('*') {
              color: black !important;
              text-decoration: none;
          };
          
          /* #someObject3 a:hover,
            #someObject3b a:hover,
            #someObject3 a:visited,
            #someObject3b a:visited 
          */
          @rule('a:hover, a:visited') {
              text-decoration: underline;
              
              /* #someObject3 a:hover *, 
               #someObject3b a:hover *,
               #someObject3 a:visited *,
               #someObject3b a:visited *
             */
              @rule('*') {
                  text-decoration: underline;
              };
          };
          
          border: 3px lime outset;
      }
      
      /* In HTML */
      <div style="border: 1px solid black; @rule('div') { display: inline; };">
          <div>Some</div> <div>text</div>
      </div>
  Another sample :
  @style-set AList {
      @rule ('a') {
          display: block;
      }
  }

  selector1 { extends: AList;  }

  */
Regards,
Fremy
Received on Wednesday, 2 July 2008 11:27:52 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:10 GMT