如何构建CSS类?实体或方面?

时间:2010-08-11 18:43:43

标签: css

我想知道什么更适合CSS哲学:

  1. CSS类标记实体 - 或 -
  2. CSS类标记方面
  3. 例如,让我们将单元格作为产品价格表和页脚单元格,其中包含所有价格的总和。

    在第一种情况下,每个单元格只有一个类:product-price resp。 product-price-sum(或price,例如,行有product类 换句话说:识别事物。

    如果两个单元格有许多类,它们定义产品价格的属性/方面,例如numericcurrency以及页脚的额外sum类。 numeric会将文本定义为右对齐,sum会将单元格标记为粗体。 换句话说:描述事物。

    我无法确定哪种方法更好。在过去,我使用了两者的混合,这很快导致了一堆丑陋的非结构化CSS类,它们具有冲突的样式和一些丑陋的!important黑客。

    第一种方法显然有一些冗余,因为一个会有很多类(product-*),而且大多数都会共享常见的CSS属性。

    第二个问题在于只对一个地方进行不同的格式化时,让我们说产品价格总和。可能有其他地方也分配了完全相同的三个类别,但与产品价格没有任何关系。在这种情况下,必须使用周围的HTML标记以某种方式“寻址”HTML文件中的特定位置。

    是否有关于如何处理此问题的经验法则,指南,经过验证的概念等?

5 个答案:

答案 0 :(得分:5)

只是观察......人们往往会忘记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”标记中的“selected”属性对表的标准渲染没有影响,因为它不是标记的可识别属性,但它可以由CSS(也可以通过javascript,这不是这里的情况)。像这样:

.product tr[selected=selected] { /* styles for the selected row */ }

答案 1 :(得分:2)

我强烈建议按实体标记(属性,而不是单个元素),因此class ='product price'(2个标签),而不是class ='product-price'(1个标签)。如果您小心,这将导致更清晰,更易于维护的代码。如果您在使用!important时遇到问题,请尝试绘制标签结构的树。这将有助于确定树的哪个级别声明某些属性,并最少使用!important。

答案 2 :(得分:1)

我认为没有任何正确答案,但您希望采用能够产生最干净的CSS并且整体复制最少的方法。就我个人而言,我会说你想要两种选择之间的东西,但更接近选项二。

如果我正确理解你的描述,那么你可以使用选项1:

<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上则有一个text-align:right。

我唯一要说的是,如果你必须使用!重要来覆盖你自己的风格,那你就做错了!

答案 3 :(得分:0)

  

第二个问题在于只对一个地方进行不同的格式化时,让我们说产品价格总和。可能有其他地方也分配了完全相同的三个类别,但与产品价格没有任何关系。在这种情况下,必须使用周围的HTML标记以某种方式“寻址”HTML文件中的特定位置。

这样不是“解决”CSS规则和specificity的全部要点吗?我认为它不像“寻址”而更像是“命名空间”;)

就个人而言,我更喜欢第二种方法;我倾向于使用id属性来识别事物;)
...但class属性仍被视为element identifier

最后,class属性的目的是使用“for general purpose processing by user agents.”我将其解释为意味着您提供的值应该满足您的应用程序的需求。

因此,如果您的应用程序需要识别所有产品价格 - 无论是CSS样式还是jQuery脚本或屏幕阅读器等等 - 使用product-prices的类属性来识别它们。

如果您的应用程序需要描述所有数值 - 再次,无论是CSS样式还是jQuery脚本或屏幕阅读器等等 - 使用类属性numeric识别它们。

PS Please don't call it the CSS class;简单地称它为“class属性”。除非你在Asp.NET中工作,否则没有CSS class这样的东西,甚至在Asp.NET中 - 也不应该有CSS class

抱歉我的网站有多个无耻的链接。

答案 4 :(得分:0)

我认为这是一种个人方法。 我也喜欢层次结构并使用很多。 但我最常使用实体变体,但尽量避免使用尽可能多的标记。 我使用的规则是标题总是与h1或h2一起使用。您可以在实体内进行相应的设计。 例如:

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

同样可以说导航:

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

有了这个说,我总是会说,选择标记最少的选项,而不会丢失你的概述。干净的代码很好。