원본 링크: https://hacks.mozilla.org/2016/05/css-coding-techniques/
번역 링크: http://www.zcfy.cc/article/css-coding-techniques-x2605-mozilla-hacks-8211-the-web-developer-blog-1244.html
최근에는 초보자든 숙련된 개발자든 CSS로 인해 어려움을 겪는 사람들이 많다는 것을 알게 되었습니다. 당연히 그들은 이를 대체할 더 나은 언어를 원했고 CSS 전처리기는 이러한 아이디어에서 탄생했습니다. 어떤 사람들은 코드 작성을 줄이기 위해 CSS 프레임워크를 사용하기를 원합니다(이전 기사에서 이것이 왜 좋은 해결책이 아닌지 살펴봤습니다). 어떤 사람들은 CSS를 버리고 JavaScript를 사용하여 스타일을 적용하기 시작했습니다.
그러나 작업 흐름에서 항상 CSS 전처리기를 사용할 필요는 없습니다. 모든 프로젝트의 기본 시작점으로 비대해진 프레임워크를 사용할 필요는 없습니다. CSS가 수행해야 하는 작업을 수행하기 위해 JavaScript를 사용하는 것은 끔찍한 생각입니다.
이 기사에서는 더 나은 CSS를 작성하고 CSS 코드를 더 쉽게 유지 관리하여 스타일시트를 더 짧게 만들고 규칙을 줄이기 위한 몇 가지 팁과 조언을 살펴볼 것입니다. CSS는 부담이 아닌 편리한 도구가 될 것입니다.
##
CSS는 DOM 요소의 스타일을 지정할 수 있는 선언적 언어입니다. 이 언어에서는 일부 이전 규칙을 재정의하는 인라인 스타일과 같은 일부 규칙이 다른 규칙보다 우선합니다.
예를 들어 다음과 같은 HTML 및 CSS 코드가 있는 경우:
<code><span class="tag"><button<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"button-warning"<span class="tag">></span></span></span></span></span></span></code>
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">warning <span class="pun">{<span class="pln"> background<span class="pun">:<span class="pln"> red<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> button<span class="pun">,<span class="pln"> input<span class="pun">[<span class="pln">type<span class="pun">=<span class="pln">submit<span class="pun">]<span class="pln"> <span class="pun">{<span class="pln"> background<span class="pun">:<span class="pln"> gray<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
.button-warning
이 button, input[type=submit]
앞에 정의되어 있더라도 후자의 background
속성을 재정의합니다. 왜? 어떤 규칙이 다른 규칙을 무시할지 결정하는 원칙은 무엇입니까?
정확성.
특정 선택기는 더 정확한 것으로 간주됩니다. 예를 들어 #id
선택기는 .class
선택기를 재정의합니다. 실제로 필요한 것보다 더 정확한 선택기를 적용하면 어떻게 될까요? 나중에 이러한 스타일을 재정의하고 이 선택기를 재정의하려면 더 정확한 것이 필요합니다... 예, 이것은 점점 더 커지는 눈덩이와 같아서 결국 유지 관리가 어려워지게 됩니다.
따라서 자신만의 선택기를 작성할 때 스스로에게 물어보세요. 이것이 가장 적절한 선택자인가?
모든 선택기 정밀도 규칙은 W3C CSS 사양에 공식적으로 정의되어 있으며 여기에서 각 선택기의 세부정보를 확인할 수 있습니다. 이해를 돕기 위해 더 간단한 기사를 원한다면 이 기사를 읽어보세요.
일반적인 상황을 생각해 보겠습니다. CSS에 버그가 있고 어떤 DOM 요소에 잘못된 스타일이 있는지 알아냈습니다. 게다가, 당신은 그것이 가져서는 안 되는 설명할 수 없는 속성을 가지고 있다는 것을 알게 됩니다.
계속 CSS를 추가하고 싶을 수도 있습니다. 이렇게 하면 코드 베이스가 더 커지고 나중에 버그를 찾기가 더 어려워질 것입니다.
대안으로 돌아가서 버그를 찾고 브라우저의 개발자 도구를 사용하여 요소와 모든 연쇄 관계를 확인하세요. 원하지 않는 스타일을 적용하는 규칙을 확인합니다. 바람직하지 않은 결과가 발생하지 않도록 이미 존재하는 규칙을 수정합니다.
FireFox에서는 페이지 요소를 마우스 오른쪽 버튼으로 클릭하고 检查元素
을 선택하여 스타일시트를 디버깅할 수 있습니다.
저 영광스러운 폭포를 보세요. 여기에서는 요소에 적용된 모든 규칙을 적용된 순서대로 볼 수 있습니다. 최상위 규칙은 더 정확하며 이전 스타일을 재정의할 수 있습니다. 일부 규칙의 일부 속성에는 취소선이 있는 것을 볼 수 있습니다. 이는 보다 정확한 규칙이 이 속성을 재정의했음을 의미합니다.
게다가 이러한 규칙을 볼 수 있을 뿐만 아니라 적용 여부를 선택할 수도 있고, 수정하여 결과를 관찰할 수도 있어 버그 수정에 큰 도움이 됩니다.
수정 사항은 규칙 변경일 수도 있고 캐스케이드의 다른 곳에서의 규칙 변경일 수도 있습니다. 이를 위해서는 새로운 규칙이 필요할 수 있습니다. 최소한 이것이 올바른 요구 사항이며 코드 기반의 필수 사항이라는 점을 알아야 합니다.
지금은 코드를 리팩터링하기에 좋은 시기이기도 합니다. CSS는 프로그래밍 언어는 아니지만 JavaScript 또는 Python과 동일한 고려 사항을 제공해야 합니다. 즉, 깔끔하고 읽기 쉬워야 합니다. 그러므로 필요하다면 구조도 재구성되어야 한다.
이전 팁은 이미 암시되었지만 중요성 때문에 다시 강조하고 싶습니다. 코드에 !important
를 사용하지 마세요
!important
은 계단식 규칙을 깨뜨릴 수 있는 CSS 기능입니다. CSS는 "Cascading Style Sheets"를 의미하며, 이는 팁이기도 합니다.
!important
은 시간이 부족하거나 계단식 관계를 고치고 싶지 않아 버그를 고치고 싶을 때 자주 사용됩니다.
当你给一个属性应用!important
, 浏览器将会忽视精确度规则。当你!important
一个规则来重写另外一个同样有!important
的规则时,你的大麻烦来了。
其实也有一种合适的使用!important
的情况,就是当你用开发工具调试某些东西的时候。有时候,你需要找到哪一个值可以修复你的bug。在你的开发工具中应用!important
来修改CSS规则,这可以帮助你找到那些你需要的值而不用管层叠特性。
一旦你知道哪些CSS可以起作用,你可以回到你的代码,查看你应该把你的CSS放到层联关系的哪一层。
px
和%
使用px
(pixels)和%
(percentages)单位是很直观的,因此我们在这儿将会关注那些鲜为人知的单位。
Em
and rem
最有名的相对单位就是 em。1em就等于那个元素的字体大小。
让我们考虑以下HTML代码:
<code><span class="tag"><article><span class="pln"> <span class="tag"><h1><span class="pln">Title<span class="tag"></h1><span class="pln"> <span class="tag"><p><span class="pln">One Ring to bring them all and in the darkness bind the.<span class="tag"></p><span class="pln"> <span class="tag"></article></span></span></span></span></span></span></span></span></span></span></span></code>
添加下面的规则:
<code><span class="pln">article <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">size<span class="pun">:<span class="pln"> <span class="lit">1.25em<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></code>
大多数的浏览器默认会给根元素应用16px的字体大小(顺便说一下,这个特性很容易被重写)。因此上面的article元素将有20px的字体大小(16*1.25
)。
那么对于h1
元素呢?为了更好的理解接下来将要发生的,让我们给样式表再添加另外的CSS规则:
<code><span class="pln">h1 <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">size<span class="pun">:<span class="pln"> <span class="lit">1.25em<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></code>
即使它是1.25em
,和article
元素相同,然而我们必须考虑em
单位的复合性(compound)。什么意思呢?换句话说,h1
作为body的直接子元素,将会有一个20px的字体大小(16*1.25
)。然而,我们的h1
是位于一个字体大小不同于根元素(我们的article
元素)的元素内部。在这种情况下,1.25
引用的是由层叠关系中给出的字体大小,因此h1
元素的字体大小将会是25px(16 * 1.25 * 1.25
)。
顺便说一句,作为代替自己来记忆这些乘法链,你可以使用Inspector
面板中的Computed
选项卡,它显示了实际的,最终的像素值。
em
单位事实上是非常实用的,通过用它可以很容易动态改变页面的尺寸(不仅仅是字体大小,还包括其它一些属性例如 行距, 宽度)。
如果你喜欢em中相对于基本大小的特性,而不喜欢它的复合性。你可以使用rem
单位。rem
单位和em
是非常相似的,但是去除了它的复合性,仅仅使用根元素的大小。
因此如果我们修改我们前面的CSS中h1
部分的em
单位为rem
<code><span class="pln">article <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">size<span class="pun">:<span class="pln"> <span class="lit">1.25em<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> h1 <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">size<span class="pun">:<span class="pln"> <span class="lit">1.25rem<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
vw
和vh
是视口单位。 1vw
是视口宽度的1%,同样1vh
也就是视口高度的1%。 当你需要一个UI元素占据整个屏幕的时候(比如传统的半透明遮罩层),它们非常有用,因为它们并不会和body的大小总是一致。
其它的单位也许不如上面的单位那么普遍或者有用,但是你有一天一定会遇到它们。你可以了解更多关于它们的细节(在 MDN 上)。
我们已经在前一篇关于CSS框架的文章中讨论过这个主题了,flexbox模块简化了布局和对齐对象的工作。如果你对flexbox还不了解,查看这个介绍文章。
没错,你现在可以使用flexbox了,除非你真的因为一些商业上的原因需要支持那些古老的浏览器。目前浏览器对于flexbox的支持率是94%以上。因此你可以不用继续写那些浮动div
s,它们是多么的难以调试和维护。
此外,还应该继续关注最新的Grid 模块,它将如微风般使人惬意。
CSS编译器例如Sass或者Less在前端开发领域都非常的流行。它们是极有力的工具,并且如果充分利用可以让你更高效的使用CSS。
在这些处理器中,一个比较普遍的特性就是选择器嵌套,比如,下面的这个Less代码:
<code><span class="pln">a <span class="pun">{<span class="pln"> text<span class="pun">-<span class="pln">decoration<span class="pun">:<span class="pln"> none<span class="pun">;<span class="pln"> color<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">&.<span class="pln">important <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">weight<span class="pun">:<span class="pln"> bold<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
将会被翻译为以下CSS规则:
<code><span class="pln">a <span class="pun">{<span class="pln"> text<span class="pun">-<span class="pln">decoration<span class="pun">:<span class="pln"> none<span class="pun">;<span class="pln"> color<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> a<span class="pun">.<span class="pln">important <span class="pun">{<span class="pln"> font<span class="pun">-<span class="pln">weight<span class="pun">:<span class="pln"> bold<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这个特性允许我们写更少的代码,可以更好的组织规则来应用到那些在DOM树中通常在一起的元素。这对调试也非常好用。
然而,滥用这个特性的现象随处可循,最终在CSS选择器竟然重复了整个DOM,因此,如果我们有以下HTML:
<code><span class="tag"><article<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"post"<span class="tag">><span class="pln"> <span class="tag"><header><span class="pln"> <span class="com"><!-- … --><span class="pln"> <span class="tag"><p><span class="pln">Tags: <span class="tag"><a<span class="pln"> <span class="atn">href<span class="pun">=<span class="atv">"..."<span class="pln"> <span class="atn">class<span class="pun">=<span class="atv">"tag"<span class="tag">><span class="pln">irrelevant<span class="tag"></a></p><span class="pln"> <span class="tag"></header><span class="pln"> <span class="com"><!-- … --><span class="pln"> <span class="tag"></article></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
我们也许会在CSS样式表中发现:
<code><span class="pln">article<span class="pun">.<span class="pln">post <span class="pun">{<span class="pln"> <span class="com">// ... other styling here<span class="pln"> header <span class="pun">{<span class="pln"> <span class="com">// ...<span class="pln"> p <span class="pun">{<span class="pln"> <span class="com">// ...<span class="pln"> a<span class="pun">.<span class="pln">tag <span class="pun">{<span class="pln"> background<span class="pun">:<span class="pln"> <span class="com">#ff0;<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
主要的问题在于这些CSS规则中是它们是非常特定的选择器。我们已经知道这是我们极力避免的。这儿也存在一个过度嵌套的问题。我已经在另外一篇文章讨论过了。
总之,不要生产那些你自己永远都不会输入的CSS嵌套规则。
另外一个有用的CSS特性是 混入,它是一种可复用的CSS块。例如,假如我们想要给一个按钮应用样式,并且它们中的大多数都有一些基本相同的CSS属性。我们也可以创建一个在Less混入像下面的代码:
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="kwd">base<span class="pun">()<span class="pln"> <span class="pun">{<span class="pln"> padding<span class="pun">:<span class="pln"> <span class="lit">1em<span class="pun">;<span class="pln"> border<span class="pun">:<span class="pln"> <span class="lit">0<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
然后,创建一个像下面的规则:
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">primary <span class="pun">{<span class="pln"> <span class="pun">.<span class="pln">button<span class="pun">-<span class="kwd">base<span class="pun">();<span class="pln"> background<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这将会生成以下的CSS:
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">primary <span class="pun">{<span class="pln"> padding<span class="pun">:<span class="pln"> <span class="lit">1em<span class="pun">;<span class="pln"> border<span class="pun">:<span class="pln"> <span class="lit">0<span class="pun">;<span class="pln"> background<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
正如你所看到的,对于复用一些常见的代码非常有用。
除过"包含"一个混入,其实还有另外一个选择:“扩展”或者说是继承它(确切的术语众口不一)。它所做的就是合并多个选择器到同一个规则。
我们来看一个使用混入的例子吧:
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">primary <span class="pun">{<span class="pln"> <span class="pun">&:<span class="pln">extend<span class="pun">(.<span class="pln">button<span class="pun">-<span class="kwd">base<span class="pun">)<span class="pln"> background<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">danger <span class="pun">{<span class="pln"> <span class="pun">&:<span class="pln">extend<span class="pun">(.<span class="pln">button<span class="pun">-<span class="kwd">base<span class="pun">)<span class="pln"> background<span class="pun">:<span class="pln"> red<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
这将会被翻译为:
<code><span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">primary<span class="pun">,<span class="pln"> <span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">danger <span class="pun">{<span class="pln"> padding<span class="pun">:<span class="pln"> <span class="lit">1em<span class="pun">;<span class="pln"> border<span class="pun">:<span class="pln"> <span class="lit">0<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">primary <span class="pun">{<span class="pln"> background<span class="pun">:<span class="pln"> blue<span class="pun">;<span class="pln"> <span class="pun">}<span class="pln"> <span class="pun">.<span class="pln">button<span class="pun">-<span class="pln">danger <span class="pun">{<span class="pln"> background<span class="pun">:<span class="pln"> red<span class="pun">;<span class="pln"> <span class="pun">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
网上一些文章告诉我们只需要使用“包含”。然而另外一些人却说使用“扩展”。事实是它们生产截然不同的代码,事实上它们都没有问题,而是依赖于你所使用的处理器更适合使用哪种。
我希望这可以帮助你重新打量你的CSS代码,能写更好的规则。记住我前面所说的:CSS 也是代码,因此同样值得被关注,仔细维护你的代码库。如果你给它更多的热爱,你一定会收到回报。
Belén 是一位工程师和游戏开发者,目前工作与Mozilla 开发联盟。她关注网络标准的制定,高质量代码,以及游戏开发。
More articles by Belén Albeza…