[关闭]
@a06062125 2016-05-28T17:32:02.000000Z 字数 8619 阅读 391

Reuse

重用

Summary: Don’t try and reuse styles. Adopt a duplication-first approach.

摘要: 不要重要样式,也不要做尝试. 采用重复优先的方法。

“DRY is often misinterpreted as the necessity to never repeat the exact same thing twice […]. This is impractical and usually counterproductive, and can lead to forced abstractions, over-thought and [over]-engineered code.“

— Harry Roberts, CSS Wizardy

“DRY(不要重复自己)常被误解为永远不要重复做同样的事情[…]. 这是不切实际的, 适得其反, 它可能导致强制抽象、过度思考和过度工程化的

— Harry Roberts, CSS Wizardy

Don’t take this the wrong way—MaintainableCSS has various strategies for reuse which I will talk about later. The problem is that trying to reuse the bits inbetween the curly braces is problematic. Here’s why:

不要陷入DRY的误区—MaintainableCSS 有多种重用策略,我们稍后加以讨论。问题是尝试重用花括号之间的代码段是有疑问的。原因如下:

Because styles change based on breakpoints.

因为样式随着视图改变

Building responsive sites mean that we style elements differently based on viewport size. Imagine trying to build a 2 column grid that:

构建响应式站点意味着我们根据视口尺寸为元素添加不同的样式。 设想尝试构建一个2列网格:

With this in mind how can you utilise these atomic class names: .grid, .col, .pd50, .pd20, .fs2 and fs3 and achieve these specs?

出于这种考虑, 你怎么使用这些原子类名:.grid, .col, .pd50, .pd20, .fs2fs3, 实现以上需求?

  1. <div class="grid">
  2. <div class="col pd50 pd20 fs3 fs2">Column 1</div>
  3. <div class="col pd50 pd20 fs3 fs2">Column 2</div>
  4. </div>

You can see this just isn’t going to work. You now need some crazy class names such as fs3large. This is just the tip of iceberg when it comes to maintenance issues.

你发现上面的片断实现不了需求。为了达到目标,你还需要一些更疯狂的类名,比如 fs3large. 这只是维护阶段常见问题的冰山一角。

Alternatively, take the following semantic mark-up that doesn’t attempt to reuse styles:

或者, 试试下面没有重用样式的语义化标记:

  1. <div class="someModule">
  2. <div class="someModule-someComponent"></div>
  3. <div class="someModule-someOtherComponent"></div>
  4. </div>

Ensuring this is styled as specified above, is now a simple task with 6 CSS declarations needed in total, 3 of which reside within media queries.

确保按照说明为上面的代码添加样式, 现在它变成一个总共只需要6个CSS声明的简单任务, 其中3个声明分布在媒体查询中。

Because styles change based on states.

因为样式随着状态改变

How do you make <a class="padding-left-20 red" href="#"></a> to have padding 18px, a slight border, a background of grey and a text colour as a slightly darker shade of red when it’s hovered or focused of active i.e. :hover,:focus, :active etc?

可以让 <a class="padding-left-20 red" href="#"></a> 在hover态或者获取焦点时(如 :hover,:focus, :active 等)样式发生这样的改变:padding值变为18px, 添加一个浅色边框, 背景灰色,红色文本有稍暗的阴影吗?

The short answer is you can’t. Try to avoid having to fix self-induced problems.

答案是不行。尽量避免去修复自找的问题。

Because reuse makes debugging more difficult.

因为复用让调试变得更难

When debugging an element, there will be several applicable CSS selectors playing a part making it noisy.

调度元素时,可能会有一些起作用的CSS选择器使调试变得麻烦。

Because granular styles aren’t worth bothering with.

因为没必要为了颗粒样式烦恼

If you’re going to do <div  class="red"> you may as well do <div style="color: red"> which is more explicit anyway. But we don’t want to do this because we don’t want to mix concerns.
如果我们用<div  class="red"> 表示一个层的字体为红色,直接用行内式 <div style="color: red">的结果是一样的,也更明确易理解。但是我们不想用行内式, 因为我们不想把问题混在一起。

