管理CSS爆炸


682

我一直非常依赖CSS来开发我正在工作的网站。现在,所有CSS样式都在每个标记的基础上应用,因此现在我正尝试将其移至更多外部样式中,以帮助将来进行任何更改。

但是现在的问题是,我注意到我遇到了“ CSS爆炸”。对我来说,决定如何最好地组织和抽象CSS文件中的数据变得越来越困难。

我正在div从大量基于表格的网站中使用网站中的大量标签。因此,我得到了许多如下所示的CSS选择器:

div.title {
  background-color: blue;
  color: white;
  text-align: center;
}

div.footer {
  /* Styles Here */
}

div.body {
  /* Styles Here */
}

/* And many more */

还算不错,但是作为我的初学者,我想知道是否可以就如何最好地组织CSS文件的各个部分提出建议。我不想为网站上的每个元素都拥有单独的CSS属性,而且我一直希望CSS文件相当直观且易于阅读。

我的最终目标是简化CSS文件的使用,并展示它们增强Web开发速度的功能。这样,将来可能在该站点上工作的其他个人也将进入使用良好编码实践的实践中,而不必像我以前那样去实践。


122
这是一个很大的问题,但对于许多公司而言,这是一个真正无法解决的问题。主要是因为CSS正在编写和管理的平面设计师谁可能不知道的条款simplicitycomplexitymaintenancestructurerefactoring
cherouvim 2010年

8
@cherouvim-有趣的是,您应该这样说,因为我提出这个问题的全部理由都始于看到图形艺术家设计的一些可怕的CSS。也许我们需要为他们提供更好的培训?
JasCav 2010年

13
我的解决方案(在理想的世界中)是让团队中的专门人员将PSD切成html + css,然后进行维护。这些人应该靠近程序员和设计师。
cherouvim 2010年

@cherouvim必须同意-这几乎就是代理机构的发展方向,尤其是随着CSS变得越来越复杂。
约翰·帕克

27
@JasCav,图形艺术家不应该接触CSS。Web设计人员和前端Web开发人员应处理CSS。图形设计师的工作是制作图形。
zzzzBov 2011年

Answers:


566

这个问题问得好。在我所看到的所有地方,CSS文件都会在一段时间后失去控制,尤其是(但不仅限于)团队合作时。

以下是我本人想要遵守的规则(并非我总是设法做到)。

  • 尽早重构,经常重构。经常清理CSS文件,将同一类的多个定义融合在一起。立即删除过时的定义。

  • 在修复错误期间添加CSS时,请留意更改的内容(“这是为了确保该框在IE <7中保持对齐”)

  • 避免冗余,例如在.classname和中定义相同的内容.classname:hover

  • 使用注释/** Head **/来构建清晰的结构。

  • 使用有助于保持风格不变的修饰工具。我使用Polystyle,对此我很满意(花费15美元,但花得不错)。也有免费的(例如,基于CSS Tidy的Code Beautifier,一个开放源代码工具)。

  • 建立明智的课程。请参阅下面的一些注意事项。

  • 使用语义,避免DIV汤- <ul>例如,将s用于菜单。

  • 在尽可能低的级别上定义所有内容(例如,中的默认字体系列,颜色和大小body),并inherit在可能的情况下使用

  • 如果您有非常复杂的CSS,则CSS预编译器可能会有所帮助。我正计划出于同样的原因研究xCSS。周围还有其他几个。

  • 如果是团队合作,请同时强调CSS文件的质量和标准。每个人都非常重视其编程语言的编码标准,但是很少有人意识到这对于CSS也是必要的。

  • 如果是团队合作,考虑使用版本控制。它使事情更容易跟踪,而编辑冲突也更容易解决。即使您只是“简单”地学习HTML和CSS,这也确实值得。

  • 请勿使用!important。不仅因为IE = <7无法处理它。在复杂的结构中,!important经常会使用来更改无法找到其来源的行为,但这是长期维护的毒药

建立明智的班级

这就是我喜欢建立明智的班级的方式。

我首先应用全局设置:

body { font-family: .... font-size ... color ... }
a { text-decoration: none; }

然后,我确定页面布局的主要部分,例如顶部区域,菜单,内容和页脚。如果我编写了不错的标记,那么这些区域将与HTML结构相同。

然后,我开始构建CSS类,在合理的范围内尽可能多地指定祖先,并尽可能地将相关类分组。

div.content ul.table_of_contents 
div.content ul.table_of_contents li 
div.content ul.table_of_contents li h1
div.content ul.table_of_contents li h2
div.content ul.table_of_contents li span.pagenumber

