개발 공부 기록하기

Section 7. CSS 선택자의 세계(3) 본문

프밍/CSS

Section 7. CSS 선택자의 세계(3)

태영(泰伶) 2023. 1. 4. 23:52

11. 가상 요소

앞에서 학습한 가상 클래스와 용어가 헷갈릴 수는 있다.

가상 요소 또한 '~에 한하여'와 같이 스타일을 적용하는 데 제한을 거는 방식이기 때문이다.

 

하지만 가상 요소는 선택된 요소에서도 특정 부분만을 선택하기 때문에

가상 클래스와는 엄연히 다른 개념이다.

 

MDN 홈페이지에서 가상 요소로 쓰일 수 있는 목록들이 나타나 있는데,

그 목록 중에서도 플라스크 아이콘이 뒤에 붙어있는 것들이 있었다.

(시험용을 뜻한다. 일종의 베타 테스트 중인 가상 요소이니 실제 개발 코드로 아직 사용하지 말라는 뜻이라고 한다.)

▼ MDN에 나열된 가상 요소 목록 (취소선 그어진 것이 시험용)
::after ::cue-region ::grammar-error ::selection
::backdrop ::first-letter ::marker ::slotted()
::before ::first-line ::part() ::spelling-error
::cue ::file-selector-button ::placeholder ::target-text

보통은 2개의 colon(:)을 붙이는데 하나만 쓰더라도 대부분의 브라우저들이 이를 유추해낸다고 한다ㅎㅎ

(그래도 신경 쓰지 않기에는 좀...^^;;;)

 

::first-letter

특정 선택에서 첫 글자를 선택하는 가상요소이다.

모든 단락 <p> 또는 모든 <span>과 같은 데에서 첫 글자에 스타일을 지정하는 데 사용된다.

<p>오늘은 2023년 첫번째 월요일!</p>
p::first-letter {
  font-size: 200%;
  color: red;
  font-weight: bold;
}

코드 쓸 때 상용구는 생략해 버렸다...ㅎㅎ 실제로 웹 페이지 만들 거 아니니까!

 

 

 

::first-line

특정 선택에서 첫 줄을 선택하는 가상요소이다.

<p>자취를 하면 뭐가 좋고 뭐가 안 좋을까?? 정말 나가고 싶다는 일념 하나만으로 내가 나가서 과연 후회하지 않을 수 있을까? 걱정이 되는 마음에 한 번 정리해 봤다. 부모님이 말로만 허락이라 해놓고 자꾸 주저앉히려는데 그걸 어떻게 논리적으로 납득시킬 수 있을 것이냐!가 요즘 내 머릿속을 완전히 지배하고 있다. 에휴... 공부는 언제 할 거니....</p>
<fieldset>
   <legend>자취의 좋은 점!</legend>
      <ul>
         <li>정말 자유롭다</li>
         <li>독립심을 기를 수 있다.</li>
         <li>개인 시간과 개인 공간이 생긴다.</li>
         <li>가족들의 시선과 방해를 받지 않고 다양한 일을 할 수 있다.</li>
         <li>가족들과 부딪칠 일이 줄어들고 사이가 돈독해진다.</li>
         <li>친구들을 초대해서 음식 대접을 할 수 있다.</li>
         <li>인테리어 하는 재미를 알 수 있다.</li>
         <li>내가 다 해야 해서 부지런해질 수 있다.</li>
      </ul>
</fieldset>
<br/>
<fieldset>
   <legend>자취의 나쁜 점!</legend>
      <ul>
         <li>집안일은 그냥 되는 게 아니다.</li>
         <li>모든 문제를 내 스스로 해결해야 한다.</li>
         <li>공과금, 관리비, 거주비가 든다.</li>
         <li>정말 다 돈이다.</li>
         <li>매일 뭘 먹어야 하는지 고민의 딜레마에 빠진다.</li>
         <li>귀차니즘이 폭발할 수 있다.</li>
         <li>혼자서 아프기라도 하면 엄청 서럽다.</li>
      </ul>
</fieldset>
* {
  word-break: keep-all;
}
fieldset {
  width: 500px;
}
fieldset:first-of-type legend {
  font-weight: bolder;
  color: #06f;
  font-size: 25px;
}
fieldset:last-of-type legend {
  font-weight: bolder;
  color: #f60;
  font-size: 25px;
}
li {
  list-style: circle;
}
p::first-line {
  color: #1232ff;
}

정말 예시를 위한 예시;;;

 

 

 

::selection

웹 문서에서 강조 표시를 하는 부분에 스타일이 적용되는 가상 요소이다.

문서의 특정 부분뿐만 아니라 선택한 요소의 일부여도 문제없다.

 

그냥, 다 떠나서 웹 문서에 있는 것을 드래그해서 블록 씌우면 나타나는 스타일이다! 