Because visual class names don’t hold much meaning.

因为视觉类名的含义有限

Take red. Does this mean a red background? Does this mean red text? Does this mean a red gradient? What tint of red does this mean?
比如red 这个类名, 它是指红色背景呢, 还是指红色文本?还是红色渐变?到底什么属性的值是红色?

Because updating a “utility” class applies to all instances.

因为更新后的工具类会适用于所有的实例

This sounds good but it isn’t. You end up applying changes where you didn’t mean to. Think regression. Alternatively, you end up scared to touch this utility class so you end up with .red2. Then you end up with redundant code. Obviously this is not fun to maintain.

听起来很美好,但其实并非如此。结果是有些地方的修改并非你本意。想想回退。或者, 由于害怕修改这些工具类引起的麻烦后果,你又添加了一个 .red2类, 这样的结果是产生了冗余代码。很明显维护这样的代码一点也不开心。

Because non-semantic class names are hard to find.

因为非语义化的类名很难查找

If an element has classes based on how it looks such as .red, .col-lg-4 and .large, then these classes will be scattered all over the codebase so searching for “red” will yield many results across the HTML templates, making it hard to find the element in question.

假如元素的类名是基于外观的, 比如 .red, .col-lg-4.large,通常这些类名四散在代码库中, 检索“red”,会得到许多遍布于HTML模板中的结果, 想要确定哪个是问题元素就变难了。

If you use semantic class names, a search should yield just one result. And if it yields more than one result, then this should indicate a problem that needs dealing with.

假如你使用语义类名, 一次检索应该只有一条结果。如果结果不止一条, 这说明应该有些问题需要解决。

Note: if you have a repeated component within a module, then searching might yield several results within 1 file. That is, a module would typically live in a single template.

注意: 假如有一个重复组件内置模块, 大量检索结果可能来自同一个文件。 也就是, 一个模块通常需要在一个单独的模板中维护。

Because reuse causes bloat.

因为重用引起了膨胀

If you attempt to reuse every single rule you’ll end up with classes such as: red, clearfix, pull-left, grid which leads to HTML bloat:

假如你尝试重用每一个单一规则 , 最终你会有许多这样的类: red, clearfix, pull-left, grid, 这会导致 HTML膨胀:

  1. <div class="clearfix pull-left red etc"></div>

Bloat makes it harder to maintain and degrades performance (albeit in a minor way).

膨胀带来的后果是维护变难, 性能降级(虽然很小)。

Because reuse breaks semantics.

因为重用破坏语义

If you strive to reuse the bits inbetween the curly braces to create “atomic” class names, then you encounter all the problems stated in the chapter about Semantics. Read that chapter now, if you haven’t already.

假如你力图重用花括号间的代码来创建原子类名, 你将遇到语义化章节中描述的所有问题。假如你还没读过, 现在就去读一下。

What if I really want to reuse a style?

假如我真的想要重要样式呢?

It is extremely rare, but there are times when it really does make sense to reuse a style. In this case use the comma in your selectors and place it in a well named file.

这是极为罕见的, 但有时重用样式的确很有道理 。这种情况下, 在选择器中使用逗号, 并采用良好命名的方式 。

For example let’s say you wanted a bunch of different modules or components to have red text you might do this:

例如, 你有一堆模块或组件的文本都是红色, 你可以这样做:

  1. /* colours.css */
  2. /* red text */
  3. .someSelector,
  4. .someOtherSelector {
  5. color: red;
  6. }

Remember though that if any selector deviates, even a little bit, then remove it from the common list and duplicate. You must be very careful with something like this. Do it for convenience, not for performance. Your mileage may vary.

谨记,假如哪个选择器的样式发生了变化, 哪怕只有一点点, 一定要把它从通用列表中移除, 并拷贝一个单独的出来。 对这种情况你一定要非常小心。 这样做是为了方便, 而不是为了性能. 你的情况可能有所不同

What about mixins?

怎么看 mixins ?

CSS preprocessors allow you to create mixins which can be really helpful because they provide the best of both worlds but they should be designed with caution.

