CSS 架构,第一部分:代码清理原则和新的最佳实践





5.00/5 (5投票s)
基本的、扎实的 CSS 编写实践可以极大地提高任何组织样式表的维护性,但最终目标是构建一个给定站点的样式表,以显著提高可伸缩性。本系列文章的第一篇将探讨编写干净高效的 CSS 的基本实践
很多时候,大型(和小型)网站的 CSS 都存在代码臃肿和冗余的典型问题,代码行中存在不必要的限定符元素、过长的选择器链导致的选择器过于具体、过度依赖后代选择器(而其他选择器更合适),以及不当或不必要地使用 !important。
我们可以采取 几种基本的、扎实的 CSS 编写实践 来极大地提高任何组织样式表的维护性。然而,最终,我们真正应该追求的是构建一个给定站点的样式表,以显著提高 *可伸缩性*。
因此,我们的方法是双管齐下的。首先,我们必须采取几项基本的实践来编写干净高效的 CSS。其次,我们需要了解并采用越来越受欢迎的可伸缩 CSS 架构的核心方法论,将我们的网站样式表提升到新的水平。
我将在本文中探讨这两个主题,但在我们开始讨论代码的可伸缩性之前,让我们先做一些 CSS 清理工作,从我最喜欢的一些技巧开始。
一些有用的技巧
从其他开发人员那里学习工作流程技巧通常非常有帮助。以下是我个人最喜欢的一些。
定位样式
最好有一种方法来定位页面上的样式。如果您没有使用 Internet Explorer Developer Toolbar、Mozilla 的 Firebug 或 Chrome Developer Tools 等工具,这种老式的方法通过添加 outline 属性可以帮助您更快地查看和操作所需的元素。
.searchform > .searchsubmit { width: 14%; height: 25px; background: transparent url(images/icon_magnify.png) 0 0 no-repeat; outline: 1px solid red }
使用此属性和值的原理是 outline 不会像 border 那样增加元素的尺寸。即使使用红色(或其他任何颜色名称)也是有意义的。在编码时,请仅使用十六进制、rgb(a) 或 hsl(a) 颜色代码。这样,当您看到颜色名称时,就知道它仅用于故障排除目的。请注意,IE8 及更低版本不支持 outline。
添加测试样式
在测试和故障排除时,另一个好的做法是 缩进新的试用样式。
.searchform > .searchsubmit { width: 14%; height: 25px; background: transparent url(images/icon_magnify.png) 0 0 no-repeat; margin: -2px 0 0 0; }
通过缩进,您可以确定该样式是临时的,并且以后可以轻松地扫描和查找。当您决定保留该样式时,请像处理永久样式一样对其进行缩进。
禁用样式
在添加新样式方面,这里有一种快速禁用它们的方法:“X”掉它们,方法是在样式选择器或样式规则前加上“x-”。
.social a { -moz-transition: opacity 0.3s ease 0s; x-display: block; height: 35px; opacity: 0.4; }
此方法比注释掉样式更快。它也很容易扫描和查找,并且如果您稍后决定保留该样式,它仍然在那里。
CSS 清理和优化指南
现在我们已经介绍了这些技巧,让我们将注意力转移到编写干净、优化代码的一些经验法则上——或者在您清理别人混乱的 CSS 时。我们将从宏观到微观级别进行,首先探讨如何提高 HTML 的可读性和语义,然后转向如何更好地组织和减少样式声明的数量。
宏观优化
很容易专注于样式声明本身,但在创建选择器之前,您需要使 HTML 和样式表本身易于阅读。
提供样式表信息并指示结构
对于非常大的样式表,我喜欢使用目录。对于新接触某个样式表的开发人员来说,知道各部分是什么以及在需要查找一组样式时应该跳转到哪个名称,这非常有帮助。
在基本层面,我建议在样式表中插入开发人员信息(姓名等)和最后更新日期。这样,如果对文档内容有任何疑问,当前开发人员就知道该询问谁。
/* stylesheet information for XyZ Corp File created date: 09.15.2010 Last modified date: 06.04.2012 By: [name] */
此外,我建议放入一个初步的目录,以便其他开发人员可以了解文档的结构和不同样式的部分。
/* Table of Contents - Link Styles - Other sitewide styles - Actions - Layout - LOGO - TOP NAV - NAVBAR - SUBNAV */ … (later in the document…) /* =Layout */ (etc.)
请注意,在样式表的部分名称前包含等号(=)是故意的——它充当一个标记,并且是一种更轻松地搜索文档的方法。
注释和嵌套
注释和嵌套标记有助于您跟踪包含其他元素的元素的开始和结束,从而使您能够更快地识别各个部分。
使用标记 `` 注释 div 和其他主要布局元素,并使用标记 `` 或 `` 来结束它们。
嵌套可能看起来是一个不必要的步骤,但它在视觉上很有用,并且通过清晰地指示视觉层次,还可以更容易地发现诸如内联元素中的块级元素以及元素的不当关闭和重新打开等问题,这些问题可能导致主要的布局问题——这些问题验证器通常无法轻易帮助您找到。
您可以在以下示例中看到区别:
<body> <div id="pagewrap"> <div id="header"> <h1>Website Title</h1> <ul id="navigation"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> <div id="contentwrap"> <div id="maincontent"> <h2>Main Content Title</h2> <p>Main content, which is so much more important than the secondary content that it makes one teary with emotion.</p> </div> <div id="secondarycontent"> <h3>Sidebar Title</h3> <p>Sidebar content, which is not as important as the primary content (which is why it is in the sidebar)</p> </div> <div id="footer"> <p>standard copyright and footer information</p> </div> </body> |
<body> <div id="pagewrap"> <div id="header"> <h1>Website Title</h1> <ul id="navigation"> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </div><!-- end #header --> <div id="contentwrap"> <div id="maincontent"> <h2>Main Content Title</h2> <p>Main content, which is so much more important than the secondary content that it makes one teary with emotion.</p> </div><!-- end #maincontent --> <div id="secondarycontent"> <h3>Sidebar Title</h3> <p>Sidebar content, which is not as important as the primary content (which is why it is in the sidebar)</p> </div><!-- end #secondarycontent --> </div><!-- end #contentwrap --> <div id="footer"> <p>standard copyright and footer information</p> </div><!-- end #footer --> </div><!-- end #pagewrap --> </body> |
您可以在“创建有效的语义标记”中找到有关组织样式表信息的更多信息和技巧。
微观优化
微观优化可以减小文件大小,加快页面加载时间,并鼓励最佳实践。以下是一些您可以从微观层面改进 CSS 的方法。
按字母顺序排列规则
将 CSS 声明按字母顺序排列是实现干净代码和减少问题的好方法。为什么?因为您的样式声明将更容易定位和查找。
示例一 | 示例二 |
.login { margin-top: 5px; line-height: 1.5em; padding-left: 5px; float: right; list-style-type: none; width: 80px; font-weight: bold; border-left: 1px solid #69824d; } |
.login { border-left: 1px solid #69824d; float: right; font-weight: bold; line-height: 1.5em; list-style-type: none; margin-top: 5px; padding-left: 5px; width: 80px; } |
提高效率以加快速度
长串的元素选择器迫使浏览器不必要地搜索页面 DOM 以进行匹配。消除元素限定符并舍弃后代选择器而采用更直接的选择器有助于加快速度。
预优化
div#wrapper div#maincontent div#sidebar { background: #fff url(bg.png) repeat-x 0 0; border: 1px solid #ff0; font: normal 1.33em/1.33 Georgia, serif; margin: 10px 20px; padding: .1em; }
后优化
#sidebar { background: #fff url(bg.png) repeat-x 0 0; border: 1px solid #ff0; font: normal 1.33em/1.33 Georgia, serif; margin: 10px 20px; padding: .1em; }
在“优化以提高页面加载时间”中阅读有关此主题的更多信息。
KISS:保持简单和简短
在样式声明和选择器方面,少即是多。对于样式声明,请遵循以下规则:
- 尽可能使用简写属性(在使用简写时请记住这些项目:简写属性语法;属性值顺序(如果有);默认值和必需属性值)。
- 压缩值和单位
- 尽可能避免重复的属性
以前
#sidebar { background-color: #fff; background-image: (bg.png); background-position: 0 0; background-repeat: repeat-x; border-width: 1px; border-style: solid; border-color: #ffff00; font-family: Georgia, serif; font-size: 1.33em; line-height: 1.33em; font-weight: normal; margin: 10px 20px 10px 20px; padding: .1em; }
操作后
#sidebar { background: #fff url(bg.png) repeat-x 0 0; border: 1px solid #ff0; font: normal 1.33em/1.33 Georgia, serif; margin: 10px 20px; padding: .1em; }
压缩代码
最后,移除多行和缩进也有助于保持您的网站 高效和快速。在开发 CSS 时,建议使用多行、嵌套和缩进,但一旦网站准备上线,最小化 CSS 是最佳选择。两个不错的压缩 CSS 的工具是 CSS Compressor 和 CSS Drive。
工具可以提供帮助……呃……帮忙
在编码时牢记这些规则有助于避免以后浪费时间和沮丧的错误。但是,不要认为您必须独自完成所有工作,因为有一些很棒的工具可用于清理您的代码。我认为 CleanCSS 和 Code Beautifier 值得一看。使用这些工具进一步清理您的代码,同时学习整合我描述的一些方法。
通过最新的最佳实践改进代码
如您所知,前端开发的领域在过去几年中发展迅速,新思维不断提出解决老问题的创新方法。以下是一些最新的前端编码最佳实践,它们将极大地帮助您的样式表和 HTML。
使用 Normalize.css 重置
CSS 重置有助于建立一个基础,所有样式都基于此设置。重置有效地覆盖了浏览器对某些元素的默认样式(这些样式可能差异很大)。尽管 CSS 重置 在过去几年中广受欢迎,但许多网站仍未采用它们,并且这些网站的 CSS 可伸缩性因此受到了严重影响。
许多人推荐使用 normalize.css,而不是使用 Eric Meyer 非常流行的 CSS Reset(因为它过于广泛)或自己制作 DIY 重置。Normalize.css 将代码“标准化”到一个共同的基线,而不是重置所有浏览器中元素的基线样式。参考 Github 上的 normalize.css 项目,它相对于 CSS Reset 的优点如下:
- 保留了有用的默认值,不像许多 CSS 重置那样
- 标准化了广泛 HTML 元素的样式
- 修复了 bug 和常见的浏览器不一致性
- 通过细微的改进提高了可用性
- 使用详细的注释解释了代码的作用
使用 normalize.css 而不是标准的重置,将使您走上正确的编码之路,并节省大量因需要重新建立基线样式而浪费的时间。
清晰地解决清除浮动问题
如果您仍在文档中使用此处所示的方法来清除浮动,那么我们*真的*需要谈谈。
<div class="clear"></div> … .clear { clear: both; }
建议使用其他清除方法而不是这种方法,这是 CSS 布局开始使用浮动时设计的最早的浮动清除方法之一,大约在 10 年前。
Micro Clearfix,在 HTML5 Boilerplate 中使用,采用了最新的、经过验证的前端编码最佳实践。Micro Clearfix 支持 Firefox 3.5 及更高版本、Safari 4 及更高版本、Chrome、Opera 9 及更高版本以及 Internet Explorer 6 及更高版本。这是一个例子:
/* For modern browsers */ .cf:before, .cf:after { content:""; display:table; } .cf:after { clear:both; } /* For IE 6/7 (triggers hasLayout) */ .cf { *zoom:1; }
clearfix .cf 类应添加到包含浮动的每个元素上。在这种情况下,可以使用带有 clear 属性的旧式空分隔符元素(`<div class="clear"></div>`)
来永久淘汰您的代码库。
溢出:隐藏呢?
另一个清除浮动的流行技巧是使用 overflow: hidden,尽管 Micro Clearfix 更受推荐,因为在 Internet Explorer 7 及更早版本中,overflow: hidden 方法有时会出现问题。
虽然 overflow:hidden 曾经是几乎每个人最喜欢的浮动清除技术,但它也带来了一些问题,例如:
- 在浏览器窗口小于容器时隐藏内容和子元素,而没有滚动条。
- 与边距、边框、轮廓和绝对定位的 PNG 发生冲突。
- 应用 CSS3 属性,例如 box-shadow、text-shadow 和 transforms。
Louis Lazaris,HTML5 and CSS3 for the Real World 的合著者,认为使用 overflow:hidden 会在复杂的布局中导致问题,并建议避免使用它,而选择 Micro Clearfix。
如果您一定要使用 overflow:hidden,那么可以使用以下版本,它考虑了 Internet Explorer 中的 hasLayout 和块级元素。
.container { overflow: hidden; /* Clearfix! */ zoom: 1; /* Triggers "hasLayout" in IE */ display: block; /* Element must be a block to wrap around contents. Unnecessary if only /* using on elements that are block-level by default. */ }
分隔符
说到错误地使用空 div……您必须停止使用带有边框的空清除 <div> 作为页面分隔符。
<div class="divider"></div> … div.divider { border-top: 1px solid #ABAA9A; clear: both; }
是的,我知道这段代码可以很好地作为视觉分隔符清除页面,但它不是语义化的。CSS 忍者、面向对象 CSS (OOCSS) 的创造者 Nicole Sullivan Nicole Sullivan 建议使用 <hr> 元素来分隔页面部分,并为其添加必要的样式。
因此,您将使用以下代码代替之前的代码:
<hr class="divider"> … .divider { border-top: 1px solid #ABAA9A; clear: both; }
图片替换
前端开发在使用 CSS 技术用图像替换文本方面有着悠久而辉煌的历史。2012 年 3 月,Jeffrey Zeldman 推出了一种新方法,称为Kellum 方法。他的技术不是通过 -9999px 技巧将文本隐藏在屏幕外(从而创建一个巨大的不可见框),而是隐藏文本,同时使其可供屏幕阅读器访问。
.hide-text { text-indent: 100%; white-space: nowrap; overflow: hidden; }
性能得到了提高,尤其是在平板电脑和屏幕较小的设备上。
使用图标元素
您可能正在使用 <span></span> 来在页面中放置图标,如下所示:
<li class="favorite"> <span class="icon favorite"></span><span id="favorite-insert-point" class="favorite"></span> </li>
如果是这样,请尝试使用图标元素,利用 <i> 标签。这种方法在 Twitter Bootstrap 中使用后变得越来越流行。
<p><i class="icon icon-comment"></i>23 comments</p> ... .icon { background-image: url( sprites.png ); } .icon-comments { background-position: 0 -30px; }
使用 <i> 比使用标准的 <span> 标签更具语义化,并且可以更轻松地识别页面中的图标位置。
开始使用 CSS3
通常,网站会在不必要的情况下使用图像,从而导致图像过多。使用 CSS3 在消除这些图像方面有很大帮助,同时让网站准备好迁移到响应式设计实践。对于大多数网站来说,CSS3 在圆角(border-radius)、阴影(box-shadow)、文本阴影(text-shadow)、渐变和 box-sizing 方面都有很大帮助。
但是,CSS3 有两个缺点:首先,CSS3 规范的许多部分仍在不断变化,因此即使是现代浏览器也需要为大多数属性使用供应商前缀。其次,CSS3 不被流行的旧浏览器支持,因此需要回退或辅助脚本。
CSS3 兼容性
不幸的是,旧版本的 Internet Explorer 对 CSS3 的兼容性问题最多。目前,Internet Explorer 9 只部分支持 CSS3(最值得注意的是 CSS3 选择器;有关最新列表,请参阅 HTML5 and CSS3 Support),而 Internet Explorer 6 至 8 完全不支持。如果您计划使用任何 CSS3 属性,我建议为使用 Internet Explorer 9、8 或更早版本的受众安装适当的回退。
幸运的是,有一些脚本可以提供帮助。以下脚本有助于 Internet Explorer 对 CSS3 的支持:
这些脚本的缺点是它们会增加页面权重和加载时间,但这种权衡是值得的。
CSS3 工具
对 CSS3 的概述以及哪些属性现在可以使用可能是另一篇文章的主题。关于 CSS3 最重要的一步之一是及时了解规范的变化和浏览器的采用情况。跟踪所有这些可能有点麻烦,所以我建议使用 http://css3please.com/ 和 http://html5please.com 网站来了解最新的语法变化和支持情况。
许多优秀的 CSS3 生成器可供使用。对于几乎所有属性,CSS3, Please! 是一个绝佳的资源。对于渐变,Ultimate CSS Gradient Generator 是一个用于生成具有正确语法和回退的渐变代码的出色工具。
如果您特别懒惰,不想记住如何写所有供应商前缀,Prefixr 会为您将其添加到代码中。您还可以使用 Lea Verou 的这个很棒的脚本 ,它会在将 CSS 上传到服务器后为您添加所有前缀。
建立网格系统
如果您的站点目前没有建立的网格系统,您必须“立即行动”并建立一个。如果您当前的代码包含大量 width、margin 和 padding 的实例,并且元素之间的尺寸不一致,而它们应该大小相同,那么您的站点早就应该进行网格化了。
您可以根据元素的尺寸自行构建,也可以采用预制的 CSS 网格框架(有几十个,甚至有响应式的)。
使用 Box-Sizing
如果您正在创建自己的网格系统,一个非常有用的 CSS 属性是 box-sizing。Box-sizing 可以改变浏览器计算元素框大小的方式,它对于处理尺寸来说是一大福音,尤其适用于布局和网格。
Box-sizing 根据所谓的“IE 盒子模型”计算元素框的尺寸——也就是说,内边距被计入盒子的大小。这意味着当元素的宽度和内边距一起声明时,盒子的大小将等于声明的宽度值,而不是宽度值加上内边距。图 1 说明了这一点。
使用 box-sizing: border-box(与 box-sizing: content-box 相反,后者是基于 W3C 盒子模型的默认值)可以极大地简化布局计算。box-sizing 属性确实需要供应商前缀。
使网格和图像具有流动性
规划建立网格系统的最后一个方面(如果您正在为未来做准备,以实现面向未来)是从固定像素网格切换到百分比(或 ems)网格。确定尺寸百分比的最佳方法是使用 Ethan Marcotte 的响应式 Web 设计黄金法则:目标=内容/上下文。 幸运的是,有一些计算器可以帮助确定网格的 RWD 数字。我推荐 RWD Calculator。
为了实现面向未来,至关重要的是要让图像能够随着其容器的大小而自适应和移动。实现这一点的主要方法是一行简单的代码:
img { max-width: 100%; height: auto; }
图像现在将会在流式容器内收缩或增长。
别忘了 HTML5
最后,HTML5 对于所有网站来说都至关重要。现在的问题不再是某个网站是否决定实施它,而是*何时*实施。我认为 HTML5 有几个方面对任何人都很有用,可以为响应式设计打下基础,但最容易入手的是 HTML5 doctype。HTML5 doctype 是您可以在页面模板中立即进行的快速更改,作为迁移到 HTML5 标签和文档重构的先决条件。
<!DOCTYPE html>
您的文档中的其他任何内容都不需要更改,因为 doctype 向后兼容,但如果引入任何 HTML5 标签,它们都会起作用。
说到标签,HTML5 的另一个方面是利用一些新标签,它们有助于页面的语义化,同时为创建代码模块奠定良好基础。但是,与 CSS3 一样,浏览器的向后兼容性是一个严重的问题。为了支持新标签的识别,需要在页面上使用脚本来使旧浏览器能够正确渲染 HTML5 元素。
最常见的脚本是 HTML5 Shiv,它允许 Internet Explorer 6 至 8 识别 HTML5 元素。唯一的缺点是还需要另一个脚本来添加到页面加载中。但实际上,没有理由等待使用 HTML5,所以大胆尝试吧!
不错,干净,为重大重构做好准备
这不算太难,对吧?通过从宏观层面清理代码(给予它正确的结构),然后缩小到微观层面组织代码,您可以大大改善糟糕的 CSS。此外,用更高效的最佳实践替换过时的解决方案也大有裨益。
现在我们已经完成了初步的清理工作,我们可以开始进行一些严肃的 CSS 重构了。通过采用越来越受欢迎的可伸缩 CSS 架构的一些方法论,可以大大提高网站样式表的可维护性和效率。请稍候;您将在本系列的下一篇文章中了解四大方法的概述。
本文是 Internet Explorer 团队 HTML5 技术系列的一部分。 在 http://modern.IE 免费试用 BrowserStack 跨浏览器测试 3 个月,并在本文中应用这些概念。
DENISE R. JACOBS 是一位 Web 设计专家,拥有超过 14 年的行业经验。她现在做着她最喜欢的事情:担任演讲者 + 作者 + Web 设计顾问 + 创意传播者。她在 Twitter 上被@denisejacobs 称为“很棒的资源”,Denise 是《The CSS Detective Guide》的作者,这是关于 CSS 代码故障排除的权威书籍,也是《Interact with Web Standards》和《Smashing Book #3: Redesign the Web》的合著者。她最新的项目是鼓励更多来自代表性不足群体的人通过成为知名的 Web 专家来 Rawk the Web。您可以通过 denise@denisejacobs.com 联系她,并在 DeniseJacobs.com 上查看更多信息。