Selector Subtleties

If you have no idea what the title of this blog entry means, chances are that you are not a web developer. Fee free to skip to the next article in this case. We are going to discuss CSS selectors and how they may be used to streamline web development. Traditionally, CSS selectors are used to create logical groups of visual styles which are applied to HTML elements. You could think of selectors as patterns that are matched against a set of tags in a web document. We are considering both CSS 2.1 and CSS 3 selector syntax and functionality, while keeping in mind that the latter is not fully supported by all current browsers. Notably, the Internet Explorer took 10 years from the publication of the CSS 2 specifications in 1998 until the release of IE8 in 2008 with full support for CSS 2.

A proper understanding of selector pattern matching has become more important with the advent of jQuery, the most widely used Javascript library today, that employs CSS selector syntax for DOM element addressing, traversal, and manipulation. Once you have worked with jQuery and its powerful "query by selector" engine, using the conventional DOM document methods, such as getElementById(), feels a bit like operating an unwieldy steam engine. You would not want to go back. It also brings CSS syntax to the world of scripting. Using jQuery effectively, however, requires a fairly good command of some of the more complex CSS selector expressions, understanding the new CSS 3 selectors, and learning a few selector expressions specific to jQuery. But let's start at the beginning with the three most simple and most commonly used CSS selectors:

a { color: orange; }
#orange { color: orange; }
.orange { color: orange; }

The first is a type selector. It assigns the colour orange to the text colour of all anchor tags (links). The second is an id selector. It assigns the colour orange to the HTML element with the id "orange". The third is a class selector. It assigns the colour orange to all elements which have an "orange" class attribute. These three are the bread-and-butter selectors that probably make up 90% of all selectors in CSS style sheets. Tag selectors are typically used for global style settings that apply to a large number of web pages, for example to set the font type for a website. The id selector is typically used in combination with specific layout elements, such as containers or form fields. The class selector is typically used to style elements repetitively in the same manner. These selectors can be combined. For example:

a.orange { color: orange; }

This will set only anchor tags with the CSS class orange to orange text colour. Other anchor tags and other types of tags with the CSS class "orange" set are not affected. Combining multiple selectors in order to match document structure is an important skill that -if mastered- allows you to create efficient and maintainable style sheets. Incidentally, it also makes a good recruiting question for web developer candidates. Can you tell the difference between the following three combinations?

.footer.orange { color: orange; }
.footer .orange { color: orange; }
.footer, .orange { color: orange; }

The first selector matches elements that have two class attributes named "footer" and "orange". The second selector matches elements with the class "orange" that are descendants of an element with the class "footer". The third matches all elements with either the class "footer" or the class "orange". In other words, these selectors express three different types of relationships: logical and (written together), descendant (separated by blanks), and logical or (separated by comma). In geek speak, these are called combinators. There are a few more combinator thingies, although the following are lesser known and used:

#footer > .orange { color: orange; }
#footer + .orange { color: orange; }
#footer ~ .orange { color: orange; }

The angle bracket denotes child relationship. The first example matches all elements with the class "orange" that are children (=immediate descendants) of the element with the id "footer". The plus sign means adjacent sibling. Line 2 matches elements with the class "orange" that are immediately preceded by an element with the id "footer". The tilde denotes a general sibling combinator. The third example matches all elements with the "orange" class that are siblings of the element with the id "footer". These combinators are sometimes handy for formatting lists. The next group of selectors we are going to take a look are attribute selectors. They match elements by attributes and are equally useful for processing HTML and XML documents:

div[class] { color: orange; }
div[class="orange"] { color: orange; }
div[class~="orange"] { color: orange; }
div[class^="orange"] { color: orange; }
div[class$="orange"] { color: orange; }
div[class*="orange"] { color: orange; }

Line 1 selects all div elements that have a class attribute. Line 2 selects all div elements whose class attribute is set to "orange". Another good test question: how is this different from the class selector .orange? Answer: It only selects those elements where the class attribute exactly matches the word "orange". For example, the element <div class="orange fruit"> is not matched. This one is matched by the selector in line 3, however, because ~= matches all div elements where the class attribute contains a whitespace-separated list of words, one of which is "orange". The latter is functionally equivalent to the class selector .orange. Line 4 matches div elements whose class attribute begins with "orange", line 5 matches div elements whose class attribute ends with "orange", and line 6 matches div elements whose class attribute contains the string "orange", such as <div class="all-orange-fruits">.