将整个CSS结构视为一棵具有越来越具体定义的,离您的根越远。您希望保持尽可能少的类数,并且希望尽可能少地重复自己。

例如,假设您具有三个级别的导航菜单。这三个菜单看起来不同,但是它们也具有某些特征。例如,它们都是<ul>,它们的字体大小都相同,并且所有项目彼此相邻(与的默认呈现相反ul)。此外,所有菜单都没有任何项目符号(list-style-type)。

首先,在名为的类中定义通用特征menu

div.navi ul.menu { display: ...; list-style-type: none; list-style-image: none; }
div.navi ul.menu li { float: left }

然后,定义三个菜单中每个菜单的特定特征。级别1高40像素;2和3级,20像素。

注意:您也可以为此使用多个类,但是Internet Explorer 6的多个类存在问题,因此本示例使用id

div.navi ul.menu#level1 { height: 40px; }
div.navi ul.menu#level2 { height: 20px; }
div.navi ul.menu#level3 { height: 16px; }

菜单的标记如下所示:

<ul id="level1" class="menu"><li> ...... </li></ul>
<ul id="level2" class="menu"><li> ...... </li></ul>
<ul id="level3" class="menu"><li> ...... </li></ul>

如果您在页面上具有语义上相似的元素(例如这三个菜单),请尝试首先计算出共同点,然后将它们放入类中;然后,计算出特定的属性并将其应用于类,或者,如果必须支持Internet Explorer 6,则将其应用于ID。

其他HTML技巧

如果将这些语义添加到HTML输出中,则设计人员以后可以使用纯CSS自定义网站和/或应用程序的外观,这是一个很大的优势,可以节省时间。

  • 如果可能的话,给每个页面的主体一个唯一的类:<body class='contactpage'>这使得在样式表中添加特定于页面的调整非常容易:

    body.contactpage div.container ul.mainmenu li { color: green }
  • 自动构建菜单时,请添加尽可能多的CSS上下文,以便以后进行广泛的样式设置。例如:

    <ul class="mainmenu">
     <li class="item_first item_active item_1"> First item </li> 
     <li class="item_2"> Second item </li> 
     <li class="item_3"> Third item </li> 
     <li class="item_last item_4"> Fourth item </li> 
    </ul>

    这样,每个菜单项都可以根据其语义上下文进行样式设置:无论是列表中的第一项还是最后一项;是否为当前活动项目;和数字。

请注意,上面示例中概述的这种分配多个类在IE6中无法正常工作。有一种解决方法可以使IE6能够处理多个类。如果无法解决,则必须设置对您来说最重要的类(项目编号,使用中的或第一个/最后一个),或者使用ID。


3
@Andrew主要是因为在动态环境(例如CMS)中使用ID可能会轻易导致冲突(例如,用户将页面重命名为“ contact”,从而导致该名称被用作主体的ID,从而与联系表发生冲突)也称为“联系人”)。因此,我通常建议尽量少使用ID。
Pekka 2010年

4
@Pekka,您应该访问www.oocss.org,这与您在这里提到的内容大相径庭,但这是我见过的管理CSS膨胀的最好方法。见我的回答如下太:stackoverflow.com/questions/2253110/how-to-manage-css-explosion/...
莫恩扎曼

2
@山姆,谢谢!我喜欢它的相当不错,虽然我偶尔发现这些准则非常难以遵循自己。CSS样式表是如此容易随着时间的推移搞砸了-颜色变化在这里是font-weight: bold有....纪律是唯一的药:)
佩卡·

1
作为“ css爆炸”研究的新手,“独特的阶级”一词令人困惑。我感觉那不是一个,id但听起来确实像一个。也许可以澄清这个概念?
阿里·金

2
@ari你是对的,从技术上讲也可以是id
Pekka

89

这只是4个示例:

在所有4个问题上,我的答案都包括下载和阅读Natalie Downe的PDF CSS Systems的建议。(PDF包含大量不在幻灯片中的注释,因此请阅读PDF!)。注意她对组织的建议。

四年后编辑(2014/02/05),我会说:

  • 使用CSS预处理器并将文件作为部分文件进行管理(我个人更喜欢Sass和Compass,但是Less也很不错,还有其他功能)
  • 阅读有关OOCSSSMACSSBEMgetbem的概念
  • 看一下BootstrapZurb Foundation等流行的CSS框架的结构。并且不要打折不太流行的框架- 因纽特人是一个有趣的框架,但还有很多其他框架。
  • 在持续集成服务器和/或诸如Grunt或Gulp之类的任务运行器上,通过构建步骤来组合/缩小文件。

