모르면 배우면 된다

CSS 스터디 1주차 : 셀렉터, 콤비네이터, 가상셀렉터 본문

FRONT

CSS 스터디 1주차 : 셀렉터, 콤비네이터, 가상셀렉터

Okguri 2022. 8. 30. 13:50

CSS 스터디 정리! 

참고 : https://github.com/techhtml/css-study-2022/tree/main/1st

 

1. CSS란 

Cascading Style Sheet 

sheet : 데이터가 나열된 곳.

IBSheet도 sheet라고 씀!

style sheet : style이 나열된 공간. 

CSS는 조건이 맞으면, 이걸 보여줘. 정도는 가능하지만 논리적 결과물을 만들어낼 수 있지는 않다. 

cascading : 폭포. 위에서 아래로 내려오는 형상을 말함. 

CSS grid layout : 모듈 단위로 관리됨 

 

2. selector 

- CSS는 스타일의 나열. 

- 스타일을 어디에 적용할지 판단하는 것이 selector다. 

p {} : 전체 <p> 태그에 스타일 적용.

그러나 위 같은 selector는 너무 범용적이므로 보통 클래스로 선택을 한다. 

클래스는 공백으로 중복 적용할 수 있다. 확장성을 고려해 스타일을 잘 분리해놓으면 안정적인 서비스를 만드는 데 도움이 된다. 

 

<!-- Box 스타일 + Area 스타일 + Container 스타일 -->
<div class="box area container">

/* 클래스 셀렉터 */
/* 특정한 클래스명을 가진 요소에 스타일을 부여 */
/* 숫자나 특수문자로 시작하면 X */
/* 클래스명은 기본적으로 중복이 가능 */
.box {}
.area {}
.wrapper {}
.container {}
.header {}
.footer {}
<!-- Box 스타일 -->
<div class="box">
  <h1>안녕하세요</h1>
</div>
<!-- Box 스타일 + Area 스타일 -->
<div class="box area">
  <h1>안녕하세요</h1>
</div>
<!-- Box 스타일 + Area 스타일 + Container 스타일 -->
<div class="box area container">
  <h1>안녕하세요</h1>
  <div>
    <h1>안녕하세요</h1>
  </div>
</div>

 

3. 콤비네이터 

- selector 만으로 못하는 것. 

- 특정 요소의 자식 요소를 제어하고 싶을 때

1) 자손 콤비네이터

- 형식 : {조상 요소}(공백){자손 요소}

- 자손 요소 : 손주....!

- 자식이 어떤 요소이든 간에, 자손 요소 중 해당 요소가 있다면 적용

<div class="box">
	<div>
		<h1>안녕하세요</h1>
	</div>
</div>

.box h1 {} ==> 안녕하세요 h1에 접근. 즉 .box의 자손 h1에게 접근. h1의 부모가 div든 뭐든 상관없음

2) 자식 콤비네이터

- 형식 : { 부모 }>{자식}

 - 코드가 길어지면 비용이 된다. 한 태그마다 모두 class를 붙이면 안전할 수는 있지만, 코드량이 늘어나며 비용도 늘어난다. 이에 간편하게 자식 요소를 >로 설정할 수 있음.

<ul class="main">
	<li>
    	<ul class="sub">
        	<li></li>
            <li></li>
        </ul>
    </li>
</ul>

.main > li {} ==> main 클래스의 자식 li만 접근
.sub > li {} ==> sub클래스의 자식 li만 접근

 

3) 형제 콤비네이터

- 형제 콤비네이터 : 특정한 요소의 형제이기만 하면 된다. 

- 인접 형제 콤비네이터 : 특정한 요소의 형제인데, 해당 요소에 바로 붙어있는 형제 요소.

- 어떤 때 가장 많이 쓰일까 ? <li> 같은 열거형 아이템에서 많이 쓰인다. 

- 중요한 것 : 첫째는 형제를 가질 수 없다. 두 번째 놈부터 형제를 인식한다. 

<article>
  <h1>제목</h1>
  <p>설명</p>
  <h2>제목 2</h2>
  <p>설명</p>
</article>
<ul>
  <li>리스트 아이템</li>
  <li>리스트 아이템</li>
  <li>리스트 아이템</li>
  <li>리스트 아이템</li>
</ul>

h1 ~ p {} : h1과 형제인 모든 p에 접근
h1 + p {} : h1과 형제이면서, 바로 인접한 아래 p만 접근 
/* li 요소에 바로 붙어있는 형제 요소인 Li 요소에게만 스타일 */
li + li { border-top: 1px solid #eee }

 

중요: 콤비네이터는 부모를 모른다! 자손/자식/형제로만 접근 가능.

 

4. 셀렉터 + 콤비네이터 조합

div.box{} 
.box.area ==> box와 area 클래스를 모두 가진 요소에 접근
.button.on
.button.off 요런 식으로

CSS 선택자/콤비네이션 중첩이 너무 길어지면 복잡도가 증가하고 관리할 게 많아지므로, 4중첩을 넘기지 않도록 한다. 4중첩이 넘어갈 수밖에 없으면 구조를 바꾸는 것도 고려해봄직 하다. 

.box > div > h1 + p{}
.box ~ .box > h1 {}

 

5. 가상셀렉터

- 가상 : (psuedo, 의사) 

- 코드상으로 개념적으로 존재하는 것들, 가상

- 요소로 완전히 존재하지는 않는데, 개념적으로는 존재.

- selector, combinator는 특정 html 요소를 지정해서 설정했는데, 가상셀렉터는 딱 html 요소를 찍을 수는 없음. 그러나 특정한 상태를 지칭함.

- 예시 : 요소에 마우스를 올린 상태 등이 

- 형식 : : 또는 :: ex) a:hover{}