We go on to the so-called pseudo classes and pseudo elements that provide useful matching techniques for dynamic manipulation in response to user interaction:

div:hover { color: orange; }
input:focus { color: red; }
input:enabled { color: green }
input:disabled { color: grey }
input:checked { color: blue }

Line 1 matches a div element during the time the mouse  pointer is on it (the "rollover" effect). Line 2 matches a form input element that has the focus (the time during which data can be manipulated with the element). Line 3 matches all enabled input elements and line 4 matches all disabled input elements. Line 5 matches a checked form element, such as a radio button or a checkbox. Question: how can you match an unchecked element? The answer is: you need an additional selector. Unchecked elements can be matched by combining the :checked selector with the :not selector, which -strictly speaking- operates like a combinator:

input:not(:checked) { color: yellow; }

You can of course put any valid CSS selector or selector combination into the parentheses of the :not() selector to create more specific and more complex expressions. Finally, there are a number of pseudo class selectors that relate to the DOM tree structure which may be useful for manipulating DOM (in combination with jQuery, for example). The three following lines  match the first, last, and third children of all div elements, respectively:

div:first-child { color: pink }
div:last-child { color: silver }
div:nth-child(3) { color: purple }

Although we have not enumerated all CSS selectors here, the ones we have covered are probably the the most useful and most often used ones. For a complete reference, see the W3C specification for CSS selectors.

To inline or not to inline

As every web developer knows, there are three ways to apply CSS styles to a document. One can use a separate style sheet in connection with the <link> tag, one can embed style definition block(s) directly in the HTML document, or one can inline CSS using the style attribute with single HTML tags. These three approaches represent different (descending) levels of separation. The last method, inline CSS, is somewhat peculiar, because it appears to defeat the principle that CSS is founded upon, namely the separation of content of presentation. After all, writing something like <span style=”font-style: bold”>something</span> ist just another -more cumbersome- way of writing <b>something<b>.

Hence, the question arises: why use inline CSS at all? The naive understanding is that only external style sheets are “good” and that inline CSS and embedded CSS styles are “bad”. It may not be a bad idea to reflect on the criticism and ask the obvious counter question: why did the designers of CSS provide for the possibility of inline styles if it was evil to begin with? Are CSS inline styles the equivalent of the infamous “goto” command?

The truth is that, despite the overarching goal of high level of abstraction and presentation separation, there are some legitimate uses for inline styles. To be precise, there are two such cases. First, inline CSS is appropriate when the default styling, as specified by one or more style sheets, needs to be overridden in specific instances. Second, inline CSS is appropriate for micro-styling issues that relate to specific HTML structure of a document. The first use case is easy to understand. For example, you have all your links defined to be blue and non-underlined using the appropriate definitions in a style sheet. There is one point, however, where you want the link to be green rather than blue. Use an inline style in this case.

The other case requires some explanation, and to be frank, some experience in web design as well. What I have called micro-styling issues are layout issues related to the specific sequence of HTML, text, and images in a given document. These are instance-specific issues that don’t repeat. The vast majority -probably over 90%- of these issues concern spacing and text flow. A typical example would be to adjust the vertical and horizontal spacing between adjacent elements using the float, margin, and padding styles. A somewhat less typical example would be setting the width of columns or text paragraphs in specific instances, or make the corners of an outlined box rounded using CSS 3 styles.

In summary, inline CSS is appropriate wherever styling is specific to the document. This could be the case if default styles must be overridden or if custom layouts require micro-styling. However, if you find yourself repeating the same style tags in many different places, there is something going wrong. As soon as a you see a pattern emerge, refactor! Withstand the copy-paste coding temptation. It is easy to generate code that way, but very hard to maintain. Create classes or appropriate selectors instead and move the definitions to an external style sheet.

Let’s look at a typical border case. Say, we use tables to contain form elements in our web application in order to arrange form controls and labels into columns and rows. Typical micro-styling issues, such as managing white space between specific columns can be solved with inline CSS. If we find that certain spacing definitions repeat, for example if we want all form rows to have a five pixel bottom padding, then this situation would call for a CSS style sheet definition.