CSS预处理程序是问题的原因,而不是解决方案。真正掌握级联概念,您将减少膨胀。
Daniel Sokolowski

@DanielSokolowski任何不正确使用的工具可能是问题而不是解决方案。但是100%的人同意掌握级联的观点。
安迪·福特

73

不要在CSS中写标题

只需将部分拆分为文件。任何CSS注释都应该是注释。

reset.css
base.css
somepage.css
someotherpage.css
some_abstract_component.css

使用脚本将它们组合为一个;如有必要。您甚至还可以拥有一个不错的目录结构,只需让您的脚本以递归方式扫描.css文件即可。

如果必须写标题,请在文件开头添加目录

TOC中的标题应与您稍后编写的标题完全相同。搜索标题很痛苦。更麻烦的是,有人究竟想知道您在第一个标头之后还有另一个标头吗?ps。编写TOC时,不要在每行的开头添加类似doc的*(星号),这只会使选择文本更加麻烦。

/* Table of Contents
   - - - - - - - - -
   Header stuff
   Body Stuff
   Some other junk
   - - - - - - - - -
 */
...
/* Header Stuff 
 */
...
/* Body Stuff 
 */

在规则内或规则内(而不是在块外)编写注释

首先,当您编辑脚本时,您有50/50的机会会注意规则块之外的内容(尤其是在一大堆文本中);)。其次,(几乎)在任何情况下,您都不需要外部“评论”。如果它在外面,则是99%的时间是标题,因此应保持该标题不变。

将页面拆分为组件

大多数情况下position:relative,组件应具有no padding和no margin。这简化%原则很多,以及允许更简单的absolute:position“荷兰国际集团的元素,因为如果有一个绝对定位的容器绝对定位的元素将计算时所使用的容器toprightbottomleft的属性。

HTML5文档中的大多数DIV通常是一个组件。

组件也是可以视为页面上的独立单元的东西。用外行的话来说,如果把像黑匣子这样的东西当作有意义的东西对待就好了。

再次使用“质量检查”页面示例:

#navigation
#question
#answers
#answers .answer
etc.

通过将页面拆分为组件,您可以将工作拆分为可管理的单元。

将具有累积效果的规则放在同一行上。

例如bordermarginpadding(但不是outline全部)会增加您要设置样式的元素的尺寸和大小。

position: absolute; top: 10px; right: 10px;

如果它们在一行上不那么可读,则至少将它们靠近:

padding: 10px; margin: 20px;
border: 1px solid black;

尽可能使用速记:

/* the following... */
padding-left: 10px;
padding-right: 10px;
/* can simply be written as */
padding: 0 10px;

切勿重复选择器

如果您有更多相同选择器的实例,那么您很有可能最终会遇到相同规则的多个实例。例如:

#some .selector {
    margin: 0;
    font-size: 11px;
}
...
#some .selector {
    border: 1px solid #000;
    margin: 0;
}

当您可以使用ID /类时,避免使用TAG作为选择器

首先,DIV和SPAN标签是个例外:永远不要使用它们!;)仅使用它们附加一个类/ ID。

这个...

div#answers div.answer table.statistics {
    border-collapse: collapsed;
    color: pink;
    border: 1px solid #000;
}
div#answers div.answer table.statistics thead {
    outline: 3px solid #000;
}

应该这样写:

#answers .answer .statistics {
    border-collapse: collapsed;
    color: pink;
    border: 1px solid #000;
}
#answers .answer .statistics thead {
    outline: 3px solid #000;
}

因为那里有多余的悬挂DIV,所以对选择器没有任何作用。它们还会强制执行不必要的标签规则。如果你要改变,例如,.answer从一个divarticle你的风格将打破。

或者,如果您希望更清晰:

#answers .answer .statistics {
    color: pink;
    border: 1px solid #000;
}
#answers .answer table.statistics {
    border-collapse: collapsed;
}
#answers .answer .statistics thead {
    outline: 3px solid #000;
}

原因是该border-collapse属性是一个特殊属性,仅当应用于时才有意义table。如果.statistics不是table,则不适用。

通用规则是邪恶的!

  • 如果可以,请避免编写通用/魔术规则
  • 除非用于CSS重置/取消重置,否则所有通用魔术都应至少应用于一个根组件

它们没有节省您的时间,却使您的头部爆炸。并使维护成为一场噩梦。当您编写规则时,您可能会知道它们的适用位置,但这并不能保证您的规则以后不会惹您。

