вторник, 17 мая 2016 г.

Как еще можно строить разметку в HTML

Интересная статья о том, как еще можно строить разметку в HTML

http://css-live.ru/articles/osmyslennyj-css-opisyvajte-stilyami-svoyu-logiku.html

http://techmeat.net/aria-roles-v-html5-semanticheskaya-razmetka.html

http://accessibility.athena-ict.com/aria/examples/tabpanel2.shtml

Осмысленный CSS: описывайте стилями свою логику


Перевод статьи Meaningful CSS: Style Like You Mean It с сайта alistapart.com для css-live.ru. Автор — Тим Бакстер.
В наши дни огромный мир семантической разметки раскинулся у кончиков наших пальцев. HTML5 щедро одарил нас новыми элементами и атрибутами с семантическим значением, стандарт ARIA определил целую платформу для описания полнофункциональных интернет-приложений, а благодаря микрофоматам стандартизованных, детальных понятий еще прибавилось. Настал золотой век для полнокровной, осмысленной разметки.
И всё же слишком часто наша разметка напоминает клубок div-ов, а наш CSS — трясина классов, лишь отдаленно связанных с этими div-ами. Мы строим пирамиды вложенных div-ов и навешиваем на каждый divпачку классов — но при взгляде в CSS эти классы едва ли подскажут нам, что именно мы хотели описать. Даже когда разметка семантична и осмысленна, в итоге мы переопределяем ее CSS-классами, взятыми с потолка. У них нет внутреннего значения.
Много лет назад нас предупреждали насчет такого подхода:
На зараженном классянкой сайте буквально на каждом теге сыпью выступает его распухший, пузырящийся класс. Классянка — заразная болезнь разметки, застилающая смысл, без нужды утяжеляя каждую страницу.
Джефри Зельдман, «Разработка по веб-стандартам», 1-е изд.
Похожие доводы приводит и W3C:
CSS наделяет атрибут «class» такой мощью, что разработчики в принципе могут создавать собственный «язык документов», основанный на элементах почти без особого представления (например, DIV и SPAN в HTML), и указывать стилевую информацию через атрибут «class».Разработчикам следует избегать этой практики, посколько у структурных элементов языка документа, в отличие от классов, часто есть распознаваемые и одобренные значения.(выделено мной).
Так почему же всё-таки наш CSS так нещадно злоупотребляет классами, и зачем мы мусорим своими классами в разметке? Что мешает нашему CSS быть столь же семантичным, как разметка? Почему они обане могут стать семантичнее и осмысленнее, развиваясь в тандеме?

Совершенствуем объекты

Давным-давно, когда CSS только вышел из пеленок и наши сайты и системы становились всё больше и больше, мы изо всех сил пытались выработать какие-то разумные соглашения, чтобы совладать с без конца растущими CSS-файлами. Из этого бардака возник объектно-ориентированный CSS.
Системы для надежного создания сложных, многоразовых компонентов породили проблему прогрессирующей злокачественной классянки — настолько, что сегодня разметку слишком часто пишут ради CSS, а не наоборот. Даже пытаясь писать семантичную, доступную разметку, мы всё равно вынуждены лепить поверх нее еще какие-то свои значения, чтобы угодить стилям. И в разметке, и в CSS у нас отразилось то время, когда для описания объектов у нас были div-ы да классы, только и всего. В любой непонятной ситуации добавляй еще тех и других. Так было безопаснее, особенно для старых браузеров, так что мы ориентировались на самые безликие объекты, какие были.
Сегодня мы уже не связаны этим. Мы можем определять объекты куда совершеннее. Мы можем создавать семантичный, самодокументируемый и осмысленный CSS, который понимает, что он описывает, и не уступает лучшей современной разметке в выразительности и доступности. Мы можем определить всего слона, а не писать что-то вроде «.колонна» или «.шланг».

Проясняем пару моментов

Но прежде чем переходить к определению более совершенных объектов, давайте оглянемся и обсудим, что не так с нашими теперешними объектами, а поможет нам в этом карикатурист Гэри Ларсон.
У Ларсона в серии «Противоположная сторона» есть одна карикатура, на которой человек таскает за собой краску и подписывает всё, что видит. По его входной двери стекает свежая надпись «Дверь», на дереве красуется подпись «Дерево», а на боку у кота отчетливо выведено «Кот». Довольный результатом, человек говорит: «Это должно прояснить пару моментов».
Каждый из нас — этот персонаж Ларсона, радующийся подписям. Мы не задумываясь пишем <table class="table"> и <form class="form">. На одном лишь Github можно наткнуться на множество примеров <main class="main">. Но зачем? Элемент main может быть только один, так что уже ясно, как сослаться на него напрямую. Новым элементам HTML5 вот-вот пойдет второй десяток лет. Ничто не мешает нам вовсю использовать их. И мы уже не можем оправдываться тем, что их, мол, не поймут наши коллеги.
Зачем заново изобретать в классах те семантические значения, которые уже есть в спецификации? Зачем повторять их и делать из них кашу?
Конечный пользователь может и не заметить, если вы налепите на элемент form класс form, и вряд ли вообще об этом задумается — но вот вам придется. Вам нужно думать о раздутой разметке и о лишних миллисекундах ожидания для пользователя. Вам нужно думать о читаемости. И раз уж вам за это платят, то нужно подумать и о том, что вы всё-таки профессионал, а профессионалы не пишут лишнего хлама. Последними словами любителей верстки на таблицах тоже были «Какое мне дело».