The quintessence is: the DRY principle also applies to CSS. While the overall goals of CSS are separation of content and presentation, abstraction, and ease of maintenance, and while the use of inline CSS generally counters these goals, inline CSS is appropriate for the mentioned purposes. It takes a bit of experience to know when it’s OK to break the rules and when it is not.

HTML5 Shaping Up

HTML 5It's been a while since I last wrote about the upcoming HTML5 standard -two years to be precise- and a lot has happened since then. Not only has the W3C (World Wide Web Consortium ) draft moved closer to the finishing line, but quite a bit of the HTML5 package is already implemented and ready for deployment in modern browsers. Regarding the completeness of HTML5 support, Google Chrome is currently leading the pack, followed closely by Firefox, Opera and Safari. Even Microsoft seems to have discovered the advantage of standards compliance, as its upcoming IE9 includes support for several new HTML5 features. If you are a web developer and haven't delved into the details of HTML5 yet, now is the time.

As many web developers spend more time coding server side languages than coding HTML, they might think about HTML programming as a secondary skill. However, this contains the misconception that the new HTML5 standard is just about angle bracket tags. – It is not . – HTML is the heart wood of web programming and the upcoming HTML5 standard is the most comprehensive update that web developers have seen since the days of Mosaic. In this article, I am going to summarise some important points about HTML5 that every web developer should understand before moving on to the technical details.

HTML5 is not just about markup. Although the new HTML5 standard contains new tag definitions and deprecates old ones, the package goes far beyond markup definition. It does not just define new tags with new functionality, but it also defines the accompanying APIs in unprecedented detail. It contains diverse features for audio and video playback, 3D imaging, drag-and-drop, new form elements, a canvas element for 2D drawing, offline database storage, document editing, geolocation, microdata for semantic markup embedding, and CSS3, the next level of the cascading style sheets standard.

HTML5 is not going to be released with a drum-roll. The HTML5 specifications have been developed by the Web Hypertext Application Technology Working Group (WHATWG) of the W3C since 2004. The first public working draft was published in 2008. The specifications are considered an ongoing work and are expected to reach candidate recommendation stage within the next two years. In the meantime, the parts of the specification which are considered stable are being implemented by browser developers. Thus HTML5 is expected to reach the market in gradual steps over a number of years.

HTML5 is not all-or-nothing. Indeed, there was never an all-or-nothing scenario, even with prior versions of the HTML standard. Browser detection software typically doesn't test for HTML version support, but for individual features, such as support for a certain DOM level, API constructs, or specific feature implementations. Because HTML5 is a bundle of (largely independent) features and APIs, it will be no different with HTML5. For example, geolocation does not rely in any way on 3D imaging, the canvas does nor rely on drag-and-drop, and so on. Application developers can make use of these features without having to worry about HTML5 support on a whole.

HTML5 is designed with backwards compatibility. Upgrading your web pages to HTML5 might be as easy as replacing the HTML4 doctype tag with the HTML5 doctype. Chances are that all tags in a typical page -if they weren't already deprecated in HTML4- will still work in HTML5. Furthermore, the new standard enhances rather than replaces existing functionality. For example, the <input> tags in an HTML5 form may use the new input types for email, date, and numeric data entry. On older browsers without support for HTML5 tags, these are rendered as regular text input fields. The HTML5 form validation functionality, designed to simplify routine Javascript data validation, is also designed to be degradable in older browsers.

HTML5 is already here. Since the market introduction of HTML5 occurs incrementally,  many features are already available in up-to-date web browsers. For instance, semantic markup, canvas, and basic audio and video playback are already supported by the latest browser versions. One can safely assume that the upcoming Firefox 4 and IE 9 releases will put even more HTML5 features at the developer's disposal. Go to http://html5test.com to check your browser and find out which new features it already supports. See http://www.html5rocks.com for an interactive presentation, as well as in-depth tutorials and code examples of the new HTML5 features. Finally, a list of websites that already makes use of HTML5 (and ideas what it may be used for) can be found at http://html5gallery.com.

Gimme Gadgets

