Thursday, July 16th, 2009

A new way to do layout; CSS Scripting Layout

Category: Chrome, CSS

CSS is great for styling, but can be agonizing for laying out applications. There have been attempts to do JavaScript powered layout, but what about adding more semantics to CSS itself?

Darrel Karisch has posted on just that, with his CSS Scripting Layout:

This document describes a new set of CSS properties and object specifications that together compose a powerful declarative means to describe complex arbitrary layout criteria that are both reusable and extensible. The new properties are Javascript expressions that are woven together in a constraint resolving system to perform a specified layout. Additionally, a set of global objects defined in the constraint resolution Javascript execution environment enable powerful operations to be expressed succinctly resulting in more readable and compact layout specifications.

  1. @layout-policy name
  2. {
  3.      container-script:”arbitrary Javascript”
  4.      container-width:”…”
  5.      container-height:”…”
  6.      rectangle-attributes:”Javascript Associative Array”
  7.      left:”arbitrary Javascript”
  8.      horizontal-center:”…”
  9.      right:”…”
  10.      width:”…”
  11.      top:”…”
  12.      vertical-center:”…”
  13.      bottom:”…”
  14.      height:”…”
  15. }

An prototype implementation has been coded as a Chrome extension, and to get this:

you code CSS like this:

  1. @layout-policy pack_column {
  2. container-script: "\
  3. var margin=container.em(0.5);\
  4. ";
  5. rectangle-attributes: "{\
  6. 'topOffset':0\
  7. }";
  8. horizontal-center:"container.width/2";
  9. top: "rectangle.topOffset+margin\
  10. +(predecessor ? predecessor.bottom : 0)";
  11. container-height: "margin*(rectangles.length+1)\
  12. +rectangles.height.sum+rectangles.topOffset.sum";
  13. container-width: "2*margin+rectangles.width.max";
  14. }
  15. @layout-policy override {
  16. container-script: "\
  17. var margin=container.em(0.25)\
  18. ";
  19. horizontal-center:none;
  20. left:"margin";
  21. }
  22. @layout-policy pack_row {
  23. container-script: "\
  24. var margin=0;\
  25. ";
  26. vertical-center:"container.height/2";
  27. left:"margin+(predecessor ? predecessor.right : 0)";
  28. container-width:"margin*(rectangles.length+1)\
  29. +rectangles.width.sum";
  30. container-height:"2*margin+rectangles.height.max;";
  31. }
  32. .body {
  33.     layout-policy: 'pack_column';
  34.     position:relative;
  35.     border:1px black dashed;
  36.     padding:0px;
  37. }
  38. .container {
  39.     layout-policy: 'pack_row';
  40.     container-script: "margin=container.ex(2);"; /* apply a margin */
  41.     position:absolute;
  42.     border:1px black solid;
  43.     padding:0px;
  44.  }
  45. .container1 {
  46.     layout-policy: 'pack_column override';
  47.     width:130px;
  48.     position:absolute;
  49.     border:1px black dotted;
  50.     margin:0px;
  51.     padding:0px;
  52.  }
  53. .text {
  54.     position:absolute;
  55.     border:1px black dashed;
  56.     padding:0px;
  57.  }
  58. .extension {
  59.     rectangle-attributes: "{\
  60. 'topOffset':'container.em(1)+margin'\
  61.    }";
  62.     width:200px;
  63.     padding:10px;
  64.  }

Huh. What do you think?

Posted by Dion Almaer at 11:46 pm

1.9 rating from 62 votes


Comments feed TrackBack URI

Great!! I’ve been touting about this type of approach to CSS before (just on an idea level), and even thought of coining it JSS (JavaScript Style Sheet). I think Darrel Karisch has managed to make this approach work very well though, combining the power of CSS and extending it with JavaScript.

I’m up for it!! Great work :)

Comment by GlenSomerville — July 17, 2009

I get not-so-fond memories of Microsofts CSS Expressions, which are buggy, insecure and drains performance like nothing else.

If we’re going to extend CSS, the list of improvements before we get to scripting would be rather long in my opinion.

Comment by MorganRoderick — July 17, 2009

Very interesting and really helpful. Thanks.

Comment by stoimen — July 17, 2009

Too much words. Where’s the information? It’s just that DOM interface details are not essential to understand what this thing is and how it’s supposed to operate.

The approach of constraint satisfaction is sound, but eventually, the layout is going to be overconstrained if you don’t pay special attention (see the Auckland layout model for the details).

On a related note, why bother with CSS for layout at all? Let’s stop fighting CSS semantics (a restricted form of attributed grammar — yes I believe it is) and define another DSL, for the specific task of layout.

What do you want from CSS? Cascading and flow. What do you want from layout? Constraint solving, self-contained elements and a way to painlessly combine them (nest, place one on top or on the left of another, etc.). The goals are contradictory. :)

Does anybody know whether going ahead and implementing your own constraint solver is any better than trying to retrofit the one built-in in CSS?

Actually, I suppose we can get away with a DSEL in JavaScript. Any takers?

Comment by chiaroscuro — July 17, 2009

CSS should be light weight and fast to parse. JavaScript isn’t CSS… And it shouldn’t be for a reason

Comment by V1 — July 17, 2009

Those who do not remember the past are condemne to repeat it:

Comment by JChung2008 — July 17, 2009

css3 already specifies a layout system, and this code is pretty stable:
The more people use it the more likely browser user agents implement it natively.

Comment by Rusco — July 17, 2009

