1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
---
title: 명시도
slug: Web/CSS/Specificity
tags:
- CSS
- Example
- Guide
- Reference
- Web
translation_of: Web/CSS/Specificity
---
<div>{{cssref}}</div>
<p><strong>명시도</strong>란 브라우저가 어느 요소와 가장 연관된 속성을 찾는 수단으로, 이렇게 찾은 속성이 해당 요소에 적용됩니다. 명시도는 여러 종류의 <a href="/ko/docs/Web/CSS/CSS_Reference#Selectors" title="CSS selectors">CSS 선택자</a>로 구성된 일치 규칙에 기반합니다.</p>
<h2 id="어떻게_계산되는가">어떻게 계산되는가?</h2>
<p>명시도는 주어진 CSS 선언에 적용되는 가중치(weight)로, 일치하는 선택자 내 각 <a href="#selector-type">선택자 유형</a>의 수에 의해 결정됩니다. 여러 선언이 명시도가 같은 경우, CSS에서 맨 끝에 오는 선언이 요소에 적용됩니다. 명시도는 같은 요소가 여러 선언의 대상이 되는 경우에만 적용합니다. CSS 규칙에 따라 <a href="#directly-targeted-elements" title="directly targeted element">직접 대상 요소</a>는 요소가 부모로부터 상속받는 규칙보다 항상 우선합니다.</p>
<div class="note"><strong>주의:</strong> 문서 트리 내 <a href="#tree-proximity-ignorance">요소의 근접도(proximity, 가까움)</a>는 명시도에 영향이 없습니다.</div>
<h3 id="선택자_유형">선택자 유형</h3>
<p>아래 선택자는 유형별로 명시도를 증가시킵니다.</p>
<ol>
<li><a href="/ko/docs/Web/CSS/Type_selectors">유형 선택자</a>(<code>h1</code> 등) 및 의사 요소(<code>:before</code> 등).</li>
<li><a href="/ko/docs/Web/CSS/Class_selectors">클래스 선택자</a>(<code>.example</code> 등), 속성 선택자(<code>[type="radio"]</code> 등), 의사 클래스(<code>:hover</code> 등).</li>
<li><a href="/ko/docs/Web/CSS/ID_selectors">ID 선택자</a>(<code>#example</code> 등).</li>
</ol>
<p>전역 선택자({{cssxref("Universal_selectors", "*")}}), 조합자({{CSSxRef("Adjacent_sibling_combinator", "+")}}, {{CSSxRef("Child_combinator", ">")}}, {{CSSxRef("General_sibling_combinator", "~")}}, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator">'<code> </code>'</a>, {{CSSxRef("Column_combinator", "||")}}) 및 부정 의사 클래스(<code>:not()</code>)는 명시도에 영향을 주지 않습니다. (<code>:not()</code> <em>내부에</em> 선언한 선택자는 영향을 끼칩니다)</p>
<p><a href="https://specifishity.com">https://specifishity.com</a>에서 자세한 정보를 확인할 수 있습니다.</p>
<p>요소에 추가한 인라인 스타일(<code>style="font-weight: bold"</code>처럼)은 항상 외부 스타일시트의 모든 스타일을 덮어쓰므로 가장 높은 명시도를 갖는 것으로 생각할 수 있습니다.</p>
<h3 id="!important_예외"><code>!important</code> 예외</h3>
<p><code>!important</code> 규칙이 스타일 선언에 사용된 경우, 이 선언은 다른 선언보다 우선합니다. 엄밀히 말해 <code>!important</code> 자체는 명시도와 아무 관련이 없지만, 명시도에 직접 영향을 미칩니다. 그러나 <code>!important</code> 사용은 <strong>나쁜 습관</strong>이고 스타일시트 내 자연스러운 <a href="/ko/docs/Web/CSS/Cascade" title="cascading">종속</a>을 깨뜨려 디버깅을 더 어렵게 만들기에 피해야 합니다. <code>!important</code> 규칙으로 충돌하는 두 선언이 같은 요소에 적용된 경우, 더 큰 명시도를 갖는 선언이 적용됩니다.</p>
<p><strong>몇몇 경험 법칙들:</strong></p>
<ul>
<li><strong>항상</strong> !important를 고려하기도 전에 명시도를 활용할 방법을 찾아보세요.</li>
<li>외부 CSS(Bootstrap 또는 Normalize.css 같은 외부 라이브러리에서)를 재정의하는 페이지 전용 CSS에<strong>만</strong> <code>!important</code>를 쓰세요.</li>
<li>플러그인/매시업을 작성할 때 <code>!important</code>는 <strong>절대</strong> 쓰지 마세요.</li>
<li>사이트 전반 CSS에는 <code>!important</code>를 <strong>절대</strong> 쓰지 마세요.</li>
</ul>
<p><strong><code>!important</code>를 사용하는 대신에, 다음을 고려하세요:</strong></p>
<ol>
<li>CSS 종속<sup>cascading</sup>을 더 잘 활용하세요.</li>
<li>
<p>더 명시된(명확한) 규칙을 쓰세요. 선택 중인 요소 앞에 하나 이상의 요소를 나타냄으로써 규칙은 더 명확해지고 더 높은 우선 순위를 얻습니다:</p>
<pre class="brush: html"><div id="test">
<span>Text</span>
</div>
</pre>
<pre class="brush: css">div#test span { color: green; }
div span { color: blue; }
span { color: red; }</pre>
<p>순서와 무관하게 첫 번째 규칙이 가장 명확하므로 텍스트는 녹색이 됩니다. (또한, 역시 순서와 무관하게 파란색 규칙이 빨간색 규칙보다 우선합니다.)</p>
</li>
<li>(2)의 말도 안 되는 특별한 경우로, 더 이상 명시할 요소가 없는 경우 간단한 선택자를 여러 번 써서 명시도를 높일 수 있습니다.
<pre class="brush: css">#myId#myId span { color: yellow; }
.myClass.myClass span { color: orange; }</pre>
</li>
</ol>
<h4 id="!important를_사용하는_때"><code>!important</code>를 사용하는 때</h4>
<h5 id="A_인라인_스타일을_재정의할_때">A) 인라인 스타일을 재정의할 때</h5>
<p>사이트 전체의 시각적 요소를 설정하는 전역 CSS 파일은 각 요소에 직접 정의된 인라인 스타일에 덮어쓰일 수 있습니다. 인라인 스타일과 <code>!important</code> 모두 매우 나쁜 습관으로 취급되지만, 가끔씩은 <code>!important</code>로 인라인 스타일을 덮어써야 할 때가 있습니다.</p>
<p>이때는 전역 CSS 파일의 몇몇 스타일을 <code>!important</code>로 설정해서 요소에 직접 작성한 인라인 스타일을 덮어쓸 수 있습니다.</p>
<pre class="brush: html"><div class="foo" style="color: red;">나는 무슨 색일까?</div>
</pre>
<pre class="brush: css">.foo[style*="color: red"] {
color: firebrick !important;
}
</pre>
<p>여러 자바스크립트 프레임워크와 라이브러리에서 인라인 스타일을 추가합니다. 이런 인라인 스타일을 덮어쓸 때 매우 구체적인 선택자와 함께 <code>!important</code>를 사용할 수 있습니다.</p>
<h5 id="B_명시도가_높은_규칙을_재정의할_때">B) 명시도가 높은 규칙을 재정의할 때</h5>
<pre class="brush: css">#someElement p {
color: blue;
}
p.awesome {
color: red;
}</pre>
<p>어떻게 하면 <code>awesome</code> 문단이 <code>#someElement</code> 안에 있더라도 항상 빨갛게 만들 수 있을까요? <code>!important</code>를 사용하지 않으면 위쪽 규칙의 명시도가 높으므로 아래쪽 규칙보다 우선합니다.</p>
<h4 id="!important를_덮어쓰는_방법"><code>!important</code>를 덮어쓰는 방법</h4>
<p>A) 태그, ID나 클래스를 추가함으로써 명시도가 더 높은 !important한 CSS 규칙을 만듭니다.</p>
<pre class="brush: css">table td { height: 50px !important; }
.myTable td { height: 50px !important; }
#myTable td { height: 50px !important; }
</pre>
<p>B) 혹은 기존의 선택자 아래에 똑같은 선택자를 하나 더 만듭니다(명시도가 같으면 나중에 정의된 규칙이 우선하므로).</p>
<pre class="brush: css">td { height: 50px !important; }</pre>
<p>C) 아니면 기존 규칙을 수정해서 아예 <code>!important</code>를 사용하지 않게 만드는 것이 더 좋은 방법입니다.</p>
<pre class="brush: css">[id="someElement"] p {
color: blue;
}
p.awesome {
color: red;
}</pre>
<p>ID를 ID 선택자 대신 속성 선택자로 선택하면 클래스 1개와 같은 명시도가 됩니다. 두 선택자의 명시도가 같아졌으므로 나중에 오는 규칙이 우선합니다.</p>
<h4 id="아래에서_자세한_정보를_확인하세요">아래에서 자세한 정보를 확인하세요:</h4>
<ul>
<li><a href="https://stackoverflow.com/questions/3706819/what-are-the-implications-of-using-important-in-css">https://stackoverflow.com/questions/3706819/what-are-the-implications-of-using-important-in-css</a></li>
<li><a href="https://stackoverflow.com/questions/9245353/what-does-important-in-css-mean">https://stackoverflow.com/questions/9245353/what-does-important-in-css-mean</a></li>
<li><a href="https://stackoverflow.com/questions/5701149/when-to-use-important-property-in-css">https://stackoverflow.com/questions/5701149/when-to-use-important-property-in-css</a></li>
<li><a href="https://stackoverflow.com/questions/11178673/how-to-override-important">https://stackoverflow.com/questions/11178673/how-to-override-important</a></li>
<li><a href="https://stackoverflow.com/questions/2042497/when-to-use-important-to-save-the-day-when-working-with-css">https://stackoverflow.com/questions/2042497/when-to-use-important-to-save-the-day-when-working-with-css</a></li>
</ul>
<h3 id="is_및_not_예외"><code>:is()</code> 및 <code>:not()</code> 예외</h3>
<p>모두 일치 의사 클래스 {{CSSxRef(":is", ":is()")}} {{Experimental_Inline}} 및 부정 의사 클래스 {{CSSxRef(":not", ":not()")}}은 명시도 계산에서 의사 클래스로 취급되지 <em>않습니다</em>. 그러나 이들 의사 클래스 안에 명시된 선택자는 <a href="#selector-type" title="selector types">선택자 유형</a>의 수를 결정할 때 일반 선택자로 셉니다.</p>
<p>다음 CSS 조각과 HTML은...</p>
<pre class="brush: css">div.outer p {
color:orange;
}
div:not(.outer) p {
color: lime;
}
</pre>
<pre class="brush: html"><div class="outer">
<p>This is in the outer div.</p>
<div class="inner">
<p>This text is in the inner div.</p>
</div>
</div>
</pre>
<p>...다음과 같이 화면에 표시됩니다.</p>
<p>{{EmbedLiveSample('is_및_not_예외','600','100')}}</p>
<h3 id="The_where_exception" name="The_where_exception"><code>:where()</code> 예외 {{Experimental_Inline}}</h3>
<p>{{SeeCompatTable}}</p>
<p>명시도 조정 가상 클래스 {{CSSxRef(":where", ":where()")}} {{Experimental_Inline}}의 명시도는 항상 0입니다.</p>
<p>다음 CSS 조각과 HTML은...</p>
<pre class="brush: css">div:where(.outer) p {
color: orange;
}
div p {
color: blueviolet;
}
</pre>
<div class="hidden">
<pre class="brush: css;">#no-where-support {
margin: 0.5em;
border: 1px solid red;
}
#no-where-support:where(*) {
display: none !important;
}
</pre>
</div>
<div class="hidden">
<pre class="brush: html;"><div id="no-where-support">
⚠️ Your browser doesn't support the <code><a href="https://developer.mozilla.org/docs/Web/CSS/:where" target="_top">:where()</a></code> pseudo-class.
</div>
</pre>
</div>
<pre class="brush: html"><div class="outer">
<p>This is in the outer div.</p>
<div class="inner">
<p>This text is in the inner div.</p>
</div>
</div>
</pre>
<p>...다음과 같이 화면에 표시됩니다.</p>
<p>{{EmbedLiveSample('The_where_exception','600','100')}}</p>
<h3 id="형태_기반_명시도">형태 기반 명시도</h3>
<p>명시도는 선택자의 형태(form)를 기반으로 합니다. 아래에서 선택자 <code>*[id="foo"]</code>는 그 자체로는 ID를 선택하지만 선택자의 명시도를 계산할 때는 속성 선택자로 취급됩니다.</p>
<p>다음 스타일 선언과 마크업은...</p>
<pre class="brush: css">*#foo {
color: green;
}
*[id="foo"] {
color: purple;
}
</pre>
<pre class="brush: html"><p id="foo">I am a sample text.</p>
</pre>
<p>...다음과 같이 표시됩니다.</p>
<p>{{EmbedLiveSample('형태_기반_명시도','600','100')}}</p>
<p>같은 요소와 일치하지만 ID 선택자는 더 높은 명시도를 갖기 때문입니다.</p>
<h3 id="트리_근접도_무시"><a id="tree-proximity-ignorance" name="tree-proximity-ignorance">트리 근접도 무시</a></h3>
<p>요소와 주어진 선택자로 참조된 다른 요소와의 근접도(proximity)는 명시도에 영향을 주지 않습니다.</p>
<p>다음 스타일 선언과 HTML은...</p>
<pre class="brush: css">body h1 {
color: green;
}
html h1 {
color: purple;
}
</pre>
<pre class="brush: html"><html>
<body>
<h1>Here is a title!</h1>
</body>
</html>
</pre>
<p>...아래와 같이 렌더링됩니다.</p>
<p>{{EmbedLiveSample('트리_근접도_무시','600','100')}}</p>
<p>두 선언은 <a href="#selector-type">선택자 유형</a> 갯수가 같지만 <code>html h1</code> 선택자가 나중에 선언되었기 때문입니다.</p>
<h3 id="직접_일치_요소와_상속된_스타일"><a id="directly-targeted-elements" name="directly-targeted-elements">직접 일치 요소와 상속된 스타일</a></h3>
<p>특정한 요소와 직접적으로 일치하는 스타일은 상속된 규칙의 명시도와 무관하게 항상 상속된 스타일보다 우선합니다.</p>
<p>다음 CSS와 HTML은...</p>
<pre class="brush: css" style="font-size: 14px;">#parent {
color: green;
}
h1 {
color: purple;
}</pre>
<pre class="brush: html" style="font-size: 14px;"><html>
<body id="parent">
<h1>Here is a title!</h1>
</body>
</html></pre>
<p>...역시 아래와 같이 렌더링됩니다.</p>
<p>{{EmbedLiveSample('직접_일치_요소와_상속된_스타일','600','100')}}</p>
<p><code>h1</code> 선택자는 특정한 요소와 직접 일치하지만 초록색 선택자는 그렇지 않고 부모로부터 상속되기 때문입니다.</p>
<h2 id="명세">명세</h2>
<div style="overflow: auto;">
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName("CSS4 Selectors", "#specificity-rules", "Calculating a selector's specificity")}}</td>
<td>{{Spec2("CSS4 Selectors")}}</td>
<td>명시도 조정 선택자 {{CSSxRef(":where", ":where()")}} 추가.</td>
</tr>
<tr>
<td>{{SpecName("CSS3 Selectors", "#specificity", "Calculating a selector's specificity")}}</td>
<td>{{Spec2("CSS3 Selectors")}}</td>
<td><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements">의사 요소</a> 추가.</td>
</tr>
<tr>
<td>{{SpecName("CSS2.1", "cascade.html#specificity", "Calculating a selector's specificity")}}</td>
<td>{{Spec2("CSS2.1")}}</td>
<td><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes">의사 클래스</a> 추가.</td>
</tr>
<tr>
<td>{{SpecName("CSS1", "#cascading-order", "Cascading order")}}</td>
<td>{{Spec2("CSS1")}}</td>
<td>초기 정의.</td>
</tr>
</tbody>
</table>
</div>
<h2 id="같이_보기">같이 보기</h2>
<ul>
<li>명시도 계산기: CSS 규칙을 테스트하고 이해할 수 있는 대화형 웹사이트 - <a href="https://specificity.keegan.st/">https://specificity.keegan.st/</a></li>
<li>CSS3 선택자 명시도 - <a class="external" href="http://www.w3.org/TR/selectors/#specificity" rel="freelink">http://www.w3.org/TR/selectors/#specificity</a></li>
<li>{{CSS_key_concepts}}</li>
</ul>
|