모듈형 디자인이 마음에 듭니다. 나는 오랫동안 웹 사이트를 페이지가 아닌 구성 요소로 분리하고 해당 구성 요소를 인터페이스에 동적으로 병합하는 것을 좋아했습니다. 이 접근 방식은 유연하고 효율적이며 유지 관리가 쉽습니다.
하지만 내 디자인이 쓸데없는 것들로 이루어진 것처럼 보이고 싶지는 않아요. 나는 초현실적인 사진이 아닌 인터페이스를 만들고 있다.
다행히도 이 문제를 해결하기 위해 특별히 고안된 CSS라는 기술이 이미 있습니다. CSS를 사용하면 HTML 구성 요소 사이 어디에서나 스타일을 전달할 수 있으므로 최소한의 노력으로 일관된 디자인을 보장할 수 있습니다. 이는 주로 두 가지 CSS 기능 덕분입니다:
상속
캐스케이드(CSS의 C, 캐스케이드)
이러한 기능을 사용하면 스타일을 지정할 수 있지만 건조하고 효율적인 방식의 웹 문서가 CSS가 존재하는 이유였지만 더 이상 선호되지 않는다는 것은 분명합니다. CSS 모듈을 프로그래밍 방식으로 캡슐화하는 BEM 및 Atomic CSS와 같은 일부 CSS 방법론에서는 많은 사람들이 이러한 기능을 피하거나 억제하기 위해 최선을 다합니다. 이는 또한 개발자에게 CSS를 제어할 수 있는 더 많은 기회를 제공하지만 이는 빈번한 개입을 기반으로 한 임시 제어일 뿐입니다.
여기서 모듈형 인터페이스 디자인과 관련하여 상속, 계단식 배열 및 범위를 다시 살펴보겠습니다. 제가 말씀드리고 싶은 것은 이러한 기능을 사용하여 CSS 코드를 더 간결하게 만들고, 더 나은 적응성을 달성하고, 페이지의 확장성을 향상시키는 방법입니다.
CSS가 전역 범위만 제공하지 않는 이유에 대해 많은 사람들이 불평하지만, 만약 그렇다면 중복된 스타일이 많이 있을 것입니다. 반면 CSS에는 전역 범위와 로컬 범위가 있습니다. JavaScript와 마찬가지로 로컬 범위는 상위 및 전역 범위에 액세스할 수 있으며 CSS에서는 로컬 범위가 상속을 돕습니다.
예를 들어 루트(전역)
font-family
요소에 대해
html
속성 을 정의하면 다음을 확신할 수 있습니다. 이 규칙은 문서의 모든 상위 요소에 적용됩니다(일부 예외는 있지만 다음 섹션에서 설명).
html {
Font-family: sans-serif;
}
/*
이 규칙은 필요하지 않습니다 ↷
p {
font-family: sans-serif;
}
*/
JavaScript와 마찬가지로 로컬 범위에서 특정 규칙을 정의하면 전역 규칙이 적용됩니다. 모든 상위 범위에서는 유효하지 않으며 자체 하위 범위에서만 유효합니다(위 코드의
font-family
요소와 마찬가지로). 다음 예에서는
p
의
1.5
가
line-height
요소에서 사용되지 않습니다. 그러나
html
의
p
요소는
a
값을 사용합니다.
html {
글꼴 계열: sans-serif;
}
p {
줄 높이: 1.5;
}
/*
이 규칙은 필요하지 않습니다. ↷
p a {
line-height: 1.5;
}
상속의 가장 큰 장점은 아주 작은 크기를 사용할 수 있다는 것입니다. 코드의 양 일관된 시각적 디자인을 위한 기반을 구축합니다. 그리고 이러한 스타일은 아직 작성하지 않은 HTML에도 적용됩니다. 우리는 미래 보장 코드에 대해 이야기하고 있습니다!
대체
물론 공통된 스타일을 제공하는 또 다른 방법이 있습니다. 예를 들어
line-height
클래스…
.sans-serif {
Font-family: sans-serif;
}
…을 만들고 적용할 수 있습니다. 이 스타일을 적용하려는 모든 요소:
4e12928968181ff2e6ad5b18fbbaaff5Lorem ipsum.94b3e26ee717c64999d7867364b1b4a3
이 방법은 일부 제어 권한을 제공합니다. 권한: 선택할 수 있습니다. 정확히 어떤 요소에 이 스타일을 적용해야 하고 어떤 요소에 적용하지 않아야 합니다.
통제 가능성은 유혹적이지만 몇 가지 명백한 문제가 있습니다. 스타일을 지정해야 하는 요소에 클래스 이름을 수동으로 추가해야 할 뿐만 아니라(즉, 스타일 클래스가 무엇인지 먼저 결정해야 함을 의미함) 이 경우 동적 콘텐츠 지원 가능성을 효과적으로 포기했습니다. : 서식 있는 텍스트 편집기 나 마크다운 파서 모두 p 요소에 대해
.sans-serif
클래스를 제공할 수 없습니다.
그리고
style="font-family: sans-serif"
的用法差不多 – 除了前者意味着要同时在样式表和 HTML 当中添加代码。使用继承,我们就可以在其中一个少写点,而另外一个则不用再写了。相比给每个字体样式写一个类,我们可以只在一个声明里,给
html
元素添加想要的规则。
html {
font-size: 125%;
font-family: sans-serif;
line-height: 1.5;
color: #222;
}
inherit关键字
某些类型的属性是不会默认继承的,而某些元素则不会继承某些属性。但是在某些情况下,可以使用
[property name]: inherit
来强制继承。
举个例子,
input
元素在之前的例子中不会继承任何字体的属性,
textarea
也一样不会继承。为了确保所有元素都可以从全局作用域中继承这些属性,可以使用通配选择符和
inherit
关键字。这样,就可以最大程度地使用继承了。
* {
font-family: inherit;
line-height: inherit;
color: inherit;
}
html {
font-size: 125%;
font-family: sans-serif;
line-height: 1.5;
color: #222;
}
注意到我忽略了
font-size
。我不想直接继承
font-size
的原因是,它会将 heading 元素(译者注:如
h1
)、
small
元素以及其他一些元素的默认 user-agent 样式给覆盖掉。这么做我就可以节省一行代码,并且让 user-agent 决定想要什么样式。
另外一个我不想继承的属性是
font-style
:我不想重设
em
的斜体,然后再次添加上它。这将成为无谓的工作并会产生多余的代码。
现在,所有不管是可以继承或者是强制继承的字体样式都是我所期望的。我们已经花了很长时间只用两个声明区块来传递一个一致性的理念和作用域。从现在开始,除开一些例外情况,没有人会在构造组件的时候还需要去考虑
font-family
、
line-height
或者
color
了。这就是层叠的由来。
我可能想要主要的 heading 元素(
h1
)采用相同的
font-family
、
color
和
line-height
。使用继承就是很好的解决方案,但是我又想要它的
font-size
不一样。因为默认的 user-agent 样式已经给
h1
元素提供了一个大号的
font-size
(但这时它就会被我设置的相对基础字体大小为 125% 的样式覆盖掉),可能的话我不需要这里发生覆盖。
然而,难道我需要调整所有元素的字体大小吗?这时我就利用了全局作用域的优势,在局部作用域里只调整我需要调整的地方。
* {
font-family: inherit;
line-height: inherit;
color: inherit;
}
html {
font-size: 125%;
font-family: sans-serif;
line-height: 1.5;
color: #222;
}
h1 {
font-size: 3rem;
}
如果 CSS 元素的样式默认被封装,那么下面的情况就不可能了:需要明确地给
h1
添加所有字体样式。反而,我可以将样式分为几个单独的样式类,然后通过空格分隔来逐一给
h1
添加样式:
b568805adf23e2f9439a2a7a196002dbHello World473f0a7621bec819994bb5020d29372a
不管哪种方式,都需要更多的工作,而且最终目的都是一个具备样式的
h1
。使用层叠,我已经给大部分元素赋上了想要的样式,并且只在一个方面使得
h1
成为一个例外。层叠作为一个过滤器,意味着样式只在添加新样式覆盖的时候才会发生改变。
我们已经开了个好头,但想要真正地掌握层叠,还需要尽可能多地给公共元素添加样式。为什么?因为我们的混合组件是由独立的 HTML 元素构成,并且一个屏幕阅读器友好的界面充分利用了语义化结构标记。
换句话说,让你的界面“分子化”(使用了 atomic 设计术语)的 “atoms” 样式应该在很大程度上可定位并且使用元素选择符。元素选择符的优先级很低,所以它们不会覆盖你之后可能加进来的基于类的样式。
首先应该做的事情就是给所有你即将需要使用的元素添加样式:
a { … }
p { … }
h1, h2, h3 { … }
input, textarea { … }
/* etc */
如果你想在无冗余的情况下有个一致性界面的话,那么下一步非常重要:每当你创建一个新组件的时候,如果它采用了一些新元素,那么就用元素选择符来给它们添加样式。现在不是时候去使用限制性、高优先级的选择符,也没有任何需要去编写一个样式类。语义化元素就使用其本身。
举个例子,如果我还没有给
button
元素 (就像前一个例子)添加样式,并且新组件加入了一个
button
元素,那么这就是一个给整个界面的
button
元素添加样式的好机会。
button {
padding: 0.75em;
background: #008;
color: #fff;
}
button:focus {
outline: 0.25em solid #dd0;
}
现在,当你想要再写一个新组件并且同样加入按钮的时候,就少了一件需要操心的事情了。在不同的命名空间下,不要去重写相同的 CSS,并且也没有类名需要记住或编写。CSS 本就应该总是致力于让事情变得简单和高效 – 它本身就是为此而设计的。
使用元素选择符有三个主要的优势:
生成的 HTML 更加简洁(没有多余的各种样式类)。
生成的样式表更加简洁(样式在组件间共享,不需要在每个组件里重写)。
生成的添加好样式的界面基于语义化 HTML。
使用类来专门提供样式常常被定义为“关注点分离”。这是对 W3C 的关注点分离原则的误解。它的目的是用 HTML 和 CSS 样式来描述整个结构。因为类专门是为了样式目的而制定,而且是在结构标记里出现,所以无论它们在哪里使用,技术上都是在打破分离,你不得不改变实质结构来得到样式。
不管在哪里都不要依赖表面的结构标记(样式类,内联样式),你的 CSS 应该兼容通用的结构和语义化的约定。这就可以简单地扩展内容和功能而无需它也变成一个样式的任务。同样在不同传统语义化结构的项目里,也可以让你的 CSS 变得更加可复用(但是这一点 CSS 的“方法论”可能会有所不同)。
特殊情况
在有人指责我过分简单化之前,我意识到界面上不是所有的按钮都做同样的事情,我还意识到做不同事情的按钮在某种程度上可能应该看起来不一样。
但这并不是说我们就需要用样式类、继承或者层叠来处理了。让一个界面上的按钮看起来完全不一样是在混淆你的用户。为了可访问性和一致性,大多数按钮在外观上只需要通过标签来进行区分。
bb9345e55eb71822850ff156dfde57c8create65281c5ac262bf6d81768915a4a77ac0
bb9345e55eb71822850ff156dfde57c8edit65281c5ac262bf6d81768915a4a77ac0
bb9345e55eb71822850ff156dfde57c8delete65281c5ac262bf6d81768915a4a77ac0
记住样式并不是视觉上唯一的区分方法。内容同样可以在视觉上区分,而且在一定程度上它更加明确一些,因为你可是在文字上告诉了用户不同的地方。
大多数情况下,单独使用样式来区分内容都不是必要或者正确的。通常,样式区分应该是附加条件,比如一个红色背景或者一个带图标的文本标签。文本标签对那些使用声音激活的软件有着特定的效果:当说出 “red button” 或者 “button with cross icon” 的时候并没有引起软件的识别时。
我将在“工具类”部分探讨关于添加细微差别到看起来相似的元素上的话题。
语义化 HTML 并不仅仅关于元素。标签属性定义类型、样式属性和状态。这些对可访问性来说也很重要,所以它们需要写在 HTML 里合适的地方。而且因为都在 HTML 里,所以它们还提供了做样式钩子的机会。
举个例子,
input
元素有一个
type
属性,那么你应该想要利用它的好处,还有像
aria-invalid
属性是用来描述状态的。
input, textarea {
border: 2px solid;
padding: 0.5rem;
}
[aria-invalid] {
border-color: #c00;
padding-right: 1.5rem;
background: url(images/cross.svg) no-repeat center 0.5em;
}
这里有几点需要注意一下:
这里我不需要设置
color
、
font-family
或者
line-height
,因为这些都从
html
上继承了,得益于上面使用的
inherit
关键字。如果我想在整个应用的层面上改变
font-family
,只需要在
html
那一块对其中一个声明进行编辑就可以了。
border 的颜色关联到
color
,所以它同样是从全局
color
中继承。我只需声明 border 的宽度和风格。
[aria-invalid]
属性选择符是没有限制的。这意味着它有着更好的应用(它可以同时作用在
input
和
textarea
选择符)以及最低的优先级。简单的属性选择符和类选择符有着同样的优先级。无限制使用它们意味着之后任何写在层叠下的样式类都可以覆盖它们。
BEM 方法论通过一个修饰符类来解决这个问题,比如
input--invalid
。但是考虑到无效的状态应该只在可通信的时候起作用,
input--invalid
还是一定的冗余。换句话说,
aria-invalid
属性不得不写在那里,所以这个样式类的目的在哪里?
只写 HTML
在层叠方面关于大多数元素和属性选择符我绝对喜欢的事情是:组件的构造变成更少地了解公司或组织的命名约定,更多地关注 HTML。任何精通写出像样 HTML 的开发者被分配到项目中时,都会从已经写到位的继承样式当中获益。这些样式显著地减少了读文档和写新 CSS 的需要。大多数情况下,他们可以只写一些死记硬背应该知道的(meta)语言。Tim Baxter 同样为此在 Meaningful CSS: Style It Like You Mean It 里写了一个案例。
目前为止,我们还没有写任何指定组件的 CSS,但这并不是说我们还没有添加任何相关样式。所有组件都是 HTML 元素的组合。形成更复杂的组件主要是靠这些元素的组合顺序和排列。
这就给我们引出了布局这个概念。
主要我们需要处理流式布局 – 连续块元素之间的间距。你可能已经注意到目前为止我没有给任何元素设置任何的外边距。那是因为外边距不应该考虑成一个元素的属性,而应该是元素上下文的属性。也就是说,它们应该只在遇到元素的时候才起作用。
幸运的是,直接相邻选择符可以准确地描述这种关系。利用层叠,我们可以使用一个统一默认贯穿所有连续块级元素的选择符,只有少数例外情况。
* {
margin: 0;
}
* + * {
margin-top: 1.5em;
}
body, br, li, dt, dd, th, td, option {
margin-top: 0;
}
使用优先级极低的猫头鹰选择符确保了任意元素(除了那些公共的例外情况)都通过一行来间隔。这意味着在所有情况下都会有一个默认的白色间隔,所有编写组件流内容的开发者都将有一个合理的起点。
在大多数情况下,外边距只会关心它们自己。不过因为低优先级,很轻易就可以在需要的时候覆盖掉那基础的一行间隔。举个例子,我可能想要去掉标签和其相关元素之间的间隔,好表示它们是一对的。在下面的示例里,任意在标签之后的元素(
input
、
textarea
、
select
等等)都不会有间隔。
label {
display: block
}
label + * {
margin-top: 0.5rem;
}
再次,使用层叠意味着只需要在需要的时候写一些特定的样式就可以了,而其他的元素都符合一个合理的基准。
需要注意的是,因为外边距只在元素之间出现,所以它们不会和可能包括在容器内的内边距重叠。这也是一件不需要担心或者预防的事情。
还注意到不管你是否决定引入包装元素都得到了同样的间隔。就是说,你可以像下面这样做并实现相同的布局 – 外边距在
p
之间出现比在标签和输入框之间出现要好得多。
5c73b9aa2fdcb03bf958d2a0e73b3327
e388a4556c0f65e1904146cc1a846bee
7397536d5778189d44ca8e1a252f44bbLabel one8c1ecd4bb896b2264e0711597d40766c
db29e09265e98a045996b6cd6b2ee5d4
94b3e26ee717c64999d7867364b1b4a3
e388a4556c0f65e1904146cc1a846bee
de26c6f59d175596302fdd42a7d948beLabel two8c1ecd4bb896b2264e0711597d40766c
da9cd4393fbc04279e38cd99b3d67213
94b3e26ee717c64999d7867364b1b4a3
c415d2ff3ee673aea99c9206d2287ae5Submit65281c5ac262bf6d81768915a4a77ac0
f5a47148e367a6035fd7a2faa965022e
用像 atomic CSS 这样的方法能实现同样的效果,只需组合各种外边距相关的样式类并在各种情况下手动添加它们,包括被
* + *
隐式控制的
first-child
这种例外情况:
98904965285a41eaa4d6bab8821082fe
b30c3c206244575bc1656887b7b5f8a3
e04ea3d3f3ecde3aee09171132e1ed1dLabel one8c1ecd4bb896b2264e0711597d40766c
3d64676d6acac8b1bfdd1ebcfc8ede0d
94b3e26ee717c64999d7867364b1b4a3
b003e2ac46d008c8ad012ae82a7120f5
6ae28b821320590edae0c445342608ddLabel two8c1ecd4bb896b2264e0711597d40766c
3f57ac1a57dc927768eacc6c0e104c1f
94b3e26ee717c64999d7867364b1b4a3
2f46062c63542038315f8de5c4399234Submit65281c5ac262bf6d81768915a4a77ac0
f5a47148e367a6035fd7a2faa965022e
记住如果坚持使用 atomic CSS 的话,像上面那么写只会覆盖到顶部外边距的情况。你必须还要为
color
、
background-color
以及其他属性建立独立的样式类,因为 atomic CSS 不会控制继承或者元素选择符。
5bef16c4c688cbcaa910e06fcb21ef95
b30c3c206244575bc1656887b7b5f8a3
aabe7b036107ea7f3bdac071cbc94efaLabel one8c1ecd4bb896b2264e0711597d40766c
262a72d9ba59b61e614ed2f7c82341be
94b3e26ee717c64999d7867364b1b4a3
b003e2ac46d008c8ad012ae82a7120f5
753aefcb6271f9cef799424e31913194Label two8c1ecd4bb896b2264e0711597d40766c
ffc27de3808c0bbda8185eaf584cf5ce
94b3e26ee717c64999d7867364b1b4a3
eca3449d10225825f76c50b49d8aefb5Submit65281c5ac262bf6d81768915a4a77ac0
f5a47148e367a6035fd7a2faa965022e
Atomic CSS 使开发者可以直接控制样式而不再使用内联样式,内联样式不像样式类一样可以复用。通过为各种独立的属性提供样式类,减少了样式表中的重复声明。
但是,它需要直接介入标记从而实现这些目的。这就要求学习并投入它那冗长的 API,同样还需要编写大量额外的 HTML 代码。
相反,如果只用来对任意 HTML 元素及其空间关系设计样式的话,那么 CSS “方法论”就要被大范围弃用了。使用一致性设计的系统有着很大的优势,相比一个叠加样式的 HTML 系统更方便考虑和分开管理。
无论如何,下面是我们的 CSS 架构和流式布局内容解决方案应该具备的特征:
全局(
html
)样式并强制继承,
流式布局方法及部分例外(使用猫头鹰选择符),
元素及属性样式。
我们还没有编写一个特定组件或者构思一个 CSS 样式类,但我们大部分的样式都已经写好了,前提是如果我们能够将样式类写得合理且可复用。
关于样式类它们有一个全局作用域:在 HTML 里任何地方使用,它们都会被关联的 CSS 所影响。对大多数人来说,这都被看做一个弊端,因为两个独立的开发者有可能以同样的命名来编写一个样式类,从而互相影响工作。
CSS modules 最近被用来解决这种情况,通过以程序来生成唯一的样式类名,绑定到它们的局部或组件作用域当中。
45eb5d721274a622b5c5223efd2702ff
a020ee0ca32b2b4efa0c9669dbf0fc2ePress me65281c5ac262bf6d81768915a4a77ac0
18a5f445132479bbd6b863fb63882b51
f04ba8f02f01374e863a438d4d9c052eHit me65281c5ac262bf6d81768915a4a77ac0
忽略掉生成代码的丑陋,你应该能够看到两个独立组件之间的不同,并且可以轻易地放在一起:唯一的标识符被用来区分同类的样式。在这么多更好的努力和冗余代码下,结果界面将要么不一致,要么一致。
没有理由对公共元素来进行唯一性区分。你应该对元素类型添加样式,而不是元素实例。谨记 “class” 意味着“某种可能存在很多的东西的类型”。换句话说,所有的样式类都应该是工具类:全局可复用。
当然,在这个示例里,总之
.button
类是冗余的:我们可以用
button
元素选择符来替代。但是如果有一种特殊类型的按钮呢?比如,我们可能编写一个
.danger
类来指明这个按钮是做危险性操作,比如删除数据:
.danger {
background: #c00;
color: #fff;
}
因为类选择符的优先级比元素选择符的优先级高,而和属性选择符优先级相同,所以这种方式添加在样式表后面的样式规则会覆盖前面元素和属性选择符的规则。所以,危险按钮会以红色背景配白色文本出现,但它其他的属性,比如内边距,聚焦轮廓以及外边距都会通过之前的流式布局方法添加,保持不变。
a6dcdbcffd1210ccc568b15beafa1522delete65281c5ac262bf6d81768915a4a77ac0
如果多位开发人员长时间在同样的代码基础上工作,那么偶尔就会发生命名冲突。但是有几种避免这种情况的方法,比如,噢,我不太知道,但对于你想要采用的名称我建议首先做一个文本搜索,看看是否已经存在了。因为你不知道,可能已经有人解决了你正在定位的问题。
局部作用域的各种工具类
对于工具类来说,我最喜欢做的事情就是把它们设置在容器上,然后用这个钩子去影响内部子元素的布局。举个例子,我可以快速对任意元素设置一个等间隔、响应式以及居中的布局。
.centered {
text-align: center;
margin-bottom: -1rem; /* adjusts for leftover bottom margin of children */
}
.centered > * {
display: inline-block;
margin: 0 0.5rem 1rem;
}
使用这个方法,我可以把列表项、按钮、按钮组合以及链接等随便什么元素居中展示。全靠
> *
的使用,在这个作用域中,它意味着带有
.centered
样式的元素下最近的子元素将会采用这些样式,并且还继承全局和父元素的样式。
而且我调整了外边距,好让元素可以自由进行包裹,而且不会破坏使用
* + *
选择符设置的垂直设定。这少量的代码通过对不同元素设置一个局部作用域,就提供了一个通用、响应式的布局解决方案。
我的一个小型(压缩后 93B)的基于 flexbox 网格布局系统 就是一个类似这种方法的工具类。它高度可复用,而且因为它使用了
flex-basis
,所以不需要断点干预。我只是用了 flexbox 布局的方法。
.fukol-grid {
display: flex;
flex-wrap: wrap;
margin: -0.5em; /* adjusting for gutters */
}
.fukol-grid > * {
flex: 1 0 5em; /* The 5em part is the basis (ideal width) */
margin: 0.5em; /* Half the gutter value */
}
使用 BEM 的方法,你会被鼓励在每个网格项上放置一个明确的“元素”样式类:
2c96be8ce1a9b3da92e0078e139c53db eedf335ab175f2058c2ad0b14087039f
29140088aecb442a69572eeecdffa3c9
817650e98b80081cbc8d242293f69ba8bed06894275b65c1ab86501b08a632eb
817650e98b80081cbc8d242293f69ba8bed06894275b65c1ab86501b08a632eb
817650e98b80081cbc8d242293f69ba8bed06894275b65c1ab86501b08a632eb
817650e98b80081cbc8d242293f69ba8bed06894275b65c1ab86501b08a632eb
929d1f5ca49e04fdcb27f9465b944689
94b3e26ee717c64999d7867364b1b4a3
但这不是必要的。只需一个标识符去实例化本地作用域。这里的列表项相比起我版本当中的列表项,不再受外部影响的保护,也不应该被
> *
所影响。仅有的区别就是充斥了大量样式类的标记。
所以,现在我们已经开始合并样式类,但只在通用性上合并,和它们所预期的效果一样。我们仍然还没有独立地给复杂组件添加样式。反而,我们在以一种可复用的方式解决一些系统性的问题。当然,你将需要在注释里写清楚这些样式类是如何使用的。
像这些的工具类同时采用了 CSS 的全局作用域、局部作用域、继承以及层叠的优点。这些样式类可以在各个地方使用,它们实例化局部作用域从而只影响它们的子元素,它们从父级或全局作用域中继承没有设置在自身的样式,而且我们没有过度使用元素或类选择符。
下面是现在我们的层叠看上去的样子:
全局(
html
)样式和强制性继承,
流式布局方法和一些例外(使用猫头鹰选择符),
元素和属性样式,
通用的工具类。
当然,可能没有必要去编写所有这些示例工具类。重点是,如果在使用组件的时候出现了需求,那么解决方案应该对所有组件都有效才行。一定要总是站在系统层面去思考。
特定组件样式
我们从一开始就已经给组件添加了样式,并且学习样式结合组件的方法,所以很多人有可能会忽略掉马上要讲到这个部分。但值得说明的是,任何不是从其他组件中创建的组件(甚至包括单个 HTML 元素)都是有必要存在的。它们是使用 ID 选择符的组件,以及有可能成为系统问题的风险。
事实上,一个好的实践是只使用 ID 来给复杂组件标识(“molecules”、“organisms”),并且不在 CSS 里使用这些 ID。比如,你可以在登录表单组件上写一个
#login
,那么你就不应该在 CSS 里以元素、属性或者流式布局方法的样式来使用
#login
,即使你可能会发现你在创造一个或两个可以在其他表单组件里使用的通用工具类。
如果你确实使用了
#login
,那么它只会影响那个组件。值得提醒的是如果这么做,那么你就已经偏离了开发一个设计系统方向,并且朝着只有不停纠结像素的冗长代码前进。
내가 BEM과 같은 방법론이나 CSS 모듈과 같은 도구를 사용하지 않는다고 사람들에게 말하면 대부분의 사람들은 CSS를 다음과 같이 작성할 것이라고 생각할 것입니다.
header nav ul li {
디스플레이: 인라인 블록; 우리가 피해야 할 사항과 함께 명확한 진술이 여기에 있습니다. BEM(OOCSS, SMACSS, Atomic CSS 등과 함께)이 복잡하고 관리가 불가능한 CSS를 피하는 유일한 방법은 아니라는 점을 말씀드리고 싶습니다.
우선순위 문제를 해결하기 위해 많은 방법론에서는 거의 항상 클래스 선택기를 사용합니다. 문제는 이로 인해 많은 스타일 클래스가 생성된다는 것입니다. HTML 마크업을 부풀리고 문서에 대한 초점을 잃게 만드는 모든 종류의 마법 코드는 새로운 개발자가 작업 중인 시스템에 대해 혼란을 줄 수 있습니다.
스타일 클래스를 광범위하게 사용함으로써 HTML 시스템과 크게 분리된 스타일 시스템도 관리해야 합니다. 이러한 부적절한 "관심사 분리"는 중복성을 야기하거나 더 나쁘게는 접근 불가능성을 초래할 수 있습니다. 접근 가능한 상태에서 시각적 스타일에 영향을 미칠 수 있습니다.
931fd07e140b80e00c54404df0eae36b
많은 글쓰기와 다양한 스타일 클래스를 대체하기 위해 다른 방법을 찾았습니다.
전제 조건 설정 일관성을 유지하여 상속을 제어합니다.
요소 및 속성 선택기를 최대한 활용하여 투명성과 표준 기반 구성 스타일을 지원합니다.
유동적인 레이아웃 시스템; 여러 요소에 영향을 미치는 일반적인 레이아웃 문제를 해결하기 위해 매우 다양한 도구 클래스를 통합합니다.
이러한 모든 방법은 새 구성 요소를 더 간단하게 작성하고 프로젝트가 성숙해짐에 따라 새 CSS 코드를 추가할 필요성을 줄이는 디자인 시스템을 만들기 위한 것입니다. 그리고 이것은 엄격한 이름 지정 및 병합의 이점이 아니라 오히려 그것들이 없다는 것입니다.
여기서 제가 추천하는 특정 기술에 관심이 없으실 수도 있지만, 적어도 이 기사를 통해 구성 요소가 무엇인지 다시 생각해 볼 수 있기를 바랍니다. 그것들은 당신이 독립적으로 창조하는 것이 아닙니다. 때로는 표준 HTML 요소의 경우 사용자가 만든 요소도 아닙니다. 구성 요소가 다른 구성 요소에서 더 많이 빌릴수록 인터페이스의 접근성과 시각적 일관성이 향상되고 결국 이를 구현하는 데 CSS를 덜 사용하게 됩니다.
CSS는 (이러한 문제에 대해) 큰 책임이 없습니다. 사실, 많은 일을 할 수 있다는 것은 좋은 일이지만, 우리는 그것을 활용하지 않습니다.
-->
위 내용은 CSS 상속 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!