CSS or just MESS?

January 27, 2010

Filed under: HTML and CSS — Andrew @ 11:50 pm

I believe that CSS (Cascading Style Sheets) in its development has reached some point that could be classified as a mess.
I suspect that quantity of features has changed the quality of the whole foundation. And not exactly in good direction.

Look, CSS used to have simple and regular construction:

selector
{
  attribute1: value[s];
  attribute2: value[s];
  ...
}

Pretty neat and clear if you would ask me. Simple list of name:value pairs separated by ‘;’ and enclosed by ‘{’,'}’ brackets.

At some point people decided to add media-queries that required new level of block containment:

@media <media-expr> {
   selector {
     attribute1: value[s];
    ...
   }
}

which is not that bad – still manageable by some tools like ANTLR parser generator.

But please note that media-expr above. It has its own micro-format with AND, OR and peculiar ONLY operators. Even media-expression specific length units… But no arithmetic operations there. Hmm, wait, there are arithmetic operations in CSS now! In the calc() function. But there are no AND, OR and friends in this place.

So we have at least two places in CSS where expressions are used but with different notations.
Seems like as different strangers passed by this X-Mas tree and have left their own decoration on it.

CSS design principle fig

And those lists in CSS …

First of all I do not know any other language but CSS that uses space (’ ‘) as an operator. Space here is a) token delimeter and b) an operator that glues two tokens into a list. So value of the attribute border: 1px solid red; is a list of three values ‘1px’, ’solid’ and ‘red’. That is again fine. We can live with this.
But here another stranger passes by our tree who needed e.g. list of fonts. So one list should contain another one. In good mood that stranger would introduce brackets and write something like this:

font: 12pt (Arial Verdana sans-serif)

But sudden voice from the Heaven: “brackets and other programming stuff are not for CSS – John the Web Designer will not get them”. So our stranger decided to add ‘,’ (comma) as another list-gluing-operator. And we’ve got this:

font: 12pt Arial, Verdana, sans-serif;

Note that comma here is an operator of higher priority than space as Arial, Verdana, sans-serif here is a single value (list by itself) of <font-family> attribute.

Story continues…. Another girl was swinging around that tree and suddenly decided that ‘/’ (slash) would also look extremely cool as another list-gluing-operator of her own. And so, voila!, we have:

p { font: x-large/110% "New Century Schoolbook",serif }

.
with the hope that this in principle better comprehensible than something like font: (x-large 110%) ("New Century Schoolbook" serif).

Well, our beautiful in its ugliness CSS tree was standing this way for years. But now new people are singing Jingle Bells around it. New times – new ideas, e.g. of multiple backgrounds. So instead of single list of values defining various background attributes (like positions, repeat, url, color, etc) we will have list of list of values.

Yeah! So another list-gluing-operator is coming, right?

Nope. There are simply no characters left after 10 years of CSS development. So another creative approach was introduced – to reuse ‘,’ (comma) again but with the brand new meaning.

In the background we are getting this:

background: url(a.png) top left no-repeat,
            url(b.png) center / 100% 100% no-repeat,
            url(c.png) white;

Note that comma is a different operator here as its priority is less than space. That is clearly different from the ‘font’ attribute we saw above. And yet note that clever use of ‘/’ again …

Yes, it is just a mess. It is not possible to write a parser that will handle ‘font’ and ‘background’ by using the same code as e.g. ‘font’ and ‘background’ attributes are written in different languages.

If you think that this is over then no. Another creative team is entering the stage with the Wobble song:

@keyframes 'wobble' {
    0% { left: 100px;  }
    40% { left: 150px; }
    60% { left: 75px;  }
    100% { left: 100px;  }
  }

Yeah, why not? Indeed, values in place of name tokens are really nothing if to compare with those lists …

And while our party is going on there is another group of modest people is busy printing their own stuff on other side of the tree:

@page :first {
  color: green;
  @top-left {
    content: "foo";
    color: blue;
  }
  @top-right {
    content: "bar";
  }
}

At the moment CSS looks like a patch quilt where each tile uses its own language with distinct notation and grammar. Am I alone who think that this is a sign of bad language design [process]?

It appears that all successful programming and data definition languages were created by single persons or compact groups of like-minded people. Java, C/C++, Pascal, SQL, you name it. Is this mess because of CSS has no central author[ity] or why?

Vancouver winter sunset

January 10, 2010

Filed under: Photos — Ivan @ 2:39 pm

Now, could the rain stop more often around here?

Tree Of Life by IvanAndreevich

Aero, Windows V/7

December 2, 2009

Filed under: HTMLayout, Sciter — Andrew @ 9:00 pm

In the middle of adding Windows Aero DWM support to HTMLayout and Sciter:
htmlayout-aero-w7

This is standard sample htmlayoutsdk/html_samples/border-radius/rounded-tabs.htm from the SDK

Seems like I need to add “aero” as an additional value to CSS @media selector in order to support such screens. This document is using simple html { background-color:transparent; } declaration to make it transparent.

And w7aero sample application is calling this function

void ExtendFrameIntoClient(HWND hwnd)
{
   // Negative margins have special meaning to DwmExtendFrameIntoClientArea.
   // Negative margins create the "sheet of glass" effect, where the client area
   //  is rendered as a solid surface with no window border.
   MARGINS margins = {-1};
   HRESULT hr = S_OK;
   // Extend frame across entire window.
   hr = DwmExtendFrameIntoClientArea(hwnd,&margins);
   assert (SUCCEEDED(hr)); hr;
}

Pretty easy I would say…

Multi-return and multi-assignment in TIScript.

October 31, 2009