<p class="title">10cm-그라데이션</p>
<p>
밤은 다시 길고 깊어졌네<br/>나는 점점 너로 잠 못 들게 돼<br/>글로 적어내긴 어려운 이 기분을<br/>너도 느꼈으면 좋겠는데<br/><br/>
너는 아무 생각 없이 몇 번<br/>나를 지나가며 웃은 거라지만<br/>나의 하얀 옷에 너의 잉크가 묻어<br/>닦아낼 수 없을 만큼 번졌네<br/><br/>
달콤한 색감이 물들어 조금씩<br/>정신을 차렸을 땐 알아볼 수도 없지<br/>가득 찬 마음이 여물다 못해 터지고 있어<br/>내일은 말을 걸어봐야지<br/><br/>
요즘 노랜 뭔가 맘에 안 들어<br/>네게 불러주기엔 좀 어려워서<br/>나름 며칠 밤을 새워 연습했지만<br/>네게 들려주기엔 무리인 것 같아<br/><br/>
너는 번질수록 진해져 가고<br/>나의 밤은 좀 더 길고 외롭지만<br/>하루종일 떠오르는 너의 얼굴은<br/>방을 가득 채워 무지개 같이<br/><br/>
달콤한 색감이 물들어 조금씩<br/>정신을 차렸을 땐 알아볼 수도 없지<br/>가득 찬 마음이 여물다 못해 터지고 있어<br/>내일은 말을 걸어봐야지<br/><br/>
바람을 맞고 빗물에 젖어<br/>나의 색감도 흐려지겠지만<br/>너는 항상 빛에 반짝일 테니까<br/><br/>
멋진 말들을 전하지 못하고<br/>아무도 관심 없는 그림이 되겠지만<br/>달콤한 색감은 감추지 못해 터지고 있어<br/>내일은 말을 걸어봐야지<br/><br/>
그냥 이 노래가 어떨까 싶어
</p>
* {
  text-align: center;
}
.title {
  font-size: 120%;
  font-weight: bold;
}
p:last-of-type::selection {
  background-color: #fcbf49;
}

드래그해서 블럭 씌운 부분이 주황색으로 바뀐 상태로 캡처했다.

 

 

 

 

12. 계단식 CSS

CSS = Cascading StyleSheet

즉, 적용된 스타일의 순서가 중요하다는 의미!

 

지정한 각각의 스타일을 맞닥뜨리는 순서가 브라우저에 표시되는 스타일에 반영된다는 뜻이다.

h1 {
   color: red;
}
h1 {
   color: purple;
}
h1 {
   color: olivedrab;
}

이렇게 h1에 글자색을 적용하도록 하는 곳이 세 군데가 있으면 나중에 쓰인 스타일이 그 앞의 것을 덮어쓰게 되어 있다.

 

거기에 더해서,

<!DOCTYPE html>
   <html>
      <head>
         <link rel="stylesheet" href="file1.css">
         <link rel="stylesheet" href="file2.css">
      </head>
   </html>

위처럼 <link>로 연결한 별도의 CSS 파일에 위의 h1 스타일 적용하는 두 파일의 순서에 따라서

file1.css의 스타일이 적용된 데에 file2.css의 스타일이 덮어씌워진다.

 

 

 

 

 

13. 빌어먹을 우선순위

빌어먹을...ㅋㅋㅋㅋ 아니 정말로 강의 원제목에 WTF가 적혀있었다.. 나름 순화해서 해석해보려고 애썼다🤣

앞에서 학습한 것처럼 정확히 같은 선택자에 여러 스타일이 적용되어

그 순서대로 나중에 나온 것이 먼저 나온 것을 덮어쓰는 경우가 아니라

 

그런데 선택자가 다른 경우라면, 스타일 간에 충돌이 발생하게 되면, 어떻게 스타일이 적용될까?

 ⟹ 우선순위 specificity (= 명시도, 특이도 ...)

 

하나 이상의 스타일이 동일한 요소에 적용되거나 적용될 수 있는 경우 충돌이 발생한다.

 

.post button:hover {
   background-color: #e63946;
   color: #f1faee;
}
button:hover {
   background-color: olive;
   font-size: 10px;
}

만약 '버튼에 배경색을 적용하라'는 똑같은 지시가 위처럼 2가지가 함께 쓰였을 때,

브라우저는 주어진 선택자가 얼마나 구체적인지를 측정하고, 더 구체적인 선택자를 우선적으로 적용한다.

(브라우저는 위의 두 예시 중에서 위의 것을 더 구체적인 것으로 간주한다.)

 

어떤 선택자의 힘이 더 센지, 어느 것이 더 우선적이고 구체적이라고 간주하냐면

일반적으로

ID 선택자 > class 선택자 > 요소 선택자

 

