Cheap CSS implementations?

September 2, 2010

Filed under: HTML and CSS — Andrew @ 1:26 pm

CSS3 defines [att=val] selectors . And they work in all modern browsers in static form.

But when you will try to use such a selector with attributes changed from script you will get problems.

Following works as expected in FF but does not work in Google Chrome and Opera:

<html>
<head>
  <style>

    div { display:none; }
    body[show="n1"] #n1 { display:block; }
    body[show="n2"] #n2 { display:block; }

  </style>
  <script type="text/javascript">

    function test()
    {
      document.body.setAttribute("show","n2");
    }

  </script>
</head>
<body show="n1">
  <a href="javascript:test()">Test</a>
  <div id="n1">1</div>
  <div id="n2">2</div>
</body>
</html>

I am wondering why Opera and WebKit implementations are failed on this simple test.
As for my [educated] knowledge attribute value selector has the same complexity as e.g. class selector in CSS. No idea to be honest.

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?

CSS Flexible Flow Module

April 10, 2009

Filed under: HTML and CSS, Web Application Techologies — Andrew @ 6:05 pm

We have published official proposal about ‘flow’ and flex units used in h-smile core:
CSS Flexible Flow Module

With the hope that the Web will benefit from them.

Announce: ScIDE

August 3, 2008

Filed under: HTML and CSS, Sciter, Script, Web Application Techologies — Andrew @ 10:40 am

ScIDE is a compact and handy source code editor with syntax highlighting (colorizing).

ScIDE is a system of HTML, CSS and scripting files that are running inside the Sciter. So ScIDE is so-called .scapp – Sciter application.

ScIDE screenshot

You can run ScIDE:

  1. inside Sciter.exe player (part of main SDK distribution) or
  2. as a separate application ScIDE.exe that is available as a separate install-by-unzip ScIDE distribution.
    ScIDE.exe is a simple bootstrap exe of Embeddable Sciter – sciter-x.dll. Its sources are in the SDK.
  3. sciter-x.dll can be embedded in other applications so ScIDE or its parts may appear in other applications too.

ScIDE uses Scintilla editing engine wrapped as so called native behavior module. Sources of the behavior + slightly modified version of Scintilla are here.

ScIDE is lightweight and very fast despite of the fact that it uses scripting. Script is used as a glue sticking UI components together.

