我一直非常依赖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汤 -
例如,使用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结构想象成一棵树,具有越来越具体的定义,离你的根越远.您希望尽可能减少类的数量,并且您希望尽可能少地重复自己.
例如,假设您有三个级别的导航菜单.这三个菜单看起来不同,但它们也具有某些特征.例如,它们都是!important
,它们都具有相同的字体大小,并且项目彼此相邻(与a的默认呈现相反
).此外,没有菜单有任何项目符号(ul
).
首先,将共同特征定义为名为的类list-style-type
:
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 存在多个类的问题,因此本示例使用menu
s.
div.navi ul.menu#level1 { height: 40px; }
div.navi ul.menu#level2 { height: 20px; }
div.navi ul.menu#level3 { height: 16px; }
菜单的标记如下所示:
如果你在页面上有类似语义的元素 - 比如这三个菜单 - 试着先找出共性,然后把它们放到一个类中; 然后,计算出特定属性并将它们应用于类,或者,如果必须支持Internet Explorer 6,则为ID.
其他HTML提示
如果您将这些语义添加到HTML输出中,设计人员可以稍后使用纯CSS自定义网站和/或应用程序的外观,这是一个很大的优势和节省时间.
如果可能的话,给每个页面的主体一个唯一的类:id
这使得向样式表添加特定于页面的调整变得非常容易:
body.contactpage div.container ul.mainmenu li { color: green }
在自动构建菜单时,尽可能多地添加CSS上下文,以便以后进行广泛的样式设置.例如:
这样,每个菜单项都可以根据其语义上下文进行样式访问:它是列表中的第一个还是最后一个项目; 是否是当前活动的项目; 并按数字.
请注意,上面示例中概述的多个类的分配在IE6中无法正常工作.有一种解决方法可以使IE6能够处理多个类; 我还没有尝试过,但看起来非常有前途,来自Dean Edwards.在此之前,您必须设置对您来说最重要的类(项目编号,活动或第一个/最后一个)或使用ID.(booo IE6!)
这里只有4个例子:
CSS约定/代码布局模型
在编写我的第一个样式表时是否应该遵循CSS标准?
整理CSS的最佳方法是什么?
最佳实践 - CSS样式表格式
在所有4个答案中,我的答案包括下载和阅读Natalie Downe的PDF CSS Systems的建议.(PDF包含不在幻灯片中的大量笔记,因此请阅读PDF!).记下她对组织的建议.
编辑(2014/02/05)四年后,我会说:
使用CSS预处理器并将文件管理为部分(我个人更喜欢使用指南针的Sass,但是Less也很好,还有其他的)
阅读OOCSS,SMACSS和BEM或getbem等概念.
看一下像Bootstrap和Zurb Foundation这样流行的CSS框架是如何构建的.并且不要打折不那么受欢迎的框架 - 因纽特人是一个有趣的框架,但还有很多其他框架.
通过持续集成服务器和/或Grunt或Gulp等任务运行器上的构建步骤来合并/缩小文件.
只需将部分拆分成文件即可 任何CSS评论,应该只是评论.
reset.css base.css somepage.css someotherpage.css some_abstract_component.css
使用脚本将它们合并为一个; 如有必要.您甚至可以拥有一个漂亮的目录结构,只需让您的脚本以递归方式扫描.css
文件.
TOC中的标题应该与您稍后写的标题完全相同.寻找标题真是太痛苦了.要添加问题,在第一个标题后,有多人认为你知道你有另一个标题?PS.在编写TOC时,不要在每行的开头添加doc-like*(star),这只会让选择文本更加烦人.
/* Table of Contents - - - - - - - - - Header stuff Body Stuff Some other junk - - - - - - - - - */ ... /* Header Stuff */ ... /* Body Stuff */
首先,当您编辑脚本时,有50/50的机会您将注意规则块之外的内容(特别是如果它是一个大的文本块;)).其次,(几乎)没有你需要在外面"评论"的情况.如果它在外面,它是99%的时间标题,所以保持这样.
组件在大多数情况下应该有position:relative
,不padding
,不margin
.这简化%原则很多,以及允许更简单的absolute:position
"元素的ING,因为如果有一个绝对定位的容器绝对定位的元素将计算时所使用的容器top
,right
,bottom
,left
的属性.
HTML5文档中的大多数DIV通常都是一个组件.
组件也可以被视为页面上的独立单元.在非专业人士的术语中,如果对待像黑盒子这样的东西是有意义的,那就把它当成一个组件.
再次使用QA页面示例:
#navigation
#question
#answers
#answers .answer
etc.
通过将页面拆分为组件,可以将工作分成可管理的单元.
例如border
,margin
和padding
(但不是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;
}
首先关闭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
从a div
到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
属性的原因是一个特殊的属性,只有在应用于a时才有意义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;
}
如果你写下这样的话:"这个价值取决于等等等等等等等等,那就不可避免地会犯错误而且它会像纸牌屋一样掉下来.
保持简单的评论; 如果您需要"逻辑运算",请考虑其中一种CSS模板语言,如SASS或LESS.
你怎么写一个彩色托盘?
把这个留到最后.拥有整个颜色托盘的文件.在这个文件中,你的风格应该仍然在规则中有一些可用的颜色托盘.你的颜色托盘应该覆盖.您使用非常高级别的父组件链接选择器(例如#page
),然后将您的样式编写为自给自足的规则块.它可以只是颜色或更多.
例如.
#page #header .description,
#page #categories .description,
#page #answers .answer .body
{
color: #222; background: #fff;
border-radius: 10px;
padding: 1em;
}
这个想法很简单,您的颜色托盘是一个独立于基本样式的样式表,您可以将其级联到其中.
使用较少的名称更好.理想情况下使用非常简单(和简短!)的单词:text,body,header.
我还发现简单单词的组合更容易理解,然后有一个长"适当"的词:postbody,posthead,userinfo等.
保持词汇量很小,即使有些陌生人进来阅读你的风格汤(比如几周之后你自己);这只需要了解使用单词的地方而不是每个选择器的使用位置.例如,.this
每当元素被认为是"所选项目"或"当前项目"时,我就会使用它等.
编写CSS就像吃东西,有时你会留下一团糟.确保你清理那个烂摊子,否则垃圾代码会堆积起来.删除您不使用的类/ ID.删除不使用的CSS规则.确保一切都很好,你没有冲突或重复的规则.
如果您按照我的建议将某些容器视为您的样式中的黑盒子(组件),在选择器中使用这些组件,并将所有内容保存在一个专用文件中(或者使用TOC和标头正确拆分文件),然后工作大大简化......
您可以使用firefox扩展Dust-Me Selectors等工具(提示:将其指向您的sitemap.xml),以帮助您找到隐藏在您的css核武器和狂欢中的一些垃圾.
unsorted.css
文件假设您正在为QA网站设计样式,并且您已经有了"答案页面"的样式表,我们将调用该样式表answers.css
.如果您现在需要添加大量新css,请将其添加到unsorted.css
样式表中,然后重构到answers.css
样式表中.
有几个原因:
在你完成后重构更快,然后搜索规则(可能不存在)并注入代码
您将编写要删除的内容,注入代码会使删除该代码变得更加困难
附加到原始文件很容易导致规则/选择器重复
看看1. SASS 2. 指南针
我看到反击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膨胀 - (幻灯片)
您还应该了解级联,重量以及它们的工作原理.
我注意到你只使用类标识符(div.title).您是否知道您也可以使用ID,并且ID比类更重要?
例如,
#page1 div.title, #page1 ul, #page1 span { // rules }
将使所有这些元素共享字体大小,比如或颜色,或任何规则.你甚至可以让所有作为#page1后代的DIV获得一定的规则.
至于重量,请记住CSS轴从最普通/最轻到最特定/最重.也就是说,在CSS选择器中,由类说明符推翻的元素说明符被ID说明符否决.数字计数,因此具有两个元素说明符(ul li)的选择器将比仅具有单个说明符(li)的选择器具有更多权重.
把它想象成数字.在一列中的9仍然小于十列中的一个.具有ID说明符,类说明符和两个元素说明符的选择器将比没有ID的选择器,500个类说明符和1,000个元素说明符具有更多权重.当然,这是一个荒谬的例子,但你明白了.关键是,应用此概念可以帮助您清理大量的CSS.
顺便说一句,除非你遇到与class ="title"的其他元素发生冲突,否则不必将元素说明符添加到类(div.title)中.不要添加不必要的重量,因为您可能需要稍后使用该重量.
我可以建议Less CSS动态框架
它类似于前面提到的SASS.
它有助于维护每个父类的CSS.
例如
#parent{ width: 100%; #child1 { background: #E1E8F2; padding: 5px; } #child2 { background: #F1F8E2; padding: 15px } }
这样做:对#child1和#child2应用宽度:100%.
此外,#child1特定CSS属于#parent.
这将呈现给
#parent #child1 { width: 100%; background: #E1E8F2; padding: 5px; } #parent #child2 { width: 100%; background: #F1F8E2; padding: 15px; }
我发现困难的事情是将网站所需的设计转换为一系列规则.如果网站的设计清晰且基于规则,那么您的类名和CSS结构可以从中流出.但是,如果人们随着时间的推移,随意地向网站添加一些没有多大意义的内容,那么在CSS中你可以做很多事情.
我倾向于组织我的CSS文件大致如下:
CSS重置,基于Eric Meyer的.(因为我发现,对于大多数元素,我至少有一两个规则只是重置默认浏览器样式 - 例如,我的大多数列表看起来都不像列表的默认HTML样式.)
网格系统CSS,如果站点要求它.(我的基础是960.gs)
每个页面上显示的组件样式(页眉,页脚等)
在整个站点的各个位置使用的组件的样式
仅与单个页面相关的样式
如您所见,大部分内容取决于网站的设计.如果设计清晰有序,那么你的CSS就可以了.如果没有,你就搞砸了.
我的答案是高级别的,以解决您在问题中提出的高级别问题.可能会有低级别的组织技巧和调整,你可以做的更漂亮,但没有一个可以解决方法上的缺陷.有几件事会影响CSS爆炸.显然,网站的整体复杂性,还有命名语义,CSS性能,CSS文件组织和可测试性/可接受性等.
您似乎在使用命名语义的正确路径上,但它可以更进一步.在没有结构修改的情况下在网站上重复出现的HTML部分(称为"模块")可以被视为选择器根,从那里您可以将内部布局相对于该根进行范围.这是面向对象CSS的基本原则,您可以在雅虎工程师的演讲中阅读/观看更多相关内容.
重要的是要注意,这种干净的方法可能与性能的关注相反,这有利于基于id或标记名称的短选择器.找到这种平衡取决于你,但除非你有一个庞大的网站,这应该只是你头脑中的指南,提醒你保持你的选择器短. 更多关于性能的信息.
最后,您是要为整个站点创建一个CSS文件,还是多个文件(与每页或-section文件一起使用的单个基本文件)?单个文件对性能更好,但可能更难理解/维护多个团队成员,并且可能更难测试.对于测试,我建议你有一个CSS测试页面,其中包括每个支持的CSS模块,用于测试冲突和意外的级联.
或者,您可以使用多文件方法,将CSS规则范围限定为页面或节.这需要浏览器下载多个文件,这是性能问题.您可以使用服务器端编程来动态地指定CSS文件并将其聚合(并缩小)为单个文件.但由于这些文件是独立的,并且对它们的测试是分开的,因此您会在页面/部分之间引入不一致的外观和感觉.因此测试变得更难.
由您来分析客户的具体需求,相应地平衡这些问题.
如前所述:进入OOCSS.Sass/Less/Compass很有吸引力,但在使用vanilla CSS之前,Sass/Less/Compass只会让事情变得更糟.
首先,阅读有关高效的CSS.试试Google Page Speed并阅读Souders撰写的有关高效css的文章.
然后,输入OOCSS.
学习使用级联.(毕竟,我们称之为Cascading Stylesheets).
了解如何正确获取粒度(自下而上而不是自上而下)
学习如何分离结构和皮肤(什么是独特的,以及这些对象的变化是什么?)
了解如何分隔容器和内容.
学会爱网格.
它将彻底改变关于编写CSS的每一点.我完全更新并喜欢它.
更新:SMACSS类似于OOCSS,但一般来说更容易适应.