I released a BRS Lab named CuttySSark some months ago. It operated under an experimental idea that fundamentally changes how a front-end developer could approach interaction design. The library generated some buzz on Twitter when Chris Coyier of CSS-Tricks.com tweeted about it favorably. Amongst a humbling number of appreciative tweets, re-tweets, pre-tweets, and un-tweets, there they were, gorgeous as ever: the haters. Now, I can deal with haters --- in fact, I really love them for the sake of provoking thoughtful conversation.

Twitter isn’t a great place for thoughtful conversation, so here I am on the “Internet,” responding to tweets in web log format (a silly thing, but alas). See y’all in the comments! Dukes up (just kidding).

stick. gloves. shirt.

— Mighty Ducks Quotes (@QuotesDucks) December 7, 2012

For those of you who are curious to know: the purpose of CuttySSark is to augment CSS by exposing to it user interaction, similarly to the useful and stateful CSS1/2 :hover, :active, and :focus pseudo-selectors. The JavaScript event model is the vehicle for this, but nothing more than that. You can mess things up with CuttySSark. However, you can also turn your front-end developer life into butter. We hope native user interaction design may follow a similar, but improved model in the future. For now, this is what I have.

Let me back up a tad bit to explain the idea behind CuttySSark, and why I believe it scares some people, including several of my co-workers. CuttySSark allows one to write CSS that interacts directly with the JavaScript event model. Here’s a simple example:

big[on~="click|toggle"] #little { background: transparent; }

Cutty reads my stylesheet and finds this rule that causes the background transparency on #little to toggle when #big is clicked. Cutty is responsible for setting up JS events so that the CSS2-compliant selector written in the stylesheet, #big[on~="click|toggle"] #little, is actually matched at the correct time.

The crucial distinction here: The CSS you write is directly responsible for the style changes, as opposed to JavaScript manipulating styles via the DOM style object.

This approach has the same benefit as class-swapping via JS. I expect we can all agree that it’s useful for styles to live solely in stylesheets and not in JS.

@cbracco @chriscoyier Neat! Not to argue, but isn't this just a messier version of JS? Didn't we stop using the onclick attr for a reason?

— Paul Molluzzo (@PaulMolluzzo) November 14, 2013

Ah, you’ve got me! I don’t want styles to live in JS, but I do want JS-driven events to live in CSS. In all earnestness, yes! Well, I don’t want all events to live in CSS, but I do want the ones related to style-specific changes. I just want my stylesheets to reflect the statefulness of the styles described. It works wonderfully for :hover, :focus, and :active, does it not? I’ve never heard anyone complain about them, and nobody should! They are incredibly convenient because I can simultaneously understand both what style will appear, and also when and where it will appear. Class-swapping via JS obfuscates that very action.

Well, interaction design has pushed beyond these “dynamic/interactive” pseudo-selectors: two simple examples of revolutions in interaction being HTML5’s draggable and CSS3’s animations, both of which are backed by a suite of JS-driven events. CuttySSark is a polyfill bringing CSS2’s stateful-mindedness into the present.

@chriscoyier I think CSS should be more or less static and JS should be used to control it dynamically. Events in CSS and JS is just messy.

— Ryan (@swap_meet) November 14, 2013

I do agree that there is one idea floating around with CuttySSark that has not been properly addressed. It’s possible that on the Labs demo page I stressed the usage of “event”-driven styles too much. Here I’m stressing the usage of “stateful” style, and events are not states --- they’re typically transitions into states. For example, the Cutty selector [on~=mouseover] would match the moment the cursor moves on top of an element, but it would still match when the cursor leaves the element. Thus, it’s matching a relatively meaningless state of the element of “having been moused-over.” That’s why I implemented the state, clear, toggle, and once options within Cutty.

These options allow us to implement well-defined states using events as transitions. I’m thinking a little state-machiney right now. Even though the events represent the transitions (denoted by --> in a moment), CuttySSark’s options do support the idea of actual statefulness:

  • once implements the states of “on” and “off” in the machine [off]-->[on]
  • toggle implements the states of “on”, “off”, and “default” in several machines, one of which being [default]-->[on]<==>[off]
  • clear allows for a sort of “return to statefulness” by reverting non-stateful style blocks.
  • state implements statefulness by forcing elements to assume exactly one stated style block at a time.

I genuinely had this in mind! It’s easy to deviate from it, and I understand that you can shoot yourself in the foot by allowing an element to have too many disparate Cutty-induced styles applied to it at once. Of course, any flexible system can be used for evil.

@chriscoyier Is the idea that anything which gets done in JS a lot should be implemented? Not sure of the feature creep potential...

— Chris Bowyer (@chrisabowyer) November 14, 2013

Hmm...I sense an elephant in the room. There is a somewhat ugly corner of Cutty that won’t need to be used most of the time: the support of a rather ugly syntax that allows an event on one set of elements to trigger a different event on another set of elements. It looks like this:

selector1[on~="event1|trigger|event2(selector2)"] { ... }

That actually reads somewhat reasonably (“for elements in selector1, on event1 trigger event2 on elements in selector2”), but I concede it’s an abuse of CSS because it’s a meaningless style block that interacts directly with the event model, and not with any styles.

That said, it can be incredibly useful for simple UI elements. I was thinking about all the different UI elements that could be created simply by manipulating styles without reference to any sort of programming logic once a user’s interaction with the DOM were exposed to CSS.

The last step in exposing user interaction to CSS was to allow interaction with one element to affect the state/styles of a separate, non-child element. Thus, that’s precisely why this feature exists. Again, the purpose here is not to mindlessly force a random piece of JS into CSS, and of course I do not support extending JS functionality into CSS. Rather, my purpose is to expose user interaction to CSS beyond CuttySSark’s grandparents, :focus and :hover. JS is merely the vehicle for that.

The bottom line here is that CuttySSark is a simple tool loaded with implications. I like to think with Cutty we’re one step closer to a non-Frankensteined incarnation of CSS, which has kept up with user interaction beyond mousing over and out.

Cutty Shark!

Share this post

Work With Us

We've been waiting for this moment our entire lives.