HyunJun 기술 블로그

CSS 선택자, Selector 본문

CSS

CSS 선택자, Selector

공부 좋아 2023. 5. 29. 11:07
728x90
반응형

1. CSS 선택자(Selector)란?

CSS는 HTML의 특정 요소(Element)에 대해서 스타일을 적용하는 것입니다.

 

  • 특정 요소에 스타일을 적용하려면, 특정 요소를 선택할 수 있어야 합니다. 이렇게 요소를 선택하기 위해 사용되는 것이 선택자입니다.
  • 예를 들어 현재 HTML 문서의 ul 태그 중 3번째 ul 태그의 li 태그 들을 빨간색 글자로 작성하고 싶다면?

2. Rule Set

CSS를 적용하기 위해, HTML 페이지 안의 특정 요소들(선택자)을 어떻게 렌더링(Rendering) 할 것인지 브라우저에게 알려주는 CSS 문장입니다.

3. 선택자 (Selector)

3-1. 전체 선택자(Universal Selector)

전체 선택자는 HTML 페이지 내부의 모든 요소에 같은 CSS 속성을 적용합니다. 하지만 이를 사용하면 문서 안의 모든 요소를 읽어내려야 하기 때문에 페이지의 로딩 속도가 느려질 수 있습니다. 자주 사용하는 것은 좋지 않습니다.

* {
  background-color: aquamarine;
}

3-2. 태그 선택자(Type Selector)

태그 선택자는 말 그대로 HTML Element의 특정 요소 (p, ul, div 등)에 대해서 CSS를 적용하는 선택자입니다. 주의해야 할 점은 단순히 태그 선택자만 사용 시 해당 태그 전부가 스타일이 적용되게 되고, HTML 속성으로 style이 걸려 있는 경우 해당 요소가 우선권이 더 높습니다.

p {
  color: red;
}
<p>테스트 1번</p>
<p>테스트 2번</p>
<p>테스트 3번</p>
<p style="color: blue">테스트 4번</p>
<div>테스트 5번</div>

3-3. 클래스 선택자(Class Selector)

클래스 선택자는 해당 클래스를 속성값으로 가진 HTML 요소를 찾아 선택하는 선택자입니다. 해당 클래스에 해당하는 요소들은 전부 스타일이 적용됩니다. 역시 HTML에 style이 직접 적용되어 있는 경우 해당 요소가 우선순위를 가집니다.

.p-tag {
  color: red;
}
<p class="p-tag">테스트 1번</p>
<p class="p-tag">테스트 2번</p>
<p>테스트 3번</p>
<p class="p-tag" style="color: blue">테스트 4번</p>

3-4. 아이디 선택자(ID Selector)

말 그대로 해당 ID를 가진 HTML 요소를 선택하는 선택자입니다. HTML에서 ID 같은 경우 중복 ID로 사용하지 않는 것이 좋습니다. CSS에서 ID 선택자를 사용하는 경우 중복의 ID가 있더라도 인식을 하지만, 나중에 자바스크립트 사용 시 문제가 발생할 수 있습니다.

#one {
  color: red;
}

#two {
  color: red;
}

#three {
  color: red;
}
<!-- id가 one인 요소 2개에 적용이 되기는 하나 사용하지 않는 것이 좋음 -->
<p id="one">테스트 1번</p>
<p id="one">테스트 2번</p>
<p id="two">테스트 3번</p>
<p>테스트 4번</p>
<p id="three" style="color: blue">테스트 5번</p>

3-5. 복합 선택자(Combinator)

복합 선택자는 두 가지 이상의 선택자를 복합적으로 사용하는 선택자입니다. (지금까지 말한 모든 요소의 선택자를 복합적으로 사용 가능합니다.)

1) 하위 선택자(Descendant Combinator)

A라는 선택자의 하위에 있는 B라는 선택자를 선택합니다. 위에서 설명했듯이 꼭 태그 선택자만의 조합은 아니어도 되며 모든 선택자를 복합적으로 조합할 수 있습니다.

 

예를 들어 아래 예시 코드의 경우 HTML 페이지의 모든 div 요소 중 해당 div의 자식 요소 중 id가 p-tag인 요소만 적용하는 선택자입니다.

div #p-tag {
  color: red;
}
<div>
  <p id="p-tag">테스트 1번</p>
  <p>테스트 2번</p>
  <span>
    <p id="p-tag">테스트 3번</p>
  </span>
</div>
<p id="p-tag">테스트 4번</p>

여기서 주의 깊게 봐야 할 점은, 하위 선택자는 예제 기준 div라는 요소만 충족한다면 div의 자식의 자식, 그 자식의 자식 요소까지도 어떠한 엘리먼트(태그)가 오더라도 id가 p-tag라면 해당 요소를 선택합니다.