It looks awful. I can’t (and would rather not) imagine trying to maintain that.

I’m all for adding more semantics to CSS, but tacking JavaScript onto it is not “extending” CSS. It’s befuddling CSS.

Comment by willbo — July 17, 2009

Yes, it looks hard to do and maintain that.

I prefer wait for CSS3 layout system.

Comment by Jerusalem — July 17, 2009

Even if it’s technically an amazing thing, mixing JS and CSS is a bad idea ! They do not achieve the same purpose. People that write CSS stuff are not necessarily people that write JS stuffs. And by the way, what about security concern !

I strongly prefer the CSS3 Template Layout Module, which could be used thanks to a JS implementation by Alexia Deveria

Comment by Jeremie — July 17, 2009

All of these layout proposals floating around lack simplicity. What we’re looking for is being able to size things to the “remaining width or height”, after all the margins and padding and so on are applied.

The simplest proposal I’ve seen that did that was to add “%%” sizing. So, if you said an element was “height: 100%%” that meant it would take up 100% of the remaining height after laying out the other elements in its container.

If I just had that, combined with “float:top/bottom”, then I could do all the layouts I need in pure CSS.

Comment by Joeri — July 17, 2009

At first glance, this looks like a lame attempt at reproducing Silverlight.

Comment by tiengow — July 17, 2009

Why! This makes baby Jesus cry. Keep the three layers separate.

Comment by RichardJohn — July 17, 2009

The Ajaxian code block should ditch the line continuation backslashes and (failed attempt at) syntax highlighting. It makes it seem more confusing than it really is. The key in this is reusability of these behaviors so you could drop this into a project for layout w/ little worry, but still the taste of CSS expressions will (and maybe should) sour people on the idea.

Comment by mrclay — July 17, 2009

How about no?

Let’s not start repeating Microsoft’s mistakes, ummkay?

Comment by mdmadph — July 17, 2009

@Darrel Karisch

Get out.

Comment by Darkimmortal — July 17, 2009

I thought we knew this was a bad idea. Is it April Fools Day?

Comment by AaronHeckmann — July 17, 2009

Microsoft introduced a similar feature (CSS Expressions) about 10 years ago, which it has since abandoned (for good reason). The cost of using this approach (performance and maintainability) don’t justify the benefit.

Comment by WillPeavy — July 17, 2009

No. CSS == Cascading Style Sheet. CSS != Cascading Style Script. It’s a set of static properties. If you can’t accomplish something with CSS, you need to learn to use it better or reconsider your design.

Comment by mjuhl — July 17, 2009

Putting this into script makes me skittish, since it can’t interact with the browser’s (potential) caching and batching of layout operations. Something more along the lines of a constraint language seems equally powerful:


Comment by slightlyoff — July 17, 2009

No CSS! Good god man!

Comment by cssgallery — July 17, 2009

been there done that 1/2 a year ago:

Comment by mattprokes — July 18, 2009

I’m with pretty much everyone here. CSS is suppose to be simple, with one clear job, mixing in JavaScript into it is a bad idea.

Comment by iliad — July 19, 2009

What a hideous mess! Whatever happened to separation of design and code?


Comment by Zoob — July 19, 2009

I DO accept anything that help me to avoid creating 8 nested div to build a simple rectangular container with artistic stuffs.

Zoob > Writing javascript does not mean that you’re “coding”. A javascript code that create 7 nested divs in my container is a part of my “design process” and there is no mixes between design and code.

And finally, the fact that Microsoft failed to implement this aspect correctly do not means that it’s impossible to implement correctly.

I think that this is a interesting feature.

Comment by manitra — July 20, 2009

Constraint cascading style sheets as referenced by slightlyoff is clearly the right direction for an all-inclusive resolution to the weaknesses in CSS. It’s unfortunate that it has not gained more attention and traction in the community.
had CCSS been adopted ten years back, we would have a much better platform for the web.

Comment by dkarisch — July 20, 2009

there is a fear that javascript in CSS opens up a vulnerability to XSS attacks.

this discussion in google’s chromium-dev group addresses the issue…

this layout proposal is not vulnerable to XSS attacks as there is no DOM in its execution environment.

the CSS3 template layout is fine… so is the multicolumn layout. their emergence is a testimony to the inadequacy of the CSS layout solution. the spec is monolithic, attempting to be everything for everybody. the result is an increasing number of often incompatible attributes. this is an unfortunate side-effect of a monolithic design.

furthermore, the spec seems to be geared for those in the print layout community as indicated here…

application layouts often have different layout and resize needs for which CSS is ill-fitting or inadequate.

as to whether JavaScript should be included in CSS at all appears to be an ascetic issue for many here. this may sound harsh, but these Luddite arguments are void of rationality. perhaps it is understandable to not expect anyone with weak programming skills to support JavaScript inclusion in CSS.

this proposal attempts to take this into account, whereby a layout policy can be predefined and then merely used by reference by those who are confused or insulted by JavaScript.

performance is always an issue. this issue would have to be addressed in actual implementations. To dismiss the proposal on these grounds is premature and a bit presumptious.

Comment by dkarisch — July 20, 2009

I should have stated that it’s an esthetic issue for some although I cannot rule out that some may object on ascetic grounds :)

Comment by dkarisch — July 21, 2009

There’s already a solution for this. It’s called tables.

Comment by nsrmbo — July 22, 2009

html tables are not a generalized solution for layout.

Comment by dkarisch — July 22, 2009

Leave a comment

You must be logged in to post a comment.