css
는 html에 스타일을 입히는 스타일시트 언어이며 우선순위에 따라 스타일이 입혀지는 형태로 구성되어 있다. css의 우선 순위는 선택자에 따라, 작성된 위치에 따라, !important의 유무에 따라 정해진다.
css의 선택자는 태그명
, 아이디
, 클래스
, 추상 클래스
정도로 구분할 수 있다. 다음과 같이 생긴 태그가 있는 경우
<div id="container" class="container2"></div>
1) 태그명은 <div>
와 같은 태그를 의미한다.
2) 아이디는 태그에서 id 속성에 명시된 이름으로 #
과 함께 사용해 #container
로 작성한다.
3) 클래스는 태그에서 class 속성에 명시된 이름으로 .
과 함께 사용해 .contaienr2
로 작성한다.
4) 추상 클래스는 가상 선택자로, :
나 ::
과 함께 사용하는데, 이벤트나 자식 요소, 요소의 before, after처럼 이미 요소가 가지고 있는 속성으로 호출할 수 있다. 흔히 사용하는 추상 클래스는 마우스 오버되었을 경우를 특정하는 :hover
, input 태그에 포커싱이 되었을 경우를 특정하는 :focus
, 클릭한 요소를 특정하는 :active
, 자식 요소를 특정하는 :nth-child(n)
, 이전 태그가 아닌 태그와 태그 사이의 공간을 특정하는 ::before
, after
등이 있다.
선택자는 단독으로 명시할 수도 있고, 태그가 겹쳐진 순서대로 명시할 수도 있으며, 같은 위치에 있는 요소들을 함께 호출할 수도 있다.
div {
color: red;
}
#container {
color: blue;
}
.container2 {
color: green;
}
위와 같이 동일한 태그를 세 가지 방식으로 선택할 수 있는데, 세 가지 방법 중에서는 id 선택자가 가장 높은 우선 순위(명시도 점수)를 얻는다. 따라서 위와 같이 작성하게 되면 클래스 선택자로 지정한 green이 가장 마지막에 있더라도 명시도가 높은 id 선택자에 지정한 blue 색상을 입게 된다.
.container2 {
color: green;
}
div {
color: red;
}
같은 원리로 다음과 같이 작성된 스타일의 경우, 태그명보다는 클래스명이 명시도가 높기 때문에 .container
로 선언된 스타일인 green 색상을 입게 된다.
1) css는 작성된 위치에 따라 명시도가 달라진다. 우선 css는 작성된 순서대로 스타일을 입게 되는데, 때문에 같은 명시도라면 마지막에 선언된 스타일을 입게 된다.
.container2 {
color: red;
}
.container2 {
color: green;
}
위와 같이 작성된 코드일 경우 red 색상 위에 green 색상이 덮어지는 형태가 되기 때문에 최종적으로 보여지는 색상은 green이 된다.
2) 스타일은 inline 으로 작성된 것이 가장 명시도가 높다. inline 으로 작성되었다는 뜻은 태그 내부에 스타일이 작성되었다는 뜻으로 다음과 같은 태그 모양을 갖는다.
<div id="conatiner" class="container2" style="color: red">
스타일 태그 내부에 아이디로 선택자를 사용하더라도 inline으로 작성된 스타일의 우선 순위가 높다.
!important
는 기존의 우선 순위를 무시하고 !important
가 작성된 스타일의 우선 순위를 가장 높게 만들어준다. 다만 !important
자체가 명시도를 갖는 것은 아닌데 명시도에 관여하는 선언이기 때문에 mdn
에서는 !important
의 사용을 자제할 것을 권한다.
<div id="conatiner" class="container2" style="color: red">
!important
는 위와 같이 inline 스타일로 작성된 우선 순위도 무시한다. inline으로 선언된 스타일이 id보다도 명시도가 높다고 했기 때문에 !important
를 선언하면 명시도가 가장 높아진다고 이해해도 좋다. 다만, !important
를 선언한 스타일보다 더 높은 명시도가 필요할 경우 !important
를 남발하는 문제를 가질 수도 있기 때문에 유의해서 사용해야 한다. 그냥 쓰지마세요
최근 이런 질문을 받았다.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
.container {
width: 600px;
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row;
border: 1px solid pink;
}
.item {
border: 1px solid red;
}
.item:nth-child(1) {
grid-column: span 2;
background: aqua;
}
.item:nth-child(2) {
grid-column: 2/4;
background: springgreen;
}
위와 같은 코드가 있을 때 .container 내부에 작성된 스타일 중 grid-auto-flow
가 row이면 다음과 같이 1번 박스가 상단을 차지하는데,
grid-auto-flow
를 column으로 바꾸면 다음과 같이 2번 박스가 상단을 차지하는데 왜 그러냐는 질문이었다.
css의 우선 순위는 웹 개발을 처음 배울 때 당시에 배우고 그 뒤로 깊게 생각해본 적이 없었기 때문에 질문을 받았을 땐 나도 그러게요...? 라고 생각했었는데 코드를 조금 더 뜯어보고서야 이게 우선 순위와 관련된 문제라는 것을 알게 되었다.
.item:nth-child(1) {
grid-column: span 2;
background: aqua;
}
.item:nth-child(2) {
grid-column: 2/4;
background: springgreen;
}
1번과 2번 박스를 보면 grid-column
이 span을 사용한 것과 위치를 지정해준 것, 이렇게 두 가지로 구분된다. 만약 두 박스가 위치를 명시적으로 지정하는 동일한 방식으로 작성되었을 경우 grid-auto-flow
를 column이더라도 다음과 같이 정렬된다.
.item:nth-child(1) {
grid-column: 1/3;
background: aqua;
}
.item:nth-child(2) {
grid-column: 2/4;
background: springgreen;
}
span으로 작성한 경우도 마찬가지다. 다만 이 경우엔 위치를 지정하지 않았기 때문에 영역이 좌측 1번부터 시작하게 된다.
.item:nth-child(1) {
grid-column: span 2;
background: aqua;
}
.item:nth-child(2) {
grid-column: span 2;
background: springgreen;
}
즉, 박스가 갖는 영역을 어떻게 지정하느냐에 따라 css의 우선 순위가 달라진다는 것을 알 수 있다. grid의 경우 테트리스처럼 구역을 짜맞추는 것에 가깝다고 생각했었는데, 영역을 차지하는 방법에서도 우선 순위가 달라질 수 있다는 것을 알게 되었다.
css는 다른 요소와의 상호작용을 통해 위치 또는 색상이 정해지는 것보다 직접 호명을 해서 위치나 색상을 지정하는 것이 더 높은 우선 순위를 갖는다는 것을 좀 더 확실히 알게 된 계기였다.