SMACSS, имена семантических классов и вложенные элементы
Я только что прочитал масштабируемую и модульную архитектуру для CSS, и это заставило меня задуматься о нескольких вещах. Два основных принципа Snook:
- Увеличить семантическую ценность раздела HTML и контента
- Уменьшите ожидание определенной структуры HTML
Таким образом, это означает использование семантических имен классов, а не использование несемантических типов элементов для нацеливания. Например, а не нацеливание .someClass h5
Я мог бы нацелиться .someClass-title
вместо этого, так что если h5 заменен на что-то другое, вещи не сломаются.
Лично я нахожу кодирование иерархии элемента в его названии несколько неприятным (даже если это семантически правильно). Я бы предпочел сделать .someClass .title
, Но чтобы использовать класс в качестве заголовка, нужно принять, что этот класс будет использоваться во многих различных контекстах.
Итак, есть ли что-то не так с использованием одного и того же класса в совершенно разных контекстах, если я знаю, что он будет находиться в пространстве имен предыдущего элемента в селекторе?
Например, скажем, у меня есть три разных места на моем сайте, где класс 'title' имеет смысл:
HTML
<header class="pageHeader">
<h1 class="title">Some Title</h1>
</header>
...
<article class="leadArticle>
<h3 class="title">Some Article Title</h3>
</article>
...
<ul class="productPreviews">
<li class="product">
<h5 class="title">Some Product Name</h5>
</li>
</ul>
CSS
.pageHeader .title
{
}
.leadArticle .title
{
}
.productPreview .product .title
{
}
Изменить: как Alohci упоминает в своем ответе ниже, тег заголовка не является несемантическим, так что, возможно, это не лучший пример для использования.
Очевидно, я мог бы делать что-то совершенно иное с заголовком в этих контекстах, но заголовок имеет абсолютный смысл с пространством имен его модуля, и я никогда не собирался использовать заголовок в качестве общего селектора.
Это, кажется, отметьте все коробки. Он семантически богат, полностью отделен от реализации. Например, если последний пример был изменен на ol или стек div, ничто не сломалось бы, и если title было заключено в div, он все равно был бы целевым.
Это имеет смысл для меня, но я не видел, чтобы этот подход использовался много, и мне интересно, почему. Очевидным недостатком является то, что вы используете цепочки классов в селекторе, но я думаю, что это предпочтительнее, чем пространство имен для каждого имени класса.
4 ответа
Я предпочитаю использовать такой класс, как.title, а не просто элемент h5, так как я чувствую, что он еще больше отделяет HTML от CSS. Если по какой-либо причине вы решите, что h4 или h6 больше подходят для контура документа или какого-либо другого элемента / причины, вам придется реорганизовать свой CSS, если вы выбираете элемент (h5) по сравнению с выбором класса (. заглавие).
Вот почему я предпочитаю классифицировать ВСЕ ВЕЩИ против селекторов элементов, потому что разметка может со временем меняться. Если вы работаете на небольшом сайте, который не видит много обновлений, это может не беспокоить, хотя это полезно знать.
Если что-то не так с использованием одного и того же класса в совершенно разных контекстах, если вы знаете, что это будет пространство имен предыдущего элемента в селекторе, у меня смешанные мысли по этому поводу.
С одной стороны, возникают некоторые проблемы, например, использование / значение / роль.title может быть пустым без родительского селектора. (.pageHeader.title) Хотя я думаю, что.title - отличное имя класса, другим разработчикам может быть трудно понять, что его значение происходит от родительского селектора, такого как .pageHeader .title
Другая проблема заключается в том, что если вы используете класс.title для нескольких экземпляров "заголовков" в модуле, вы можете столкнуться с проблемами. Основная идея заключается в том, что локальные ограничивающие селекторы потомков могут иногда быть слишком ограничивающими, если пытаются расширить возможность повторного использования.title внутри модуля. Я установил демонстрационную версию кода, чтобы показать, о чем я говорю здесь.
С другой стороны, селекторы-потомки являются одними из наиболее часто используемых селекторов, специально для их определения.
Тим Мёрто, который является одним из разработчиков (не уверен, является ли он ведущим разработчиком) для AList Apart, использует селекторы-потомки для большинства своих стилей на своем личном сайте.
Я недавно изучал это и БЭМ и согласился бы с вашим выводом: "это предпочтительнее, чем пространство имен каждого имени класса".
Я предпочитаю.pageHeader .title{...} против.pageHeader__title{...}, но всегда есть случаи, когда один подход может быть более выгодным в ситуации, чем другой.
Как и с большинством вещей, это зависит, но я думаю, что если вы не позволите вложенности слишком углубиться и задумаетесь над тем, как вы их используете, селекторы-потомки являются мощным и хорошим решением для предоставления стилей с локальной областью, а также предлагают решение для всего мира. стилевые рамки.
Например:
/* Globally scoped styles for all .title(s) */
.title{
font-family: serif;
font-weight: bold;
}
/* Locally scoped styles for individual .title(s) */
.pageHeader .title {
color: #f00;
}
.leadArticle .title {
color: #00f;
}
.productPreview .product .title {
color: #0f0;
}
Я думаю, что очень мало что можно сказать по этому поводу. То, что вы делаете, хорошо, хотя это не единственный подход к организации вашей разметки для CSS. Важно понимать, что имена классов не являются частью CSS, они являются частью HTML.
Таким образом, классы, применяемые к элементу, не являются, в терминах HTML, "пространством имен" их предками в дереве DOM, но стоят сами по себе. Поэтому разумно, чтобы вы использовали "title" для имен классов каждого из элементов в вашем примере, потому что все они одинаковы в качестве заголовков.
Противоположным примером может быть использование имени класса "note", где на одном элементе он обозначает тип комментария, а на другом элементе музыкальная нота, и затем предполагается, что их значения могут быть различены путем проверки элемента-предка., Это не так, как классы HTML должны работать.
Это также работа, отмечающая, что в этом нет ничего бессмысленного <h5>
, Использование имен элементов в ваших селекторах CSS - это просто еще один способ описания отношений между элементами, которые вы хотите стилизовать. .product h5
под селектором подразумевается "стиль заголовков пятого уровня в контексте поддерева класса" product ", как это...". Это другое утверждение от .product .title
что означает "элементы стиля класса title в контексте поддерева класса product, как это...". Оба утверждения полезны.
Очень важно отметить, что браузеры читают CSS справа налево, а не слева направо, поэтому, если вы структурируете свои селекторы на несколько уровней глубже, браузерам нужно больше работать.
.pageHeader .title {}
.leadArticle .title {}
.productPreview .product .title {}
Так что это один.title, но в другом контексте. Браузер при рендеринге проверит, находится ли дочерний элемент внутри определенного родительского элемента, и затем он применит соответствующие правила.
.pageHeader-title {}
.leadArticle-title {}
.productPreview .product-title {}
Здесь у нас есть 3 очень разных названия (не одно!), Поэтому браузер не будет делать никаких дополнительных вычислений и проверять, является ли дочерний элемент дочерним по отношению к конкретному родительскому элементу. У нас здесь также более плоская структура модулей, что всегда приятно.
Всегда помните, что вложение ваших селекторов и присвоение им имен одинаковым образом, но в другом контексте, влияет на производительность, что ничего не значит, если вы пишете небольшой персональный веб-сайт, но если вам нужно планировать и предоставлять решение, которое будет просматриваться миллионами тогда важно знать, как правильно структурировать разметку.
Иногда его называют "отношения между родителями и детьми" ( http://thesassway.com/advanced/modular-css-naming-conventions) и часто рекомендуется использовать .page-header-title
,
В твоем случае .page-header
можно рассматривать как компонент и .title
как составная часть. RCSS ( https://github.com/rstacruz/rscss/) стандартные адвокаты .page-header > .title
, Я лично считаю, что это не очень хорошая идея. Подумайте о следующем:
<header class="page-header">
<h2 class="title">
<span class="tooltip">
<span class="title">..</span>
</span>
</h2>
</header>
.tooltip > .title
непреднамеренно наследует от .page-header > .title
,
Так что я бы пошел с .page-header-title
,
Когда вы намереваетесь унаследовать заголовок от базового класса, просто добавьте класс к элементу HTML
<header class="page-header">
<h2 class="page-header-title title">
</h2>
</header>
Сейчас page-header-title
содержит специфичные для компонента стили и title
дополнения с абстрактными стилями заголовка. Да, это многословно, но безопасно. Здесь, если есть интерес, мое подробное мнение о том, как сохранить каскадный стиль вменяемым и иметь чистую и очевидную абстракцию https://github.com/dsheiko/pcss