1. selector(선택자)
style을 적용하고자 하는 HTML 요소를 특정하기 위해서 selector가 존재한다.
style을 적용하고자 하는 HTML 요소를 selector로 특정하고 선택된 요소에 스타일을 정의하는 것이다.
구조를 그림으로 그려보자면 다음과 같다.

선택자의 종류
크게 4가지가 있다.
- 기본 선택자(Basic selectors) - 기본적인 선택자의 표현
- 그룹 선택자(Grouping selectors) - 다수의 요소를 선택하는 선택자의 표현
- 결합 선택자(Combinator selectors) - 요소와 인접하는 형제 또는 자식 요소들을 선택하는 선택자의 표현
- 의사 클래스 또는 의사 요소(Pseudo classes or Pseudo elements)
1. 기본 선택자
기본적이고 가장 대중적으로 요소들을 선택하는 방법을 뜻한다.
| 종류 | 기능 | 표현방법 | Comment |
| 전체 선택자 (Universal selector) |
모든 요소를 선택 (Namespace 제한 가능) | * | HTML 문서 내의 모든 요소를 선택한다. html 요소를 포함한 모든 요소가 선택된다. (head 요소도 포함된다) |
| 유형[태그] 선택자 (Type selector) |
요소의 이름으로 선택(태그 이름) | elementname | |
| 클래스 선택자 (Class selector) |
요소의 클래스명으로 선택 | .classname | class 어트리뷰트 값은 중복될 수 있다. |
| ID 선택자 (ID selector) |
요소의 아이디명으로 선택 | #idname | id 값은 중복될 수 없는 유일한 값이다. |
| 속성 선택자 (Attribute selector) |
해당 속을 포함한 요소를 선택 | [attr] 또는 [attr=value] 등 |
테이블에 표시된 왼쪽의 패턴 말고도 여러 패턴이 있다. 바로 아래에서 다룬다. |
속성 선택자
개인적으로 익숙하지 않았던 속성 선택자만 잠깐 보면 기본적으로는 같이 표현할 수 있었다.
속성 선택자를 앞에 태그를 붙이지 않고 단독으로도 쓸 수 있다는 점도 처음 알게 되었다.
[special] 이런 식으로 말이다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>속성 선택자</title>
</head>
<style>
.flex-box {
display: flex;
flex-direction: column;
}
span[data-special='special'] {
color: rgb(186, 85, 211);
}
[special] {
color: rgb(98, 255, 0);
}
</style>
<body>
<main>
<div class="flex-box">
<span>div 바로 밑 span</span>
<section>
<span data-special="special"> div 밑 section 바로 밑 span </span>
</section>
<div>div 밑 div</div>
<span>div와 같은 선상에서 이후의 span</span>
<span special>연속 span</span>
</div>
</main>
</body>
</html>

