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


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…


…and see this as the output?

<div id="content">

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:


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

Downloads (Full Support)

Downloads (Partial Support, “Expand Abbreviation” Only)

Now, let’s see how these tools work.

Expand Abbreviation

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…


…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…


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

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.


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

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

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
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>

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

Key Bindings

  • 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

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

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

Partial Support (“Expand Abbreviation” Only)

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.


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!



  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.

  1. 1

    Cool !!!

    This should be a Code Lobster plug-in =(

  2. 252

    Cool coding for html but where is the info on css code using zen coding. please let me know.

  3. 503

    HTML/CSS/JavaScript aren’t meant to be coded by machines. You need a smarter race for that.

  4. 754

    gracias utilisimo esta en mis top 5

  5. 1005

    How to Key Bindings with Zen Coding for Notepad++ ?

  6. 1256

    Brand new plugin for NetBeans! Full support to Expand Abbreviation!

  7. 1507

    Thank you very much for sharing this indispensable tool. What a pleasure to write html now !!!

  8. 1758

    Honestly, guys who say that writing html/css is just copying/pasting snippets or templates should consider not writing any html/css and stick to php and databases.

    As a frontend webdeveloper/designer I have to deal with such thinking on regular basis and I’m fed up with html written by the backend devs, as it’s usually based on idea of divitis and classitis “because it’s quicker”.

    If you’re into databases and php, stick with that. And let the right people do the frontend job the right way with the right tools.

    Especially that if you consider HTML5 coming with even more tags or imagine complex layouts, then no snippets could be useful, you wanna be quick and flexible.

  9. 2009

    I try this week end to create new abbreviations and snippets in the Zend codding.js file. It work very well. After that I try to add no xml outup. For example : div>p>php where the php abbreviation is ‘php': ‘<?php ?>’. This doesnt work, I have output <php />.

    I would like to know if there is a way no have a no xml output ? May be you try it ? The idea it’s to you use zen coding for common html/php template or for jquery script. For example script>p.test>click give the script tag and $(‘p.test’).click(function(){ … }) , or p>echo give <p><?php echo ?><p/>.

    Thank you !!

  10. 2260


  11. 2511

    Its great but i still love Emacs with yasnippet or auto-complete

  12. 2762

    I had two major changes in my lifespan, the first time I meet “Lucy in the sky with diamonds” and the first time I used zen coding, I really don’t know how to thank you !!!

  13. 3013

    I think some are missing the point of this. Zen Coding will never replace manual coding. It’s simply a helper. In the same way as you use copy and paste, you’ll only use Zen Coding when you need it. Who copies and pastes every line of HTML they write?

    Anyone who makes a lot of HTML templates with navbars, tables with product specifications and so on will find this immensely helpful.

    I’ve got it on Notepad++ and while I don’t use it all the time but when I do use it it’s a joy to be able to create a lot of HTML within a few seconds and the IDs and class names already in place.

  14. 3264

    A more direct link to the Vim solution: https://github.com/mattn/zencoding-vim

  15. 3515

    Fantastic! I’m using it in Espresso for Mac Os X, great time saver.
    The music in the video is great.

  16. 3766

    Is {this is a test} the way to specify the innerhtml of an element? it works as shown below

    div#box>div.sub{Item $}*3

  17. 4017

    It’s a brilliant step forward. Many thanks to Sergey for putting effort into this.

  18. 4268

    How about a character to make a new sibling to the parent? like + adds a sibling maybe exit to the parent level via <


    would create





  19. 4519

    I simply can’t get Zen Coding to work in either Coda (1.7) or TextMate (1.5.10) (with Python 2.6) on OS X 10.4.11 – nothing happens in Coda, and TextMate throws this:

    Traceback (most recent call last):
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/expand_abbreviation.py”, line 7, in ?
    import zencoding
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/__init__.py”, line 1, in ?
    import utils
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/utils.py”, line 71
    return text[pos] if pos < len(text) else ''
    SyntaxError: invalid syntax

    I can't find any 'minimum system' information, and the various pages on the project (Google Code, the forked project on GitHub – 'report an issue' throws a 404!, and the MacRabbit page) have inconsistent info and links to deprecated versions. Finally (reading issues on Google Code) the TextMate bundle shortcut defaults clash with the existing HTML bundle, but to fix this you'd have to fork'n'fix, or edit them in TextMate. Installing TextMate bundles from the CL also fails, as there's nothing listed in the usual bundle repos. None of this facilitates 'ease of use' or 'swift installation', so – although I really wanted this in TextMate and Coda – it seems the will beyond Expresso is no longer there for the developer, who is now on the Expresso team.

  20. 4770


    No support for HTML5 tags

  21. 5021

    Just try it! Believe me, you’ll change your mind and will re-phrase your comments.

  22. 5272

    i LoOOOVe it!! its going to save me so much time :)

  23. 5523

    Zen code means as unobtrusive typing as possible. Zen coding brings you exactly that.

    It’s a typing tool not a coding tool. Code your way.

    Thanks for that Sergey
    – T –

  24. 5774

    This is a very very helpful tool. I wouldn’t use it for all my coding, but it’s very intuitive, I picked it up really fast, and for some things, this would save me tons of time. Time is very important to me, and that’s why this tool works.

    Thanks (Using Zen Coding on Notepad++)

  25. 6025

    A great tool. Too bad I discovered it now.

    @Thomas things are improving. Let me quote the developer from his post

    “It is certainly possible to develop support for HTML 5 include all the features of CSS 3, to realize an even greater number required daily patterns. And this is done, but in the second turn. First of all, I plan to seriously change the way a set of HTML-code and method of storage library of templates in the packages. And of course to improve the consistency and intuitiveness of abbreviations and shortcuts”

    So wait patiently and you will get the good news soon.


  26. 6276

    love it!! thanks!

  27. 6527

    Well said.

  28. 6778

    this is really great effort but difficult to use difficult to handle but if you get practice more on this tool it would be great for html coders :)

  29. 7029

    naturally like your web-site however you have to test the spelling on quite a few of your posts. A number of them are rife with spelling issues and I find it very bothersome to tell the reality then again I will certainly come again again.

  30. 7280

    Is there any way to collapse (or undo expand) the code? or is it tool specific implementation?

    let’s say… it takes few trials to come to this final structure for wrapping with abbreviation : div#header>ul#navigation>li.times$*>a>span

    I can always do Ctr Z in notepad++, but it’s just one timer revert, anything more robust?

  31. 7531

    Thanks Sergey
    After started using zen coding, my html coding time is reduced by 50%.

  32. 7782

    Nice tool. I was wondering about adding snippets to it that zen can not find. Is this possible? Thanks.

  33. 8033

    Why would you install Aptana and ZenCoding over and over again? There is no need for a loop statement here. Your coding is flawed.

  34. 8284

    Rather than learning another syntax, why not just use a code generator like Dreamweaver? I don’t have to memorize all this stuff, and still faster HTML. I don’t get it?

  35. 8535

    Awesome tool. Using on new project.

    Thanks for post this.

  36. 8786

    I agree with Peter!
    It would be nice if you could use the opposite bracket (<) for going up one level. So you could code the whole layout before expanding the abbreviation!

  37. 9037

    Very cool~
    Can zen-coding used in javascript document?

  38. 9288

    i have installed zen coding on sublime text 2…
    when i type ul>li it just expands to ul><li></li>
    Please help me out ?

  39. 9539

    BHaskar Chaudhary

    September 5, 2012 7:41 am

    Looks great but sadly no support for notepad++ – which i guess is the most widely used code editor.
    Can we expect it to be supported any time soon ?

  40. 9790
  41. 10041

    awesome work
    it would be nice if support write inline style using abbrevations !

  42. 10292

    Also, this is the best method of writing XML as well.

  43. 10543

    Really awesome tool !!

  44. 10794

    Demo Links are not working its broken:


↑ Back to top