我一直非常依赖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开发速度的能力 . 这样,将来可能在这个网站上工作的其他人也将进入使用良好编码实践的实践,而不是像我那样采取它 .
15 回答
合理CSS的核心原则,摘自CSS Refactoring: From append-only to modular CSS
看看1. SASS 2. Compass
你应该看 BEM .
Theory
BEM试图提供一组用于组织和命名css选择器的指令使事物更易于使用和模块化,并避免选择器之间的冲突,这通常会导致意大利面条代码和特殊性问题 .
当它正确使用时,它实际上有一些非常积极的效果 .
样式在添加到元素时执行您期望的操作
样式没有't leak and effect only what they'重新加入
样式与文档结构完全分离
样式不需要被迫相互覆盖
BEM与SASS配合使用可为CSS带来几乎面向对象的风格 . 您可以构建模块化文件,这些文件处理单个UI元素的显示并包含变量,例如颜色和'methods',例如如何处理内部元素 . 事实上,虽然硬核OO程序员可能会对这个想法不以为然,但应用概念带来了OO结构的许多更好的部分,例如模块化,松散耦合和紧密内聚以及无上下文的可重用性 . 您甚至可以使用Sass and the & operato r以类似于封装对象的方式构建 .
来自Smashing Magazine的更深入的文章可以是found here;还有一个来自CCS Wizardry的Harry Roberts(任何参与css的人都应该阅读)is here .
In Practice
我已经多次使用过这个,并且使用过SMACSS和OOCSS意味着我也有一些东西可以比较它们 . 我也经历过一些大的混乱,通常是我自己的,没有经验的创造 .
当我在现实世界中使用BEM时,我用一些额外的原则来增强技术 . 我使用实用程序类 - 一个很好的例子是包装类:
我也在某种程度上依赖于级联和特异性 . 这里BEM模块将是
.primary-box
而.header
将是特定覆盖的上下文(我尽最大努力使一切尽可能通用和无上下文,这意味着一个好项目几乎所有东西都在可重复使用的模块中)
我在这里要做的最后一点是,无论你的项目是多么小而且不复杂,你应该从一开始就这样做,原因有两个:
项目的复杂性增加,因此奠定良好的基础非常重要,包括css
即使是一个看起来很简单的项目,因为它必须进行任何服务器端编码,因此该部分很简单,但是宣传册穿戴前端有20个模块,每个模块有三个变体:你有一些非常复杂的css !
Web Components
2015年,我们开始关注Web组件 . 我对这些内容还不太了解,但他们希望将所有前端功能集中在自包含的模块中,有效地尝试将BEM的各种原则应用到整个前端,并且组件分散但完全耦合DOM片段,Js(MVC)和CSS等元素都构建了相同的UI小部件 .
通过这样做,他们将解决css中存在的一些原始问题,我们试图用BEM之类的东西来解决这些问题,同时让一些其他前端架构更加清晰 .
还有一些进一步阅读here以及一个框架Polymer here非常值得一看
Finally
我也认为这是一个excellent, modern best practice css guide - 专门用于阻止大型CSS项目变得混乱 . 我试着遵循其中的大部分内容 .
这里有一些很棒的材料,有些已经花了很多时间来回答这个问题,但是当涉及到单独或单独的样式表时,我会使用单独的文件进行开发,然后进入所有通用的css用于整个选址的合并部署时将其放入单个文件中 .
通过这种方式,您可以充分利用这两个方面,提高性能(减少从浏览器请求的HTTP请求)以及在开发过程中分离代码问题 .
我建议你看看"Compass Style" CSS framework .
这里只有4个例子:
CSS Conventions / Code Layout Models
Are there any CSS standards that I should follow while writing my first stylesheet?
What is the best method for tidying CSS?
Best Practices - CSS Stylesheet Formatting
在所有4个答案中都包含了下载和阅读Natalie Downe的PDF CSS Systems的建议 . (PDF包含幻灯片中没有的大量笔记,因此请阅读PDF!) . 记下她对组织的建议 .
_435008_四年后,我会说:
Use a CSS pre-processor 并将您的文件作为局部文件管理(我个人更喜欢使用指南针的Sass,但是Less也很好,还有其他的)
阅读OOCSS,SMACSS和BEM或getbem等概念 .
看看像Bootstrap和Zurb Foundation这样流行的CSS框架是如何构建的 . 并且不要打折不那么流行的框架 - Inuit是一个有趣的框架,但还有很多其他框架 .
使用连续集成服务器和/或Grunt或Gulp等任务运行程序上的构建步骤合并/缩小文件 .
我可以建议Less CSS Dynamic framework
它类似于前面提到的SASS .
它有助于维护每个父类的CSS .
例如 .
这样做:对#child1和#child2应用宽度:100% .
此外,#child1特定CSS属于#parent .
这个会渲染到
我发现困难的是将网站所需的设计转换为一系列规则 . 如果网站的设计清晰且基于规则,那么您的类名和CSS结构可以从中流出 . 但是,如果人们随着时间的推移,随意地向网站添加一些没有多大意义的内容,那么在CSS中你可以做很多事情 .
我倾向于组织我的CSS文件大致如下:
CSS重置,基于Eric Meyer’s . (因为我发现,对于大多数元素,我至少有一两个规则只是重置默认的浏览器样式 - 例如,我的大多数列表看起来都不像列表的默认HTML样式 . )
网格系统CSS,如果站点要求它 . (我的基础是960.gs)
每个页面上显示的组件样式(页眉,页脚等)
在整个站点的各个位置使用的组件的样式
仅与各个页面相关的样式
如您所见,其中大部分取决于网站的设计 . 如果设计清晰有序,那么你的CSS就可以了 . 如果没有,你就搞砸了 .
不要在CSS中写 Headers
只需将部分拆分成文件即可任何CSS评论,应该只是评论 .
使用脚本将它们合并为一个;如有必要 . 你甚至可以拥有一个漂亮的目录结构,只需让你的脚本递归扫描
.css
文件 .如果必须编写 Headers ,请在文件开头添加TOC
TOC中的 Headers 应该与您稍后写的 Headers 完全相同 . 寻找 Headers 真是太痛苦了 . 要添加问题,在第一个 Headers 后,有多人认为你知道你有另一个 Headers ? PS . 在编写TOC时,不要在每行的开头添加doc-like *(star),这只会让选择文本更加烦人 .
在规则内或规则内写注释,而不是在块外
首先,当您编辑脚本时,有50/50的机会您将注意规则块之外的内容(特别是如果它是一个大的文本块;)) . 其次,(几乎)没有在外面需要“评论”的情况 . 如果它在外面,它是99%的时间 Headers ,所以保持这样 .
将页面拆分为组件
组件应该具有
position:relative
,没有padding
且没有margin
,大多数情况下 . 这大大简化了%规则,并且允许更简单的绝对定位容器,绝对定位元素在计算top
,right
,bottom
,left
属性时将使用容器 .HTML5文档中的大多数DIV通常都是一个组件 .
组件也可以被视为页面上的独立单元 . 在非专业人士的术语中,如果对待像 blackbox 这样的东西是有意义的,那就把它当成一个组件 .
再次使用QA页面示例:
通过将页面拆分为组件,您可以将工作分成可管理的单元 .
将规则与累积效果放在同一行上 .
例如
border
,margin
和padding
(但不是outline
)都会添加到要样式化的元素的尺寸和大小 .如果它们在一条线上不可读,至少将它们放在一起:
尽可能使用速记:
永远不要重复选择器
如果你有相同选择器的更多实例,那么你很可能不可避免地会遇到相同规则的多个实例 . 例如:
当您可以使用id / classes时,避免使用TAG作为选择器
首先关闭DIV和SPAN标签是例外:永远不要使用它们! ;)仅使用它们来附加类/ id .
这个...
应该这样写:
因为那里额外的悬空DIV不会给选择器增加任何东西 . 它们还强制执行不必要的标记规则 . 如果您要将
.answer
从div
更改为article
,您的风格将会中断 .或者如果您希望更清晰:
原因是
border-collapse
属性是一个特殊属性,只有在应用于table
时才有意义 . 如果.statistics
不是table
,则不应该适用 .通用规则是邪恶的!
如果可以,请避免编写通用/魔法规则
除非是CSS重置/未设置,否则所有通用魔法应该适用于至少一个根组件
它们不会节省你的时间,它们会使你的头发爆炸;以及使维护成为一场噩梦 . 当你编写规则时,你可能知道它们适用的地方,但是不能保证你的规则不会在以后弄乱你 .
添加到这个通用规则是令人困惑和难以阅读的,即使您对您正在构建的文档有所了解 . 这并不是说您不应该编写通用规则,只是不要使用它们,除非您真正想要它们是通用的,甚至它们尽可能多地将范围信息添加到选择器中 .
好像的东西这个...
...与在编程语言中使用全局变量具有相同的问题 . 你需要给他们范围!
基本上读作:
每当我知道的组件是页面上的单例时,我喜欢使用ID;你的需求可能会有所不同 .
注意:理想情况下,你应该写得足够好 . 然而,与提及较少的组件相比,在选择器中提及更多组件是更宽容的错误 .
让我们假设你有一个
pagination
组件 . 您可以在整个网站的许多地方使用它 . 这将是你何时编写通用规则的一个很好的例子 . 让我们说你display:block
个人页码链接,并给他们一个深灰色的背景 . 要让它们可见,你必须有这样的规则:现在让我们假设你使用你的分页作为答案列表,你可能会遇到这样的事情
这将使您的白色链接变黑,这是您不想要的 .
修复它的错误方法是:
解决问题的正确方法是:
复杂的“逻辑”评论不起作用:)
如果你写下这样的话:“这个 Value 取决于等等等等等等等等,那就不可避免地会犯错误而且它会像纸牌屋一样掉下来 .
保持简单的评论;如果你需要"logical operations"考虑其中一种CSS模板语言,如SASS或LESS .
你怎么写一个彩色托盘?
把这个留到最后 . 拥有整个颜色托盘的文件 . 有了这个文件,你的风格应该仍然在规则中有一些可用的颜色托盘 . 你的颜色托盘应该覆盖 . 您使用非常高级的父组件(例如
#page
)链接选择器,然后将您的样式编写为自给自足的规则块 . 它可以只是颜色或更多 .例如 .
这个想法很简单,你的颜色托盘是一个独立于基本风格的样式表,你可以级联进去 .
更少的名称,需要更少的内存,使代码更容易阅读
使用较少的名称更好 . 理想情况下使用非常简单(和简短!)的单词:text,body,header .
我还发现简单单词的组合更容易理解,然后有一个长“适当”的词:postbody,posthead,userinfo等 .
保持词汇量很小,即使有些陌生人进来阅读你的风格汤(比如几周之后你自己);这只需要了解使用单词的地方而不是每个选择器的使用位置 . 例如,每当元素被认为是"the selected item"或"the current item"等时,我就会使用
.this
.自己清理干净
编写CSS就像吃东西,有时你会留下一团糟 . 确保你清理那个烂摊子,否则垃圾代码就会堆积起来 . 删除您不使用的类/ ID . 删除不使用的CSS规则 . 确保一切都很好,你没有冲突或重复的规则 .
如果您按照我的建议将某些容器视为您的样式中的黑盒子(组件),在选择器中使用这些组件,并将所有内容保存在一个专用文件中(或使用TOC和标头正确拆分文件),然后工作要容易得多......
您可以使用firefox扩展Dust-Me Selectors等工具(提示:将其指向您的sitemap.xml),以帮助您找到隐藏在您的css核武器和狂欢中的一些垃圾 .
保留unsorted.css文件
假设您正在为QA网站设计样式,并且您已经有"answers page"的样式表,我们将其称为
answers.css
. 如果您现在需要添加大量新css,请将其添加到unsorted.css
样式表,然后重构到answers.css
样式表中 .有几个原因:
它's faster to refactor in after you'重新完成,然后搜索规则(可能不存在)并注入代码
您将编写要删除的内容,注入代码会使删除该代码变得更加困难
附加到原始文件很容易导致规则/选择器重复
我看到反击
CSS
膨胀的最好方法是使用面向对象的CSS原则 .甚至还有一个非常好的OOCSS框架 .
一些意识形态与顶部答案中的许多内容相悖,但是一旦你知道如何以面向对象的方式构建
CSS
,你会发现它实际上可以保持代码精益和意味着 .这里的关键是在您的站点和架构师中识别“对象”或构建块模式 .
Facebook聘请了OOCSS的创建者Nicole Sullivan,以便在他们的前端代码(HTML / CSS)中节省大量资金 . 是的,你实际上不仅可以在你的CSS中获得节省,而且在你的HTML中也可以节省成本,因为你提到将基于
table
的布局转换为很多div
另一个很好的方法在某些方面与OOCSS类似,就是从一开始就规划和编写CSS,使其具有可扩展性和模块性 . Jonathan Snook做了一篇精彩的写作和书籍/电子书SMACSS - Scalable and Modular Architecture for CSS
让我联系你一些链接:
5 mistakes of massive CSS - (Video)
5 mistakes of massive CSS - (Slides)
CSS Bloat - (Slides)
很多时候,我会看到个人将文件分成几个部分,部分之间有 Headers 注释 .
就像是
它工作得非常好,可以让以后轻松返回并查找您正在处理的内容 .
如前所述:进入OOCSS . Sass / Less / Compass很有吸引力,但是直到使用vanilla CSS才能正确使用Sass / Less / Compass会让事情变得更糟 .
首先,阅读有关高效的CSS . 试试Google Page Speed并阅读Souders撰写的有关高效css的文章 .
然后,输入OOCSS .
学习使用级联 . (毕竟,我们称之为Cascading Stylesheets) .
了解如何正确获取粒度(自下而上而不是自上而下)
了解如何分离结构和皮肤(什么是独特的,以及这些对象的变化是什么?)
了解如何分隔容器和内容 .
学会爱网格 .
它将彻底改变关于编写CSS的每一点 . 我完全更新并喜欢它 .
更新:SMACSS类似于OOCSS,但一般来说更容易适应 .
您还应该了解级联,重量以及它们的工作原理 .
我注意到你只使用类标识符(div.title) . 您是否知道您也可以使用ID,并且ID比一个级别更重要?
例如,
将使所有这些元素共享字体大小,比如说或颜色,或任何规则 . 你甚至可以让所有作为#page1后代的DIV获得某些规则 .
至于重量,请记住CSS轴从最普通/最轻到最特定/最重 . 也就是说,在CSS选择器中,类说明符被ID说明符否决了类说明符 . 数字计数,因此具有两个元素说明符(ul li)的选择器将比仅具有单个说明符(li)的选择器具有更多权重 .
把它想象成数字 . 在一列中的9仍然小于十列中的一个 . 具有ID说明符,类说明符和两个元素说明符的选择器将比没有ID的选择器,500个类说明符和1,000个元素说明符具有更多权重 . 当然,这是一个荒谬的例子,但你明白了 . 关键是,应用这个概念可以帮助你清理很多CSS .
顺便说一句,除非你遇到与class =“title”的其他元素发生冲突,否则不必将元素说明符添加到类(div.title)中 . 不要添加不必要的重量,因为您可能需要稍后使用该重量 .
我的回答是高级别的,以解决您在问题中提出的高级别问题 . 可能存在低级别的组织技巧和调整,你可以做的更漂亮,但没有一个可以解决方法上的缺陷 . 有几件事会影响CSS爆炸 . 显然,网站的整体复杂性,还有命名语义,CSS性能,CSS文件组织和可测试性/可接受性等 .
您似乎在使用命名语义的正确路径上,但它可以更进一步 . 在没有结构修改的情况下在网站上重复出现的HTML部分(称为"modules")可以被视为选择器根,从那里您可以将内部布局相对于该根进行范围调整 . 这是 object-oriented CSS 的基本原则,您可以read/watch more about it in this talk by a Yahoo engineer .
值得注意的是,这种干净的方法可能与性能的关注相反,这有利于 short selectors based either on id or tag name . 找到这种 balancer 取决于你,但除非你有一个庞大的网站,这应该只是你头脑中的指南,提醒你保持你的选择器短 . More about performance here .
最后,您是要为整个站点设置 single CSS file ,还是多个文件(与每页或-section文件一起使用的单个基本文件)?单个文件对性能更好,但可能更难理解/维护多个团队成员,并且可能更难测试 . 为了进行测试,我建议您使用 single CSS-test page ,其中包含用于测试冲突和意外级联的所有受支持的CSS模块 .
或者,您可以使用 multiple file approach 将CSS规则范围限定为页面或节 . 这需要浏览器下载多个文件,这是性能问题 . 您可以使用服务器端编程来动态地指定CSS文件并将其聚合(并缩小)为单个文件 . 但由于这些文件是独立的,并且对它们的测试是分开的,因此您可能会在页面/部分之间引入不一致的外观和感觉 . 因此测试变得更难 .
由您来分析客户的具体需求,相应地 balancer 这些问题 .
这个问题问得好 . 我看到的每个地方,CSS文件都会在一段时间后失控 - 特别是,但不仅仅是在团队中工作时 .
以下是我自己要遵守的规则(并非我总是能够遵守的规则 . )
Refactor early, refactor often. 经常清理CSS文件,将同一类的多个定义融合在一起 . 去掉立即废弃的定义 .
在修复错误期间添加CSS时,请对更改的内容发表评论(“这是为了确保该框在IE <7中保持对齐”)
避免裁员,例如在
.classname
和.classname:hover
中定义相同的东西 .使用注释
/** Head **/
构建清晰的结构 .使用有助于保持恒定样式的美化工具 . 我使用的是Polystyle,我确定周围也有免费的(更新:例如Code Beautifier基于CSS Tidy,一个开源工具,我还没有使用过,但看起来非常有趣 . )
Build 合理的课程 . 请参阅下面的一些注释 .
使用语义,避免DIV汤 - 例如,使用
<ul>
s作为菜单 .将所有内容定义在尽可能低的级别(例如
body
中的默认字体系列,颜色和大小)并尽可能使用inherit
如果你有非常复杂的CSS,也许CSS预编译有帮助 . 我打算很快调查xCSS也是出于同样的原因 . 周围还有其他几个 .
如果在团队中工作,也要强调CSS文件的质量和标准的必要性 . 每个人都对编程语言中的编码标准很重要,但很少有人意识到这也是CSS所必需的 .
如果在团队中工作,请考虑使用版本控制 . 它使事情更容易跟踪,编辑冲突更容易解决 . 它's really worth it, even if you'重新"just"成为HTML和CSS .
不适用于
!important
. 不仅因为IE = <7还可以找到它,而且它对于长期维护是有害的 .Building sensible classes
这就是我喜欢 Build 合理课程的方式 .
我首先应用全局设置:
然后,我确定了页面布局的主要部分 - 例如顶部区域,菜单,内容和页脚 . If I wrote good markup, these areas will be identical with the HTML structure.
然后,我开始构建CSS类,尽可能多地指定祖先和合理,并尽可能地将相关类分组 .
将整个CSS结构视为一棵树,具有越来越具体的定义,越远离您的根 . 您希望尽可能减少类的数量,并且您希望尽可能少地重复自己 .
例如,假设您有三个级别的导航菜单 . 这三个菜单看起来不同,但它们也具有某些特征 . 例如,它们都是
<ul>
,它们都具有相同的字体大小,并且这些项目彼此相邻(与ul
的默认呈现相反) . 此外,没有菜单有任何项目符号(list-style-type
) .首先,将公共特征定义为名为
menu
的类:然后,定义三个菜单中每个菜单的具体特征 . 1级高40像素; 2级和3级20像素 .
Note: 您也可以为此使用多个类但Internet Explorer 6 has problems with multiple classes,因此本示例使用
id
.菜单的标记如下所示:
如果你在页面上有类似语义的元素 - 比如这三个菜单 - 试着先找出共性,然后把它们放到一个类中;然后,计算出特定属性并将它们应用于类,或者,如果必须支持Internet Explorer 6,则为ID .
Miscellaneous HTML tips
<body class='contactpage'>
这使得向样式表添加特定于页面的调整变得非常容易:这样,每个菜单项都可以根据其语义上下文进行样式访问:它是列表中的第一个还是最后一个项;是否是当前活动的项目;并按数字 .