계단식 및 상속

This translation is in progress.

이 수업의 목적은 CSS 가 HTML 에 적용되는 방법과 충돌을 해결하는 방법을 제어하는 CSS 의 가장 기본적인 개념인 — cascade, 특수성 및 상속 — 에 대한 이해를 발전 시키는 것입니다.

이 수업을 통해 작업하면 코스의 다른 부분 보다 관련성이 떨어지고 좀 더 학문적으로 보일 수 있지만, 이러한 사항을 이해하면 나중에 많은 고통을 덜 수 있습니다! 이 섹션을 주의 깊게 살펴보고 계속 진행하기 전에 개념을 이해하는지 확인 하십시오.

전제조건: 기본 컴퓨터 활용 능력, 기본 소프트웨어 설치파일 작업 에 대한 기본 지식,  HTML 기본 사항 (HTML 소개 학습) 및 , CSS 작동 방식 이행 (CSS 첫 번째 단계 학습)
목적: 계단식 및 특수성 과 CSS 에서 상속이 작동하는 방식 배우기.

규칙 충돌

CSS 는 Cascading Style Sheets, 의 약자이며, CSS 라는 단어를 이해하는 데 있어 첫 번째 단어 cascading 은 매우 중요합니다.

어느 시점에서, 당신은 프로젝트를 진행할 것이며 요소에 적용해야 할 CSS 가 작동하지 않는다는 것을 알게 될 것입니다. 일반적으로 문제는 동일한 요소에 적용 할 수 있는 두 가지 규칙을 작성 했다는 것입니다. 계단식(cascade) 과 밀접하게 관련된 특수성(specificity) 개념은 그러한 충돌이 있을 때 적용되는 규칙을 제어하는 메커니즘입니다. 어떤 규칙에 따라 요소를 원하는 스타일로 만들지 못할 수도 있으므로 이러한 메커니즘의 작동 방식을 이해해야 합니다.

상속(inheritance) 개념도 중요합니다. 기본적으로 일부 CSS 속성은 현재 요소의 부모 요소에 설정된 값을 상속하지만, 일부는 그렇지 않습니다. 또한 예상치 못한 일부 동작이 발생 할 수 있습니다.

우리가 다루고 있는 주요 사항을 간단히 살펴보면서 시작해 봅시다. 차례대로 살펴보고 서로 상호 작용하고 CSS 와 어떻게 상호 작용 하는지 살펴 보겠습니다. 이것은 이해하기 어려운 까다로운 개념으로 보일 수 있습니다. 그러나 CSS 작성에 대한 연습이 많을 수록 작동 방식이 더 명확해 집니다.

계단식 (cascade)

스타일 시트 cascade — 매우 간단한 수준에서 이는 CSS 규칙의 순서가 중요하다는 것을 의미 합니다. 동일한 특수성을 갖는 두 규칙이 적용 될 때, CSS 에서 마지막에 나오는 규칙이 사용 될 것입니다.

아래 예에서는, h1 에 적용 할 수 있는 두 가지 규칙이 있습니다. h1 은 파란색으로 표시 됩니다 — 이러한 규칙에는 동일한 선택자가 있고 동일한 고유성을 가지므로, 소스 순서의 마지막 규칙이 우선합니다.

 

특수성 (Specificity)

특수성은 여러 규칙에 다른 선택자가 있지만, 여전히 동일한 요소에 적용 될 수 있는 경우, 브라우저가 어떤 규칙을 적용할 지 결정하는 방법입니다. 기본적으로 선택자의 선택이 얼마나 구체적인지 측정합니다:

  • 요소 선택자는 덜 구체적입니다 — 페이지에 나타나는 해당 유형의 모든 요소를 선택하므로 — 점수가 낮아집니다.
  • class 선택자는 보다 구체적입니다 — 특정 class 속성 값이 있는 페이지의 요소만 선택하므로 — 점수가 높아집니다.

시간 예제! 아래에는 h1. 에 적용 할 수 있는 두 가지 규칙이 다시 있습니다. 아래 h1 은 빨간색으로 표시 됩니다 — class 선택자는 규칙에 더 높은 특수성을 부여하므로 요소 선택자가 있는 규칙은 소스 순서에서 더 아래에 표시 되더라도 적용됩니다.

 

특수성 점수 및 기타 사항에 대해서는 나중에 설명 하겠습니다.

상속 (Inheritance)

상속은 이 맥락에서 이해되어야 합니다 — 부모 요소에서 설정된 일부 CSS 속성 값은 자식 요소에 의해 상속되며, 일부는 그렇지 않습니다.