Переходим к семантике

Первый шаг к семантическому, осмысленному CSS — писать семантическую, осмысленную разметку. Классы случайны, а HTML — нет. В HTML у каждого элемента есть четко определенное, общепринятое значение, у каждого его атрибута — тоже. Хорошая разметка по построению выразительна, семантична, осмысленна и сама говорит за себя.
А на тот случай, когда семантики HTML5 мало, у нас есть ARIA — стандарт, специально призванный закрывать дыры. От ARIA часто отмахиваются как от «доступности и только», но на самом деле — в полном соответствии с названием — он про «Доступные насыщенные интернет-приложения». А значит, расширенной семантики в нем выше крыши.
Например, если хотите определить шапку в верху страницы, можно создать собственный класс .page-header, который не несёт никакого реального смысла. Можно использовать элемент header, но поскольку их может быть несколько, это может не сработать. Но в спецификации ARIA уже есть [role=banner], который как раз четко говорит: «Это шапка в верху страницы».
Когда уже есть <header role="banner">, добавлять еще какой-то класс попросту излишне, это мусор. Мы и так точно знаем, о чем говорим в CSS, никакой неоднозначности.
И это относится не только к таким вот крупным элементам разметки основных областей страницы. ARIA умеет семантически обозначать и маленькие, атомарные элементы вроде предупреждений.
Внимание: не прописывайте ARIA-ролей для элементов, у которых уже есть та же самая семантика. Например, не пишите <button role="button">, поскольку эта семантика уже заложена в самом элементе. Вместо этого используйте [role=button] в элементе, который должен выглядеть и вести себя, как кнопка, и оформляйте соответственно:
button,
[role=button] {
    … }
Всё, что семантически должно соответствовать кнопке, заодно получит и те же стили. Благодаря семантической разметке, в CSS элементы у нас оказываются объединены по их предназначению, а не сгруппированы наобум. Благодаря семантической разметке компоненты остаются многоразовыми. Хорошая разметка не меняется от проекта к проекту.
Ладно, но почему?
А вот почему:
  • Если вы уже писали семантичную, доступную разметку, то вы здорово сокращаете размер кода, а разметка остается чистой, экономной и легковесной. Ее будет легче читать людям и — в большинстве случаев — быстрее загружать и парсить. Вы убираете весь свой мусор и браузеру достаются лишь знакомые элементы. У каждого элемента своя определенная задача и свой смысл.
  • Если же до сих пор вы бодались с мешаниной div-ов и class-ов, то вы изрядно выиграете в доступности, потому что теперь вам служат роли и разметка, полезная для вспомогательных технологий. Кроме того, вы нарабатываете стандартные паттерны разметки, упрощая их повторение и приводя его к единообразию.
  • Вы всячески поощряете последовательный визуальный язык многоразовых элементов. Последовательный визуальный язык — ключ к тому, что вашим продуктом будет достаточно удобно пользоваться, и вы обрадуете дизайнеров, поскольку избегаете тех пугающих моментов, где элементы выглядят почти полностью одинаковыми, но не до конца. Напротив, если что-то выглядит и крякает как утка, вы гарантируете, что это действительно утка, а не кролик.утка.
  • Не приходится переключаться между контекстами CSS и HTML, поскольку каждый из них чётко описывает, что он делает в соответствии со стандартами языка.
  • Вы получите более последовательные паттерны разметки, поскольку делать правильно проще и нагляднее, а неправильно — труднее.
  • Вам не потребуется долго обдумывать названия. Просто следуйте спецификации.
  • Вы сможете отказаться от сегодняшних CSS-фреймворков.
А вот еще сценарий поинтереснее. Вот так (или еще хуже) может выглядеть типичная разметка формы:
<form class="form" method="POST" action=".">
        <div class="form-group">
                <label for="id-name-field">Ваше имя</label>
                <input type="text" class="form-control text-input" name="name-field" id="id-name-field" />
        </div>
        <div class="form-group">
                <input type="submit" class="btn btn-primary" value="Enter" />
        </div>      </form>