부등호가 큰 쪽을 더 구체적인 것으로 간주한다.

 

0   0   0
ID 선택자   class 선택자, 속성 선택자, 가상 클래스 선택자   요소 선택자, 가상 요소 선택자

각 위치가 100의 자리, 10의 자리, 1의 자리로 인지하고,

스타일을 작성했을 때, 그 구체적인 정도, 즉, 그 스타일의 우선순위 파워(?)가 그만큼 세다고 이해하면 된다.

 

예를 들어,

section p {
   color: teal;
}

이 경우에는 요소 선택자가 2개 쓰였으니 우선순위의 파워(?)는 002, 즉 2이다.

 

그런데,

#submit {
   color: olive;
}

이 경우에는 ID 선택자가 1개 쓰였으니 우선순위의 파워(?)는 100이다.

(그러니까 위에서 파워가 2인 경우보다 50배 파워가 센 셈이다ㅎㅎ)

 

이를 응용한다면,

nav a.active {
   color: orange;
}

이 경우는 각 자리가 0 1 2로, 파워가 12쯤 되는 것이다.

 

실제로 2배, 10배, 50배만큼 파워가 세다고 이야기하기보다는, 숫자가 클수록 우선적으로 스타일이 적용된다고, 그 정도로만 이해하는 것이 좋다. 보편적인 10진법이 아니라는 뜻이다.

(10개 class 선택자 ≠ 1개 ID 선택자)

 

요소 선택자가 수십 개 있대도 class 선택자 1개 있는 게 우선순위가 높다.

 

 

우선순위를 계산해주는 사이트도 강사님이 소개해주었다. 영어 사이트지만...ㅎㅎ

https://specificity.keegan.st/

 

Specificity Calculator

Specificity Calculator A visual way to understand CSS specificity. Change the selectors or paste in your own.

specificity.keegan.st

 

 

 

 

 

14. 퀴즈 2: 우선순위 퀴즈

Q1.

<ul>
   <li class="nav-link">Home</li>
</ul>

위의 HTML 마크업에 적용된 스타일이

li {
   color: orange;
}
.nav-link {
   color: magenta;
}
ul li {
   color: blue;
}

라고 한다면 Home 글씨의 색상은 어떻게 나타날까?

 

A1.

자홍색

 

 

 

Q2.

<p>
   <button id="submit" class="btn">Submit</button>
</p>

위의 HTML 마크업에 적용된 스타일이

#submit {
   color: blue;
}
.btn {
   color: pink;
}
p button.btn {
   color: purple;
}

라고 한다면 버튼의 색상은 어떻게 나타날까?

 

A2.

파란색

 

 

 

Q3.

<section class="about">
   <h2 class="heading">Welcome To My Page</h2>
</section>

위의 HTML 마크업에 적용된 스타일이

.about .heading {
   color: orange;
}
.about h2.heading {
   color: pink;
}
section.about .heading {
   color: yellow;
}

라고 한다면 h2의 색상은 어떻게 나타날까?

 

A3.

노란색

(왜냐하면 CSS 스타일의 두 번째, 세 번째의 우선순위가 같지만, 세 번째 것이 아래에 쓰여서 두 번째 스타일을 덮어쓰기 때문이다..!!!)

 

 

 

 

 

15. 팁: Chrome 개발자 도구와 CSS

웹 사이트의 아무 요소를 오른쪽 마우스로 클릭해서 '검사'를 선택하면 개발자 도구를 열 수 있다.

 

개발자 도구를 열면 보이는 화면에

위의 사진에서의 빨간색 네모 부분에서

CSS 스타일을 어떻게 작성했는지 볼 수 있다.

 

빨간색 네모 안의 중간 부분에 취소선으로 적힌 스타일은

적용될 뻔했지만, 앞서 학습한 '우선순위' 또는 순서 경쟁에서 밀려서 탈락했다는 의미이다.    (= 이건 적용 안 됨)

 

우선순위 또는 순서 경쟁에서 이긴 요소를 클릭하면, 그 스타일이 적용되지 않은 모습을 화면에서 볼 수 있는데,

이건 html을 영구적으로 변화시킨 것이 아니고, 일시적이기 때문에 새로고침 하면 원래의 우선순위대로 스타일이 돌아온다.

뿐만 아니라, html 파일에는 추가하지 않았던 다른 스타일을 적어보고 그 효과를 화면에서 바로 볼 수도 있다.

(그걸 *토글 하면서 적용할 때와 아닐 때의 효과도 극명하게(?) 확인할 수도 있다.)

* 토글(toggle): 디지털 신호가 1 또는 0을 반복적으로 되풀이하는 상태. 즉, 여기서는 껐다 켰다 반복을 의미한다.

 

중간 아래쯤에 :hov를 클릭해 Force element state의 :hover에 체크하게 되면 :hover를 적어 넣은 요소의 상태가 어떤지도 확인할 수 있다.

 

 

 

 

 