加上这些通用规则,即使您对文档的样式有所了解,也难以理解且难以理解。这并不是说您不应该编写通用规则,除非您真正打算使它们通用,否则不要使用它们,甚至它们会向选择器中添加尽可能多的作用域信息。

像这样的东西

.badges {
    width: 100%;
    white-space: nowrap;
}

address {
    padding: 5px 10px;
    border: 1px solid #ccc;
}

...具有与在编程语言中使用全局变量相同的问题。您需要给他们范围!

#question .userinfo .badges {
    width: 100%;
    white-space: nowrap;
}

#answers .answer .userinfo address {
    padding: 5px 10px;
    border: 1px solid #ccc;
}

基本上是这样的:

components                   target
---------------------------- --------
#answers .answer   .userinfo address
-------- --------- --------- --------
domain   component component selector 

每当我知道的组件是页面上的单个组件时,我都喜欢使用ID。您的需求可能有所不同。

注意:理想情况下,您应该编写足够的内容。与提及较少的组件相比,在选择器中提及更多的组件是更宽容的错误。

假设您有一个pagination组件。您可以在网站的许多地方使用它。这将是编写通用规则时的一个很好的例子。假设您display:block为各个页码链接设置了深灰色背景。为了使它们可见,您必须具有以下规则:

.pagination .pagelist a {
    color: #fff;
}

现在假设您使用分页获取答案列表,则可能会遇到类似这样的情况

#answers .header a {
    color: #000;
}
...
.pagination .pagelist a {
    color: #fff;
}

这会使您的白色链接变黑,这是您不需要的。

解决该问题的不正确方法是:

.pagination .pagelist a {
    color: #fff !important;
}

解决该问题的正确方法是:

#answers .header .pagination .pagelist a {
    color: #fff;
}

复杂的“逻辑”注释不起作用:)

如果您写这样的东西:“此值取决于blah-blah加上blah-blah的高度”,那么不可避免的是您会犯错,并且它们都会像纸牌屋一样掉下来。

保持您的评论简单;如果需要“逻辑运算”,请考虑使用CSS模板语言之一,例如SASSLESS

我该如何写一个彩色托盘?

最后结束。为您的整个彩色托盘准备一个文件。没有此文件,您的样式在规则中仍应具有一些可用的调色板。您的颜色托盘应覆盖。您可以使用非常高级的父级组件(例如#page)来链接选择器,然后将样式编写为自足的规则块。它可以只是颜色或更多。

例如。

#page #header .description,
#page #categories .description,
#page #answers .answer .body
{
    color: #222; background: #fff; 
    border-radius: 10px;
    padding: 1em;
}

这个想法很简单,您的调色板是独立于基本样式的样式表,您可以将其层叠成样式。

更少的名称,需要更少的内存,使代码更易于阅读

使用较少的名称更好。理想情况下,使用非常简单(且简短!)的单词:文本,正文,标题。

我还发现,简单单词的组合比较容易理解,然后加上一长串“适当的”单词:postbody,posthead,userinfo等。

即使某些陌生人进来阅读您的风格汤(像几周后;就像您自己一样;)),也应使词汇量保持较小,只需要了解用词的位置而不是使用每个选择器的位置。例如,.this每当一个元素被认为是“所选项目”或“当前项目”等时,我就使用。

自己清理一下

编写CSS就像吃东西,有时会留下一团糟。确保清理混乱,否则垃圾代码将堆积。删除不使用的类/标识。删除不使用的CSS规则。确保一切都很好,并且您没有冲突或重复的规则。

如果您按照我的建议将某些容器视为样式中的黑盒(组件),在选择器中使用了这些组件,并将所有内容保存在一个专用文件中(或使用TOC和标头正确分割了一个文件),那么您的工作实质上更容易...

您可以使用诸如firefox扩展名Dust-Me Selectors(提示:将其指向您的sitemap.xml)之类的工具来帮助您找到一些隐藏在CSS核武器和狂欢者中的垃圾。

保留unsorted.css档案

假设您正在对质量检查网站进行样式设置,并且已经有了“答案页面”的样式表,我们将其称为answers.css。如果现在需要添加很多新的CSS,请将其添加到unsorted.css样式表中,然后将其重构到answers.css样式表中。

原因如下:

  • 完成后重构的速度更快,然后就是搜索规则(可能不存在)并注入代码
  • 您将编写要删除的内容,注入代码只会使删除该代码更加困难
  • 附加到原始文件很容易导致规则/选择器重复

1
非标签选择器要比基于标签的选择器慢得多。所有浏览器都有本机方法来获取例如“ div”(或任何其他标签)。如果让它过于通用('.class'),则呈现引擎将不得不遍历DOM的所有元素以查看是否存在匹配项。
Miguel Ping

@Miguel为什么渲染引擎不必遍历DOM中的所有元素以查看它们是否为DIV?如果有一些特殊的优化,为什么不将其应用于类/ id?你有资源吗?我用CSS注意到的唯一可见的性能杀手是浮动垃圾邮件-滚动页面时,它可能导致渲染引擎在某些浏览器上严重滞后(可能是太多的计算)。
srcspider 2011年

3
我本打算投票反对说不以tagNames为目标(是的!),但是其中一部分涉及不通用的问题(嘘!)
mwilcox

1
@Miguel,这种方式行不通。浏览器向后读取CSS字符串,因此它将采用:“ div .myclass”并找到所有“ .myclass”类,然后检查它是否是div的祖先。
mwilcox 2011年

5
将通用规则与全局变量进行比较是我听说过的关于CSS的最大误解。
gblazex 2011年

55

看看1. SASS 2. 指南针


11
一百万倍。使用Sass使我比以往任何时候都更有组织,更强大的CSS牧马人。它让我组织方式在多个文件中,巢风格,使用变量,等等,等等,等等
阿伦H.

2
麻烦,指南针和其他所有东西最终都会产生正常的CSS,但它们仍然可能丑陋且爆炸。它本身并不是CSS膨胀的解决方案。
Moin Zaman

8
@Moin_Zaman,我的拙见,先生,您的说法纯属虚构。您用sass / compass / less编写代码,并在其文件中组织代码。您不必担心输出CSS的外观。同样,至少减少(通过更少的应用程序)可以减少输出,这是很好的。
2011年

1
@bzx证明了我的意思:)浏览器不理解sass / compass / less。所有这些都需要在客户端或作为构建的一部分编译为普通的旧CSS。使用这样的工具而最终不知道它们作为CSS会产生什么,这使得很容易在不知不觉中滥用它们并最终获得比最佳CSS文件更大的文件。
Moin Zaman

那就是gzip压缩发挥作用的地方…大多数Web服务器和浏览器将在可能的情况下与gzip压缩的内容进行通信。如果最终多次重复选择器片段,则将其压缩到单个哈希表条目中。唯一真正的问题是解析浏览器中的CSS规则所需的RAM数量。
第三方2013年

31

我见过的应对CSS膨胀的最佳方法是使用面向对象的CSS原则。

甚至还有一个非常好的OOCSS框架。

某些思想与上面最佳答案中提到的许多CSS观点背道而驰,但是一旦您知道如何以面向对象的方式进行架构,您就会发现它实际上在保持代码精简和卑鄙的方面起作用。

这里的关键是识别站点中的“对象”或构建模块模式,并与它们一起设计。

Facebook聘请了OOCSS的创建者Nicole Sullivan,以节省大量前端代码(HTML / CSS)。是的,你可以真正得到节省,不仅在你的CSS,但在你的HTML太多,它通过它的声音,很可能就是你,你提一个转换table基于布局投入了大量div

另一个很棒的方法在某些方面与OOCSS类似,它是从一开始就计划和编写CSS以便使其具有可伸缩性和模块化。乔纳森· 斯努克(Jonathan Snook)SMACSS-CSS的可扩展和模块化体系结构做了出色的写作和书籍/电子书

让我为您提供一些链接:
大型CSS的5个错误-(视频)
大型CSS的5个错误-(幻灯片)
CSS膨胀-(幻灯片)


16

您还应该了解级联,重量以及它们如何工作。

我注意到您仅使用类标识符(div.title)。您是否知道您也可以使用ID,并且ID的权重比班级高?

例如,

#page1 div.title, #page1 ul, #page1 span {
  // rules
}

将使所有这些元素共享字体大小(例如颜色)或任何规则。您甚至可以使所有属于#page1后代的DIV获得某些规则。

至于重量,请记住CSS轴从最通用/最轻到最特定/最重。也就是说,在CSS选择器中,元素说明符被类说明符推翻,而ID说明符则被元素说明符推翻。数字很​​重要,因此具有两个元素说明符(ul li)的选择器比仅具有单个说明符(li)的选择器具有更大的权重。

认为它像数字。“ 1”列中的9仍然小于“十”列中的1。具有ID说明符,类说明符和两个元素说明符的选择器比没有ID,500个类说明符和1,000个元素说明符的选择器具有更大的权重。当然,这是一个荒谬的例子,但是您明白了。关键是,应用此概念可帮助您清理大量CSS。

顺便说一句,除非您与具有class =“ title”的其他元素发生冲突,否则不必将元素说明符添加到类(div.title)中。请勿添加不必要的重量,因为您稍后可能需要使用该重量。


就像在Visual Basic代码中使用全局变量一样,使用ID也很糟糕。
羊驼

2
@alpav:对不起,那是不对的。ID是一种极好的方式,可以使相似的元素在页面的不同部分以不同的方式显示,而不必费力地组成新的类名。
Robusto 2010年

@Robusto:为什么要创建新的ID名称比创建新的类名称要难?
羊驼

@Robusto:创建新的类名实际上比使用ID名要容易,因为使用ID时,您不必担心全局范围,而使用类名时,则只需担心局部范围的唯一性,这与局部变量的好处相同。
羊驼

1
@alpav“这违反了封装的目的-能够在本地命名而无需全局考虑。” 是的,但是CSS选择器本质上是全局的:编写时.myclass,您可以使用class选择所有内容myclass。在CSS中,类在这方面与id相同。
Paul D. Waite,2010年

12

我可以建议更少的CSS动态框架

它类似于前面提到的SASS。

它有助于维护每个父类的CSS。

例如

 #parent{     
  width: 100%;

    #child1
    {    
     background: #E1E8F2;    
     padding: 5px;    
    }

    #child2
   {
     background: #F1F8E2;
     padding: 15px
   }
 }

它的作用:将宽度:100%应用于#child1和#child2。

同样,#child1特定的CSS属于#parent。

这将导致

#parent #child1
{
 width: 100%;
 background: #E1E8F2;
 padding: 5px;
}

#parent #child2
{
 width: 100%;
 background: #F1F8E2;
 padding: 15px;
}

