我一直严重依赖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原则。

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

一些意识形态与上面的答案相悖,但一旦你知道如何以面向对象的方式构建CSS,你就会发现它实际上有助于保持代码的精简和平均。

这里的关键是在你的网站中识别“对象”或构建块模式,并使用它们进行架构。

Facebook聘请了OOCSS的创建者Nicole Sullivan,以节省大量的前端代码(HTML / CSS)。是的,你实际上可以得到节省,不仅在你的CSS,但在你的HTML太,这是由它的声音,是非常有可能为你,因为你提到转换一个基于表格的布局到很多div的

另一个很好的方法在某些方面与OOCSS类似,就是从一开始就计划和编写可伸缩和模块化的CSS。Jonathan Snook写了一本关于SMACSS的书/电子书——CSS的可伸缩和模块化架构

让我给你介绍一些链接: 海量CSS的5个错误-(视频) 海量CSS的5个错误(幻灯片) CSS膨胀-(幻灯片)

其他回答

很多时候,我看到有人把文件分成几个部分,在部分之间加上标题注释。

类似的

/* Headings and General Text */

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

/* Main page layout */

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

它工作得很好,可以让你很容易回头看看你正在做什么。

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

Write in SASS. You'd be insane to forego the advantages of variables, mixins, and so on. Never use an HTML ID for styling; always use classes. HTML IDs, when used correctly, appear only once in the whole page, which is the complete opposite of re-usability — one of the most basic goods in sensible engineering. Moreover, it's really hard to override selectors containing IDs and often the only way to overpower one HTML ID is to create another ID, causing IDs to propagate in the codebase like the pests they are. Better to leave the HTML IDs for unchanging Javascript or integration test hooks. Name your CSS classes by their visual function rather than by their application-specific function. For example, say ".highlight-box" instead of ".bundle-product-discount-box". Coding in this way means that you can re-use your existing style-sheets when you role out side-businesses. For example, we started out selling law notes but recently moved into law tutors. Our old CSS classes had names like ".download_document_box", a class name that makes sense when talking about digital documents but would only confuse when applied to the new domain of private tutors. A better name that fits both existing services — and any future ones — would be ".pretty_callout_box". Avoid naming CSS classes after specific grid information. There was (and still is) a dreadful anti-pattern in CSS communities whereby designers and creators of CSS frameworks (cough Twitter Bootstrap) believe that "span-2" or "cols-8" are reasonable names for CSS classes. The point of CSS is to give you the possibility to modify your design without affecting the markup (much). Hardcoding grids sizes into the HTML thwarts this goal, so it is advised against in any project expected to last longer than a weekend. More on how we avoided grid classes later. Split your CSS across files. Ideally you would split everything into "components"/"widgets" and then compose pages from these atoms of design. Realistically though, you'll notice that some of your website pages have idiosyncrasies (e.g. a special layout, or a weird photo gallery that appears in just one article). In these cases you might create a file related to that specific page, only refactoring into a full-blown widget when it becomes clear that the element will be re-used elsewhere. This is a tradeoff, one that is motivated by practical budgetary concerns. Minimise nesting. Introduce new classes instead of nesting selectors. The fact that SASS removes the pain of repeating selectors when nesting doesn't mean that you have to nest five levels deep. Never over-qualify a selector (e.g. don't use "ul.nav" where ".nav" could do the same job.) And don't specify HTML elements alongside the custom class name (e.g."h2.highlight"). Instead just use the class name alone and drop the base selector (e.g. the previous example should be ".highlight"). Over-qualifying selectors doesn't add any value. Create styles for HTML elements (e.g. "h1") only when styling base components which should be consistent in the whole application. Avoid broad selectors like "header ul" because it's likely that you have to override them in some places anyway. As we keep saying, most of the time you want to use a specific, well-named class whenever you want a particular style. Embrace the basics of Block-Element-Modifier. You can read about it for example on here. We used it quite lightly, but still it helped us a lot in organising CSS styles.

看一看 1. 萨斯 2. 指南针

不要用CSS写标题

只是将部分分割成文件。任何CSS注释,都应该是注释。

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

使用脚本将它们合并为一个;如果有必要的话)。您甚至还可以拥有一个漂亮的目录结构,只需让脚本递归地扫描.css文件。

如果你必须写标题,在文件的开头有一个TOC

TOC中的标题应该与您稍后编写的标题完全相同。搜索标题是件痛苦的事。更麻烦的是,人们怎么知道在第一个头文件之后还有另一个头文件呢?注:写toc时不要在每行开头加上类似doc的*(星号),这只会让选择文本变得更烦人。

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

使用规则或在规则内编写注释,而不是在块之外

首先,当您编辑脚本时,有50%的几率您会注意到规则块之外的内容(特别是如果它是一大块文本;))。其次,(几乎)不需要在外部添加“注释”。如果是在室外,那么99%的情况下都是游戏,所以保持这种状态。

将页面拆分为多个组件

组件应该有位置:相对的,没有填充和空白,大多数时候。这大大简化了%规则,并且允许更简单的元素的绝对:位置,因为如果有一个绝对定位的容器,绝对定位的元素将在计算上、右、下、左属性时使用容器。

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

组件也可以被认为是页面上的一个独立单元。用门外汉的话说,如果把一个东西当作一个黑盒是有意义的,那么就把它当作一个组件。

