css规则_CSS规则,将使您的生活更轻松

css规则

by Nick Gard

尼克·加德(Nick Gard)

CSS规则,将使您的生活更轻松 (CSS rules that will make your life easier)

After years of writing and maintaining a couple of very large web projects and numerous smaller ones, I have developed some heuristics for writing maintainable CSS. I have used BEM, SMACSS, and CSS Modules for naming, though this article is not about naming, per se. (I tend to use a mix of atomic classes and BEM-ish naming.) This article is more about the properties and values I use or avoid.

经过多年的编写和维护,我们开发了一些启发式方法,以编写可维护CSS。 我已经使用BEM,SMACSS和CSS模块进行命名,尽管本文本身并不是关于命名的。 (我倾向于混合使用原子类和类似于BEM的命名。)本文更多地是关于我使用或避免使用的属性和值。

My StyleLint config: https://github.com/NickGard/css-utils/blob/master/stylelint.config.json

我的StyleLint配置: https : //github.com/NickGard/css-utils/blob/master/stylelint.config.json

色彩 (Colors)

A pet peeve of mine is an over-abundance of color values in a web project. A large, long-lived project I worked on a few years ago had over 300 unique colors declared across 40-some CSS files. A third of these were shades of grey. Brand colors were repeated with slight differences of hue. Many of these colors differed by literally imperceptible values, like #3426D1 and #3426D2. The solution to this is to either use atomic color classes or variables (in SCSS or CSS) for the accepted brand colors.

我的宠儿是Web项目中过多的颜色值。 几年前我从事的一个大型,长期的项目在40多个CSS文件中声明了300多种独特的颜色。 其中三分之一是灰色阴影。 重复品牌颜色,但色调略有不同。 这些颜色中的许多颜色之间在字面上难以察觉,例如#3426D1#3426D2 。 解决方案是对接收的品牌颜色使用原子颜色类或变量(在SCSS或CSS中)。

Limiting the number of accepted colors has the added benefit of making it simple to ensure that the background and foreground colors meet the WCAG2.0 Color Contrast guidelines.

限制可接受的颜色数量具有使确保背景和前景色符合WCAG2.0颜色对比准则的简单优势。

Another bug-prone practice is using alpha-channel colors, usually by declaring the color with rgba() or hsla() functions. A color created this way with an alpha channel value of anything other than 1 is semi-opaque. The perceived color now changes depending on what is in the background. Usually, the desired color is what this one looks like over a white background, so you can use a hex value instead. Some preprocessor functions, like SASS’s lighten(), will generate a semi-opaque color, so stick to hard-coded values or variables.

