한 줄 요약 — CSS를 페이지에 끼우는 방법은 세 가지 — <link>로 불러오는 외부 스타일시트, <style> 태그 안에 적는 내부 스타일시트, 태그에 직접 적는 style 속성 — 입니다. 세 방식이 같은 자리에서 부딪치면 가장 가까이 입은 옷, 즉 인라인이 이깁니다. 보통은 외부 스타일시트를 기본으로 두고 나머지 둘은 특별한 경우에만 씁니다.

학습 목표

  • CSS가 무엇이며 HTML과 어떻게 역할이 나뉘는지 한 줄로 설명할 수 있다.
  • <link rel="stylesheet">, <style> 태그, style 속성의 세 가지 적용 방식을 구분해 쓸 수 있다.
  • 세 방식이 같은 자리에서 충돌할 때 누가 이기는지 짐작할 수 있다.
  • 평소에는 외부 스타일시트를 기본으로 두고, 나머지 둘은 특별한 경우에만 쓰는 이유를 안다.

오늘의 비유 — 옷장의 옷, 오늘만 입을 옷, 그 자리에서 덧 걸치는 옷

오늘 입을 옷을 정하는 방법은 크게 세 가지입니다. 첫째, 옷장에서 평소 자리에 정리해 둔 옷을 꺼내 입습니다. 한번 잘 정리해 두면 다른 날에도 같은 옷장에서 골라 입을 수 있고, 한 사람만 그 옷장을 쓰는 것도 아니라 가족 여럿이 두루 씁니다. 둘째, 그날 아침에 침대 위에 꺼내 둔 옷을 입습니다. 그 하루치에만 미리 골라 놓은 묶음이라 그 방을 벗어나면 다른 사람은 못 씁니다. 셋째, 이미 옷을 입고 나가다가 그 자리에서 카디건을 어깨에 덧 걸칩니다. 가장 빠르지만 그 한 사람, 그 한 번에만 적용됩니다.

CSS도 그대로입니다. 외부 스타일시트(.css 파일)는 옷장입니다. 한번 정리해 두면 여러 페이지가 같은 옷장에서 꺼내 씁니다. 내부 스타일시트(<style> 태그 안의 규칙)는 침대 위에 꺼내 둔 오늘의 옷입니다. 그 페이지 안에서만 통합니다. 인라인 스타일(태그의 style 속성)은 카디건을 그 자리에서 덧 걸치는 일입니다. 그 한 태그에만 효과가 있습니다. 세 방식이 같은 자리에서 부딪치면, 가장 가까이 입은 옷이 이깁니다.

CSS는 Cascading Style Sheets의 약자로, "계단식으로 흘러내리듯 적용되는 스타일 묶음" 정도의 뜻입니다. 같은 자리에 여러 옷이 겹치면 위에서 아래로, 또 가까운 쪽이 먼 쪽을 가린다는 발상이 이름에 그대로 들어 있습니다.

핵심 개념

지금까지 우리는 HTML로 자료의 의미만 적어 왔습니다. <h1>이면 큰 제목, <p>면 한 문단, <table>이면 표 — 이런 "이건 무엇이다"를 정한 셈입니다. CSS는 그 자료에 색·글자 크기·줄 간격·칸 위치 같은 꾸밈을 입힙니다. HTML이 "이건 표다"라고 알려 주면, CSS가 "그 표의 머리글은 진하게, 본문 행은 한 줄 걸러 연한 회색"이라고 옷을 입혀 주는 식입니다.

CSS 규칙 하나는 늘 같은 모양입니다.

선택자 {
  속성: 값;
}

선택자는 어떤 태그를 꾸밀지 가리키는 이름이고, 중괄호 안에는 그 태그에 입힐 속성과 값을 짝지어 적습니다. 이 규칙을 페이지에 끼우는 방법이 오늘 정리할 세 가지입니다.

외부 스타일시트 — <link>로 불러오는 옷장

