03.10.13

Emmet - полезный инструмент для создания HTML разметки. Часть 1

Emmet (ранее известный как Zen Coding) является инструментом для веб-разработки, который может значительно улучшить и облегчить работу с HTML и CSS. Эта статья посвящена возможностям Emmet, которые он предоставляет для быстрого создания разметки  HTML.

Содержание


В принципе, большинство текстовых редакторов позволяют хранить и повторно использовать часто используемые фрагменты кода, называемые "сниппеты". Хотя сниппеты и являются хорошим способом повышения производительности, все их реализации имеют общие недостатки: вы должны сначала определить сниппет и вы не можете расширить их при исполнении.
Emmet выводит идею сниппетов на совершенно новый уровень: вы вводите CSS-подобные выражения, которые динамически анализируются, и получаете результат в зависимости от введённой аббревиатуры. Emmet разработан и оптимизирован для HTML/XML и CSS, но может использоваться и для языков программирования.
Вы можете скачать Emmet в виде плагина для одного из редакторов, которых поддерживается не мало:
download-emmet-for-editors

Аббревиатуры

Аббревиатуры являются сердцем Emmet: эти специальные выражения обрабатываются во время выполнения и превращаются в структурированный блок кода, например HTML. Синтаксис аббревиатур похож на селекторы CSS, за исключением нескольких особых расширений для генерации кода. Таким образом, каждый веб-разработчик уже знает как его использовать.
Вот пример: эта аббревиатура
#page>div.logo+ul#navigation>li*5>a{Item $}
превращается в
<div id="page">
<div class="logo"></div>
<ul id="navigation">
<li><a href="">Item 1</a></li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
<li><a href="">Item 4</a></li>
<li><a href="">Item 5</a></li>
</ul>
</div>
... с помощью всего одного нажатия клавиши. Во многих редакторах (например, Eclipse, Sublime Text 2, Espresso и т.д.) плагины также будут генерировать надлежащие позиции tabstop, что даст вам возможность пройти между важными местами сгенерированного кода с помощью клавиши табуляции.
Аббревиатуры оптимизированы для HTML и XML, но не ограничиваются ими, и делают утомительное написание кода разметки сверхбыстрым. Изучите синтаксис аббревиатур, чтобы раскрыть всю мощь Emmet.

Синтаксис аббревиатур

Emmet использует аналогичный CSS-селекторам синтаксис, для описания позиций внутри генерируемого дерева и атрибутов элемента.

Элементы

Вы можете использовать имена элементов, как p или div для генерации HTML-тегов. Emmet не имеет предопределенного набора доступных имен тегов, поэтому вы можете написать любое слово и превратить его в тег: сdiv<div></div>, foo<foo></foo> и так далее.

Операторы вложения

Вложенные операторы используются для позиционирования элементов аббревиатуры внутри генерируемого дерева: должны ли они размещаться внутри или рядом с элементом контекста.

Вложение: >

Вы можете использовать оператор > для вложения элементов друг в друга:
div>ul>li
...станет
<div>
<ul>
<li></li>
</ul>
</div>

Добавление: +

Используйте оператор + для размещения элементов рядом друг с другом на том же уровне:
div+p+bq
...выведет
<div></div>
<p></p>
<blockquote></blockquote>

На уровень вверх: ^

С оператором > вы спускаетесь по сгенерированному дереву и позиции всех родственных элементов будут определятся в отношении самого глубокого элемента:
div+div>p>span+em
...будет преобразована в
<div></div>
<div>
<p><span></span><em></em></p>
</div>   
С оператором ^ вы можете подняться на один уровень вверх в дереве и изменить контекст, в котором должны отображаться следующие элементы:
div+div>p>span+em^bq
выведет ...
<div></div>
<div>
<p><span></span><em></em></p>
<blockquote></blockquote>
</div>
Вы можете использовать столько угодно операторов ^, каждый из них будет перемещать на один уровень вверх:
div+div>p>span+em^^^bq
...будет выводить
<div></div>
<div>
<p><span></span><em></em></p>
</div>
<blockquote></blockquote>

Повторение: *