2) 자식 선택자(Child Combinator)

자식 선택자는 하위 선택자와 비슷하지만, 정확히 div 자식으로서의 p-tag라는 id를 가진 요소들만 선택합니다. 즉, 더 이상 자식 요소로 들어간다면 해당 요소들은 선택하지 않습니다.

div > #p-tag {
  color: red;
}
<div>
  <p id="p-tag">테스트 1번</p>
  <p id="p-tag">테스트 2번</p>
  <span>
    <p id="p-tag">테스트 3번</p>
  </span>
</div>
<p id="p-tag">테스트 4번</p>

3) 인접 형제 선택자(Adjacent Sibling Combinator)

같은 부모 요소를 가지는 요소들을 형제 관계라고 부릅니다. 이때 먼저 나오는 요소를 '형 요소' 나중에 나오는 요소를 '동생 요소'라고 부릅니다. 먼저 나온다는 표현은 html 문서 상 먼저 쓰이는 것을 의미합니다.

 

인접 형제 선택자는 A라는 형제의 첫 번째로 오는 B라는 동생 요소를 선택합니다.

 

예를 들어 아래 예제의 경우 div 엘리먼트를 먼저 찾고, 그다음에 나오는 아이디가 p-tag인 동생 요소(div를 먼저 탐색하므로 div는 무조건 형 요소)를 선택합니다. (말 그대로 인접한 형제를 선택하는 선택자)

div + #p-tag {
  color: red;
}
<div>
  <p id="p-tag">테스트 1번</p>
</div>
<p id="p-tag">테스트 2번</p>
<p id="p-tag">테스트 3번</p>
<p id="p-tag">테스트 4번</p>

4) 일반 형제 선택자(General Sibling Combinator)

일반 형제 선택자는 A ~ B일 경우, A라는 형 요소의 B에 해당하는 동생 요소들 전부를 선택하는 선택자입니다.

div ~ #p-tag {
  color: red;
}
<div>
  <p id="p-tag">테스트 1번</p>
</div>
<p id="p-tag">테스트 2번</p>
<p id="p-tag">테스트 3번</p>
<p id="p-tag">테스트 4번</p>

3-6. 속성 선택자(Attribute Selectors)

속성 선택자는 해당 엘리먼트가 가진 속성에 대해서 일치하는 요소를 선택하는 선택자입니다.

[속성] 요소[속성] 해당 속성을 가지는 요소를 선택합니다.
[속성="속성값"]  요소[속성="속성값"] 해당 속성과 속성값을 가지는 요소를 선택합니다.

속성값의 경우 문자열로서 인식하여 공백을 포함 완벽히 일치해야 합니다.

[href] {
  color: black;
}

h1[title="h1 태그입니다."] {
  color: yellow;
}
<h1 title="h1 태그입니다.">h1</h1>
<h1 title="h1">h1</h1>
<a href="www.test.com">a 태그</a>

1) 문자열 속성 선택자.

[속성~="속성값"] 요소[속성~="속성값"] 해당 속성과 속성 값을 가지는 요소를 선택합니다. 여러 개의 속성 값 중 해당 속성값이 포함된다면 선택합니다.
[속성|="속성값"] 요소[속성|="속성값"] 속성값이 정확히 일치하는 요소나 속성값-1, 속성값-2 ... 인 요소만 선택합니다.
[속성^="속성값"] 요소[속성^="속성값"] 속성 값이 "값"으로 시작하는 요소를 선택합니다.
[속성$="속성값"] 요소[속성$="속성값"] 속성 값이 "값"으로 끝나는 요소를 선택합니다.
[속성*="속성값"] 요소[속성*="속성값"] 해당 속성값을 포함하는 요소를 모두 선택합니다.

 

2) ~= 선택자.

속성값에 일치하는 단어가 포함된다면 선택합니다. 단어는 공백을 기준으로 설정됩니다. 또한 단어가 정확히 일치해야 선택합니다.

p[class~="two"] {
  color: blue;
}
<p class="one two three">p-tag</p>

이처럼, 속성값의 순서는 상관없지만 단어가 정확히 일치해야 합니다.

 

3) |= 선택자.

속성값이 정확히 일치하는 요소나, 속성값-문자열인 요소를 선택합니다.

<p class="p">p tag</p>
<p class="p-1">p tag</p>
<p class="p-2">p tag</p>
p[class|="p"] {
  color: blue;
}

4) ^=, $= 선택자.

속성값이 해당 문자열로 시작하거나(^=) 끝나는($=) 요소를 선택합니다.

<p class="p-tag-1">p tag</p>
<p class="p-tag-2">p tag</p>
p[class^="p"] {
  color: blue;
}

