Как избежать лишних загрузок для отзывчивых изображений
Элемент <picture>
— это одно из нововведений HTML5, разработанное
общественной группой W3C по адаптивным изображениям (Responsive Images
Community Group — RICG). Оно должно стать семантичным, основанным на
разметке, инструментом для реализации отзывчивых изображений без использования
JavaScript или сложных проверок на стороне сервера.
Элемент <picture>
поддерживает возможность добавления различных типов
резервного контента, но пока в практической реализации этой поддержки есть ряд
проблем. В этой статье мы разберемся как работает резервный контент, в каких
случаях он перестает работать и как это можно исправить.
Элемент <picture>
и резервное содержимое
Как и для <video>
и <audio>
, в <picture>
могут быть помещены элементы
<source>
для указания набора изображений, из которых браузер может выбрать
подходящее. Элементы <source>
могут при необходимости принимать атрибуты
type
и media
, которые предоставляют браузеру сведения о типе файла и
медиатипе подключенного контента соответственно. На основе информации,
помещенной в атрибуты, браузер должен загружать первый <source>
с типом файла,
который поддерживается, и с подходящим медиазапросом. Например:
<picture>
<source src="landscape.webp" type="image/webp" media="screen and (min-width: 20em) and (orientation: landscape)" />
<source src="landscape.jpg" type="image/jpg" media="screen and (min-width: 20em) and (orientation: landscape)" />
<source src="portrait.webp" type="image/webp" media="screen and (max-width: 20em) and (orientation: portrait)" />
<source src="portrait.jpg" type="image/jpg" media="screen and (max-width: 20em) and (orientation: portrait)" />
</picture>
Для подстраховки от ситуаций когда браузер не поддерживает <picture>
(или
<video>
, или <audio>
) или не может отобразить содержимое ни одного из
элементов <source>
, разработчик может добавить резервный контент. Этим
резервным контентом обычно является изображение или текстовое описание; если
резервный контент помещён в тег <img>
, обычно добавляют дополнительный
резервный контент в атрибуте alt
(или longdesc
).
<picture>
<source type="image/webp" src="image.webp" />
<source type="image/vnd.ms-photo" src="image.jxr" />
<img src="fallback.jpg" alt="модные штаны">
</picture>
Элемент <picture>
отличается от <video>
и <audio>
тем, что может принимать
атрибут srcset
. С его помощью разработчик может указать разные изображения для
устройств с разной пиксельной плотностью. При создании отзывчивого изображения
используя <picture>
и srcset
, мы получим что-то вроде следующего:
<picture>
<source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" type="image/jpeg" media="(min-width: 40em)" />
<source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" type="image/jpeg" />
<img src="fallback.jpg" alt="модные штаны" />
</picture>
Главная идея такого кода с использованием <picture>
состоит в том, чтобы
загружалось только одно изображение в зависимости от контекста пользователя:
- в браузер, поддерживающий
<picture>
, на устройствах с шириной не меньше 40 em должно быть загружено большое изображениеbig.jpg
. - В браузер, поддерживающий
<picture>
, на устройствах с шириной меньше 40 em должно быть загружено изображение средней величиныmed.jpg
. - В браузере, который не поддерживает
<picture>
, должно быть отображено резервное изображение.
Если браузер решает отобразить файлbig
илиmed
, он может выбрать изображение с подходящим разрешением исходя из содержимого атрибутаsrcset
. - В браузере на устройстве с низким разрешением (таком как iMac) должно отображаться изображение 1x.
- В браузере на устройстве с более высоким разрешением (таком как iPhone с дисплеем Retina) должно отображаться изображение 2x.
- В браузере на устройстве следующего поколения с еще большим разрешением должно отображаться изображение 3x.
Для пользователя преимущество в том, что скачивается только один файл с изображением, вне зависимости от возможностей браузера, параметров экрана устройства или его пиксельной плотности.
Элемент <picture>
также позволяет использовать не только изображения в
качестве резервного контента, что положительно влияет на доступность: можно
добавить <p>
, <span>
, <table>
или любой другой элемент в качестве
резервного контента на тот случай если ни одно из изображений не может быть
отображено или если пользователю нужно описание изображения. Такой резервный
контент более надёжен и логичен чем простое описание в атрибуте alt
.
Проблема резервного содержимого
На данный момент ни один браузер не поддерживает элемент <picture>
.
Разработчики, которые хотя использовать <picture>
, могут воспользовать
полифилом Picturefill, который предложил Скотт Джэлл (Scott Jehl).
Кроме того, Йоав Вайс (Yoav Weiss) разработал прототип базовой
реализации на основе Chromium, которая частично поддерживает <picture>
.
Его сборка Chromium не только доказывает что поддержка <picture>
возможна в
техническом плане, а также даёт нам возможность сравнить нашими ожиданиями с
реальными функциональностью и поведением этого элемента.
Тестируя код, похожий на приведенный в качестве примера выше, в своей сборке
Chromium, Йоав обнаружил проблему: хотя <picture>
поддерживается и один из
двух первых элементов <source>
загружается, резервное изображение <img>
также загружается. Скачиваются два изображения, хотя используется только
одно из них.
Это происходит потому что браузеры «забегают наперёд» когда грузится HTML и немедленно начинают загрузку изображений. Вот как Йоав это объясняет:
«Когда парсер обнаруживает тэг img, он создаёт узел HTMLImageElement и присваивает ему его атрибуты. Когда атрибуты добавлены, узел не обращает внимание на родительские элементы и после добавления атрибута
src
немедленно запускается скачивание изображений»
Такой поспешный парсинг очень удобен в большинстве случаев, так как браузер
может начать загрузку изображений даже до окончания загрузки разметки HTML. Но в
ситуациях когда элемент img
является дочерним элементом <picture>
(или
<video>
, или <audio>
), браузер не обращает внимание на родительский элемент:
он видит img
и начинает загрузку. Проблема также возникает если мы забудем о
родительском элементе и рассмотрим <img>
с атрибутами src
и srcset
: парсер
скачивает изображения src
до того как выберет подходящее для отображения из
srcset
.
<picture>
<source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" media="(min-width: 40em)" />
<source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" />
<img src="fallback.jpg" alt="модные штаны" />
<!-- резервное изображение fallback.jpg скачивается *всегда* -->
</picture>
<img src="fallback.jpg" srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" alt="модные штаны" />
<!-- резервное изображение fallback.jpg скачивается *всегда* -->
<video>
<source src="video.mp4" type="video/mp4" />
<source src="video.webm" type="video/webm" />
<source src="video.ogv" type="video/ogg" />
<img src="fallback.jpg" alt="модные штаны" />
<!-- резервное изображение fallback.jpg скачивается *всегда* -->
</video>
В каждом случае загрузятся все изображения, а не только то, которое будет отображено. Но какая разница? Разница есть для ваших пользователей, которые скачивают лишний контент и таким образом теряют время и деньги, особенно если у них лимитирован трафик и медленное соединение. Возможно и для вас есть разница если вы оплачиваете полосу пропускания.
Возможное решение
Для этой проблемы нужно найти краткосрочное и долгосрочное решение.
С точки зрения долгосрочной перспективы, мы должны убедиться что при реализации
<picture>
(а также <video>
и <audio>
) в браузерах этот глюк будет
устранён. Например, Робин Бэрджон (Robin Berjon) предложил сделать
содержимое <picture>
пассивным, как содержимое <template>
, и использовать
Shadow DOM (о нём можно почитать, например, в статье «Template, новый тэг HTML5:
стандартизация шаблонизации на стороне клиента»). Йоав предложил
использовать для <img>
атрибут, который прикажет браузеру подождать перед
загрузкой содержимого из src
.
Хотя технически изменение работы парсера возможно, это усложнит реализацию.
Изменения парсера могут повлиять на код и библиотеки JavaScript, построенные на
предположении что загрузка начинается как только к <img>
добавляется атрибут
src
. Эти долгосрочные изменения требуют сотрудничества разработчиков браузеров,
создателей библиотек JavaScript и веб-разработчиков.
В краткосрочной перспективе нам нужно найти работающее решение которое позволит
избежать лишней нагрузки на полосу пропускания по ходу экспериментов с
<picture>
и srcset
, а также при использовании <video>
и <audio>
с
<img>
в качестве резервного контента. В связи с тем что обновление
спецификаций и браузеров — длительный и сложный процесс, кратковременное решение
должно основываться на ныне существующих инструментах и поведении браузеров.
Так что же нам поможет найти кратковременное решение? Наши старые друзья
<object>
и <embed>
, которые могут быть использованы для добавления
изображений. Изображение, добавленное с помощью этих тэгов, будет должным
образом отображаться в ситуации когда нужно активировать резервный контент и не
будет загружаться пока такая ситуация не наступила.
Браузеры ведут себя по-разному в зависимости от того какой тэг используется:
<object>
, <embed>
или оба. Чтобы определить какое решение является лучшим, я
провел тестирование (используя немного измененную версию этого кода) в:
- браузере Android 528.5+/4.0/525.20.1 на Android 1.6 (используя виртуальную версию Sony Xperia X10 на BrowserStack).
- Браузер Android 533.1/4.0/533.1 на Android 2.3.3 (используя виртуальную версию Samsung Galaxy S II на BrowserStack).
- Браузер Android 534.30/4.0/534.30 на Android 4.2 (используя виртуальную версию LG Nexus 4 на BrowserStack).
- Chrome 25.0.1364.160 на OS X 10.8.2.
- Chromium 25.0.1336.0 (169465) (сборка RICG) на OS X 10.8.2.
- Firefox 19.0.2 на OS X 10.8.2.
- Internet Explorer 6.0.3790.1830 на Windows XP (используя BrowserStack).
- Internet Explorer 7.0.5730.13 на Windows XP (используя BrowserStack).
- Internet Explorer 8.0.6001.19222 на Windows 7 (используя BrowserStack).
- Internet Explorer 9.0.8112.16421 на Windows 7 (используя BrowserStack).
- Internet Explorer 10.0.9200.16384 (настольная версия) на Windows 8 (используя BrowserStack).
- Opera 12.14, сборка 1738 на OS X 10.8.2.
- Opera Mobile 9.80/2.11.355/12.10 на Android 2.3.7 (используя виртуальную версию Samsung Galaxy Tab 10.1 на эмуляторе Opera Mobile для Mac).
- Safari 6.0.2 (8536.26.17) на OS X 10.8.2.
- Safari (Mobile) 536.26/6.0/10B144/8536.25 на iOS 6.1 (10B144) (используя iPhone 4).
- Safari (Mobile) 536.26/6.0/10B144/8536.25 на iOS 6.1 (10B141) (используя iPad 2).
Я провёл пять тестов:
- для
<picture>
в качестве резервного контента используется<object>
. - Для
<picture>
в качестве резервного контента используется<embed>
. - Для
<picture>
в качестве резервного контента используется<object>
, и для него в свою очередь<embed>
. - Для
<picture>
в качестве резервного контента используется<object>
, и для него в свою очередь<img>
. - Для
<picture>
в качестве резервного контента используется<img>
.
Результаты оказались следующими:
Тест 1 | Тест 2 | Тест 3 | Тест 4 | Тест 5 | |
---|---|---|---|---|---|
Android 1.6 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Android 2.3 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Android 4.2 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Chrome 25 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Chromium 25 (RICG) | исходное изображение | исходное изображение | исходное изображение | исходное изображение | исходное изображение |
Firefox 19 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
IE 6 | изображение отсутствует | изображение отсутствует | изображение отсутствует | изображение отсутствует | резервное изображение |
IE 7 | изображение отсутствует | изображение отсутствует | изображение отсутствует | изображение отсутствует | резервное изображение |
IE 8 | резервное изображение | изображение отсутствует | резервное изображение | резервное изображение | резервное изображение |
IE 9 | резервное изображение | резервное изображение (обрезанное, с полосками прокрутки) | резервное изображение | резервное изображение | резервное изображение |
IE 10 | резервное изображение | резервное изображение (обрезанное, с полосками прокрутки) | резервное изображение | резервное изображение | резервное изображение |
Opera 12.1 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Opera Mobile 12.1 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Safari 6 | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Safari iOS 6 (iPad) | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Safari iOS 6 (iPhone) | резервное изображение | резервное изображение | резервное изображение | резервное изображение | резервное изображение |
Тест 1 | Тест 2 | Тест 3 | Тест 4 | Тест 5 | |
---|---|---|---|---|---|
Android 1.6 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Android 2.3 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Android 4.2 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Chrome 25 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Chromium 25 (RICG) | 1 GET | 1 GET | 1 GET | 2 GET | 2 GET |
Firefox 19 | 1 GET | 1 GET | 2 GET | 2 GET | 1 GET |
IE 6 | 1 GET | нет | 1 GET | 1 GET | 1 GET |
IE 7 | 1 GET | нет | 1 GET | 1 GET | 1 GET |
IE 8 | 1 GET | нет | 1 GET | 1 GET | 1 GET |
IE 9 | 1 HEAD, 1 GET | 1 GET | 1 HEAD, 1 GET | 1 HEAD, 2 GET | 1 GET |
IE 10 | 1 HEAD, 1 GET | 1 GET | 1 HEAD, 1 GET | 1 HEAD, 2 GET | 1 GET |
Opera 12.1 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Opera Mobile 12.1 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Safari 6 | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Safari iOS 6 (iPad) | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Safari iOS 6 (iPhone) | 1 GET | 1 GET | 1 GET | 2 GET | 1 GET |
Тест 1 | Тест 2 | Тест 3 | Тест 4 | Тест 5 | |
---|---|---|---|---|---|
Android 1.6 | есть | есть | есть | есть | есть |
Android 2.3 | есть | есть | есть | есть | есть |
Android 4.2 | есть | есть | есть | есть | есть |
Chrome 25 | нет | нет | нет | нет | есть |
Chromium 25 (RICG) | нет | нет | нет | нет | нет |
Firefox 19 | есть | есть | есть | есть | есть |
IE 6 | нет | нет | нет | нет | есть |
IE 7 | нет | нет | нет | нет | есть |
IE 8 | есть | нет | есть | есть | есть |
IE 9 | есть | есть | есть | есть | есть |
IE 10 | есть | есть | есть | есть | есть |
Opera 12.1 | есть | есть | есть | есть | есть |
Opera Mobile 12.1 | есть | нет | есть | есть | есть |
Safari 6 | нет | нет | нет | нет | есть |
Safari iOS 6 (iPad) | нет | нет | нет | нет | есть |
Safari iOS 6 (iPhone) | нет | нет | нет | нет | есть |
Обеспечиваем доступность контента
Хотя насчёт самого лучшего способа добавления резервного контента для
<picture>
мнения пока расходятся (также взгляните на это
обсуждение), мне захотелось проверить как программа VoiceOver от Apple
будет работать с разными элементами. В процессе этого эксперимента я проверил
как VoiceOver понимает атрибут alt
в разных контекстах и резервные элементы
<span>
. К сожалению у меня не было возможности провести проверку других
скринридеров и вспомогательных технологий, буду рад если вы поделитесь своим
опытом.
`alt` для `picture` | `alt` для `source` (`picture → source`) | `alt` для `object` (`picture → object`) | `alt` для `embed` (`picture → embed`) | `alt` для `embed` (`picture → object → embed`) | |
---|---|---|---|---|---|
Chrome 25 | нет | нет | да | да | нет |
Chromium 25 (RICG) | да | нет | нет | нет | нет |
Firefox 19 | нет | нет | да | да | нет |
Opera 12.1 | нет | нет | нет | нет | нет |
Safari 6 | нет | нет | да | да | нет |
Safari iOS 6 (iPad) | нет | нет | да | да | нет |
Safari iOS 6 (iPhone) | нет | нет | да | да | нет |
`alt` для `img` (`picture → object → img`) | `alt` для `img` (`picture → img`) | `span` (`picture → span`) | `span` (`picture → object → span`) | |
---|---|---|---|---|
Chrome 25 | нет | да | да | нет |
Chromium 25 (RICG) | нет | нет | нет | нет |
Firefox 19 | нет | да | да | нет |
Opera 12.1 | нет | нет | да | нет |
Safari 6 | нет | да | да | нет |
Safari iOS 6 (iPad) | нет | да | да | нет |
Safari iOS 6 (iPhone) | нет | да | да | нет |
Ошибкоустойчивый синтаксис
Опираясь на эти данные я пришёл к следующему ошибкоустойчивому решению:
<picture alt="модные штаны">
<!-- загружается в браузерах, которые поддерживают тэг picture и один из элементов source -->
<source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg" type="image/jpeg" media="(min-width: 40em)" />
<source srcset="med.jpg 1x, med-2x.jpg 2x, big-3x.jpg" type="image/jpeg" />
<!-- загружается в браузерах IE 8+, браузерах других производителей, которые не поддерживают picture, а также браузерах, которые поддерживают picture, но не могут принять ни один из элементов source -->
<![if gte IE 8]>
<object data="fallback.jpg" type="image/jpeg"></object>
<span class="fake-alt">модные штаны</span>
<![endif]>
<!-- загружается в IE 6 и 7 -->
<!--[if lt IE 8]>
<img src="fallback.jpg" alt="модные штаны" />
<![endif]-->
</picture>
.fake-alt {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
У нас есть элемент <picture>
, два элемента source
на выбор для браузеров,
поддерживающих <picture>
, резервный контент в <object>
и <span>
для
большинства браузеров (смотрите примечание сразу под этим абзацом) и отдельное
резервное изображение <img>
для IE 7 и старше. Пустой alt
не даёт
скринридерам озвучить информацию о настоящем изображении, <span>
спрятан с
помощью CSS (используемый класс идентичен .visuallyhidden
, который применяется
в HTML5 Boilerplate), но может быть прочитан скринридерами. В элементе
<embed>
нет необходимости.
( Примечание: Мы вынуждены использовать <span>
как бутафорный alt
чтобы
VoiceOver мог прочитать текст в браузере Opera. Хотя процент пользователей Opera
относительно небольшой и она находится в процессе перехода на движок WebKit, я
всё же считаю что её стоит принимать во внимание. Однако, если для вас не важна
поддержка этого конкретного браузера, вы можете избавиться от <span>
и вместо
него добавить alt
для <object>
(хотя это и не приветствуется спецификацией).
Это в случае если в <span>
и alt
помещён один и тот же контент. Если у вас
более сложный резервный элемент, например <table>
, вероятно предпочтительней
использовать и <span>
, и alt
с текстовым описанием)
Похожее решение должно работать и для <audio>
, хотя элементы <img>
довольно
редко используются для него в качестве резервного контента. При работе с
<video>
, проблема легко решается если резервное изображение совпадает с
превью-картинкой. Если они могут быть одинаковыми, надёжный синтаксис для
<video>
будет таким:
<video poster="fallback.jpg">
<!-- загружается в браузерах, которые поддерживают тэг video и один из элементов source -->
<source src="video.mp4" type="video/mp4" />
<source src="video.webm" type="video/webm" />
<source src="video.ogv" type="video/ogg" />
<!-- загружается в браузерах, которые не поддерживают video, и браузерах, которые поддерживают video, но не могут принять ни один из элементов source -->
<img src="fallback.jpg" alt="fancy pants" />
</video>
Однако если для вашего <video>
резервное изображение и превью-картинка должны
быть разными, возможно вам стоит использовать такой же код как приведён для
<picture>
выше.
Обратите внимание что <video>
и <audio>
не принимают атрибут alt
, даже
если вы его добавите, VoiceOver его проигнорирует. Если вас интересует
оптимизация доступности видео, вам будет интересно ознакомиться с работой
которая ведется для формата Web Video Text Tracks (WebVTT).
К сожалению, подробное тестирование работы элементов <video>
и <audio>
выходит за рамки этой статьи, если у вас есть интересная информация на эту тему,
делитесь ею в комментариях.
Насколько хорошим (или плохим) является это решение?
Давайте сначала рассмотрим его недостатки. Это решение является хаком. Его определённо нельзя рассматривать как настоящее, долгосрочное решение. Оно безумно объемное; никто будучи в здравом уме не захочет писать столько кода только чтобы просто добавить изображение на страницу.
Кроме того, с точки зрения семантики для добавления изображения нам следует
использовать элемент <img>
, а не <object>
. Именно для этого был придуман
<img>
.
Также есть несколько практических моментов:
-
Chrome и Safari не выводят соответствующее контекстное меню для изображений, значит пользователи не смогут открыть или сохранить их привычным способом.
-
IE 9 и 10 кроме запроса GET посылают дополнительный запрос HEAD
-
Решение с использованием
<span>
как фальшивогоalt
довольно нестабильно, хотя оно и сработало при моих тестах для VoiceOver, оно может вызвать проблемы с доступностью в других ситуациях.
Принимая всё это во внимание, такое решение можно считать неплохим в краткосрочной перспективе. Оно даёт нам следующие преимущества:
-
тесты подтверждают, что во всех браузерах, для которых они были проведены, изображение будет отображено (из элементов
<picture>
и<source>
если они поддерживаются или из резервного элемента в противном случае). -
Тесты подтверждают, что во всех браузерах, на которых они проводились, будет отправлен только один HTTP запрос GET (дополнительный запрос
HEAD
и ответ в IE очень маленькие). -
VoiceOver поддерживается (так же как и другие скринридеры, надеюсь)
Семантика этого решения хоть и не идеальна, но и не ужасна: спецификация
HTML5 говорит что элемент <object>
«может представлять внешний ресурс,
который, в зависимости от его типа, будет рассматриваться как изображение,
встроенный контекст просмотра или внешний ресурс, который должен быть обработан
с помощью плагина» (выделение в текст добавил я).
И хотя <span>
не так же хорош как настоящий атрибут alt, использование
визуально невидимого элемента в целях повышения доступности является довольно
распространённой практикой. Вспомните о ссылках «перейти к содержимому»,
спрятанных для глаза, но видимых для скринридеров.
Следующие шаги
Решение, которое я предложил, подчёркивает насколько плоха нынешняя ситуация. Это настоящая проблема и она заслуживает лучшего решения чем безобразие, предложенное мной.
Решить этот вопрос можно только посредством обсуждения и активного участия
разработчиков браузеров и веб-разработчиков. Поддержка со стороны создателей
браузеров крайне важна; ведь можно написать спецификацию для чего-бы то ни было,
но она останется только на бумаге пока не будет реализована в браузерах.
Поддержка со стороны веб-разработчиков также важна, они могут помочь
убедиться что то или иное решение достаточно хорошо продумано чтобы
использоваться на практике. Именно такой подход, основанный на всеобщем
соглашении, недавно был использован при добавлении элемента <main>
в
спецификацию; Стив Фолкнер (Steve Faulkner) описывает этот процесс в
замечательном интервью с доктором HTML5.
Если вы хотите помочь найти решение для этой проблемы, присоединяйтесь к её обсуждению:
- зарегистрируйтесь в RICG и подписывайтесь на канал #respimg IRC и рассылку public-respimg.
- Зайдите на страницу RICG на GitHub и участвуйте в обсуждении этой проблемы.
- Подпишитесь на рассылки W3C public-html и the WHATWG чтобы получать обновления и участвовать в обсуждении спецификаций.
- Помогите исправить ошибки в текущих реализациях спецификации в WebKit, Mozilla and Internet Explorer: проводите тестирования, предлагайте патчи, свои комментарии и решения для багов.
Следующим шагом навстречу долгосрочному решению должно стать достижения консенсуса между веб-разработчиками и создателями браузеров. Не упустите возможность в этом поучаствовать.
Хочу поблагодарить Йоава Вайса, Маркоса Касереса (Marcos Cáceres) и Мэта Маркуиса (Mat Marquis), членов RICG, за отзывы об этой статье.