아 그리고 중요한 점이 한 가지 있는데, 속성 선택자에서 혹시 inline-style 속성을 가져올 경우가 있으면(거의 없지만) 세미콜론(;)까지 맞추는 것도 아주 중요하다. 그 이유는 어떤 태그의 인라인 스타일 속성이 세미콜론(;)으로 문의 끝을 마무리 지었다면 속성 선택자에서도 세미콜론(;)을 붙여서 찾아야 하기 때문이다. (인라인 스타일 속성은 프로퍼티가 하나일 경우에는 프로퍼티간 구분이 필요없기 때문에 세미콜론(;) 없이 문을 끝내도 문제가 없지만 보통 붙이는 편이다.)
여러 가지 속성 선택 방법
속성 선택자에도 방법이 여럿 있음을 알게 되었다.
아래 예시들은 `target`과 `class`만으로 속성 선택을 보여줬지만, 이외의 모든 속성으로도 가능하다는 점을 알고 가면 좋다.
1. [attribute]
지정된 어트리뷰트를 갖는 모든 요소를 선택한다.
a[target] { color: red; }
a태그에 target이라는 속성을 가진 요소를 선택한다.
= `<a href="#" target="_blank">link</a>`선택함
= `<a href="#">link</a>` 선택하지 않음
참고로 앞에 element를 적어주지 않고 [attribute] 이 패턴만으로도 선택된다.
[target] { color: red; }
2. [attribute="value"]
지정된 어트리뷰트를 가지며 지정된 값과 어트리뷰트의 값이 일치하는 모든 요소를 선택한다.
a[target="_blank"] { color: red; }
a태그에 target=”_blank”라는 속성을 가진 요소를 선택한다.
※ target이 반드시 _blank인 요소만 잡으니 주의!
= `<a href="#" target="_blank">link</a>` 선택함
= `<a href="#" target="_self">link</a>` 선택하지 않음
= `<a href="#" target="_blankk">link</a>` 선택하지 않음
3. [attribute~="value"]
지정된 어트리뷰트의 값이 지정된 값을 (공백으로 분리된) 단어로 포함하는 요소를 선택한다.
div[class~="apple"] { background-color: red; }
apple이라는 class를 가진 요소를 선택한다.
※ 여러개의 class가 함께 지정되어 있어도, apple을 가졌다면 선택한다.
= `<div class="apple">layer</div>` 선택함
= `<div class="pine apple">layer</div>` 선택함
= `<div class="pine-apple">layer</div>` 선택하지 않음('-' 하이픈으로 붙어 있기 때문)
4. [attribute|=”value”]
지정된 어트리뷰트의 값과 일치하거나 지정 어트리뷰트 값 뒤 연이은 하이픈(“값-“)으로 시작하는 요소를 선택한다.
div[class|="layer"] { background-color: red; }
layer라는 class로 시작하는 요소만 선택하되, 하이픈(-)으로 구분해 더 많은, 더 다양한 요소를 선택할 수 있다.
= <div class="layer">layer</div> 선택함
= <div class="layer-red">layer</div> 선택함
= <div class="layer-blue">layer</div> 선택함
= <div class="layer yellow">layer</div> 선택하지 않음
= <div class="green layer">layer</div> 선택하지 않음
5. [attribute^=value]
지정된 어트리뷰트 값으로 시작하는 요소를 선택한다.
div[class^="minions"] { background-color: red; }
minions라는 class로 시작하는 요소를 전부 선택한다.
= <div class="minions">layer</div> 선택함
= <div class="minions-yellow">layer</div> 선택함
= <div class="minions_yellow">layer</div> 선택함
= <div class="minions minimini">layer</div> 선택함
= <div class="yellow minions">layer</div> 선택하지 않음
= <div class="yellow_minions">layer</div> 선택하지 않음
6. [attribute$=value]
지정된 어트리뷰트 값으로 끝나는 요소를 선택한다.
div[class$="end"] { background-color: red; }
end라는 class로 끝나는 요소를 선택한다.
.pdf등을 값(value)으로 지정해 특정 파일만 선택하는 것도 가능하다.
= <div class="end">layer</div> 선택함
= <div class="start end">layer</div> 선택함
= <div class="ok_end">layer</div> 선택함
= <div class="end bye">layer</div> 선택하지 않음
유용한 예시를 또 봤는데 이러한 코드였다.
<!DOCTYPE html>
<html>
<head>
<style>
/* a 요소 중에 href 어트리뷰트 값이 ".html"로 끝나는 요소 */
a[href$=".html"] { color: red; }
</style>
</head>
<body>
<a href="test.html">test.html</a><br>
<a href="test.jsp">test.jsp</a>
</body>
</html>
7. [attribute*=value]
지정된 어트리뷰트 값을 포함하는 요소를 선택한다.
div[class*="wow"] { background-color: red; }
wow라는 class를 가진 모든 요소를 선택한다.
class가 어떻게 조합이 되어도 wow만 완성되면 무조건 선택한다.
= <div class="wow">layer</div> 선택함
= <div class="wow ohoh">layer</div> 선택함
= <div class="wow-haha">layer</div> 선택함
= <div class="wwwwwow">layer</div> 선택함
8. not equal 구현하기
있을 법한 [attr!=value] not equal 기호가 없다. 이는 `:not` 부정 셀렉터와 결합하여 만들어야 한다.
예를 들어 "wow"라는 속성값이 부여된 태그들은 전부 선택하고 싶지 않다면, 이와 같이 만들어야 한다.
:not([class*="wow"]) { background-color: red; }
2. 결합자
결합 선택자(Combinator Selectors) 또는 복합 셀렉터라고 불린다.
그냥 예시와 함께 보는 것이 빠르게 이해하는 편에 좋다.
(mdn 문서 그대로 참고했음)
🟦 자손 결합자
형태: A B
예시: div span
결과: <div> 요소 안에 위치하는 모든 <span> 요소와 일치(depth 무한)
사이에 공백으로 표현한 것이다.
활용예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>자손 결합자</title>
<style>
.flex-box {
display: flex;
flex-direction: column;
}
div span {
color: rgb(186, 85, 211);
}
</style>
</head>
<body>
<main>
<div class="flex-box">
<span>div 바로 밑 span</span>
<section>
<span> div 밑 section 바로 밑 span </span>
</section>
<div>div 밑 div</div>
<span>div와 같은 선상에서 이후의 span</span>
<span>연속 span</span>
</div>
</main>
</body>
</html>