p[class$="2"] {
  color: red;
}

5) *= 선택자.

해당 속성값의 문자열을 포함하는 요소를 선택합니다. 이는 단어 유무를 떠나서 단순히 해당 문자(문자열)이 포함된다면 선택됩니다.

<p class="one two three">p tag</p>
p[class*="e"] {
  color: blue;
}

one two three 등 e가 여러 번 포함되므로 선택됨.

3-7. 가상 클래스 선택자(Pseudo-Classes)

1) 링크 선택자(The link pseudo-classes)

link는 방문하지 않은 요소를 선택합니다. visited는 방문한 적이 있는 요소를 선택합니다.

a:link {
  color: green;
}

a:visited {
  color: black;
}
<a href="https://google.com">구글</a>
<a href="https://test.com">test</a>

2) 동적 선택자(The user action pseudo-classes)

:active 요소에 마우스 클릭 또는 키보드 엔터가 눌린 동안 해당 요소를 선택합니다.

:hover 요소에 마우스가 올라가 있는 동안 해당 요소를 선택합니다.

:focus 요소에 포커싱이 돼있는 경우 해당 요소를 선택합니다.

focus의 경우 <input>, <select>, <button>, <a> 태그 등에만 적용됩니다.

div,
button {
  background-color: blanchedalmond;
  margin-bottom: 10px;
}

.active:active {
  background-color: blue;
}

.hover:hover {
  background-color: red;
}

.focus:focus {
  background-color: aquamarine;
}
<div class="active">active div</div>
<div class="hover">hover div</div>
<button class="focus">focus button</button>

3) 구조적 가상 클래스 선택자(Structural pseudo-classes)

요소의 순서에 따른 선택을 하는 선택자입니다. 괄호 안에 (an+b)를 넣을 수 있습니다.

  • a: 배수
  • n: 카운터, 0부터 시작
  • b: 시작 위치
  • (odd) 홀수, (even) 짝수
  • 2n + 1 홀수, 2n + 0 짝수, 3n + 0 3의 배수, 4n + 0 4의 배수, ....

 

4) 일반 구조 선택자

해당 요소의 지정된 순서가 일치한다면 선택합니다. (해당 요소가 아닌 요소도 계산에 포함됩니다.)

li:first-child {
  color: blue;
}
li:last-child {
  color: red;
}

li:nth-child(3) {
  color: aquamarine;
}

li:nth-last-child(2) {
  color: bisque;
}
<ol>
  <li>one</li>
  <li>two</li>
  <div>div</div>
  <li>three</li>
  <li>four</li>
  <li>five</li>
  <li>six</li>
</ol>

li:nth-child(3)의 요소가 div이므로 선택하지 않음.

5) 요소 지정 구조 선택자

해당 요소의 지정된 순서가 일치한다면 선택합니다. (해당 요소만 계산에 포함됩니다.)

<ol>
  <li>one</li>
  <li>two</li>
  <div>div</div>
  <li>three</li>
  <li>four</li>
  <li>five</li>
  <li>six</li>
</ol>
li:first-of-type {
  color: red;
}

li:last-of-type {
  color: blue;
}

li:nth-of-type(3) {
  color: aqua;
}

li:nth-last-of-type(5) {
  color: blueviolet;
}

nth-of-type(nth-last-of-type)의 결과가 div가 아닌 li 요소의 순서만을 선택하므로 아래와 같은 결과가 나옵니다.

그 외

  • :root 문서의 최상위 요소(html)을 선택합니다.
  • :only-child 해당 요소가 유일한 자식이면 선택합니다.
  • :only-of-type 해당 요소가 유일한 타입이면 선택합니다.
  • :empty  텍스트 및 공백을 포함하여 자식 요소가 없는 요소를 선택합니다.
:root {
  background-color: azure;
}

div div:only-child {
  background-color: red;
}

ol:only-of-type {
  color: blue;
}

div:empty {
  width: 300px;
  height: 300px;
  background-color: black;
}
<ol>
  <li>one</li>
  <li>two</li>
  <li>three</li>
</ol>

<div><div>div1</div></div>

<div>div2</div>
<div></div>

3-8. 언어 선택자(language pseudo-classes)

lang 속성의 값이 일치하는 요소들을 선택합니다.

div:lang(ko) {
  background-color: red;
}
<div lang="ko">ko1</div>
<div lang="ko">ko2</div>
<div lang="en">en1</div>

3-9. 부정 선택자

A가 아닌 B 요소들을 선택합니다.

.my-div 요소가 아닌 div 요소들을 선택합니다.

div:not(.my-div) {
  background-color: red;
}
<div class="my-div">div1</div>
<div>div2</div>

