Как структурировать CSS классы? По сущностям или по аспектам? - PullRequest
11 голосов
/ 11 августа 2010

Интересно, что лучше вписывается в философию CSS:

  1. Классы CSS отмечают сущности - ИЛИ -
  2. Классы CSS отмечают аспекты

Например, возьмем ячейку для прайс-листа продукта и ячейку нижнего колонтитула, которая содержит сумму всех цен.

В первом случае каждая из ячеек будет иметь только один класс: product-priceсоответственноproduct-price-sum (или price и строка, например, имеет класс product) Другими словами: Классы идентифицируют вещей.

В случае, если дваячейки будут иметь много классов, которые определяют свойства / аспекты цены продукта, например, numeric и currency и дополнительный класс sum для нижнего колонтитула.numeric будет определять текст для выравнивания по правому краю, sum будет выделять ячейку жирным шрифтом.Другими словами: Классы описывают вещей.

Я не могу решить, какой подход лучше.В прошлом я использовал смесь обоих, что быстро привело к уродливой куче неструктурированных CSS-классов с конфликтующими стилями и некоторыми уродливыми !important взломами.

Первый подход, очевидно, имеет некоторую избыточность, потому что у одного было бы многоклассы (product-*) и большинство из них будут иметь общие свойства CSS.

У второго возникают проблемы, когда речь идет о различном форматировании только одного места, скажем, суммы цены продукта.Вполне возможно, что есть другие места, которым также назначены те же три класса, но они не имеют никакого отношения к цене продукта.В этом случае нужно было бы использовать окружающие теги HTML, чтобы как-то «адресовать» определенное место в файле HTML.

Существуют ли практические правила, рекомендации, проверенные концепции и т. Д. О том, как решить эту проблему

Ответы [ 5 ]

5 голосов
/ 11 августа 2010

Просто наблюдение ... Люди склонны забывать, что 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 */ }

Thisэто не окончательное решение.Просто новый подход к проблеме.

Помните также, что вы можете указать некоторые состояния или дополнительную информацию для 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>

Обратите внимание, что атрибут selected в теге tr не влияет на стандартную визуализацию таблицы, поскольку он не является распознанным атрибутом тега, но можетбыть идентифицированным CSS (а также javascript, который здесь не тот).Как это:

.product tr[selected=selected] { /* styles for the selected row */ }
2 голосов
/ 11 августа 2010

Я бы настоятельно рекомендовал делать пометки по сущности (атрибуту, а не отдельному элементу), поэтому class = 'product price' (2 tag), а не class = 'product-price' (1 tag). Если вы будете осторожны, это приведет к тому, что код станет чище и проще в обслуживании. Если у вас возникли проблемы с! Важно, попробуйте нарисовать дерево структуры тегов. Это поможет решить, на каком уровне дерева объявлять определенные свойства, и приведет к минимальному использованию! Важное.

1 голос
/ 11 августа 2010

Я не думаю, что есть правильный ответ, но вы хотите отдать предпочтение подходу, который приводит к чистому CSS и наименьшему дублированию в целом.Лично для меня я бы сказал, что вы хотите что-то среднее между вашими двумя вариантами, но ближе ко второму варианту.

Если я правильно понимаю ваши описания, с первым вариантом у вас будет что-то вроде этого:

<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 {
    // etc.
}

.currency {
    // etc.
}

Использование окружающих тегов HTML для ваших исключений хорошо, если вы можете сделать это семантическим способом.Например, у вас могут быть некоторые общие стили для класса валюты, но затем выравнивание текста: прямо на td.currency.

Единственное, что я бы сказал, это то, что если вам придется использовать! важно переопределить свои собственные стили, вы делаете что-то не так!

0 голосов
/ 12 августа 2010

Я думаю, что это немного индивидуальный подход. Я также люблю иерархию и использую это много. Но я больше всего использую вариант сущности, но стараюсь избегать как можно большего количества разметки. Правило, которое я использую, гласит, что заголовки всегда идут с h1 или h2. И вы можете стиль соответственно внутри вашей сущности. Так, например:

.product               { }
.product h1            { }
.product span.price    { }
.product span.discount { }

То же самое для, скажем, навигации:

ul.navigation          { }
ul.navigation li       { }
ul.navigation li.first { }
ul.navigation li.last  { }

И с учетом сказанного, я бы всегда сказал, пойти на вариант, который имеет наименьшее количество разметки, без потери вашего обзора. Чистый код это хорошо.

0 голосов
/ 11 августа 2010

У второго возникают проблемы, когда речь идет о другом формате, скажем, о сумме цены продукта. Вполне возможно, что есть другие места, которым также назначены те же три класса, но они не имеют никакого отношения к цене продукта. В этом случае нужно было бы использовать окружающие теги HTML, чтобы как-то «адресовать» определенное место в файле HTML.

Разве «адресация» - это не весь смысл правил CSS и специфичность ? Я думаю об этом меньше как о «адресации» и больше как о «пространстве имен»;)

Лично я предпочитаю второй метод; Я предпочитаю использовать атрибут id для идентификации вещей;)
... но атрибут class считается, тем не менее, идентификатором элемента .

В конце концов, цель атрибута class используется " для обработки общего назначения пользовательскими агентами. " Я интерпретирую это как означающее, что значения, которые вы ему задаете, должны соответствовать потребностям вашего приложения.

Так что, если вашему приложению необходимо определить все цены на продукты - будь то для стилевого оформления CSS или для сценария jQuery, программы для чтения с экрана или чего-либо еще - идентифицируйте их с атрибутом класса product-prices.

Если вашему приложению необходимо описать все числовые значения - опять-таки, будь то для CSS-стиля, или для сценария jQuery, или для чтения с экрана, или что-то еще - идентифицируйте их с атрибутом класса numeric.

PS Пожалуйста, не называйте это CSS class; Назовите его просто «class атрибут». Если вы не работаете в Asp.NET, не существует такой вещи, как CSS class, и даже в Asp.NET - не должно быть CSS class.

Извините за множество бесстыдных ссылок на мой собственный веб-сайт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...