🟦 자식 결합자
형태: A > B
예시: ul > li
결과: <ul> 요소 바로 아래(1 depth만 해당)에 위치하는 모든 <li> 요소와 일치
활용예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>자식 결합자</title>
</head>
<style>
.flex-box {
display: flex;
flex-direction: column;
}
div > span {
color: rgb(186, 85, 211);
}
</style>
<body>
<main>
<div class="flex-box">
<span>div 바로 밑 span</span>
<section>
<span> div 밑 section 바로 밑 span </span>
</section>
<div>div 밑 div</div>
<span>div와 같은 선상에서 이후의 span</span>
<span>연속 span</span>
</div>
</main>
</body>
</html>

🟦 일반 형제 결합자
형태: A ~ B
추가설명: 첫 번째 요소를 뒤따르면서(첫 번째 요소랑 같은 급) 같은 부모를 공유하는 모든 두 번째(B) 요소.
예시: p ~ span
결과1: <p> 요소를 뒤따르는 모든 <span> 요소와 일치
결과2: 만약 A가 부모요소, B가 자식요소라면 A의 자식인 모든 B 요소를 선택하게 된다.
활용예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>일반 형제 결합자</title>
<style>
div ~ span {
color: rgb(186, 85, 211);
}
.flex-box {
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<main>
<div class="flex-box">
<span>div 바로 밑 span</span>
<section>
<span> div 밑 section 바로 밑 span </span>
</section>
<div>div 밑 div</div>
<span>div와 같은 선상에서 이후의 span</span>
<span>연속 span</span>
</div>
</main>
</body>
</html>

🟦인접 형제 결합자
형태: A + B
예시: h2 + p
결과: <h2> 바로 뒤에 위치하는 단 한개의 <p> 요소와 일치
활용예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>인접 형제 결합자</title>
<style>
.flex-box {
display: flex;
flex-direction: column;
}
div + span {
color: rgb(186, 85, 211);
}
</style>
</head>
<body>
<main>
<div class="flex-box">
<span>div 바로 밑 span</span>
<section>
<span> div 밑 section 바로 밑 span </span>
</section>
<div>div 밑 div</div>
<span>div와 같은 선상에서 이후의 span</span>
<span>연속 span</span>
</div>
</main>
</body>
</html>

🟦열 결합자
형태: A || B
예시: col || td
결과: <col> 범위에 속하는 모든 <td> 요소와 일치
🚨주의사항: Experimental: This is an experimental technology. 아직 실험적인 요소입니다. 해당 열 결합자가 아직 적용되는 브라우저는 없습니다.(2023.10.06 기준)

문법:
"||" 를 중심으로 양옆 빈 공간( )은 선택사항이지만 권장됩니다.
좌항에 선택될 열(col)을 적어주고 우항에는 그 열에 속해있는 요소들 중에 선택할 요소를 고르면 됩니다.
/* The white space around the || combinator is optional but recommended. */
column-selector || cell-selector {
/* style properties */
}
예시 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>column combinator</title>
<style>
col.selected||td {
background: gray;
color: white;
font-weight: bold;
}
</style>
</head>
<body>
<table border="10">
<colgroup>
<col span="2" />
<col class="selected" />
</colgroup>
<tbody>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td colspan="2">D</td>
<td>E</td>
</tr>
<tr>
<td>F</td>
<td colspan="2">G</td>
</tr>
</tbody>
</table>
</body>
</html>
selector playground
🎈all selector playground except column combinator
See the Pen Untitled by Olimjo (@OLIMJO) on CodePen.
3. 그룹 선택자
여러 요소를 한 번에 선택하기 위한 방법이다.
아래 예시는 div와 span요소를 모두 선택한 것이다.
div, span {
...
}
4. 의사 클래스 또는 의사 요소(Pseudo classes or Pseudo elements)
가상 클래스 또는 가상 요소라고도 불린다.
종류가 아주 많기에 모든 걸 다룰 순 없다. 따로 사용 방법과 관련해서 🔗글을 적었다.
자주 사용하는 클래스와 요소만 정리하자면 다음과 같다.
의사 클래스(Pseudo classes)
| 이름 | 설명 |
| :link | 사용자가 방문하지 않은 링크를 선택 |
| :visited | 사용자가 방문했던 링크를 선택 |
| :hover | 마우스 커서가 링크위에 올라와 있는 요소를 선택 |
| :nth-child(n) | n번째 위치에 있는 자식 요소를 선택 |
| :focus | 포커스가 들어와 있을 때선택 |
| :active | 클릭된 상태일 때 선택 |
| :checked | 체크된 input 요소를 선택 |
| :enabled | 셀렉터가 사용 가능한 상태일 때 |
| :disabled | 셀렉터가 사용 불가능한 상태일 때 |
의사 요소(Pseudo elements)
| 이름 | 설명 |
| ::before | 특정 요소의 시작부분에 콘텐츠를 추가한다. |
| ::after | 특정 요소의 끝부분에 콘텐츠를 추가한다. |
| ::first-line | 요소의 텍스트 첫 줄을 선택한다. |
| ::first-letter | 요소의 첫 글자를 선택한다. |
2. 박스모델(블럭 요소와 인라인 요소 이해하기)
의도한 대로 박스를 구성하고 싶다면, 박스모델을 전부 외우지는 못해도 이해는 하고 있어야 한다.
🟦 블럭 요소(block level element): 기본값으로 화면 전체를 쓰는 태그들
- 블럭 요소는 모든 인라인 요소를 포함할 수 있고, 다른 블록 요소도 포함할 수 있음.
- width, height, margin, padding 등을 사용하여 형태를 변형하여 레이아웃을 수정할 수 있음.
- 블록 요소 다음에는 줄바꿈(line-break)이 이루어짐.
- 블럭 레벨 엘리먼트를 인라인 엘리먼트처럼 바꿔줄 수도 있다.
🎈블럭 요소들
address, article, aside, audio, blockquote, canvas, dd, div, dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, noscript, ol, output, p, pre, section, table, ul, video
🟦 인라인 요소(inline element) : 기본값으로 자신의 컨텐트 만큼의 크기를 갖는 태그들
- 인라인 요소는 항상 블록 요소 안에 포함되어 있음.
- 인라인 요소 안에 다른 인라인 요소가 포함될 수 있음.
- margin, padding을 사용할 수 있음.
- 기본적으로 컨텐츠가 끝나는 지점까지를 넓이로 가지게 됨. => 임의로 width, height 변형을 줄 수 없다는 얘기
- 인라인 요소는 line-height로 줄의 높낮이를 조절할 수 있고, text-align 으로 텍스트의 중앙, 좌, 우측을 정렬할 수 있음.
- 인라인 요소 다음에는 줄바꿈(line-break)이 없고 우측으로 바로 이어서 표시가 됨.
- 인라인 엘리먼트를 블럭 엘리먼트처럼 바꿔줄 수 있다.
🎈인라인 요소들
a, abbr, acronym, b, bdo, big, br, button, cite, code, dfn, em, i, img, input, kbd, label, map, object, q, samp, small, script, select, span, strong, sub, sup, textarea, tt, u, var
🟦 인라인 블럭 요소(inline-block element) : 인라인 요소 특징에 block요소의 특징을 합한 태그
- `display: inline-block`이라고 속성 선언을 해야 인라인 블럭 요소가 됨.
- width, height 크기를 지정할 수 있는 인라인 요소라고 생각하면 됨.
- margin, padding과 border는 인라인, 인라인 블럭 요소 둘 다 가질 수 있지만 width와 height는 인라인 블럭 요소만 가질 수 있음.
🎈예시
`<h1>`은 블럭요소라서 화면 전체 너비를 차지하고, `<a>` 태그는 인라인 요소라서 컨텐츠 크기만큼을 너비로 가지는 모습을 볼 수 있다.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h1 {
border-width: 5px;
border-color: red;
border-style: solid;
}
a {
border-width: 5px;
border-color: red;
border-style: solid;
}
</style>
</head>
<body>
<h1>CSS</h1>
CasCading Style Sheet means CSS.
<a href="#">CSS</a> is a style sheet language.
</body>
</html>
🟦 display: inline, display: block;
-- 블럭 레벨 엘리먼트를 인라인 엘리먼트처럼 바꿔줄 수도 있다.
-- 인라인 엘리먼트를 블럭 엘리먼트처럼 바꿔줄 수 있다.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h1 {
border-width: 5px;
border-color: red;
border-style: solid;
display: inline;
}
a {
border-width: 5px;
border-color: red;
border-style: solid;
display: block;
}
</style>
</head>
<body>
<h1>CSS</h1>
CasCading Style Sheet means CSS.
<a href="#">CSS</a> is a style sheet language.
</body>
</html>
🎈 블럭 컨텐트(content)의 크기는 width와 height로 지정할 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h1, a{
border: 5px solid red;
/* padding: 20px; */
margin: 0px;
display: inline-block;
}
</style>
</head>
<body>
<h1>CSS</h1>
<h1>CSS</h1>
</body>
</html>
🟦 display: inline-block, display: inline;
text 텍스트를 가지는 span 태그에 클래스 선택자(.block)를 이용해서 `inline-block` 속성값을 줬다.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.inline {
color: blue;
width: 100px;
border: 1px solid blue;
}
.block {
display: inline-block;
}
</style>
</head>
<body>
<main>
<section>
<article>
<div>
Amet consectetur incididunt
<span class="inline block">test</span>tempor velit eiusmod cillum pariatur aute mollit ut velit
<span class="inline">one republic</span> ipsum ut adipisicing.
</div>
<h2 title>Document</h2>
</article>
</section>
</main>
</body>
</html>
🎈shortcut 방법
참고로 단축 속성이 가능한 프로퍼티들이 있다.
프로퍼티 값들의 위치는 중요하지 않다.
solid 5px red 등 순서는 막 바뀌어도 상관없다. 단, 몇 가지 특수한 프로퍼티들은 순서가 중요하다.
h1, a{
border: 5px solid red;
}
순서가 중요한 animation 단축 속성
/* @keyframes duration | easing-function | delay |
iteration-count | direction | fill-mode | play-state | name */
animation: 3s ease-in 1s 2 reverse both paused slidein;