← home← blog

The Principle of Least Power

26 Sep 2013

Tim Berners-Lee on the Principle of Least Power:

"Computer Science spent the last forty years making languages which were as powerful as possible. Nowadays we have to appreciate the reasons for picking not the most powerful solution but the least powerful. The less powerful the language, the more you can do with the data stored in that language. If you write it in a simple declarative from, anyone can write a program to analyze it. If, for example, a web page with weather data has RDF describing that data, a user can retrieve it as a table, perhaps average it, plot it, deduce things from it in combination with other information. At the other end of the scale is the weather information portrayed by the cunning Java applet. While this might allow a very cool user interface, it cannot be analyzed at all. The search engine finding the page will have no idea of what the data is or what it is about. The only way to find out what a Java applet means is to set it running in front of a person."

The challenge

Consider the following:

I have a <ul></ul> and an unknown number of <li> as children. If there is one child, I want it to be red, else if there are more than one child, I want all the children to be green.

Given the choice of any combination of tech, solve this.

Our solutions

First up, we might go for some server-side rendering with logic wrapped around the output of the <li>.

PHP

The following code would suffice:

ul.multiple li {
	color: green;
}
ul.single li {
	color: red;
}



$arr = array(1, 2, 3, 4);
$klass = (count($arr) == 1) ? 'single' : 'multiple';
echo "<ul class='".$klass."'>";
for($i = 0; $i < count($arr); $i++){
	echo "<li>" . $arr[$i] . "</li>";
}
echo "</ul>";

Messy, no separation of concerns, mixed logic and probably over-engineered.

Template helpers

So, we could do something with Handlebars for example and register ourself a little helper:

Handlebars.registerHelper('oneOrMany', function (value) {
    return (value.length == 1) ? 'single' : 'multiple';
});

Some simple CSS:

ul.multiple li {
	color: green;
}
ul.single li {
	color: red;
}

and the template (in a gist, because for the life of me, I could not work out how to escape hashes in Markdown):

<ul class=>
    
      <li></li>
    
</ul>

Little bit more elegant, can be pre-compiled so it's fairly performant. It's also only using JavaScript for purely presentation logic, so it satisfies our separation of concerns issue.

So, convinced there must be a simpler way to do this, using far less powerful languages (because, as Berners-Lee says, "picking not the most powerful solution but the least powerful"). I consulted some people that were far better, and far more up to date on modern CSS selectors, to see if it could be achieved using CSS only. Crazy, right??

Turns out, it could.

CSS

Harry Robert's solution:

ul > li {
    color: green;
}

ul > li:only-child {
    color: red;
}

Both Harry and my colleague Daniel Grant came to this secondary solution independently. This solution seems to offer greater browser support:

ul > li {
    color: green;
}

ul > li:first-child:last-child {
    color: red;
}

Two pure CSS solutions, boiled down from server-side rendering and intertwined business logic.

Future for CSS

It's exciting times for CSS, we started to see a whole heck of stuff being included and people are pushing the boundaries of CSS everyday.

To quote, this answer on Performance of CSS Transitions vs. JS animation packages from Stack Overflow:

"JavaScript is an interpreted language and the JS engine of the browser has to parse and execute every instruction during run-time (I know there exist JS compilers, like V8 (used in Chrome), but the principle remains the same).

On the other hand, browsers can implement CSS transitions natively, e.g. in C/C++ or something. This code will be compiled to machine language."

So, remember that the most powerful language or tech may not offer the best solution.

If anyone has any other exotic solutions to the above challenge, I'd love to see them.

I'm available for hire

Hire me