예를 들어, 요소에 color 및 font-family 를 설정하면, 다른 색상 및 글꼴 값을 직접 적용하지 않는 한, 해당 요소 내부의 모든 요소에도 해당 색상 및 글꼴로 스타일이 지정됩니다.

 

일부 속성은 상속되지 않습니다 — 예를 들어 요소에 width 를 50% 로 설정하면, 모든 하위 항목의 너비가 부모 너비의 50% 가 되지 않습니다. 이 경우, CSS 는 사용하기가 매우 어려울 것입니다!

노트: MDN CSS 속성 참조 페이지에서 일반적으로 specifications 섹션의 맨 아래에 기술 정보 박스가 있습니다. 여기에는 해당 속성의 상속 여부를 포함하여 해당 속성에 대한 여러 데이터 요소가 나열되어 있습니다. 예를 들어, color 속성 Specifications 섹션, 을 참조 하십시오.

개념이 함께 작동하는 방식 이해하기

이 세 가지 개념은 어떤 CSS 가 어떤 요소에 적용 되는지를 함께 제어합니다. 아래 섹션에서 우리는 그들이 어떻게 함께 작동하는지 볼 것입니다. 때로는 약간 복잡해 보일 수 있지만, CSS 에 익숙해지면 기억하기 시작하고 잊어 버린 경우, 항상 세부 정보를 찾을 수 있습니다! 숙련된 개발자 조차도 모든 세부 사항을 기억하지 못합니다.

상속 이해하기

상속부터 시작 하겠습니다. 아래 예에서는 <ul> 이 있으며, 그 안에 순서가 없는 두 가지 수준의 목록이 있습니다. 외부 <ul> 에 테두리, 패딩 및 글꼴 색상을 지정 했습니다.

색상은 직접 자식 항목 뿐만 아니라 간접 자식 항목 (직접 자식 <li>) 및 첫 번째 중첩 목록에 있는 자식 항목에도 적용됩니다. 그런 다음 두 번째 중첩 목록에 special class 를 추가하고 다른 색상을 적용 했습니다. 그런 다음 자식을 통해 상속됩니다.

 

너비 (위에서 언급 한 것처럼), 마진, 패딩 및 테두리와 같은 것은 상속되지 않습니다. 만약 우리 목록의 자식들이 테두리를 물려 받았다면, 모든 단일 목록과 목록 항목은 테두디를 얻게 될 것입니다 — 아마도 우리가 원하는 효과는 아닙니다!

기본적으로 상속되는 속성과 그렇지 않은 속성은 대체로 상식적입니다.

상속 제어하기

CSS 는 상속을 제어하기 위한 4 가지 특수 범용 속성 값을 제공합니다. 모든 CSS 속성은 이러한 값을 허용합니다.

inherit
선택한 요소에 적용된 속성 값을 부모 요소의 속성 값과 동일하게 설정합니다. 사실상, 이것은 "상속에 영향을 미칩니다".
initial
선택한 요소에 적용된 속성 값을 브라우저의 기본 스타일 시트에서 해당 요소의 해당 속성에 설정된 값과 동일하게 설정합니다. 브라우저의 기본 스타일 시트에서 값을 설정하지 않고 속성이 자연스럽게 상속되면 속성 값이 대신 inherit 되도록 설정됩니다.
unset
속성을 natural 값으로 재설정 합니다. 즉, 속성이 자연적으로 상속되면 inherit 된 것처럼 작동하고 그렇지 않으면 initial 처럼 작동합니다.

노트: 브라우저 지원이 제한된 새로운 값인 revert 도 있습니다.

노트: 각각에 대한 자세한 내용과 작동 방식에 대한 자세한 내용은 Origin of CSS declarations in Introducing the CSS Cascade 를 참조 하십시오.

우리는 링크 목록을 보고 보편적 가치가 어떻게 작용하는지 탐구 할 수 있습니다. 아래의 라이브 예제를 사용하면 CSS 를 사용하여 변경 작업을 수행 할 수 있습니다. 코드를 가지고 노는 것이 HTML 과 CSS 를 이해하는 가장 좋은 방법입니다.

예를 들면:

  1. 두 번째 목록 항목에는 my-class-1 class 가 적용 되었습니다. 내부에 중첩된 <a> 요소의 색상을 상속하도록 설정합니다. 규칙을 제거하면 링크 색상이 어떻게 변경됩니까?
  2. 왜 세 번째 와 네 번째 링크가 그 색깔인지 이해합니까? 그렇치 않은 경우 위의 값에 대한 설명을 확인 하십시오.
  3. <a> 요소에 대해 — 예를 들어 a { color: red; } 와 같은 새 색상을 정의하는 경우 어떤 링크가 색상이 변경됩니까?

 

모든 속성 값 재설정

CSS shorthand 속성을 all 로 사용하면 이러한 상속 값 중 하나를 (거의) 모든 속성에 한 번에 적용 할 수 있습니다. 이 값은 상속 값 (inherit, initial, unset 또는 revert) 중 하나 일 수 있습니다. 스타일에 대한 변경 사항을 취소하여 새로운 변경을 시작하기 전에 알려진 시작 지점으로 돌아갈 수 있는 편리한 방법입니다.

아래 예제에는 두 개의 인용문이 있습니다. 첫 번째는 인용문 자체에 스타일을 적용하고 두 번째는 all 값을 unset 하도록 인용문에 적용된 class 를 갖습니다.

 

all 의 값을 사용 가능한 다른 값 중 일부로 설정하고 차이가 무엇인지 관찰 하십시오.

Understanding the cascade

We now understand why a paragraph nested deep in the structure of your HTML is the same color as the CSS applied to the body, and from the introductory lessons we have an understanding of how to change the CSS applied to something at any point in the document — whether by assigning CSS to an element or creating a class. We will now take a proper look at how the cascade defines which CSS rules apply when more than one thing could style an element.

There are three factors to consider, listed here in decreasing order of importance. Earlier ones overrule later ones:

  1. Importance
  2. Specificity
  3. Source order

We will look at these from the bottom up, to see how browsers figure out exactly what CSS should be applied.

Source order

We have already seen how source order matters to the cascade. If you have more than one rule, which has exactly the same weight, then the one that comes last in the CSS will win. You can think of this as rules which are nearer the element itself overwriting early ones until the last one wins and gets to style the element.

Specificity

Once you understand the fact that source order matters, at some point you will run into a situation where you know that a rule comes later in the stylesheet, but an earlier, conflicting, rule is applied. This is because that earlier rule has a higher specificity — it is more specific, and therefore is being chosen by the browser as the one that should style the element.

As we saw earlier in this lesson, a class selector has more weight than an element selector, so the properties defined on the class will override those applied directly to the element.

Something to note here is that although we are thinking about selectors, and the rules that are applied to the thing they select, it isn't the entire rule which is overwritten, only the properties which are the same.

This behavior helps avoid repetition in your CSS. A common practice is to define generic styles for the basic elements, and then create classes for those which are different. For example, in the stylesheet below we have defined generic styles for level 2 headings, and then created some classes which change only some of the properties and values. The values defined initially are applied to all headings, then the more specific values are applied to the headings with the classes.

 

Let's now have a look at how the browser will calculate specificity. We already know that an element selector has low specificity and can be overwritten by a class. Essentially a value in points is awarded to different types of selectors, and adding these up gives you the weight of that particular selector, which can then be assessed against other potential matches.

The amount of specificity a selector has is measured using four different values (or components), which can be thought of as thousands, hundreds, tens and ones — four single digits in four columns:

  1. Thousands: Score one in this column if the declaration is inside a style attribute, aka inline styles. Such declarations don't have selectors, so their specificity is always simply 1000.
  2. Hundreds: Score one in this column for each ID selector contained inside the overall selector.
  3. Tens: Score one in this column for each class selector, attribute selector, or pseudo-class contained inside the overall selector.
  4. Ones: Score one in this column for each element selector or pseudo-element contained inside the overall selector.

Note: The universal selector (*), combinators (+, >, ~, ' '), and negation pseudo-class (:not) have no effect on specificity.

The following table shows a few isolated examples to get you in the mood. Try going through these, and making sure you understand why they have the specificity that we have given them. We've not covered selectors in detail yet, but you can find details of each selector on the MDN  selectors reference.

Selector Thousands Hundreds Tens Ones Total specificity
h1 0 0 0 1 0001
h1 + p::first-letter 0 0 0 3 0003
li > a[href*="en-US"] > .inline-warning 0 0 2 2 0022
#identifier 0 1 0 0 0100
No selector, with a rule inside an element's style attribute 1 0 0 0 1000

Before we move on, let's look at an example in action.

 

So what's going on here? First of all, we are only interested in the first seven rules of this example, and as you'll notice, we have included their specificity values in a comment before each one.

  • The first two selectors are competing over the styling of the link's background color — the second one wins and makes the background color blue because it has an extra ID selector in the chain: its specificity is 201 vs. 101.
  • The third and fourth selectors are competing over the styling of the link's text color — the second one wins and makes the text white because although it has one less element selector, the missing selector is swapped out for a class selector, which is worth ten rather than one. So the winning specificity is 113 vs. 104.
  • Selectors 5–7 are competing over the styling of the link's border when hovered. Selector six clearly loses to five with a specificity of 23 vs. 24 — it has one fewer element selectors in the chain. Selector seven, however, beats both five and six — it has the same number of sub-selectors in the chain as five, but an element has been swapped out for a class selector. So the winning specificity is 33 vs. 23 and 24.

