Grow your CSS skills. Land your dream job.

An Intro to Hitch.js and the Extensible Web

Published by Guest Author

The following is a guest post by Brian Kardell. Brian wrote me after I linked up Hitch.js a few weeks ago to give me more insight. It's pretty interesting stuff, so I thought we should share that here. Hitch is an artifact of a larger "Extensible Web" movement, including a manifesto, community group, and funny word.

What is Hitch.js exactly?

Hitch is a proof-of-concept “prollyfill engine” (we'll define that later) specializing in CSS selectors. It gives you jQuery-style selector plugins right in CSS itself. It’s based on proposals from the CSS working group list a few years ago by Yehuda Katz, myself and a few others as well as some very long email threads with Google’s Tab Atkins and Mozilla’s Boris Zbarsky. During the discussions I found myself wanting to prove something, so I’d write a little code. In the end I worked with my friend Clint Hill stringing it together and re-working it into a usable open-source project that might give developers some immediate value. That's Hitch.js.

Has it done that?

I think so. It’s done a few things: First, it shines some light on yet another example of what Alex Russell and Yehuda Katz are talking about in the Technical Architecture Group about a need for layering the design of things and how, for a lot of things, developers wind up re-implementing things that the browser already does much better because we’re sealed off from at high levels and we can’t tweak just one piece. In CSS, we’re missing some primitives and good extension points along the way. It is surprisingly difficult to add this sort of thing. It has also helped to convince certain key members of the CSS Working Group that CSS needs some things like this. Tab wrote about it on his blog in a New Year’s Resolution post. I am pretty confident that we will wind up with some good new abilities in CSS like in the next few years. Until that time, we have Hitch.

What would you really use it for?

This is the key question, whether it was provided via Hitch or natively, what could you do with this new found power? I think you could help change the Web forever. I know that sounds big, but I think it is. We could use it to help better the whole model of how we think about standards. Consider this: CSS 2 became a W3C Recommendation in May 1998. We might still think of “CSS 3″ as being something relatively new – but actually they published the first draft for CSS 3 in August 1999. Way back then, they were discussing way more selector power than is in CSS Selectors Level 3 today. Think about that for a moment. If you were a toddler when they started CSS 3, you would be graduating from high school now. There are a lot of reasons for that, but even if that is artificially long by a factor of 5, it still means that you have to wait a few years for something to make it through the process until anyone really gets to use it. Then it’s sometimes only in nightlies, or behind a flag, so you can’t really use it for anything “real”. Historically then it would be added behind a prefix and a few daring souls might start using it, but it’s hard because it only works in a few browsers. That meant that realistically it was a few more years out until it is usable by a wide enough audience to find out that, actually “I don’t care for half of these selectors and why didn’t they do X instead?” This is exacerbated by the fact that once it is that far, you are really hard pressed to convince anyone to change it because that means potentially “breaking the Web” as they like to say. In a word, that sucks.

How would it help change that? Is this related to the Extensible Web?

What if, instead of that model, I could let you use CSS Selectors Level 4 or 5 – or any proposed selectors right now in a way that was reasonably performant and you could know that the implementation wouldn’t change out from underneath you? It should be possible right? If we use polyfills to “fill the gaps” providing reasonable implementations for standards on the least capable older browsers then why not build reasonable implementations of the proposals in the first place that work on modern browsers – prollyfills - so that we could evaluate, iterate and compete. If we did, we could cut to the chase right? You could complain that they were no good now before they went any further. If we did it out in public on GitHub, you might even be able to fork them and make them better – and you probably would, because, lets face it: Way more people use GitHub than participate in Web Standards discussions. We might even collect data on use, complaints, stability and vendor reviews to determine when one is “baked” enough to worry about moving on to native implementations and prioritize them quickly.

Can you give me some examples?

Let’s say there is something in the Selectors Level 4 proposal that you think might be useful, like the :local-link pseudo-class which lets you select links that are within your domain and at varying URL levels (as you often have in navigation links). Is it? Are you sure you even understand it? With Hitch, we can develop a prollyfill for that and share it – in fact, we did - you can view a demo of it. That means you can actually use it for something real today. You can help make it better too, fork it on GitHub and improve it you can send me a pull request, share your use cases, open issues, or add some reftests. Any feedback that you send, we will relate up to the CSS Working Group.

Here's an even more simple example. We'll make a selector that only selects external links. First link up the Hitch.js:

<script src="http://hitchjs.com/dist/hitch-0.6.3.js"></script>

Then use the Hitch syntax for adding a new selector. We'll make sure the hostname of the href matches the hostname of the window.

Hitch.add([{
  
  type: 'selector',
  name: '-links-external', 
  base: '[href]',
  filter: function (match, argsString, o) {
    if (!match.hostname) {  
      return false;
    }
    return match.hostname !== window.location.hostname;
  }
  
}]);

Then we can use the name we set up there in our CSS. Note the special attribute on the CSS that ensures Hitch parses it.

<style data-hitch-interpret>
  a:-links-external() {
    background-color: yellow;
  }
</style> 
Check out this Pen!

Or, let’s say that you had a proposal for a selector that isn’t in any draft: You could write a prollyfill and submit a draft by creating a git just like the one above and share it with the CSS Working Group. In fact, this has happened already and you can read about it in our post About :time – Taming the standards process. Even better, what if browser vendors followed this same pattern whenever possible? Well, that’s happened too: Adobe did something similar with a regions proposal – they didn’t use Hitch because they didn’t know about it, but they wrote a kind of one-off that does something similar. Mozilla did this with X-Tags and Google with Polymer – both of which can more freely evolve, be used in any modern browser and even maybe compete a little outside the browser before we rush in and commit. We’ve followed the same basic idea with Futures/Promises and with Navigation Controller. I consider these all great successes that helped us coordinate a lot of groups and get a lot of minds together in new ways.

How does Hitch relate to Web Components?

It has some stuff about Web Components, but those were based on an earlier draft. It pre-dates Mozilla’s X-Tags or Google’s Polymer and we have no real interest in competing with them. In fact, we’d love to collaborate. Both are considerably better and based off updated work. It just turned out that internally we were doing 95% of the stuff necessary to make a simple element “upgrade” happen easily, so we exposed it. If you just want to break down into modular ‘widgets,’ you can probably get away without more. But that isn’t what it's about.

You mentioned that Hitch wasn’t a pre-processor, why not?

As it stands today, Hitch includes some aspects of a CSS pre-processor, but it’s not a pre-processor. It isn’t intended to be a replacement for things like Sass, it just turns out that internally exposing a bit of simple pre-processing is easy, so we expose it. If you just need some simple token replacement, you can probably get away without more, but that isn’t what it is about. In fact, the input to the actual “engine” in Hitch isn’t even CSS, but a kind of parse tree. It’s layered so that we can move the pre-processing piece out if we can partner up with existing things like Sass. We kept it simple for now because some people don’t have a rich pre-processor and don’t want one and we honestly don’t want to try to compete with those guys. It’s better for us to work together with them for that piece as an optimization.

How does all of this relate to the Extensible Web?

That’s what The Extensible Web Manifesto is all about – changing the way we think about standards. Hitch predates this, so I can’t honestly say that it is the “perfect” example of it all. Several of us came to very similar conclusions about the same time and we’ve been discussing for a long time now and honing it all. But it does illustrate, at a high level at least, some of how we’d like to change the model and make it possible for good developers to help #extendthewebforward. If any of this sounds compelling to you, I’d encourage you to go give it a read. And hopefully to sign it yourself. Then tell a friend!

Comments

  1. ulf gjerdingen

    ok. i’m spreading this. so cool.

  2. Great stuff! What about perf?

  3. The ‘hitch-like’ CSS Regions polyfill can be found here: https://github.com/adobe-webplatform/css-regions-polyfill

  4. Reminds me of directives in angular.js, which is awesome to have in a lighter standalone version.

  5. Indeed an interesting article, but can’t figure out the usage in our web projects.

    • there is good introduction video on hitchjs official website. In a nutshell, you can use, for instance, parent selector like .a < .b and many others made by community. Or you can expose CSS selectors set, by writing your own. No need to wait while they would be implemented in CSS4.

  6. Any mention of performance?

  7. Would LOVE to finally be able to use CSS Parent Selectors, but I didn’t see an example in their docs or repository (am I blind?).

    I am constantly finding myself wanting to style a parent element when some child attribute is changed.

    <div class="some-parent">
      <input type="checkbox">
    </div>
    
    .some-parent < input[type="checkbox"]:checked {
        background-color: papayawhip;
    }
    
  8. This is awesome! Going to give this a good try tomorrow.

  9. Nojan A.

    So it’s a framework to build our own polyfills :-?
    Sounds fantastic!!

  10. One thing to note is that this is an JavaScript CSS interpreter, meaning changes to pseudo-elements after page load will not be reflected unless you wire up additional JavaScript to call hitch on said pseudo-element changes. Let me explain a bit….

    I would love to be able to change the CSS on a parent element when its child psudo-element changes.

    <style data-hitch-interpret>
    p:-hitch-has(input:checked) {
    color:red;
    }
    </style>

    <p>
    parent element 1 text
    <input type="checkbox" checked>
    </p>
    <p>
    parent element 2 text
    <input type="checkbox">
    </p>

    <script type="text/javascript" src="http://www.hitchjs.com/dist/hitch-0.6.1.min.js"></script&gt;

    In the above example the “-hitch-has” selector works great on initial page load (the default state of the 1st checkbox is “checked”, and its parent “p” is colored “red”). The problem occurs when you then interact with the pseudo-elements after page load(checking/unchecking the checkboxes).

    Anyway, just wanted to share my experience so far…

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".