С оператором * вы можете определить сколько раз должен быть выведен элемент:
ul>li*5
выведет ...
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>

Группировка: ()

Скобки используются в Emmet для группировки поддеревьев в сложные аббревиатуры:
div>(header>ul>li*2>a)+footer>p
...будет развёрнуто в
<div>
<header>
<ul>
<li><a href=""></a></li>
<li><a href=""></a></li>
</ul>
</header>
<footer>
<p></p>
</footer>
</div>
Если вы работаете с деревом DOM браузера, то думайте о группах как о фрагментах документа: каждая группа содержит аббревиатуру поддерево и все следующие элементы вставляются на том же уровне, в качестве первого элемента в группе.
Вы можете создавать группы внутри друг друга и объединять их с помощью оператора *:
(div>dl>(dt+dd)*3)+footer>p
...превратится
<div>
<dl>
<dt></dt>
<dd></dd>
<dt></dt>
<dd></dd>
<dt></dt>
<dd></dd>
</dl>
</div>
<footer>
<p></p>
</footer>
С группами, вы в буквальном смысле можете написать полную разметку страницы с помощью одной аббревиатуры, но пожалуйста, не делайте этого.

Операторы атрибутов

Операторы атрибутов используются для изменения атрибутов выводимых элементов. Например, в HTML и XML вы можете быстро добавить атрибут class к создаваемому элементу.

ID и CLASS

В CSS вы используете elem#id и elem.class , чтобы выбрать элементы с заданным id или атрибутом class. В Emmet вы можете использовать тот же синтаксис, чтобы добавить эти атрибуты к указанному элементу:
div#header+div.page+div#footer.class1.class2.class3
...выведет
<div id="header"></div>
<div class="page"></div>
<div id="footer" class="class1 class2 class3"></div>

Пользовательские атрибуты

Для добавления к элементу пользовательских атрибутов вы можете использовать нотацию [attr] (как в CSS):
td[title="Hello world!" colspan=3]
...выведет
<td title="Hello world!" colspan="3"></td>
  • Вы можете размещать внутри квадратных скобок неограниченное количество атрибутов.
  • Вам не обязательно указывать значения атрибутов: td[colspan title] сгенерирует <td colspan="" title=""> с табстопами внутри каждого пустого атрибута (если ваш редактор поддерживает их).
  • Для заключения в кавычки значений атрибутов вы можете использовать как одинарные, так и двойные кавычки.
  • Не надо заключать в кавычки значения, если они не содержат пробелы: td[title=hello colspan=3] будет работать.

Нумерация элементов: $

С помощью оператора * вы можете повторять элементы, но с $ их можно нумеровать. Оператор $ должен располагаться в имени элемента, имени атрибута или в значении атрибута, чтобы выводился порядковый номер повторяющихся элементов:
ul>li.item1*5
выведет ...
<ul>
<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
</ul>
Вы можете использовать несколько $ подряд, чтобы получить номер с нулями:
ul>li.item001*5
выведет ...
<ul>
<li class="item001"></li>
<li class="item002"></li>
<li class="item003"></li>
<li class="item004"></li>
<li class="item005"></li>
</ul>

Изменение начала и направления нумерации

С модификатором @ вы можете изменить направление нумерации (по возрастанию или по убыванию) и начальное значение.
Например, чтобы изменить направление, добавьте @- после $:
ul>li.item1*5
...даст результат
<ul>
<li class="item5"></li>
<li class="item4"></li>
<li class="item3"></li>
<li class="item2"></li>
<li class="item1"></li>
</ul>
Для изменения начального значения счетчика добавьте модификатор @N:
ul>li.item3*5
...преобразуется в
<ul>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
<li class="item6"></li>
<li class="item7"></li>
</ul>
Вы можете использовать эти модификаторы вместе:
ul>li.item3*5
...преобразуется в
<ul>
<li class="item7"></li>
<li class="item6"></li>
<li class="item5"></li>
<li class="item4"></li>
<li class="item3"></li>
</ul>

Текст: {}

