[BECS] CSSS! - CSS script

Idea is to add ability to define simple event handlers in CSS.

Event handlers are ordinary style attributes with names starting with 
"when-...".
Such attributes accept sequence of statements of so called CSSScript 
ending with ';'

Here is practical example:  implementation of Tabs functionality.
Tabs is a set of labels and set of panels. Visibility of panel is bound 
with correspondent tab.
Only one tab can be in current state at the moment and so only one panel 
from the set can be visible.

Here is one of possible markups:

  <div class="tab-strip">
       <span current>First tab</span>
       <span>Second tab</span>
       <span>Third tab</span>
  </div>
  <div class="panels">
    <div current>First panel.</div>
    <div>Second panel.</div>
    <div>Third panel.</div>
  </div>

Here is style definition that use CSSS! feature:

div.tab-strip span
{
    when-active-on:
           $(div.tab-strip span[current]).current = null
           $(div.panels>div[current]).current = null
           self.current = true
           $1(div.panels>div:nth-child(< self:index >)).current = true;
 }
 div.tab-strip span[current] { background: yellow; border:1px solid; 
border-bottom:none; }
 div.panels > div { display: none; }
 div.panels > div[current] { display: block; background: yellow; 
border:1px solid; height:200px; }

This simple set of rules will present panel corresponded to its 
tab/label. As you may see tabs and panels may not
be in parent/child relationship. And usually they are not.

Here I am using 'when-active-on' event handler that is triggered when 
element is getting active state.
Meaning of statements of when-active-on handler:

$(div.tab-strip span[current]).current = null
$(div.panels>div[current]).current = null

  - select set of DOM elements by the selector "div.tab-strip 
span[current]" and remove
    attribute 'current' from each of them (by assigning null).
    Do the same for the "div.panels>div[current]" selector.

self.current = true

  - set 'current' attribute equal to "true" on the DOM element this rule 
is applied to.

$1(div.panels>div:nth-child(< self:index >)).current = true;

  - set 'current' attribute equal to "true" on the DOM element 
satisfying the selector
    "div.panels>div:nth-child(X)" where X is an index of the 'self' - 
DOM element this
    rule is applied to.

The CSSScript is simple. It is a sequence of statements in the form:

   <target> <prop> = <left-side-expression>

Where 'target' is either:
    self - pseudo variable holding reference to the element this rule is 
applied to (close to 'this' in JS), or
    $xx(...) - one of six selector pseudo-functions. These functions 
return either one or set of elements.

'prop' is either:

    * .attrname - name of DOM element attribute, or
    * :statename - name of state flag of the DOM element, examples are:
      :hover, :active, :checked, etc. And there are two additional state
      fields:
          o :index - index of the DOM element in its parent collection and
          o :value - runtime value of the DOM element, for input
            elements that is the value and for other it is a text of the
            DOM element.

Thus CSSS! is allowed to change DOM element attributes and states but 
not CSS attributes. For many reasons.

Selector pseudo functions:

   1. $(selector) - select elements globally with the :root set to the
      root node of the document.
   2. $1(selector) - select first matching element globally with the
      :root set to the root node of the document.
   3. $c(selector) - select children of the self element, the :root is
      the self element.
   4. $1c(selector) - select first matching child of the self element,
      the :root is the self element.
   5. $p(selector) - select all parents of the self element matching the
      selector, the :root is the root node of the document.
   6. $1p(selector) - select nearest parent of the self element matching
      the selector.

In principle CSSS! can interact with JS by calling functions assigned to 
DOM elements. But this is optional.

List of when-... event handlers I've found useful so far:

    * when-hover-on:
    * when-hover-off:
    * when-active-on:
    * when-active-off:
    * when-focus-on:
    * when-focus-off:
    * when-click:
    * when-value-changed:
    * when-assigned: - triggered when this rule is assigned to the
      element. Used for initialization of states.

I have an implementation of CSSScript already - it is a simple stack 
based machine that does not require any GC (garbage collector)
and the like. In the case of any interest I can publish detailed 
specification of CSSS! grammar.

Some tasks that can be accomplished with CSSS!:
Collapsible tree views, Tabs, binding value of input elements with 
visibility of other DOM elements, etc.
Surprisingly many common UI tasks can by handled by such simple thing.

Hope this is interesting. If someone will want to play with CSSS! then 
it will be available in the next build of
htmlayout @ terrainformatica.com

--
Andrew Fedoniouk.
http:/terrainformatica.com

Received on Thursday, 8 May 2008 00:27:32 UTC