가장 흔히 쓰는 방식입니다. CSS 규칙을 별도 파일(style.css 같은 이름)에 모아 두고, HTML의 <head> 안에서 <link> 태그로 불러옵니다.

<!-- index.html -->
<head>
  <meta charset="UTF-8">
  <title>CSS 첫걸음</title>
  <link rel="stylesheet" href="style.css">
</head>
/* style.css */
h1 {
  color: tomato;
}

rel="stylesheet"은 "지금 가져오는 이 파일이 스타일시트입니다"라고 브라우저에게 알려 주는 표시입니다. href는 어디서 그 파일을 가져올지 — 위 예시는 같은 폴더의 style.css입니다. 이 한 줄을 여러 페이지의 <head>에 똑같이 두면 모든 페이지가 같은 옷장에서 옷을 꺼내 입게 됩니다. <h1>의 색을 바꾸고 싶을 때 style.css 한 곳만 고치면 모든 페이지의 <h1> 색이 한꺼번에 바뀝니다.

내부 스타일시트 — <style> 태그에 직접 적기

CSS를 외부 파일이 아니라 HTML 안에 바로 적는 방식입니다. <head> 안에 <style> 태그를 두고 그 안에 규칙을 적습니다.

<head>
  <meta charset="UTF-8">
  <title>CSS 첫걸음</title>
  <style>
    h1 {
      color: royalblue;
    }
  </style>
</head>

규칙 자체는 외부 스타일시트와 똑같지만, 다른 페이지는 이 규칙을 못 씁니다. 이 페이지만 입는 오늘의 옷인 셈입니다. 한 페이지 안에서만 잠깐 시험해 볼 때나, 그 페이지에만 적용할 짧은 스타일이 있을 때 씁니다.

인라인 스타일 — 태그에 style 속성을 바로 적기

옷을 그 자리에서 덧 걸치는 방식입니다. HTML 태그에 style 속성을 두고, 그 안에 속성: 값; 짝을 바로 적습니다.

<h1 style="color: seagreen;">CSS 첫걸음</h1>

선택자가 없는 이유는 분명합니다 — 이 style은 자기가 붙어 있는 그 태그 하나에만 적용되니까 가리킬 대상이 따로 없습니다. 가장 빠르지만 그 한 태그에만 효과가 있어서, 같은 모양을 여러 자리에 입히고 싶다면 자리마다 똑같은 옷을 매번 덧 걸쳐야 합니다.

셋이 부딪치면 누가 이기는가

같은 <h1>color를 세 곳에서 다르게 지정하면, 화면에 보이는 색은 단 하나뿐입니다. 우선순위는 다음 순서로 정해집니다.

  1. 인라인 (style="...") — 그 자리에서 덧 걸친 옷이라 가장 가깝습니다. 우선순위가 가장 높습니다.
  2. 내부 스타일시트외부 스타일시트 — 둘은 같은 무게입니다. 어느 쪽이 이기는지는 "더 구체적인 선택자"와 "더 나중에 적힌 규칙" 같은 기준으로 정해집니다. 같은 선택자라면 나중에 적힌 쪽이 이깁니다.

이 우선순위 자체가 곧 만나는 회차의 큰 주제(명시도와 캐스케이드)입니다. 오늘은 "인라인은 가장 가까이 입은 옷이라 거의 항상 이긴다" 정도로 기억해 두면 충분합니다.

함께 따라하기 — 세 방식이 한 페이지에서 부딪치는 모습

day-12 폴더를 만들고 그 안에 index.htmlstyle.css 두 파일을 둡니다.

