Как структурировать классы CSS? Субъектами или аспектами?
Интересно, что лучше подходит для философии CSS:
- Классы CSS отмечают объекты
- ИЛИ -
- Классы CSS отмечают аспекты
Например, возьмите ячейку для ценового листка продукта и нижнюю сноску, содержащую сумму всех цен.
В первом случае каждая из ячеек будет иметь только один класс: product-price
resp. product-price-sum
(или price
, а строка, например, имеет класс product
)
Другими словами: Классы идентифицируют вещи.
В случае двух ячеек будет иметь много классов, которые определяют свойства/аспекты цены продукта, например numeric
и currency
, и дополнительный класс sum
для нижнего колонтитула. numeric
будет определять выравниваемый текст, sum
будет отмечать ячейку жирным шрифтом.
Другими словами: Классы описывают вещи.
Я не могу решить, какой подход лучше. В прошлом я использовал смесь обоих, которая быстро привела к уродливой куче неструктурированных классов CSS с противоречивыми стилями и некоторыми уродливыми взломами !important
.
Первый подход, очевидно, имеет некоторую избыточность, потому что у него будет много классов (product-*
), и большинство из них будут иметь общие свойства CSS.
У второго есть проблемы, когда дело доходит до формата только одного места по-разному, скажем, цена цены продукта. Возможно, что есть и другие места, которые также имеют одинаковые три класса, но не имеют ничего общего с ценой продукта. В этом случае вам придется использовать окружающие теги HTML, чтобы каким-то образом "указать" конкретное место в файле HTML.
Существуют ли какие-либо эмпирические правила, рекомендации, проверенные концепции и т.д. о том, как справиться с этой проблемой?
Ответы
Ответ 1
Просто наблюдение... Люди склонны забывать, что CSS является иерархическим. Позвольте мне дать вам очень простой пример (пожалуйста, теги сводятся к минимуму):
<table class="product">
<thead>
<tr><th>Name</th><th class="price">Price</th></tr>
</thead>
<tbody>
<tr><td>Product 1</td><td class="price">1</td></tr>
<tr><td>Product 2</td><td class="price">2</td></tr>
<tr><td>Product 3</td><td class="price">3</td></tr>
</tbody>
<tfoot>
<tr><td>Total</td><td class="price">6</td></tr>
</tfoot>
</table>
вы можете создавать стили классов со стилем тега, чтобы указать, где будет использоваться стиль:
table { /* styles for all tables */ }
.product { /* styles for the product table */ }
.product thead { /* styles for the all product table header row */ }
.product thead th{ /* styles for header row generic column */ }
.product thead .price { /* styles for header row price column */ }
.product tbody { /* styles for the all product table data row */ }
.product tbody td { /* styles for data row generic column */ }
.product tbody .price { /* styles for data row price column */ }
.product tfoot { /* styles for the all product table summarize row */ }
.product tfoot td { /* styles for summarize row generic column */ }
.product tfoot .price { /* styles summarize row price column */ }
Или вы можете использовать только простые теги таблицы (теги th, thead, tbody и tfoot) следующим образом:
<table class="product">
<tr class="header"><td>Name</td><td class="price">Price</td></tr>
<tr class="data"><td>Product 1</td><td class="price">1</td></tr>
<tr class="data"><td>Product 2</td><td class="price">2</td></tr>
<tr class="data"><td>Product 3</td><td class="price">3</td></tr>
<tr class="footer"><td>Total</td><td class="price">6</td></tr>
</table>
И CSS будет
.product { /* styles for the product table */ }
.product .header { /* styles for the all product table header row */ }
.product .header td{ /* styles for header row generic column */ }
.product .header .price { /* styles for header row price column */ }
.product .data { /* styles for the all product table data row */ }
.product .data td { /* styles for data row generic column */ }
.product .data .price { /* styles for data row price column */ }
.product .footer { /* styles for the all product table summarize row */ }
.product .footer td { /* styles for summarize row generic column */ }
.product .footer .price { /* styles summarize row price column */ }
Это не окончательное решение. Просто новый подход к проблеме.
Помните также, что вы можете указать некоторые состояния или дополнительную информацию в CSS с использованием пользовательских атрибутов. См. Этот пример:
<table class="product">
<tr class="header"><td>Name</td><td class="price">Price</td></tr>
<tr class="data"><td>Product 1</td><td class="price">1</td></tr>
<tr class="data" selected="selected"><td>Product 2</td><td class="price">2</td></tr>
<tr class="data"><td>Product 3</td><td class="price">3</td></tr>
<tr class="footer"><td>Total</td><td class="price">6</td></tr>
</table>
Посмотрите, что атрибут "выбран" в теге "tr" не влияет на стандартную визуализацию таблицы, поскольку он не является признанным атрибутом тега, но может быть идентифицирован с помощью CSS (а также с помощью javascript, что здесь не так). Вот так:
.product tr[selected=selected] { /* styles for the selected row */ }
Ответ 2
Я бы рекомендовал пометку по объекту (атрибуту, а не отдельному элементу), поэтому class= "цена продукта" (2 тега), а не class= "цена продукта" (1 тэг). Если вы будете осторожны, это приведет к более чистым, легче поддерживать код. Если у вас возникли проблемы с! Important, попробуйте создать дерево того, как будут структурированы теги. Это поможет решить, на каком уровне дерева объявить определенные свойства, и в результате минимальное использование важности.
Ответ 3
Я не думаю, что есть правильный ответ, но вы хотите одобрить подход, который приводит к чистым CSS и наименьшему дублированию в целом. Для меня лично я бы сказал, что вы хотите что-то между вашими двумя вариантами, но ближе к варианту 2.
Если я правильно понимаю ваши описания, с одним вариантом у вас будет что-то вроде этого:
<table>
<tr>
<td>Product A</td>
<td class="price">£1</td>
</tr>
<tr>
<td>Product B</td>
<td class="price">£2</td>
</tr>
<tr>
<td>Total</td>
<td class="price-sum">£3</td>
</tr>
</table>
а затем CSS:
.price {
text-align: right;
}
.price-sum {
text-align: right;
font-weight: bold;
}
а второй вариант будет примерно таким:
<table>
<tr>
<td>Product A</td>
<td class="numeric currency">£1</td>
</tr>
<tr>
<td>Product B</td>
<td class="numeric currency">£2</td>
</tr>
<tr>
<td>Total</td>
<td class="numeric currency sum">£3</td>
</tr>
</table>
но почему бы и нет:
<table>
<tr>
<td>Product A</td>
<td class="price">£1</td>
</tr>
<tr>
<td>Product B</td>
<td class="price">£2</td>
</tr>
<tr>
<td>Total</td>
<td class="price sum">£3</td>
</tr>
</table>
и
.price {
text-align: right;
}
.sum {
font-weight: bold;
}
Нет смысла указывать ячейку как "numeric", так и "currency", если все поля валюты всегда будут иметь оба класса - лучше дать валюте те же стили, что и числовые в таблице стилей, а затем просто использовать валюту в источнике:
.numeric, .currency {
// etc.
}
.currency {
// etc.
}
Использование окружающих тегов HTML для ваших исключений прекрасно, если вы можете сделать это семантическим способом. Например, у вас могут быть некоторые общие стили в классе валют, но затем выравнивание по тексту: прямо на td.currency.
Единственное, что я могу сказать, это то, что если вам нужно использовать! важно переопределить свои собственные стили, вы делаете что-то неправильно!
Ответ 4
У второго есть проблемы, когда дело доходит до формата только одного места по-разному, скажем, цена цены продукта. Возможно, что есть и другие места, которые также имеют одинаковые три класса, но не имеют ничего общего с ценой продукта. В этом случае вам придется использовать окружающие теги HTML, чтобы каким-то образом "указать" конкретное место в файле HTML.
Разве это не означает "адресация" всей цели правил CSS и specificity? Я думаю, что это меньше, чем "обращение" и больше похоже на "namespacing";)
Лично я предпочитаю второй метод; Я предпочитаю использовать атрибут id
для определения вещей;)
... но атрибут class
тем не менее считается идентификатором элемента.
В конце концов, цель атрибута класса используется " для обработки общего назначения агентами пользователя." Я интерпретирую это как что значения, которые вы им даете, должны соответствовать потребностям вашего приложения.
Итак, если ваше приложение должно идентифицировать все цены на продукт - будь то для стилей CSS или для jQuery script или для чтения с экрана или любого другого - идентифицируйте их с атрибутом класса product-prices
.
Если вашему приложению необходимо описать все числовые значения - опять же, будь то стилистика CSS или для jQuery script или программа чтения с экрана или что-то еще - укажите их с атрибутом класса numeric
.
PS Не называйте это CSS class
; назовите его просто атрибутом <<21 > . Если вы не работаете в Asp.NET, нет такой вещи, как CSS class
и даже в Asp.NET - не должно быть CSS class
.
Извините за несколько бесстыдных ссылок на мой собственный веб-сайт.
Ответ 5
Я думаю, что это немного личный подход.
Мне также нравится иерархия, и я использую это много.
Но я больше использую вариант сущности, но стараюсь избегать как можно большего количества разметки.
Правило, которое я использую, - это названия, которые всегда идут с h1 или h2. И вы можете соответствующим образом подстроить свой объект.
Так, например:
.product { }
.product h1 { }
.product span.price { }
.product span.discount { }
То же самое можно сказать о навигации:
ul.navigation { }
ul.navigation li { }
ul.navigation li.first { }
ul.navigation li.last { }
И с учетом сказанного, я бы всегда говорил, иди за вариантом, у которого есть наименьшая сумма разметки, не теряя ваш обзор. Чистый код хорош.