Для добавления текста в элемент используйте фигурные скобки:
a{Click me}
...выведет
<a href="">Click me</a>
Обратите внимание, что {текст} используется и обрабатывается как отдельный элемент (как div, p и др.), но имеет особое значение, когда написан сразу после элемента. Например, a{click} и a>{click} дадут одинаковый результат, но a{click}+b{here} и a>{click}+b{here} нет:
<!-- a{click}+b{here} -->
<a href="">click</a><b>here</b>
 
<!-- a>{click}+b{here} -->
<a href="">click<b>here</b></a>
Во втором примере элемент <b> расположен внутри элемента <a>. И вот в чем разница: когда {текст} пишется сразу после элемента, то это не изменяет родительского контекста. Вот более сложный пример, показывающий, почему это важно:
p>{Click }+a{here}+{ to continue}
...даст результат
<p>Click <a href="">here</a> to continue</p>
В этом примере, чтобы написать Click here to continue внутри элемента <p>, мы четко движемся вниз по дереву, используя оператор > после p, но для элемента <a> мы его не используем, так как в нём нам нужно только слово, без изменения родительского контекста.
Для сравнения, та же самая аббревиатура, написанная без вложенного оператора >:
p{Click }+a{here}+{ to continue}
...выводит
<p>Click </p>
<a href="">here</a> to continue

Совет по форматированию аббревиатур

Когда вы ознакомитесь с синтаксисом аббревиатур Emmet, вы возможно захотите использовать некоторые элементы форматирования, чтобы сделать ваши аббревиатуры более читаемыми. Например, использовать пробелы между элементами и операторами, вроде этого:
(header > ul.nav > li*5) + footer
Но она не будет работать, потому что пробел - это символ остановки, на котором Emmet прекращает разбор аббревиатуры.
Многие пользователи ошибочно полагают, что каждая аббревиатура должна быть написана с новой строки, но они ошибаются: вы можете вводить и выполнять аббревиатуры где-угодно в тексте.

Типы элементов

в HTML- и XML-документах, при развертывании аббревиатур все их части трансформируются "на лету" в HTML/XML-теги. Но некоторые элементы, как например a или img, превращаются в элементы с предопределенными атрибутами: <a href=""></a> и <img src="" alt="" />. Откуда Emmet знает когда следует добавлять атрибуты?
Все описания элементов Emmet хранятся в файле snippets.json в следующем формате:
{
"html": {
"abbreviations": {
"a": "<a href=\"\">",
"link": "<link rel=\"stylesheet\" href=\"\" />"
...
},
"snippets": {
"cc:ie6": "<!--[if lte IE 6]>\n\t${child}|\n<![endif]-->"
...
}
},
 
"css": {
...
}
}
Как вы можете видеть, на первом уровне размещаются языки разметки, для которых определены элементы. Внутри этой секции расположены определения элементов, разделённые на две части: snippets и abbreviations.

Сниппеты

Сниппеты - это просто куски обычного кода, как и в большинстве редакторов. Вы можете напечатать здесь что угодно и оно будет выводится “как есть”, без каких-либо преобразований.

Аббревиатуры

Аббревиатуры - это на самом деле блоки с некоторыми подсказками. Emmet, в основном, используется для написания HTML/XML-тегов, объявление аббревиатуры использует XML-формат для описания элемента.
Emmet анализирует определение аббревиатуры и получает следующие данные:
  • имя элемента;
  • атрибуты по умолчанию;
  • порядок атрибутов;
  • значения по умолчанию атрибутов;
  • должен элемент содержать закрывающий тег или нет.
Давайте внимательнее посмотрим на объявления аббревиатур HTML на примере выше. Элемент link определяется как <link rel="stylesheet" href="" /> (двойные кавычки должны быть экранированы в JSON; или используйте одинарные кавычки). Это определение говорит, что этот тег, созданный для аббревиатуры link, должен быть назван link и должен содержать два атрибута: rel со значением по умолчанию “stylesheet” и href с пустым значением (именно в этом порядке), а также сгенерированный элемент не должен содержать закрывающий тег.
После раскрытия аббревиатуры link вы получите следующий результат в HTML:
<link rel="stylesheet" href="">
Вы можете переопределить значения атрибутов по умолчанию и добавить новые:
link[rel=prefetch title="Hello world"]
...преобразуется в
<link rel="prefetch" href="" title="Hello world">
Вы можете добавлять дочерние элементы:
link>xsl:apply-templates
...выведет
<link rel="stylesheet" href="">
<xsl:apply-templates></xsl:apply-templates>
</link>