There are quite a few reasons to like gadgets. They are usually free and open source by design. They use standard web technologies, such as HTML, CSS, and Javascript. They are -at least in principle- platform-independent and portable. Perhaps most importantly, they are easy to program and deploy, which makes them ideal for small personal applications. I am thinking about keeping oneself informed about the scores of one's favourite sports team, displaying local bus schedules, or aggregating social network feeds into a custom-designed widget that sits on the desktop. I am sure that every computer user can come up with an idea for a mini-application that they always wanted but never found. Gadgets are the obvious solution, as they have web connectivity and web technology built in.

The first question for the budding gadget developer is then which gadget
technology to choose. In an ideal world, there would only be a single standardised package format and only a single standardised API. This would allow gadgets to be used on any platform and the question of choosing a format would not even arise. Alas, we don't live in an ideal world and therefore different platforms and markets have produced different gadget formats. For example, there are Windows desktop gadgets, Linux desktop gadgets, Google gadgets, and gadgets designed to be integrated into web portals. We will look at the different types of gadgets and their use in brief.

Windows Gadgets

Formerly known as Windows sidebar, Windows gadgets are based on the widget engine for Microsoft gadgets, which runs on the Windows platform only. A minimal gadget contains an XML configuration file (gadget.xml) and an HTML file (main.html). Other web files can be added. These are zipped for distribution and the resulting file is renamed to *.gadget. Windows gadgets have access to a special API divided into three parts. 1. Gadget objects provide gadget state and event handling. 2. System objects provide access to files, network and OS functions. 3. Presentation objects provide visual functionality, namely background, image, and text handling. Many Windows desktop gadgets can also be run (with slight modifications) inside a Windows Live homepage. The latter don't have access to the system API and cannot modify the page's DOM object tree.

Apple Dashboard

Dashboard is an application that hosts widgets on a Mac Computer. The widgets are contained in an invisible layer that is activated by clicking on a dock icon, or by pressing a key. Like Windows gadgets, Dashboard widgets are based on standard web technologies. A typical dashboard gadget contains six files: a property list and a JavaScript containing the interactive functionality, and HTML and CSS files, a background image and an icon for the visual design. Dashboard implements a client server architecture with widgets running as clients. There are three classes of Dashboard widgets: Accessory widgets that are self-contained mini-applications like clocks, calculators, etc., application widgets that interact with an existing Mac application, and information widgets that retrieve information from the Internet.

Google Gadgets

As is the case with Windows gadgets, Google gadgets come in different flavours. They are based on the Google Gadget API and run inside an iGoogle page or can be embedded into any web page, usually by loading content from a remote server. Google gadgets can also be run on the desktop if the Google Desktop product is installed, which is a bit of a downer, because Google Desktop also contains desktop search functionality that constantly indexes your PC's filesystem and allows text searches on all of your files. The good news is that the latter functionality can be disabled. Furthermore, there are Google gadgets with enhanced capabilities for the (recently decommissioned) Google Wave application. Like Windows gadgets, Google gadgets consist of XML, HTML, JavaScript (lots of it) and other web files. The advantage over their Windows cousins is that Google gadgets are more platform-independent, since Google Desktop is available for Windows, Linux and Mac. Reusing web gadgets for the desktop (or vice versa) is also easier. The Java-like Google Gadgets API provides methods in the gadgets.* namespace for IO, string and JSON processing, skinning, and other functions. Developers can use the iGoogle gadget editor and gadget testing environment for creating gadgets.

Yahoo Widgets

Google's competitor Yahoo also offers a gadget technology called Yahoo widgets based on the Konfabulator product. Yahoo widgets are primarily intended to run on the desktop rather than inside a web page and to that end, users must install the Yahoo widget engine. Unfortunately, this product is closed source and only available for Windows and Mac. Like their cousins, Yahoo widgets are comprised of XML, HTML, JavaScript, CSS (and optionally Flash) and are zipped into a single *.widget file for distribution. The comprehensive Yahoo Widgets API includes functions for event-driven GUI programming, DOM processing, downloading web pages, and access to Yahoo services. It is even possible to create and use an SQLite database with Yahoo widgets or access OS-specific functions by running shell scripts on Windows or AppleScript on the Mac.

Linux/Unix Gadgets

There is a variety of widget engines available for Linux and the market seems to be highly fragmented. For the already mentioned Google gadgets, Linux users can download the open source Google-Gadgets-For-Linux software that allows Google gadgets to be run without Google Desktop. In addition, there are the following widget engines, among others, for which a limited choice of existing widgets is available:

Gdesklet – is a Gnome program for running gadgets on a Linux desktop. Despite its name, it can be also be used with other Desktop managers other than Gnome, like KDE or Xfce. Desklets are applets programmed in the Python language.

SuperKaramba – is a widget engine for the KDE desktop. The visual aspects of a SuperKaramba widget are specified in a text file, while its functionality can be programmed in either Python, Ruby, or JavaScript.

Screenlets – is a X11/Compiz-based widget engine that is independent of the desktop environment. It supports Python applets with skins drawn in SVG and -more recently- web widgets written in HTML, CSS and JavaScript.

Frameworkless Architecture

Perhaps suggesting to eschew web frameworks for web application development is playing the devil’s advocate. Perhaps it is even foolish. To renounce the productivity boost one gets with a properly designed framework does not sound like sensible advice. Only ignorant script kiddies entertain such ideas. Well, for the most part that is true. A web framework does indeed simplify application development if it is chosen well. It does even more if it is designed well. It can provide architectural support for building maintainable applications. It can help with the plumbing and provide conceptual structure to guide the development process.

So, what speaks against using a web framework? Plenty actually, especially at the lower end of the spectrum and especially with dynamic languages. The main problem with web frameworks is that they add overhead. This means that the added functionality and structure is bought at the cost of performance degradation. The graveness of this problem depends on the system architecture. One  needs to keep in mind, that dynamic languages are interpreted at runtime, which makes them CPU-intensive and relatively slow. Because the life cycle of a script is essentially stateless and single-step, classes and data structures need to be rebuild and reloaded (in theory) at each request.

In practice, this does not happen, because servers are designed to provide at least rudimentary caching. However, the runtime performance of interpreted languages is typically several magnitudes smaller than that of a compiled language, which magnifies the problem. To illustrate my point, consider these benchmarks for PHP frameworks kindly provided by Paul M. Jones. According to these figures, a trivial PHP page is served by Apache 2 at a performance reduction of 43% compared to static HTML. The use of various PHP web frameworks further reduces performance by 85% – 95% compared to a PHP page that merely echoes content. Although it can be expected that these figures develop inverse logarithmically with increasing application code complexity, the slowdown is significant.

PHP offers a number of remedies, such as  opcode caching, object caching, and products such as Zend Server, APC, and MCache, yet performance is unlikely to get even close to that of a compiled language. Furthermore, there is the question whether the complexity of the project justifies the complexity introduced by a web framework. Would you use a web framework for building a guestbook script? Probably not. What about a blog software? A photo gallery? A bulletin board? These types of applications are the mainstay of dynamic languages, such as PHP. It is the area where PHP really shines. Think of WordPress, phpBB, Mediawiki, Drupal, osCommerce, Coppermine and other popular applications. They all have one thing in common: they don’t use a framework.

Hence, before choosing a web framework for PHP development, it may be worth pondering if any is required. This suggestion may sound a bit contradictory, having just reviewed the Zend framework in a previous article. However, in my own practice I haven’t come across many complex PHP projects. The commercial PHP projects I worked on during the last 10 years can roughly be divided into three categories: 1. extensions and customisations of open source packages, 2. intranet information systems, and 3. e-commerce systems and “catalogware”.

Although the latter two may be considered candidates for web frameworks, the size of these projects was almost always small enough to do without. On several occasions, I chose to implement an “ultralight” MVC architecture by hand instead of using an out-of-the-box framework. The main reason for this was again performance. The “ultralight” approach is defined by implementing only the required functionality, which results in highly specialised design.

In practice, this means slimming the controller, reducing DB abstraction to a thin wrapper around the native library, and foregoing a templating system in favour of embedded PHP. The advantage of this approach is that you get separation of presentation and business logic, componentisation, and customisable control flow without the performance cost of full-blown framework. The disadvantage is that it is slightly more laborious to implement and less flexible. Don’t get me wrong. I have no problems imagining scenarios where I would want to use a PHP web framework such as the Zend framework. However, in these cases I’d probably be drawn towards using Java or (hopefully) Scala in the first place. In summary, I have found myself using PHP mostly in situations where a web framework seemed dispensable, while I have been using Java mostly in situations where a web framework seemed essential.