16. 인라인 스타일과 중요도

앞에서 다루었던 우선순위를 능가하는 것이 두 가지 더 있다.

 

바로

① 인라인 스타일

② !important

이다.

 

이 둘은 ID 선택자, class 선택자 요소보다 훨씬 더 우선적으로 적용된다.

 

인라인 스타일

별도의 CSS 파일로, 또는 html 파일의 <head> 안에 <style>로 작성하는 방식이 아닌,

요소에 직접적으로 스타일을 적용하는 방식을 말한다.

 

사용하도록 추천하는 사람도, 사용하는 사람도  실제로 거의 없을 거라고 강사님은 이야기하셨는데,

많이 쓰는 사람 여기 있다...ㅎㅎ

 

지금 이 포스팅을 HTML 모드로 켠 화면의 일부이다. 직접 <tr>과 <td>에 style이라는 속성을 사용해서 스타일을 지정해주었다.

 

티스토리 포스팅에서 직접적으로 요소마다 스타일을 적용하는 방식을 차용하는 것 같아서, 나도 포스팅에서 스타일을 쓰고 싶을 땐 이렇게 작성하고 있다.

(별도로 스타일시트 만드는 방법을 모르겠다..)

 

사실 요소마다 다 써주어야 해서 매우 귀찮은 방법이다.

그런 번거로운 점 때문에 강사님이 아마 쓰는 사람은 거의 없을 거라고 한 것 같다. 

 

강사님이 설명한, 인라인 스타일을 되도록 쓰지 말라는 이유는,

별도의 CSS 파일(스타일 시트) 또는  html 파일 내의 <style>에 적혀있지 않고, 이들과 분리되어 있기 때문에.

인라인 스타일을 어딘가 설정했다는 사실을 알아채지 못할 수도 있어 혼란을 줄 수 있기 때문이었다.

 

 

 

!important

개별 스타일 지정에 사용할 수 있는 선택자로, 이 또한 되도록 안 쓰는 게 좋다.

그렇지만 가끔, 아주 가끔 효과적일 때도 있다.

 

.foo[style*="color: red"] {
   color: firebrick !important;
}

위와 같이 속성 뒤에 입력하여 사용한다.

 

!important가 쓰였다면 다른 어떤 지시보다 우선시하게 된다.

 

다른 사람이 써 놓은 스타일, 즉 반드시 통제할 필요가 없는 외부 라이브러리나, 도구를 다룰 때,

무언가를 바꾸거나 덮어쓰고 싶을 때 !important를 쓸 수 있다.

 

 

 

 

 

17. CSS 상속

CSS 상속: 구체적인 특성을 지정하지 않은 하위 요소에 상위 항목 특성이 적용되는 것.

 

<!DOCTYPE html>
<html>
   <head>
   </head>
   <body>
      <h1>큰 제목</h1>
      <section>
         <h2>작은 제목1</h2>
         <p>blah blah blah</p>
         <p>blah blah blah</p>
      </section>
      <section>
         <h2>작은 제목 2</h2>
         <p>blah blah blah</p>
         <p>blah blah blah</p>
      </section>
   </body>
</html>

위의 코드에

다음 같은 스타일 시트가 연결된다면

body {
   color: purple;
}
h1 {
   color: blue;
}

작은 제목 2개를 포함한 내용 부분에는 직접적으로 스타일을 지정하지도 않았는데, body에 지정한 스타일이 그대로 상속되어 나타남을 확인할 수 있다.

 

그 와중에 h1의 스타일은 콕 집어서 파란색 글씨로 하라고 지정해 주었으니, 상속을 받지 않고, 지정한 스타일이 나타나는 것이다.

 

 

만약 스타일 시트를 다음과 같이 고친다면,

body {
   color: purple;
}
section {
   color: aqua;
}

body의 하위 항목들인 h1, h2, section, p 모두 보라색 글씨로 되어야 맞는데,

그보다 하위항목인 section을 아쿠아색으로 지정하는 바람에

section에 묶이지 않은 h1만 보라색으로 남게 되고, 나머지 요소들은 모두 아쿠아색으로 변하게 됨을 알 수 있다.

 

하지만 그렇다고 해서 모든 스타일이 하위항목에 반드시 상속되는 것은 또 아니다.

 

 

button, input 등은 자동 상속이 되지 않도록 기본적으로 설정이 되어 있다.

 

그래서 상속을 원한다면,

button, input {
   color: inherit;
}

이렇게 써 줘야만 상위 항목의 스타일을 상속받을 수 있다.

 

 

 

스타일을 상속을 받을 수 있는지 여부도 MDN 홈페이지에서 확인할 수 있다.

 

border는 상속이 안 된다.

 

color는 상속이 된다.

Comments