a:hover {} ==> 마우스를 올린 상태. 
a:active {} ==> a요소를 클릭하면 활성화된다
a:visited {} ==> 특정 링크를 이미 사용한 상태. 이미 방문한 사이트
a:focus {} ==> 특정 요소에 포커스된 상태 

사용예시
a:hover ~ div {} ==> a에 마우스를 올리면 a의 형제 div가 주르륵 펼쳐진다든가, 이런 스타일이 가능

2) 가상요소

- 형식 : ::(콜론 2개)

- 언제 사용? 어떤 스타일을 넣기 위해서 요소를 추가해야하는 데, 이 요소가 의미론적으로는 필요는 없는데... 스타일을 위해 넣어야 할 때. ex 아이콘
- 가상 요소를 사용하면, HTML이 존재하는 것처럼 가상으로 요소를 추가

- 가상요소는 솔직히 잘 모르겠어서 실습하면서 공부하는 게 나을 거 같다. 

<div>
  <!-- ::before -->
  <span class="text">텍스트</span>
  <!-- ::after -->
</div>
/* ::before, ::after */
/* 가상 요소 셀렉터는 모두 :: 를 사용 */
/* content 속성이 필수값 */
/* 별도로 display 속성을 지정하지 않았다면, text로 취급 */
/* 복사 할 때 가상 요소 콘텐츠는 복사 범위 X */
/* 스타일적으로는 필요하나, 의미론적으로는 필요 없을 때 */
div {}
div::before { content: '' } /* div 요소의 앞편 */
div::after { content: '' } /* div 요소의 뒤편 */
input::placeholder {}

 

6. 캐스케이딩

<!-- Blue -->
<div class="box area">무슨 색이게?</div> == > 파란색 나옴
.box {
  color: red;
}

.area {
  color: blue;
}

- 스타일이 중복되거나, 여러 스타일을 한 요소에 적용했을 때 어떤 걸 적용할지 기준이 있음.

기준 1. 같은 스타일이라면, 뒤에 있는 게 적용. 같은 color가 적용됐으면 뒤에 있는 넘으로. 

  • 폭포
    • 스타일이 어느 위치에 존재하는 지 (같은 특정성이라면 뒤쪽에 존재하는 게 적용)
    • 특정성이 높은 순서대로 적용
      • 셀렉터 중 ID 셀렉터의 갯수를 셉니다 (= a)
      • 셀렉터 중 클래스 셀렉터, 속성 셀렉터, 가상 클래스의 갯수를 셉니다 (= b)
      • 셀렉터 중 요소 셀렉터와 가상 요소의 갯수를 셉니다 (= c)
      • 전역 셀렉터는 무시합니다.
      • { a b c }
    • !important 키워드 (안 쓰는 게 좋으니까 있는 것만 알아두세요)
#box { color: red } /* a = 1, 특정성: 100 */
.box { color: blue } /* b = 1, 특정성: 010 */
.area {} /* b = 1, 특정성: 010 */
.box .area {} /* b = 2, 특정성: 020 */
.box.area.container {} /* b = 3, 특정성: 030 */
div {} /* c = 1, 특정성: 001 */
div.box {} /* b = 1, c = 1, 특정성: 011 */
div[lang] {} /* 속성 셀렉터 */

 

7. 상속

- 부모에 적용된 스타일이 자손 요소까지 여향을 주는 경우

- 다른 요소들에 특별히 CSS로 font-size를 지정하지 않으면 body의 font-size를 기본값으로 가져가는 것과 가튼 개념. 부모에

- 컬러, 폰트, 타이포 같은 것들은 자손 요소에 영향을 준다. 

- 기본 폰트 같은 건 body에서 미리 설정해두는 게 나음. 하나만 설정해두면 알아서 바뀌게 때문임. 와일드카드도 부작용이 많아서, body에 선언해두는 게 나을 거임. 

- 단, input 같은 건 자체적인 스타일이 있으므로, 상속을 시키고 싶으면 아래와 같이 하면됨 

input, button {
  font-size: inherit;
  color: inherit;
}

 

8. 스타일 적용 방법

1) html 태그에 style 꽂아버리기

장점: 해당 요소에만 스타일 들어감. 우선순위 높음

단점 : 그외 모두. 

<div style="color:red"></div>

 

2) <style> 요소를 사용해 페이지별로 스타일 주기

- 특징 : 리액트 같은 데서 많이 쓰임. Styled Component

- 장점 : 페이지별로 필요한 스타일 지정, 자바스크립트로 제어 수월

- 단점 : 공통스타일 관리 어려움. 모든 페이지에서 사용하는 스타일 같은 거.

<head>
	<style>
    	.box {}
        .area {}
    </style>
</head>

 

3) css 파일을 만들어 <link>로 연결

- 장점 : 공통 스타일 관리 쉬움

- 단점: 외부에 파일이 있어서 HTTP 요청이 한 번 발생, CSS 이해가 낮은 상황에서 공통 스타일을 만들면 지옥도 펼쳐짐. 근데 얘만의 단점은 아니고 모든 상황에서 그렇긴 함.. 

<head>
	<link rel="styleSheet" href="style.css"/>
</head>

- 실무에서는 3번, 리액트에서는 2번을 가장 많이 쓸 듯.