<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Веб-стандарты &#187; Статьи</title>
	<atom:link href="http://web-standards.ru/category/articles/feed/" rel="self" type="application/rss+xml" />
	<link>http://web-standards.ru</link>
	<description>Российское сообщество разработчиков</description>
	<lastBuildDate>Mon, 20 Feb 2012 21:02:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Как работает nth-child</title>
		<link>http://web-standards.ru/articles/nth-child/</link>
		<comments>http://web-standards.ru/articles/nth-child/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 12:55:20 +0000</pubDate>
		<dc:creator>Крис Койер</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[вёрстка]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/nth-child/</guid>
		<description><![CDATA[<p>Существует такой селектор, точнее псевдокласс, называемый <code>:nth-child</code>. Вот пример его использования:</p>

<pre>
	<code>UL LI:nth-child(3n+3) {</code>
	<code>    color:#CCC;</code>
	<code>    }</code>
</pre>

<p>Что делает CSS-код, приведенный выше? Он выбирает каждый третий элемент внутри маркированного списка: это 3-й, 6-й, 9-й, 12-й и т.д. Давайте посмотрим, как именно работает это выражение и что еще можно сделать с помощью <code>:nth-child</code>.</p>

<p>Всё зависит от того, что находится между скобками. Селектор <code>:nth-child</code> принимает два ключевых слова: <code>even</code> и <code>odd</code>. Тут всё просто: <code>even</code> выбирает чётные элементы, такие как 2-ой, 4-ый, 6-ой и т.д., а <code>odd</code> выбирает нечётные элементы, такие как 1-й, 3-й, 5-й и т.д.</p>

<p>Как видно из первого примера, <code>:nth-child</code> также принимает в качестве параметра выражения. В том числе и простейшие уравнения, иначе говоря, просто числа. Если поставить их в скобки, будет выбран только один элемент с соответствующим номером. Например, вот как выбрать только пятый элемент:</p>

<pre>
	<code>UL LI:nth-child(5) {</code>
	<code>    color:#CCC;</code>
	<code>    }</code>
</pre>

<p>Однако давайте вернемся к <code>3n+3</code> из первого примера. Как он работает и почему выбирается каждый третий элемент? Весь фокус в понимании переменной <code>n</code> и приведенного алгебраического уравнения. Подумайте об <code>n</code>, как о начинающемся с нуля множестве целых чисел. Потом дополните уравнение. Так <code>3n</code> это <code>3×n</code>, а все уравнение вместе это <code>(3×n)+3</code>. Теперь, подставляя вместо <code>n</code> числа больше или равные нулю, мы получим:</p>

<ul>
	<li>(3 × 0) + 3 = 3 = 3-й элемент</li>
	<li>(3 × 1) + 3 = 6 = 6-й элемент</li>
	<li>(3 × 2) + 3 = 9 = 9-й элемент и т.д.</li>
</ul>

<p>А как насчёт <code>:nth-child(2n+1)</code>?</p>

<ul>
	<li>(2 × 0) + 1 = 1 = 1-й элемент</li>
	<li>(2 × 1) + 1 = 3 = 3-й элемент</li>
	<li>(2 × 2) + 1 = 5 = 5-й элемент и т.д.</li>
</ul>

<p>Так, стоп! Это ведь то же самое, что и <code>odd</code>. Тогда, возможно, не стоит использовать это выражение? Но разве в этом случае мы не подвергаем наш первый пример излишнему усложнению? Что, если вместо <code>3n+3</code> мы запишем <code>3n+0</code> или ещё проще <code>3n</code>?</p>

<ul>
	<li>(3 × 0) = 0 = ничего нет</li>
	<li>(3 × 1) = 3 = 3-й элемент</li>
	<li>(3 × 2) = 6 = 6-й элемент</li>
	<li>(3 × 3) = 9 = 9-й элемент и т.д.</li>
</ul>

<p>Итак, как вы можете видеть, результат получится такой же, а значит, нет необходимости в <code>+3</code>. Мы можем использовать и отрицательные значения <code>n</code>, с таким же успехом, как и вычитание в уравнениях. Например, <code>4n-1</code>:</p>

<ul>
	<li>(4 × 0) – 1 = –1 = ничего нет</li>
	<li>(4 × 1) – 1 = 3 = 3-й элемент</li>
	<li>(4 × 2) – 1 = 7 = 7-й элемент и т.д.</li>
</ul>

<p>Использование <code>-n</code> может показаться странным — ведь если конечный результат отрицательный, то никакие элементы в выборку не попадут. Но если дополнить уравнение и снова сделать результат положительным, то выборка окажется довольно интересной: при помощи неё можно будет получить первые <code>n</code> элементов, например так: <code>-n+3</code>:</p>

<ul>
	<li>–0 + 3 = 3 = 3-й элемент</li>
	<li>–1 + 3 = 2 = 2-й элемент</li>
	<li>–2 + 3 = 1 = 1-й элемент</li>
	<li>–3 + 3 = 0 = ничего нет и т.д.</li>
</ul>

<p>На SitePoint есть хороший справочник <a href="http://reference.sitepoint.com/css/understandingnthchildexpressions">с милой табличкой</a>, которую я бесстыдно опубликую здесь:</p>

<table>
<tr>
	<th>n</th>
	<th>2n+1</th>
	<th>4n+1</th>
	<th>4n+4</th>
	<th>4n</th>
	<th>5n-2</th>
	<th>-n+3</th>
</tr>
<tr>
	<td>0</td>
	<td>1</td>
	<td>1</td>
	<td>4</td>
	<td>–</td>
	<td>–</td>
	<td>3</td>
</tr>
<tr>
	<td>1</td>
	<td>3</td>
	<td>5</td>
	<td>8</td>
	<td>4</td>
	<td>3</td>
	<td>2</td>
</tr>
<tr>
	<td>2</td>
	<td>5</td>
	<td>9</td>
	<td>12</td>
	<td>8</td>
	<td>8</td>
	<td>1</td>
</tr>
<tr>
	<td>3</td>
	<td>7</td>
	<td>13</td>
	<td>16</td>
	<td>12</td>
	<td>13</td>
	<td>–</td>
</tr>
<tr>
	<td>4</td>
	<td>9</td>
	<td>17</td>
	<td>20</td>
	<td>16</td>
	<td>18</td>
	<td>–</td>
</tr>
<tr>
	<td>5</td>
	<td>11</td>
	<td>21</td>
	<td>24</td>
	<td>20</td>
	<td>23</td>
	<td>–</td>
</tr>
</table>

<h2>Поддержка браузерами</h2>

<p>Селектор <code>:nth-child</code> — один из немногих CSS-селекторов, который почти полностью поддерживается в современных браузерах и абсолютно не поддерживается в IE, даже в IE8. Поэтому когда дело доходит до его использования, и конечный результат сделан по технологии прогрессивного улучшения — вы можете смело использовать его для некоторых оформительских элементов, вроде расцветки строк таблицы. Однако не стоит применять его в более серьезных случаях. Например, полагаться на него в раскладке сайта или удалять правое поле из каждого третьего блока в сетке три на три, чтобы они вошли в ряд.</p>

<p>Спасением здесь может послужить библиотека <a href="http://jquery.com/">jQuery</a>, которая реализует поддержку всех CSS-селекторов, включая <code>:nth-child</code>, даже в Internet Explorer.</p>

<h2>Всё равно неясно?</h2>

<p>Я не большой поклонник фразы <q>я лучше воспринимаю визуальную информацию</q>. И вы, конечно, тоже. Но примеры являются чрезвычайно полезными именно в таких ситуациях. Чтобы облегчить понимание, я сделал <a href="http://css-tricks.com/examples/nth-child-tester/">небольшую тестовую страничку</a>. На ней вы сможете написать свои уравнения и ниже увидеть то, что попадет в выборку.</p>

<p>Также загляните на страничку <a href="http://css-tricks.com/9657-useful-nth-child-recipies/">полезных рецептов <code>:nth-child</code></a>, там вы сможете найти код для наиболее распространенных случаев.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://css-tricks.com/5452-how-nth-child-works/">How nth-child Works</a>» <a href="http://snook.ca/about/">Криса Койера</a> (Chris Coyier), опубликованной на сайте «<a href="http://css-tricks.com/">CSS-Tricks</a>».</p>]]></description>
			<content:encoded><![CDATA[<p>Существует такой селектор, точнее псевдокласс, называемый <code>:nth-child</code>. Вот пример его использования:</p>

<pre>
	<code>UL LI:nth-child(3n+3) {</code>
	<code>    color:#CCC;</code>
	<code>    }</code>
</pre>

<p>Что делает CSS-код, приведенный выше? Он выбирает каждый третий элемент внутри маркированного списка: это 3-й, 6-й, 9-й, 12-й и т.д. Давайте посмотрим, как именно работает это выражение и что еще можно сделать с помощью <code>:nth-child</code>.</p>

<p>Всё зависит от того, что находится между скобками. Селектор <code>:nth-child</code> принимает два ключевых слова: <code>even</code> и <code>odd</code>. Тут всё просто: <code>even</code> выбирает чётные элементы, такие как 2-ой, 4-ый, 6-ой и т.д., а <code>odd</code> выбирает нечётные элементы, такие как 1-й, 3-й, 5-й и т.д.</p>

<p>Как видно из первого примера, <code>:nth-child</code> также принимает в качестве параметра выражения. В том числе и простейшие уравнения, иначе говоря, просто числа. Если поставить их в скобки, будет выбран только один элемент с соответствующим номером. Например, вот как выбрать только пятый элемент:</p>

<pre>
	<code>UL LI:nth-child(5) {</code>
	<code>    color:#CCC;</code>
	<code>    }</code>
</pre>

<p>Однако давайте вернемся к <code>3n+3</code> из первого примера. Как он работает и почему выбирается каждый третий элемент? Весь фокус в понимании переменной <code>n</code> и приведенного алгебраического уравнения. Подумайте об <code>n</code>, как о начинающемся с нуля множестве целых чисел. Потом дополните уравнение. Так <code>3n</code> это <code>3×n</code>, а все уравнение вместе это <code>(3×n)+3</code>. Теперь, подставляя вместо <code>n</code> числа больше или равные нулю, мы получим:</p>

<ul>
	<li>(3 × 0) + 3 = 3 = 3-й элемент</li>
	<li>(3 × 1) + 3 = 6 = 6-й элемент</li>
	<li>(3 × 2) + 3 = 9 = 9-й элемент и т.д.</li>
</ul>

<p>А как насчёт <code>:nth-child(2n+1)</code>?</p>

<ul>
	<li>(2 × 0) + 1 = 1 = 1-й элемент</li>
	<li>(2 × 1) + 1 = 3 = 3-й элемент</li>
	<li>(2 × 2) + 1 = 5 = 5-й элемент и т.д.</li>
</ul>

<p>Так, стоп! Это ведь то же самое, что и <code>odd</code>. Тогда, возможно, не стоит использовать это выражение? Но разве в этом случае мы не подвергаем наш первый пример излишнему усложнению? Что, если вместо <code>3n+3</code> мы запишем <code>3n+0</code> или ещё проще <code>3n</code>?</p>

<ul>
	<li>(3 × 0) = 0 = ничего нет</li>
	<li>(3 × 1) = 3 = 3-й элемент</li>
	<li>(3 × 2) = 6 = 6-й элемент</li>
	<li>(3 × 3) = 9 = 9-й элемент и т.д.</li>
</ul>

<p>Итак, как вы можете видеть, результат получится такой же, а значит, нет необходимости в <code>+3</code>. Мы можем использовать и отрицательные значения <code>n</code>, с таким же успехом, как и вычитание в уравнениях. Например, <code>4n-1</code>:</p>

<ul>
	<li>(4 × 0) – 1 = –1 = ничего нет</li>
	<li>(4 × 1) – 1 = 3 = 3-й элемент</li>
	<li>(4 × 2) – 1 = 7 = 7-й элемент и т.д.</li>
</ul>

<p>Использование <code>-n</code> может показаться странным — ведь если конечный результат отрицательный, то никакие элементы в выборку не попадут. Но если дополнить уравнение и снова сделать результат положительным, то выборка окажется довольно интересной: при помощи неё можно будет получить первые <code>n</code> элементов, например так: <code>-n+3</code>:</p>

<ul>
	<li>–0 + 3 = 3 = 3-й элемент</li>
	<li>–1 + 3 = 2 = 2-й элемент</li>
	<li>–2 + 3 = 1 = 1-й элемент</li>
	<li>–3 + 3 = 0 = ничего нет и т.д.</li>
</ul>

<p>На SitePoint есть хороший справочник <a href="http://reference.sitepoint.com/css/understandingnthchildexpressions">с милой табличкой</a>, которую я бесстыдно опубликую здесь:</p>

<table>
<tr>
	<th>n</th>
	<th>2n+1</th>
	<th>4n+1</th>
	<th>4n+4</th>
	<th>4n</th>
	<th>5n-2</th>
	<th>-n+3</th>
</tr>
<tr>
	<td>0</td>
	<td>1</td>
	<td>1</td>
	<td>4</td>
	<td>–</td>
	<td>–</td>
	<td>3</td>
</tr>
<tr>
	<td>1</td>
	<td>3</td>
	<td>5</td>
	<td>8</td>
	<td>4</td>
	<td>3</td>
	<td>2</td>
</tr>
<tr>
	<td>2</td>
	<td>5</td>
	<td>9</td>
	<td>12</td>
	<td>8</td>
	<td>8</td>
	<td>1</td>
</tr>
<tr>
	<td>3</td>
	<td>7</td>
	<td>13</td>
	<td>16</td>
	<td>12</td>
	<td>13</td>
	<td>–</td>
</tr>
<tr>
	<td>4</td>
	<td>9</td>
	<td>17</td>
	<td>20</td>
	<td>16</td>
	<td>18</td>
	<td>–</td>
</tr>
<tr>
	<td>5</td>
	<td>11</td>
	<td>21</td>
	<td>24</td>
	<td>20</td>
	<td>23</td>
	<td>–</td>
</tr>
</table>

<h2>Поддержка браузерами</h2>

<p>Селектор <code>:nth-child</code> — один из немногих CSS-селекторов, который почти полностью поддерживается в современных браузерах и абсолютно не поддерживается в IE, даже в IE8. Поэтому когда дело доходит до его использования, и конечный результат сделан по технологии прогрессивного улучшения — вы можете смело использовать его для некоторых оформительских элементов, вроде расцветки строк таблицы. Однако не стоит применять его в более серьезных случаях. Например, полагаться на него в раскладке сайта или удалять правое поле из каждого третьего блока в сетке три на три, чтобы они вошли в ряд.</p>

<p>Спасением здесь может послужить библиотека <a href="http://jquery.com/">jQuery</a>, которая реализует поддержку всех CSS-селекторов, включая <code>:nth-child</code>, даже в Internet Explorer.</p>

<h2>Всё равно неясно?</h2>

<p>Я не большой поклонник фразы <q>я лучше воспринимаю визуальную информацию</q>. И вы, конечно, тоже. Но примеры являются чрезвычайно полезными именно в таких ситуациях. Чтобы облегчить понимание, я сделал <a href="http://css-tricks.com/examples/nth-child-tester/">небольшую тестовую страничку</a>. На ней вы сможете написать свои уравнения и ниже увидеть то, что попадет в выборку.</p>

<p>Также загляните на страничку <a href="http://css-tricks.com/9657-useful-nth-child-recipies/">полезных рецептов <code>:nth-child</code></a>, там вы сможете найти код для наиболее распространенных случаев.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://css-tricks.com/5452-how-nth-child-works/">How nth-child Works</a>» <a href="http://snook.ca/about/">Криса Койера</a> (Chris Coyier), опубликованной на сайте «<a href="http://css-tricks.com/">CSS-Tricks</a>».</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/nth-child/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Почему у нас нет селектора по родителю</title>
		<link>http://web-standards.ru/articles/parent-selector/</link>
		<comments>http://web-standards.ru/articles/parent-selector/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 11:23:05 +0000</pubDate>
		<dc:creator>Джонатан Снук </dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[методика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/parent-selector/</guid>
		<description><![CDATA[<p>Относительно регулярно я вижу дискуссии о том, должен ли CSS включать селектор по родителю и, пока я не выяснил, как работает движок браузера, сам строил предположения по этому поводу.</p>

<p>Вкратце: <em>производительность</em>.</p>

<h2>Как работает CSS</h2>

<p>В связи с моей работой я делаю много тестов производительности. Для определения «узких мест» мы используем массу приложений. Например, Google Page Speed, который дает рекомендации по улучшению производительности JavaScript и рендеринга. Прежде чем я перейду к рассмотрению этих рекомендаций, нам нужно разобраться как браузеры работают с CSS</p>

<h2>Стиль элемента применяется в момент его создания</h2>

<p>Мы часто рассматриваем веб-страницы как полноценные документы, наполненные элементами и содержимым. Между тем, браузеры разработаны так, чтобы обрабатывать документ потоково. Они начинают получать документ с сервера и могут начать его отображать до момента полной загрузки. Каждый узел анализируется и отображается в окне по мере получения.</p>

<p>Взгляните на этот документ:</p>

<pre>
	<code>&lt;body&gt;</code>
	<code>    &lt;div id="content"&gt;</code>
	<code>        &lt;div class="module intro"&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>        &lt;/div&gt;</code>
	<code>        &lt;div class="module"&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum &lt;span&gt;Test&lt;/span&gt;&lt;/p&gt;</code>
	<code>        &lt;/div&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>&lt;/body&gt;</code>
</pre>

<p>Браузер начинает сначала и видит элемент <code>&lt;body&gt;</code>. В этот момент времени считается, что этот узел не имеет дочерних узлов. Ничего более не рассматривается. Браузер определяет соответствующий ему обобщенный набор стилей и применяет его к элементу. Какой шрифт, цвет, интерлиньяж? После того, как это все будет выяснено, элемент отображается на экране.</p>

<p>Далее браузер видит элемент <code>&lt;div&gt;</code> со значением атрибута ID <code>content</code>. И снова в этот момент времени браузер считает его пустым. Он не рассматривает другие элементы. Как только браузер рассчитает стиль, элемент отображается на экране. Затем браузер определяет нужно ли перерисовать <code>&lt;body&gt;</code> — стал ли элемент шире или выше? Я подозреваю, что там есть масса других проверок, но изменение ширины и высоты — самый распространенный способ повлиять на отображение родительского узла.</p>

<p>Процесс продолжается, пока браузер не достигнет корневого узла документа.</p>

<p>Вот как выглядит визуализация процессов перерисовки в Firefox:</p>

<iframe width="510" height="382" src="http://www.youtube.com/embed/ZTnIxIA5KGw" frameborder="0" class="video-player"></iframe>

<h2>CSS селекторы анализируется справа налево</h2>

<p>Чтобы определить, применяется ли CSS-правило к определенному элементу, браузер рассматривает селектор справа налево.</p>

<p>Если у вас есть селектор <code>body div#content p { color: #003366; }</code>, то, когда каждый элемент появляется на странице, браузер проверяет, является ли он параграфом. Если да, он начинает подниматься вверх по DOM и ищет <code>&lt;div&gt;</code> со значением атрибута ID равным <code>content</code>. Если он его находит, то продолжает подниматься по DOM пока не найдет <code>&lt;body&gt;</code>.</p>

<p>Таким образом, читая селектор справа налево, браузер значительно быстрее может определить применяется ли правило к элементу. Чтобы определить, какой из селекторов обладает большей производительностью, нужно выяснить, как много узлов придется рассмотреть, чтобы определить, можно ли применить правило к элементу.</p>

<h2>Правила</h2>

<p>Возвращаясь к Page Speed, давайте рассмотрим <a href="http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">несколько его рекомендаций</a>:</p>

<ul>
	<li>Избегайте селектора по потомку: <code>.content .sidebar</code>;</li>
	<li>Избегайте селектора по дочернему элементу: <code>.content &gt; .sidebar</code> и селектора по следующему элементу: <code>.content + .sidebar</code>.</li>
</ul>

<p>Конечно, селекторы по ID — самые быстрые. Проверить применимость селектора <code>#content</code> к рассматриваемому элементу можно очень быстро. Есть у него этот ID или нет? Селекторы по классу практически такие же быстрые, так как нет никаких связанных элементов, которые надо проверять.</p>

<p>Селекторы по потомкам, такие как <code>.content .sidebar</code> — более ресурсоемкие, так как, чтобы определить надо ли применять правило к <code>.sidebar</code>, браузер должен найти <code>.content</code>. Cелектор по дочернему элементу, например, <code>.content &gt; .sidebar</code>, лучше селектора по потомку, так как браузер должен проверить только один элемент вместо множества.</p>

<p class="note">К сожалению, селекторы <code>+</code> и <code>&gt;</code> не поддерживаются IE6. Так что если его поддержка актуальна для вас, то про них придется забыть. Примечание переводчика.</p>

<h2>Селектор по тегу и универсальный селектор</h2>

<p>В рамках рекомендации избегать селекторов по потомку, дочернему или следующему элементам, рекомендуется избегать универсального селектора и селектора по тегу.</p>

<p>Рассмотрим следующий пример:</p>

<pre><code>#content * { color: #039; }</code></pre>

<p>Так как в селекторе присутствует ID, то можно подумать, что этот селектор обрабатывается очень быстро. Проблема в том, что браузер обрабатывает селектор справа налево и сперва проверяется универсальный селектор. Для того чтобы браузер мог определить, должен ли цвет текста элемента быть тёмно-синим, надо проверить каждый предок элемента, пока не будет найден предок с атрибутом ID равным <code>content</code> или не будет достигнут корень документа.</p>

<p>И это должно быть сделано для каждого элемента на странице.</p>

<p>Теперь, когда мы понимаем, как элемент обрабатывается, как определяется применимость правил к элементу, давайте рассмотрим пример.</p>

<h2>Почему IE долго не поддерживал <code>:last-child</code></h2>

<p>Все жаловались: у всех браузеров, кроме IE, есть поддержка <code>:last-child</code> (она появилась только в IE9!) Некоторые могли подумать <q>насколько же сложнее сделать :last-child, если уже реализован :first-child?</q></p>

<p>Давайте представим, что мы — браузер и мы парсим документ-пример, который я приводил ранее.</p>

<pre>
	<code>.module &gt; p:first-child { color: red; } /* Первое правило */</code>
	<code>.module &gt; p:last-child { color: blue; } /* Второе правило */</code>
</pre>

<p>Когда мы рассматриваем внутренности первого <code>&lt;div&gt;</code>, мы видим, что там есть параграф. Браузер видит что-то вроде этого:</p>

<pre>
	<code>&lt;div class="module"&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
</pre>

<p>Нужно ли применить первое правило к параграфу? Да, это параграф; да, это первый дочерний узел; и, да, это непосредственный потомок элемента с классом <code>module</code>.</p>

<p>Нужно ли применить к этому параграфу второе правило? На данный момент это последний элемент. Но мы могли ещё не загрузить все элементы и не можем быть уверены, что он останется последним.</p>

<p>Вне зависимости от того, как решать эту дилемму, у нас возникает необходимость повторного анализа стилей двух узлов для каждого нового узла, который мы добавляем в DOM. Если я добавлю ещё один параграф следом за первым, мы должны так же повторно перерассчитать стили, которые применяются к предыдущему параграфу.</p>

<h2>Как на самом деле это делает браузер?</h2>

<p>Я не мог сказать с абсолютной уверенностью, как браузеры парсят <code>:last-child</code>, так что я создал несколько тестов:</p>

<ul>
	<li><a href="http://testing.snook.ca/css-1.html">Статическая HTML-страница</a>;</li>
	<li><a href="http://testing.snook.ca/css-1.php">Рендеринг с паузами в одну секунду</a>.</li>
</ul>

<p>Первый пример весьма скучен. В любом браузере, включая IE9, всё отображается корректно. Внутри <code>&lt;div&gt;</code> первый элемент красный, а последний синий. Но посмотрите на второй пример, и вы увидите интересные отличия в поведении браузеров.</p>

<p>Второй пример приостанавливается перед добавлением каждого параграфа в <code>&lt;div&gt;</code>.</p>

<p>В Firefox первый параграф изначально отображается синим. Когда загружается второй параграф, первый становится красным и второй — синим. Когда загружается третий параграф, второй отображается цветом по умолчанию и третий отображается синим. Firefox рассматривает каждый элемент, который был загружен в качестве последнего элемента, пока не будет загружен ещё один.</p>

<p>В Safari, Chrome и Opera мы увидим другой подход. Первый параграф красный. Второй отображается чёрным. Последний параграф отображается чёрным, пока браузер не получит закрывающий тег <code>&lt;/div&gt;</code>. В этот момент последний параграф становится синим. Эти браузеры не рассматривают элемент как последний, пока не будет закрыт родительский.</p>

<p>В Internet Explorer 9 Beta я нашел интересный баг. В то время, как статическая страница отображается корректно, версия с паузами отрабатывает с любопытным побочным эффектом. Первый параграф синий, второй параграф синий и затем — третий. Когда закрывающий тег <code>&lt;/div&gt;</code> загружен, предпоследний параграф меняет цвет на чёрный. IE9 пытается обрабатывать селектор как Webkit и Opera, но… м-м… не выходит. Надо бы отправить багрепорт в Microsoft.</p>

<h2>Почему у нас нет селектора по родителю?</h2>

<p>Уже дано достаточно пояснений, чтобы можно было вернуться к оригинальному вопросу. Проблема не в том, что у нас не может быть селектора по родителю. Проблема в том, что мы столкнемся с проблемами быстродействия, когда дело дойдет до определения того, какие CSS-правила применимы к данному элементу. Если Google Page Speed не рекомендует использование универсальных селекторов, то можно гарантировать, что селектор по родителю будет первым в списке ресурсоемких селекторов, намного опережая все проблемы с производительностью, которые могут быть вызваны использованием универсального селектора.</p>

<p>Давайте посмотрим почему. Первым делом давайте приведём пример синтаксиса для селектора по родителю.</p>

<pre><code>div.module:has(span) { color: green; }</code></pre>

<p>Проблема в том, что мы не можем определить применимость правила до тех пор, либо пока мы не найдем соответствия, либо пока все элементы, дочерние по отношению к родителю данного, не будут загружены. Ввиду этого мы должны оценивать правило и все остальные (в случае наличия специфических особенностей), применяющиеся к элементу, для каждого дочернего элемента, который мы загружаем.</p>

<p>Посмотрите на часть нашего документа:</p>

<pre>
	<code>&lt;div class="module"&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum &lt;span&gt;Test&lt;/span&gt;&lt;/p&gt;</code>
	<code>&lt;/div&gt;</code>
</pre>

<p>Исходя из того, что мы видим, <code>.module</code> будет отображён без использования правила, применяемого селектором по родителю. Когда будет загружен первый элемент <code>&lt;p&gt;</code>, нужно повторно оценить применимость селектора по родителю к <code>&lt;div&gt;</code>. Нужно сделать это снова для следующего параграфа. И снова, для следующего. Наконец, когда <code>&lt;span&gt;</code> загружен, селектор по родителю будет применен к родительскому <code>&lt;div&gt;</code>, и элемент нужно будет повторно перерисовать.</p>

<p>И что теперь? Теперь, если изменится любое наследуемое CSS-свойство, каждый потомок должен будет повторно анализироваться и перерисовываться. Ох…</p>

<h2>Почему проблему можно решить с помощью JavaScript?</h2>

<p>Это только кажется, что JavaScript решает проблему. В общем случае JavaScript-заплатки (<em>заплатки — polyfills — части кода, обеспечивающие функциональность, которую должен обеспечивать браузер. Примечание переводчика</em>). Или регрессивное усовершенствование (или как там вы, молодежь, это сейчас называете) запускаются только один раз, после полной загрузки DOM.</p>

<p>Для того чтобы действительно имитировать поведение CSS, любой скрипт, решающий эту проблему, должен запускаться после отображения каждого элемента на странице, чтобы определить, нужно ли применить нашу «заплатку». Помните CSS-expressions в Internet Explorer? Именно по этой причине они вызывали такие проблемы с производительностью.</p>

<h2>Не невозможно</h2>

<p>Появится ли когда-нибудь селектор по родителю? Возможно. То, что я опиcал, не невозможно. На самом деле — наоборот. Это значит только то, что нам придётся иметь дело с ухудшением производительности из-за использования этого селектора.</p>

<p class="note note-last">Перевод оригинальной заметки «<a href="http://snook.ca/archives/html_and_css/css-parent-selectors/">Why we don't have a parent selector</a>» <a href="http://snook.ca/about/">Джонатана Снука</a> (Jonathan Snook), опубликованной в блоге «<a href="http://snook.ca/">Snook.ca</a>».</p>]]></description>
			<content:encoded><![CDATA[<p>Относительно регулярно я вижу дискуссии о том, должен ли CSS включать селектор по родителю и, пока я не выяснил, как работает движок браузера, сам строил предположения по этому поводу.</p>

<p>Вкратце: <em>производительность</em>.</p>

<h2>Как работает CSS</h2>

<p>В связи с моей работой я делаю много тестов производительности. Для определения «узких мест» мы используем массу приложений. Например, Google Page Speed, который дает рекомендации по улучшению производительности JavaScript и рендеринга. Прежде чем я перейду к рассмотрению этих рекомендаций, нам нужно разобраться как браузеры работают с CSS</p>

<h2>Стиль элемента применяется в момент его создания</h2>

<p>Мы часто рассматриваем веб-страницы как полноценные документы, наполненные элементами и содержимым. Между тем, браузеры разработаны так, чтобы обрабатывать документ потоково. Они начинают получать документ с сервера и могут начать его отображать до момента полной загрузки. Каждый узел анализируется и отображается в окне по мере получения.</p>

<p>Взгляните на этот документ:</p>

<pre>
	<code>&lt;body&gt;</code>
	<code>    &lt;div id="content"&gt;</code>
	<code>        &lt;div class="module intro"&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>        &lt;/div&gt;</code>
	<code>        &lt;div class="module"&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>            &lt;p&gt;Lorem Ipsum &lt;span&gt;Test&lt;/span&gt;&lt;/p&gt;</code>
	<code>        &lt;/div&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>&lt;/body&gt;</code>
</pre>

<p>Браузер начинает сначала и видит элемент <code>&lt;body&gt;</code>. В этот момент времени считается, что этот узел не имеет дочерних узлов. Ничего более не рассматривается. Браузер определяет соответствующий ему обобщенный набор стилей и применяет его к элементу. Какой шрифт, цвет, интерлиньяж? После того, как это все будет выяснено, элемент отображается на экране.</p>

<p>Далее браузер видит элемент <code>&lt;div&gt;</code> со значением атрибута ID <code>content</code>. И снова в этот момент времени браузер считает его пустым. Он не рассматривает другие элементы. Как только браузер рассчитает стиль, элемент отображается на экране. Затем браузер определяет нужно ли перерисовать <code>&lt;body&gt;</code> — стал ли элемент шире или выше? Я подозреваю, что там есть масса других проверок, но изменение ширины и высоты — самый распространенный способ повлиять на отображение родительского узла.</p>

<p>Процесс продолжается, пока браузер не достигнет корневого узла документа.</p>

<p>Вот как выглядит визуализация процессов перерисовки в Firefox:</p>

<iframe width="510" height="382" src="http://www.youtube.com/embed/ZTnIxIA5KGw" frameborder="0" class="video-player"></iframe>

<h2>CSS селекторы анализируется справа налево</h2>

<p>Чтобы определить, применяется ли CSS-правило к определенному элементу, браузер рассматривает селектор справа налево.</p>

<p>Если у вас есть селектор <code>body div#content p { color: #003366; }</code>, то, когда каждый элемент появляется на странице, браузер проверяет, является ли он параграфом. Если да, он начинает подниматься вверх по DOM и ищет <code>&lt;div&gt;</code> со значением атрибута ID равным <code>content</code>. Если он его находит, то продолжает подниматься по DOM пока не найдет <code>&lt;body&gt;</code>.</p>

<p>Таким образом, читая селектор справа налево, браузер значительно быстрее может определить применяется ли правило к элементу. Чтобы определить, какой из селекторов обладает большей производительностью, нужно выяснить, как много узлов придется рассмотреть, чтобы определить, можно ли применить правило к элементу.</p>

<h2>Правила</h2>

<p>Возвращаясь к Page Speed, давайте рассмотрим <a href="http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">несколько его рекомендаций</a>:</p>

<ul>
	<li>Избегайте селектора по потомку: <code>.content .sidebar</code>;</li>
	<li>Избегайте селектора по дочернему элементу: <code>.content &gt; .sidebar</code> и селектора по следующему элементу: <code>.content + .sidebar</code>.</li>
</ul>

<p>Конечно, селекторы по ID — самые быстрые. Проверить применимость селектора <code>#content</code> к рассматриваемому элементу можно очень быстро. Есть у него этот ID или нет? Селекторы по классу практически такие же быстрые, так как нет никаких связанных элементов, которые надо проверять.</p>

<p>Селекторы по потомкам, такие как <code>.content .sidebar</code> — более ресурсоемкие, так как, чтобы определить надо ли применять правило к <code>.sidebar</code>, браузер должен найти <code>.content</code>. Cелектор по дочернему элементу, например, <code>.content &gt; .sidebar</code>, лучше селектора по потомку, так как браузер должен проверить только один элемент вместо множества.</p>

<p class="note">К сожалению, селекторы <code>+</code> и <code>&gt;</code> не поддерживаются IE6. Так что если его поддержка актуальна для вас, то про них придется забыть. Примечание переводчика.</p>

<h2>Селектор по тегу и универсальный селектор</h2>

<p>В рамках рекомендации избегать селекторов по потомку, дочернему или следующему элементам, рекомендуется избегать универсального селектора и селектора по тегу.</p>

<p>Рассмотрим следующий пример:</p>

<pre><code>#content * { color: #039; }</code></pre>

<p>Так как в селекторе присутствует ID, то можно подумать, что этот селектор обрабатывается очень быстро. Проблема в том, что браузер обрабатывает селектор справа налево и сперва проверяется универсальный селектор. Для того чтобы браузер мог определить, должен ли цвет текста элемента быть тёмно-синим, надо проверить каждый предок элемента, пока не будет найден предок с атрибутом ID равным <code>content</code> или не будет достигнут корень документа.</p>

<p>И это должно быть сделано для каждого элемента на странице.</p>

<p>Теперь, когда мы понимаем, как элемент обрабатывается, как определяется применимость правил к элементу, давайте рассмотрим пример.</p>

<h2>Почему IE долго не поддерживал <code>:last-child</code></h2>

<p>Все жаловались: у всех браузеров, кроме IE, есть поддержка <code>:last-child</code> (она появилась только в IE9!) Некоторые могли подумать <q>насколько же сложнее сделать :last-child, если уже реализован :first-child?</q></p>

<p>Давайте представим, что мы — браузер и мы парсим документ-пример, который я приводил ранее.</p>

<pre>
	<code>.module &gt; p:first-child { color: red; } /* Первое правило */</code>
	<code>.module &gt; p:last-child { color: blue; } /* Второе правило */</code>
</pre>

<p>Когда мы рассматриваем внутренности первого <code>&lt;div&gt;</code>, мы видим, что там есть параграф. Браузер видит что-то вроде этого:</p>

<pre>
	<code>&lt;div class="module"&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
</pre>

<p>Нужно ли применить первое правило к параграфу? Да, это параграф; да, это первый дочерний узел; и, да, это непосредственный потомок элемента с классом <code>module</code>.</p>

<p>Нужно ли применить к этому параграфу второе правило? На данный момент это последний элемент. Но мы могли ещё не загрузить все элементы и не можем быть уверены, что он останется последним.</p>

<p>Вне зависимости от того, как решать эту дилемму, у нас возникает необходимость повторного анализа стилей двух узлов для каждого нового узла, который мы добавляем в DOM. Если я добавлю ещё один параграф следом за первым, мы должны так же повторно перерассчитать стили, которые применяются к предыдущему параграфу.</p>

<h2>Как на самом деле это делает браузер?</h2>

<p>Я не мог сказать с абсолютной уверенностью, как браузеры парсят <code>:last-child</code>, так что я создал несколько тестов:</p>

<ul>
	<li><a href="http://testing.snook.ca/css-1.html">Статическая HTML-страница</a>;</li>
	<li><a href="http://testing.snook.ca/css-1.php">Рендеринг с паузами в одну секунду</a>.</li>
</ul>

<p>Первый пример весьма скучен. В любом браузере, включая IE9, всё отображается корректно. Внутри <code>&lt;div&gt;</code> первый элемент красный, а последний синий. Но посмотрите на второй пример, и вы увидите интересные отличия в поведении браузеров.</p>

<p>Второй пример приостанавливается перед добавлением каждого параграфа в <code>&lt;div&gt;</code>.</p>

<p>В Firefox первый параграф изначально отображается синим. Когда загружается второй параграф, первый становится красным и второй — синим. Когда загружается третий параграф, второй отображается цветом по умолчанию и третий отображается синим. Firefox рассматривает каждый элемент, который был загружен в качестве последнего элемента, пока не будет загружен ещё один.</p>

<p>В Safari, Chrome и Opera мы увидим другой подход. Первый параграф красный. Второй отображается чёрным. Последний параграф отображается чёрным, пока браузер не получит закрывающий тег <code>&lt;/div&gt;</code>. В этот момент последний параграф становится синим. Эти браузеры не рассматривают элемент как последний, пока не будет закрыт родительский.</p>

<p>В Internet Explorer 9 Beta я нашел интересный баг. В то время, как статическая страница отображается корректно, версия с паузами отрабатывает с любопытным побочным эффектом. Первый параграф синий, второй параграф синий и затем — третий. Когда закрывающий тег <code>&lt;/div&gt;</code> загружен, предпоследний параграф меняет цвет на чёрный. IE9 пытается обрабатывать селектор как Webkit и Opera, но… м-м… не выходит. Надо бы отправить багрепорт в Microsoft.</p>

<h2>Почему у нас нет селектора по родителю?</h2>

<p>Уже дано достаточно пояснений, чтобы можно было вернуться к оригинальному вопросу. Проблема не в том, что у нас не может быть селектора по родителю. Проблема в том, что мы столкнемся с проблемами быстродействия, когда дело дойдет до определения того, какие CSS-правила применимы к данному элементу. Если Google Page Speed не рекомендует использование универсальных селекторов, то можно гарантировать, что селектор по родителю будет первым в списке ресурсоемких селекторов, намного опережая все проблемы с производительностью, которые могут быть вызваны использованием универсального селектора.</p>

<p>Давайте посмотрим почему. Первым делом давайте приведём пример синтаксиса для селектора по родителю.</p>

<pre><code>div.module:has(span) { color: green; }</code></pre>

<p>Проблема в том, что мы не можем определить применимость правила до тех пор, либо пока мы не найдем соответствия, либо пока все элементы, дочерние по отношению к родителю данного, не будут загружены. Ввиду этого мы должны оценивать правило и все остальные (в случае наличия специфических особенностей), применяющиеся к элементу, для каждого дочернего элемента, который мы загружаем.</p>

<p>Посмотрите на часть нашего документа:</p>

<pre>
	<code>&lt;div class="module"&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum&lt;/p&gt;</code>
	<code>    &lt;p&gt;Lorem Ipsum &lt;span&gt;Test&lt;/span&gt;&lt;/p&gt;</code>
	<code>&lt;/div&gt;</code>
</pre>

<p>Исходя из того, что мы видим, <code>.module</code> будет отображён без использования правила, применяемого селектором по родителю. Когда будет загружен первый элемент <code>&lt;p&gt;</code>, нужно повторно оценить применимость селектора по родителю к <code>&lt;div&gt;</code>. Нужно сделать это снова для следующего параграфа. И снова, для следующего. Наконец, когда <code>&lt;span&gt;</code> загружен, селектор по родителю будет применен к родительскому <code>&lt;div&gt;</code>, и элемент нужно будет повторно перерисовать.</p>

<p>И что теперь? Теперь, если изменится любое наследуемое CSS-свойство, каждый потомок должен будет повторно анализироваться и перерисовываться. Ох…</p>

<h2>Почему проблему можно решить с помощью JavaScript?</h2>

<p>Это только кажется, что JavaScript решает проблему. В общем случае JavaScript-заплатки (<em>заплатки — polyfills — части кода, обеспечивающие функциональность, которую должен обеспечивать браузер. Примечание переводчика</em>). Или регрессивное усовершенствование (или как там вы, молодежь, это сейчас называете) запускаются только один раз, после полной загрузки DOM.</p>

<p>Для того чтобы действительно имитировать поведение CSS, любой скрипт, решающий эту проблему, должен запускаться после отображения каждого элемента на странице, чтобы определить, нужно ли применить нашу «заплатку». Помните CSS-expressions в Internet Explorer? Именно по этой причине они вызывали такие проблемы с производительностью.</p>

<h2>Не невозможно</h2>

<p>Появится ли когда-нибудь селектор по родителю? Возможно. То, что я опиcал, не невозможно. На самом деле — наоборот. Это значит только то, что нам придётся иметь дело с ухудшением производительности из-за использования этого селектора.</p>

<p class="note note-last">Перевод оригинальной заметки «<a href="http://snook.ca/archives/html_and_css/css-parent-selectors/">Why we don't have a parent selector</a>» <a href="http://snook.ca/about/">Джонатана Снука</a> (Jonathan Snook), опубликованной в блоге «<a href="http://snook.ca/">Snook.ca</a>».</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/parent-selector/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Элементы details и summary</title>
		<link>http://web-standards.ru/articles/details-summary-elements/</link>
		<comments>http://web-standards.ru/articles/details-summary-elements/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 09:51:30 +0000</pubDate>
		<dc:creator>Том Лидбеттер</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[методика]]></category>
		<category><![CDATA[семантика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/details-summary-elements/</guid>
		<description><![CDATA[<p>Вам часто приходилось использовать JavaScript для создания виджета, показывающего и скрывающего какое-то содержимое? Возможно, для этого вы даже скачивали целую JavaScript-библиотеку? Что ж, можете радоваться: HTML5 позволяет создавать подобное всего лишь парой строчек кода, без применения JavaScript. Зависит от браузера, конечно, но мы вернёмся к этому позже. Представляем вам элемент <code>&lt;details&gt;</code>.</p>

<p>Вот что о нём написано <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-details-element">в спецификации</a>:</p>

<blockquote>
	<p>Элемент <code>details</code> представляет собой раскрывающийся виджет, показывающий пользователю дополнительную информацию или элементы управления.</p>
	<p><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-details-element">Спецификация WHATWG HTML5</a></p>
</blockquote>

<p>Мы можем использовать <code>&lt;details&gt;</code> для создания «виджетов-аккордеонов», которые пользователь может разворачивать и сворачивать. Внутри этого элемента можно разместить любое содержимое.</p>

<h2>Поддержка браузерами</h2>

<p>Прежде чем мы продолжим, вам нужно учесть, что сейчас только Chrome поддерживает элемент <code>&lt;details&gt;</code>. <a href="http://my.opera.com/ODIN/blog/implementing-html5-details">Скоро к нему присоединится и Opera</a>, но немного костылей нам все-таки понадобится. Что ж, запускайте Chrome, и давайте смотреть.</p>

<h2>Использование <code>&lt;details&gt;</code></h2>

<p>Имеются два элемента: <code>&lt;details&gt;</code> и необязательный <code>&lt;summary&gt;</code>. Элемент <code>&lt;details&gt;</code> — это обёртка для содержимого, которое мы хотим показать и скрыть, а <code>&lt;summary&gt;</code> содержит описание и заголовок этой группы. Формально <code>&lt;summary&gt;</code> нам не нужен. В его отсутствие браузер подставит текст по умолчанию, например «details» в Chrome. Давайте взглянем на код:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;Покажи-скрой меня&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Бурное развитие внутреннего туризма привело Томаса Кука.&lt;/p&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Вы можете <a href="http://jsbin.com/egefop#html,live">посмотреть это в действии на jsbin</a>. Даже этот простой пример прекрасно демонстрирует эффект переключения. Без JavaScript!</p>

<h3>Атрибут <code>open</code></h3>

<p>В вышеприведенном примере содержимое скрыто при загрузке страницы. Мы можем сделать его видимым по умолчанию, добавив одиночный атрибут <code>open</code> для <code>&lt;details&gt;</code>, <a href="http://jsbin.com/egefop/2#html,live">пример на jsbin</a>:</p>

<pre>
	<code>&lt;details open&gt;</code>
	<code>    &lt;summary&gt;Покажи-скрой меня&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Бурное развитие внутреннего туризма привело Томаса Кука.&lt;/p&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Атрибута <code>closed</code> не существует. Поэтому, опуская <code>open</code>, вы по умолчанию подразумеваете <code>closed</code>.</p>

<h3>Элемент <code>&lt;summary&gt;</code></h3>

<p>Мы бегло взглянули на <code>&lt;summary&gt;</code> в действии, теперь остановимся на нём подробнее. Внутри <code>&lt;summary&gt;</code> могут использоваться строчные элементы, такие как <code>&lt;span&gt;</code> или <code>&lt;strong&gt;</code>. Для чего это может быть нужно? Например, для дополнительного оформления или, как предлагает спецификация, использования <code>&lt;label&gt;</code> для элемента формы. По крайней мере, <em>было бы</em> удобно, если бы <a href="http://jsbin.com/egefop/3#html">подобная конструкция</a> работала корректно:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;&lt;label for="name"&gt;Имя:&lt;/label&gt;&lt;/summary&gt;</code>
	<code>    &lt;input type="text" id="name" name="name" /&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Теоретически, нажатие на <code>&lt;summary&gt;</code> должно раскрывать содержимое элемента <code>&lt;details&gt;</code>. Но в этом примере содержимое не будет развернуто, потому что вы, фактически, взаимодействуете с <code>&lt;label&gt;</code>, который переводит фокус на соответствующий <code>&lt;input&gt;</code> — даже если он скрыт с помощью <code>&lt;details&gt;</code>.</p>

<p>Честно говоря, этот момент еще требует прояснения. А что по вашему мнению должно происходить? Возможно, у разработчиков браузеров, читающих эту статью, есть какие-то идеи? :)</p>

<h3>Вложенность <code>&lt;details&gt;</code></h3>

<p>Вы можете помещать <code>&lt;details&gt;</code> друг в друга, если хотите, как это сделано в <a href="http://jsbin.com/egefop/14#html,live">следующем, вполне валидном примере</a>:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;Вопрос 1&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Население превышает широкий кристаллический фундамент.&lt;/p&gt;</code>
	<code>    &lt;details&gt;</code>
	<code>        &lt;summary&gt;Приложенные документы&lt;/summary&gt;</code>
	<code>        &lt;ul&gt;</code>
	<code>            &lt;li&gt;&lt;a href="#"&gt;Болгары очень дружелюбны;&lt;/a&gt;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Скумбрия неумеренно перевозит вулканизм;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Дождливая погода, куда входят Пик-Дистрикт;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Белый саксаул дегустирует живописный утконос;&lt;/li&gt;</code>
	<code>        &lt;/ul&gt;</code>
	<code>    &lt;/details&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<h2>Примеры использования</h2>

<p>Так в каких же случаях вы можете использовать <code>&lt;details&gt;</code>? Первое, что приходит в голову — FAQ. Разработчики часто используют для них «аккордеоны», поэтому <code>&lt;details&gt;</code> замечательно подходит.</p>

<p>Также не забывайте о навигации по странице. Это может быть закрепленный блок, передвигающаяся одновременно с прокруткой. <a href="http://jsbin.com/egefop/8#html,live">Возможно, что-то вроде этого?</a></p>

<p>Вы можете использовать <code>&lt;details&gt;</code> для сворачивания и разворачивания блока комментариев в блоге, для профиля пользователя, для описания загружаемого файла, для сложных форм или в веб-приложениях, как показано в этом примере из спецификации:</p>

<p><img src="http://static.web-standards.ru/articles/details-summary-elements/details-w3c.png" alt="Пример использования &lt;details&gt; из спецификации" class="pic pic-middle"></p>

<p class="note">Пример использования <code>&lt;details&gt;</code> из спецификации.</p>

<p>На самом деле, даже глядя сейчас на админку WordPress, я вижу множество возможностей использования <code>&lt;details&gt;</code>. Если у вас есть ещё какие-то идеи и предложения — расскажите о них в комментариях.</p>

<h2>Оформление</h2>

<p>Как же нам оформить эту штуку? Для элемента, раскрывающего содержимое, в WebKit вы можете использовать псевдо-элемент <code>::-webkit-details-marker</code>. <a href="http://jsbin.com/egefop/9#html,live">Небольшой пример</a>:</p>

<pre>
	<code>details summary::-webkit-details-marker {</code>
	<code>    background: red;</code>
	<code>    color: #fff;</code>
	<code>    font-size: 500%;</code>
	<code>}</code>
</pre>

<p>Мы также можем позиционировать этот элемент по отношению к родителю. <a href="http://jsbin.com/egefop/17#html,live">Здесь, например, он прижат к правому краю</a>. В общем-то, и все.</p>

<p>А как же заменить раскрывающий элемент своей иконкой? Используя выборку по атрибуту, вы можете определить, когда <code>&lt;details&gt;</code> раскрыт, а когда закрыт, и применить соответствующее фоновое изображение. Мы делаем примерно то же самое в <a href="http://jsbin.com/egefop/11#html,live">этом примере</a>, за исключением того, что вместо фонового изображения мы используем псевдо-элемент <code>:after</code>:</p>

<pre>
	<code>summary::-webkit-details-marker {</code>
	<code>    display: none</code>
	<code>}</code>
	<code>summary:after {</code>
	<code>    background: red;</code>
	<code>    border-radius: 5px;</code>
	<code>    content: "+";</code>
	<code>    color: #fff;</code>
	<code>    float: left;</code>
	<code>    font-size: 1.5em;</code>
	<code>    font-weight: bold;</code>
	<code>    margin: -5px 10px 0 0;</code>
	<code>    padding: 0;</code>
	<code>    text-align: center;</code>
	<code>    width: 20px;</code>
	<code>}</code>
	<code>details[open] summary:after {</code>
	<code>    content: "-";</code>
	<code>}</code>
</pre>

<p>В этом примере символы <code>+</code> и <code>-</code> используются в качестве раскрывающей ссылки. В зависимости от дизайна вы можете использовать <code>:before</code> вместо <code>:after</code>, но, в любом случае, оба псевдо-элемента позволяют использование изображения.</p>

<p>Выборка по атрибуту <code>details[open]</code> скрывает в себе некоторые интересные возможности. Как хорошие HTML5-доктора, мы создали <a href="http://jsbin.com/egefop/15#html,live">доработанный пример</a>, показанный на этом скриншоте:</p>

<p><img src="http://static.web-standards.ru/articles/details-summary-elements/nice-details.png" alt="Элемент &lt;details&gt; в Chrome" class="pic pic-middle"></p>

<p class="note">Оформленный <code>&lt;details&gt;</code> в Chrome.</p>

<p>Было бы интересно (хотя это и не всегда уместно), если бы мы могли использовать CSS-трансформации для анимации разворачивания и сворачивания <code>&lt;details&gt;</code>, но пока это невозможно.</p>

<h2>Доступность</h2>

<p>К сожалению, на момент написания статьи отсутствует возможность управления <code>&lt;details&gt;</code> с помощью клавиатуры. <a href="http://www.paciellogroup.com/blog/2011/08/accessibility-notes-2nd-august-2011/">Стив Фолкнер пишет</a>:</p>

<blockquote>
	<p>Проблема в том, что на данный момент отсутствует поддержки клавиатуры и нет никакой инофрмации для обеспечения доступности.</p>
</blockquote>

<p>Попробуйте сами. Если вы раскроете элемент <code>&lt;details&gt;</code> с помощью мыши, тогда вы сможете использовать клавиатуру для навигации по вложенным элементам, но вы также должны иметь возможность открывать и закрывать <code>&lt;details&gt;</code> с клавиатуры. Что ж, неидеально, но я уверен, что разработчики Chrome скоро с этим разберутся. Правда, ребята?</p>

<h2>Обратная совместимость</h2>

<p>Прежде чем кто-то начнет восклицать, что это не работает в IE6, хочу сказать: мы знаем. Тем не менее, благодаря некоторым умным людям, мы можем обеспечить изящную обратную совместимость. В этой <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">очень полезной коллекции всевозможных кроссбраузерных костылей</a> я нашел два решения, оба они требуют jQuery:</p>

<ul>
	<li>Обратная совместимость для <a href="http://mathiasbynens.be/notes/html5-details-jquery"><code>&lt;details&gt;</code> с помощью jQuery</a> от Матиаса Байненса;</li>
	<li><a href="https://github.com/manuelbieh/details-Polyfill">Еще одна альтернатива <code>&lt;details&gt;</code>, также основанная на jQuery</a> от Мануэля Бье.</li>
</ul>

<p>Многие из вас захотят использовать <a href="http://modernizr.com/">Modernizr</a> для определения возможностей браузера, но на данный момент в Modernizr отсутствует проверка поддержки <code>&lt;details&gt;</code>. Матиас, автор приведенного выше решения для обратной совместимости, предлагает использовать <a href="https://github.com/Modernizr/Modernizr/blob/master/feature-detects/elem-details.js">этот Modernizr-сниппет</a>.</p>

<h2>Зачем вообще это использовать?</h2>

<p>Конечно, дарёному коню в зубы не смотрят, но все-таки — почему этот виджет существует в HTML5? Что ж, как и в случае с другими возможностями HTML5, он просто делает нашу жизнь легче. Реализация таких элементов, как календарь, слайдер, прогресс-бар, а теперь ещё и «аккордеон», становится гораздо проще и не требует использования JavaScript. Кто знает, что будет следующим? Нативные табы? Было бы здорово :)</p>

<h2>В заключение</h2>

<p>В этой статье мы продемонстрировали, как использовать элементы <code>&lt;details&gt;</code> и <code>&lt;summary&gt;</code>. Элемент <code>&lt;details&gt;</code> при помощи <code>&lt;summary&gt;</code> создаёт естественный для браузера интерактивный раскрывающийся виджет.</p>

<p>На текущий момент <code>&lt;details&gt;</code> работает только в Chrome, но, надеюсь, эта ситуация в скором времени изменится. Пока что мы можем использовать в CSS только <code>::-webkit-details-marker</code>, но есть и множество других CSS-техник. Если у вас есть какой-либо опыт или идеи для использования элемента <code>&lt;details&gt;</code>, расскажите об этом в комментариях.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/the-details-and-summary-elements/">The details and summary elements</a>» <a href="http://html5doctor.com/author/toml/">Тома Лидбеттера</a> (Tom Leadbetter), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Вам часто приходилось использовать JavaScript для создания виджета, показывающего и скрывающего какое-то содержимое? Возможно, для этого вы даже скачивали целую JavaScript-библиотеку? Что ж, можете радоваться: HTML5 позволяет создавать подобное всего лишь парой строчек кода, без применения JavaScript. Зависит от браузера, конечно, но мы вернёмся к этому позже. Представляем вам элемент <code>&lt;details&gt;</code>.</p>

<p>Вот что о нём написано <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-details-element">в спецификации</a>:</p>

<blockquote>
	<p>Элемент <code>details</code> представляет собой раскрывающийся виджет, показывающий пользователю дополнительную информацию или элементы управления.</p>
	<p><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#the-details-element">Спецификация WHATWG HTML5</a></p>
</blockquote>

<p>Мы можем использовать <code>&lt;details&gt;</code> для создания «виджетов-аккордеонов», которые пользователь может разворачивать и сворачивать. Внутри этого элемента можно разместить любое содержимое.</p>

<h2>Поддержка браузерами</h2>

<p>Прежде чем мы продолжим, вам нужно учесть, что сейчас только Chrome поддерживает элемент <code>&lt;details&gt;</code>. <a href="http://my.opera.com/ODIN/blog/implementing-html5-details">Скоро к нему присоединится и Opera</a>, но немного костылей нам все-таки понадобится. Что ж, запускайте Chrome, и давайте смотреть.</p>

<h2>Использование <code>&lt;details&gt;</code></h2>

<p>Имеются два элемента: <code>&lt;details&gt;</code> и необязательный <code>&lt;summary&gt;</code>. Элемент <code>&lt;details&gt;</code> — это обёртка для содержимого, которое мы хотим показать и скрыть, а <code>&lt;summary&gt;</code> содержит описание и заголовок этой группы. Формально <code>&lt;summary&gt;</code> нам не нужен. В его отсутствие браузер подставит текст по умолчанию, например «details» в Chrome. Давайте взглянем на код:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;Покажи-скрой меня&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Бурное развитие внутреннего туризма привело Томаса Кука.&lt;/p&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Вы можете <a href="http://jsbin.com/egefop#html,live">посмотреть это в действии на jsbin</a>. Даже этот простой пример прекрасно демонстрирует эффект переключения. Без JavaScript!</p>

<h3>Атрибут <code>open</code></h3>

<p>В вышеприведенном примере содержимое скрыто при загрузке страницы. Мы можем сделать его видимым по умолчанию, добавив одиночный атрибут <code>open</code> для <code>&lt;details&gt;</code>, <a href="http://jsbin.com/egefop/2#html,live">пример на jsbin</a>:</p>

<pre>
	<code>&lt;details open&gt;</code>
	<code>    &lt;summary&gt;Покажи-скрой меня&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Бурное развитие внутреннего туризма привело Томаса Кука.&lt;/p&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Атрибута <code>closed</code> не существует. Поэтому, опуская <code>open</code>, вы по умолчанию подразумеваете <code>closed</code>.</p>

<h3>Элемент <code>&lt;summary&gt;</code></h3>

<p>Мы бегло взглянули на <code>&lt;summary&gt;</code> в действии, теперь остановимся на нём подробнее. Внутри <code>&lt;summary&gt;</code> могут использоваться строчные элементы, такие как <code>&lt;span&gt;</code> или <code>&lt;strong&gt;</code>. Для чего это может быть нужно? Например, для дополнительного оформления или, как предлагает спецификация, использования <code>&lt;label&gt;</code> для элемента формы. По крайней мере, <em>было бы</em> удобно, если бы <a href="http://jsbin.com/egefop/3#html">подобная конструкция</a> работала корректно:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;&lt;label for="name"&gt;Имя:&lt;/label&gt;&lt;/summary&gt;</code>
	<code>    &lt;input type="text" id="name" name="name" /&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<p>Теоретически, нажатие на <code>&lt;summary&gt;</code> должно раскрывать содержимое элемента <code>&lt;details&gt;</code>. Но в этом примере содержимое не будет развернуто, потому что вы, фактически, взаимодействуете с <code>&lt;label&gt;</code>, который переводит фокус на соответствующий <code>&lt;input&gt;</code> — даже если он скрыт с помощью <code>&lt;details&gt;</code>.</p>

<p>Честно говоря, этот момент еще требует прояснения. А что по вашему мнению должно происходить? Возможно, у разработчиков браузеров, читающих эту статью, есть какие-то идеи? :)</p>

<h3>Вложенность <code>&lt;details&gt;</code></h3>

<p>Вы можете помещать <code>&lt;details&gt;</code> друг в друга, если хотите, как это сделано в <a href="http://jsbin.com/egefop/14#html,live">следующем, вполне валидном примере</a>:</p>

<pre>
	<code>&lt;details&gt;</code>
	<code>    &lt;summary&gt;Вопрос 1&lt;/summary&gt;</code>
	<code>    &lt;p&gt;Население превышает широкий кристаллический фундамент.&lt;/p&gt;</code>
	<code>    &lt;details&gt;</code>
	<code>        &lt;summary&gt;Приложенные документы&lt;/summary&gt;</code>
	<code>        &lt;ul&gt;</code>
	<code>            &lt;li&gt;&lt;a href="#"&gt;Болгары очень дружелюбны;&lt;/a&gt;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Скумбрия неумеренно перевозит вулканизм;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Дождливая погода, куда входят Пик-Дистрикт;&lt;/li&gt;</code>
	<code>            &lt;li&gt;Белый саксаул дегустирует живописный утконос;&lt;/li&gt;</code>
	<code>        &lt;/ul&gt;</code>
	<code>    &lt;/details&gt;</code>
	<code>&lt;/details&gt;</code>
</pre>

<h2>Примеры использования</h2>

<p>Так в каких же случаях вы можете использовать <code>&lt;details&gt;</code>? Первое, что приходит в голову — FAQ. Разработчики часто используют для них «аккордеоны», поэтому <code>&lt;details&gt;</code> замечательно подходит.</p>

<p>Также не забывайте о навигации по странице. Это может быть закрепленный блок, передвигающаяся одновременно с прокруткой. <a href="http://jsbin.com/egefop/8#html,live">Возможно, что-то вроде этого?</a></p>

<p>Вы можете использовать <code>&lt;details&gt;</code> для сворачивания и разворачивания блока комментариев в блоге, для профиля пользователя, для описания загружаемого файла, для сложных форм или в веб-приложениях, как показано в этом примере из спецификации:</p>

<p><img src="http://static.web-standards.ru/articles/details-summary-elements/details-w3c.png" alt="Пример использования &lt;details&gt; из спецификации" class="pic pic-middle"></p>

<p class="note">Пример использования <code>&lt;details&gt;</code> из спецификации.</p>

<p>На самом деле, даже глядя сейчас на админку WordPress, я вижу множество возможностей использования <code>&lt;details&gt;</code>. Если у вас есть ещё какие-то идеи и предложения — расскажите о них в комментариях.</p>

<h2>Оформление</h2>

<p>Как же нам оформить эту штуку? Для элемента, раскрывающего содержимое, в WebKit вы можете использовать псевдо-элемент <code>::-webkit-details-marker</code>. <a href="http://jsbin.com/egefop/9#html,live">Небольшой пример</a>:</p>

<pre>
	<code>details summary::-webkit-details-marker {</code>
	<code>    background: red;</code>
	<code>    color: #fff;</code>
	<code>    font-size: 500%;</code>
	<code>}</code>
</pre>

<p>Мы также можем позиционировать этот элемент по отношению к родителю. <a href="http://jsbin.com/egefop/17#html,live">Здесь, например, он прижат к правому краю</a>. В общем-то, и все.</p>

<p>А как же заменить раскрывающий элемент своей иконкой? Используя выборку по атрибуту, вы можете определить, когда <code>&lt;details&gt;</code> раскрыт, а когда закрыт, и применить соответствующее фоновое изображение. Мы делаем примерно то же самое в <a href="http://jsbin.com/egefop/11#html,live">этом примере</a>, за исключением того, что вместо фонового изображения мы используем псевдо-элемент <code>:after</code>:</p>

<pre>
	<code>summary::-webkit-details-marker {</code>
	<code>    display: none</code>
	<code>}</code>
	<code>summary:after {</code>
	<code>    background: red;</code>
	<code>    border-radius: 5px;</code>
	<code>    content: "+";</code>
	<code>    color: #fff;</code>
	<code>    float: left;</code>
	<code>    font-size: 1.5em;</code>
	<code>    font-weight: bold;</code>
	<code>    margin: -5px 10px 0 0;</code>
	<code>    padding: 0;</code>
	<code>    text-align: center;</code>
	<code>    width: 20px;</code>
	<code>}</code>
	<code>details[open] summary:after {</code>
	<code>    content: "-";</code>
	<code>}</code>
</pre>

<p>В этом примере символы <code>+</code> и <code>-</code> используются в качестве раскрывающей ссылки. В зависимости от дизайна вы можете использовать <code>:before</code> вместо <code>:after</code>, но, в любом случае, оба псевдо-элемента позволяют использование изображения.</p>

<p>Выборка по атрибуту <code>details[open]</code> скрывает в себе некоторые интересные возможности. Как хорошие HTML5-доктора, мы создали <a href="http://jsbin.com/egefop/15#html,live">доработанный пример</a>, показанный на этом скриншоте:</p>

<p><img src="http://static.web-standards.ru/articles/details-summary-elements/nice-details.png" alt="Элемент &lt;details&gt; в Chrome" class="pic pic-middle"></p>

<p class="note">Оформленный <code>&lt;details&gt;</code> в Chrome.</p>

<p>Было бы интересно (хотя это и не всегда уместно), если бы мы могли использовать CSS-трансформации для анимации разворачивания и сворачивания <code>&lt;details&gt;</code>, но пока это невозможно.</p>

<h2>Доступность</h2>

<p>К сожалению, на момент написания статьи отсутствует возможность управления <code>&lt;details&gt;</code> с помощью клавиатуры. <a href="http://www.paciellogroup.com/blog/2011/08/accessibility-notes-2nd-august-2011/">Стив Фолкнер пишет</a>:</p>

<blockquote>
	<p>Проблема в том, что на данный момент отсутствует поддержки клавиатуры и нет никакой инофрмации для обеспечения доступности.</p>
</blockquote>

<p>Попробуйте сами. Если вы раскроете элемент <code>&lt;details&gt;</code> с помощью мыши, тогда вы сможете использовать клавиатуру для навигации по вложенным элементам, но вы также должны иметь возможность открывать и закрывать <code>&lt;details&gt;</code> с клавиатуры. Что ж, неидеально, но я уверен, что разработчики Chrome скоро с этим разберутся. Правда, ребята?</p>

<h2>Обратная совместимость</h2>

<p>Прежде чем кто-то начнет восклицать, что это не работает в IE6, хочу сказать: мы знаем. Тем не менее, благодаря некоторым умным людям, мы можем обеспечить изящную обратную совместимость. В этой <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">очень полезной коллекции всевозможных кроссбраузерных костылей</a> я нашел два решения, оба они требуют jQuery:</p>

<ul>
	<li>Обратная совместимость для <a href="http://mathiasbynens.be/notes/html5-details-jquery"><code>&lt;details&gt;</code> с помощью jQuery</a> от Матиаса Байненса;</li>
	<li><a href="https://github.com/manuelbieh/details-Polyfill">Еще одна альтернатива <code>&lt;details&gt;</code>, также основанная на jQuery</a> от Мануэля Бье.</li>
</ul>

<p>Многие из вас захотят использовать <a href="http://modernizr.com/">Modernizr</a> для определения возможностей браузера, но на данный момент в Modernizr отсутствует проверка поддержки <code>&lt;details&gt;</code>. Матиас, автор приведенного выше решения для обратной совместимости, предлагает использовать <a href="https://github.com/Modernizr/Modernizr/blob/master/feature-detects/elem-details.js">этот Modernizr-сниппет</a>.</p>

<h2>Зачем вообще это использовать?</h2>

<p>Конечно, дарёному коню в зубы не смотрят, но все-таки — почему этот виджет существует в HTML5? Что ж, как и в случае с другими возможностями HTML5, он просто делает нашу жизнь легче. Реализация таких элементов, как календарь, слайдер, прогресс-бар, а теперь ещё и «аккордеон», становится гораздо проще и не требует использования JavaScript. Кто знает, что будет следующим? Нативные табы? Было бы здорово :)</p>

<h2>В заключение</h2>

<p>В этой статье мы продемонстрировали, как использовать элементы <code>&lt;details&gt;</code> и <code>&lt;summary&gt;</code>. Элемент <code>&lt;details&gt;</code> при помощи <code>&lt;summary&gt;</code> создаёт естественный для браузера интерактивный раскрывающийся виджет.</p>

<p>На текущий момент <code>&lt;details&gt;</code> работает только в Chrome, но, надеюсь, эта ситуация в скором времени изменится. Пока что мы можем использовать в CSS только <code>::-webkit-details-marker</code>, но есть и множество других CSS-техник. Если у вас есть какой-либо опыт или идеи для использования элемента <code>&lt;details&gt;</code>, расскажите об этом в комментариях.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/the-details-and-summary-elements/">The details and summary elements</a>» <a href="http://html5doctor.com/author/toml/">Тома Лидбеттера</a> (Tom Leadbetter), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/details-summary-elements/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Вам не нравится IE6? Что, правда?</title>
		<link>http://web-standards.ru/articles/dont-like-ie6-really/</link>
		<comments>http://web-standards.ru/articles/dont-like-ie6-really/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 10:19:23 +0000</pubDate>
		<dc:creator>Реми Шарп</dc:creator>
				<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/dont-like-ie6-really/</guid>
		<description><![CDATA[<p>Сегодня прочёл очередное высказывание на тему <q>Почему я не поддерживаю IE6</q> из длинного-предлинного списка ему подобных. Что за бред? Если поддержка IE6 является частью вашей работы или включена в договор — значит так оно и есть, такова профессия, и в этих сложностях её смысл.</p>

<p>Меня тошнит от подобных старых и скучных публикаций и даже целых сайтов, посвящённых разглагольствованиям, почему IE6 должен умереть. Мы все в курсе, что IE6 должен умереть. Microsoft в курсе, что IE6 должен умереть. Чёрт, даже сам IE6 в курсе, что он должен умереть. Он шатается вокруг уже многие годы как чёртов зомби.</p>

<p>А теперь смотрите, факт: никто сегодня не устанавливает IE6 в качестве основного браузера. Более того, я готов спорить, что никто, будь у него такой выбор, не предпочтёт IE6 любому другому браузеру. Но проблема не в этом. Теперь нам ясно: никто, блин, специально не выбирает IE6 и уж точно не использует этот браузер, чтобы просто вас взбесить!</p>

<p>Кстати, когда IE6 наконец-то помрёт, кто займётся поиском и заменой IE6 на IE7 во всех записях, а потом IE7 на IE8 и так далее?</p>

<p>Вполне очевидно, что когда компания АБВ во времена XP и IE6 приобретала оборудование для своих сотрудников, это стоило ей чёртову кучу денег. Компании не любят тратить деньги, когда им кажется, что это совсем не нужно. Поэтому очередное обновление всех этих ПК не входит в их приоритеты. Не забывайте, что обновление тянет за собой поддержку, обслуживание, простой и так далее — всё, что стоит ещё одну чёртову кучу денег.</p>

<p>Относительно недавно я вёл курсы в одном научном институте, где местные разработчики рассказали мне, что самый часто используемый браузер у них — это IE6. И поддерживать этот браузер — это их работа.</p>

<p>Их работа. За которую им платят. Если вы не хотите поддерживать IE6 — не поддерживайте. Никто не выкручивает вам руки, заставляя фрилансить над подобными проектами. Если вы настолько против IE6 и имеете постоянную работу — я надеюсь, что вы упомянули это на собеседовании, но если нет — и вы действительно ненавидите IE6, то вы можете уволиться и найти другую работу, правильно?</p>

<p>То, что разрабатывать под IE6 сложно из-за того, что он уже не поддерживается и, в частности, просто не совместим с требованиями к современным сайтам — это факт. Поэтому мы просим за это больше денег.</p>

<p>Если ваш клиент создаёт совершенно новый продукт, то у вас нет причин для поддержки старых браузеров, если только у них нет чёткой статистики, показывающей эту необходимость. В любом случае, существует множество способов просчитать потенциальную статистику использования браузеров. Однако если это уже существующая компания, и у них есть поток IE6, обеспечивающий поддержку их бизнесу — тогда это просто часть вашей работы.</p>

<p>Некоторые команды разработчиков имеют такие размеры и способны нанимать новых людей только благодаря браузерам вроде IE. Если бы всё было так просто, куча людей осталась бы без работы.</p>

<p>Разработка для сети подразумевает, что вы знаете как работают браузеры. Суть такой работы заключается в том, чтобы сайты работали везде. Знание всех «подводных граблей» браузеров — это то, что отличает <em>Ваньку Середнячка</em> от <em>господина Николая Великолепного</em>. Если вы не хотите учить трюки IE6 (или IE7, или IE8, или IE9) — не надо. Вашу работу заберёт кто-нибудь другой.</p>

<p>Что до меня, я с нетерпением жду новых причин, согласно которым IE6 должен умереть — как будто это и так прекрасно не задокументировано.</p>

<p class="note note-last">Перевод оригинальной заметки «<a href="http://remy.tumblr.com/post/8334086394/what-do-you-mean-you-dont-like-ie6-really">What do you mean, you don’t like IE6? Really?</a>» <a href="http://richclarkdesign.com/">Реми Шарпа</a> (Remy Sharp), опубликованной в блоге «<a href="http://remy.tumblr.com/">rem @ &gt; 140 characters</a>».</p>]]></description>
			<content:encoded><![CDATA[<p>Сегодня прочёл очередное высказывание на тему <q>Почему я не поддерживаю IE6</q> из длинного-предлинного списка ему подобных. Что за бред? Если поддержка IE6 является частью вашей работы или включена в договор — значит так оно и есть, такова профессия, и в этих сложностях её смысл.</p>

<p>Меня тошнит от подобных старых и скучных публикаций и даже целых сайтов, посвящённых разглагольствованиям, почему IE6 должен умереть. Мы все в курсе, что IE6 должен умереть. Microsoft в курсе, что IE6 должен умереть. Чёрт, даже сам IE6 в курсе, что он должен умереть. Он шатается вокруг уже многие годы как чёртов зомби.</p>

<p>А теперь смотрите, факт: никто сегодня не устанавливает IE6 в качестве основного браузера. Более того, я готов спорить, что никто, будь у него такой выбор, не предпочтёт IE6 любому другому браузеру. Но проблема не в этом. Теперь нам ясно: никто, блин, специально не выбирает IE6 и уж точно не использует этот браузер, чтобы просто вас взбесить!</p>

<p>Кстати, когда IE6 наконец-то помрёт, кто займётся поиском и заменой IE6 на IE7 во всех записях, а потом IE7 на IE8 и так далее?</p>

<p>Вполне очевидно, что когда компания АБВ во времена XP и IE6 приобретала оборудование для своих сотрудников, это стоило ей чёртову кучу денег. Компании не любят тратить деньги, когда им кажется, что это совсем не нужно. Поэтому очередное обновление всех этих ПК не входит в их приоритеты. Не забывайте, что обновление тянет за собой поддержку, обслуживание, простой и так далее — всё, что стоит ещё одну чёртову кучу денег.</p>

<p>Относительно недавно я вёл курсы в одном научном институте, где местные разработчики рассказали мне, что самый часто используемый браузер у них — это IE6. И поддерживать этот браузер — это их работа.</p>

<p>Их работа. За которую им платят. Если вы не хотите поддерживать IE6 — не поддерживайте. Никто не выкручивает вам руки, заставляя фрилансить над подобными проектами. Если вы настолько против IE6 и имеете постоянную работу — я надеюсь, что вы упомянули это на собеседовании, но если нет — и вы действительно ненавидите IE6, то вы можете уволиться и найти другую работу, правильно?</p>

<p>То, что разрабатывать под IE6 сложно из-за того, что он уже не поддерживается и, в частности, просто не совместим с требованиями к современным сайтам — это факт. Поэтому мы просим за это больше денег.</p>

<p>Если ваш клиент создаёт совершенно новый продукт, то у вас нет причин для поддержки старых браузеров, если только у них нет чёткой статистики, показывающей эту необходимость. В любом случае, существует множество способов просчитать потенциальную статистику использования браузеров. Однако если это уже существующая компания, и у них есть поток IE6, обеспечивающий поддержку их бизнесу — тогда это просто часть вашей работы.</p>

<p>Некоторые команды разработчиков имеют такие размеры и способны нанимать новых людей только благодаря браузерам вроде IE. Если бы всё было так просто, куча людей осталась бы без работы.</p>

<p>Разработка для сети подразумевает, что вы знаете как работают браузеры. Суть такой работы заключается в том, чтобы сайты работали везде. Знание всех «подводных граблей» браузеров — это то, что отличает <em>Ваньку Середнячка</em> от <em>господина Николая Великолепного</em>. Если вы не хотите учить трюки IE6 (или IE7, или IE8, или IE9) — не надо. Вашу работу заберёт кто-нибудь другой.</p>

<p>Что до меня, я с нетерпением жду новых причин, согласно которым IE6 должен умереть — как будто это и так прекрасно не задокументировано.</p>

<p class="note note-last">Перевод оригинальной заметки «<a href="http://remy.tumblr.com/post/8334086394/what-do-you-mean-you-dont-like-ie6-really">What do you mean, you don’t like IE6? Really?</a>» <a href="http://richclarkdesign.com/">Реми Шарпа</a> (Remy Sharp), опубликованной в блоге «<a href="http://remy.tumblr.com/">rem @ &gt; 140 characters</a>».</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/dont-like-ie6-really/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Избегаем популярных ошибок в HTML5</title>
		<link>http://web-standards.ru/articles/avoiding-html5-mistakes/</link>
		<comments>http://web-standards.ru/articles/avoiding-html5-mistakes/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 16:12:33 +0000</pubDate>
		<dc:creator>Ричард Кларк</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[методика]]></category>
		<category><![CDATA[семантика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/avoiding-html5-mistakes/</guid>
		<description><![CDATA[<p>Разбирая сайты для <a href="http://html5gallery.com/">Галереи HTML5</a> и отвечая на вопросы читателей на сайте <a href="http://html5doctor.com/">Доктор HTML5</a>, я вынужден просматривать целую кучу страниц на HTML5 и, конечно же, их исходный код. В этой статье я расскажу вам об ошибках и сомнительной разметке, которые мне частенько приходится видеть, и объясню, как их избежать.</p>

<h2>Не используйте <code>&lt;section&gt;</code> как обёртку для оформления</h2>

<p>Одна из самых распространённых проблем, которую я часто вижу в разметке сайтов — это произвольная замена элементов <code>&lt;div&gt;</code> структурными элементами из HTML5, особенно замена оформительской обёртки на <code>&lt;section&gt;</code>. В XHTML или HTML4 я бы увидел что-нибудь такое:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;div id="wrapper"&gt;</code>
	<code>    &lt;div id="header"&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="secondary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="footer"&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>&lt;/div&gt;</code>
</pre>

<p>Вместо этого я вижу следующее:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;section id="wrapper"&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;div id="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;section id="secondary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/section&gt;</code>
	<code>    &lt;footer&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/footer&gt;</code>
	<code>&lt;/section&gt;</code>
</pre>

<p>Честно говоря, это неправильно: <code>&lt;section&gt;</code> — это <strong>не обёртка.</strong> <a href="http://html5doctor.com/section">Элемент <code>&lt;section&gt;</code></a> определяет смысловую секцию содержимого для создания <a href="http://html5doctor.com/outline">структуры документа</a>. Он должен содержать заголовок. Если вы ищете элемент для того чтобы обернуть в него всю страницу (в стиле HTML или XHTML), подумайте, не применить ли стили непосредственно к элементу <code>&lt;body&gt;</code>, <a href="http://camendesign.com/code/developpeurs_sans_frontieres">как описано у Крока Кеймена</a>. Если же вам всё ещё нужна дополнительная обёртка, используйте <code>&lt;div&gt;</code>. Раз уж <a href="http://html5doctor.com/div">Доктор Майк объясняет, что <code>&lt;div&gt;</code> не мёртв</a>, а вам не удаётся найти ничего более удачного, пожалуй, этот элемент будет самым подходящим для создания оформительской обёртки.</p>

<p>Таким образом, корректной разметкой для упомянутого выше примера с использованием HTML5 и пары ролей ARIA будет следующий код. Обратите внимание, что вам, в зависимости от дизайна, всё ещё могут понадобится экстра-элементы <code>&lt;div&gt;</code>.</p>

<pre>
	<code>&lt;body&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;div role="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;aside role="complementary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/aside&gt;</code>
	<code>    &lt;footer&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/footer&gt;</code>
	<code>&lt;/body&gt;</code>
</pre>

<p>Если вы не уверены, какие элементы использовать, я рекомендую вам обратиться к нашей <a href="http://html5doctor.com/happy-1st-birthday-us/#flowchart">пошаговой схеме выбора HTML5-элементов</a> для разметки содержимого.</p>

<h2>Используйте <code>&lt;header&gt;</code> и <code>&lt;hgroup&gt;</code> осознанно</h2>

<p>Нет смысла писать разметку, если этого можно не делать, так ведь? К сожалению, я часто вижу элементы <code>&lt;header&gt;</code> и <code>&lt;hgroup&gt;</code> там, где они совсем не нужны. Вы можете узнать все подробности в наших статьях, посвящённых <a href="http://html5doctor.com/header">элементу <code>&lt;header&gt;</code></a> и <a href="http://html5doctor.com/hgroup">элементу <code>&lt;hgroup&gt;</code></a>, но я коротко резюмирую:</p>

<ul>
	<li>Элемент <code>&lt;header&gt;</code> представляет собой группу вводного содержимого или навигационных средств и обычно содержит структурный заголовок.</li>
	<li>Элемент <code>&lt;hgroup&gt;</code> группирует набор элементов от <code>&lt;h1&gt;</code> до <code>&lt;h6&gt;</code>, представляя собой структурный заголовок в случае, когда заглавие имеет несколько уровней, вроде подзаголовков, альтернативных названий или слоганов.</li>
</ul>

<h3>Злоупотребление <code>&lt;header&gt;</code></h3>

<p>Думаю, что вы в курсе, что <code>&lt;header&gt;</code> можно использовать в документе несколько раз. Но эта возможность привела к следующим ошибкам:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;article&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;!-- Содержимое записи --&gt;</code>
	<code>&lt;/article&gt;</code>
</pre>

<p>Если ваш <code>&lt;header&gt;</code> содержит единственный заголовок, избавьтесь от ненужного <code>&lt;header&gt;</code>. Элемент <code>&lt;article&gt;</code> в любом случае гарантирует, что заголовок войдёт в смысловую структуру документа. И поскольку <code>&lt;header&gt;</code> не содержит нескольких элементов, как указано в его описании, зачем вам код, который, в общем-то, не нужен? Будьте проще:</p>

<pre>
	<code>&lt;article&gt;</code>
	<code>    &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;!-- Содержимое записи --&gt;</code>
	<code>&lt;/article&gt;</code>
</pre>

<h3>Неправильное использование <code>&lt;hgroup&gt;</code></h3>

<p>Раз уж зашла речь о заголовках — я часто вижу неправильное использование <code>&lt;hgroup&gt;</code>. Не следует использовать <code>&lt;hgroup&gt;</code> в сочетании с <code>&lt;header&gt;</code> в случае, когда:</p>

<ul>
	<li>дочерний заголовок всего один или</li>
	<li>элемента <code>&lt;hgroup&gt;</code> будет достаточно и без <code>&lt;header&gt;</code>.</li>
</ul>

<p>Первая проблема выглядит так:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;hgroup&gt;  </code>
	<code>        &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;/hgroup&gt;</code>
	<code>    &lt;p&gt;Ричард Кларк&lt;/p&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>В этом случае стоит избавиться от <code>&lt;hgroup&gt;</code> и оставить только заголовок:</p>

<pre>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;p&gt;Ричард Кларк&lt;/p&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Следующая проблема состоит в очередном использовании элементов там, где они необязательны:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;hgroup&gt;  </code>
	<code>        &lt;h1&gt;Моя компания&lt;/h1&gt;</code>
	<code>        &lt;h2&gt;Основана в 1893 году&lt;/h2&gt;</code>
	<code>    &lt;/hgroup&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Когда <code>&lt;hgroup&gt;</code> — это единственный дочерний элемент <code>&lt;header&gt;</code>, то какой смысл в этом <code>&lt;header&gt;</code>? Если в нём нет дополнительных элементов, соседствующих с <code>&lt;hgroup&gt;</code>, смело избавляйтесь от <code>&lt;header&gt;</code>.</p>

<pre>
	<code>&lt;hgroup&gt;  </code>
	<code>    &lt;h1&gt;Моя компания&lt;/h1&gt;</code>
	<code>    &lt;h2&gt;Основана в 1893 году&lt;/h2&gt;</code>
	<code>&lt;/hgroup&gt;</code>
</pre>

<p>Больше примеров использования <code>&lt;hgroup&gt;</code> вы можете найти <a href="http://html5doctor.com/hgroup">в отдельной, более подробной статье</a>.</p>

<h2>Не оборачивайте все списки ссылок в <code>&lt;nav&gt;</code></h2>

<p>На момент написания статьи существует <a href="http://dev.w3.org/html5/html4-differences/#new-elements">более 30-ти новых элементов</a> и неудивительно, что у нас разбегаются глаза, когда дело доходит до создания осмысленной структурной разметки. Поэтому не стоит злоупортреблять всеми доступными сейчас суперсемантическими элементами. Что, к сожалению, часто происходит с элементом <code>&lt;nav&gt;</code>. Спецификация определяет роль <code>&lt;nav&gt;</code> следующим образом:</p>

<blockquote>
	<p>Элемент <code>&lt;nav&gt;</code> представляет собой часть страницы, которая ссылается на другие страницы или части текущей, то есть раздел с навигационными ссылками.</p>
	<p>Замечание: не все группы ссылок на странице должны быть обёрнуты в элемент <code>&lt;nav&gt;</code> — этот элемент, главным образом, предназначен для группировки главных навигационных блоков. В частности, в подвалах часто содержатся короткие списки ссылок на различные части сайта, вроде правил использования сервиса, домашней страницы и копирайтов. Элемента <code>&lt;footer&gt;</code> вполне достаточно для группировки такого рода ссылок; и несмотря на то, что элемент <code>&lt;nav&gt;</code> может быть использован в таких случаях, обычно в этом нет необходимости.</p>
	<p><a href="http://www.whatwg.org/specs/web-apps/current-work/complete/sections.html#the-nav-element">Спецификация WHATWG HTML</a></p>
</blockquote>

<p>Ключевая фраза — «главных навигационных блоков». Мы можем дискутировать весь день о значении слова «главный», но для меня это значит:</p>

<ul>
	<li>Самая главная навигация;</li>
	<li>Поиск по сайту;</li>
	<li>Вторичная навигация (что спорно);</li>
	<li>Внутренняя навигация (по длинной статье, например).</li>
</ul>

<p>И хотя здесь не может быть «правильного» или «неправильного» использования, поверхностный опрос вкупе с моей собственной интерпретацией говорят, что следующие случаи не подходят для использования <code>&lt;nav&gt;</code>:</p>

<ul>
	<li>Постраничная навигация;</li>
	<li>Социальные ссылки, за исключением тех случаев, когда такие ссылки являются основной навигацией, к примеру, на сайтах <a href="http://about.me/">About Me</a> и <a href="http://flavours.me/">Flavours</a>;</li>
	<li>Тэги к записи в блоге;</li>
	<li>Категории записи;</li>
	<li>Навигация третьего уровня;</li>
	<li>Подвалы, набитые ссылками.</li>
</ul>

<p>Если вы не уверены, стоит ли оборачивать список ссылок в <code>&lt;nav&gt;</code>, просто спросите у себя: «главная ли это навигация?» Чтобы было легче ответить на этот вопрос, обратитесь к следующим правилам:</p>

<ul>
	<li>«Не используйте <code>&lt;nav&gt;</code>, если кажется, что в этом случае может подойти и <code>&lt;section&gt;</code> с заголовком <code>&lt;hx&gt;</code>», — <a href="http://krijnhoetmer.nl/irc-logs/whatwg/20091209#l-480">Ян Хиксон, IRC</a>.</li>
	<li>Добавите ли вы этот блок в список ссылок «перейти» для улучшения доступности?</li>
</ul>

<p>Если ответ на оба эти вопроса «нет», то, скорее всего, это не <code>&lt;nav&gt;</code>.</p>

<h2>Общие ошибки с элементом <code>&lt;figure&gt;</code></h2>

<p>Ах, <code>&lt;figure&gt;</code>. Правильным использованием этого элемента вместе с подельником <code>&lt;figcaption&gt;</code> не так-то просто овладеть. Рассмотрим некоторые общие проблемы, которые я вижу при использовании <code>&lt;figure&gt;</code>.</p>

<h3>Не каждая картинка это <code>&lt;figure&gt;</code></h3>

<p>Ранее я советовал вам не писать лишний код там, где этого не требуется. Та же ошибка и здесь. Я видел сайты, где каждая картинка была обёрнута в <code>&lt;figure&gt;</code>. Нет никакой необходимости в добавлении экстра-разметки вокруг картинок только ради самого процесса. Вы просто делаете лишнюю работу и нисколько не улучшаете описание содержимого страницы.</p>

<p>Спецификация обозначает <code>&lt;figure&gt;</code> как «содержимое в потоке, с необязательным заглавием, самодостаточное, обычно упоминаемое в качестве смысловой единицы в основном тексте». Как раз в этом состоит вся красота элемента <code>&lt;figure&gt;</code>, который может быть перемещён из основного содержимого, скажем, в колонку, что никак не повлияет на основной поток документа.</p>

<p>Если это исключительно оформительская картинка, никаким образом не упомянутая в основном документе, то это точно не <code>&lt;figure&gt;</code>. Есть и другие варианты использования, но просто спросите себя: «Нужна ли эта картинка для лучшего понимания контекста?» Если нет, то это вероятно не <code>&lt;figure&gt;</code>, а, возможно, <code>&lt;aside&gt;</code>. Если да, спросите себя: «Можно ли переместить эту картинку в примечания к тексту?» Если ответ на оба вопроса «да», то это, вероятнее всего, <code>&lt;figure&gt;</code>.</p>

<h3>Ваш логотип — это не <code>&lt;figure&gt;</code></h3>

<p>Плавно переходим к следующей проблеме, вышеупомянутые правила применимы и к ней. Вот пара регулярно встречающихся примеров:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;</code>
	<code>        &lt;figure&gt;</code>
	<code>            &lt;img src="logo.png" alt="Моя компания"&gt;</code>
	<code>        &lt;/figure&gt;</code>
	<code>        Название компании</code>
	<code>    &lt;/h1&gt;</code>
	<code>&lt;/header&gt;</code>
	<code> </code>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;  </code>
	<code>    &lt;figure&gt;</code>
	<code>        &lt;img src="logo.png" alt="Моя компания"&gt;</code>
	<code>    &lt;/figure&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Добавить здесь нечего: это совсем неправильно. Мы можем спорить до посинения насчёт того, должно ли лого находиться внутри <code>&lt;h1&gt;</code>, но мы здесь не за этим. Настоящая проблема — в неправильном употреблении <code>&lt;figure&gt;</code>. Этот элемент должен использоваться, только если он упоминается в документе или контексте общего структурного элемента. Будет честным признать, что ваш логотип вряд ли будет упомянут подобным образом. Просто не делайте так. Всё, что вам нужно, это:</p>

<pre>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;Название компании&lt;/h1&gt;</code>
	<code>    &lt;!-- и всё остальное здесь --&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<h3>Элемент <code>&lt;figure&gt;</code> — это не только картинки</h3>

<p>Другое распространённое заблуждение насчёт <code>&lt;figure&gt;</code> — что он может быть использован только для картинок. Это не так. Элемент <code>&lt;figure&gt;</code> может быть видео, аудио, графиком (на SVG, к примеру), цитатой, таблицей, блоком кода, фрагментом текста или любой комбинацией этих и многих других элементов. Не ограничивайте использование <code>&lt;figure&gt;</code> только картинками. Наша работа, как энтузиастов от веб-стандартов, заключается в том, чтобы максимально точно описывать содержимое при помощи разметки.</p>

<p>Некоторое время назад я <a href="http://html5doctor.com/figure">писал про <code>&lt;figure&gt;</code> детальнее</a>. Рекомендую почитать, если вам интересно узнать подробности или просто освежить знания.</p>

<h2>Не используйте ненужные атрибуты <code>type</code></h2>

<p>Эта проблема, пожалуй, является самой распространённой среди заявок в Галерею HTML5. И хотя это, по сути, не ошибка, мне кажется, что правильнее будет её избегать.</p>

<p>Дело в том, что в HTML5 не нужно добавлять атрибут <code>type</code> для элементов <code>&lt;script&gt;</code> и <code>&lt;style&gt;</code>. Если эти элементы автоматически добавляются вашей CMS, то избавиться от них может быть непросто, но если вы пишете код руками или полностью контролируете шаблоны, то нет никакого смысла писать избыточные атрибуты. Поскольку все браузеры ожидают, что скриптами будет JavaScript, а стилями CSS, вам это совсем не нужно:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;link type="text/css" rel="stylesheet" href="styles.css"&gt;</code>
	<code>&lt;script type="text/javascript" src="scripts"&gt;&lt;/script&gt;</code>
</pre>

<p>Вместо этого просто напишите:</p>

<pre>
	<code>&lt;link rel="stylesheet" href="styles.css"&gt;</code>
	<code>&lt;script src="scripts"&gt;&lt;/script&gt;</code>
</pre>

<p>Кроме того, вы можете уменьшить объём кода, который пишете для задания кодировки документа и других вещей. Глава про семантику в «<a href="http://diveintohtml5.org/semantics.html">Погружении в HTML5</a>» Марка Пилгрима объясняет всё.</p>

<h2>Неправильное использование атрибутов форм</h2>

<p>Вы, должно быть, знаете, что HTML5 предложил набор новых атрибутов для элементов форм. Мы расскажем о них подробнее в ближайшие месяцы, а пока я покажу вам некоторые вещи, которые делать не стоит.</p>

<h3>Одиночные атрибуты</h3>

<p>Некоторые новые атрибуты для элементов форм являются одиночными, и только одно их присутствие в разметке обеспечивает смену поведения. Эти атрибуты включают:</p>

<pre>
	<code>autofocus</code>
	<code>autocomplete</code>
	<code>required</code>
</pre>

<p>Надо признаться, я нечасто встречал подобное, но если в качестве примера взять атрибут <code>required</code>, то попадалось следующее:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;input type="email" name="email" required="true"&gt;</code>
	<code>&lt;!-- Ещё один плохой пример --&gt;</code>
	<code>&lt;input type="email" name="email" required="1"&gt;</code>
</pre>

<p>В конечном счёте это никому не вредит. HTML-парсер видит атрибут <code>required</code> в разметке, поэтому требуемая функциональность будет включена. Но что, если поставить код вверх ногами и написать <code>required="false"</code>?</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;input type="email" name="email" required="false"&gt;</code>
</pre>

<p>Парсер по-прежнему увидит атрибут <code>required</code> и применит поведение, несмотря на то, что вы пытались сказать ему не делать этого. Явно не то, что вам было нужно.</p>

<p>Существует три правильных способа задания одиночных атрибутов, второй и третий из которых нужны только если вы пишете XHTML:</p>

<pre>
	<code>required</code>
	<code>required=""</code>
	<code>required="required"</code>
</pre>

<p>Если применить эту запись к нашему примеру (в HTML), получится следующее:</p>

<pre>
	<code>&lt;input type="email" name="email" required&gt;</code>
</pre>

<h2>Резюме</h2>

<p>Было бы просто невозможным перечислить здесь все странные приёмы и образцы разметки, с которыми мне довелось столкнуться, но эти — одни из самых часто встречавшихся. А какие ещё ошибки разметки бросались вам в глаза? Расскажите в комментариях.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/avoiding-common-html5-mistakes/">Avoiding common HTML5 mistakes</a>» <a href="http://richclarkdesign.com/">Ричарда Кларка</a> (Richard Clark), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Разбирая сайты для <a href="http://html5gallery.com/">Галереи HTML5</a> и отвечая на вопросы читателей на сайте <a href="http://html5doctor.com/">Доктор HTML5</a>, я вынужден просматривать целую кучу страниц на HTML5 и, конечно же, их исходный код. В этой статье я расскажу вам об ошибках и сомнительной разметке, которые мне частенько приходится видеть, и объясню, как их избежать.</p>

<h2>Не используйте <code>&lt;section&gt;</code> как обёртку для оформления</h2>

<p>Одна из самых распространённых проблем, которую я часто вижу в разметке сайтов — это произвольная замена элементов <code>&lt;div&gt;</code> структурными элементами из HTML5, особенно замена оформительской обёртки на <code>&lt;section&gt;</code>. В XHTML или HTML4 я бы увидел что-нибудь такое:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;div id="wrapper"&gt;</code>
	<code>    &lt;div id="header"&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="secondary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;div id="footer"&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>&lt;/div&gt;</code>
</pre>

<p>Вместо этого я вижу следующее:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;section id="wrapper"&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;div id="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;section id="secondary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/section&gt;</code>
	<code>    &lt;footer&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/footer&gt;</code>
	<code>&lt;/section&gt;</code>
</pre>

<p>Честно говоря, это неправильно: <code>&lt;section&gt;</code> — это <strong>не обёртка.</strong> <a href="http://html5doctor.com/section">Элемент <code>&lt;section&gt;</code></a> определяет смысловую секцию содержимого для создания <a href="http://html5doctor.com/outline">структуры документа</a>. Он должен содержать заголовок. Если вы ищете элемент для того чтобы обернуть в него всю страницу (в стиле HTML или XHTML), подумайте, не применить ли стили непосредственно к элементу <code>&lt;body&gt;</code>, <a href="http://camendesign.com/code/developpeurs_sans_frontieres">как описано у Крока Кеймена</a>. Если же вам всё ещё нужна дополнительная обёртка, используйте <code>&lt;div&gt;</code>. Раз уж <a href="http://html5doctor.com/div">Доктор Майк объясняет, что <code>&lt;div&gt;</code> не мёртв</a>, а вам не удаётся найти ничего более удачного, пожалуй, этот элемент будет самым подходящим для создания оформительской обёртки.</p>

<p>Таким образом, корректной разметкой для упомянутого выше примера с использованием HTML5 и пары ролей ARIA будет следующий код. Обратите внимание, что вам, в зависимости от дизайна, всё ещё могут понадобится экстра-элементы <code>&lt;div&gt;</code>.</p>

<pre>
	<code>&lt;body&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Моя супер-пупер страница&lt;/h1&gt;</code>
	<code>        &lt;!-- Содержимое шапки --&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;div role="main"&gt;</code>
	<code>        &lt;!-- Содержимое страницы --&gt;</code>
	<code>    &lt;/div&gt;</code>
	<code>    &lt;aside role="complementary"&gt;</code>
	<code>        &lt;!-- Вторичное содержимое --&gt;</code>
	<code>    &lt;/aside&gt;</code>
	<code>    &lt;footer&gt;</code>
	<code>        &lt;!-- Содержимое подвала --&gt;</code>
	<code>    &lt;/footer&gt;</code>
	<code>&lt;/body&gt;</code>
</pre>

<p>Если вы не уверены, какие элементы использовать, я рекомендую вам обратиться к нашей <a href="http://html5doctor.com/happy-1st-birthday-us/#flowchart">пошаговой схеме выбора HTML5-элементов</a> для разметки содержимого.</p>

<h2>Используйте <code>&lt;header&gt;</code> и <code>&lt;hgroup&gt;</code> осознанно</h2>

<p>Нет смысла писать разметку, если этого можно не делать, так ведь? К сожалению, я часто вижу элементы <code>&lt;header&gt;</code> и <code>&lt;hgroup&gt;</code> там, где они совсем не нужны. Вы можете узнать все подробности в наших статьях, посвящённых <a href="http://html5doctor.com/header">элементу <code>&lt;header&gt;</code></a> и <a href="http://html5doctor.com/hgroup">элементу <code>&lt;hgroup&gt;</code></a>, но я коротко резюмирую:</p>

<ul>
	<li>Элемент <code>&lt;header&gt;</code> представляет собой группу вводного содержимого или навигационных средств и обычно содержит структурный заголовок.</li>
	<li>Элемент <code>&lt;hgroup&gt;</code> группирует набор элементов от <code>&lt;h1&gt;</code> до <code>&lt;h6&gt;</code>, представляя собой структурный заголовок в случае, когда заглавие имеет несколько уровней, вроде подзаголовков, альтернативных названий или слоганов.</li>
</ul>

<h3>Злоупотребление <code>&lt;header&gt;</code></h3>

<p>Думаю, что вы в курсе, что <code>&lt;header&gt;</code> можно использовать в документе несколько раз. Но эта возможность привела к следующим ошибкам:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;article&gt;</code>
	<code>    &lt;header&gt;  </code>
	<code>        &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;/header&gt;</code>
	<code>    &lt;!-- Содержимое записи --&gt;</code>
	<code>&lt;/article&gt;</code>
</pre>

<p>Если ваш <code>&lt;header&gt;</code> содержит единственный заголовок, избавьтесь от ненужного <code>&lt;header&gt;</code>. Элемент <code>&lt;article&gt;</code> в любом случае гарантирует, что заголовок войдёт в смысловую структуру документа. И поскольку <code>&lt;header&gt;</code> не содержит нескольких элементов, как указано в его описании, зачем вам код, который, в общем-то, не нужен? Будьте проще:</p>

<pre>
	<code>&lt;article&gt;</code>
	<code>    &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;!-- Содержимое записи --&gt;</code>
	<code>&lt;/article&gt;</code>
</pre>

<h3>Неправильное использование <code>&lt;hgroup&gt;</code></h3>

<p>Раз уж зашла речь о заголовках — я часто вижу неправильное использование <code>&lt;hgroup&gt;</code>. Не следует использовать <code>&lt;hgroup&gt;</code> в сочетании с <code>&lt;header&gt;</code> в случае, когда:</p>

<ul>
	<li>дочерний заголовок всего один или</li>
	<li>элемента <code>&lt;hgroup&gt;</code> будет достаточно и без <code>&lt;header&gt;</code>.</li>
</ul>

<p>Первая проблема выглядит так:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;hgroup&gt;  </code>
	<code>        &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;/hgroup&gt;</code>
	<code>    &lt;p&gt;Ричард Кларк&lt;/p&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>В этом случае стоит избавиться от <code>&lt;hgroup&gt;</code> и оставить только заголовок:</p>

<pre>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;Мой лучший пост&lt;/h1&gt;</code>
	<code>    &lt;p&gt;Ричард Кларк&lt;/p&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Следующая проблема состоит в очередном использовании элементов там, где они необязательны:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;hgroup&gt;  </code>
	<code>        &lt;h1&gt;Моя компания&lt;/h1&gt;</code>
	<code>        &lt;h2&gt;Основана в 1893 году&lt;/h2&gt;</code>
	<code>    &lt;/hgroup&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Когда <code>&lt;hgroup&gt;</code> — это единственный дочерний элемент <code>&lt;header&gt;</code>, то какой смысл в этом <code>&lt;header&gt;</code>? Если в нём нет дополнительных элементов, соседствующих с <code>&lt;hgroup&gt;</code>, смело избавляйтесь от <code>&lt;header&gt;</code>.</p>

<pre>
	<code>&lt;hgroup&gt;  </code>
	<code>    &lt;h1&gt;Моя компания&lt;/h1&gt;</code>
	<code>    &lt;h2&gt;Основана в 1893 году&lt;/h2&gt;</code>
	<code>&lt;/hgroup&gt;</code>
</pre>

<p>Больше примеров использования <code>&lt;hgroup&gt;</code> вы можете найти <a href="http://html5doctor.com/hgroup">в отдельной, более подробной статье</a>.</p>

<h2>Не оборачивайте все списки ссылок в <code>&lt;nav&gt;</code></h2>

<p>На момент написания статьи существует <a href="http://dev.w3.org/html5/html4-differences/#new-elements">более 30-ти новых элементов</a> и неудивительно, что у нас разбегаются глаза, когда дело доходит до создания осмысленной структурной разметки. Поэтому не стоит злоупортреблять всеми доступными сейчас суперсемантическими элементами. Что, к сожалению, часто происходит с элементом <code>&lt;nav&gt;</code>. Спецификация определяет роль <code>&lt;nav&gt;</code> следующим образом:</p>

<blockquote>
	<p>Элемент <code>&lt;nav&gt;</code> представляет собой часть страницы, которая ссылается на другие страницы или части текущей, то есть раздел с навигационными ссылками.</p>
	<p>Замечание: не все группы ссылок на странице должны быть обёрнуты в элемент <code>&lt;nav&gt;</code> — этот элемент, главным образом, предназначен для группировки главных навигационных блоков. В частности, в подвалах часто содержатся короткие списки ссылок на различные части сайта, вроде правил использования сервиса, домашней страницы и копирайтов. Элемента <code>&lt;footer&gt;</code> вполне достаточно для группировки такого рода ссылок; и несмотря на то, что элемент <code>&lt;nav&gt;</code> может быть использован в таких случаях, обычно в этом нет необходимости.</p>
	<p><a href="http://www.whatwg.org/specs/web-apps/current-work/complete/sections.html#the-nav-element">Спецификация WHATWG HTML</a></p>
</blockquote>

<p>Ключевая фраза — «главных навигационных блоков». Мы можем дискутировать весь день о значении слова «главный», но для меня это значит:</p>

<ul>
	<li>Самая главная навигация;</li>
	<li>Поиск по сайту;</li>
	<li>Вторичная навигация (что спорно);</li>
	<li>Внутренняя навигация (по длинной статье, например).</li>
</ul>

<p>И хотя здесь не может быть «правильного» или «неправильного» использования, поверхностный опрос вкупе с моей собственной интерпретацией говорят, что следующие случаи не подходят для использования <code>&lt;nav&gt;</code>:</p>

<ul>
	<li>Постраничная навигация;</li>
	<li>Социальные ссылки, за исключением тех случаев, когда такие ссылки являются основной навигацией, к примеру, на сайтах <a href="http://about.me/">About Me</a> и <a href="http://flavours.me/">Flavours</a>;</li>
	<li>Тэги к записи в блоге;</li>
	<li>Категории записи;</li>
	<li>Навигация третьего уровня;</li>
	<li>Подвалы, набитые ссылками.</li>
</ul>

<p>Если вы не уверены, стоит ли оборачивать список ссылок в <code>&lt;nav&gt;</code>, просто спросите у себя: «главная ли это навигация?» Чтобы было легче ответить на этот вопрос, обратитесь к следующим правилам:</p>

<ul>
	<li>«Не используйте <code>&lt;nav&gt;</code>, если кажется, что в этом случае может подойти и <code>&lt;section&gt;</code> с заголовком <code>&lt;hx&gt;</code>», — <a href="http://krijnhoetmer.nl/irc-logs/whatwg/20091209#l-480">Ян Хиксон, IRC</a>.</li>
	<li>Добавите ли вы этот блок в список ссылок «перейти» для улучшения доступности?</li>
</ul>

<p>Если ответ на оба эти вопроса «нет», то, скорее всего, это не <code>&lt;nav&gt;</code>.</p>

<h2>Общие ошибки с элементом <code>&lt;figure&gt;</code></h2>

<p>Ах, <code>&lt;figure&gt;</code>. Правильным использованием этого элемента вместе с подельником <code>&lt;figcaption&gt;</code> не так-то просто овладеть. Рассмотрим некоторые общие проблемы, которые я вижу при использовании <code>&lt;figure&gt;</code>.</p>

<h3>Не каждая картинка это <code>&lt;figure&gt;</code></h3>

<p>Ранее я советовал вам не писать лишний код там, где этого не требуется. Та же ошибка и здесь. Я видел сайты, где каждая картинка была обёрнута в <code>&lt;figure&gt;</code>. Нет никакой необходимости в добавлении экстра-разметки вокруг картинок только ради самого процесса. Вы просто делаете лишнюю работу и нисколько не улучшаете описание содержимого страницы.</p>

<p>Спецификация обозначает <code>&lt;figure&gt;</code> как «содержимое в потоке, с необязательным заглавием, самодостаточное, обычно упоминаемое в качестве смысловой единицы в основном тексте». Как раз в этом состоит вся красота элемента <code>&lt;figure&gt;</code>, который может быть перемещён из основного содержимого, скажем, в колонку, что никак не повлияет на основной поток документа.</p>

<p>Если это исключительно оформительская картинка, никаким образом не упомянутая в основном документе, то это точно не <code>&lt;figure&gt;</code>. Есть и другие варианты использования, но просто спросите себя: «Нужна ли эта картинка для лучшего понимания контекста?» Если нет, то это вероятно не <code>&lt;figure&gt;</code>, а, возможно, <code>&lt;aside&gt;</code>. Если да, спросите себя: «Можно ли переместить эту картинку в примечания к тексту?» Если ответ на оба вопроса «да», то это, вероятнее всего, <code>&lt;figure&gt;</code>.</p>

<h3>Ваш логотип — это не <code>&lt;figure&gt;</code></h3>

<p>Плавно переходим к следующей проблеме, вышеупомянутые правила применимы и к ней. Вот пара регулярно встречающихся примеров:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;</code>
	<code>        &lt;figure&gt;</code>
	<code>            &lt;img src="logo.png" alt="Моя компания"&gt;</code>
	<code>        &lt;/figure&gt;</code>
	<code>        Название компании</code>
	<code>    &lt;/h1&gt;</code>
	<code>&lt;/header&gt;</code>
	<code> </code>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;header&gt;  </code>
	<code>    &lt;figure&gt;</code>
	<code>        &lt;img src="logo.png" alt="Моя компания"&gt;</code>
	<code>    &lt;/figure&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<p>Добавить здесь нечего: это совсем неправильно. Мы можем спорить до посинения насчёт того, должно ли лого находиться внутри <code>&lt;h1&gt;</code>, но мы здесь не за этим. Настоящая проблема — в неправильном употреблении <code>&lt;figure&gt;</code>. Этот элемент должен использоваться, только если он упоминается в документе или контексте общего структурного элемента. Будет честным признать, что ваш логотип вряд ли будет упомянут подобным образом. Просто не делайте так. Всё, что вам нужно, это:</p>

<pre>
	<code>&lt;header&gt;</code>
	<code>    &lt;h1&gt;Название компании&lt;/h1&gt;</code>
	<code>    &lt;!-- и всё остальное здесь --&gt;</code>
	<code>&lt;/header&gt;</code>
</pre>

<h3>Элемент <code>&lt;figure&gt;</code> — это не только картинки</h3>

<p>Другое распространённое заблуждение насчёт <code>&lt;figure&gt;</code> — что он может быть использован только для картинок. Это не так. Элемент <code>&lt;figure&gt;</code> может быть видео, аудио, графиком (на SVG, к примеру), цитатой, таблицей, блоком кода, фрагментом текста или любой комбинацией этих и многих других элементов. Не ограничивайте использование <code>&lt;figure&gt;</code> только картинками. Наша работа, как энтузиастов от веб-стандартов, заключается в том, чтобы максимально точно описывать содержимое при помощи разметки.</p>

<p>Некоторое время назад я <a href="http://html5doctor.com/figure">писал про <code>&lt;figure&gt;</code> детальнее</a>. Рекомендую почитать, если вам интересно узнать подробности или просто освежить знания.</p>

<h2>Не используйте ненужные атрибуты <code>type</code></h2>

<p>Эта проблема, пожалуй, является самой распространённой среди заявок в Галерею HTML5. И хотя это, по сути, не ошибка, мне кажется, что правильнее будет её избегать.</p>

<p>Дело в том, что в HTML5 не нужно добавлять атрибут <code>type</code> для элементов <code>&lt;script&gt;</code> и <code>&lt;style&gt;</code>. Если эти элементы автоматически добавляются вашей CMS, то избавиться от них может быть непросто, но если вы пишете код руками или полностью контролируете шаблоны, то нет никакого смысла писать избыточные атрибуты. Поскольку все браузеры ожидают, что скриптами будет JavaScript, а стилями CSS, вам это совсем не нужно:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;link type="text/css" rel="stylesheet" href="styles.css"&gt;</code>
	<code>&lt;script type="text/javascript" src="scripts"&gt;&lt;/script&gt;</code>
</pre>

<p>Вместо этого просто напишите:</p>

<pre>
	<code>&lt;link rel="stylesheet" href="styles.css"&gt;</code>
	<code>&lt;script src="scripts"&gt;&lt;/script&gt;</code>
</pre>

<p>Кроме того, вы можете уменьшить объём кода, который пишете для задания кодировки документа и других вещей. Глава про семантику в «<a href="http://diveintohtml5.org/semantics.html">Погружении в HTML5</a>» Марка Пилгрима объясняет всё.</p>

<h2>Неправильное использование атрибутов форм</h2>

<p>Вы, должно быть, знаете, что HTML5 предложил набор новых атрибутов для элементов форм. Мы расскажем о них подробнее в ближайшие месяцы, а пока я покажу вам некоторые вещи, которые делать не стоит.</p>

<h3>Одиночные атрибуты</h3>

<p>Некоторые новые атрибуты для элементов форм являются одиночными, и только одно их присутствие в разметке обеспечивает смену поведения. Эти атрибуты включают:</p>

<pre>
	<code>autofocus</code>
	<code>autocomplete</code>
	<code>required</code>
</pre>

<p>Надо признаться, я нечасто встречал подобное, но если в качестве примера взять атрибут <code>required</code>, то попадалось следующее:</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;input type="email" name="email" required="true"&gt;</code>
	<code>&lt;!-- Ещё один плохой пример --&gt;</code>
	<code>&lt;input type="email" name="email" required="1"&gt;</code>
</pre>

<p>В конечном счёте это никому не вредит. HTML-парсер видит атрибут <code>required</code> в разметке, поэтому требуемая функциональность будет включена. Но что, если поставить код вверх ногами и написать <code>required="false"</code>?</p>

<pre>
	<code>&lt;!-- Не копируйте этот код! Он неправильный! --&gt;</code>
	<code>&lt;input type="email" name="email" required="false"&gt;</code>
</pre>

<p>Парсер по-прежнему увидит атрибут <code>required</code> и применит поведение, несмотря на то, что вы пытались сказать ему не делать этого. Явно не то, что вам было нужно.</p>

<p>Существует три правильных способа задания одиночных атрибутов, второй и третий из которых нужны только если вы пишете XHTML:</p>

<pre>
	<code>required</code>
	<code>required=""</code>
	<code>required="required"</code>
</pre>

<p>Если применить эту запись к нашему примеру (в HTML), получится следующее:</p>

<pre>
	<code>&lt;input type="email" name="email" required&gt;</code>
</pre>

<h2>Резюме</h2>

<p>Было бы просто невозможным перечислить здесь все странные приёмы и образцы разметки, с которыми мне довелось столкнуться, но эти — одни из самых часто встречавшихся. А какие ещё ошибки разметки бросались вам в глаза? Расскажите в комментариях.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/avoiding-common-html5-mistakes/">Avoiding common HTML5 mistakes</a>» <a href="http://richclarkdesign.com/">Ричарда Кларка</a> (Richard Clark), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/avoiding-html5-mistakes/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Элементы small и hr</title>
		<link>http://web-standards.ru/articles/small-hr-elements/</link>
		<comments>http://web-standards.ru/articles/small-hr-elements/#comments</comments>
		<pubDate>Mon, 30 May 2011 06:55:52 +0000</pubDate>
		<dc:creator>Оли Стадхольм</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[семантика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/small-hr-elements/</guid>
		<description><![CDATA[<p>Не так давно мы писали <a href="http://web-standards.ru/articles/i-b-em-strong-elements/">о презентационных элементах <code>&lt;i&gt;</code> и <code>&lt;b&gt;</code></a> из HTML4, возродившихся к новой семантической жизни. Другие два элемента, которые претерпели изменения, чтобы получить значения в HTML5 — это <code>&lt;small&gt;</code> и <code>&lt;hr&gt;</code>:</p>

<ul>
	<li><code>&lt;small&gt;</code> — использовался раньше для того, чтобы просто сделать текст помельче, теперь же он предназначен для пометок и небольших надписей (<a href="http://dev.w3.org/html5/markup/small.html">W3C:Markup</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-small-element">WHATWG</a>);</li>
	<li><code>&lt;hr&gt;</code> — использовался раньше для создания горизонтальных линеек, теперь предназначен для смысловой разбивки на уровне текстовых блоков (<a href="http://dev.w3.org/html5/markup/hr.html">W3C:Markup</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-hr-element">WHATWG</a>).</li>
</ul>

<h2>Элемент <code>&lt;small&gt;</code></h2>

<blockquote>
	<p>Элемент <code>&lt;small&gt;</code> представляет собой так называемые «надписи мелким шрифтом», вроде тех, что используются для предостережений и оговорок в юридических документах.</p>
	<p><a href="http://dev.w3.org/html5/markup/small.html">Спецификация W3C</a></p>
</blockquote>

<p>Теперь <code>&lt;small&gt;</code> применяется для пометок и является более локальным аналогом элемента <code>&lt;aside&gt;</code> — для второстепенной информации на странице. Типичным примером будет следующая за основным содержимым юридическая болтовня, вроде заявлений об авторском праве в подвале, отказе от ответственности, или же информации о лицензии. Он также может быть использован для указания авторства. <strong>Не используйте его для содержимого на блочном уровне</strong> (параграфы, списки и т.д.), иначе это будет воспринято как основное содержимое.</p>

<pre>
	<code>&lt;p&gt;</code>
	<code>    Я использую</code>
	<code>    &lt;span class="museo"&gt;Museo Slab&lt;/span&gt;,</code>
	<code>    &lt;small class="font-license"&gt;</code>
	<code>        шрифт Жоса Буйвенга (exljbris)</code>
	<code>        &lt;a href="http://www.exljbris.nl/"&gt;www.exljbris.nl&lt;/a&gt;</code>
	<code>    &lt;/small&gt;</code>
	<code>&lt;/p&gt;</code>
</pre>

<p class="note">Использование <code>&lt;small class="font-license"&gt;</code> для того, чтобы выполнить требования лицензионного соглашения</p>

<pre>
	<code>&lt;small&gt;</code>
	<code>    &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/"</code>
	<code>        rel="license"&gt;</code>
	<code>        Creative Commons Attribution Share-alike license</code>
	<code>    &lt;/a&gt;</code>
	<code>&lt;/small&gt;</code>
</pre>

<p class="note">Использование <code>&lt;small&gt;</code> вокруг ссылки на <a href="http://creativecommons.org/choose/">Creative Commons license</a> с <code>rel="license"</code></p>

<p>Текст внутри <code>&lt;small&gt;</code> необязательно должен быть меньше, чем окружающий — если же вам нужен именно мелкий текст, то для этого лучше подойдет CSS. Используйте <code>&lt;small&gt;</code> только на строчном уровне. В конце концов, <code>&lt;small&gt;</code> не влияет на семантику <code>&lt;em&gt;</code> или <code>&lt;strong&gt;</code>.</p>

<h2>Элемент <code>&lt;hr&gt;</code></h2>

<blockquote>
	<p><code>&lt;hr&gt;</code> служит для смысловой разбивки на уровне блоков текста</p>
	<p><a href="http://dev.w3.org/html5/markup/hr.html">Спецификация W3C</a></p>
</blockquote>

<p>Пообщавшись с <a href="http://ian.hixie.ch/">Яном Хиксоном</a> (редактором HTML5) я понял, что до сих пор неправильно понимал <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/content-models.html#paragraph">модель поведения содержимого</a>. Я узнал, что <code>&lt;hr&gt;</code> на самом деле означает <q>конец одной секции и начало другой</q> — что семантически равносильно <code>&lt;/section&gt;&lt;section&gt;</code>. Но поскольку элементы вроде <code>&lt;section&gt;</code> и так указывают на это, получается, что <code>&lt;hr&gt;</code> больше подходит для смысловой разбивки, вроде смыслового разделения внутри блока текста или отделения одной сцены в романе от другой. В любом случае, вы можете использовать этот элемент везде, где вы используете элемент <code>&lt;p&gt;</code>. Из-за унылого вида в браузерах по умолчанию, <code>&lt;hr&gt;</code> не слишком распространён сегодня, однако это не мешает оформить его при помощи CSS в виде красивого вензеля.</p>

<p><img src="http://static.web-standards.ru/articles/small-hr-elements/hr-separator.png" alt="Оформление &lt;hr&gt; в виде вензеля" class="pic"></p>

<pre>
	<code>hr {</code>
	<code>    margin:3em 0;</code>
	<code>    height:24px;</code>
	<code>    border:0;</code>
	<code>    background:url(flourish.png) 50% 50% no-repeat;</code>
	<code>    }</code>
</pre>

<p class="note">Оформите <code>&lt;hr&gt;</code> красиво: уберите рамку, поля и добавьте фоновую картинку.</p>

<p>IE7 и младше оправдывают свою дурную репутацию, добавляя рамку вокруг изображения, несмотря на наши усилия, <a href="http://blog.neatlysliced.com/2008/03/hr-image-replacement/">но и это можно исправить</a>. Или же вы можете просто скрыть <code>&lt;hr&gt;</code> в стилях для IE7 и младше. Если переход между частями содержимого очевиден или разделение чисто визуальное, а не смысловое, то вместо <code>&lt;hr&gt;</code> лучше нарисовать рамку или фоновую картинку на другом элементе.</p>

<p><img src="http://static.web-standards.ru/articles/small-hr-elements/corkd.png" alt="Неподходящий случай для использования &lt;hr&gt; на Cork’d.com" class="pic"></p>

<p class="note">На <a href="http://content.corkd.com/">Cork’d</a> используеся декоративная фоновая картинка для заголовков. Но несмотря на обилие линеек, это совсем неподходящий случай для использования <code>&lt;hr&gt;</code>.</p>

<h2>В заключение</h2>

<p>В момент выхода HTML4, презентационные элементы <code>&lt;basefont&gt;</code>, <code>&lt;font&gt;</code>, <code>&lt;s&gt;</code>, <code>&lt;strike&gt;</code> и <code>&lt;u&gt;</code> уже были помечены как нежелательные для использования, в пользу применения CSS. HTML5 завершил этот процесс, избавившись от элементов <code>&lt;big&gt;</code> и <code>&lt;tt&gt;</code>.</p>

<p>Остальные презентационные элементы из HTML4 — долго игнорируемые <code>&lt;small&gt;</code> и <code>&lt;hr&gt;</code> (<a href="http://web-standards.ru/articles/i-b-em-strong-elements/">наряду с <code>&lt;i&gt;</code> и <code>&lt;b&gt;</code></a>) — были пересмотрены в HTML5 с учетом их полезных, медиа-независимых семантических свойств, которые имеют отношение к их типичному использованию. Будете ли <em>вы</em> использовать их? Выскажитесь в комментариях!</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/small-hr-element/">The small &amp; hr elements</a>» <a href="http://oli.jp/">Оли Стадхольма</a> (Oli Studholme), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Не так давно мы писали <a href="http://web-standards.ru/articles/i-b-em-strong-elements/">о презентационных элементах <code>&lt;i&gt;</code> и <code>&lt;b&gt;</code></a> из HTML4, возродившихся к новой семантической жизни. Другие два элемента, которые претерпели изменения, чтобы получить значения в HTML5 — это <code>&lt;small&gt;</code> и <code>&lt;hr&gt;</code>:</p>

<ul>
	<li><code>&lt;small&gt;</code> — использовался раньше для того, чтобы просто сделать текст помельче, теперь же он предназначен для пометок и небольших надписей (<a href="http://dev.w3.org/html5/markup/small.html">W3C:Markup</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-small-element">WHATWG</a>);</li>
	<li><code>&lt;hr&gt;</code> — использовался раньше для создания горизонтальных линеек, теперь предназначен для смысловой разбивки на уровне текстовых блоков (<a href="http://dev.w3.org/html5/markup/hr.html">W3C:Markup</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-hr-element">WHATWG</a>).</li>
</ul>

<h2>Элемент <code>&lt;small&gt;</code></h2>

<blockquote>
	<p>Элемент <code>&lt;small&gt;</code> представляет собой так называемые «надписи мелким шрифтом», вроде тех, что используются для предостережений и оговорок в юридических документах.</p>
	<p><a href="http://dev.w3.org/html5/markup/small.html">Спецификация W3C</a></p>
</blockquote>

<p>Теперь <code>&lt;small&gt;</code> применяется для пометок и является более локальным аналогом элемента <code>&lt;aside&gt;</code> — для второстепенной информации на странице. Типичным примером будет следующая за основным содержимым юридическая болтовня, вроде заявлений об авторском праве в подвале, отказе от ответственности, или же информации о лицензии. Он также может быть использован для указания авторства. <strong>Не используйте его для содержимого на блочном уровне</strong> (параграфы, списки и т.д.), иначе это будет воспринято как основное содержимое.</p>

<pre>
	<code>&lt;p&gt;</code>
	<code>    Я использую</code>
	<code>    &lt;span class="museo"&gt;Museo Slab&lt;/span&gt;,</code>
	<code>    &lt;small class="font-license"&gt;</code>
	<code>        шрифт Жоса Буйвенга (exljbris)</code>
	<code>        &lt;a href="http://www.exljbris.nl/"&gt;www.exljbris.nl&lt;/a&gt;</code>
	<code>    &lt;/small&gt;</code>
	<code>&lt;/p&gt;</code>
</pre>

<p class="note">Использование <code>&lt;small class="font-license"&gt;</code> для того, чтобы выполнить требования лицензионного соглашения</p>

<pre>
	<code>&lt;small&gt;</code>
	<code>    &lt;a href="http://creativecommons.org/licenses/by-sa/3.0/"</code>
	<code>        rel="license"&gt;</code>
	<code>        Creative Commons Attribution Share-alike license</code>
	<code>    &lt;/a&gt;</code>
	<code>&lt;/small&gt;</code>
</pre>

<p class="note">Использование <code>&lt;small&gt;</code> вокруг ссылки на <a href="http://creativecommons.org/choose/">Creative Commons license</a> с <code>rel="license"</code></p>

<p>Текст внутри <code>&lt;small&gt;</code> необязательно должен быть меньше, чем окружающий — если же вам нужен именно мелкий текст, то для этого лучше подойдет CSS. Используйте <code>&lt;small&gt;</code> только на строчном уровне. В конце концов, <code>&lt;small&gt;</code> не влияет на семантику <code>&lt;em&gt;</code> или <code>&lt;strong&gt;</code>.</p>

<h2>Элемент <code>&lt;hr&gt;</code></h2>

<blockquote>
	<p><code>&lt;hr&gt;</code> служит для смысловой разбивки на уровне блоков текста</p>
	<p><a href="http://dev.w3.org/html5/markup/hr.html">Спецификация W3C</a></p>
</blockquote>

<p>Пообщавшись с <a href="http://ian.hixie.ch/">Яном Хиксоном</a> (редактором HTML5) я понял, что до сих пор неправильно понимал <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/content-models.html#paragraph">модель поведения содержимого</a>. Я узнал, что <code>&lt;hr&gt;</code> на самом деле означает <q>конец одной секции и начало другой</q> — что семантически равносильно <code>&lt;/section&gt;&lt;section&gt;</code>. Но поскольку элементы вроде <code>&lt;section&gt;</code> и так указывают на это, получается, что <code>&lt;hr&gt;</code> больше подходит для смысловой разбивки, вроде смыслового разделения внутри блока текста или отделения одной сцены в романе от другой. В любом случае, вы можете использовать этот элемент везде, где вы используете элемент <code>&lt;p&gt;</code>. Из-за унылого вида в браузерах по умолчанию, <code>&lt;hr&gt;</code> не слишком распространён сегодня, однако это не мешает оформить его при помощи CSS в виде красивого вензеля.</p>

<p><img src="http://static.web-standards.ru/articles/small-hr-elements/hr-separator.png" alt="Оформление &lt;hr&gt; в виде вензеля" class="pic"></p>

<pre>
	<code>hr {</code>
	<code>    margin:3em 0;</code>
	<code>    height:24px;</code>
	<code>    border:0;</code>
	<code>    background:url(flourish.png) 50% 50% no-repeat;</code>
	<code>    }</code>
</pre>

<p class="note">Оформите <code>&lt;hr&gt;</code> красиво: уберите рамку, поля и добавьте фоновую картинку.</p>

<p>IE7 и младше оправдывают свою дурную репутацию, добавляя рамку вокруг изображения, несмотря на наши усилия, <a href="http://blog.neatlysliced.com/2008/03/hr-image-replacement/">но и это можно исправить</a>. Или же вы можете просто скрыть <code>&lt;hr&gt;</code> в стилях для IE7 и младше. Если переход между частями содержимого очевиден или разделение чисто визуальное, а не смысловое, то вместо <code>&lt;hr&gt;</code> лучше нарисовать рамку или фоновую картинку на другом элементе.</p>

<p><img src="http://static.web-standards.ru/articles/small-hr-elements/corkd.png" alt="Неподходящий случай для использования &lt;hr&gt; на Cork’d.com" class="pic"></p>

<p class="note">На <a href="http://content.corkd.com/">Cork’d</a> используеся декоративная фоновая картинка для заголовков. Но несмотря на обилие линеек, это совсем неподходящий случай для использования <code>&lt;hr&gt;</code>.</p>

<h2>В заключение</h2>

<p>В момент выхода HTML4, презентационные элементы <code>&lt;basefont&gt;</code>, <code>&lt;font&gt;</code>, <code>&lt;s&gt;</code>, <code>&lt;strike&gt;</code> и <code>&lt;u&gt;</code> уже были помечены как нежелательные для использования, в пользу применения CSS. HTML5 завершил этот процесс, избавившись от элементов <code>&lt;big&gt;</code> и <code>&lt;tt&gt;</code>.</p>

<p>Остальные презентационные элементы из HTML4 — долго игнорируемые <code>&lt;small&gt;</code> и <code>&lt;hr&gt;</code> (<a href="http://web-standards.ru/articles/i-b-em-strong-elements/">наряду с <code>&lt;i&gt;</code> и <code>&lt;b&gt;</code></a>) — были пересмотрены в HTML5 с учетом их полезных, медиа-независимых семантических свойств, которые имеют отношение к их типичному использованию. Будете ли <em>вы</em> использовать их? Выскажитесь в комментариях!</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://html5doctor.com/small-hr-element/">The small &amp; hr elements</a>» <a href="http://oli.jp/">Оли Стадхольма</a> (Oli Studholme), опубликованной на сайте <a href="http://html5doctor.com/">HTML5Doctor.com</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/small-hr-elements/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Нюансы CSS</title>
		<link>http://web-standards.ru/articles/css-nuances/</link>
		<comments>http://web-standards.ru/articles/css-nuances/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 10:52:17 +0000</pubDate>
		<dc:creator>Лев Солнцев</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[методика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/css-nuances/</guid>
		<description><![CDATA[<p>Многие используют CSS для оформления сайтов и веб-страниц, знают основные приёмы вёрстки, а если и нет, то быстро найдут решение в интернете, или им подскажут в тематических сообществах. Тем не менее многие широко используемые решения не оптимальны, и если ознакомиться со спецификациями чуть глубже, можно написать лучший код.</p>
<p>К примеру многие знают, что цвет в шестнадцатеричной нотации вида <code>#RRGGBB</code> можно писать сокращённо как <code>#RGB</code>, если каждый старший разряд совпадает с младшим, или что нуль можно писать без единиц измерения, таких как «px» или «em», так как нуль — в любой системе измерения нуль.</p>

<h2>Что считает браузер</h2>
<p>Также широко известно, что можно отцентрировать блок с шириной меньше родительского элемента при помощи <code>margin:0 auto</code>. Однако мало кто задумывается, что почти во всех случаях дело касается непозиционированных элементов, и в этом случае значение <code>margin-top:auto</code> или <code>margin-bottom:auto</code> устанавливается равным нулю, а значит данное правило можно сократить до простого <code>margin:auto</code>.</p>
<p>Правила <code>margin-left:auto</code> и <code>margin-right:auto</code> при ширине блока меньше ширины контейнера равномерно распределяют оставшееся место. Так, задав только <code>margin-left:auto</code>, можно выровнять элемент по правому краю.</p>
<p>В обычном потоке элементы идут сверху вниз, поэтому <code>margin-top:auto</code> устанавливается нулевым. Однако для абсолютно спозиционированных элементов действует то же распределение свободного места, и аналогичным образом можно сделать <a href="http://test.csswg.org/suites/css2.1/20110111/html4/absolute-non-replaced-height-003.htm">центрирование по вертикали</a> при заданных высоте и <code>top</code> с <code>bottom</code> (не работает в IE7).</p>

<h2>Сокращения и значения по умолчанию</h2>
<p>Не менее широко распространено использование спрайтов, например: <code>background:url(icons.png) 0 0 no-repeat</code>. Однако, <code>background-position:0 0</code> является значением по умолчанию, поэтому <code>0 0</code> в таком случае можно опустить.</p>
<p>Но если в <code>background-position</code> задана хоть одна координата: будь то <code>top</code>, <code>left</code> или <code>100%</code>, то вторая принимает значение 50%. Это может быть полезно для значков, выровненных посередине строки по вертикали — достаточно указать лишь положение слева или справа.</p>
<p>Не все знают, что опущенные в сокращённой записи правила принимают своё значение по умолчанию. Поэтому уточняющие правила надо писать после или делать сильнее общей сокращённой надписи, как <code>background-position</code> уточняет положение каждого спрайта после <code>background</code> в предыдущем примере.</p>
<p>При подобном написании:</p>

<pre>
	<code>h1 {</code>
	<code>    font:2em/1 Arial,sans-serif;</code>
	<code>}</code>
</pre>

<p>задаётся не только шрифт, его размер и интерлиньяж, но и сразу сбрасывается полужирное написание (<code>font-weight:normal</code>), а также другие свойства, такие как <code>font-style</code> (курсив) и <code>font-variant</code> (капитель). Некоторые авторы совершенно зря дописывают в <code>font</code> значение <code>normal</code>. Непонятно даже к какому правилу из перечисленных трёх оно могло бы относиться — порядок следования в сокращённых свойствах неважен, и неучитывание порядка могло приводить к ошибкам лишь в устаревших браузерах.</p>
<p>Другими недопонятыми, но тоже полезными сокращёнными записями являются отдельные правила рамок <code>border-width</code>, <code>border-style</code> и <code>border-color</code>. Например, благодаря им можно задать верхнюю и нижнюю одинаковые рамки не дублированием кода в <code>border-top</code> и в <code>border-bottom</code>, а подобным образом:</p>

<pre>
	<code>border:solid gray;</code>
	<code>border-width:3px 0;</code>
</pre>

<p>Кроме меньшего размера кода, такая запись полезна тем, что каждое значение написано только один раз, и поменять, скажем, <code>solid</code> на <code>double</code> не составляет труда.</p>
<p>Более того, если будет использоваться <code>border-image</code>, то здесь явно задано, что размер боковых рамок нулевой. В противном случае <code>border-image</code> приводит к неявному появлению рамок, что может дать неожиданный эффект в углах.</p>
<p>Есть возможность, что <code>border-radius</code> может быть включен в сокращённую запись <code>border</code> (предлагался вариант с косой чертой «/»), поэтому записывайте на всякий случай <code>border-radius</code> после <code>border</code>.</p>

<h2>Переусложенение</h2>
<p>Часто, чтобы избавиться от рамки на картинке внутри ссылки, пишут:</p>

<pre>
	<code>a img {</code>
	<code>    border:0;</code>
	<code>}</code>
</pre>

<p>Однако в таком случае бразуер будет на каждой картинке проверять, не находится ли она в ссылке. Если для простых страниц это кажется несущественным (вы и глазом моргнуть не успеете за те несколько миллисекунд, на которое задержится отображение страницы), то в какой-нибудь фотогалерее со сложной анимацией это может лишить вас нескольких кадров в секунду, прибавляя ощущения «тормознутости». Куда проще написать так:</p>

<pre>
	<code>img {</code>
	<code>    border:0;</code>
	<code>}</code>
</pre>

<p>Эффект будет тот же самый. Уточнение, что рамка появляется на ссылках <code>a</code> в данном случае совершенно излишне.</p>
<p>Из тех же соображений производительности, как правило, незачем писать имя тэга вместе с классом и уж тем более с идентификатором, который сам по себе уникален. В данном правиле могут быть только два исключения: уточнение для конкретного тэга (возможно в этом случае у вас очень общий класс), и обход недостатка IE7, где эффекты при наведении <code>:hover</code> тормозят, если в селекторе не указан тэг (то есть надо писать <code>a.class:hover { color:#FC0; }</code>).</p>

<h2>Наследование</h2>
<p>Ещё одна недооценённая многими возможность CSS: наследование стилей. Например, может не устраивать, что по умолчанию содержимое ячеек таблиц центрируется по вертикали, при этом используются следующие правила:</p>

<pre>
	<code>th {</code>
	<code>    vertical-align:bottom;</code>
	<code>}</code>
	<code>td {</code>
	<code>    vertical-align:top;</code>
	<code>}</code>
</pre>

<p>Вроде бы всё здорово, но, сделав так, вы лишаетесь простого способа переопределить выравнивание для целого ряда:</p>

<pre>
	<code>tr.images {</code>
	<code>    vertical-align:middle;</code>
	<code>}</code>
</pre>

<p>Этого можно избежать, воспользовавшись тем, что ячейки таблицы <code>th</code> и <code>td</code> наследуют правила от рядов <code>tr</code>, а те в свою очередь от блоков <code>thead</code>, <code>tfoot</code> и <code>tbody</code>.</p>

<pre>
	<code>thead {</code>
	<code>    vertical-align:bottom;</code>
	<code>}</code>
	<code>tbody,</code>
	<code>tfoot {</code>
	<code>    vertical-align:top;</code>
	<code>}</code>
</pre>

<p>Стоит отметить, что все браузеры, кроме IE8, наследуют еще и значение <code>text-align</code> для <code>th</code>, а сам IE8 понимет ключевое слово <code>inherit</code>, что также позволяет наследовать значение <code>text-align</code>.</p>

<h2>Заключение</h2>
<p>Знание основ спецификаций, понимание механизмов работы браузеров и выполняемых действий позволяет оптимизировать написание кода, упростить его, сделать лаконичней, а также упростить дальшейшую разработку и поддержку.</p>]]></description>
			<content:encoded><![CDATA[<p>Многие используют CSS для оформления сайтов и веб-страниц, знают основные приёмы вёрстки, а если и нет, то быстро найдут решение в интернете, или им подскажут в тематических сообществах. Тем не менее многие широко используемые решения не оптимальны, и если ознакомиться со спецификациями чуть глубже, можно написать лучший код.</p>
<p>К примеру многие знают, что цвет в шестнадцатеричной нотации вида <code>#RRGGBB</code> можно писать сокращённо как <code>#RGB</code>, если каждый старший разряд совпадает с младшим, или что нуль можно писать без единиц измерения, таких как «px» или «em», так как нуль — в любой системе измерения нуль.</p>

<h2>Что считает браузер</h2>
<p>Также широко известно, что можно отцентрировать блок с шириной меньше родительского элемента при помощи <code>margin:0 auto</code>. Однако мало кто задумывается, что почти во всех случаях дело касается непозиционированных элементов, и в этом случае значение <code>margin-top:auto</code> или <code>margin-bottom:auto</code> устанавливается равным нулю, а значит данное правило можно сократить до простого <code>margin:auto</code>.</p>
<p>Правила <code>margin-left:auto</code> и <code>margin-right:auto</code> при ширине блока меньше ширины контейнера равномерно распределяют оставшееся место. Так, задав только <code>margin-left:auto</code>, можно выровнять элемент по правому краю.</p>
<p>В обычном потоке элементы идут сверху вниз, поэтому <code>margin-top:auto</code> устанавливается нулевым. Однако для абсолютно спозиционированных элементов действует то же распределение свободного места, и аналогичным образом можно сделать <a href="http://test.csswg.org/suites/css2.1/20110111/html4/absolute-non-replaced-height-003.htm">центрирование по вертикали</a> при заданных высоте и <code>top</code> с <code>bottom</code> (не работает в IE7).</p>

<h2>Сокращения и значения по умолчанию</h2>
<p>Не менее широко распространено использование спрайтов, например: <code>background:url(icons.png) 0 0 no-repeat</code>. Однако, <code>background-position:0 0</code> является значением по умолчанию, поэтому <code>0 0</code> в таком случае можно опустить.</p>
<p>Но если в <code>background-position</code> задана хоть одна координата: будь то <code>top</code>, <code>left</code> или <code>100%</code>, то вторая принимает значение 50%. Это может быть полезно для значков, выровненных посередине строки по вертикали — достаточно указать лишь положение слева или справа.</p>
<p>Не все знают, что опущенные в сокращённой записи правила принимают своё значение по умолчанию. Поэтому уточняющие правила надо писать после или делать сильнее общей сокращённой надписи, как <code>background-position</code> уточняет положение каждого спрайта после <code>background</code> в предыдущем примере.</p>
<p>При подобном написании:</p>

<pre>
	<code>h1 {</code>
	<code>    font:2em/1 Arial,sans-serif;</code>
	<code>}</code>
</pre>

<p>задаётся не только шрифт, его размер и интерлиньяж, но и сразу сбрасывается полужирное написание (<code>font-weight:normal</code>), а также другие свойства, такие как <code>font-style</code> (курсив) и <code>font-variant</code> (капитель). Некоторые авторы совершенно зря дописывают в <code>font</code> значение <code>normal</code>. Непонятно даже к какому правилу из перечисленных трёх оно могло бы относиться — порядок следования в сокращённых свойствах неважен, и неучитывание порядка могло приводить к ошибкам лишь в устаревших браузерах.</p>
<p>Другими недопонятыми, но тоже полезными сокращёнными записями являются отдельные правила рамок <code>border-width</code>, <code>border-style</code> и <code>border-color</code>. Например, благодаря им можно задать верхнюю и нижнюю одинаковые рамки не дублированием кода в <code>border-top</code> и в <code>border-bottom</code>, а подобным образом:</p>

<pre>
	<code>border:solid gray;</code>
	<code>border-width:3px 0;</code>
</pre>

<p>Кроме меньшего размера кода, такая запись полезна тем, что каждое значение написано только один раз, и поменять, скажем, <code>solid</code> на <code>double</code> не составляет труда.</p>
<p>Более того, если будет использоваться <code>border-image</code>, то здесь явно задано, что размер боковых рамок нулевой. В противном случае <code>border-image</code> приводит к неявному появлению рамок, что может дать неожиданный эффект в углах.</p>
<p>Есть возможность, что <code>border-radius</code> может быть включен в сокращённую запись <code>border</code> (предлагался вариант с косой чертой «/»), поэтому записывайте на всякий случай <code>border-radius</code> после <code>border</code>.</p>

<h2>Переусложенение</h2>
<p>Часто, чтобы избавиться от рамки на картинке внутри ссылки, пишут:</p>

<pre>
	<code>a img {</code>
	<code>    border:0;</code>
	<code>}</code>
</pre>

<p>Однако в таком случае бразуер будет на каждой картинке проверять, не находится ли она в ссылке. Если для простых страниц это кажется несущественным (вы и глазом моргнуть не успеете за те несколько миллисекунд, на которое задержится отображение страницы), то в какой-нибудь фотогалерее со сложной анимацией это может лишить вас нескольких кадров в секунду, прибавляя ощущения «тормознутости». Куда проще написать так:</p>

<pre>
	<code>img {</code>
	<code>    border:0;</code>
	<code>}</code>
</pre>

<p>Эффект будет тот же самый. Уточнение, что рамка появляется на ссылках <code>a</code> в данном случае совершенно излишне.</p>
<p>Из тех же соображений производительности, как правило, незачем писать имя тэга вместе с классом и уж тем более с идентификатором, который сам по себе уникален. В данном правиле могут быть только два исключения: уточнение для конкретного тэга (возможно в этом случае у вас очень общий класс), и обход недостатка IE7, где эффекты при наведении <code>:hover</code> тормозят, если в селекторе не указан тэг (то есть надо писать <code>a.class:hover { color:#FC0; }</code>).</p>

<h2>Наследование</h2>
<p>Ещё одна недооценённая многими возможность CSS: наследование стилей. Например, может не устраивать, что по умолчанию содержимое ячеек таблиц центрируется по вертикали, при этом используются следующие правила:</p>

<pre>
	<code>th {</code>
	<code>    vertical-align:bottom;</code>
	<code>}</code>
	<code>td {</code>
	<code>    vertical-align:top;</code>
	<code>}</code>
</pre>

<p>Вроде бы всё здорово, но, сделав так, вы лишаетесь простого способа переопределить выравнивание для целого ряда:</p>

<pre>
	<code>tr.images {</code>
	<code>    vertical-align:middle;</code>
	<code>}</code>
</pre>

<p>Этого можно избежать, воспользовавшись тем, что ячейки таблицы <code>th</code> и <code>td</code> наследуют правила от рядов <code>tr</code>, а те в свою очередь от блоков <code>thead</code>, <code>tfoot</code> и <code>tbody</code>.</p>

<pre>
	<code>thead {</code>
	<code>    vertical-align:bottom;</code>
	<code>}</code>
	<code>tbody,</code>
	<code>tfoot {</code>
	<code>    vertical-align:top;</code>
	<code>}</code>
</pre>

<p>Стоит отметить, что все браузеры, кроме IE8, наследуют еще и значение <code>text-align</code> для <code>th</code>, а сам IE8 понимет ключевое слово <code>inherit</code>, что также позволяет наследовать значение <code>text-align</code>.</p>

<h2>Заключение</h2>
<p>Знание основ спецификаций, понимание механизмов работы браузеров и выполняемых действий позволяет оптимизировать написание кода, упростить его, сделать лаконичней, а также упростить дальшейшую разработку и поддержку.</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/css-nuances/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Преимущества многострочного CSS</title>
		<link>http://web-standards.ru/articles/multiline-css/</link>
		<comments>http://web-standards.ru/articles/multiline-css/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 09:00:26 +0000</pubDate>
		<dc:creator>Вячеслав Олиянчук</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[методика]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/multiline-css/</guid>
		<description><![CDATA[<p>Предлагаю вашему вниманию моё видение наиболее удобной методики форматирования CSS-кода. Я знаю, что вопрос этот достаточно холиварный, однако материалов, статей или другого рода информации по этому вопросу очень мало, поэтому я постараюсь аргументированно раскрыть причины существования как многострочного, так и однострочного форматирования, рассказать о том, к чему приводит применение каждого из них и проанализировать, помогает или мешает выбранный стиль в работе.</p>

<p>Для начала определимся в терминологии. В CSS-коде у нас есть: блок правил — селектор и список правил для него; каждое правило состоит из свойства и его значения.</p>

<p>Есть два варианта форматирования CSS-кода, иначе говоря, расположения правил: однострочный и многострочный, а также их комбинации. Однострочное форматирование, правила для селектора записаны в одну строку:</p>

<pre>
	<code>.example { position:absolute; top:10px; display:block; width:10px; height:10px; background:url(icon.png) no-repeat }</code>
</pre>

<p>Многострочное форматирование, каждая пара <code>свойство:значение</code> на новой строке:</p>

<pre>
	<code>.example {</code>
	<code>    position:absolute;</code>
	<code>    top:10px;</code>
	<code>    display:block;</code>
	<code>    width:10px;</code>
	<code>    height:10px;</code>
	<code>    background:url(icon.png) no-repeat;</code>
	<code>    }</code>
</pre>

<p>Однострочный способ хорош в «наборах», «батареях» селекторов с одинаковыми свойствами. Например, там, где одно свойство принимает разные значения:</p>

<pre>
	<code>.tag-cloud .xs    { font-size:0.5em }</code>
	<code>.tag-cloud .s     { font-size:0.75em }</code>
	<code>.tag-cloud .m     { font-size:1em }</code>
	<code>.tag-cloud .l     { font-size:1.25em }</code>
	<code>.tag-cloud .xl    { font-size:1.5em }</code>
	<code>.tag-cloud .xxl   { font-size:1.75em }</code>
</pre>

<p>Многострочный: перфекционистский, безопасный, наглядный. Давайте разберем по порядку все его преимущества.</p>

<h2>Анализ</h2>

<p>Работа с кодом — это операции написания, поиска и редактирования текста. Чтобы работать результативно, нужно преследовать две цели:</p>

<h3 id="target-1">Цель №1: минимизация шанса на ошибку</h3>

<p>Некоторые из ошибок бывают вполне безобидны (вроде дублирования одного и того же свойства или одновременного использования двух взаимоисключающих), а некоторые могут быть критичны. Например, ошибочное переопределение или опечатка, которая блокирует работу следующих свойств.</p>

<h3 id="target-2">Цель №2: скорость восприятия свойств</h3>

<p>Основной труд при написании CSS файла — это объявление значений определенных свойств. Значит, нужно иметь набор этих свойств наглядно и под рукой, в рамках одного селектора.</p>

<p>Разве вам нужно следить за огромным количеством строк одновременно? Посмотрите, например, как думает программист, пишущий новую функцию. Его внимание сосредоточено только на этой функции. Так и у верстальщика — работа идет одновременно только с одним селектором. Столбик — самая наглядная запись. Он является потомком примитивного <em>списка в столбик</em>. Вы же не будете отрицать, что вытянутые в строку элементы списка теряют в доступности?</p>

<p>Например, довольно трудно найти отдельный элемент этого списка:</p>

<pre>
	<code>Я полюбил { Машеньку:болтушку; Юшечку:тихоню; Лизоньку:умницу; Алиночку:скромницу }</code>
</pre>

<p>Гораздо проще найти нужный нам пункт в таком виде:</p>

<pre>
	<code>Я полюбил {</code>
	<code>    Машеньку:болтушку;</code>
	<code>    Юшечку:тихоню;</code>
	<code>    Лизоньку:умницу;</code>
	<code>    Алиночку:скромницу</code>
	<code>    }</code>
</pre>

<p>Не нужно думать, что HTML-верстка это нечто обособленное в плане написания кода. Обратите внимание на практики, которые используют программисты, пишущие на JavaScript, PHP или Perl. Пара <code>свойство:значение</code> в CSS — это объявление той же переменной, только с ограниченным вариантом значений.</p>

<p>Пример JavaScript-кода:</p>

<pre>
	<code>function example() {</code>
	<code>    var position = 'absolute', display = 'block', width = 10, height = 10, background = 'icon.png';</code>
	<code>    …</code>
	<code>}</code>
</pre>

<p>То же самое, но в традиционном для JavaScript стиле форматирования:</p>

<pre>
	<code>function example() {</code>
	<code>    var position = 'absolute',</code>
	<code>        display = 'block',</code>
	<code>        width = 10,</code>
	<code>        height = 10,</code>
	<code>        background = 'icon.png';</code>
	<code>    …</code>
	<code>}</code>
</pre>

<p>Теперь давайте вернёмся и еще раз перечитаем как <a href="#target-2">сформулирована цель №2</a>: ключевое слово <em>«свойства»</em>. Нам не так часто приходится править селектор или расположение блоков с селекторами, но очень часто приходится править набор правил, иметь ввиду значение свойств, следить, какие уже объявлены, а каких еще нет. Именно поэтому важно <strong>сконцентрировать</strong> свое внимание на наборе правил.</p>

<h2>Автоматизация</h2>

<p>Помимо привычного нам ручного копания в коде, можно использовать автоматические решения. Далее речь пойдет о тех приемах, которые каждый способен применять в IntelliJ IDEA. Возможно, ваш любимый редактор кода тоже способен на нечто подобное.</p>

<p>Среди автоматических способов решения проблем первым стоит упомянуть построчную валидацию CSS-свойств в рамках селектора. Пусть машина помогает вам находить опечатки и проблемные фрагменты кода:</p>

<img src="http://static.web-standards.ru/articles/multiline-css/validation.png" alt="" class="pic">

<p>При многострочном форматировании сложнее пропустить:</p>

<ul>
	<li>переопределение одного правила другим и уже объявленное правило;</li>
	<li>пропущенную <code>;</code> в последовательности правил;</li>
	<li>незаметные опечатки, вроде <code>height</code> и <code>heigth</code>;</li>
	<li>хаки.</li>
</ul>

<h3>Визуализация цветов</h3>

<p>У каждой строки с использованием цветового кода мой редактор визуализирует цвет. Это нагляднее. Привлекает внимание быстрее. Еще один способ быстро найти нужное.</p>

<img src="http://static.web-standards.ru/articles/multiline-css/colors.png" alt="" class="pic">

<h3>Порядок свойств, селекторов, решений</h3>

<p>Организация свойств и селекторов поможет вам значительно улучшить понимание и читабельность кода, ускорить доступ к тем или иным решениям. Вы можете работать самостоятельно или в команде, над одним файлом или над гигантским проектом. В любой ситуации порядок будет на вашей стороне.</p>

<p>Я рекомендую разбить ваш CSS на три части. Это может быть как в прямом смысле разделение по файлам, так и просто мысленное принятие этого правила. Первая часть — это сброс умолчаний, так называемый reset.css, вторая — правила для HTML-тегов, третья — объявления классов и уникальных идентификаторов. Любой из этих частей может и не быть, но так можно организовать порядок на верхнем уровне. В каждой из этих частей всё тоже можно организовать: теги сгруппировать по функциональному признаку, классы и идентификаторы по решениям.</p>

<p>После того, как сделано всё вышесказанное, возникает вопрос: как организовать свойства в рамках одного селектора — по алфавиту, по длине записи, по частоте использования? Эти методы не годятся потому, что организация, навязываемая ими, не отвечает нашим целям. Вот, например, всё отсортировано по алфавиту, и чтобы увидеть какой <code>z-index</code> у абсолютно позиционированного блока, нужно выискивать его вдалеке от <code>position:absolute</code>, а свойство <code>left</code> совершенно неочевидно будет соседствовать с <code>letter-spacing</code>.</p>

<p>Наиболее правильный метод — это функциональная группировка. Например: позиционирование, поведение блока, размеры, цвета и т.д. Один из наиболее продуманных вариантов сортировки есть <a href="http://code.google.com/p/zen-coding/wiki/ZenCSSPropertiesEn">в документации к проекту Zen Сoding</a>.</p>

<p>Случается, что вам приходится работать с неопрятным кодом, доставшимся вам от других разработчиков. В этом случае можно автоматически пересортировать CSS-свойства в нужном вам порядке утилитой <a href="http://csscomb.ru/">CSScomb</a>.</p>

<h3>Дополнительное окно</h3>

<p>Несколько окон для одного файла позволяют удобно работать с отдаленными участками кода. Можно подсмотреть решение, скопировать, сверить с чем-то. Опять-таки, я берегу внимание, избавляюсь от беготни по файлу вверх и вниз.</p>

<a href="http://static.web-standards.ru/articles/multiline-css/split.view.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/split.view.small.png" alt="" class="pic"></a>

<h3>Сравнение содержимого построчно</h3>

<p>Вы можете писать однострочный CSS, но вполне вероятно что вы вырастете до работы над большими проектами с множеством файлов и большим объемом CSS. Вам придётся работать с системой контроля версий, построением проекта и другими разработчиками в вашей команде. Обратите внимание на то, что разница между двумя файлами вычисляется именно построчно, и при однострочной записи вам будет труднее выявить различия, так как строка будет различаться сразу несколькими свойствами:</p>

<a href="http://static.web-standards.ru/articles/multiline-css/diff.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/diff.small.png" alt="" class="pic"></a>

<h3>Доступ по селектору через поиск</h3>

<p>Один из главных аргументов <em>однострочников</em> сводится к тому, что перед глазами сразу располагаются только нужные селекторы. Процесс поиска нужных селекторов можно банально и очень эффективно автоматизировать при помощи поиска по файлу или проекту. Пусть машина ищет, пока вы экономите своё драгоценное внимание. Никакого просматривания глазами и выискивания. Никакой прокрутки. Не напрягайте глаза больше, чем это реально нужно.</p>

<h3>Доступ к свойству конкретного селектора по номеру строки</h3>

<p>Номер строки можно найти так: проинспектировать нужный блок в верстке с помощью Firebug, Web Inspector или Dragonfly, затем найти нужный селектор, который срабатывает для данного блока и подсмотреть номер строки и имя файла. Далее дело техники и знания горячих клавиш вашего любимого редактора. Объем CSS-кода и его растянутость (излишняя, как считают некоторые) не имеет никакого значения в этом случае.</p>

<h3>Комментирование</h3>

<p>При построчной записи удобнее комментировать конкретное свойство. Например напомнить, что оно переопределено в файле ie6.css. Или указать, что эта ширина может меняться в зависимости от наличия другого класса.</p>

<a href="http://static.web-standards.ru/articles/multiline-css/comment.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/comment.small.png" alt="" class="pic"></a>

<p>Взгляните, как комментируют свой код программисты — люди высокой организации мышления. Сложно оставить комментарий-послание себе или другим специалистам, если у вас однострочный код. И не говорите, что это вам не нужно. Когда понадобится неожиданно — будет мучительно неудобно.</p>

<p>При должной сноровке и знании горячих клавиш вашего любимого редактора закомментировать одно свойство на одной строке — легко. Комментарий <code>/* … */</code> автоматически обхватит свойство в многострочной записи. В однострочной записи вам недоступна такая роскошь. <q>А я комментирую, ломая имя свойства иксиком или другим символом</q> — детский сад, и к тому же небезопасно для обработки браузером дальнейшего кода. Не стоит испытывать на прочность CSS-парсеры.</p>

<h3>А у меня CSS меньше и быстрее</h3>

<p>Теперь о мнениях из серии <q>я пишу код в одну строку потому, что так посетители не грузят пробелы или символы табуляции</q>.</p>

<p>Версия в разработке и версия в бою — разные вещи. Версия для разработки должна быть максимально заточена под нужды разработчика и способствовать минимизации шансов на ошибку или опечатку из-за невнимательности. Для боевой версии актуальны совсем другие вещи: количество запросов к серверу, объем кода, актуальность загрузки всего кода сразу либо по частям, обфускация.</p>

<h2>В итоге</h2>

<p>Рекомендую пересилить себя и в целях повышения продуктивности, как личной, так и вашего проекта в целом, задуматься: почему вы пишете именно так? Может дело в простой привычке? Если вы преследуете <a href="#target-1">цель №1</a> и <a href="#target-2">цель №2</a>, то настоятельно рекомендую переходить на многострочный стиль.</p>

<h3>Дополнительное чтение</h3>

<ul>
	<li><a href="http://vimeo.com/17498225">CSS-менеджмент. Три года спустя</a>, доклад Вадима Макеева;</li>
	<li><a href="http://www.artlebedev.ru/tools/technogrette/soft/eclipse-ant/">Eclipse: знакомство с Ant</a>, статья Сергея Чикуёнка;</li>
	<li><a href="http://csscomb.ru/">CSScomb.ru</a>, инструменты для сортировки CSS-свойств.</li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>Предлагаю вашему вниманию моё видение наиболее удобной методики форматирования CSS-кода. Я знаю, что вопрос этот достаточно холиварный, однако материалов, статей или другого рода информации по этому вопросу очень мало, поэтому я постараюсь аргументированно раскрыть причины существования как многострочного, так и однострочного форматирования, рассказать о том, к чему приводит применение каждого из них и проанализировать, помогает или мешает выбранный стиль в работе.</p>

<p>Для начала определимся в терминологии. В CSS-коде у нас есть: блок правил — селектор и список правил для него; каждое правило состоит из свойства и его значения.</p>

<p>Есть два варианта форматирования CSS-кода, иначе говоря, расположения правил: однострочный и многострочный, а также их комбинации. Однострочное форматирование, правила для селектора записаны в одну строку:</p>

<pre>
	<code>.example { position:absolute; top:10px; display:block; width:10px; height:10px; background:url(icon.png) no-repeat }</code>
</pre>

<p>Многострочное форматирование, каждая пара <code>свойство:значение</code> на новой строке:</p>

<pre>
	<code>.example {</code>
	<code>    position:absolute;</code>
	<code>    top:10px;</code>
	<code>    display:block;</code>
	<code>    width:10px;</code>
	<code>    height:10px;</code>
	<code>    background:url(icon.png) no-repeat;</code>
	<code>    }</code>
</pre>

<p>Однострочный способ хорош в «наборах», «батареях» селекторов с одинаковыми свойствами. Например, там, где одно свойство принимает разные значения:</p>

<pre>
	<code>.tag-cloud .xs    { font-size:0.5em }</code>
	<code>.tag-cloud .s     { font-size:0.75em }</code>
	<code>.tag-cloud .m     { font-size:1em }</code>
	<code>.tag-cloud .l     { font-size:1.25em }</code>
	<code>.tag-cloud .xl    { font-size:1.5em }</code>
	<code>.tag-cloud .xxl   { font-size:1.75em }</code>
</pre>

<p>Многострочный: перфекционистский, безопасный, наглядный. Давайте разберем по порядку все его преимущества.</p>

<h2>Анализ</h2>

<p>Работа с кодом — это операции написания, поиска и редактирования текста. Чтобы работать результативно, нужно преследовать две цели:</p>

<h3 id="target-1">Цель №1: минимизация шанса на ошибку</h3>

<p>Некоторые из ошибок бывают вполне безобидны (вроде дублирования одного и того же свойства или одновременного использования двух взаимоисключающих), а некоторые могут быть критичны. Например, ошибочное переопределение или опечатка, которая блокирует работу следующих свойств.</p>

<h3 id="target-2">Цель №2: скорость восприятия свойств</h3>

<p>Основной труд при написании CSS файла — это объявление значений определенных свойств. Значит, нужно иметь набор этих свойств наглядно и под рукой, в рамках одного селектора.</p>

<p>Разве вам нужно следить за огромным количеством строк одновременно? Посмотрите, например, как думает программист, пишущий новую функцию. Его внимание сосредоточено только на этой функции. Так и у верстальщика — работа идет одновременно только с одним селектором. Столбик — самая наглядная запись. Он является потомком примитивного <em>списка в столбик</em>. Вы же не будете отрицать, что вытянутые в строку элементы списка теряют в доступности?</p>

<p>Например, довольно трудно найти отдельный элемент этого списка:</p>

<pre>
	<code>Я полюбил { Машеньку:болтушку; Юшечку:тихоню; Лизоньку:умницу; Алиночку:скромницу }</code>
</pre>

<p>Гораздо проще найти нужный нам пункт в таком виде:</p>

<pre>
	<code>Я полюбил {</code>
	<code>    Машеньку:болтушку;</code>
	<code>    Юшечку:тихоню;</code>
	<code>    Лизоньку:умницу;</code>
	<code>    Алиночку:скромницу</code>
	<code>    }</code>
</pre>

<p>Не нужно думать, что HTML-верстка это нечто обособленное в плане написания кода. Обратите внимание на практики, которые используют программисты, пишущие на JavaScript, PHP или Perl. Пара <code>свойство:значение</code> в CSS — это объявление той же переменной, только с ограниченным вариантом значений.</p>

<p>Пример JavaScript-кода:</p>

<pre>
	<code>function example() {</code>
	<code>    var position = 'absolute', display = 'block', width = 10, height = 10, background = 'icon.png';</code>
	<code>    …</code>
	<code>}</code>
</pre>

<p>То же самое, но в традиционном для JavaScript стиле форматирования:</p>

<pre>
	<code>function example() {</code>
	<code>    var position = 'absolute',</code>
	<code>        display = 'block',</code>
	<code>        width = 10,</code>
	<code>        height = 10,</code>
	<code>        background = 'icon.png';</code>
	<code>    …</code>
	<code>}</code>
</pre>

<p>Теперь давайте вернёмся и еще раз перечитаем как <a href="#target-2">сформулирована цель №2</a>: ключевое слово <em>«свойства»</em>. Нам не так часто приходится править селектор или расположение блоков с селекторами, но очень часто приходится править набор правил, иметь ввиду значение свойств, следить, какие уже объявлены, а каких еще нет. Именно поэтому важно <strong>сконцентрировать</strong> свое внимание на наборе правил.</p>

<h2>Автоматизация</h2>

<p>Помимо привычного нам ручного копания в коде, можно использовать автоматические решения. Далее речь пойдет о тех приемах, которые каждый способен применять в IntelliJ IDEA. Возможно, ваш любимый редактор кода тоже способен на нечто подобное.</p>

<p>Среди автоматических способов решения проблем первым стоит упомянуть построчную валидацию CSS-свойств в рамках селектора. Пусть машина помогает вам находить опечатки и проблемные фрагменты кода:</p>

<img src="http://static.web-standards.ru/articles/multiline-css/validation.png" alt="" class="pic">

<p>При многострочном форматировании сложнее пропустить:</p>

<ul>
	<li>переопределение одного правила другим и уже объявленное правило;</li>
	<li>пропущенную <code>;</code> в последовательности правил;</li>
	<li>незаметные опечатки, вроде <code>height</code> и <code>heigth</code>;</li>
	<li>хаки.</li>
</ul>

<h3>Визуализация цветов</h3>

<p>У каждой строки с использованием цветового кода мой редактор визуализирует цвет. Это нагляднее. Привлекает внимание быстрее. Еще один способ быстро найти нужное.</p>

<img src="http://static.web-standards.ru/articles/multiline-css/colors.png" alt="" class="pic">

<h3>Порядок свойств, селекторов, решений</h3>

<p>Организация свойств и селекторов поможет вам значительно улучшить понимание и читабельность кода, ускорить доступ к тем или иным решениям. Вы можете работать самостоятельно или в команде, над одним файлом или над гигантским проектом. В любой ситуации порядок будет на вашей стороне.</p>

<p>Я рекомендую разбить ваш CSS на три части. Это может быть как в прямом смысле разделение по файлам, так и просто мысленное принятие этого правила. Первая часть — это сброс умолчаний, так называемый reset.css, вторая — правила для HTML-тегов, третья — объявления классов и уникальных идентификаторов. Любой из этих частей может и не быть, но так можно организовать порядок на верхнем уровне. В каждой из этих частей всё тоже можно организовать: теги сгруппировать по функциональному признаку, классы и идентификаторы по решениям.</p>

<p>После того, как сделано всё вышесказанное, возникает вопрос: как организовать свойства в рамках одного селектора — по алфавиту, по длине записи, по частоте использования? Эти методы не годятся потому, что организация, навязываемая ими, не отвечает нашим целям. Вот, например, всё отсортировано по алфавиту, и чтобы увидеть какой <code>z-index</code> у абсолютно позиционированного блока, нужно выискивать его вдалеке от <code>position:absolute</code>, а свойство <code>left</code> совершенно неочевидно будет соседствовать с <code>letter-spacing</code>.</p>

<p>Наиболее правильный метод — это функциональная группировка. Например: позиционирование, поведение блока, размеры, цвета и т.д. Один из наиболее продуманных вариантов сортировки есть <a href="http://code.google.com/p/zen-coding/wiki/ZenCSSPropertiesEn">в документации к проекту Zen Сoding</a>.</p>

<p>Случается, что вам приходится работать с неопрятным кодом, доставшимся вам от других разработчиков. В этом случае можно автоматически пересортировать CSS-свойства в нужном вам порядке утилитой <a href="http://csscomb.ru/">CSScomb</a>.</p>

<h3>Дополнительное окно</h3>

<p>Несколько окон для одного файла позволяют удобно работать с отдаленными участками кода. Можно подсмотреть решение, скопировать, сверить с чем-то. Опять-таки, я берегу внимание, избавляюсь от беготни по файлу вверх и вниз.</p>

<a href="http://static.web-standards.ru/articles/multiline-css/split.view.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/split.view.small.png" alt="" class="pic"></a>

<h3>Сравнение содержимого построчно</h3>

<p>Вы можете писать однострочный CSS, но вполне вероятно что вы вырастете до работы над большими проектами с множеством файлов и большим объемом CSS. Вам придётся работать с системой контроля версий, построением проекта и другими разработчиками в вашей команде. Обратите внимание на то, что разница между двумя файлами вычисляется именно построчно, и при однострочной записи вам будет труднее выявить различия, так как строка будет различаться сразу несколькими свойствами:</p>

<a href="http://static.web-standards.ru/articles/multiline-css/diff.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/diff.small.png" alt="" class="pic"></a>

<h3>Доступ по селектору через поиск</h3>

<p>Один из главных аргументов <em>однострочников</em> сводится к тому, что перед глазами сразу располагаются только нужные селекторы. Процесс поиска нужных селекторов можно банально и очень эффективно автоматизировать при помощи поиска по файлу или проекту. Пусть машина ищет, пока вы экономите своё драгоценное внимание. Никакого просматривания глазами и выискивания. Никакой прокрутки. Не напрягайте глаза больше, чем это реально нужно.</p>

<h3>Доступ к свойству конкретного селектора по номеру строки</h3>

<p>Номер строки можно найти так: проинспектировать нужный блок в верстке с помощью Firebug, Web Inspector или Dragonfly, затем найти нужный селектор, который срабатывает для данного блока и подсмотреть номер строки и имя файла. Далее дело техники и знания горячих клавиш вашего любимого редактора. Объем CSS-кода и его растянутость (излишняя, как считают некоторые) не имеет никакого значения в этом случае.</p>

<h3>Комментирование</h3>

<p>При построчной записи удобнее комментировать конкретное свойство. Например напомнить, что оно переопределено в файле ie6.css. Или указать, что эта ширина может меняться в зависимости от наличия другого класса.</p>

<a href="http://static.web-standards.ru/articles/multiline-css/comment.png" rel="darkbox"><img src="http://static.web-standards.ru/articles/multiline-css/comment.small.png" alt="" class="pic"></a>

<p>Взгляните, как комментируют свой код программисты — люди высокой организации мышления. Сложно оставить комментарий-послание себе или другим специалистам, если у вас однострочный код. И не говорите, что это вам не нужно. Когда понадобится неожиданно — будет мучительно неудобно.</p>

<p>При должной сноровке и знании горячих клавиш вашего любимого редактора закомментировать одно свойство на одной строке — легко. Комментарий <code>/* … */</code> автоматически обхватит свойство в многострочной записи. В однострочной записи вам недоступна такая роскошь. <q>А я комментирую, ломая имя свойства иксиком или другим символом</q> — детский сад, и к тому же небезопасно для обработки браузером дальнейшего кода. Не стоит испытывать на прочность CSS-парсеры.</p>

<h3>А у меня CSS меньше и быстрее</h3>

<p>Теперь о мнениях из серии <q>я пишу код в одну строку потому, что так посетители не грузят пробелы или символы табуляции</q>.</p>

<p>Версия в разработке и версия в бою — разные вещи. Версия для разработки должна быть максимально заточена под нужды разработчика и способствовать минимизации шансов на ошибку или опечатку из-за невнимательности. Для боевой версии актуальны совсем другие вещи: количество запросов к серверу, объем кода, актуальность загрузки всего кода сразу либо по частям, обфускация.</p>

<h2>В итоге</h2>

<p>Рекомендую пересилить себя и в целях повышения продуктивности, как личной, так и вашего проекта в целом, задуматься: почему вы пишете именно так? Может дело в простой привычке? Если вы преследуете <a href="#target-1">цель №1</a> и <a href="#target-2">цель №2</a>, то настоятельно рекомендую переходить на многострочный стиль.</p>

<h3>Дополнительное чтение</h3>

<ul>
	<li><a href="http://vimeo.com/17498225">CSS-менеджмент. Три года спустя</a>, доклад Вадима Макеева;</li>
	<li><a href="http://www.artlebedev.ru/tools/technogrette/soft/eclipse-ant/">Eclipse: знакомство с Ant</a>, статья Сергея Чикуёнка;</li>
	<li><a href="http://csscomb.ru/">CSScomb.ru</a>, инструменты для сортировки CSS-свойств.</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/multiline-css/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Какой расклад?</title>
		<link>http://web-standards.ru/articles/state-of-layout/</link>
		<comments>http://web-standards.ru/articles/state-of-layout/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 08:54:50 +0000</pubDate>
		<dc:creator>Вячеслав Олиянчук</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[раскладка]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/state-of-layout/</guid>
		<description><![CDATA[<p class="intro">Эта статья посвящается тем, кто задает правильные вопросы.</p>

<p>В этой статье я постарался рассмотреть все самые распространенные вопросы, сомнения и критику по поводу необходимости создания и внедрения новых механизмов раскладки. Cтатья дополняет и продолжает содержание моего выступления «<a href="http://web-standards.ru/events/wsd-spb-2010/#layout">CSS3: будущее механизмов раскладки</a>». Если вы его не смотрели, то рекомендую ознакомиться.</p>

<p>Итак, у нас есть три черновика модулей CSS3: <a href="http://www.w3.org/TR/css3-grid/">Grid Positioning Module</a>, <a href="http://www.w3.org/TR/css3-flexbox/">Flexible Box Layout</a>, <a href="http://www.w3.org/TR/css3-layout/">Template Layout</a>. Каждый ценен своей уникальной идеей. Эти идеи <em>специально спроектированы</em> для решения определенного рода задач по раскладкам. Задач, которые в настоящее время решают <em>не предназначенными</em> для этого методами. Отсюда сложности в разработке и поддержке, ограничения и даже побочные эффекты этих методов.</p>

<h2>Долететь до Луны, используя катапульту</h2>
<p>Эра CSS-вёрстки, как и эра бурного развития клиентских технологий, длится не так уж и долго. С большой натяжкой — каких-то полтора десятка лет. Сначала все сайты не имели никаких раскладок. Даже графика была редкостью. Затем в веб стали приходить бизнес, индустрия развлечений, СМИ… Требования к представлению информации несоизмеримо выросли.</p>

<p>Сегодня мы находимся в ситуации, когда CSS не отвечает требованиям гибких, технологичных и надежных раскладок. Именно поэтому создаются новые модули, посвященные созданию сеток, шаблонов, гибких блоков. Параллельно с этим разрабатываются такие модули, как <a href="http://www.w3.org/TR/css3-mediaqueries/">Media Queries</a>, <a href="http://www.w3.org/TR/css3-page/">Paged Media</a> и другие. Всё это способствует расширению возможностей представления информации в разных условиях и на разных устройствах.</p>

<h2>То, что нельзя прочитать в спецификации</h2>
<p>Теперь давайте рассмотрим несколько вопросов, возникающих при размышлении о раскладках.</p>

<dl>
	<dt>Чем не устраивает <code>float</code>?</dt>
	<dd>
		<p>Свойство <code>float</code> способно наделять блоки плавающим поведением. Можно поместить блок слева или справа в контексте других блоков. Недостаточная гибкость <code>float</code> заключается в невозможности поместить блок в контексте других блоков, не прижимая его к краям этого контекста. Такого поведения <a href="http://www.w3.org/TR/css3-grid/#grid-units">можно добиться</a>, используя модуль Grid.</p>
	</dd>
	<dt>Почему бы просто не реализовать <code>display:table</code> во всех браузерах и не забыть про эти многочисленные модули?</dt>
	<dd>
		<p>Я полностью поддерживаю стремление реализовать <code>display:table</code> во всех браузерах. Но это вовсе не означает, что <code>display:table</code> сможет дать нам гибкий и перспективный механизм создания раскладок. Как можно поменять местами две колонки, не меняя HTML-разметки? Или как, например, возможно поместить блок, который будет одновременно находиться в области этих двух колонок, и при этом их содержимое будет его обтекать? Свойство <code>display:table</code> (как и свойства <code>position</code> и <code>float</code>) проектировалось совсем не для создания раскладок.</p>
	</dd>
	<dt>Кто круче: Grid, Flexbox, Template?</dt>
	<dd>
		<p>Очень хороший вопрос: какой из этих трёх модулей лучше, и кто в итоге должен выиграть? На самом деле, сила этих модулей именно в комбинировании возможностей и в совместном их использовании. Эти модули не стоит воспринимать как конкурентов друг другу. Наоборот, в основе каждого лежит идея позволяющая реализовать уникальные вещи. Так, Grid предназначен для создания сетки и привязки к этой сетке; Flexbox реализует особый механизм поведения блоков; Template создает набор слотов и позволяет, управляя ими, строить раскладки.</p>
	</dd>
	<dt>Что за разговор, это же всё очень сырое и потому неинтересное!</dt>
	<dd>
		<p>Это действительно интересный момент. Сырое, согласен. Но почему никого не смущают и, напротив, очень даже интересуют сырые реализации <code>box-shadow</code> и <code>border-radius</code>, а также остальных модных оформительских CSS-свойств. Лично меня очень расстраивает эта возня около вещей, продиктованных модой. Сегодня уголки квадратные, завтра круглые… а послезавтра?</p>
		<p>Если серьезно, то на тенюшках, красивых градиентах, кнопках и декоративных вещах нельзя построить большой и серьезный сайт. Основа сайта — раскладка. Именно поэтому мне непонятно, почему жадная до зрелищ толпа разработчиков и дизайнеров давит на производителей браузеров и повышает приоритет и престиж того же <code>border-radius</code>, а потом с салютом и ночными гуляниями отмечает выпуск новой бета-версии браузера с поддержкой этого свойства.</p> 
		<p>Я считаю, что внедрение, например, модуля Grid или Template может принести гораздо больше пользы, сократить тысячи часов однообразного труда и сэкономить бесчисленное количество денег при разработке раскладок для проектов по всему миру. А это очевидное развитие всей отрасли.</p>
	</dd>
	<dt>Mozilla сказала своё слово, разработав и внедрив Flexbox. Чей ход теперь?</dt>
	<dd>
		<p>Справедливости ради нужно сказать, что Flexbox работает не только в Firefox, но и в Safari и в Chrome. А это уже три браузера из большой пятерки. Мой прогноз: в ближайший год IE или Opera введут поддержку этого модуля. Причем я больше склоняюсь в сторону IE. Предпосылки к этому есть — активное обсуждение в рассылке <a href="http://lists.w3.org/Archives/Public/www-style/">www-style</a>, где Рабочая группа CSS (<a href="http://www.w3.org/Style/CSS/members.php3">CSS Working Group</a>) и все желающие обсуждают технические вопросы.</p>
	</dd>
	<dt>Давайте сделаем тег <code>&lt;layout&gt;</code>?</dt>
	<dd>
		<p>Это совсем провальное намерение. Идеология открытого веба, к которому мы все так стремимся, гласит: отделяй данные от их представления. Таким образом, внедрять экстра-разметку или какие-либо заведомо стилизованные теги — тупиковый путь.</p>
		<p>И главное: <code>&lt;layout&gt;</code> — это путь в каменный век табличной вёрстки. Подобные методы не оправдали себя в создании гибких раскладок. Вот простой пример: нужно изменять внешний вид страницы и саму раскладку в зависимости от размеров окна браузера. С HTML-разметкой это невозможно. А сейчас для этого существует CSS-модуль <a href="http://www.w3.org/TR/css3-mediaqueries/">Media Queries</a>.</p>
	</dd>
	<dt>Какие преимущества мы получаем?</dt>
	<dd>
		<p>Создавать раскладку при помощи Grid, Flexbox и Template гораздо проще. Следовательно, не нужно оплачивать труд CSS-гуру или самому быть им. Это совсем не означает, что высококвалифицированному специалисту будет нечего делать. Наоборот, он найдет себе применение в решении более интересных задач вёрстки.</p>
		<p>Создавать раскладки можно гораздо быстрее, а значит — можно сократить сроки вёрстки.</p>
		<p>Раскладка на Grid, Flexbox и Template более функциональная и гибкая. Таким образом, внесение изменений будет обходиться дешевле, проще и быстрее.</p>
		<p>Так как раскладкой в CSS будут заведовать определенные специально предназначенные для этого свойства, легко можно будет наладить автоматическую генерацию раскладок. Возможно, именно тогда CSS-фреймворки обретут второе дыхание.</p>
	</dd>
</dl>

<h3>Главный вопрос</h3>
<p>Сейчас не нужно выдумывать ничего нового. Нужно сосредоточить свое внимание на этих спецификациях. Осознать, что уже проделана огромная работа по придумыванию и обсуждению этих идей. Также важно, что именно Рабочая группа CSS занимается этими вопросами. Эти идеи родились в их умах. В умах людей, которые сегодня имеют непосредственное отношение к разработке браузеров. На этом уровне вопросы не решаются мгновенно, но на динамику и приоритет новых механизмов раскладок можно повлиять. К профессиональному сообществу веб-разработчиков производители браузеров, их специалисты по связям с разработчиками, технические специалисты и руководство прислушиваются всегда. Так может, спросим все вместе: «Когда же?»</p>]]></description>
			<content:encoded><![CDATA[<p class="intro">Эта статья посвящается тем, кто задает правильные вопросы.</p>

<p>В этой статье я постарался рассмотреть все самые распространенные вопросы, сомнения и критику по поводу необходимости создания и внедрения новых механизмов раскладки. Cтатья дополняет и продолжает содержание моего выступления «<a href="http://web-standards.ru/events/wsd-spb-2010/#layout">CSS3: будущее механизмов раскладки</a>». Если вы его не смотрели, то рекомендую ознакомиться.</p>

<p>Итак, у нас есть три черновика модулей CSS3: <a href="http://www.w3.org/TR/css3-grid/">Grid Positioning Module</a>, <a href="http://www.w3.org/TR/css3-flexbox/">Flexible Box Layout</a>, <a href="http://www.w3.org/TR/css3-layout/">Template Layout</a>. Каждый ценен своей уникальной идеей. Эти идеи <em>специально спроектированы</em> для решения определенного рода задач по раскладкам. Задач, которые в настоящее время решают <em>не предназначенными</em> для этого методами. Отсюда сложности в разработке и поддержке, ограничения и даже побочные эффекты этих методов.</p>

<h2>Долететь до Луны, используя катапульту</h2>
<p>Эра CSS-вёрстки, как и эра бурного развития клиентских технологий, длится не так уж и долго. С большой натяжкой — каких-то полтора десятка лет. Сначала все сайты не имели никаких раскладок. Даже графика была редкостью. Затем в веб стали приходить бизнес, индустрия развлечений, СМИ… Требования к представлению информации несоизмеримо выросли.</p>

<p>Сегодня мы находимся в ситуации, когда CSS не отвечает требованиям гибких, технологичных и надежных раскладок. Именно поэтому создаются новые модули, посвященные созданию сеток, шаблонов, гибких блоков. Параллельно с этим разрабатываются такие модули, как <a href="http://www.w3.org/TR/css3-mediaqueries/">Media Queries</a>, <a href="http://www.w3.org/TR/css3-page/">Paged Media</a> и другие. Всё это способствует расширению возможностей представления информации в разных условиях и на разных устройствах.</p>

<h2>То, что нельзя прочитать в спецификации</h2>
<p>Теперь давайте рассмотрим несколько вопросов, возникающих при размышлении о раскладках.</p>

<dl>
	<dt>Чем не устраивает <code>float</code>?</dt>
	<dd>
		<p>Свойство <code>float</code> способно наделять блоки плавающим поведением. Можно поместить блок слева или справа в контексте других блоков. Недостаточная гибкость <code>float</code> заключается в невозможности поместить блок в контексте других блоков, не прижимая его к краям этого контекста. Такого поведения <a href="http://www.w3.org/TR/css3-grid/#grid-units">можно добиться</a>, используя модуль Grid.</p>
	</dd>
	<dt>Почему бы просто не реализовать <code>display:table</code> во всех браузерах и не забыть про эти многочисленные модули?</dt>
	<dd>
		<p>Я полностью поддерживаю стремление реализовать <code>display:table</code> во всех браузерах. Но это вовсе не означает, что <code>display:table</code> сможет дать нам гибкий и перспективный механизм создания раскладок. Как можно поменять местами две колонки, не меняя HTML-разметки? Или как, например, возможно поместить блок, который будет одновременно находиться в области этих двух колонок, и при этом их содержимое будет его обтекать? Свойство <code>display:table</code> (как и свойства <code>position</code> и <code>float</code>) проектировалось совсем не для создания раскладок.</p>
	</dd>
	<dt>Кто круче: Grid, Flexbox, Template?</dt>
	<dd>
		<p>Очень хороший вопрос: какой из этих трёх модулей лучше, и кто в итоге должен выиграть? На самом деле, сила этих модулей именно в комбинировании возможностей и в совместном их использовании. Эти модули не стоит воспринимать как конкурентов друг другу. Наоборот, в основе каждого лежит идея позволяющая реализовать уникальные вещи. Так, Grid предназначен для создания сетки и привязки к этой сетке; Flexbox реализует особый механизм поведения блоков; Template создает набор слотов и позволяет, управляя ими, строить раскладки.</p>
	</dd>
	<dt>Что за разговор, это же всё очень сырое и потому неинтересное!</dt>
	<dd>
		<p>Это действительно интересный момент. Сырое, согласен. Но почему никого не смущают и, напротив, очень даже интересуют сырые реализации <code>box-shadow</code> и <code>border-radius</code>, а также остальных модных оформительских CSS-свойств. Лично меня очень расстраивает эта возня около вещей, продиктованных модой. Сегодня уголки квадратные, завтра круглые… а послезавтра?</p>
		<p>Если серьезно, то на тенюшках, красивых градиентах, кнопках и декоративных вещах нельзя построить большой и серьезный сайт. Основа сайта — раскладка. Именно поэтому мне непонятно, почему жадная до зрелищ толпа разработчиков и дизайнеров давит на производителей браузеров и повышает приоритет и престиж того же <code>border-radius</code>, а потом с салютом и ночными гуляниями отмечает выпуск новой бета-версии браузера с поддержкой этого свойства.</p> 
		<p>Я считаю, что внедрение, например, модуля Grid или Template может принести гораздо больше пользы, сократить тысячи часов однообразного труда и сэкономить бесчисленное количество денег при разработке раскладок для проектов по всему миру. А это очевидное развитие всей отрасли.</p>
	</dd>
	<dt>Mozilla сказала своё слово, разработав и внедрив Flexbox. Чей ход теперь?</dt>
	<dd>
		<p>Справедливости ради нужно сказать, что Flexbox работает не только в Firefox, но и в Safari и в Chrome. А это уже три браузера из большой пятерки. Мой прогноз: в ближайший год IE или Opera введут поддержку этого модуля. Причем я больше склоняюсь в сторону IE. Предпосылки к этому есть — активное обсуждение в рассылке <a href="http://lists.w3.org/Archives/Public/www-style/">www-style</a>, где Рабочая группа CSS (<a href="http://www.w3.org/Style/CSS/members.php3">CSS Working Group</a>) и все желающие обсуждают технические вопросы.</p>
	</dd>
	<dt>Давайте сделаем тег <code>&lt;layout&gt;</code>?</dt>
	<dd>
		<p>Это совсем провальное намерение. Идеология открытого веба, к которому мы все так стремимся, гласит: отделяй данные от их представления. Таким образом, внедрять экстра-разметку или какие-либо заведомо стилизованные теги — тупиковый путь.</p>
		<p>И главное: <code>&lt;layout&gt;</code> — это путь в каменный век табличной вёрстки. Подобные методы не оправдали себя в создании гибких раскладок. Вот простой пример: нужно изменять внешний вид страницы и саму раскладку в зависимости от размеров окна браузера. С HTML-разметкой это невозможно. А сейчас для этого существует CSS-модуль <a href="http://www.w3.org/TR/css3-mediaqueries/">Media Queries</a>.</p>
	</dd>
	<dt>Какие преимущества мы получаем?</dt>
	<dd>
		<p>Создавать раскладку при помощи Grid, Flexbox и Template гораздо проще. Следовательно, не нужно оплачивать труд CSS-гуру или самому быть им. Это совсем не означает, что высококвалифицированному специалисту будет нечего делать. Наоборот, он найдет себе применение в решении более интересных задач вёрстки.</p>
		<p>Создавать раскладки можно гораздо быстрее, а значит — можно сократить сроки вёрстки.</p>
		<p>Раскладка на Grid, Flexbox и Template более функциональная и гибкая. Таким образом, внесение изменений будет обходиться дешевле, проще и быстрее.</p>
		<p>Так как раскладкой в CSS будут заведовать определенные специально предназначенные для этого свойства, легко можно будет наладить автоматическую генерацию раскладок. Возможно, именно тогда CSS-фреймворки обретут второе дыхание.</p>
	</dd>
</dl>

<h3>Главный вопрос</h3>
<p>Сейчас не нужно выдумывать ничего нового. Нужно сосредоточить свое внимание на этих спецификациях. Осознать, что уже проделана огромная работа по придумыванию и обсуждению этих идей. Также важно, что именно Рабочая группа CSS занимается этими вопросами. Эти идеи родились в их умах. В умах людей, которые сегодня имеют непосредственное отношение к разработке браузеров. На этом уровне вопросы не решаются мгновенно, но на динамику и приоритет новых механизмов раскладок можно повлиять. К профессиональному сообществу веб-разработчиков производители браузеров, их специалисты по связям с разработчиками, технические специалисты и руководство прислушиваются всегда. Так может, спросим все вместе: «Когда же?»</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/state-of-layout/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Префикс или постхак</title>
		<link>http://web-standards.ru/articles/prefix-or-posthack/</link>
		<comments>http://web-standards.ru/articles/prefix-or-posthack/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 22:31:59 +0000</pubDate>
		<dc:creator>Эрик Мейер</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[хаки]]></category>

		<guid isPermaLink="false">http://web-standards.ru/articles/prefix-or-posthack/</guid>
		<description><![CDATA[<p>В то время, как поддержка CSS в браузерах улучшается с каждым днём — включая впечатляющие успехи команды разработчиков IE9 — всё больше и больше авторов увлекаются CSS3. По этой причине им приходится сталкиваться с <em>браузерными префиксами</em> — свойствами вида <code>-*-</code>, вроде <code>-moz-border-radius</code>, <code>-webkit-animation</code> и так далее.</p>

<p>И конечно же, по поводу этих префиксов слышится ворчание. Звучат призывы совсем отказаться от них или объединить все специфичные браузерные префиксы в один вида <code>-beta-</code>. Главная причина всего этого шума — никто, на самом деле, не хочет писать одно и то же свойство четыре или пять раз подряд только для того, чтобы, скажем, скруглить уголки.</p>

<p>Даже если это ворчание и можно понять, оно всё равно несправедливо. На самом деле, мы должны благодарить производителей браузеров за использование префиксов и безусловно поощрять их развитие. Более того, я уверен, что префиксы должны стать основой процесса развития стандарта CSS. И я говорю это не от большой любви к повторению правил, а, напротив — от большого желания видеть последовательное развитие CSS. Я верю, что префиксы на самом деле могут ускорить развитие и совершенствование CSS.</p>

<h2>Вспоминая ужасы</h2>

<p>Для понимания того, почему браузерные префиксы в принципе существуют, очень поучительно будет вспомнить историю с <a href="http://www.w3.org/TR/CSS2/box.html">блочной моделью</a>, которая чуть не убила CSS на пороге второго тысячелетия. Противоречивые реализации блочной модели в браузерах привели тогда к серьёзному кризису. Для того, чтобы обезопасить себя от такой ситуации в будущем, мы должны придумать новый механизм на основе существующих возможностей языка и изобрести <em>принципиально новый</em> тип хаков.</p>

<p>Для наших самых маленьких читателей, пропустивших всё веселье, — история произошла следующая: среди первых браузеров, поддерживающих CSS, Netscape внедрил блочную модель, найденную в CSS-спецификации. Это означало, что свойства <code>width</code> и <code>height</code> соотносились с шириной и высотой границ содержимого блока. А Internet Explorer внедрил интуитивную блочную модель, в которой свойства <code>width</code> и <code>height</code> обозначали размеры по внешней границе блока.</p>

<p>Какая бы из реализаций ни казалась удачнее, факт оставался фактом — в тот момент на рынке существовало два браузера принципиально несовместимых друг с другом, и у каждого из них была большая пользовательская база. Дело было в конце 90-х, когда мы боролись как проклятые, чтобы вырваться из трясины предупреждений «этот сайт лучше всего отображается в…», и обычной была ситуация, когда одна и та же вёрстка отлично работала в одном браузере, но напрочь разваливалась в другом.</p>

<p>Суть проблемы состояла в том, что каждый из браузеров не мог изменить своего поведения до зеркального соответствия другому. Представим на секунду, что команда разработчиков IE решает изменить поддержку CSS для большего соответствия спецификации. Подобный поступок привёл бы к тому, что десятки или даже сотни тысяч сайтов, работавших в IE, не просто где-то там сломаются, а буквально развалятся на части в определённых версиях браузера. И пока всё сообщество веб-стандартистов будет рукоплескать этому поступку, весь остальной мир откажется от браузера по причине полной его бесполезности. И даже если Рабочая группа CSS (<a href="http://www.w3.org/Style/CSS/members.php3">CSS Working Group</a>) решит изменить спецификацию для соответствия поведению IE, то Netscape столкнётся ровно с теми же трудностями.</p>

<p>Таким образом и был придуман механизм переключения <code>&lt;DOCTYPE&gt;</code>. Вся эта история со «стандартным» (standards mode) и «хитрым» (quirks mode) режимами выросла как раз из этой ситуации. Механизм переключения <code>&lt;DOCTYPE&gt;</code> решал многие проблемы, но его появление спровоцировали именно сложности с блочной моделью. Вдумайтесь: из-за того, что два браузера вели себя по-разному, сегодняшние браузеры вынуждены поддерживать два основных режима обработки страниц и выбирать нужный на основании SGML-декларации, в которой <em>вообще ничего</em> не сказано про обработку страниц.</p>

<p>Более того, все CSS-хаки первой волны были посвящены именно этой проблеме. Название классического представителя хаков той поры говорит само за себя: «<a href="http://tantek.com/CSS/Examples/boxmodelhack.html">хак для блочной модели</a>» (The Box Model Hack). Фактически, сам хак был основан на ошибке в синтаксической обработке значения свойства <code>voice-family</code>, но почему-то никто ни разу не назвал его «voice-family-хак».</p>

<p>Самое смешное, что это был не единственный случай, в котором непоследовательность внедрения спецификации привела к проблемам. Спустя некоторое время после появления механизма переключения <code>&lt;DOCTYPE&gt;</code>, спасшего CSS, команда разработчиков IE внедрила некоторые CSS-свойства позиционирования. Одним из внедрённых свойств было <code>clip</code>. Наученные горьким опытом шумихи с блочной моделью, инженеры Microsoft с большим вниманием отнеслись к спецификации и сделали всё в точности так, как там было сказано.</p>

<p>Вскоре после публичного релиза браузера, Рабочая группа CSS серьёзно поменяла принцип работы свойства <code>clip</code>. Синтаксис выглядел точно так же, однако приводил совсем к другим результатам.</p>

<p>В очередной раз спецификация вошла в противоречие с публично доступным браузером — или, если хотите, наоборот. Окончательным решением стало возвращение к прежнему поведению и полный отказ от нового. Фактически, это свойство стало бесполезным для элементов с непредсказуемой высотой и шириной — т.е. для всех незамещаемых элементов в нормальном потоке, вроде элементов <code>&lt;div&gt;</code> и <code>&lt;p&gt;</code>. Подробнее о типах элементов (replaced, non-replaced) можно прочитать в <a href="http://www.w3.org/TR/CSS2/visudet.html">документации W3C</a>. Несмотря на то, что были предложены и другие варианты решения, они так и не были реализованы, и свойство <code>clip</code> утратило часть своей полезности.</p>

<h2>Представим себе другой исход</h2>

<p>Предположим, что вместо внедрения свойства <code>clip</code> разработчики IE внедрили бы свойство <code>-ms-clip</code>. В этом случае было бы не так сложно справиться с последующим изменением поведения в спецификации. Из-за того, что префикс обозначает для свойства статус «в разработке», в дальнейшем производителю браузера будет гораздо проще пересмотреть работу свойства. Таким образом, разработчики IE могли бы поменять поведение свойства <code>-ms-clip</code>, в следующем релизе и объяснить разработчикам, что они обновили экспериментальное свойство для соответствия спецификации.</p>

<p>И даже если бы они решили, что сделать это невозможно, вся опасность «неправильного» внедрения была бы изолирована в рамках префиксной версии свойства. Другие производители браузеров могли бы внедрить новую версию свойства <code>clip</code> (со своим префиксом) и это никак бы не повлияло на то, что сделали разработчики IE. Один производитель никак не смог бы навредить своими действиями спецификации и другим производителям.</p>

<p>В этом состоит польза префиксов: это способ показать, что свойство находится «в разработке» и не обязательно будет вести себя так же в будущих релизах; это решение для разработчиков, которым необходимо внести изменения в работу свойства; это защита от неудачной или преждевременной реализации, которая вполне может случиться при первом внедрении. Префиксы придают столь необходимую гибкость процессу развития CSS.</p>

<p>Мы конечно можем заявить: «Когда браузер неправ по отношению к спецификации, то он должен изменить реализацию, даже если это сломает вёрстку сайтов». Благодаря предупреждению о рабочем статусе свойства, которое подразумевают префиксы, сделать это становится гораздо проще. Без использования префиксов это крайне сложно или, зачастую, просто невозможно. Microsoft так и не изменила способ расчёта <code>width</code> и <code>height</code> для устаревших сайтов — вместо этого она использовала объявление <code>&lt;DOCTYPE&gt;</code> для включения другого поведения для новых (теоретически, более совместимых со стандартами) сайтов. Это был очень полезный и необходимый трюк, но один из тех, что срабатывают только один раз.</p>

<h2>И даже сейчас мы страдаем</h2>

<p>И если вы думаете, что все эти глупости стали частью истории, вот вам два примера несовместимости, существующие <em>прямо сейчас</em>:</p>

<p>Браузеры на движках Mozilla и Webkit обрабатывают размытие для свойства <code>box-shadow</code> по-разному, и ни одна из реализаций полностью не соответствует спецификации. И пока я пишу эти строки, длинные и жаркие дебаты кипят в рассылке www-style. По меньшей мере одной, а, возможно, и обеим реализациям размытия тени придётся измениться для достижения совместимости. То же самое справедливо и для реализаций Opera и Microsoft.</p>

<p>Браузеры на движках Mozilla и Webkit поддерживают градиенты, используя <strong>категорически</strong> разный синтаксис для достижения простых результатов. А теперь представьте ситуацию, в которой производители браузеров внедрили бы градиенты без префиксов. В ней мы имеем три варианта:</p>

<ol>
	<li>Выбрать, какой браузер получит градиенты, а какой нет;</li>
	<li>использовать CSS-хаки или фильтрацию браузеров для выдачи разных стилей разным браузерам;</li>
	<li>полностью отказаться от использования градиентов.</li>
</ol>

<p>И мы имеем здесь <em>целых три</em> варианта только потому, что градиенты, реализованные в этих браузерах, имеют очень разный синтаксис, что открывает дорогу для первого варианта. В случае, когда обе реализации имели бы схожий синтаксис значения, но различную реализацию — как в истории со свойством <code>clip</code> — у нас были бы только два последних варианта: хакать и фильтровать для выдачи разных стилей, либо просто отказаться от этой затеи.</p>

<p>Мы уже вдоволь находились по этим граблям за всю историю развития CSS. Нет смысла наступать на них ещё раз, если первая дюжина попыток закончилась плохо.</p>

<h2>Пре-фикс или пост-хак</h2>

<p>Но настолько ли хороши префиксы? В конце концов, было же сказано, что префиксы — это всего лишь новые CSS-хаки. Как сказал Аарон Густафсон в <a href="http://www.alistapart.com/articles/stop-forking-with-css3/">недавней статье</a>, это:</p>

<pre>
<code>-moz-border-radius: 10px 5px;</code>
<code>-webkit-border-top-left-radius: 10px;</code>
<code>-webkit-border-top-right-radius: 5px;</code>
<code>-webkit-border-bottom-right-radius: 10px;</code>
<code>-webkit-border-bottom-left-radius: 5px;</code>
<code> border-radius: 10px 5px;</code>
</pre>

<p>…слишком напоминает вот эту историю:</p>

<pre>
<code>padding: 10px;</code>
<code>width: 200px;</code>
<code>w\idth: 180px;</code>
<code>height: 200px;</code>
<code>heigh\t: 180px;</code>
</pre>

<p>С точки зрения чрезмерного повторения и раздражения — да, они более чем похожи. Но, с другой стороны, они принципиально различаются: префиксы дают нам контроль над судьбой наших хаков. В прошлом нам приходилось выискивать кучу ошибок парсера только для того, чтобы заставить противоречивые реализации работать одинаково, как только мы выясняли, что они работают противоречиво. Таким образом, мы реагировали на имеющуюся проблему. Использование префиксов — это упреждающий подход.</p>

<p>Более того, префиксы — это временный хак. Со временем, когда реализация свойств станет более совместимой, браузеры просто откажутся от префиксов. И тогда авторы смогут писать всего одну строку вместо шести с чем-то для свойства <code>border-radius</code>. Без префиксов мы будем вынуждены ждать очередных сомнительных реализаций и год от года поддерживать их при помощи хаков.</p>

<p>Поэтому создание единого префикса, вроде <code>-beta-</code> или <code>-w3c-</code> — это, по меньшей мере, полшага назад. Это, конечно, позволит производителям помечать свойства префиксом «в разработке» и делать в дальнейшем необходимые изменения, но, к сожалению, полностью закроет для авторов возможность исключать поддержку или просто отдавать различные значения каждому отдельному браузеру, в случае очередной сомнительной реализации. С точки зрения авторов, единый префикс ничем не лучше, чем полный отказ от них.</p>

<p>Иногда мне кажется, что так же история обстоит и с методами предварительной обработки кода для работы с префиксами — серверными (при помощи <a href="http://lesscss.org/">LESS</a>) или клиентскими (куча JS-фреймворков). Использование этих инструментов позволяет просто писать правило <code>border-radius</code> и поручать им разворачивание этой строки в список необходимых правил с префиксами. С одной стороны, это уменьшает количество необходимого кода и повышает его чистоту и понятность. С другой стороны, этот подход мало чем отличается от ситуации с единым префиксом или вообще без них — всего одна неудачная реализация, и ваша вёрстка развалится.</p>

<p>Преимущество этого способа состоит в том, что если что-то пойдёт не так, то любой автор сможет вернуться, отключить препроцессинг и написать все префиксы вручную. Или сами препроцессоры кода могут обновиться для решения проблемы. В любом случае, это некоторый перебор сложности для авторов, хотя и не такой большой.</p>

<p>Обратная сторона этого способа более философская, но не менее важная: пряча свойства с префиксами за обработчиком, авторы могут забыть о том, что используют экспериментальные свойства, которые могут измениться. Неосознанно они могут начать думать, что используют что-то устоявшееся и стабильное, хотя это может быть совсем не так.</p>

<h2>Делаем префиксы действительно важными</h2>

<p>Я настолько твёрдо уверен, что префиксы — это хорошая вещь, что готов перейти к следующему логическому заключению: префиксы должны занять центральное место в развитии стандартов. Они должны быть <em>обязательными</em> для только что реализованных свойств, и должны стать механизмом, декларирующим совместимость.</p>

<p>Вот что я имею в виду: предположим, что кто-то изобрёл новое свойство под названием <code>text-curl</code>. Тотчас же трое производителей реализуют его. Каждый из них будет <em>обязан</em> добавить префикс к своей реализации. Таким образом, получается следующая картина:</p>

<pre>
<code>h1 {</code>
<code>    -webkit-text-curl: minor;</code>
<code>    -moz-text-curl: minor;</code>
<code>    -o-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>Со временем производители совершенствуют свои реализации в ответ на сообщения об ошибках и уточнения от Рабочей группы CSS. В какой-то момент Рабочая группа решает, что две из трёх реализаций вполне совместимы со спецификацией. Тогда две эти реализации начинают поддерживать оригинальное свойство. Третья — нет.</p>

<p>В этот момент авторы могут решить упростить свои стили до следующих:</p>

<pre>
<code>h1 {</code>
<code>    -webkit-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>В отличие от ситуации с хаками, которые только разрастаются со временем, мы просто отбрасываем ненужное. В итоге, всё, что остаётся — это одна строчка с <code>text-curl</code>.</p>

<p>И что же происходит, когда дебютирует очередная реализация? В первом своём релизе она также использует префикс, вне зависимости от количества уже существующих удачных реализаций. Значит, нам придётся вернуться к нашему CSS и поменять его следующим образом:</p>

<pre>
<code>h1 {</code>
<code>    -ms-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>Как только Рабочая группа сочтёт реализацию свойства <code>-ms-text-curl</code> полной, префикс сможет быть отброшен в следующей версии IE. После чего CSS снова может быть уменьшен до единственной беспрефиксной строчки. И снова — количество хаков только уменьшается со временем.</p>

<p>Конечно, каждый из производителей продолжит поддерживать свойства с префиксами, так что даже если мы и не удалим эти правила, каждый из поддерживаемых браузеров распознает и использует свойство без префикса, если конечно оно будет следовать после правила с префиксом. Для любого браузера, который внедрил свойство с префиксом и не позаботился о том, чтобы привести его в беспрефиксное состояние, это свойство по-прежнему будет работать. Даже если CSS-код останется нетронутым, он всё равно продолжит функционировать.</p>

<p>Вернёмся к тому моменту, когда Рабочая группа называет две реализации полностью совместимыми и даёт им право избавиться от префиксов. Эта ситуация приводит к двум результатам. Во-первых, как я уже говорил, это говорит о том, что свойство имеет достаточный уровень совместимости, и это позволяет развивать процесс стандартизации дальше.</p>

<p>Но, с другой стороны, — что, вероятно, более важно, — это заставляет производителей и Рабочую группу сотрудничать в разработке тестов, необходимых для определения условий совместимости. В дальнейшем, эти тесты могут помочь остальным производителям достичь статуса совместимости гораздо раньше. Они могут выпустить версию с префиксом в одной публичной бете и отказаться от префикса буквально в следующем же бета-релизе.</p>

<p>Это полностью меняет существующий сейчас порядок вещей. Так уж пошло, что когда CSS-модуль достигает статуса возможной рекомендации (CR), производители начинают отказываться от префиксов для свойств из этого модуля. Но такая ситуация снова приводит к возможности появления некачественных реализаций и новых хаков для решения возникших проблем.</p>

<p>Как предлагалось выше, модулю должно быть позволено достигнуть статуса возможной рекомендации только в случае, когда все его свойства имеют, как минимум, две реализации без префиксов, работающие в реальных условиях. Любые подобные свойства, появившиеся после этого, должны иметь префикс, от которого они смогут избавиться, только доказав на практике полную совместимость с уже существующими реализациями без префикса. Вместо того чтобы внушать сомнения, свойства с отброшенными префиксами могут стать гарантами стабильности, вместе с уже давно известными свойствами.</p>

<h2>Заключение</h2>

<p>Если история развития веб-стандартов и научила нас чему-то, то скорее тому, что хаки будут необходимы всегда. Подставляя хаки при помощи префиксов и используя их в процессе стандартизации, мы действительно можем справиться с потенциальными проблемами и ускорить разработку CSS.</p>

<p>И когда в следующий раз вы начнёте ворчать по поводу указания одних и тех же правил четыре раза, по одному на каждый из браузеров, вспомните, что это временная проблема. Это немного напоминает вакцинацию — укол побаливает, это правда, но всё не настолько плохо по сравнению с болезнью, которую он предотвращает. И в нашем случае вы вакцинируетесь от многолетней возни с хаками, от фильтрации браузеров, и от других скверных вещей. Мы уже однажды пережили эту эпидемию. При должном использовании префиксы позволят надолго сдержать очередную вспышку этой напасти.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://www.alistapart.com/articles/prefix-or-posthack/">Prefix or Posthack</a>» <a href="http://meyerweb.com/">Эрика Мейера</a> (Eric Meyer), опубликованной на сайте <a href="http://www.alistapart.com/">A List Apart</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>В то время, как поддержка CSS в браузерах улучшается с каждым днём — включая впечатляющие успехи команды разработчиков IE9 — всё больше и больше авторов увлекаются CSS3. По этой причине им приходится сталкиваться с <em>браузерными префиксами</em> — свойствами вида <code>-*-</code>, вроде <code>-moz-border-radius</code>, <code>-webkit-animation</code> и так далее.</p>

<p>И конечно же, по поводу этих префиксов слышится ворчание. Звучат призывы совсем отказаться от них или объединить все специфичные браузерные префиксы в один вида <code>-beta-</code>. Главная причина всего этого шума — никто, на самом деле, не хочет писать одно и то же свойство четыре или пять раз подряд только для того, чтобы, скажем, скруглить уголки.</p>

<p>Даже если это ворчание и можно понять, оно всё равно несправедливо. На самом деле, мы должны благодарить производителей браузеров за использование префиксов и безусловно поощрять их развитие. Более того, я уверен, что префиксы должны стать основой процесса развития стандарта CSS. И я говорю это не от большой любви к повторению правил, а, напротив — от большого желания видеть последовательное развитие CSS. Я верю, что префиксы на самом деле могут ускорить развитие и совершенствование CSS.</p>

<h2>Вспоминая ужасы</h2>

<p>Для понимания того, почему браузерные префиксы в принципе существуют, очень поучительно будет вспомнить историю с <a href="http://www.w3.org/TR/CSS2/box.html">блочной моделью</a>, которая чуть не убила CSS на пороге второго тысячелетия. Противоречивые реализации блочной модели в браузерах привели тогда к серьёзному кризису. Для того, чтобы обезопасить себя от такой ситуации в будущем, мы должны придумать новый механизм на основе существующих возможностей языка и изобрести <em>принципиально новый</em> тип хаков.</p>

<p>Для наших самых маленьких читателей, пропустивших всё веселье, — история произошла следующая: среди первых браузеров, поддерживающих CSS, Netscape внедрил блочную модель, найденную в CSS-спецификации. Это означало, что свойства <code>width</code> и <code>height</code> соотносились с шириной и высотой границ содержимого блока. А Internet Explorer внедрил интуитивную блочную модель, в которой свойства <code>width</code> и <code>height</code> обозначали размеры по внешней границе блока.</p>

<p>Какая бы из реализаций ни казалась удачнее, факт оставался фактом — в тот момент на рынке существовало два браузера принципиально несовместимых друг с другом, и у каждого из них была большая пользовательская база. Дело было в конце 90-х, когда мы боролись как проклятые, чтобы вырваться из трясины предупреждений «этот сайт лучше всего отображается в…», и обычной была ситуация, когда одна и та же вёрстка отлично работала в одном браузере, но напрочь разваливалась в другом.</p>

<p>Суть проблемы состояла в том, что каждый из браузеров не мог изменить своего поведения до зеркального соответствия другому. Представим на секунду, что команда разработчиков IE решает изменить поддержку CSS для большего соответствия спецификации. Подобный поступок привёл бы к тому, что десятки или даже сотни тысяч сайтов, работавших в IE, не просто где-то там сломаются, а буквально развалятся на части в определённых версиях браузера. И пока всё сообщество веб-стандартистов будет рукоплескать этому поступку, весь остальной мир откажется от браузера по причине полной его бесполезности. И даже если Рабочая группа CSS (<a href="http://www.w3.org/Style/CSS/members.php3">CSS Working Group</a>) решит изменить спецификацию для соответствия поведению IE, то Netscape столкнётся ровно с теми же трудностями.</p>

<p>Таким образом и был придуман механизм переключения <code>&lt;DOCTYPE&gt;</code>. Вся эта история со «стандартным» (standards mode) и «хитрым» (quirks mode) режимами выросла как раз из этой ситуации. Механизм переключения <code>&lt;DOCTYPE&gt;</code> решал многие проблемы, но его появление спровоцировали именно сложности с блочной моделью. Вдумайтесь: из-за того, что два браузера вели себя по-разному, сегодняшние браузеры вынуждены поддерживать два основных режима обработки страниц и выбирать нужный на основании SGML-декларации, в которой <em>вообще ничего</em> не сказано про обработку страниц.</p>

<p>Более того, все CSS-хаки первой волны были посвящены именно этой проблеме. Название классического представителя хаков той поры говорит само за себя: «<a href="http://tantek.com/CSS/Examples/boxmodelhack.html">хак для блочной модели</a>» (The Box Model Hack). Фактически, сам хак был основан на ошибке в синтаксической обработке значения свойства <code>voice-family</code>, но почему-то никто ни разу не назвал его «voice-family-хак».</p>

<p>Самое смешное, что это был не единственный случай, в котором непоследовательность внедрения спецификации привела к проблемам. Спустя некоторое время после появления механизма переключения <code>&lt;DOCTYPE&gt;</code>, спасшего CSS, команда разработчиков IE внедрила некоторые CSS-свойства позиционирования. Одним из внедрённых свойств было <code>clip</code>. Наученные горьким опытом шумихи с блочной моделью, инженеры Microsoft с большим вниманием отнеслись к спецификации и сделали всё в точности так, как там было сказано.</p>

<p>Вскоре после публичного релиза браузера, Рабочая группа CSS серьёзно поменяла принцип работы свойства <code>clip</code>. Синтаксис выглядел точно так же, однако приводил совсем к другим результатам.</p>

<p>В очередной раз спецификация вошла в противоречие с публично доступным браузером — или, если хотите, наоборот. Окончательным решением стало возвращение к прежнему поведению и полный отказ от нового. Фактически, это свойство стало бесполезным для элементов с непредсказуемой высотой и шириной — т.е. для всех незамещаемых элементов в нормальном потоке, вроде элементов <code>&lt;div&gt;</code> и <code>&lt;p&gt;</code>. Подробнее о типах элементов (replaced, non-replaced) можно прочитать в <a href="http://www.w3.org/TR/CSS2/visudet.html">документации W3C</a>. Несмотря на то, что были предложены и другие варианты решения, они так и не были реализованы, и свойство <code>clip</code> утратило часть своей полезности.</p>

<h2>Представим себе другой исход</h2>

<p>Предположим, что вместо внедрения свойства <code>clip</code> разработчики IE внедрили бы свойство <code>-ms-clip</code>. В этом случае было бы не так сложно справиться с последующим изменением поведения в спецификации. Из-за того, что префикс обозначает для свойства статус «в разработке», в дальнейшем производителю браузера будет гораздо проще пересмотреть работу свойства. Таким образом, разработчики IE могли бы поменять поведение свойства <code>-ms-clip</code>, в следующем релизе и объяснить разработчикам, что они обновили экспериментальное свойство для соответствия спецификации.</p>

<p>И даже если бы они решили, что сделать это невозможно, вся опасность «неправильного» внедрения была бы изолирована в рамках префиксной версии свойства. Другие производители браузеров могли бы внедрить новую версию свойства <code>clip</code> (со своим префиксом) и это никак бы не повлияло на то, что сделали разработчики IE. Один производитель никак не смог бы навредить своими действиями спецификации и другим производителям.</p>

<p>В этом состоит польза префиксов: это способ показать, что свойство находится «в разработке» и не обязательно будет вести себя так же в будущих релизах; это решение для разработчиков, которым необходимо внести изменения в работу свойства; это защита от неудачной или преждевременной реализации, которая вполне может случиться при первом внедрении. Префиксы придают столь необходимую гибкость процессу развития CSS.</p>

<p>Мы конечно можем заявить: «Когда браузер неправ по отношению к спецификации, то он должен изменить реализацию, даже если это сломает вёрстку сайтов». Благодаря предупреждению о рабочем статусе свойства, которое подразумевают префиксы, сделать это становится гораздо проще. Без использования префиксов это крайне сложно или, зачастую, просто невозможно. Microsoft так и не изменила способ расчёта <code>width</code> и <code>height</code> для устаревших сайтов — вместо этого она использовала объявление <code>&lt;DOCTYPE&gt;</code> для включения другого поведения для новых (теоретически, более совместимых со стандартами) сайтов. Это был очень полезный и необходимый трюк, но один из тех, что срабатывают только один раз.</p>

<h2>И даже сейчас мы страдаем</h2>

<p>И если вы думаете, что все эти глупости стали частью истории, вот вам два примера несовместимости, существующие <em>прямо сейчас</em>:</p>

<p>Браузеры на движках Mozilla и Webkit обрабатывают размытие для свойства <code>box-shadow</code> по-разному, и ни одна из реализаций полностью не соответствует спецификации. И пока я пишу эти строки, длинные и жаркие дебаты кипят в рассылке www-style. По меньшей мере одной, а, возможно, и обеим реализациям размытия тени придётся измениться для достижения совместимости. То же самое справедливо и для реализаций Opera и Microsoft.</p>

<p>Браузеры на движках Mozilla и Webkit поддерживают градиенты, используя <strong>категорически</strong> разный синтаксис для достижения простых результатов. А теперь представьте ситуацию, в которой производители браузеров внедрили бы градиенты без префиксов. В ней мы имеем три варианта:</p>

<ol>
	<li>Выбрать, какой браузер получит градиенты, а какой нет;</li>
	<li>использовать CSS-хаки или фильтрацию браузеров для выдачи разных стилей разным браузерам;</li>
	<li>полностью отказаться от использования градиентов.</li>
</ol>

<p>И мы имеем здесь <em>целых три</em> варианта только потому, что градиенты, реализованные в этих браузерах, имеют очень разный синтаксис, что открывает дорогу для первого варианта. В случае, когда обе реализации имели бы схожий синтаксис значения, но различную реализацию — как в истории со свойством <code>clip</code> — у нас были бы только два последних варианта: хакать и фильтровать для выдачи разных стилей, либо просто отказаться от этой затеи.</p>

<p>Мы уже вдоволь находились по этим граблям за всю историю развития CSS. Нет смысла наступать на них ещё раз, если первая дюжина попыток закончилась плохо.</p>

<h2>Пре-фикс или пост-хак</h2>

<p>Но настолько ли хороши префиксы? В конце концов, было же сказано, что префиксы — это всего лишь новые CSS-хаки. Как сказал Аарон Густафсон в <a href="http://www.alistapart.com/articles/stop-forking-with-css3/">недавней статье</a>, это:</p>

<pre>
<code>-moz-border-radius: 10px 5px;</code>
<code>-webkit-border-top-left-radius: 10px;</code>
<code>-webkit-border-top-right-radius: 5px;</code>
<code>-webkit-border-bottom-right-radius: 10px;</code>
<code>-webkit-border-bottom-left-radius: 5px;</code>
<code> border-radius: 10px 5px;</code>
</pre>

<p>…слишком напоминает вот эту историю:</p>

<pre>
<code>padding: 10px;</code>
<code>width: 200px;</code>
<code>w\idth: 180px;</code>
<code>height: 200px;</code>
<code>heigh\t: 180px;</code>
</pre>

<p>С точки зрения чрезмерного повторения и раздражения — да, они более чем похожи. Но, с другой стороны, они принципиально различаются: префиксы дают нам контроль над судьбой наших хаков. В прошлом нам приходилось выискивать кучу ошибок парсера только для того, чтобы заставить противоречивые реализации работать одинаково, как только мы выясняли, что они работают противоречиво. Таким образом, мы реагировали на имеющуюся проблему. Использование префиксов — это упреждающий подход.</p>

<p>Более того, префиксы — это временный хак. Со временем, когда реализация свойств станет более совместимой, браузеры просто откажутся от префиксов. И тогда авторы смогут писать всего одну строку вместо шести с чем-то для свойства <code>border-radius</code>. Без префиксов мы будем вынуждены ждать очередных сомнительных реализаций и год от года поддерживать их при помощи хаков.</p>

<p>Поэтому создание единого префикса, вроде <code>-beta-</code> или <code>-w3c-</code> — это, по меньшей мере, полшага назад. Это, конечно, позволит производителям помечать свойства префиксом «в разработке» и делать в дальнейшем необходимые изменения, но, к сожалению, полностью закроет для авторов возможность исключать поддержку или просто отдавать различные значения каждому отдельному браузеру, в случае очередной сомнительной реализации. С точки зрения авторов, единый префикс ничем не лучше, чем полный отказ от них.</p>

<p>Иногда мне кажется, что так же история обстоит и с методами предварительной обработки кода для работы с префиксами — серверными (при помощи <a href="http://lesscss.org/">LESS</a>) или клиентскими (куча JS-фреймворков). Использование этих инструментов позволяет просто писать правило <code>border-radius</code> и поручать им разворачивание этой строки в список необходимых правил с префиксами. С одной стороны, это уменьшает количество необходимого кода и повышает его чистоту и понятность. С другой стороны, этот подход мало чем отличается от ситуации с единым префиксом или вообще без них — всего одна неудачная реализация, и ваша вёрстка развалится.</p>

<p>Преимущество этого способа состоит в том, что если что-то пойдёт не так, то любой автор сможет вернуться, отключить препроцессинг и написать все префиксы вручную. Или сами препроцессоры кода могут обновиться для решения проблемы. В любом случае, это некоторый перебор сложности для авторов, хотя и не такой большой.</p>

<p>Обратная сторона этого способа более философская, но не менее важная: пряча свойства с префиксами за обработчиком, авторы могут забыть о том, что используют экспериментальные свойства, которые могут измениться. Неосознанно они могут начать думать, что используют что-то устоявшееся и стабильное, хотя это может быть совсем не так.</p>

<h2>Делаем префиксы действительно важными</h2>

<p>Я настолько твёрдо уверен, что префиксы — это хорошая вещь, что готов перейти к следующему логическому заключению: префиксы должны занять центральное место в развитии стандартов. Они должны быть <em>обязательными</em> для только что реализованных свойств, и должны стать механизмом, декларирующим совместимость.</p>

<p>Вот что я имею в виду: предположим, что кто-то изобрёл новое свойство под названием <code>text-curl</code>. Тотчас же трое производителей реализуют его. Каждый из них будет <em>обязан</em> добавить префикс к своей реализации. Таким образом, получается следующая картина:</p>

<pre>
<code>h1 {</code>
<code>    -webkit-text-curl: minor;</code>
<code>    -moz-text-curl: minor;</code>
<code>    -o-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>Со временем производители совершенствуют свои реализации в ответ на сообщения об ошибках и уточнения от Рабочей группы CSS. В какой-то момент Рабочая группа решает, что две из трёх реализаций вполне совместимы со спецификацией. Тогда две эти реализации начинают поддерживать оригинальное свойство. Третья — нет.</p>

<p>В этот момент авторы могут решить упростить свои стили до следующих:</p>

<pre>
<code>h1 {</code>
<code>    -webkit-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>В отличие от ситуации с хаками, которые только разрастаются со временем, мы просто отбрасываем ненужное. В итоге, всё, что остаётся — это одна строчка с <code>text-curl</code>.</p>

<p>И что же происходит, когда дебютирует очередная реализация? В первом своём релизе она также использует префикс, вне зависимости от количества уже существующих удачных реализаций. Значит, нам придётся вернуться к нашему CSS и поменять его следующим образом:</p>

<pre>
<code>h1 {</code>
<code>    -ms-text-curl: minor;</code>
<code>    text-curl: minor;</code>
<code>}</code>
</pre>

<p>Как только Рабочая группа сочтёт реализацию свойства <code>-ms-text-curl</code> полной, префикс сможет быть отброшен в следующей версии IE. После чего CSS снова может быть уменьшен до единственной беспрефиксной строчки. И снова — количество хаков только уменьшается со временем.</p>

<p>Конечно, каждый из производителей продолжит поддерживать свойства с префиксами, так что даже если мы и не удалим эти правила, каждый из поддерживаемых браузеров распознает и использует свойство без префикса, если конечно оно будет следовать после правила с префиксом. Для любого браузера, который внедрил свойство с префиксом и не позаботился о том, чтобы привести его в беспрефиксное состояние, это свойство по-прежнему будет работать. Даже если CSS-код останется нетронутым, он всё равно продолжит функционировать.</p>

<p>Вернёмся к тому моменту, когда Рабочая группа называет две реализации полностью совместимыми и даёт им право избавиться от префиксов. Эта ситуация приводит к двум результатам. Во-первых, как я уже говорил, это говорит о том, что свойство имеет достаточный уровень совместимости, и это позволяет развивать процесс стандартизации дальше.</p>

<p>Но, с другой стороны, — что, вероятно, более важно, — это заставляет производителей и Рабочую группу сотрудничать в разработке тестов, необходимых для определения условий совместимости. В дальнейшем, эти тесты могут помочь остальным производителям достичь статуса совместимости гораздо раньше. Они могут выпустить версию с префиксом в одной публичной бете и отказаться от префикса буквально в следующем же бета-релизе.</p>

<p>Это полностью меняет существующий сейчас порядок вещей. Так уж пошло, что когда CSS-модуль достигает статуса возможной рекомендации (CR), производители начинают отказываться от префиксов для свойств из этого модуля. Но такая ситуация снова приводит к возможности появления некачественных реализаций и новых хаков для решения возникших проблем.</p>

<p>Как предлагалось выше, модулю должно быть позволено достигнуть статуса возможной рекомендации только в случае, когда все его свойства имеют, как минимум, две реализации без префиксов, работающие в реальных условиях. Любые подобные свойства, появившиеся после этого, должны иметь префикс, от которого они смогут избавиться, только доказав на практике полную совместимость с уже существующими реализациями без префикса. Вместо того чтобы внушать сомнения, свойства с отброшенными префиксами могут стать гарантами стабильности, вместе с уже давно известными свойствами.</p>

<h2>Заключение</h2>

<p>Если история развития веб-стандартов и научила нас чему-то, то скорее тому, что хаки будут необходимы всегда. Подставляя хаки при помощи префиксов и используя их в процессе стандартизации, мы действительно можем справиться с потенциальными проблемами и ускорить разработку CSS.</p>

<p>И когда в следующий раз вы начнёте ворчать по поводу указания одних и тех же правил четыре раза, по одному на каждый из браузеров, вспомните, что это временная проблема. Это немного напоминает вакцинацию — укол побаливает, это правда, но всё не настолько плохо по сравнению с болезнью, которую он предотвращает. И в нашем случае вы вакцинируетесь от многолетней возни с хаками, от фильтрации браузеров, и от других скверных вещей. Мы уже однажды пережили эту эпидемию. При должном использовании префиксы позволят надолго сдержать очередную вспышку этой напасти.</p>

<p class="note note-last">Перевод оригинальной статьи «<a href="http://www.alistapart.com/articles/prefix-or-posthack/">Prefix or Posthack</a>» <a href="http://meyerweb.com/">Эрика Мейера</a> (Eric Meyer), опубликованной на сайте <a href="http://www.alistapart.com/">A List Apart</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://web-standards.ru/articles/prefix-or-posthack/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