Note: This has only been an approximate example for ease of understanding. In actuality, each selector type has its own level of specificity that cannot be overwritten by selectors with a lower specificity level. For example, a million class selectors combined would not be able to overwrite the rules of one id selector.

A more accurate way to evaluate specificity would be to score the specificity levels individually starting from highest and moving on to lowest when necessary. Only when there is a tie between selector scores within a specificity level do you need to evaluate the next level down; otherwise, you can disregard the lower specificity level selectors since they can never overwrite the higher specificity levels.

!important

There is a special piece of CSS that you can use to overrule all of the above calculations, however you should be very careful with using it — !important. This is used to make a particular property and value the most specific thing, thus overriding the normal rules of the cascade.

Take a look at this example where we have two paragraphs, one of which has an ID.

 

Let's walk through this to see what's happening — try removing some of the properties to see what happens if you are finding it hard to understand:

  1. You'll see that the third rule's color and padding values have been applied, but the background-color hasn't. Why? Really all three should surely apply, because rules later in the source order generally override earlier rules.
  2. However, The rules above it win, because class selectors have higher specificity than element selectors.
  3. Both elements have a class of better, but the 2nd one has an id of winning too. Since IDs have an even higher specificity than classes (you can only have one element with each unique ID on a page, but many elements with the same class — ID selectors are very specific in what they target), the red background color and the 1 pixel black border should both be applied to the 2nd element, with the first element getting the gray background color, and no border, as specified by the class.
  4. The 2nd element does get the red background color, but no border. Why? Because of the !important declaration in the second rule — including this after border: none means that this declaration will win over the border value in the previous rule, even though the ID has higher specificity.

Note: The only way to override this !important declaration would be to include another !important declaration on a declaration with the same specificity later in the source order, or one with a higher specificity.

It is useful to know that !important exists so that you know what it is when you come across it in other people's code. However, we strongly recommend that you never use it unless you absolutely have to. !important changes the way the cascade normally works, so it can make debugging CSS problems really hard to work out, especially in a large stylesheet.

One situation in which you may have to use it is when you are working on a CMS where you can't edit the core CSS modules, and you really want to override a style that can't be overridden in any other way. But really, don't use it if you can avoid it.

The effect of CSS location

Finally, it is also useful to note that the importance of a CSS declaration depends on what stylesheet it is specified in — it is possible for users to set custom stylesheets to override the developer's styles, for example the user might be visually impaired, and want to set the font size on all web pages they visit to be double the normal size to allow for easier reading.

To summarize

Conflicting declarations will be applied in the following order, with later ones overriding earlier ones:

  1. Declarations in user agent style sheets (e.g. the browser's default styles, used when no other styling is set).
  2. Normal declarations in user style sheets (custom styles set by a user).
  3. Normal declarations in author style sheets (these are the styles set by us, the web developers).
  4. Important declarations in author style sheets
  5. Important declarations in user style sheets

It makes sense for web developers' stylesheets to override user stylesheets, so the design can be kept as intended, but sometimes users have good reasons to override web developer styles, as mentioned above — this can be achieved by using !important in their rules.

Active learning: playing with the cascade

In this active learning, we'd like you to experiment with writing a single new rule that will override the color and background color that we've applied to the links by default. Can you use one of the special values we looked at in the Controlling inheritance section to write a declaration in a new rule that will reset the background color back to white, without using an actual color value?

If you make a mistake, you can always reset it using the Reset button. If you get really stuck, take a look at the solution here.

What's next

If you understood most of this article, then well done — you've started getting familiar with the fundamental mechanics of CSS. Next up, we'll look at selectors in detail.

If you didn't fully understand the cascade, specificity, and inheritance, then don't worry! This is definitely the most complicated thing we've covered so far in the course, and is something that even professional web developers sometimes find tricky. We'd advise that you return to this article a few times as you continue through the course, and keep thinking about it.

Refer back here if you start to come across strange issues with styles not applying as expected. It could be a specificity issue.

In this module

  1. Cascade and inheritance
  2. CSS selectors
  3. The box model
  4. Backgrounds and borders
  5. Handling different text directions
  6. Overflowing content
  7. Values and units
  8. Sizing items in CSS
  9. Images, media, and form elements
  10. Styling tables
  11. Debugging CSS
  12. Organizing your CSS