Filed under: Sciter, Script, Web Application Techologies — Andrew @ 11:42 pm

As we know parameters of functions are passed by value in languages like TIScript and JavaScript. Inside the function we can modify paramaters and their new values will not be seen outside the function.

Let’s say we need to implement function expand(rect, dx, dy) : rect that should increase dimensions of the rectangle.

If the rect is an object then we will write something like this:

function expand(rect, dx, dy)
{
   return {
     x: rect.x - dx,
     y: rect.y - dy,
     w: rect.w + 2*dx,
     h: rect.h + 2*dy };
}

Problem with this implementation: it allocates brand new object on each call. That is not desirable if the function is used frequently.

If TIScript would support pass-by-reference for parameters then this function will have signature like this: inset(&x, &y, &w, &h, dx, dy) but no such thing as pass-by-reference in JS and TIScript for many good reasons.

As a solution: in TIScript we can use so called multi-return and multi-assignment feature – function is allowed to return multiple values.

Using this feature we can rewrite our function as:

function expand( x, y, w, h , dx, dy)
{
   return ( rect.x - dx, rect.y - dy, rect.w + 2*dx, rect.h + 2*dy );
          // returns "list" or tuple if you wish of four values.
}

To call such function and to get multiple values from it we will use list of values as an l-value expression:

var x = 10, y = 10, w = 100, h = 100;
(x,y,w,h) = expand(x,y,w,h, 20, 20 );

Parameters and return values are passed using stack of the VM so this will not create additional payload for the heap manager.

And yet it is pretty convenient for other cases too. For example this:

var a = 10, b = 5;
(a,b) = (b,a);

is how you can swap values of two variables.

Small feature but quite usefull.

Main challenge was to plug value lists into existing syntax of JavaScript. Implementation is quite simple.

Stringizer functions in TIScript

October 24, 2009

Filed under: Sciter, Script — Andrew @ 4:28 pm

Motivation.

Tasks of defining string expressions and textual fragments in script code are pretty common.

Typical example in JS/browser is:

someelement.innerHTML = 
"<span style=\"color:#ffffff\">" + somestuff + "</span>";

As you see this could be quite noisy and complex to be comprehensible by human.

Various scripting languages are trying to reduce syntax noise in various ways. Scala for example allows to define XML literals http://programming-scala.labs.oreilly.com/ch10.html inline without need of "mangling" it by quotes. This feature appears as quite neat but is limited by XML only. E.g. it will not work for HTML ("HTML is not XML"™) or for things like CSS selectors, etc.

Another example is string templates in Ruby. They allow to define string literals with embedded code:

template = 'Dear #{customer},\nPlease pay us #{amount} now.\n'

but this still needs string literal. One more problem with such approach: various types of strings need different escapement rules applied to values being embedded in the string. E.g. for HTML it should be String.htmlEscape() call, for URLs – String.urlEscape(), etc.

So there is a need to have some syntax construction that will allow to define various ways to define string compostions.

Solution.

As a solution I’ve implemented in TIScript so called stringizer functions.

Stringizer function is a function (or method) with the name starting from ‘$’ character and with variable number of parameters.

Call of such function is written in the form:

$name( ... some text here... )

Where the text inside ‘(’ and ‘)’ is not required to be enclosed in quotes. Characters ‘(’ and ‘)’ are serving role of quotes by themselves.

Example of such stringizer call:

var firstDiv = self.$( #content > div:first-child );

$ here a stringizer method that accepts CSS selector expressions. The sample above is a direct equivalent of this:

var firstDiv = self.select( "#content > div:first-child" );

Text inside ‘(’ and ‘)’ may contain expressions enclosed in curly brackets ‘{’ and ‘}’. Result of the expression in such brackets will be passed into the stringizer function as is.

Having all this in place the very first example of the article can be written in Sciter simply as:

someelement.html
    = $html( <span style="color:#ffffff">{ somestuff }</span> );

TIScript will de facto compile this call as:

someelement.html
    = $html( "<span style="color:#ffffff">",
               somestuff,
               "</span>" );

The only thing left is an implementation of the $html() function that we can define like this:

function $html(params..)
{
  for( var (n,v) in params )
    if( n & 1 ) // each odd paramter is a
                    // value of expression inside '{' and '}'
      params[n] = v.toHtmlString(); // calling method
                    // that will do HTML escapement
  return params.join(""); //return composed string
}

Some ideas

Here are some ideas for such stringizer functions we can use in the Sciter:

  • function Element.$append( ... inline html ... ) – method of the DOM element class – appends the html after last child of the element.
  • function Element.$prepend( ... inline html ... ) – prepends the html before first child of the element.
  • function $text( ... some text ... ) – simple way of composing texts.
  • function Stream.$print(... some text ... ) – simply prints text with possible { } inclusions.
  • function $xml( ... some xml... ) – to compose XML string and create XML tree using built-in XML parser.
  • you name it…

Achtung, minen!

July 11, 2009

Filed under: Script, Web Application Techologies — Andrew @ 11:20 pm

One more “cool” thing about JS:

somevar = 100;

      function test()
      {
        somevar = 1;
        return somevar;
        if(false) { var somevar; }
      }

      alert(test());
      alert(somevar);

Try to guess first what these two alert()s will output in JS.

You did?

Then try to see this code running alive: js-mine.

That is what Web2 is supposed to be based on… Huh?

[update] Here is a link on Doug’s Crockford talk at Google about JS.

Doug Crockford is behind JSON spec and ECMAScript 3.1.

Probably Doug’s speech may explain why I decided to go with TIScript rather than implementing JS as it is.

Next Page »