“Classy HTML”: A Speculative Design Pattern about Classes and Composition

This is a pattern about Classy HTML.

Classy

ooo posh

No, not THAT “Classy”. This “Classy”:

HTML

No, not THAT “HTML”. This HTML:

The Classy HTML Pattern

Pretty simple: Store important app state as classes in your root (“html”) element.

For example, consider a countdown app. Its significant (from a UI perspective) state can be summed up as being one of three things: “fresh” (app just started), “counting”, “done”. Your app is, in effect, a state machine transitioning between those states according to a set of rules. (Acknowledging that reality and subsequently managing those state transitions with JavaScript can also be an interesting problem ripe for a parsimonious design, but let’s just take that for granted here.)

You would set your HTML class as “fresh” to begin with, and then programmatically switch it over to “counting” or “done” as the app plays out.

Your CSS reflects it:

  1. /* We choose the default case to reflect the most common case, ie "counting" or "done" */
  2. html.fresh .welcomeMessage { display: none; }
  3.  
  4. html.fresh { background: white; }
  5. html.fresh .counter { opacity: 0.3; }
  6.  
  7. html.done { background: red; }

The important thing here is the selector idiom, which can be summed up as “html.state descendentSelector“. We’re styling our classes all the way down, based on the overall application state.

I haven’t done too much of this kind of design, but I can see myself doing more of it as apps get more complex and everything becomes single-state. I’ve been contemplating refactoring the Hacker News Reader along these lines, since (thanks mostly to Paul), it now has sliding panels, and so can effectively be in three states: stories, story (one story above the list of stories), comments (comments above one story above the list of stories).

I guess all this is obvious to CSS design pros, i.e. it’s a natural consequence of the CSS model, but I’ve not thought about doing it much and I mainly got the idea from this FOUC trick, which uses this pattern, but in a very restricted and specific way. The main insight really is that single-page apps usually have a small number of key states which can affect the entire UI.

As with any good pattern, it raises further questions:

  • Should you use “class” or an HTML5 custom “data-something” attributes. I think it’s in the spirit of HTML/CSS to use “class” to represent a state, so that’s fine. And CSS attribute-based support won’t work on older browsers, so that’s another tick for “class”. BUT custom attributes have the distinct advantage that you can be more precise about what kind of state you’re referring to. So while it could just be “data-state”, it could also be “data-phase” or (a boolean) “data-active”. Which takes us to the next question …
  • Should you use more than one type of state? I think for complex apps, yes. And you can then use custom data attributes to manage the type of class. Or you could just use them as a list of free-floating class names on the HTML tag.
  • Should you use multiple selectors, e.g. [data-phase=”counting”][data-authenticated=”false”] to be more precise? In general, I think no. It would lead to ridiculous combinatorial complexity, so it’s better to treat each state variable – if you must have more than one of them – as being orthogonal. That said, there are probably special cases where it makes sense and fortunately modern CSS makes it easy to pull off.
  • What’s the base case? Should it be the initial state or the “typical” state?
  • Looking at the bigger picture, when do you switch pages versus switch states inside the app?

Teaching Maths and Problem-Solving: TED Talk

I just caught this genius talk from Dan Meyer on teaching maths, and more generally, problem-solving. It appealed to me because of the emphasis on learning through concrete things, not abstractions.

Watch for the way students are hand-fed the answers in conventional learning environments. In one case, an otherwise-fine worded problem concludes with a parenthesised reference to a similar problem. In another problem, the ski lift, the modelling is provided at the same time as the question is asked.

Meyer’s main point is that worded problems should feel real, and students should really sit there and struggle with them for a while. He uses the example of a water pump – how long does it take to fill up? Great question, but the typical math textbook presents it in this weird abstract and wordly way:

This is the 21st century, so we can better represent the problem like this:

The whole problem is just a photo and a simple question. Now you have something you can struggle with. Eventually you’ll get sick of talking in long-winded ways about the concepts and you’ll start to introduce abstract modelling. The modelling comes from the conversation, not vice-versa.

But wait, we said this is the twenty-first century, so Meyer goes one better and actually shows a video of the water tank filling up.

Now it’s filling up agonisingly slowly, and all the students have successfully been baited into really wanting to know when will this thing end. They are on equal footing when coming up with intuitive guesses and the mathematical modelling falls from that.

This all reminds me of the tension you’re supposed to feel when reading the problem and forces of a design pattern. You’re supposed to feel a little queasy as you realise how all the forces are in conflict with each other, and then the sense of relief from the answer that resolves the tension.

I’ll finish off with Meyer’s practical tips:

  • Use multimedia
  • Encourage student intuition
  • Ask the shortest question you can
  • Let students build the problem
  • Be less helpful

Events Last Week: Web Fonts, Social Design Patterns, BT Dev Day, Real-Time Javascript

