Zen Coding: A Speedy Way To Write HTML/CSS Code

Advertisement

In this post we present a new speedy way of writing HTML code using CSS-like selector syntax — a handy set of tools for high-speed HTML and CSS coding. It was developed by our author Sergey Chikuyonok1 and released for Smashing Magazine and its readers.

How much time do you spend writing HTML code: all of those tags, attributes, quotes, braces, etc. You have it easier if your editor of choice has code-completion capabilities, but you still do a lot of typing.

We had the same problem in JavaScript world when we wanted to access a specific element on a Web page. We had to write a lot of code, which became really hard to support and reuse. And then JavaScript frameworks came along, which introduced CSS selector engines. Now, you can use simple CSS expressions to access DOM elements, which is pretty cool.

But what if you could use CSS selectors not just to style and access elements, but to generate code? For example, what if you could write this…

div#content>h1+p

…and see this as the output?

<div id="content">
<h1></h1>
<p></p>
</div>

Today, we’ll introduce you to Zen Coding2, a set of tools for high-speed HTML and CSS coding. Originally proposed by Vadim Makeev3 (article in Russian) back in April 2009, it has been developed by yours truly (i.e. me) for the last few months and has finally reached a mature state. Zen Coding consists of two core components: an abbreviation expander (abbreviations are CSS-like selectors) and context-independent HTML-pair tag matcher. Watch this demo video to see what they can do for you.

If you’d like to skip the detailed instructions and usage guide, please take a look at the demo and download your plugin right away:

Demo Link

  • Demo164 (use Ctrl + , to expand an abbreviation, requires JavaScript)

Downloads (Full Support) Link

Downloads (Partial Support, “Expand Abbreviation” Only) Link

Now, let’s see how these tools work.

Expand Abbreviation Link

The Expand Abbreviation function transforms CSS-like selectors into XHTML code. The term “abbreviation” might be a little confusing. Why not just call it a “CSS selector”? Well, the first reason is semantic: “selector” means to select something, but here we’re actually generating something, writing a shorter representation of longer code. Secondly, it supports only a small subset of real CSS selector syntax, in addition to introducing some new operators.

Here is a list of supported properties and operators:

  • E
    Element name (div, p);
  • E#id
    Element with identifier (div#content, p#intro, span#error);
  • E.class
    Element with classes (div.header, p.error.critial). You can combine classes and IDs, too: div#content.column.width;
  • E>N
    Child element (div>p, div#footer>p>span);
  • E+N
    Sibling element (h1+p, div#header+div#content+div#footer);
  • E*N
    Element multiplication (ul#nav>li*5>a);
  • E$*N
    Item numbering (ul#nav>li.item-$*5);

As you can see, you already know how to use Zen Coding: just write a simple CSS-like selector (oh, “abbreviation”—sorry), like so…

div#header>img.logo+ul#nav>li*4>a

…and then call the Expand Abbreviation action.

There are two custom operators: element multiplication and item numbering. If you want to generate, for example, five <li> elements, you would simply write li*5. It would repeat all descendant elements as well. If you wanted four <li> elements, with an <a> in each, you would simply write li*4>a, which would generate the following output:

<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>
<li><a href=""></a></li>

The last one–item numbering is used when you want to mark a repeated element with its index. Suppose you want to generate three <div> elements with item1, item2 and item3 classes. You would write this abbreviation, div.item$*3:

<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>

Just add a dollar sign wherever in the class or ID property that you want the index to appear, and as many an you want. So, this…

div#i$-test.class$$$*5

would be transformed into:

<div id="i1-test" class="class111"></div>
<div id="i2-test" class="class222"></div>
<div id="i3-test" class="class333"></div>
<div id="i4-test" class="class444"></div>
<div id="i5-test" class="class555"></div>

You’ll see that when you write the a abbreviation, the output is <a href=""></a>. Or, if you write img, the output is <img src="" alt="" />.

How does Zen Coding know when it should add default attributes to the generated tag or skip the closing tag? A special file, called zen_settings.js13 describes the outputted elements. It’s a simple JSON file that describes the abbreviations for each language (yes, you can define abbreviations for different syntaxes, such as HTML, XSL, CSS, etc.). The common language abbreviations definition looks like this:

'html': {
'snippets': {
'cc:ie6': '<!--[if lte IE 6]>nt${child}|n<![endif]-->',
...
}, 

'abbreviations': {
'a': '<a href=""></a>',
'img': '<img src="" alt="" />',
...
}
}

Element Types Link

Zen Coding has two major element types: “snippets” and “abbreviations.” Snippets are arbitrary code fragments, while abbreviations are tag definitions. With snippets, you can write anything you want, and it will be outputted as is; but you have to manually format it (using n and t for new lines and indentation) and put the ${child} variable where you want to output the child elements, like so: cc:ie6>style. If you don’t include the ${child} variable, the child elements are outputted after the snippet.

With abbreviations, you have to write tag definitions, and the syntax is very important. Normally, you have to write a simple tag with all default attributes in it, like so: <a href=""></a>. When Zen Coding is loaded, it parses a tag definition into a special object that describes the tag’s name, attributes (including their order) and whether the tag is empty. So, if you wrote <img src="" alt="" />, you would be telling Zen Coding that this tag must be empty, and the “Expand Abbreviation” action would apply special rules to it before outputting.

For both snippets and abbreviations, you can ad a pipe character (|), which tells Zen Coding where it should place the cursor when the abbreviation is expanded. By default, Zen Coding puts the cursor between quotes in empty attributes and between the opening and closing tag.

Example Link

So, here’s what happens when you write an abbreviation and call the “Expand Abbreviation” action. First, it splits a whole abbreviation into separate elements: so, div>a would be split into div and a elements, with their relationship preserved. Then, for each element, the parser looks for a definition inside the snippets and then inside the abbreviations. If it doesn’t find one, it uses the element’s name as the name for the new tag, applying ID and class attributes to it. For example, if you write mytag#example, and the parser cannot find the mytag definition among the snippets or abbreviation, it will output <mytag id="example"><mytag>.

We have made a lot of default CSS14 and HTML abbreviations and snippets15. You may find that learning them increases your productivity with Zen Coding.

HTML Pair Matcher Link

Another very common task for the HTML coder is to find the tag pair of an element (also known as “balancing”). Let’s say you want to select the entire <div id="content"> tag and move it elsewhere or just delete it. Or perhaps you’re looking at a closing tag and want to known which opening tag it belongs to.

Unfortunately, many modern development tools lack support for this feature. So, I decided to write my own tag matcher as part of Zen Coding. It is still in beta and has some issues, but it works quite well and is fast. Instead of scanning the full document (as regular HTML pair matchers do), it finds the relevant tag from the cursor’s current position. This makes it very fast and context-independent: it works even with this JavaScript code snippet:

var table = '<table>';
for (var i = 0; i < 3; i++) {
table += '<tr>';
for (var j = 0; j < 5; j++) {
table += '<td>' + j + '</td>';
}
table += '</tr>';
}
table += '</table>';

Wrapping With Abbreviation Link

This is a really cool feature that combines the power of the abbreviation expander with the pair tag matcher. How many times have you found that you have to add a wrapping element to fix a browser bug? Or perhaps you have had to add decoration, such as a background image or border, to a block’s content? You have to write the opening tag, temporarily break your code, find the appropriate spot and then close the tag. Here’s where “Wrap with Abbreviation” helps.

This function is pretty simple: it asks you to enter the abbreviation, then it performs the regular “Expand Abbreviation” action and puts your desired text inside the last element of your abbreviation. If you haven’t selected any text, it fires up the pair matcher and use the result. It also makes sense of where your cursor is: inside the tag’s content or within the opening and closing tag. Depending on where it is, it wraps the tag’s content or the tag itself.

Abbreviation wrapping introduces a special abbreviation syntax for wrapping individual lines. Simply skip the number after the multiplication operator, like so: ul#nav>li*>a. When Zen Coding finds an element with an undefined multiplication number, it uses it as a repeating element: it is outputted as many times as there are lines in your selection, putting the content of each line inside the deepest child of the repeating element.

If you’ll wrap this abbreviation div#header>ul#navigation>li.item$*>a>span around this text…

About Us
Products
News
Blog
Contact Up

You’ll get the following result:

<div id="header">
<ul id="navigation">
<li class="item1"><a href=""><span>About Us</span></a></li>
<li class="item2"><a href=""><span>Products</span></a></li>
<li class="item3"><a href=""><span>News</span></a></li>
<li class="item4"><a href=""><span>Blog</span></a></li>
<li class="item5"><a href=""><span>Contact Up</span></a></li>
</ul>
</div>

You can see that Zen Coding is quite a powerful text-processing tool.

Key Bindings Link

  • Ctrl+,
    Expand Abbreviation
  • Ctrl+M
    Match Pair
  • Ctrl+H
    Wrap with Abbreviation
  • Shift+Ctrl+M
    Merge Lines
  • Ctrl+Shift+?
    Previous Edit Point
  • Ctrl+Shift+?
    Next Edit Point
  • Ctrl+Shift+?
    Go to Matching Pair

Online Demo Link

You’ve learned a lot about how Zen Coding works and how it can make your coding easier. Why not try it yourself now, right here? Because Zen Coding is written in pure JavaScript and ported to Python, it can even work inside the browser, which makes it a prime candidate for including in a CMS.

  • Demo164 (use Ctrl + , to expand an abbreviation, requires JavaScript)

Supported Editors Link

Zen Coding doesn’t depend on any particular editor. It’s a stand-alone component that works with text only: it takes text, does something to it and then returns new text (or indexes, for tag matching). Zen Coding is written in JavaScript and Python, so it can run on virtually any platform out of the box. On Windows, you can run the JavaScript version of Windows Scripting Host. And modern Macs and Linux distributions are bundled with Python.

To make your editor support Zen Coding, you need to write a special plug-in that can transfer data between your editor and Zen Coding. The problem is that an editor may not have full Zen Coding support because of its plug-in system. For example, TextMate17 easily supports the “Expand Abbreviation” action by replacing the current line with the script output, but it can’t handle pair-tag matching because there’s no standard way to ask TextMate to select something.

Full Support Link

Partial Support (“Expand Abbreviation” Only) Link

Aptana is my primary development environment, and it uses a JavaScript version of Zen Coding. It also contains many more tools that I use for routine work. Every new version of Zen Coding will be available for Aptana first, then ported to Python and made available to other editors.

The Coda and Espresso plug-ins are powered by the excellent Text Editor Actions26 (TEA) platform, developed by Ian Beck27. The original source code is available at GitHub28, but I made my own fork29 to integrate Zen Coding’s features.

Conclusion Link

Many people who have tried Zen Coding have said that it has changed their way of creating Web pages. There’s still a lot of work to do, many editors to support and much documentation to write. Feel free to browse the existing documentation30 and source code31 to find answers to your questions. Hope you enjoy Zen Coding!

(al)

Footnotes Link

  1. 1 http://www.smashingmagazine.com/author/sergey-chikuyonok/
  2. 2 http://code.google.com/p/zen-coding/
  3. 3 http://pepelsbey.net/2009/04/zen-coding-concept/
  4. 4 http://zen-coding.ru/demo/
  5. 5 http://code.google.com/p/zen-coding/downloads/detail?name=Zen.Coding-Aptana.v0.5.zip
  6. 6 http://github.com/sergeche/tea-for-coda/downloads
  7. 7 http://github.com/sergeche/tea-for-espresso/downloads
  8. 8 http://code.google.com/p/zen-coding/downloads/detail?name=Zen%20Coding%20for%20TextMate%20v0.3.1.zip
  9. 9 http://code.google.com/p/zen-coding/downloads/detail?name=TopStyle.Zen.Coding.1.0.zip
  10. 10 http://code.google.com/p/zen-coding/downloads/detail?name=Sublime.Zen.Coding.1.1.3.zip
  11. 11 http://www.kryogenix.org/days/2009/09/21/zen-coding-for-gedit
  12. 12 http://zen-coding.ru/demo/
  13. 13 http://code.google.com/p/zen-coding/source/browse/branches/serge.che/aptana/zen_settings.js
  14. 14 http://code.google.com/p/zen-coding/wiki/ZenCSSPropertiesEn
  15. 15 http://code.google.com/p/zen-coding/wiki/ZenHTMLElementsEn
  16. 16 http://zen-coding.ru/demo/
  17. 17 http://macromates.com/
  18. 18 http://code.google.com/p/zen-coding/downloads/detail?name=Zen.Coding-Aptana.v0.5.zip
  19. 19 http://github.com/sergeche/tea-for-coda/downloads
  20. 20 http://github.com/sergeche/tea-for-espresso/downloads
  21. 21 http://code.google.com/p/zen-coding/downloads/detail?name=Zen%20Coding%20for%20TextMate%20v0.3.1.zip
  22. 22 http://code.google.com/p/zen-coding/downloads/detail?name=TopStyle.Zen.Coding.1.0.zip
  23. 23 http://code.google.com/p/zen-coding/downloads/detail?name=Sublime.Zen.Coding.1.1.3.zip
  24. 24 http://www.kryogenix.org/days/2009/09/21/zen-coding-for-gedit
  25. 25 http://zen-coding.ru/demo/
  26. 26 http://onecrayon.com/tea/
  27. 27 http://beckism.com/
  28. 28 http://github.com/onecrayon
  29. 29 http://github.com/sergeche/
  30. 30 http://code.google.com/p/zen-coding/w/list
  31. 31 http://code.google.com/p/zen-coding/source/browse/#svn/branches/serge.che

↑ Back to top Tweet itShare on Facebook

Sergey Chikuyonok is a Russian front-end web-developer and writer with a big passion on optimization: from images and JavaScript effects to working process and time-savings on coding.

Advertisement
  1. 1

    Well done sir. This is pure awesome.

    -1
  2. 2

    well I’d rather keep using haml, this sounds good to quickly write html pages but a good template language actually makes them maintainable afterwards

    -2
  3. 3

    Excuse me but I haven’t seen something new in ZC. As my friend said above, auto complementation softwares had already released.

    -1
  4. 4

    WOW! This is just awesome and revolutionary. Just added to my favorites. Will definitely read it more in depth later today.

    3
  5. 5

    looks promising
    thanks for yr hard work guys

    0
  6. 6

    I agree, this looks like sheer awesomesauce.

    0
  7. 7

    would be nice if it had some sort of group support like

    html:xt>div#wrapper>[div#header>ul#navigation>li*5>a, div#content>p*4, div#footer>p#copyright]

    expected output http://pastie.org/709059

    0
  8. 8

    Wouldn’t say revolutionary. Auto-completion and text expanders have been out there for years.

    TextExpander on Mac: http://www.smileonmymac.com/TextExpander/

    Texter on Windows: http://lifehacker.com/238306/lifehacker-code-texter-windows

    AutoKey on Linux: http://losingit.me.uk/2008/12/26/autokey-nifty-text-expander-for-linux

    -2
  9. 9

    Zen Coding is really nice! I use it for Coda and it is fast fast fast.

    0
  10. 10

    Looks really good, I’ll try with Aptana.

    0
  11. 11

    looking good, got to try it out.. thanks SM

    0
  12. 12

    This is exactly how I’ve been trying to work for years… (I was typing CSS while I was doing HTML, doing!)

    Awesome demo and I’m definetly going to try it out! (Textmate)

    0
  13. 13

    It sounds a bit confusing for me.

    -1
  14. 14

    When programming, the actual time spent typing should be trivial when compared to any other task. I think tools like this just add complexity to a nonexistent problem.

    -4
  15. 15

    Thanks, will definitely try it!
    One very newbie question: how do you install this (using Coda & Espresso)?

    0
  16. 16

    Just double-click on Coda’s bundle or Espresso’s sugar

    0
  17. 17

    Most text expanders works with predefined set of snippets only. Zen Coding parses code snippet in real-time and produces desired output

    9
  18. 18

    HOT! HOT! HOT!

    0
  19. 19

    Thanks Sergey – had downloaded the wrong files ;-P

    0
  20. 20

    I’ll say after a week if this will reduce my coding time. Happy testing!

    0
  21. 21

    I’m thinking about it, but I’m afraid it will add unneeded complexity to ZC. The whole idea of ZC is to quickly write code snippets using syntax familiar to any HTML-coder, not to create a new programming language to make you think about how to write abbreviation.

    1
  22. 22
  23. 23

    In Russia code writes you!

    5
  24. 24

    Make a Vim script out of this and I’ll build you an altar to pray everyday for the SM gods!

    0
  25. 25

    kicking asses!!!!

    0
  26. 26

    Darn, I had submitting this article in mind last week, yours however is more detailed.

    0
  27. 27

    interesting programming problem to solve, but with respect I don’t honestly see the point. HTML is pretty straightforward to write with modern editors like Coda, which include auto-completion, custom snippets and tag closing. You’ve basically created a markup language for a markup language.

    1
  28. 28

    Perhaps it’s just me, but this logic seems a totally backwards approach to modern HTML markup. Not only is it–in my opinion–practically unreadible to develop, you lose the semantic process of HTML to begin with (meaning, starting with headers and paragraphs and then adding more meta data semantics, divs for layouts, etc). How do you go about including semantic meaning such as RDFa and Microformats without everything turning it a huge, sloppy mess to read? (Nevermind the whole dynamic DOM aspect to your page.)
    I have never understood the need for these sorts of creations… It seems to take more time to learn these new “techniques” than to just learn how to markup a page semantically and properly from the start.
    HTML has always been and will always be a simple set of markup elements for the reason of ease. It is easy and this just obfuscates things.

    Akiva Levy, http://sixthirteendesign.com

    -3
  29. 29

    How to install it into Aptana 2?!? I going to install it for 4 hours and done nothing…

    0
  30. 30

    I agree with simon r jones

    I will stick with the old way of doing it by hand.

    0
  31. 31

    And Chris Done has written a version for Emacs, see here:

    http://www.emacswiki.org/emacs/ZenCoding

    I think he is trying to combine that with yasnippet expansion at the moment.

    0
  32. 32

    Create a new folder named scripts or a monkey in any top-level project folder in your workspace and drop Zen Coding in it. This is how Aptana scripts are installed. More info: https://aptanastudio.tenderapp.com/faqs/scripting-with-eclipse-monkey/create-script

    2
  33. 33

    Hey folks,
    There’s a tool out there called Sparkup that does a similar thing, but adds more (specifically, more shortcuts, whitespace support, text and more useful selectors). :) You can see a demo of it here http://www.youtube.com/watch?v=Jw3jipcenKc — it shows some new selectors that aren’t in Zen.

    And it has support for VIM! :)

    Here: http://github.com/rstacruz/sparkup

    0
  34. 34

    Zen coding looks nice! What is the music, is it Seba and Paradox? Awesome tune…

    0
  35. 35

    Another Zen-like package solves this problem. It’s called Sparkup (http://github.com/rstacruz/sparkup), but at the moment it only has support for Textmate. You can do something like:

    #header > .navigation < #area > .content + .sidebar < .copyright

    The reason I wrote it like this (well, I made Sparkup :) is that if it was done via grouping (with parantheses or brackets), you would have to go back, add open parentheses to your code, then move back forward to close it. Doing it with a < means you can write your markup ‘straightforward’ without back-tracking.

    Demo: http://www.youtube.com/watch?v=Jw3jipcenKc
    Download: http://github.com/rstacruz/sparkup

    0
  36. 36

    I’ll have to give this a go on Aptana. Not sure I’d want to stick with it full time for every project, but sounds great for punching out some quick header footer column layouts to match up with a pre-existing style sheet.

    0
  37. 37

    If you’re already comfortable with CSS selectors (and you probably should be) this can be a great way to get past the boring part of your page development and get you to interesting stuff.

    If you can think html:xs>div#all>div#head+div#nav+div#body naturally, why shouldn’t you be able to write that and have it turn into code? I do think one level of parens would be nice, but not absolutely necessary (after all, just expand and put a new abbreviation in the appropriate spot.)

    This may actually keep me in Aptana a bit longer. (I was starting to move to Komodo because of the nicer abbreviations and macros.)

    0
  38. 38

    Dean Higginbotham

    November 21, 2009 1:05 pm

    I agree.

    -4
  39. 39

    I have to agree with Simon R Jones, HTML is pretty straight forward, and most people will now have a pretty comprehensive snippet library, most modern editors have a snippet facility, so dont really see the point. bet I could drag a snippet out quicker than I could Zen code the same line of code.

    I chuck this in the same category as “object orientated” CSS, its just seems like wheel reinvention.

    -2
  40. 40

    Hello! I’m new coding.

    how do you install the plugin in aptana?

    0
  41. 41

    James Padolsey has written a similar script called Satisfy:
    http://github.com/jamespadolsey/satisfy

    It has a jQuery plugin API, as well.

    0
  42. 42

    Sergey Chikuyonok

    November 21, 2009 1:15 pm

    Bet I could write any arbitrary HTML code with ZC faster than you create snippet for it and drag it :)

    7
  43. 43
  44. 44

    This is LOL

    0
  45. 45

    I am with you on this too. I can code comfortably fast any way.
    We as designer/developers should all be developing our own Frameworks so that we can cut and paste our favourite codes on the fly.

    -3
  46. 46

    Incredible, I will help me a lot. Thanks.

    0
  47. 47

    Okay, this is pretty cool. Definitely going to try it out on my next project.

    0
  48. 48

    Wow, I’m going to give this a shot in Coda!

    0
  49. 49

    Very cool demo. Unfortunately the textmate version does almost none of the cool stuff. Hopefully that can be fixed, though maybe it’ll require the next version of Textmate.

    Tempting to try using this instead of something like HAML, though I still hate wading through pages and pages of HTML when the meaning and syntax can be nice and condensed.

    0
  50. 50

    Which is greater?

    Time saved by using this?

    Or time spent learning it?

    That’s the essential question.

    0

↑ Back to top