另一种容易出错的做法是使用alpha通道颜色,通常是通过使用rgba()hsla()函数声明颜色。 用这种方式创建的Alpha通道值不是1的颜色是半透明的。 现在,可感知的颜色会根据背景的不同而变化。 通常,所需的颜色是该颜色在白色背景上的外观,因此可以使用十六进制值代替。 一些预处理器函数(例如SASS的lighten()将生成半透明的颜色,因此请坚持使用硬编码的值或变量。

版式 (Typography)

All properties that affect or are affected by the font should be declared once together. Right after declaring any @font-face rules, I like to add atomic classes for the font that change the font-size (via rem) and include line-height, letter-spacing, and word-spacing that are appropriate for that combination of font and size. After that, no font-* or text-* (with the exception of text-overflow) property should be used in any ruleset.

影响字体或受字体影响的所有属性应一起声明一次 。 在声明任何@font-face规则之后,我想为字体添加原子类,以更改font-size (通过rem ),并包括适用于该组合的line-heightletter-spacingword-spacing 。字体和大小。 在那之后,任何规则集中都不应使用font-*text-* ( text-overflow除外)属性。

Declaring these properties once in conjunction with the font-face ensures that the copy on the site always looks right. Adjusting the line-height instead of padding or margin will create bugs when the text wraps. Adjusting font-weight separately from the font declaration runs the risk of creating a faux bold font. Changing font-style on a font that doesn’t support it creates a faux oblique.

将这些属性与字体一起声明一次,可确保网站上的副本始终看起来正确。 line-height调整line-height而不是paddingmargin会产生错误。 与字体声明分开单独调整font-weight冒创建人造粗体字体的风险。 在不支持的字体上更改font-style会创建一个仿斜角。

Lastly, avoid setting font sizes in anything other than rem units. Using em causes problems when nesting elements because em is a scalar multiple of the current font-size. Using px (or any other “fixed” measurement) risks creating copy that is difficult to read and impossible for the user to adjust. Allow the user (or the user’s browser) to set the font-size to what is right for them by not declaring a font-size on the body or html element and only using rem.

最后,避免以rem单位以外的任何方式设置字体大小。 在嵌套元素时使用em会引起问题,因为em当前 font-size的标量倍数。 使用px (或任何其他“固定”度量)会产生难以阅读 用户无法调整的副本。 通过不在bodyhtml元素上声明font-size ,而仅使用rem允许用户(或用户的浏览器)将font-size设置为适合他们的font-size

间距 (Spacing)

On a content-first site, spacing should complement copy. Any static measurement, like padding: 4px, looks wrong at some font size. A dynamic measurement responsive to font sizes, like padding: .5em, looks right at every font size.

在内容优先的网站上,空格应补充副本。 在某些字体大小下,任何静态测量(例如padding: 4px )看起来都是错误的。 响应字体大小的动态度量,例如padding: .5em ,可以正确地查看每种字体大小。

Use em for spacing properties.

使用em作为间距属性。

(Grid)

CSS Grid is very well supported (back to IE10!) and allows the arranging of content in two dimensions without added container elements like Bootstrap’s row or col grid elements. Designers often work in 12-column grids and CSS frameworks tend to follow suit but grids, like all spacing, should complement copy, not constrain it. Grids should be written ad hoc, not in a pre-determined format without context. Do not bloat your CSS with a “grid framework.”

CSS网格很好的支持 (回IE10!),并允许在两个维度上的内容安排不添加容器元素,如引导的rowcol网格元素。 设计人员通常在12列的网格中工作,而CSS框架往往会效仿,但是网格像所有间距一样,应该补充副本,而不是限制副本。 网格应该是临时编写的,而不是没有上下文的预定格式。 不要使用“网格框架”来夸大CSS。

文字对齐 (Text alignment)

text-align is often used to align things other than text. This is not the right tool for the job. Use flexbox for this kind of alignment. Using the values left and right doesn’t always work with languages that are right-to-left or vertical (some browsers map these values to the flow-relative start and end, but not all). Using the value justify on text can cause problems in some languages with digraphs, and it can cause problems for people with dyslexia. Every use case for text-align is better solved by flexbox, so use that instead. Always.

text-align通常用于对齐文本以外的内容。 这不是完成这项工作的正确工具。 使用flexbox进行这种对齐。 使用值leftright并不总是与那些从右到左或垂直语言工作(某些浏览器将这些值映射到流相对startend ,但不是全部)。 在文本上使用价值justify可能会在某些语言中使带字的单词出现问题,并可能给阅读障碍的人带来麻烦 。 flexbox可以更好地解决每个text-align用例,因此请改用它。 总是。

概述 (Outlines)

Outlines on focused elements are how browsers natively communicate which element is receiving input. The default outlines are usually prominent enough to be useful to every user, including those needing high contrast. The default outline is usually overwritten (or removed) because it doesn’t fit with the site’s design. Unless you are replacing the focused outline style with some other prominent and accessible focus indicator, do not remove or nullify the outline property.

关于重点元素的概述是浏览器如何本地交流哪个元素正在接收输入。 默认轮廓通常醒目到足以对每个用户都有用,包括那些需要高对比度的用户。 默认轮廓通常会被覆盖(或删除),因为它与网站的设计不符。 除非您聚焦outline样式替换为其他突出且可访问的聚焦指示符, 否则不要删除或使outline属性无效

焦点与悬停 (Focus & Hover)

As mentioned above, beware changing :focus styling because it acts as an indicator for which element is currently receiving input. Adding styles to an element on :hover is often a nice touch, but do not use that pseudo-selector to show additional copy unless you do the same for :focus (and, of course, if the element is focusable). It is usually, but not always, a good idea to use both the :hover and :focus pseudo-selectors for the same ruleset. (Adding the :focus selector to the hover styles for a button can result in a pressed button looking “stuck” on.)

如上所述,请注意更改:focus样式,因为它充当当前哪个元素正在接收输入的指示符。 添加样式上的元素:hover往往是一个很好的接触,但不要使用伪选择显示其他副本,除非你做同样的:focus (当然,如果该元素是可聚焦 )。 通常,但并非总是一个好主意,对于同一规则集同时使用:hover:focus伪选择器。 (将:focus选择器添加到按钮的悬停样式中可能会导致按下的按钮看起来“卡在”状态。)

不透明度 (Opacity)

Setting the opacity of an element to 0 does not actually hide it from accessibility tools. The element still takes up room in the flow of the document and its copy is still read by screen-readers. The only two use-cases that reasonably call for the use of the opacity property is when transitioning an element into view (transition quickly from 0 to 1) and when styling a dialog overlay (so the content below is somewhat visible). Beware of “stacked” semi-opaque overlays. The opacity level is multiplicative, so the content below two overlays each with opacity: 50% is shown as if it is below a single element with opacity: 25%.

将元素的opacity设置为0并不会实际上将其隐藏在可访问性工具中。 该元素仍在文档流中占据空间,并且屏幕阅读器仍会读取其副本。 合理要求使用opacity属性的两个用例是在将元素转换为视图时(快速从0过渡到1 )和对对话框覆盖进行样式设置(因此下面的内容有些可见)。 当心“堆叠”的半透明覆盖层。 不透明度级别是可乘的,因此两个覆盖下的内容每个都有opacity: 50%就好像它位于一个opacity: 25%的单个元素下面。

选择器 (Selectors)

Stick to using class and class-like selectors. Using id, type, and universal selectors come with headaches. In CSS specificity, id selectors will always win against any other selector, but id attributes are supposed to be unique (per page) so they’re not useful for applying reusable styles.

坚持使用类和类选择器。 使用id,type和通用选择器会让人头疼。 在CSS特定性中,id选择器将始终与其他选择器抗衡,但是id 属性应该是唯一的 (每页),因此它们对应用可重用样式没有用。

Selector performance in modern browsers is a negligible concern, so despite what you may have heard about the universal selector (*) not being performant, my real concern with its use is that it is too general for almost every use-case. Using some selector like .my-class >; * will eventually lead to opting out some child, so you might as well add classes to the elements you wish to style and target them directly.

在现代浏览器中,选择器的性能可以忽略不计,因此尽管您可能听说过通用选择器( * )的性能不佳,但我真正关心的是它的使用对于几乎所有用例而言都过于笼统。 使用一些选择器,例如.my-class > ; *最终会导致选择退出某些子项,因此您最好将类添加到要设置样式并直接定位它们的元素。

A similar argument can be made for not using type selectors, like div, main. They tend to match too many elements and usually require more details to be useful, such as div.some-class. Compound selectors like this have a higher specificity than a single class selector, a bug-generating problem addressed below.

对于不使用类型选择器(例如divmain可以做出类似的论点。 它们倾向于匹配太多元素,通常需要更多细节才能有用,例如div.some-class 。 像这样的复合选择器比单个类选择器具有更高的特异性,下面将解决导致错误的问题。

Stick to class (.class), attribute ([attribute]), and pseudo-class (:focus) selectors. They all have the same level of specificity.

坚持使用类( .class ),属性( [attribute] )和伪类( :focus )选择器。 它们都具有相同的特异性水平。

特异性 (Specificity)

At the opposite end of the spectrum of selectors being too general (like using *) are selectors being too specific. Both cases cause problems. An overly-specific selector breeds even more specific selectors or the dreaded !important declarations. Each successive selector becomes a new hurdle to overcome when making styling changes, and following this path leads to the ever-growing fragile stylesheets we all dread working with.

在选择器范围的另一端,选择器过于笼统(例如使用* )。 两种情况都会引起问题。 过于具体的选择器会滋生甚至更具体的选择器或可怕的!important声明。 进行样式更改时,每个接连的选择器都将成为克服的新障碍,而遵循这条道路会导致我们所有人都惧怕的不断增长的脆弱样式表。

CSS has a naturally increasing specificity — the order of the rulesets. This is part of the cascade in Cascading Style Sheets. With this in mind, we can write rulesets in ascending order of “importance” without increasing the selector specificity level. For example:

CSS具有自然增加的特殊性-规则集的顺序。 这是级联样式表中级联的一部分。 考虑到这一点,我们可以按“重要性”的升序编写规则集,而无需增加选择器的特异性级别。 例如:

.btn {  color: black;}.btn--primary {  color: green;}.btn--primary--light {  color: white;}

In this example, each single-class-selector is more specific than its predecessor, eliminating the need to declare a ruleset for .btn.btn--primary or .btn.btn--primary--light.

在此示例中,每个单一类选择器都比其前任更为具体,从而无需声明.btn.btn--primary.btn.btn--primary--light规则集。

The fix is to stick to single class selectors as much as possible, written in order of increasing “importance,” and avoid using !important declarations.

解决方法是尽可能地坚持单一类选择器,以增加“重要性”的顺序编写,并避免使用!important声明。

文字转换 (Text-transform)

For sites that support languages other than English, using text-transform will probably cause problems. There are several cases where browsers replace a character with an incorrect version for the upper- or lower-case transformations. The fix is never to use text-transform and instead rely on an accurately capitalized copy.

对于支持英语以外其他语言的网站,使用text-transform可能会引起问题。 在某些情况下,浏览器会使用大写或小写转换用不正确的版本替换字符 。 解决方法是永远不要使用text-transform ,而要依靠准确大写的副本。

Z指数 (Z-index)

If any z-index rule is included in a stylesheet, there will eventually be two other rules that declare z-index: 9999; and z-index: 99999;. Attempting to use atomic classes or variables to limit the number of acceptable z-indexes will not only fail to curb developers from using calc() and SCSS math to modify the value for their use-case, but will miss the target entirely because of how stacking contexts work.

如果样式表中包含任何z-index规则,则最终会有另外两个声明z-index: 9999;规则z-index: 9999;z-index: 99999; 。 尝试使用原子类或变量来限制可接受的z索引的数量,不仅将无法阻止开发人员使用calc()和SCSS数学来修改其用例的值,而且将完全无法达到目标,因为堆栈上下文工作。

It has been my experience that most, if not all, uses of z-index can be replaced by restructuring the HTML to use the natural stacking context (elements lower on the page are higher in the context) or by adding a property to the element or its parent to force a new stacking context.

根据我的经验,可以通过重构HTML以使用自然堆叠上下文(页面中元素越低,上下文中越高)来替换z-index大多数(如果不是全部)用途,或者通过向元素添加属性或其父级强制一个新的堆栈上下文

Avoid z-index at all costs.

不惜一切代价避免使用z-index

伪元素 (Pseudo-elements)

Using the pseudo-elements ::before and ::after is not only helpful, but it’s often fun! Many stylistic tricks rely on the use of these two pseudo elements and, as long as there is no copy in them (via their content property), they are considered semantic. The issue with putting copy in these elements is that whether or not they are read by accessibility devices varies across browsers and devices. It is better to not deal with that discrepancy by avoiding placing a copy in them.

使用伪元素::before::after不仅有用,而且通常很有趣! 许多样式技巧都依赖于这两个伪元素的使用,并且只要它们中没有副本(通过它们的content属性),它们就被视为语义。 将副本放入这些元素的问题在于,可访问性设备是否读取它们在浏览器和设备之间会有所不同。 最好通过避免在副本中放置副本来处理这种差异。

The pseudo-elements ::first-letter and ::first-line do not work like you probably think they should. They only target the first letter/line in a block-level element. There are also issues with the ::first-line selector incorrectly targeting double-byte characters (such as Japanese Kana) and digraphs.

伪元素::first-letter::first-line不能像您可能认为的那样工作。 它们仅针对块级元素中的第一个字母/行。 ::first-line选择器还错误地将双字节字符(例如日语假名)和有向图定位到目标。

Manipulating the styles of selected text or placeholder text via ::selection and ::placeholder, respectively, often leads to trouble. With ::placeholder, the concern is simple: you shouldn’t be using placeholders. This is especially true for anything of importance, such as input labels or hints. By including ::placeholder styles, you encourage developers, designers, and authors to use them, much to the frustration of your users.

分别通过::selection::placeholder操纵所选文本或占位符文本的样式通常会带来麻烦。 使用::placeholder ,问题很简单: 您不应该使用placeholders 。 对于任何重要的事情,例如输入标签或提示,尤其如此。 通过包含::placeholder样式,您可以鼓励开发人员,设计师和作者使用它们,这在很大程度上使用户感到沮丧。

Modifying selection styles, usually color and background-color, leads to more subtle but insidious bugs. While the default selection colors are not consistent across browsers or devices and they do not always provide an acceptable contrast with your site’s text color, users sometimes overwrite them for accessibility reasons. Changing the colors, in this case, could either not work (because of the user’s accessibility CSS trumps yours) or it could interfere with their style sheets (if you use !important). Using this pseudo-element to try to guarantee an accessible contrast could end up disrupting the experience for the very people you wish to help.

修改选择样式(通常是colorbackground-color )会导致更细微但隐蔽的错误。 尽管默认选择颜色在浏览器或设备之间不一致,并且不能始终与您网站的文本颜色形成可接受的对比,但是出于可访问性的原因,用户有时会覆盖它们。 在这种情况下,更改颜色可能不起作用(因为用户的可访问性CSS胜过您CSS)或可能会干扰其样式表(如果使用!important )。 使用此伪元素尝试确保可访问的对比度可能最终破坏您希望帮助的人们的体验。

(Though I’ve forgotten many of the details of this bug, I ran into an issue years ago where Chrome’s auto-translated text was rendered invisible because it relied on ::selection styling which I had modified.)

(尽管我已经忘记了该错误的许多细节,但几年前我遇到了一个问题,由于它依赖于我修改过的::selection样式,因此Chrome的自动翻译文本不可见。)

转场和动画 (Transitions & Animations)

Transitioning or animating properties other than opacity and transform causes the browser to repaint or reflow the page. This may not seem like a problem on a high-end developer machine, but it will cause stuttering on low-end laptops and phones. Bad animation is worse than no animation.

转换或设置除opacitytransform之外的属性的动画,会导致浏览器重新绘制或重排页面。 在高端开发人员机器上,这似乎不是问题,但会在低端笔记本电脑和手机上造成停顿。 不良动画比没有动画更糟糕。

喜欢减少运动 (Prefers Reduced Motion)

Writing animations that are helpful, beautiful, and safe is not a simple undertaking. With the advent of the media query prefers-reduced-motion, we can help make our pages safer for people with vestibular disorders, and less annoying for the rest of us. While adding this media query is not a silver bullet, it helps. I’ve written the nested rule to be opt-out, meaning that all CSS animations get stopped unless the author includes the class safe-animation on the element.

编写有用,美观且安全的动画绝非易事。 随着媒体查询“ prefers-reduced-motion ,我们可以使我们的页面对前庭疾病患者更安全,而对其他人则减少烦恼。 尽管添加此媒体查询不是灵丹妙药,但它会有所帮助。 我已将嵌套规则写为退出,这意味着除非作者在元素上包括类safe-animation ,否则所有 CSS动画都会停止。

/* https://github.com/mozdevs/cssremedy/issues/11#issuecomment-462867630 */@media (prefers-reduced-motion: reduce) {  *:not(.safe-animation),  *:not(.safe-animation)::before,  *:not(.safe-animation)::after {    animation-duration: 0.01s !important;    animation-iteration-count: 1 !important;    transition-duration: 0s !important;    scroll-behavior: auto !important;  }}
重置扩展 (Reset extensions)

My go-to CSS reset is a modified form of the Meyers reset. There are a few rules I remove from the reset, though. I don’t like to remove list icons from ol and ul elements. I find that doing so encourages developers to use those elements in non-semantic ways, like grouping items that are physically proximate but not ontologically proximate. I also remove the rule setting the line-height on the body to 1. Setting attributes that affect, or are affected by, the font separately from setting the font is a bug waiting to happen.

我CSS重置是Meyers重置的一种修改形式。 不过,我从重置中删除了一些规则。 我不喜欢从olul元素中删除列表图标。 我发现这样做鼓励开发人员以非语义方式使用这些元素,例如将物理上接近但本体上不接近的项目进行分组。 我还删除了将bodyline-height设置为1 。 与设置字体分开设置影响字体或受字体影响的属性是一个等待发生的错误。

Some additions I make to the reset file are below. I do not like to include a .hidden atomic class in my CSS because there is a better option that will work even if the CSS doesn’t load — the hidden attribute. The default browser behavior of setting display: none on hidden elements can be overwritten, even accidentally, so I include a rule to enforce it.

下面是我对重置文件所做的一些补充。 我不喜欢在CSS中包含.hidden原子类,因为有一个更好的选项即使CSS没有加载也可以使用hidden属性。 设置display: none的默认浏览器行为display: none隐藏元素上的display: none内容都不会被覆盖,即使是偶然也不会被覆盖,因此我加入了一个强制实施规则。

body {  /* more intuitive sizing */  box-sizing: border-box;}*, ::before, ::after {  box-sizing: inherit;}i, cite, em, var, dfn, address {  /* prevent faux italic */  font-style: normal;}b, h1, h2, h3, h4, h5, h6, strong, th {  /* prevent faux bold */  font-weight: normal;}[hidden] {  /* enforce accessible semantics */  display: none !important;}

My Reset: https://github.com/NickGard/css-utils/blob/master/reset.css

我的重置: https : //github.com/NickGard/css-utils/blob/master/reset.css

Another utility that I often find necessary is a visually-hidden class. While I use aria-label more often for invisible screen-readable text, I usually include the following rule somewhere:

我经常发现有必要使用的另一个实用工具是visually-hidden类。 虽然我更经常将aria-label用于屏幕上不可见的文本,但我通常在以下位置包含以下规则:

/* https://a11yproject.com/posts/how-to-hide-content/ */.visually-hidden {  position: absolute !important;  height: 1px;  width: 1px;  overflow: hidden;  clip: rect(1px, 1px, 1px, 1px);}
BEMish命名 (BEMish naming)

I can’t end this article without at least one comment on naming conventions. I like the BEM naming because it reads well. <button class="btn--primary" /> tells me exactly what kind of button it is. My one break from the Official BEM™ methodology is that I like to use one class on an element (with the possible exception of atomic classes). It offends my sensibilities to see <button class="btn btn--primary" /> because the second class already tells me the styles extend from the base btn ruleset. This also creates two reasons for a line to change, which is a red flag.

如果没有关于命名约定的至少一条评论,我将无法结束本文。 我喜欢BEM命名,因为它读起来很好。 <button class="btn--primary" />告诉我确切的按钮类型。 我从官方BEM™方法的一次破发是我如T O u那样瑟的元件上的一个类(atomic类可能是个例外)。 它冒犯我的感情吨o see <button class="btn btn--pr imary” />,因为第二类已经告诉我的样式延伸FR om基BTN规则集。 这也是造成线数变化的两个原因 ,这是一个危险信号。

In my CSS, this looks like this:

在我CSS中,如下所示:

.btn, .btn--primary {  /* base button styles */}.btn--primary {  /* primary button overrides */  /* has naturally higher specificity */}

In SCSS, you can achieve this same effect using @extend.

在SCSS中,您可以使用@extend达到相同的效果。

结论 (Conclusion)

These have been my rules of thumb for several years now and have helped me maintain large codebases with many contributors. It’s not perfect and I’m always adjusting it (prefers-reduced-motion is new) but I hope that by sharing it, it will help others.

几年来,这些一直是我的经验法则,并帮助我维护了许多贡献者的大型代码库。 它不是完美的,我一直在调整它( prefers-reduced-motion是新的),但我希望通过分享它可以对其他人有所帮助。

翻译自: https://www.freecodecamp.org/news/css-rules-to-live-by-962a051e1eb2/

css规则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值