“Форма всегда вытекает из функциональности. Это закон”. Так говорил знаменитый архитектор и “отец небоскребов” Луи Салливан. Архитекторы не желая раздавить сотни невинных людей под тяжестью колоссального здания, беспрекословно выполняют это правило. В дизайне, вы должны всегда начинать с функциональности, а форма должна возникать в результате. Вы можете попробовать создать небоскреб в первую очередь акцентируя внимание на создании привлекательного внешнего вида, но в этом случае могут появиться разного рода опасности.
Существует множество различных видов архитекторов. А как насчет интерфейсных архитекторов — или как мы их иногда ещё называем “не настоящих архитекторов”? Должны ли они безоговорочно соблюдать этот закон, или им все сойдет с рук?
С появлением объектно-ориентированного CSS (OOCSS) все более модной становится тенденция “отделения семантики представления от семантики документа“. Используя неуказанные значения классов, можно управлять одним документом и появлением своего документа в качестве отдельного объекта.
В этой статье мы рассмотрим альтернативный подход к моделированию веб-документов. Также мы постараемся там где это возможно сопоставить семантику документа с визуальным дизайном. С помощью “умных” селекторов, мы рассмотрим, как запросить существующую функциональность семантического HTML и поощрить хорошо сформированную разметку. Если вы правильно разработаете программный код, то сможете получить ожидаемый дизайн.
Если вы похожи на меня и у вас постоянно возникают какие-либо проблемы или если за один раз пытаетесь выполнить несколько работ, я надеюсь, что использование некоторых из этих идей сделает ваш рабочий процесс более простым и вы сможете использовать их в различных проектах. Кроме того, в последнем разделе будет описана более радикальная стратегия: мы создадим букмарклет (небольшая JavaScript-программа, оформленная как javascript: URL и сохраняемая как браузерная закладка) CSS, который содержит интеллектуальные атрибуты селекторов для проверки плохой HTML разметки и с возможностью вывода сообщений об ошибках использования псевдо-контента.
Интеллектуальные селекторы.
С изобретением таблиц стилей появилась возможность физического разделения кода документа и кода используемого для представления этого документа. Эта возможность не помогала нам создавать более качественный, основанный на стандартах HTML, программный код, также как появление пульта дистанционного управления не привело к улучшению телевизионных программ. Такая возможность просто сделала использование некоторых вещей более удобным. Возможность создания стиля нескольких элементов с помощью одного селектора (например, p
для абзацев), привела к тому, что организация последовательности и обслуживание стали значительно менее сложными процессами.
Селектор p
является примером интеллектуального селектора в своей простейшей форме. Селектор p
принято считать интеллектуальным, поскольку он имеет врожденное знание семантической классификации. Без вмешательства автора этот селектор уже знает, как определить пункты и какой стиль для них нужно использовать. Простое, но достаточно эффективное средство, особенно когда вам необходимо следить за всеми автоматически созданными пунктами производства WYSIWYG («что видишь, то и получишь») редакторов.
Итак, если рассмотренный нами селектор является интеллектуальным, тогда какой селектор будет считаться не интеллектуальным? Любой селектор, который требует вмешательства автора и изменения документа для простого вызова какого-либо стилистического нюанса является не интеллектуальным селектором. class
— это пример классического не интеллектуального селектора, поскольку он не встречается в природе как часть семантического объединения. Вы можете самостоятельно организовывать и давать названия классам, но делать это нужно осторожно и осмысленно. Созданные вами классы не достаточно умны, чтобы самостоятельно обеспечить требуемый уровень функциональности, и браузеры в свою очередь не достаточно умны, чтобы представить для вас эти классы.
Не интеллектуальные селекторы требуют дополнительных усилий, поскольку они нуждаются в дополнительных индивидуальных методах моделирования. Если бы у нас не было тэга p
, то для организации пунктов мы должны были бы использовать не интеллектуальные селекторы, возможно, с использованием.paragraph
для каждого случая. Один из недостатков заключается в том, что CSS не является портативным — то есть, вы не можете использовать его для HTML документа без первичного прохождения через документ и добавления классов везде, где они требуются.
Не интеллектуальные селекторы в некоторых ситуациях кажутся необходимыми, или по крайней мере их просто легче реализовать, и лишь некоторые из нас готовы полностью положиться на интеллектуальные селекторы. Тем не менее, некоторые не интеллектуальные селекторы могут стать “просто глупыми” селекторами, создавая несоответствие между структурой документа и его представлением. Я буду говорить прямо, при использовании не интеллектуального селектора .button
быстро станет понятна ошибочность и нелепость подобного выбора.
Vive La Différence (ура разнице).
Интеллектуальные селекторы не ограничиваются только основными элементами, предлагаемыми нам в спецификации языка HTML. Для создания сложных интеллектуальных селекторов, можно воспользоваться комбинаций контекста и функциональных атрибутов, с помощью которых можно различать основные элементы. Некоторые элементы, такие как <a>
, имеют множество функциональных различий представления и использования. Другие элементы, такие как <p>
, редко отличаются от явной функции, но все же исполняют слегка различные роли в зависимости от контекста.
header p {
/* styles for prologic paragraphs */
}
footer p {
/* styles for epilogic paragraphs */
}
Простые потомственные селекторы чрезвычайно мощны, потому что они позволяют нам визуально раскрыть различные виды одного и того же элемента без необходимости физического изменения основы документа. В этом вся причина того, почему были изобретены таблицы стилей: для облегчения физического разделения, при этом не нарушая концептуальной взаимности, которая должна существовать между документом и дизайном.
Вполне возможно, что некоторые приверженцы OOCSS относятся к потомственным селекторам с некоторым подозрением, и более рьяно будут настаивать на разметке, например, как в примере ниже, найденном в документации “Определения” от BEM.
<ul class="menu">
<li class="menu__item">…</li>
<li class="menu__item">…</li>
</ul>
Далее я не буду рассматривать какие-либо контекстные селекторы, поскольку, если у вас есть склонность к реализации программного кода подобно тому, как описано в примере выше, я уверен, что подобные селекторы вы уже используете практически каждый день. Вместо этого мы сконцентрируемся на разделении по функциям, как описано в атрибутах и селекторах атрибутов.
Атрибуты Гиперссылки.
Даже те, кто выступает за концептуальное разделение между CSS и HTML с радостью признают, что некоторые атрибуты — большинство атрибутов кроме классовых и пользовательских атрибутов данных — имеют важное значение для функционирования внутреннего документа. Без атрибута href
, ваши ссылки не могут быть адресованы на абсолютно любое место. Без type
, браузер не будет знать, какое значение input
необходимо для визуализации. Без title
, ваш атрибут abbr
может относиться либо к Британской национальной партии, либо к Национальному банку Панамы.
Некоторые из этих атрибутов могут улучшить семантическую деталировку вашего документа, а другие, необходимы для обеспечения правильной передачи и функционирования элементов. Если такие атрибуты отсутствуют, то их нужно добавить, а если они есть, то почему бы не использовать их? Вы не можете создавать CSS без разработки HTML.
Атрибут rel.
Атрибут rel
появился в качестве стандарта для ссылочных зависимостей, метод описания некоторых конкретных ссылочных целей. Не все ссылки, которые вы видите, обладают требуемой функциональностью. Благодаря активному использованию в WordPress rel="prev"
и rel="next"
стали двумя наиболее широко используемыми значениями, которые помогают в описании ссылочных отношений между отдельными страницами многостраничного содержимого блога. Семантически тэг a
с атрибутом rel
это все еще тэг a
, просто с более конкретным представлением. В отличие от классов, эта специфика семантически последовательна.
Атрибут rel должен использоваться в случае необходимости, поскольку он подтвержден в HTML функциональной спецификации и поэтому может быть принят различными пользовательскими агентами для повышения опыта пользователей и точности поисковых систем. Как же тогда необходимо выполнять стилизацию таких ссылок? Конечно же с помощью простых атрибутов селекторов:
[rel="prev"] {
/* styling for "previous links" */
}
[rel="next"] {
/* styling for "next" links */
}
Атрибуты селекторов, наподобие тех, что представлены в примере, поддерживаются даже самыми устаревшими браузерами, так что нет абсолютно никаких причин отказываться от их использования. С точки зрения специфики, они имеют тот же вес, что и классы. Так что не должно возникнуть никаких проблем. Тем не менее, нужно помнить о выдвинутом ранее предположении о том, что нужно всегда стараться отделять семантику документа от семантики представления. Я не хочу отказываться от атрибута rel
(Google имеет реализованную тему), поэтому для стилизации элемента лучше буду использовать атрибут, который ничего не означает.
<a href="/previous-article-snippet/" rel="prev">previous page</a>
Первое, что нужно отметить, это то, что только часть элемента, представленного выше и которая не способствует семантическому оформлению документа, является классом. Другими словами класс – это единственная вещь в документе, которая не оказывает функционального влияния. На практике это означает, что класс является единственным элементом, который нарушает закон разделения: он имеет физическое присутствие в документе, но не способствует формированию структуры документа.
Слишком много абстрактного и как насчет обслуживания? Нужно признать, что мы используем class
как прием стилизации, а теперь давайте посмотрим, что происходит при редактировании или рефакторинге, выполняемом с целью удаления некоторых атрибутов. Предположим, что мы использовали некоторый псевдо-контент для размещения стрелки влево до [rel="prev"]
текстовой ссылки автора:
.prev:before {
content: '\2190'; /* encoding for a left-pointing arrow ("←") */
}
Удаление класса приведет к удалению псевдо-контента, который в свою очередь удалит стрелки (очевидно). А без стрелки уже ничего не будет указывать на существующие prev
взаимосвязи. К тому же, удаление атрибута rel
оставит нетронутым стрелку: класс по прежнему будет продолжать управлять представлением, все время скрывая несуществующие, но указанные в документе взаимосвязи. Только путем применения прямой стилизации, через использование семантических атрибутов вызова, вы можете сохранить ваш программный код простым и аккуратным. Если какой-то элемент действительно существуют, как функция документа, вы должны иметь возможность видеть её.
Атрибуты подстрок.
Я могу себе представить, что вы думаете: «Это все интересно, но сколько в действительности существует приемов для семантической стилизации, как на гиперссылках? В некоторой степени мне придется полагаться на классы». Я могу с вами поспорить. Считайте, что это далеко не полный перечень гиперссылок с различными функциональными возможностями, которые используют элемент a
в качестве своей основы:
- Ссылки на внешние ресурсы,
- ссылки на защищенные страницы,
- ссылки на авторские страницы,
- ссылки на страницу помощи,
- ссылки на предыдущие страницы (смотрите пример выше),
- ссылки на следующие страницы (снова смотрите пример выше),
- ссылки на PDF ресурсы,
- ссылки на документы,
- ссылки на заархивированные ZIP папки,
- ссылки на исполняемые файлы,
- ссылки на фрагменты внутренних страниц,
- ссылки, которые в действительности являются кнопками (подробнее об этом буде сказано немного позже),
- ссылки, которые в действительности являются кнопками и переключателями состояний,
- ссылки, открывающие клиентов электронной почты,
- ссылки, которые вызывают телефонные номера на смартфонах,
- ссылки на источник просмотра страниц,
- ссылки, которые открывают новые вкладки и окна,
- ссылки на JavaScript и JSON файлы,
- ссылки на RSS-каналы и XML файлы.
Как вы видите, существует большое множество функционального разнообразия. Каждая из существующих функциональных возможностей может быть идентифицирована любым из пользовательских агентов. Принято считать, что для того, чтобы все эти конкретные виды ссылок функционировали по-разному, у них должны быть взаимно дифференциальные атрибуты. То есть, для того, чтобы функционировать по-другому, они должны быть написаны по-разному, и если они написаны по-разному, они могут быть по-разному стилизированы.
При подготовке этой статьи я создал доказательную концепцию, которую назвал Auticons. Auticons представляет собой набор иконок и CSS установок, которые автоматически выполняют стилизацию ссылок. Все селекторы в файле CSS являются селекторами атрибутов, которые вызывают стили для правильно сформированных гиперссылок, без необходимости использования классов.
Во многих случаях Auticons запрашивает подмножество от href
значения для того, чтобы определить функцию гиперссылки. Возможна стилизация элементов в зависимости от способа задания значений атрибутов начала или конца, или в зависимости от содержания подстроки значений из которых они состоят. Ниже приведены некоторые общие примеры.
Безопасный протокол.
Каждый хорошо сформированный (т.е. абсолютный) URL начинается с URI схемы, которая следует за двоеточием. Наиболее распространенными протоколами в интернете являются http:
и mailto:
(для SMTP – Simple Mail Transfer Protocol – простой протокол электронной почты). Также широко распространен протокол tel:
(который относится к телефонам). Если мы будем знать ожидаемое значение href
гиперссылки, то сможем использовать это семантическое обозначение в качестве приема стилизации. В следующем примере для защищенных страниц, мы используем компаратор ^=
, который означает «начать с».
a[href^="https:"] {
/* style properties exclusive to secure pages */
}
В Auticons, ссылки на защищенные страницы отображаются в совокупности со значком замка в соответствии с определенным семантическим шаблоном, который идентифицирован внутри href
атрибута. Подобная реализация имеет следующие преимущества:
- Ссылки на защищенных страницах — и только защищенные страницы — могут быть идентифицированы соответствующим образом благодаря использованию иконки замка.
- Ссылки на защищенных страницах, которые перестают быть истинными, теряют
https
протокол, а с ним, сходство. - Новые защищенные страницы утвердят значок замка и станут напоминать ссылки на защищенные страницы автоматически.
Данный селектор становится по-настоящему интеллектуальным при использовании с динамическим контентом. Поскольку безопасные ссылки существуют абстрактно, селектор атрибутов может предвидеть их вызовом: как только редактор опубликует некоторый контент, который содержит защищенную ссылку, ссылка будет иметь сходство с безопасным для пользователя вариантом. Не требуется дополнительных знаний имен классов или сложного HTML редактирования, так что даже с помощью простого Markdown можно создать стиль:
[Link to secure page](https://payment.example.com/)
Заметим, что использование [href^="https:"]
префикса не является абсолютно правильным, поскольку не все страницы HTTPS (протокол защищённой передачи гипертекста) действительно безопасны. Тем не менее, даже самому браузеру свойственно ошибаться. При отображении HTTPS страниц все основные браузеры изначально размещают значок замка в адресной строке.
Типы файлов.
Как и было обещано, вы также можете стилизировать гиперссылки в соответствии со значением href
окончаний. На практике это означает, что вы можете использовать CSS для того, чтобы указать на какой тип файла осуществляется ссылка. Auticons поддерживает .txt
, .pdf
, .doc
, .exe
и многие другие. Вот .zip
пример, в котором с помощью $=
: определяются href
окончания:
[href$=".zip"]:before,
[href$=".gz"]:before {
content: '\E004'; /* unicode for the zip folder icon */
}
Комбинации.
Известно ли вам, как можно получить все объектно-ориентированные элементы и использовать выбор нескольких классов для создания стиля? Вы можете сделать это автоматически благодаря селекторам атрибутов. Давайте сравним:
/* The CSS for the class approach */
.new-window-icon:after {
...
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров