协慌网

登录 贡献 社区

管理 CSS 爆炸

我一直在严重依赖 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 开发速度的力量。这样,将来可能在此站点上工作的其他个人也将参与使用良好编码实践的实践,而不必像我以前那样去实践。

答案

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

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

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

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

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

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

  • 使用有助于保持样式不变的修饰工具。我使用Polystyle ,我很高兴(售价 15 美元,但花得很值)。也有免费的(例如,基于CSS Tidy 的Code Beautifier ,一个开放源代码工具)。

  • 建立明智的课程。有关此的一些注意事项,请参见下文。

  • 使用语义,避免 DIV 汤 - 例如,对菜单<ul>

  • 在尽可能低的级别上定义所有内容(例如,默认字体系列, 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。

这只是 4 个示例:

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

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

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

不要在 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 ,没有padding ,也没有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,所以对选择器没有任何作用。它们还会强制执行不必要的标签规则。例如,如果您将.answerdiv更改为article样式会中断。

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

#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每当一个元素被认为是 “所选项目” 或 “当前项目” 等时,我都使用. this。

自己清理一下

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

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

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

保留unsorted.css文件

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

造成这种情况的几个原因:

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