/* style.css */
h1 {
  color: tomato;
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>CSS 첫걸음</title>
    <link rel="stylesheet" href="style.css">
    <style>
      h1 {
        color: royalblue;
      }
    </style>
  </head>
  <body>
    <h1>이 제목은 무슨 색일까</h1>
    <h1 style="color: seagreen;">이 제목은 어떨까</h1>
  </body>
</html>

저장하고 브라우저로 열어보면 첫 줄 제목은 파란색(royalblue), 둘째 줄 제목은 초록색(seagreen)으로 보입니다. 첫 줄에는 옷장(외부)과 침대 위(내부) 두 옷이 같이 걸려 있는데, 내부 스타일시트가 외부보다 <head> 안에서 더 나중에 적혔기 때문에 파란색이 이겼습니다. 둘째 줄은 거기다 인라인까지 덧 걸친 셈이라 가장 가까이 입은 초록색이 이깁니다. 토마토 색은 어느 줄에도 보이지 않습니다 — 같은 자리에서 다른 옷에 가려진 탓입니다.

내부 스타일시트의 royalblue를 지워 보면 첫 줄이 토마토 색으로 바뀝니다. 외부 스타일시트가 그제야 모습을 드러낸 셈이죠. 인라인 style="color: seagreen;"만 지우면 둘째 줄이 파란색으로 바뀝니다. 한 줄씩 지우면서 누가 누구를 가리고 있었는지 직접 확인해 봅니다.

흔한 실수 3가지

1. style 속성을 남발해 유지보수 지옥에 빠진다

처음 CSS를 배우면 인라인이 가장 빠르고 직관적이라 손이 자꾸 그쪽으로 갑니다. 한 태그에 한 줄만 적으면 바로 색이 바뀌니까요.

<h2 style="color: navy; font-size: 22px; margin-top: 24px;">소개</h2>
<h2 style="color: navy; font-size: 22px; margin-top: 24px;">기능</h2>
<h2 style="color: navy; font-size: 22px; margin-top: 24px;">가격</h2>

(이 코드는 동작은 합니다만 같은 옷을 자리마다 매번 덧 걸쳐 두는 상태입니다.) 나중에 <h2>의 색이나 크기를 바꾸고 싶어지면 모든 자리를 손으로 다시 고쳐야 합니다. 자리가 30곳, 300곳이 되면 사실상 손댈 수 없는 코드가 됩니다. 그 한 태그에만 적용된다는 인라인의 장점이 여기서는 그대로 단점이 됩니다.

/* style.css */
h2 {
  color: navy;
  font-size: 22px;
  margin-top: 24px;
}
<h2>소개</h2>
<h2>기능</h2>
<h2>가격</h2>

같은 옷을 여러 자리에 입히려면 옷장(외부 스타일시트) 한 칸에 정리해 두는 편이 훨씬 다루기 쉽습니다. 나중에 색만 바꾸고 싶어지면 옷장의 그 옷 한 벌만 고치면 됩니다. 인라인은 "이 한 자리에만, 정말 잠깐"인 경우에만 씁니다.

2. link 태그의 rel 속성을 빼먹어 스타일이 안 먹는다

외부 스타일시트가 분명 옆 폴더에 있는데도 화면에 색이 하나도 안 적용되는 경우의 절반은 이 자리에서 생깁니다.

<link href="style.css">

(이 코드는 브라우저가 그 파일을 스타일시트로 받아들이지 않습니다.) <link> 태그는 스타일시트 말고도 아이콘이나 미리 가져올 폰트 등 여러 종류의 파일을 끌어올 때 두루 씁니다. 그래서 rel 속성으로 "이번에 가져오는 파일은 어떤 종류인가"를 따로 알려 줘야 합니다. rel="stylesheet"이 빠지면 브라우저는 그 파일을 어디에 쓸지 모른 채 그냥 무시합니다.

<link rel="stylesheet" href="style.css">

relhref 두 자리를 한 묶음으로 외워 둡니다. 한쪽이라도 빠지면 옷장에 옷이 있어도 꺼내 입지 못한다고 생각하면 잘 잊지 않습니다.

3. script 태그처럼 link도 body 끝에 둔다

자바스크립트의 <script> 태그는 본문 끝(</body> 바로 위)에 두는 게 보통이라, 그 버릇대로 <link>도 본문 끝에 두는 경우입니다.

<body>
  <h1>오늘의 가격표</h1>
  <table></table>
  <link rel="stylesheet" href="style.css">
</body>

(이 코드는 동작은 합니다만 사용자가 잠깐 동안 스타일이 안 입혀진 페이지를 보게 됩니다.) 브라우저는 HTML을 위에서 아래로 읽으며 화면을 그립니다. <link>가 본문 끝에 있으면 그 위의 표·제목이 먼저 꾸밈 없이 그려졌다가, 마지막에 스타일시트가 도착해서야 색·간격이 바뀝니다. 화면이 한 번 깜빡이듯 모양이 바뀌는 현상이 이래서 생깁니다.

<head>
  <meta charset="UTF-8">
  <title>오늘의 가격표</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>오늘의 가격표</h1>
  <table></table>
</body>

<link rel="stylesheet"><head> 안에 둡니다. 본문보다 옷장을 먼저 열어 두어야, 본문이 화면에 그려질 때부터 이미 옷을 입은 상태로 보입니다. (자바스크립트의 <script>가 본문 끝에 가는 이유는 또 다른데, 그건 자바스크립트 시리즈에서 따로 다룹니다.)

오늘 배운 것 체크리스트

  • CSS가 HTML이 정한 의미에 색·크기·간격을 입히는 역할이라고 설명할 수 있다.
  • 외부·내부·인라인 세 방식을 골라 쓸 수 있다.
  • <link rel="stylesheet" href="...">의 두 속성을 빠뜨리지 않고 <head> 안에 둔다.
  • 같은 자리에서 셋이 부딪치면 인라인이 가장 강하다는 것을 안다.
  • 평소에는 외부 스타일시트를 기본으로 쓴다.

자주 묻는 질문

Q. <link rel="stylesheet">는 왜 <head> 안에 넣어야 하나요? <body> 끝에 두면 안 되나요?

A. 브라우저가 HTML을 위에서 아래로 읽으며 화면을 그리기 때문입니다. <link>가 본문 위에 있어야 본문이 그려지기 전에 옷장이 열리고, 처음부터 옷을 입은 상태로 화면에 나타납니다. <body> 안 끝에 두면 잠깐이지만 스타일이 안 먹은 화면이 먼저 보였다가 나중에 모양이 바뀌어 사용자가 어색하게 느낍니다.

Q. <style> 태그는 <head>가 아닌 <body> 안에 둬도 동작은 하나요?

A. 동작은 합니다만 표준은 <head> 안입니다. 본문 안에 두면 코드를 읽는 사람도 스타일 규칙이 어디 있는지 찾기 어렵고, 브라우저도 본문을 그리다가 새 규칙을 만나면 앞서 그린 부분을 다시 칠해야 할 수 있어 손해입니다. 외부 파일이든 내부 <style>이든 같은 자리(<head>)에 모아 둡니다.

Q. 그래서 셋 중 무엇을 써야 하나요?

A. 거의 항상 외부 스타일시트입니다. 한 곳에서 옷을 정리해 여러 페이지가 같이 꺼내 쓰기 좋고, 나중에 색 한 가지를 바꾸려 해도 한 자리만 고치면 끝납니다. 내부 <style>은 그 페이지 단 하나에만 적용할 짧은 시험 코드일 때, 인라인은 자바스크립트가 그 순간 한 자리의 모양을 바꿔야 할 때 정도로만 씁니다.

다음 시간 예고

내일은 CSS 선택자 기초 — 태그·클래스·ID를 다룹니다. 오늘은 h1 하나를 통째로 꾸미는 수준이었다면, 내일부터는 "어떤 h1만" 골라서 꾸미는 법을 배웁니다. 옷장 전체에 옷을 거는 것이 아니라, 표시해 둔 옷걸이에만 거는 셈입니다.

더 알아보기