1
我使用sass,这可能是sass和更少之间的区别,但是我很确定它将编译为`#parent {width:100%; } #parent#child1 {背景:#E1E8F2; 填充:5px;} #parent#child2 {背景:#F1F8E2; 填充:15px; }
emik 2013年

12

我发现困难的是将网站所需的设计转换为一系列规则。如果站点的设计清晰且基于规则,那么您的类名和CSS结构就可以从中得到。但是,如果人们随着时间的推移在站点中随机添加一些没有多大意义的内容,那么CSS中就无能为力了。

我倾向于这样组织我的CSS文件:

  1. CSS重置,基于Eric Meyer的。(因为否则我发现,对于大多数元素而言,我至少有一个或两个规则只是在重置默认浏览器样式-例如,我的大多数列表看起来都不像列表的默认HTML样式。)

  2. 网格系统CSS(如果站点需要)。(我基于960.gs

  3. 在每个页面上显示的组件的样式(页眉,页脚等)

  4. 在网站的各个地方使用的组件的样式

  5. 仅在个别页面上相关的样式

如您所见,大部分取决于站点的设计。如果设计清晰,有条理,则可以使用CSS。如果没有,那你就被搞砸了。


7

我的回答是高层的,以解决您在问题中提出的高层问题。可能会有一些低级的组织技巧和调整,可以使其更漂亮,但是这些都不能解决方法上的缺陷。有几件事会影响CSS爆炸。显然,网站的整体复杂性还包括命名语义,CSS性能,CSS文件组织以及可测试性/可接受性。

您似乎在使用命名语义的道路上走了一条正确的道路,但是可以采取进一步的措施。在网站上重复出现而未经结构修改的HTML部分(称为“模块”)可以视为选择器根目录,从那里您可以确定相对于该根目录的内部布局的范围。这是面向对象CSS的基本原则,您可以在Yahoo工程师的本次演讲中阅读/观看有关它的更多内容

重要的是要注意,这种干净的方法可能与性能问题相反,后者倾向于基于id或tag name的短选择器。找到平衡点取决于您,但是除非您拥有庞大的网站,否则这仅是您脑海中的一个指南,提醒您保持选择器简短。 有关性能的更多信息

最后,您要在整个网站上使用单个CSS文件,还是使用多个文件(用于每个页面或-section文件的单个基本文件)?单个文件具有更好的性能,但可能难以理解/与多个团队成员进行维护,并且可能更难以测试。对于测试,我建议您有一个CSS测试页面,其中包含每个受支持的CSS模块,以测试碰撞和意外的级联。

或者,您可以采用多种文件方式,将CSS规则的范围限定为页面或部分。这需要浏览器下载多个文件,这是性能问题。您可以使用服务器端编程来动态指定CSS文件并将它们聚合(和缩小)为单个文件。但是由于这些文件是分开的,并且针对它们的测试也将是分开的,所以您会引入跨页面/节外观不一致的可能性。因此测试变得更加困难。

由您来分析客户的特定需求,并相应地平衡这些问题。


5

正如我之前所说:进入OOCSS。Sass / Less / Compass很诱人,但是直到使用正确的CSS CSS为止,Sass / Less / Compass只会使情况变得更糟。

首先,了解高效的CSS。尝试使用Google Page Speed,并阅读Souders关于高效CSS的文章。

然后,输入OOCSS。

  • 学习如何使用级联。(毕竟,我们称其为“ 层叠样式表”)。
  • 了解如何正确设置粒度(自下而上,而不是自上而下)
  • 了解如何分离结构和皮肤(什么是独特的,这些对象有什么变化?)
  • 了解如何分隔容器和内容。
  • 学会爱网格。

它将彻底改变有关编写CSS的每一点。我完全被更新并喜欢它。

更新:SMACSS与OOCSS相似,但从总体上讲更易于适应。


2
“省/少/指南针只会使事情变得更糟”-那是相当主观的,并且取决于项目。我会提出,将其中之一与OOCSS结合使用确实会有益于许多大型项目的可维护性(特别是那些样式可能经常更改的项目)
Zach Lysobey

Zach L:正确使用的OOCSS(或SMASMA)仅使供应商前缀需要Compass / Less / Sass。
madr

我不会试图对此争论太多(特别是因为我目前不使用预处理器),但是我敢肯定,有很多人确实认为这样的事情很有用,即使是结合使用在供应商前缀问题之外使用OOCSS / SMACSS
Zach Lysobey

4

明智的CSS的核心原理,摘自CSS重构:从仅追加到模块化CSS

用SASS编写。您会疯狂地放弃变量,mixin等的优势。

切勿使用HTML ID进行样式设置;总是使用类。如果正确使用HTML ID,则在整个页面中仅出现一次,这与可重用性完全相反,可重用性是明智工程中最基本的产品之一。此外,要覆盖包含ID的选择器确实非常困难,通常,压倒一个HTML ID的唯一方法是创建另一个ID,从而导致ID像有害生物一样在代码库中传播。最好保留HTML ID以保持不变的Javascript或集成测试挂钩。

通过视觉功能而不是特定于应用程序的功能来命名CSS类。例如,说“ .highlight-box”而不是“ .bundle-product-discount-box”。以这种方式进行编码意味着您在担当副业时可以重新使用现有的样式表。例如,我们开始出售法律笔记,但最近又转为法律辅导员。我们以前的CSS类的名称类似于“ .download_document_box”,该类名称在谈论数字文档时很有意义,但仅在应用于新的私人家教领域时才会引起混淆。既适合现有服务,又适合将来的服务的更好的名称是“ .pretty_callout_box”。

避免在特定的网格信息之后命名CSS类。CSS社区曾经(现在仍然是)可怕的反模式,CSS框架的设计者和创建者(咳嗽Twitter Bootstrap)认为“ span-2”或“ cols-8”是CSS类的合理名称。CSS的要点是使您可以修改设计而不影响标记(很多)。将网格大小硬编码为HTML会阻碍此目标,因此在任何预期持续时间超过周末的项目中均建议不要这样做。有关稍后如何避免网格类的更多信息。

在文件之间拆分CSS。理想情况下,您将所有内容分解为“组件” /“小部件”,然后由这些设计原子组成页面。但实际上,您会注意到您的某些网站页面具有特质(例如,一种特殊的布局或仅出现在一篇文章中的怪异的照片库)。在这些情况下,您可能会创建一个与该特定页面相关的文件,只有在该元素将在其他地方重新使用时,才将其重构为一个成熟的小部件。这是一种折衷,这是由实际预算问题引起的。

最小化嵌套。介绍新的类,而不是嵌套选择器。SASS消除了嵌套时重复选择器的麻烦,但这并不意味着您必须嵌套五个级别。切勿过度限定选择器的资格(例如,不要使用“ .nav”可以做同样工作的“ ul.nav”。)也不要在自定义类名称旁边指定HTML元素(例如“ h2.highlight”)。相反,仅使用类名并删除基本选择器即可(例如,前面的示例应为“ .highlight”)。合格的选择器不会增加任何价值。

仅在设计基本组​​件的样式时才为HTML元素(例如“ h1”)创建样式,这些样式在整个应用程序中应保持一致。 避免使用诸如“ header ul”之类的广泛选择器,因为无论如何,您可能必须在某些地方覆盖它们。就像我们一直说的,大多数时候,只要您想使用特定的样式,就希望使用特定的,命名良好的类。

拥抱Block-Element-Modifier的基础知识。您可以在此处阅读有关示例。我们很少使用它,但是它仍然在组织CSS样式方面提供了很多帮助。


2

很多时候,我会看到个人将文件分成几部分,并在各部分之间添加标题注释。

就像是

/* Headings and General Text */

.... stuff here for H1, etc..

/* Main page layout */

.... stuff here for layout page setup etc.

它工作得很好,可以很容易地稍后返回并找到您正在处理的内容。


这并没有说明问问者对“每件事都有单独的CSS属性”的关注。
G-Wiz 2010年

1

您应该看一下BEM

理论

BEM试图提供一组用于组织和命名css选择器的指令,以使事物更可重用和模块化,并避免那种选择器之间的冲突(这常常导致意大利面条式代码和特定性问题)。

正确使用它实际上会产生一些非常积极的影响。

  • 将样式添加到元素时,样式可以满足您的期望
  • 样式不会泄漏,只会影响添加到样式中的内容
  • 样式与文档结构完全脱钩
  • 无需强迫样式相互替代

BEM与SASS完美结合,为CSS带来了几乎面向对象的样式。您可以构建模块化文件,该文件处理单个UI元素的显示并包含变量,例如颜色和“方法”,例如内部元素的处理方式。尽管一个顽固的OO程序员可能不赞成这种想法,但实际上,所应用的概念带来了OO结构的许多更好的部分,例如模块化,松耦合和紧密的内聚以及上下文无关的可重用性。您甚至可以通过使用Sass和操作&以看起来像封装对象的方式进行构建

您可以在此处找到 Smashing Magazine上更深入的文章;CCS Wizardry的哈里·罗伯茨(Harry Roberts)的一本书(涉及css的任何人都应该读过)在这里

在实践中

我已经使用过几次,并且使用过SMACSS和OOCSS,这也意味着我也可以进行比较。我也曾在一些大混乱中工作,通常是我自己没有经验的创作。

当我在现实世界中使用BEM时,我会通过一些额外的原则来扩充该技术。我利用实用程序类-一个很好的例子是包装器类:

.page-section {
    width: 100%;
}
@media screen and (min-width: 1200px) {
    margin: 0 auto;
    width: 1200px;
}

而且我在某种程度上也依赖于级联和特异性。在这里,BEM模块将是,.primary-box而这.header将是特定替代的上下文

.header {
  .primary-box {
    color: #000;
  }
}

(我尽力使所有内容尽可能地通用和上下文无关,这意味着一个好的项目几乎所有内容都在可重用的模块中)

我在这里要说的最后一点是,无论您的项目多么小而复杂,您都应该从一开始就这样做,这有两个原因:

  • 项目的复杂性增加,因此奠定良好的基础非常重要,包括CSS
  • 即使是看起来很简单的项目,因为它是基于WordPress构建的,JavaScript却很少,而CSS中的代码仍然非常复杂-好的,您不必进行任何服务器端编码,因此这部分很简单,但是宣传册的前端有二十个模块,每个都有三个变体:您在那里有一些非常复杂的CSS!

Web组件

在2015年,我们开始研究Web组件。我还不了解这些,但是它们希望将所有前端功能整合到独立的模块中,有效地尝试将BEM的各种原理应用于整个前端,并分散但完全耦合地进行组件化都构建相同的UI小部件的DOM片段,Js(MVC)和CSS之类的元素。

通过这样做,他们将解决css所存在的一些原始问题,我们已经尝试使用BEM解决这些问题,同时使其他一些前端体系结构更加理智。

这里有一些进一步的阅读,这里还有一个Polymer框架,非常值得一看

最后

我还认为这是一本优秀的,现代的最佳实践CSS指南 -专为阻止大型CSS项目变得混乱而设计。我尝试遵循其中的大多数。



0

这里有一些很棒的材料,有些花了一些时间来回答这个问题,但是当涉及到单独的样式表或单独的样式表时,我将使用单独的文件进行开发,然后将所有用于站点的通用css合并到一起部署时将其合并为一个文件。

这样,您就可以兼得两全其美,提高了性能(减少了从浏览器请求的HTTP请求),并且在开发时分离了代码问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.