회고록 블로그

CSS 공부: 선택자에 따라 스타일을 적용하는 순서가 있을까 본문

2. 프로그래밍 언어 공부/HTML+CSS

CSS 공부: 선택자에 따라 스타일을 적용하는 순서가 있을까

김간장 2021. 3. 4. 02:59

CSS에 대해서 이제 갓 배우기 시작했다.

근데 강의를 듣다가 궁금한게 생겼다. 그래서 답을 찾아보기로 했다.

 

※ 본 글은 초급자가 머릿속에서 혼자 고민하고 탐구하여 낸 결론입니다.

따라서, 본 글에 나오는 실패 원인 등은 개인의 추측일 뿐 정답이 아닐 가능성이 99.9% 입니다.

 


CSS는 선택자에 따라 스타일을 적용하는 순서(우선순위)가 있을까?

능력자님 해답을 찾아왔다.

출처: jess2.tistory.com/111

 

[CSS] 선택자 우선순위

CSS 선택자 우선순위 특정 태그에 스타일 속성이 중복될 경우, 어떤 속성이 적용될까? CSS 선택자 우선순위에 대해 알아보자. - 1순위. 속성 값 뒤에 !important를 붙인 속성 - 2순위. HTML에서 style을 지

jess2.tistory.com

CSS에는 우선순위라는게 있다고 한다.

그 우선순위는 위의 능력자님 글에 적혀있다.

 

그리고, 능력자님 한 분의 글을 더 찾아왔다.

출처: developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance

 

계단식 및 상속 - Web 개발 학습하기 | MDN

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

developer.mozilla.org

위의 글을 보면 CSS는 계단식이라서 동일한 선택자(selector)에 대해서 다른 스타일이 적용되면 마지막 규칙이 적용된다고 한다.

 


가장 궁금한 것은 이것이다. 아래와 같이 되어 있으면 어떻게 될까?

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h2>Hello1</h2>
    <div class="hello">
      <h2>Hello2</h2>
      <p>Hello Every one!</p>
    </div>
  </body>
</html>

1) 전체 <h2> 태그에는 skyblue 색을 지정하기로 했다.

2) 특정한 부분만 <div> 태그로 묶고 그 안에 <h2> 태그를 넣었다. 

    이 <div> 태그 안에 있는 내용들은 모두 tomato 색으로 출력하고 싶다.

 

즉, <div> 태그 밖에 <h2> 태그가 하나 있고, <div> 태그 안에 <h2> 태그가 하나 있는 상태이다.

 

그리고 결과물은 이렇게 만들어내고 싶다.

Hello1과 Hello2는 <h2> 태그이다.

 


첫번째 시도.

아래와 같이

1) <div>태그에 class를 부여하고

2) 그 class에 tomato 색을 지정해봤다.

<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 전체 h2 태그는 skyblue 색으로 하자 */
      h2 {
        color:skyblue;
      }
      /* 다만, class명이 'hello'인 div 태그 안에 있는 모든 내용들만 tomato 색으로 변경하고 싶다 */
      .hello {
        color:tomato;
      }
    </style>
  </head>
...
<!-- HTML 부분 코드는 위에 적어 두었음 -->
</html>

=> 결과: 실패

원하는대로 나오지 않았다. <p> 태그의 정보들은 tomato 색이 되었는데

<div> 태그 밑에 있던 <h2> 태그는 skyblue 색이 나왔다.

 

왜 그런걸까 혼자 곰곰히 생각해보았는데, 선택자 우선순위에서 밀린 것 같다.

 

내 생각 :

우선순위가 "class로 지정된 속성" > "태그 이름으로 지정된 속성" 이니까

당연히 "class명이 hello인 스타일이 먼저 적용될 것이고, 결과적으로 tomato색이 나오겠구나.

 

결과:

실패 ㅎ..

 

원인을 자가분석 해봤는데 (뇌피셜) :

아무래도 <div>와 <h2> 사이에 부모-자식 관계가 형성되어서 그런 것 같다.

"Hello Every one!"은 "상위 객체(div)에 상속된 속성"에 해당되어서 tomato색이 출력된 것 같고.

"Hello2"는 "태그 이름으로 지정된 속성"과 "class로 지정된 속성"과의 싸움(?)이 아니라

"태그 이름으로 지정된 속성"과 "상위 객체(div 태그)에 상속된 속성"의 싸움(?)이었기 때문에

우선순위에 의해서 skyblue색이 출력된 것 같다.

 


 

그렇다면,

1) <div> 태그 밑에 있는 <h2>에게 class를 추가해주고

2) 그 <h2> 태그의 class 속성을 통해서 스타일을 변경해주어야 하는걸까?

...
    <style>
      h2 {
        color:skyblue;
      }
      /* 2) class 속성 값을 통해서 스타일을 적용시켜주었다 */
      .hello2 {
        color:tomato;
      }
    </style>