Last week saw a confluence of excellent events. In the same week as a house move, it proved to be a week of much learning and little sleep. I’d hoped to do a better write-up, it never happened, a combination of being too busy and new MAC BATTERIES SUCK, meaning the lappy couldn’t last through the whole session. But fortunately, I have some links to point to. Here’s a quick summary anyway, along with the linkage.

Web Fonts at London Web Standards

@otrops captured the live notes in glorious detail, as did Rob Crowther.

Ben is ideally placed to cover the brave new world of web fonts, being a web maker who studied fonts at uni. He walked us through the evolution of font hacks on the web: image with alt tag; CSS background image with text pushed off the page; rendering with Flash (SiFR); rendering with Canvas or SVG (Cufon, TypeFace.js), using JSON-based font spec data. It all leads up to the holy grail: @font-face.

Great, so we have @font-face, but issues remain: * The foundries – Mark Pilgrim, in no uncertain terms, complains the font vendors are stuck in the dark ages of the printing press, in their resistance to support @font-face. This seems to be changing with WOFF, a web-only format that seems to placate the foundries, who worry their fonts will be stolen. It seems more like a symbolic gesture, since the data could still be converted and in any event the print fonts could still be appropriated, but the foundries are feeling more reassured and making signs they will go along with it. * Performance issue – Bandwidth issues and Paul Irish’s “flash of unstyled text”, where the user notices the font change once the fancy @font-face font has been downloaded. * Compatibility – IE has long supported font-face, but with EOT format fonts, and that remains the case. You therefore need both types of fonts, and licenses will generally not give you both.

Social Design Patterns

I was, needless to say, psyched about this. Yahoo! has been the closest thing to a realisation of the inspiring design pattern vision of the mid-late ’90s. Patterns on the web, for both its own employees and the wider community to learn from and evolve. These are social design patterns mined by Christian Crumlish (@mediajunkie), in many respect the closest thing software has to an analogy of building architecture, where design patterns originally came from.

There are 96 patterns in all and I’m looking forward to poring through them. In these patterns are hundreds of people-years’ experience of observing real-world social systems. In my own pattern work, I’ve found it necessary to articulate the overarching design principles behind the patterns. Pattern languages should be opinionated, so it’s a good thing to make explicit your criteria for filtering design features. Christian has followed this model too, and identified 5 overarching principles:

  • Paving the cowpaths. Facilitating the patterns that are already happening, rather than imposing your own invented process. Also means evolving with your users, ev dogster started as photo sharing but evolved to social network.
  • Talk like a person.
  • Play well with others. Open standards, mashups, etc. “if you love something, set if free”
  • Learn from games.
  • game UI concepts
  • designing the rules, but ultimately letting the people who come into the space finish the experience themselves.*
  • Respect the ethical dimension.

See the wiki or the book for more details.

BT Developer Day

This was an internal conference for BTers in London covering a range of general tech trends, and also being a chance to get together and talk shop. The agenda included talks on Scala, Rails, Kanban, iPhone development, and even a lightning talk from @psd on the horrors and delights of APL.

I gave a talk on Embracing the Web, emphasising open standards and the supreme primacy of Konami Cornification.

Real-Time Javascript

At the Javascript meetup, a great talk on NodeJS and WebSockets. NodeJS is coming on thick and fast, and Makoto Inoue showed how the technology plays nicely with WebSockets. WebSockets are all about Comet-style interaction, so expect to see a lot more of this combo in the next couple years.

Luis Ciprian, visiting from Brazil, gave us an overview of XMPP and talked us through a real-time web app – a basketball score and conversation tracker – using XMPP.

Fin.

Design Pattern: Script Islands

“Script Island” is what I’m calling a design pattern I alluded to here. The pattern is to embed Javascript in your HTML like so:

  1. <script id="greeting" type="x-deferred-script">
  2.   alert("this is my script - it's eval'd on demand");
  3. </script>

When the page loads, the browser should say “I don’t know what ‘x-deferred-script’ is, and therefore ignore the concents of the script tag. You eval it manually later on, using something like eval($("script#greeting").html()); This is similar to Google’s trick of embedding Javascript in comments, but has the additional benefit of keeping Javascript where it should be, in a script tag. This way, it plays nicer with code editors (e.g. Vim happily handles syntax highlighting) and analytical tools. (Technically, those tools should probably do the same as browsers and not treat anything inside a script tag as Javascript, but fortunately for us, they do.)