CSS 预处理器允许你创建mixins, 空们非常有用,因为它们都提供了各自最好的部分, 设计mixins时也要多加谨慎。

You have to be very careful to update a mixin because it propagates in all instances just like utility classes. It can be problematic to edit and instead you create new mixins that are slightly different causing redundancy and maintenance problems.

更新mixin时要非常要小心, 和工具类一样, 对mixin的修改会扩展到所有的实例。 修改mixins时可能会有些棘手,假如你选择创建新的mixins,也可能引起一些轻微的冗余和维护问题。

Also, mixins can become very complicated with lots of params, conditionality and large declarations of styles. All of this makes it complicated and complicated is hard to maintain.

而且, 大量的参数、条件、和大量的样式声明也可能让mixins变得非常复杂。 这些都会让它复杂到难于维护。

To mitigate, you can make mixins really granular. For example you could have a “red text” mixin which is certainly better. But then again, the declaration of that mixin is basically the same as a declaration of red text—might as well just declare that instead.

为了减轻负担, 你可以把mixins颗粒化。 比如可以有一个mixin叫“red text”,专门设置文本颜色为红色, 这样当然很好。但又回到了颗粒样式 的问题,这个mixin声明和类声明<div class="red">、行内式 <div style="color: red">意义是一样的,或许还不如不用mixin呢。

If you need to update it in multiple places, then a search and replace might just do it, depending on your context. And even if you did use a mixin, when red changes to orange, you will have to do a search and replace anyway, because the mixin name will otherwise be misleading.

假如你想在许多地方更新mixins, 查找和替换可能就能搞定, 取决于你的上下文。即使你真的用了mixin, font-color从红色变成橙色,你不得不进行查找,替换掉原来的mixin, 因为假如只改了mixin里的样式规则,而不改mixin的命名,这个mixin就会产生误导性。

This does not mean mixins are “bad”—in fact they can be very helpful. For example, being able to apply clearfix rules across different elements at different breakpoints is probably a very helpful thing to do for maintainability. Just make sure to use them with care.

这并不意味mixins不好。实际上它们非常有用。比如, 它让在不同的视口里为不同的元素上应用 clearfix 规则变得可能, 这可能是件对可维护很有利的事。只要确保谨慎操作就好了。

What about performance?

怎么看性能

I don’t have stats to hand, but I can very confidently say that it’s not wise to practice premature optimisation. Let’s say you have a very large CSS codebase (100KB or more).

关于性能尚无统计结果, 但是我会非常自信得说, 过早优化并不明智。 我们来谈论下超大CSS代码库的情况还(>=100KB)

Firstly, I guess you might save yourself a few KB. Secondly, there are alternative paths to improving performance and thirdly, you probably have redundant code due to a lack of maintainability.

首先, 我猜你会先自己想些办法减少一些代码容量, 然后, 有许多可供选择的途径来提升性能, 再次, 冗余代码可能是由于缺乏维护造成的。
Also consider that one or two images are likely to be far larger than the entire CSS so exerting energy here is probably of little value.

同时也要考虑下超大尺寸图片的问题, 有些单张图片的尺寸都有可能远远超过整个CSS文件的大小。 所以在修改CSS上花费心思可能收益不大。

Is this violating DRY principles?

它违背了DRY原则吗?

Attempting to reuse float: left as an example, is akin to trying to reuse variable names in different Javascript objects. It’s simply not in violation of DRY.

举例说明,复用float: left规则类似于在不同的Javascript对象中重用变量名。并不违背DRY原则。

Final thoughts on reuse

关于复用的最后思考

Reuse and DRY are such important principles in software engineering but when it comes to CSS, striving to reuse too much ironically makes maintainance harder. However, there are times when reuse and abstraction makes sense which is discussed in later chapters.
复用的DRY(Don't Repeat Your Self) 都常软件工程领域中非常重要的原则, 但是到了CSS, 具有讽刺意味的是, 努力复用太多反而让维护变得 更麻烦。不管怎样, 有进复用和抽象也是很有意义的, 详情我们会在后面的章节加以讨论。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注