Псевдонимы

В разделе abbreviations файла snippets.json вы можете также определять псевдонимы: сокращения для широко используемых аббревиатур. Псевдонимы могут использоваться для определения:
  • коротких названий для длинных имен тегов;
  • ссылок на часто используемые аббревиатуры.
В файле snippets.json вы можете найти следующие определения:
...
"html": {
"abbreviations": {
"bq": "blockquote",
"ol+": "ol>li"
}
}
В примере выше, при преобразование аббревиатуры bq, Emmet будет искать определение аббревиатуры blockquote. Если его не существует, он выведет просто <blockquote></blockquote>. Аббревиатура ol+ фактически даёт такой же результат как и ol>li.
Определение ol+, возможно, выглядят неоднозначно, поскольку оно содержит + в конце, который также является оператором добавления. Emmet корректно выполняет такие аббревиатуры и знак "плюс" оставлен по историческим причинам. Просто помните, что вам не нужно использовать +, чтобы создать псевдоним аббревиатуры.

Неявные имена тегов

Даже с таким мощным движком аббревиатур, который может развернуть большую HTML-конструкцию из короткой аббревиатуры, написание имен тегов может быть очень утомительным.
Во многих случаях вы можете пропускать ввод имён тегов и Emmet будет подставлять их за вас. Например, вместо div.content вы можете просто написать .content и получите <div class="content"></div>.

Как это работает

Когда вы разворачиваете аббревиатуру, Emmet пытается захватить родительский контекст, например элемента HTML, внутри которого вы выполняете аббревиатуру. Если контекст был схвачен успешно, Emmet использует его имя для решения неявных имён:
Emmet смотрит на имя родительского тега каждый раз, когда вы разворачиваете аббревиатуру с неявным именем. Вот как он разрешает имена для некоторых родительских элементов:
  • li для ul и ol
  • tr для table, tbody, thead и tfoot
  • td для tr
  • option для select и optgroup
Взгляните на некоторые эквиваленты аббревиатур с явными и неявными именами тегов:
.wrap>.content div.wrap>div.content
em>.info em>span.info
ul>.item*3 ul>li.item*3
table>#row$*4>[colspan=2] table>tr#row$*4>td[colspan=2]

Генератор “Lorem Ipsum”

Текст “Lorem ipsum” используется многими веб-разработчикам для тестирования того, как их шаблоны в формате HTML будут выглядеть с реальными данными. Часто разработчики используют услуги третьих сторон для создания текста “Lorem ipsum”, но теперь вы можете сделать это прямо в вашем редакторе. Просто выполните аббревиатуры lorem или lipsum, чтобы получить следующий сниппет:
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?
lorem не просто обычный сниппет - это на самом деле генератор. Каждый раз, когда вы выполняете его, он будет генерировать 30 слов фиктивного текста, разделённого на несколько предложений.
Вы можете указать, сколько слов должно быть сгенерировано. Например, lorem100 создаст 100 слов.
Вы можете использовать генератор lorem внутри повторяющихся элементов, чтобы создать теги, полностью заполненные случайными предложениями. Например, аббревиатура p*4&gt;lorem сгенерирует следующее:
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!</p>
<p>Ad dolore dignissimos asperiores dicta facere optio quod commodi nam tempore recusandae. Rerum sed nulla eum vero expedita ex delectus voluptates rem at neque quos facere sequi unde optio aliquam!</p>
<p>Tenetur quod quidem in voluptatem corporis dolorum dicta sit pariatur porro quaerat autem ipsam odit quam beatae tempora quibusdam illum! Modi velit odio nam nulla unde amet odit pariatur at!</p>
<p>Consequatur rerum amet fuga expedita sunt et tempora saepe? Iusto nihil explicabo perferendis quos provident delectus ducimus necessitatibus reiciendis optio tempora unde earum doloremque commodi laudantium ad nulla vel odio?</p>