还是以QA页面为例:

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

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

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

例如,边框、边距和填充(但不包括轮廓)都会增加你要样式化的元素的尺寸和大小。

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/classes时,避免使用TAGs作为选择符

首先,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从一个div更改为一篇文章,那么您的风格就会中断。

或者如果你喜欢更清晰的表述:

#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属性是一个特殊的属性,只有应用于表时才有意义。如果.statistics不是一个表,它就不应该应用。

通用规则是邪恶的!

如果可以的话,避免编写通用的/神奇的规则 除非是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 .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;
}

复杂的“逻辑”评论不起作用:)

如果你这样写:“this value is dependent on blah-blah and height of blah-blah”,这是不可避免的,你会犯错误,它会像纸牌屋一样倒塌。

保持你的评论简单;如果你需要“逻辑操作”,考虑一种CSS模板语言,比如SASS或LESS。

我怎么写一个颜色托盘?

把这个留到最后。为你的整个色盘准备一个文件。如果没有这个文件,你的样式在规则中仍然有一些可用的颜色托盘。您的颜色托盘应该覆盖。你使用一个非常高级的父组件(例如。#page),然后把你的风格写成一个自给自足的规则块。它可以只是颜色或更多的东西。

eg.

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

这个想法很简单,你的颜色托盘是一个独立于基本样式的样式表,你可以级联到它。

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

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

我还发现简单单词的组合比一堆“合适”的长单词(postbody, posthead, userinfo等)更容易理解。

保持词汇量小,这样即使有陌生人进来阅读你的风格汤(比如几周后的你;)),只需要知道单词在哪里使用,而不是每个选择器在哪里使用。例如,每当一个元素被认为是“所选项目”或“当前项目”时,我就使用。this。

自己清理干净

写CSS就像吃东西,有时你会留下一团乱。确保您清理了这些混乱,否则垃圾代码就会堆积起来。删除你不使用的类/id。删除你不使用的CSS规则。确保一切都很好,你没有冲突或重复的规则。

如果您像我建议的那样,在您的风格中将一些容器视为黑盒(组件),在选择器中使用这些组件,并将所有内容保存在一个专用文件中(或使用TOC和头文件正确地分割为一个文件),那么您的工作基本上会更容易……

您可以使用工具,如firefox扩展Dust-Me Selectors(提示:指向您的sitemap.xml)来帮助您找到一些隐藏在css nukes和carnies中的垃圾。

保持一个未排序的。css文件

假设您正在设计一个QA站点,并且已经有了“答案页面”的样式表,我们将其称为answers.css。如果你现在需要添加很多新的css,将其添加到unsorted.css样式表中,然后重构到answers.css样式表中。

原因如下:

在完成之后进行重构更快,然后搜索规则(可能不存在)并注入代码 你会写一些你要删除的东西,注入代码只会让你更难删除这些代码 附加到原始文件很容易导致重复规则/选择器

这是一个非常好的问题。在我所看到的任何地方,CSS文件都倾向于在一段时间后失去控制——尤其是,但不仅仅是在团队中工作时。

以下是我自己努力遵守的规则(并不是说我总能做到)。

Refactor early, refactor often. Frequently clean up CSS files, fuse together multiple definitions of the same class. Remove obsolete definitions immediately. When adding CSS during fixing bugs, leave a comment as to what the change does ("This is to make sure the box is left aligned in IE < 7") Avoid redundancies, e.g. defining the same thing in .classname and .classname:hover. Use comments /** Head **/ to build a clear structure. Use a prettifier tool that helps maintain a constant style. I use Polystyle, with which I'm quite happy (costs $15 but is money well spent). There are free ones around as well (e.g. Code Beautifier based on CSS Tidy, an open-source tool). Build sensible classes. See below for a few notes on this. Use semantics, avoid DIV soup - use <ul>s for menus, for example. Define everything on as low a level as possible (e.g. a default font family, colour and size in the body) and use inherit where possible If you have very complex CSS, maybe a CSS pre-compiler helps. I'm planning to look into xCSS for the very same reason soon. There are several others around. If working in a team, highlight the necessity of quality and standards for CSS files as well. Everybody's big on coding standards in their programming language(s), but there is little awareness that this is necessary for CSS too. If working in a team, do consider using Version Control. It makes things that much easier to track, and editing conflicts that much easier to solve. It's really worth it, even if you're "just" into HTML and CSS. Do not work with !important. Not only because IE =< 7 can't deal with it. In a complex structure, the use of !important is often tempting to change a behaviour whose source can't be found, but it's poison for long-term maintenance.

构建合理的类

这就是我喜欢构建合理类的方式。

我首先应用全局设置:

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定制网站和/或应用程序的外观,这是一个很大的优势和节省时间。

If possible, give every page's body a unique class: <body class='contactpage'> this makes it very easy to add page-specific tweaks to the style sheet: body.contactpage div.container ul.mainmenu li { color: green } When building menus automatically, add as much CSS context as possible to allow extensive styling later. For example: <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> This way, every menu item can be accessed for styling according to its semantic context: Whether it's the first or last item in the list; Whether it's the currently active item; and by number.

请注意,如上例中所述的多个类的分配在IE6中不能正常工作。有一个变通方案可以使IE6能够处理多个类。如果没有解决方法,则必须设置对您来说最重要的类(项目编号、活动或第一个/最后一个),或者使用id。