И потом в CSS для всех этих классов были бы прописаны стили. В итоге у нас пачка классов только для того, чтобы показать, что это форма и что в ней пара полей. А потом добавляем еще два класса, чтобы сказать, что кнопка, отправляющая форму, это кнопка, и что она отвечает за главное действие, которое можно сделать с этой формой.
Распространённая и оптимальная разметка формы
Как у вас сейчасКак могло бы бытьПочему
.formformБольшинство ваших форм будут — по крайней мере, в идеале — следовать последовательным паттернам разработки. Оставьте дополнительные идентификаторы для тех форм, у которых их нет. Доверяйте вашим паттернам разработки.
.form-groupform > p илиfieldset > pW3C рекомендует оборачивать элементы формы в теги абзаца. Это предсказуемый, рекомендуемый паттерн для оборачивания элементов формы.
.form-control или.text-input[type=text]Вы уже знаете, что это поле для текста.
.btn and.btn-primary или.text-input[type=submit]Отправка формы является по сути основным действием.
Некоторые распространенные паттерны разметки форм и их более оптимальная замена
Исходя из этого, вот новая, улучшенная разметка.
<form method="POST" action=".">
        <p>
                <label for="id-name-field">What’s Your Name</label>
                <input type="text" name="name-field" id="id-name-field" />
        </p>
        <p>
                <button type="submit">Enter</button>
        </p>
</form>
Функциональность та же самая.
Или возьмём, к примеру, этот CSS. Вы наверняка разберетесь, что он описывает и что в нем происходит.
[role=tab] {
        display: inline-block;
}
[role=tab][aria-selected=true] {
        background: tomato;
}
[role=tabpanel] {
        display: none;
}
[role=tabpanel][aria-expanded=true] {
        display: block;
}
Заметьте, что здесь можно было бы использовать и [aria-hidden], который семантичнее, чем служебный класс .hide, но aria-expanded подходит лучше. Но вообще панель вкладок может обойтись без них обоих.
Бывает, что в спецификации не находится подходящего элемента или атрибута. Именно для таких случаев разработаны микроформаты и микроданные, так что часто они могут выручить. Опять же, разметка у вас остается стандартизованной и семантической, и CSS ведет себя соответственно.
На первый взгляд может показаться, что это не подходит для тех самых случаев, ради которых создавались системы наименования CSS: на крупных проектах, в больших командах. Это вовсе не факт. Паттерны наименования CSS-классов загоняют разметку в очень жесткие рамки. Другими словами, итоговый HTML вынужден подчиняться CSS-оформлению. Существенное различие в том, что с техникой осмысленного CSS стили отражают разметку, а не наобоорот. Размер проекта здесь вообще ни при чем. При каждом варианте придется соблюдать какие-то правила.
Нам могут возразить, что слишком сложно гарантировать понимание правильных паттернов разметки у всей команды. С другой стороны, если любой веб-разработчик и обязан что-то знать как следует, так это HTML, а не какие-то хитрые правила именования классов. По крайней мере, команда будет следовать ясным, определенным, хорошо описанным в самой спецификации и воспроизводимым правилам. Хорошие разметка и CSS укрепляют друг друга.
Не писать хорошие разметку и CSS, потому что некоторые члены команды не могут понять базовые HTML-структуры и семантику — отговорка. Наша сфера может — и должна — рассчитывать на лучшее. Иначе мы бы по-прежнему строили сайты на таблицах, поскольку CSS-верстка якобы слишком сложна для новичков. Это постыдный аргумент.
Вероятно, самая трудная часть осмысленного CSS — понимание, когда классы всё-таки нужны и полезны. Цель в том, чтобы использовать их по назначению: для произвольной группировки элементов. Вот случаи, где вы хотели бы создать пользовательские классы чаще всего:
  • Когда нет подходящих элементов, атрибутов или стандартных структур данных. Иногда, вы и правда могли бы использовать объекты, для которых не нашлось места в спецификации HTML, в ARIA или в микроформатах. Такое не часто, но бывает. Просто убедитесь, что ваш .единорог — это не лошадь с приклеенным к ней рогом.
  • Когда нужно произвольно сгруппировать различную разметку в едином визуальном стиле. В этом примере хочется, чтобы разные по смыслу объекты выглядели одинаково. Скорее всего они должны быть одинаковыми и семантически, но у вас могут быть свои причины для того, чтобы они были разными.
  • Это будет служебный миксин.
Еще может быть опасение, что придется писать гигантские списки селекторов. Иногда полезно создать обёрточный класс, но если честно, у вас не должно быть большой пачки селекторов, поскольку сами элементы семантически различаются и не должны иметь так много общих стилей. Суть осмысленного CSS в том, чтобы знать из CSS, что этот button или [role=button] относится ко всем кнопкам, а[type=submit] — всегда основной элемент действия в форме.
Сегодня в нашем распоряжении так много мощных атрибутов, что в большом стеке селекторов нет нужды. Их наличие говорит о том, что мы плохо представляем, с чем работаем и для чего это нужно в рамках всей системы.
Пришло время взяться за наш CSS как следует. Можно остаться догматически привязанными к уже устаревшим паттернам, а можно двигаться вперёд с CSS и разметкой, которые соответствуют официальным спецификациям и стандартам. Теперь можно использовать настоящие объекты, а не создавать их абстрактные представления. Поддержка в браузерах есть. Стандарты и ссылки на месте. Можно начать сегодня. Только привычка останавливает нас.

Возвращение