So far ScIDE knows about html, php, asp, css, js, tis, h/hpp and c/cpp files. These colorizing schemas are defined in /scapps/sciter.ide/scintilla/schemas/*.tis files and can be extended by script.

Visual style of the whole application is totally CSS driven so can be customized in different ways.

CSSS! and computational complexity of selectors.

July 25, 2008

Filed under: HTML and CSS, Philosophy, Web Application Techologies — Andrew @ 12:51 pm

Lets say we have following markup:

<ul>
   <li>First</li>
   <li>Second (with <a href=#>hyperlink</a>)</li>
   <li>Third</li>
   <li>Fourth (with <a href=#>hyperlink</a> too)</li>
</ul>

and the styling task: all <li> that have <a> elements inside have yellow background.

If we would have hypothetic selector :with-child(selector) then we could write this as:

li:with-child(a:link) { background:yellow; }

Problem with this selector lies in its complexity – to compute such selectors you need to scan whole subtree of the element (<li> here). That is a task of complexity O(n). n here is a number of children of the element. Potentially it could be the whole DOM ( html:with-child(a:link) ).

And again that O(n) is not that bad if it happens only once but for the case:

html:with-child(a:hover) p { ... }

all <p> elements of the document should get new styles each time when some <a> in document will get :hover state. And that is really bad. Standard methods of optimizing such cases (e.g. caching) may not be acceptable as they may require significant amount of RAM and/or again CPU resources.

… back to the original task of styling "<li> that have <a> elements inside". It is still possible to solve it while keeping resource consumption at the same level.

Imagine that we would have some magic engine that will assign, say, attribute has-a-inside to such <li> elements. Then our task of styling <li>s will turn into simple rule that is known to be effective:

li[has-a-inside] { background:yellow; }

In real world scenarios people these days use JavaScript for that. Requires some programming but works reasonably well.

But our desire to do this solely by CSS as JS is not always available. Here is the method of how to accomplish this by CSSS! (so called active CSS) introduced in recent versions of h-smile core (htmlayout and the Sciter).

In CSSS! we need to create one helper rule that will create attribute has-a-inside for each <li> with <a> inside:

li
{
  assigned!: self.has-a-inside = self.$1( a[href] )? "true" # null;
}

This rule simply means:

When element li will get this style declaration first time (so when assigned!) this statement do:

  1. assign "true" to the attribute has-a-inside if that li element (self) has at least one element inside matching the selector a[href].
  2. or assign null to that attribute – so to remove it form the element.

The only rule left is the one that I’ve already mentioned:

li[has-a-inside]
{
  background:yellow;
}

Thus after loading such document all <li>s with hyperlinks will have yellow background. Done.

Of course it is not so abstractedly perfect if to compare with with-child(a[href]). E.g. our solution will not reflect dynamic DOM updates but that was the problem we were trying to solve anyway.

Nevertheless it will allow to solve the task in most of practical cases and will at least not make selectors matching implementation worse than it is now.

CSS, selectors and computational complexity

July 23, 2008

Filed under: HTML and CSS, Philosophy, Web Application Techologies — Andrew @ 10:57 am

CSS (Cascading style sheets) has pretty extensive set of so called selectors. Example:

ul[type="1"] > li
{
  list-style-type: decimal;
}

Selector here means following: each li element that is immediate child of ul that has attribute type with the value "1" has that style.

Selectors and assosiated styles constitute static system of styles. And so they obey following rule (the law of CSS selectors):

At any given moment of time all elements in the DOM that satisfy set of selectors have correspondent styles applied.

Such static nature of CSS selectors establish some obvious (and not so) limitations on what could be done with selectors and what types of selectors CSS can support. For example:

  • Selectors cannot use information defined by styles. Imagine hypothetical selector and style:
    div:visible { visibility:hidden; }
    

    Such pseudo-class always fails and so breaks the rule defined above. It is simply no such moment of time when the rule above is valid.

  • Selectors can use only those features/characteristics of the DOM that can be evaluated at constant (or near) time. Otherwise observer will be able to catch moment of time when the rule will not be true.
    • Consequence of this: selectors that require scan of number of elements of the DOM unknown upfront ( have complexity O(n) in other words ) are "persons non grata" in CSS.

There is nothing wrong in principle with O(n) complexity. At the end resolution of all styles of the DOM that has n number of elements is O(n). The problem arises when you use selectors that each has O(n) complexity. Total complexity in this case will be O(n*n) and that is the cause of troubles.  In case of frequent dynamic updates each such update may require re-computation of all styles of all elements so web page may easily become non-responsive – CPU will be busy resolving styles without doing any good to the user.

Imagine that we have selector like:

ul:not-exist(a:hover) {color:red;}

where :not-exist(…) is true when DOM does not contain element in brackets.

Computation of such pseudo-class is a task of complexity O(n) where n is a number of elements in the DOM.

No one of currently supported selectors in CSS selector module (http://www.w3.org/TR/css3-selectors/) have complexity of O(n). But there are selectors like :o nly-of-type pseudo-class that are "not good" as in some conditions their computation is as complex as O(n).

Next article will explain what could be done in CSS to overcome complexity problem and still be able to accomplish tasks like ul:not-exist(a:hover) {color:red;}

Some numbers if you wish:

Let’s assume that we have

  1. DOM with 1000 elements and
  2. single selector that has complexity  O(n) that requre 1 microsecond for computation.

Total time requred for the DOM to get its styles will be:

1000 * 1000 * 1μS = 1000000 μS = 1 S (one second)

Lets double number of elements in the DOM so we will get:

2000 * 2000 * 1μS = 4000000 μS = 4 S.

So by simply doubling number of elements we’ve increased time needed by four.

In real time scenario (on complex sites) it will easily make such sites too heavy to deal with.

Next Page »