3-10. 목적 선택자

앵커에 의해 해당 엘리먼트의 URI가 요청되면 선택됩니다.

<div id="one">div 01</div>
<div id="two">div 02</div>

<a href="#one">1</a>
<a href="#two">2</a>
div:target {
  color: red;
}

 

3-11. UI 요소 상태 선택자(The UI element states pseudo-classes)

  • :enabled 셀렉터가 사용 가능한 상태일 때
  • :disabled 셀렉터가 사용 불가능한 상태일 때
  • :checked 셀렉터가 체크된 상태일 때
/* 선택 가능한 상태 */
input:enabled + span {
  color: blue;
}

/* 선택 불가능한 상태 */
input:disabled + span {
  color: gray;
  text-decoration: line-through;
}

/* 체크된 상태 */
input:checked + span {
  color: red;
}
<form action="">
  <input type="radio" name="radio" value="male" /><span>male</span> 
  <input type="radio" name="radio" value="female" /><span>female</span>
  <input type="checkbox" value="bicycle" /><span>bicycle</span>
  <input type="checkbox" value="car" /><span>car</span>
  <input type="checkbox" value="motocycle" disabled /><span>motocycle</span>
</form>

3-12. 가상 엘리먼트 선택자(Pseudo-Elements)

  • ::first-line 해당 요소의 첫 번째 라인을 선택합니다.
  • ::first-letter 해당 요소의 첫 번째 문자를 선택합니다.
  • ::before 해당 요소의 시작 지점에 생성될 요소를 선택합니다.
  • ::after 해당 요소의 끝 지점에 생성될 요소를 선택합니다.
  • ::selection 사용자가 드래그한 블록을 선택합니다.
#first-line::first-line {
  color: red;
}

#first-letter::first-letter {
  font-size: 40px;
  font-weight: bold;
}

#before-after::before {
  content: "==START==";
  color: blue;
}

#before-after::after {
  content: "==END==";
  color: red;
}

#selection::selection {
  background-color: green;
  color: white;
}
<div id="first-line">
  first-line Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iste fugit perspiciatis laudantium minus animi nesciunt, perferendis
  nostrum rerum doloremque eius reiciendis ipsum atque repellendus doloribus minima debitis error exercitationem possimus?
</div>
<hr />
<div id="first-letter">
  first-letter Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas magnam quas dolores obcaecati beatae deserunt itaque nihil?
  Minima itaque, cupiditate ex error modi incidunt inventore architecto delectus maxime saepe voluptate.
</div>
<hr />
<div id="before-after">before & after</div>
<hr />

<div id="selection">
  selection Lorem ipsum dolor sit amet consectetur adipisicing elit. Magnam neque impedit atque illum reprehenderit sequi similique quae commodi?
  Distinctio eaque dolorem libero molestias excepturi necessitatibus perspiciatis deleniti? Cumque, quia illo?
</div>

4. 선택자의 우선순위

기본적으로 웹 문서에 적용한 Style Sheets의 적용 방법에 따라 우선순위가 먼저 나뉩니다.

 

  1. 인라인 스타일 (HTML 요소의 속성에 직접적으로 style="" 적용)
  2. 내부 / 외부 스타일 시트
  3. 웹 브라우저의 기본 스타일

하지만 명시적으로 !important를 선언한 경우 내외부 스타일 시트에서 선언을 했더라도, 인라인 스타일보다 더 높은 우선순위를 가집니다. 그래서 다른 선언들을 덮어버릴 수 있기 때문에 꼭 필요한 곳에만 사용해야 합니다.

 

1) CSS 명시도(Specificity) 계산법

인라인 스타일이 아닌 내, 외부 스타일인 경우 아래의 계산법을 따르면 됩니다.

 

  • ID 선택자 하나당 100으로 계산합니다.
  • Class 선택자 하나당 10으로 계산합니다.
  • Tag 선택자 하나당 1로 계산합니다.
  • 공용 선택자는 모두 0으로 계산합니다.
  • 가상 엘리먼트는 무시합니다.

스타일의 우선순위가 같거나, 계산 방법이 없는 경우 마지막에 지정된 스타일이 우선적으로 적용됩니다. 예를 들어 자손 선택자와 자식 선택자가 중복 적용된 경우 우선순위 계산법에는 없으므로 두 선택자 중 마지막에 지정된 스타일이 적용됩니다. 

 

 

대략적으로 우선순위를 요약해 보자면 아래와 같습니다.

2) 우선순위

  1. !important 선언
  2. 인라인 스타일
  3. ID
  4. Class
  5. Tag
  6. 공용 선택자, 자식 선택자, 인접 선택자 ....
728x90
반응형
Comments