CSS 指南¶
本文档包含关于如何在 Firefox 代码库中编写 CSS 的指南,它尤其与 Firefox 前端工程师相关。
基础知识¶
以下是一些基本技巧,如果您正在更改 CSS,可以优化代码审查。
避免使用
!important
,但如果您必须使用它,请确保很清楚您使用它的原因(理想情况下添加注释)。覆盖 CSS 部分包含更多相关信息。避免使用魔法数字;优先使用自动大小或对齐方法。一些需要避免的示例:
绝对定位元素
硬编码值,例如:
vertical-align: -2px;
。您应该避免此类“硬编码”值的原因是,它们并非在所有字体大小配置下都能正常工作。
避免在 JavaScript 中设置样式。通常最好设置一个类,然后在 CSS 中指定样式。
classList
通常比className
更好。这样可以减少覆盖现有类的可能性。仅当它在语义上是您想要表达的意思时,才使用诸如
:last-child
之类的通用选择器。如果不是,使用语义类名称更具描述性,通常也更好。
样板文件¶
确保每个文件都以标准版权标头开头(请参阅 许可证样板文件)。
在添加更多 CSS 之前¶
最好检查正在编写的 CSS 是否确实需要,因为可能已经编写了一个通用的组件,可以重复使用(无需或只需少量修改)。大多数情况下,通用组件已经遵循本指南中定义的 a11y/主题标准。因此,在可能的情况下,始终优先编辑通用组件而不是编写自己的组件。
此外,当您要设置样式的新元素从另一个元素重复使用某些样式时,最好引入一个通用类,这可以降低维护成本并减少代码重复。
格式¶
空格 & 缩进¶
首选 2 个空格缩进
在每个逗号后添加一个空格,**除了**颜色函数内。
linear-gradient(to bottom, black 1px, rgba(255,255,255,0.2) 1px)
始终在
!important
之前添加一个空格。
省略 0 值的单位¶
这样做
margin: 0;
不要这样做
margin: 0px;
使用扩展语法¶
通常很难理解简写语法的作用,并且简写语法还会隐藏一些不需要的默认值。最好使用扩展语法来明确您的意图。
这样做
border-color: red;
不要这样做
border: red;
将多个选择器放在不同的行上¶
这样做
h1,
h2,
h3 {
font-family: sans-serif;
text-align: center;
}
不要这样做
h1, h2, h3 {
font-family: sans-serif;
text-align: center;
}
类名称命名标准¶
lower-case-with-dashes
最为常见。但有时也会使用
camelCase
。请尝试遵循现有或相关代码的风格。
其他提示¶
在属性选择器中假定
="true"
。示例:使用
option[checked]
,而不是option[checked="true"]
。
除非确实是想要的目标,否则避免使用 ID 选择器,因为 ID 具有更高的特异性,因此更难覆盖。
在可能的情况下,使用后代选择器是一种良好的性能实践
例如:
.autocomplete-item[selected] > .autocomplete-item-title
比.autocomplete-item[selected] .autocomplete-item-title
更有效率
覆盖 CSS¶
在覆盖任何 CSS 规则之前,请检查是否确实需要覆盖。有时,在复制粘贴旧代码时,可能会发生所讨论的代码包含不必要的覆盖。这可能是因为在此期间被覆盖的 CSS 已被删除。在这种情况下,删除覆盖应该可以解决问题。
最好也看看您要覆盖的规则是否仍然需要:也许组件的用户体验规范已更改,并且该规则实际上可以更新或删除。在这种情况下,不要害怕删除或更新该规则。
检查完上述两点后,检查您要覆盖的其他规则是否包含 !important
,如果是,请尝试质疑它,因为它可能已过时。
之后,检查其他选择器的特异性;如果它导致您的规则被覆盖,您可以尝试降低其特异性,方法是简化选择器或更改规则在样式表中的位置。如果这不可行,您还可以尝试引入 :not()
来阻止其他规则应用,这对于不同的元素状态(:hover
、:active
、[checked]
或 [disabled]
)尤其相关。但是,切勿尝试增加您正在添加的规则的选择器,因为它很容易变得难以理解。
最后,在检查完上述所有内容后,您可以允许自己在添加注释说明原因的情况下使用 !important
。
使用 CSS 变量¶
添加新变量¶
在添加新的 CSS 变量之前,请考虑以下问题
**变量值是否在运行时更改?** (无论是来自 JavaScript 还是由另一个 CSS 文件覆盖) **如果答案是否定**,请考虑使用预处理器变量或内联值。
**变量值是否被多次使用?** **如果答案是否定,并且该值在运行时没有更改**,那么您可能不需要 CSS 变量。
**是否有使用变量的替代方法,例如继承或使用 ``currentcolor`` 关键字?** 使用继承或使用
currentcolor
将避免重复值,这通常是一种良好的实践。
总的来说,最好首先考虑如何在没有 CSS 变量的情况下干净地编写一些 CSS,然后再考虑 CSS 变量如何改进该 CSS。
使用变量¶
根据变量的命名方式使用变量¶
这样做
xul|tab:hover {
background-color: var(--in-content-box-background-hover);
}
不要这样做
#certificateErrorDebugInformation {
background-color: var(--in-content-box-background-hover);
}
本地化¶
文本方向¶
对于边距、填充和边框,使用
inline-start
/inline-end
而不是left
/right
。示例:使用margin-inline-start: 3px;
而不是margin-left: 3px
。对于 RTL 感知定位 (左/右),使用
inset-inline-start
/inset-inline-end
。对于 RTL 感知浮动布局,可以使用
float: inline-start|inline-end
代替float: left|right
。border-{top/bottom}-{left/right}-radius
的 RTL 感知等效项为border-{start/end}-{start/end}-radius
当没有可用的特殊 RTL 感知属性时,请使用伪类
:-moz-locale-dir(ltr|rtl)
(对于 XUL 文件)或:dir(ltr|rtl)
(对于 HTML 文件)。请记住,虽然选项卡内容的滚动条在 RTL 中仍然显示在右侧,但溢出滚动条将显示在左侧。
编写
padding: 0 3px 4px;
而不是padding: 0 3px 4px 3px;
。这使填充的对称性更加明显(因此 RTL 不会成为问题)。
注意
有关更多信息,请参阅 CSS 逻辑属性和值。
编写跨平台 CSS¶
Firefox 支持许多不同的平台,并且这些平台中的每一个都可能包含许多不同的配置
Windows 7、8 和 10
默认主题
Aero basic (Windows 7、8)
Windows classic (Windows 7)
高对比度 (所有版本)
Linux
macOS
文件结构¶
browser/
目录包含 Firefox 特定的样式toolkit/
目录包含所有工具箱应用程序(Thunderbird 和 SeaMonkey)共享的样式
在这两个目录中的每一个下,都有一个 themes
目录,其中包含 4 个子目录
shared
linux
osx
windows
shared
目录包含所有 3 个平台共享的样式,而其他 3 个目录分别包含其平台的样式。
对于新的 CSS,在可能的情况下,请尝试优先使用 shared
目录,而不是为 3 个平台特定目录编写相同的 CSS,尤其是在大型 CSS 块中。
内容 CSS 与主题 CSS¶
以下目录也包含 CSS
browser/base/content/
toolkit/content/
这些目录包含内容 CSS,它应用于所有平台,即被认为对于浏览器正确运行至关重要的样式。要确定某些 CSS 是主题端还是内容端,了解某些 CSS 属性会倾向于哪一方很有用:color - 99% 的情况下它将是主题 CSS,overflow - 99% 内容。
99% 主题 |
70% 主题 |
70% 内容 |
99% 内容 |
---|---|---|---|
font-*, color, *-color, border-*, -moz-appearance [1] |
line-height, padding, margin |
cursor, width, max-width, top, bottom [2],等等 |
overflow, direction, display, *-align, align-*, *-box-*, flex-*, order |
如果某些 CSS 与布局或功能相关,则它可能是内容 CSS。如果它与美学相关,则它可能是主题 CSS。
导入样式表时,最好先导入内容 CSS,然后再导入主题 CSS,这样主题值就可以覆盖内容值(这可能是您想要的),并且您希望将它们都放在全局值之后,因此您的导入将如下所示
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/path/module.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/path/module.css" type="text/css"?>
颜色¶
对于 Firefox 界面(面板、工具栏按钮等)的常用区域,mozilla-central 通常会提供一些有用的 CSS 变量,这些变量会根据不同的平台配置调整为正确的值,因此使用这些 CSS 变量可以明确地节省一些测试时间,因为您可以假设它们已经可以正常工作。
使用 currentcolor
关键字或继承也是一种好的做法,因为有时所需的值已经存在于颜色中或父元素上。这与使用 -moz-context-properties: fill;
的图标结合使用时尤其有用,其中图标可以根据文本颜色自动调整到正确的平台颜色。也可以将 currentcolor
与其他属性(如 opacity
或 fill-opacity
)一起使用,以获得平台颜色的不同不透明度。
高对比度模式¶
内容区域¶
在 Windows 高对比度模式下,在内容区域中,Gecko 会对页面颜色进行一些自动颜色调整。这些调整的一部分包括使所有 box-shadow
变得不可见,因此如果您使用 box-shadow
属性创建焦点环或边框,则需要注意这一点:如果希望边框/焦点环在高对比度模式下保持可见,请考虑使用 border
或 outline
。此类错误的一个示例是 错误 1516767。
另一个需要注意的调整是,启用高对比度模式时,Gecko 会删除所有 background-image
。如果图像渲染很重要,请考虑使用实际的 <img>
标签(对于 HTML 文档)或 list-style-image
(对于 XUL 文档)。
如果您未使用 Windows,则在其他平台上测试这些调整的一种方法是
单击“语言和外观”部分的“字体和颜色”子部分中的“颜色...”按钮
在“使用以上选择覆盖页面指定的颜色”下,选择“始终”选项
Chrome 区域¶
前面提到的自动调整仅适用于在内容区域中呈现的页面。Firefox 的 Chrome 区域使用创作时的颜色,因此使用预定义变量、currentcolor
或继承对于与系统主题集成非常有用,并且几乎无需任何麻烦。
否则,作为最后的手段,使用 系统颜色 也适用于非默认 Windows 主题或 Linux。通常,使用以下颜色
-moz-Field
:文本框或字段背景颜色,也用作列表框或树的背景颜色。-moz-FieldText
:文本框或字段文本颜色,也用作列表框或树的文本颜色。-moz-Dialog
:窗口或对话框背景颜色。-moz-DialogText
:窗口或对话框文本颜色。GrayText
:在禁用项上用作文本颜色。不要将其用于未禁用的文本以弱化文本,因为它不能保证未禁用文本具有足够的对比度。ThreeDShadow
:用作元素上的边框。ThreeDLightShadow
:用作元素上的浅色边框。
使用背景/文本对尤其重要,以确保在所有情况下都尊重对比度。切勿将自定义文本颜色与系统背景颜色混合使用,反之亦然。
请注意,使用系统颜色仅对 Chrome 区域有用,因为内容区域颜色无论如何都会被 Gecko 覆盖。
编写媒体查询¶
布尔媒体查询¶
这样做
@media (-moz-mac-yosemite-theme: 0) {
不要这样做
@media not all and (-moz-mac-yosemite-theme) {
为最常见的配置设置权限 CSS¶
最好将最常见的配置(例如操作系统的最新版本或默认主题)放在媒体查询之外。在以下示例中,-moz-mac-yosemite-theme
针对 macOS 10.10 及更高版本,因此它应该优先于 macOS 10.9 的样式。
这样做
@media (-moz-mac-yosemite-theme: 0) {
#placesList {
box-shadow: inset -2px 0 0 hsla(0,0%,100%,.2);
}
}
不要这样做
#placesList {
box-shadow: inset -2px 0 0 hsla(0,0%,100%,.2);
}
@media (-moz-mac-yosemite-theme) {
#placesList {
box-shadow: none;
}
}
主题支持¶
Firefox 内置了 3 个主题:默认、浅色和深色。内置的浅色/深色主题有点特殊,因为它们会加载 compacttheme.css
样式表。除此之外,Firefox 还支持各种可以从 AMO 安装的 WebExtension 主题。出于测试目的,这是一个 WebExtension 主题的示例。
编写主题友好型 CSS¶
一些针对不同平台预先调整的 CSS 变量也针对主题进行了预先调整,因此再次建议您使用它们来支持主题。
元素的文本颜色通常包含来自主题颜色的有价值的信息,因此
currentcolor
/继承再次建议用于主题支持。除非该 CSS 不应影响 WebExtension 主题,否则切勿在
compacttheme.css
中专门为内置的浅色/深色主题编写 CSS。这些选择器可用于定位主题区域,但总的来说,建议您尽量避免使用它们,并使用
light-dark()
自动获取正确的颜色:root[lwt-toolbar-field="light/dark"]
:显式浅色或深色地址栏和搜索栏。:root[lwt-toolbar-field-focus="light/dark"]
:处于聚焦状态下的显式浅色或深色地址栏和搜索栏。:root[lwt-popup="light/dark"]
:显式浅色或深色箭头面板和自动完成面板。:root[lwt-sidebar="light/dark"]
:显式浅色或深色侧边栏。
如果您想要主题区域的不同阴影,并且没有合适的 CSS 变量,则通常使用具有 alpha 透明度的颜色是一个好主意,因为它将保留原始主题作者的颜色色调。
变量¶
为了清楚起见,仅在启用主题时使用的 CSS 变量具有 --lwt-
前缀。
布局和性能¶
布局¶
混合使用 XUL flexbox 和 HTML flexbox 会导致未定义的行为。
CSS 选择器¶
当定位页面的根元素时,使用 :root
是最有效的方法。
重排和样式刷新¶
有关此内容的更多信息,请参阅 Firefox 前端工程师的性能最佳实践。
其他¶
文本抗锯齿¶
在方便的情况下,避免在文本上设置 opacity
属性,因为它会导致文本以不同的方式进行抗锯齿。
HDPI 支持¶
建议使用 SVG,因为它在支持多种分辨率时可以保持 CSS 整洁。有关 SVG 用法的更多信息,请参阅 SVG 指南。
但是,如果只有 1x 和 2x PNG 资产可用,则可以使用此 @media
查询来定位更高密度的显示器 (HDPI)
@media (min-resolution: 1.1dppx)