The question is: can CSS stylesheet be applied in the server-side ? And if yes, would would be the purpose ? I should say yes, they can and i would explain how and why. So what for are stylesheets ? “Applying cascading styles onto the DOM” may be the answer. But i would focus more on that why actually stylesheets are used for such purpose?
- Because they are clean ?
- Because CSS selectors do so much job, that besides them only really needed things are simple properties with obligatory number of arguments ?
- Because cascading inheritance is just right for the DOM ?
- CSS selector are simply benefiting from DOM structure’s nature
So first thing which needs to be implemented on the server is the DOM. When we already got it, so we can query it thou selector, that’s the first half. Now the properties. What could be the property on the server ? border-color ? Rather not. Do we need to style the DOM on the server ? Is it shown anywhere ? Not right now. On the server, page’s DOM is being build. Typically by various ways of string concatenation.
So if we need to build a DOM and same time we can query it with selectors, then the style’s properties should build / modify it’s structure. For example, show some articles or blog posts on the page. So here is pure CSS parser-validable code with some proposed server properties.
.section.articles ul > li {
/* loop "articles" variable as "article" using "num" as index
after that remove all other-than-first LIs */
loop-one: articles num article;
/* apply filter method on next variable output */
vars-filter: htmlentities;
/* use "article" fields and populate them inside nodes
matched by ".a-%k" where %k is field name, eg .a-title */
vars-to-selector: articles var(articleFields) null ".a-%k";
/* example custom method to adding class for 1st loop node using index "num" */
add-class-to-first: num custom-class;
}
/* show .comments node if variable articleComments is true */
.comments {
if-var: articleComments;
}
/* bubbled event */
.section.articles:inserted {
/* another custom method */
/* null means 0 arguments */
strip-tables: null;
}
So what have we done here ?
- We simply build articles loop which prints it’s contents into proper child nodes automagically. It could have 3 fields or 345, but line in CSS is only one.
- We’ve also used a custom method do add class basing on the loop position.
- Comments presentance is conditional.
- One Mutation Event is used. Hidden in :insert pseudoclass, really named DOMNodeInserted will apply on all new nodes which matches prior selector and were just inserted into the DOM structure.
- Each unspecified event defaults to :load.
All properties should be simply methods which applies something on all matched nodes. Sound familiar ? That’s exactly what many of jQuery methods are doing. Take a look:
.section.articles {
remove-class: section;
attr: rel section;
/* all css properties can be used
but will result in inline "style" attributes */
css: padding 2px;
}
/* this rule applies to all load-time nodes
and the new one too */
.change-me,
.change-me:inserted {
text: "changed innerText";
prepend: "
<div>changed</div>
";
remove-class: change-me;
/* reallocation, interesting... */
insert-into: ".content";
/* passing some data to forward ? */
data: some-flag "some value for developer";
}
All from above properties are jQuery methods. Possibilities are huge. But let’s stick with simple things right now. How would it benefit ? Who will write those server-css-sheets ? I should say…
Designers
In opinion of someone, Designers doesn’t care about anything other than CSS stylesheets. I could agree with such statement. Now i would like to show you a simple but quite complete example of (again) simple webpage made almost entirely using Designer-friendly style.
That means much CSS, much HTML and small amounts of copy-and-paste code :)
Let’s start with the index.php file. I’m basing this example on QueryTemplates, a templating engine i’m currently working on. More on that later, now let’s see our files map:
our-site/
- templates/
- – page1.html
- – page2.html
- – page3.html
- index.php
index.php
include "data.php";
$dir = dirname(__FILE__).'/';
try {
require template()->parse($dir.$_REQUEST['page']);
catch (Exception $e) {
require template()->parse($dir.'404.html');
}
Simple and catch’y ;) Who would not know what is this doing ?
page1.html
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link type="text/css" href="server.css" rel="server-stylesheet"> <link type="text/css" href="document.css" rel="stylesheet"> <title>Insert title here</title> </head> <body> <h1>My Articles</h1> <div class="section articles"> <ul> <li> <div class="a-title">Lorem Ipsum Title</div> <div class="a-body">Lorem ipsum body</div></li> <li> <div class="a-title">Second row title</div> <div class="a-body">Second row body</div></li> </ul> </div> </body> </html>
Code above has a completely destroyed indentation coz of wordpress, but it should be clear. Only purpose of second row is better preview of the page1.html file directly in the browser. Noticed this server.css link ? Remember about that. Now the last piece.
data.php
$articles = array(
array(
'title' => 'My first article',
'body' => 'Some body contents'
),
array(
'title' => 'My second article',
'body' => 'Some body contents'
),
);
$articleFields = array_keys($article[0]);
Some simple data. Could be also a JSON as more user-friendly and less platform-related format.
server.css
.section.articles ul > li {
loop-one: articles num article;
vars-to-selector: articles var(articleFields);
add-class-to-first: num custom-class;
}
Stylesheet above, which simply loops our articles over UL list, will be parsed on the server and then removed from the DOM.
Let’s back to benefits. So:
- designers will write more CSS
- will have more control over templates
- will be able to realize simple tasks by themselves
- this also applies to all tasks implemented as custom methods
- there will be preview ready template sources to show to the client (in all stages of developement)
- to add more stylesheets, only needed thing is to add them as normal documents CSS stylesheets, no code-level changes would be needed.
But would it be sufficient for all app’s templates ? Or would it mean that all templates have to be implemented as CSS stylesheets ? I think this would be a disaster if we could not use real code for the templates. Remember this “template()->parse()” line ? Now after the parse() we can continue the chain in jQuery manner. We can query to multiple level and revert stack by the end() methods. We can also, same as CSS stylesheets, bind to an events, which i covered in previous post. Also those custom methods used in stylesheets (like eg add-class-to-first) have to be written by developers. There is definitely more possible things to do using code, than a stylesheet. Most important is, those two ways doesn’t preclude themselves. Everything finally ends on the DOM. And i think that’s the way it should be when it comes to dynamically created webpages.
What about AJAX ?
So we’ve got simple chains which can be written as CSS properties. Now why not to applie them on the same DOM, using same code ? But instead of compiling template to server-side language, let’s make it a JavaScript one. That’s perfectly possible and QueryTemplates is doing this today. But the data is still platform-dependant. Let’s make it a JSON. From a database for example.
articles.json.php
// DB fetch $json = array( 'articles' = $DB->articles(), 'articleFields' => $DB->article->fields(), ); QueryTemplates::jsonToScope( QueryTemplates::toJSON($json); );
To use such template inside a browser we can utilize even old-school script includes, like this:
<head> <script type="text/javascript" src="articles.json.php"></script></head> <body> <script type="text/javascript" src="index.php?page=page1.html"></script> </body>
This way of dealing with templates would be much better suiting team work and outsourcing companies. Also preparing many products on similar code/markup base become much more robust.
Another question is: can we use some of this on the browser ? AJAX, again ? Below i’m presenting something not so deeply thought. but it seems to be accomplishable and maybe even usable.
Loosy mockup: browser.css
/*
#ajax pseudo-id will limit scope of rules to apply only for AJAX responses.
*/
#ajax[url^="/forms/singup"] .change-me {
border-color: 2px;
}
#ajax > .sidebar > * {
insert-into: ".sidebar";
}
#ajax > .sidebar {
remove: null;
}
/* there is no .sidebar in the #ajax anymore */
#ajax > * {
insert-into: ".content";
}
/*
All below will also work for AJAX reponses.
*/
.article button:click {
handler: alert "sometext as arg";
/* all css will be converted into inline styles */
border-color: 2px;
}
.article .title:inserted {
/* attach method to mousein event */
handler: mousein GUI.showLayer "layer name";
/* trigger onclick event */
trigger: click;
/* wont trigger handler below, because it's not attached yet */
}
/* attach method to onclick event */
.article .title:click {
map: GUI.findAnimatedParts;
each: GUI.animate;
}
.article a.show-me-more:click {
/* new method */
load-append: "/articles/more .articles";
border-color: 2px;
}
/* context switching */
.article a.show-me-more:click {
/* null means 0 arguments */
/* this is actual stack */
parent: null;
/* possible delegation root ? */
delegate-to: this;
append: "
<div>New element inside parent</div>
";
end: null;
}
.article a {
filter: method(GUI.filterArticleAnchors);
add-class: my-filter-result;
end: null;
/* this is quite crazy! */
parent:;
next:;
add-class: 'nextone';
end:;
end:;
}
Stylesheet above behaviorizes the DOM. It realizes such functions as:
- AJAX handling
- Events Delegation
- jQuery interface in CSS
Let’s tidy this idea. Look at this diagram. It shows how various CSS stylesheets could be applied into
Document’s Lifecycle
Looks complicated but it really isn’t. It simply means this things:
- Server level CSS stylesheets
- Are applied as many-to-many on templates sources thou template’s DOM
- Are used to transform and prepare markup
- Can also be used for easy patching some small bugs
- Document level stylesheets
- Used to style content visually
- Brower level stylesheets
- Used to add behaviors to document
- Handles also AJAX requests
- Can also easily transform DOM
That would be all folks. I know it can look crazy, but i think worth checking out. Hope you understood the idea, if not – please post some questions. If yes, feedback is also appreciated :)
Important notice: most of the code in this post is just a mockup, it’s not yet implemented. You can follow server-side implementation in this ticket. Meantime if you would like to play with DOM and CSS driven templates on the server download QueryTemplates for PHP.

[...] which is generated as a real template. I just can’t wait to start implementing CSS interface i wrote before. Additionaly, as JavaScript version is out, there can be some use for jQueryServer. Possibly [...]
I’d been discussing something like the above Server-side CSS transformations with some friends for a while. I’d be interested in knowing how it’s progressing and what I could do to help.
Keep up the great work.