회고록 블로그
CSS 공부: 선택자에 따라 스타일을 적용하는 순서가 있을까 본문
CSS에 대해서 이제 갓 배우기 시작했다.
근데 강의를 듣다가 궁금한게 생겼다. 그래서 답을 찾아보기로 했다.
※ 본 글은 초급자가 머릿속에서 혼자 고민하고 탐구하여 낸 결론입니다.
따라서, 본 글에 나오는 실패 원인 등은 개인의 추측일 뿐 정답이 아닐 가능성이 99.9% 입니다.
CSS는 선택자에 따라 스타일을 적용하는 순서(우선순위)가 있을까?
능력자님 해답을 찾아왔다.
CSS에는 우선순위라는게 있다고 한다.
그 우선순위는 위의 능력자님 글에 적혀있다.
그리고, 능력자님 한 분의 글을 더 찾아왔다.
출처: developer.mozilla.org/ko/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance
위의 글을 보면 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> 태그가 하나 있는 상태이다.
그리고 결과물은 이렇게 만들어내고 싶다.
첫번째 시도.
아래와 같이
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 태그) 관계에서는 적용되지 않는 것 같다.
'2. 프로그래밍 언어 공부 > HTML+CSS' 카테고리의 다른 글
[공부 필기] 생활코딩 CSS 수업 필기_20210306 (0) | 2021.03.07 |
---|---|
HTML 공부: img 태그로 사이즈를 조절하고 CSS로도 이미지의 사이즈를 조절하면 어떻게 될까 (0) | 2021.03.04 |
[공부 필기] 생활코딩 CSS 수업 필기_20210304 (0) | 2021.03.04 |
[공부 필기] 생활코딩 HTML 수업 필기_20210303 (0) | 2021.03.03 |
HTML method: get 방식 vs post 방식 (0) | 2021.03.03 |