Script Islands are useful in the following situations:

  • With a complex web app – lots of Javascript – where you want it to load quickly and without lots of processing or round-tripping back to the server. Sometimes, it’s a better user experience to load the lot in one go, show something, and eval() the rest of the Javascript once the basic app is running (perhaps in anticipation of a separate “page” or another part of the application). This is a special case of Predictive Fetch; it makes sense Google would use (a variant of) Script Island for the mobile edition of GMail, where round trips to and from the server are expensive.
  • With a single-page application (SPA) like TiddlyWiki, where all the code is inside the HTML file. Each of the script islands is a separate module, and a microkernel is responsible for loading the scripts according to different rules. For example, the scripts might contain “depends” attributes to declare they depend on other scripts, so the microkernel sequences the script loading. Or another scenario might be that the user has some control over which scripts get loaded; instead of deleting the other scripts from the file, you keep them around in case the user wants to repackage the SPA, with a different set of scripts.

BTW I originally used <script src=""> to trick the browser into not evaluating the script tag’s innerHTML. Thanks to Jeremy for coming up with the more elegant alternative of a type=x-tiddler (which I stated above in the more generic form type=x-deferred-script).

Post-Modern Job Posting: Pattern Curator

It’s cool to see Yahoo! posting a job for pattern curator:

CURATE THE YAHOO! PATTERN LIBRARY Yahoo!’s Platform User Experience Design team is looking for a new curator for the Pattern Library. The curator works with designers from across Yahoo! to develop new patterns and to eventually migrate a pattern to the public library. You will be responsible for spotting trends in the designs of our properties, for designing and crafting new additions to the library and for evangelizing the authorship of new patterns among your Interaction Designer colleagues. You will partner with our Platform Presentation Engineering team to create interactions and best practices that accompany the UI Widget Library. Additionally, you will own the external Public Pattern Library and develop the pattern lifecycle from internal to external libraries. And last but not least, you will be the spearhead and driver for a new addition to our Library suite – a new Terms Library and will work closely with our internal editorial team.

Patterns will become more important to organisations as companies realise there’s value in concrete advice based on real-world examples, to complement vague mission statements with stuff people can actually use day to day. This will be aided by the general trend towards wikis and more user-friendly document evolution. For several years now, Yahoo! has been using patterns in this more holistic sense, and the ad for a pattern curator suggests they’ve been more than happy with the results.

“So, Jesse, Is Ajax a Pattern?”

… That’s the question I finally got to ask the man who gave Ajax its name, following Jesse James Garrett’s keynote last week at The Ajax Experience. I consider Ajax a very standard, uncontroversial, example of a pattern, so I’ve wondered why it wasn’t introduced as such, in the original Ajax paper.

Jesse said he’s asked the question quite a bit. He didn’t answer the question directly – there wasn’t a “Yes” or a “No”. Essentially, he just made the point that patterns mean different things to different people, everyone has their own idea, etc. In other words, I think he either doesn’t want to get bogged down in the debate or doesn’t consider it important.

At first, that seemed rather anticlimatic, but on reflection, I can see his point. He mentioned in his talk how people (of a certain kind, I guess) mail him saying “I wrote this app in 2000, it uses IFrame yadda yadda … Is it Ajax?”. So he probably has enough trouble with the definition of Ajax to worry about the definition of patterns as well. Moreover, he’s a consultant, and probably talks to high-level managers who wouldn’t know a pattern from a shell script.

So it’s understandable from a pragmatic perspective why “pattern” isn’t used in the original definition of Ajax, even though Ajax fits the mould perfectly. However, it is a shame for software, and industry at large, that patterns aren’t the standard way people think about designs and processes. Framed as a pattern, a high-level architectural style like Ajax can evolve quickly, as people begin to consider examples, forces, rationale, and all the other standard attributes of a pattern. Furthermore, people can ask about the role of this pattern in the entire ecosystem of patterns. What are its alternatives and how does it stack up? What are the lower-level patterns that should be solve questions opened up by applying the high-level pattern?

That many managers don’t get patterns leaves a lot of potential for improvement within organisations. An open wiki of interlinked organisational, technical, usability, etc patterns should be an asset to any company. As explained in this visionary paper by Jed Harris and Austin Henderson. The 2020 scenario suggests how patterns might be navigated in the future.

Then she puts a probe into the guise and begins looking for the patterns that the guise uses to model market response to Heavy Metal.* Her office shows her the internal organization of the guise as a network of nodes whose size and clustering reflect how much they contribute to the guise’s current display. Each of the nodes is a small view of the associated pattern, showing its current state; if she focuses on a single node, she can usually tell how it is contributing to the display. Olivia thinks of this display as a “sea of nodes” because the ripples and swirls remind her of flowing water. She swims through the sea, getting a feeling for how Fred has put the guise together, and how the guise itself is interpreting the current behavior of Heavy Metal’s customers. After a little while she zeros in on the service and support patterns. By suppressing the contribution of some patterns and looking at what changes in the display, she eventually finds a pattern— Service is a Feature— that seems to be most involved with the aspects that have been bothering her.