...
    <div class="hello">
    <!-- 1) div 태그 밑에 있는 h2 태그에게 class를 주었다 -->
      <h2 class="hello2">Hello2</h2>
...

=> 결과: 성공

당연히 성공하였다.  (아, Hello Every one! 에도 class="hello2"를 부여해줘야 하는데 빼먹었다)

그리고 상속 관계를 이용한 방법으로도 성공하였다. (밑에 코드 참고)

...
    <style>
      h2 {
        color:skyblue;
      }
      /* div 태그의 밑에 있는 h2 태그에 tomato 색을 적용시켜주자 */
      .hello h2 {
        color:tomato;
      }
    </style>
...
    <div class="hello">
      <h2>Hello2</h2>
...

 

그런데..

그럼 이렇게 매번 번거롭게 스타일 혹은 클래스를 생성해줘야하는걸까.

 

샘플 코드에서는 <h2> 하나만 지금 문제였지만

만약 <div> 태그 밑에 <h1>, <h3>, <h4>, <a> 태그 등등이 다 있었다면

각각의 태그들도 모두 위와 같이 처리해줘야 하는걸까.

 

첫번째 시도의 실패 원인을 자가분석 해봤을 때, CSS 우선순위가 문제인 것 같으니까 그걸 해결해보자.


두번째 시도.

!important 를 사용하면 CSS 우선순위가 1순위가 된다고 했으니까 !important를 이용해보자.

<!DOCTYPE html>
<html>
  <head>
    <style>
      h2 {
        color:skyblue;
      }
      /* important를 붙였다 */
      .hello {
        color:tomato !important;
      }
    </style>
...

=> 내 생각 :

hello 클래스에 important를 사용해서 우선순위를 가장 위로 올려주었으니 <div> 태그 밑에 있는 <h2>를 포함한 모든 정보들은 tomato 색으로 변경되겠지.

=> 결과: 실패

 

첫번째 시도에서 CSS 우선순위 때문에 tomato색이 적용되지 않았다고 생각했고

그래서 important를 사용해서 우선순위를 가장 위로 올려주었는데 그래도 실패했다..

 

하.. 원인을 정말 모르겠다.

 

차라리 조합 선택자를 잘 이용해보자.


 

세번째 시도.

아예 조합 선택자를 이용해보자.

<div> 태그의 자식 선택자를 "모두" 선택해서 스타일을 변경해주면 되는거 아니겠는가.

<!DOCTYPE html>
<html>
  <head>
    <style>
      h2 {
        color:skyblue;
      }
      /* class 'hello'의 자식 요소를 모두(*) 선택해서 스타일을 적용시켜준다 */
      .hello > * {
        color:tomato;
      }
    </style>
  </head>
  <body>
    <h2>Hello1</h2>
    <div class="hello">
      <h2>Hello2</h2>
      <p>Hello Every one!</p>
    </div>
  </body>
</html>

=> 결과: 성공

 

와 드디어 성공했다.

 

 

하지만 여전히 두번째 시도가 실패한 이유를 잘 모르겠다.

첫번째 시도가 실패한 이유가 애초에 CSS 우선순위 때문이 아닌가? 그걸 해결해주면 될 줄 알았는데...


==> 추가)

아, 두번째 시도가 실패한 이유를 알 것 같다.

!important 에 대해서 몇가지 시도를 해봤는데, !important는 부모-자식 관계에서는 통하지 않는 것 같다.

 

예시1.

위의 코드 같은 경우 CSS 우선순위에 의해서 "class"가 더 우선이기 때문에 skyblue 색이 나온다.

여기에다가 important 속성을 사용해보자

 

=> 결과: 예상대로 skyblue 색이 아니라 tomato 색이 적용되었다. 

 

 

예시2.

근데 아래와 같이 적용하면 !important는 적용이고 뭐고 아무기능도 안하는 것 같았다.

코드를 좀 설명하자면,

1) Hello1, Hello2, Hello Every one! 이라는 정보를 모두 <div class="hello_base">로 묶어놓았다. (그룹핑)

2) 그리고 "hello_base"라는 class를 이용해서 기본적으로 skyblue 색이 적용되도록 했다.

3) <h2> 태그만 별도로 tomato 색을 적용해놨다. 

=> 당연히 <h2> 태그만 tomato 색으로 적용되고 나머지는 skyblue 색으로 적용되었다.

 

그리고 거기에서 important 속성을 사용해서 모든 정보들이 skyblue 색이 되도록 해보자.

 

 

!important 를 사용함으로써 내가 예상했던 결과는,

Hello1, Hello2, Hello Every one! 이라는 글자가 모두 skyblue로 출력되는 것이었는데

결과는 실패였다.

 

이 결과를 바탕으로 추측해보기로는,

!important 라는 속성은 부모요소(hello_base 라는 class)와 자식, 자손요소(h2 태그) 관계에서는 적용되지 않는 것 같다.

 

Comments