CSS 기본 문법과 선택자
2장에서 우리는 HTML을 사용하여 웹 페이지의 뼈대와 콘텐츠를 구성하는 방법을 학습했습니다. 이제 여러분은 텍스트를 정리하고, 이미지를 삽입하며, 링크를 만들고, 폼을 통해 사용자 입력을 받는 기본적인 웹 페이지를 만들 수 있게 되었습니다. 하지만 HTML만으로는 웹 페이지가 다소 투박하고 정보가 나열된 문서처럼 보일 수 있습니다.
여기서 등장하는 것이 바로 CSS(Cascading Style Sheets) 입니다. CSS는 HTML 문서의 스타일(Style)과 레이아웃(Layout)을 정의하는 언어입니다. 웹 페이지의 색상, 글꼴, 크기, 배치, 여백 등 시각적인 모든 요소를 제어하여 사용자에게 매력적이고 직관적인 웹 경험을 제공하는 것이 CSS의 역할입니다.
이 장에서는 CSS의 가장 기본적인 문법 규칙을 배우고, HTML 문서 내의 특정 요소에 스타일을 적용하기 위한 핵심적인 개념인 선택자(Selector) 에 대해 깊이 있게 다룰 것입니다. CSS의 이 기본기를 탄탄하게 다져야 여러분이 원하는 디자인을 자유자재로 구현할 수 있게 됩니다.
CSS란 무엇인가? 웹 디자인의 핵심 언어
CSS는 HTML 요소들이 웹 브라우저에 어떻게 보일지를 설명하는 언어입니다. HTML이 집의 뼈대와 방의 구조를 만드는 것이라면, CSS는 벽지 색깔, 가구 배치, 창문의 모양과 같은 내부 장식을 담당한다고 생각할 수 있습니다.
CSS의 필요성
- HTML과 스타일의 분리: HTML은 콘텐츠의 구조와 의미를 담당하고, CSS는 시각적인 표현을 담당합니다. 이렇게 역할을 분리함으로써 HTML 코드는 더 간결해지고, CSS 코드는 디자인 변경에 유연하게 대응할 수 있습니다.
- 일관된 디자인 적용: 하나의 CSS 파일을 통해 여러 웹 페이지에 동일한 스타일을 적용할 수 있습니다. 웹사이트 전체의 디자인을 변경할 때도 CSS 파일 하나만 수정하면 되므로 유지보수가 매우 효율적입니다.
- 반응형 웹 디자인: CSS 미디어 쿼리(Media Query)를 사용하여 다양한 화면 크기(PC, 태블릿, 모바일)에 맞춰 웹 페이지의 레이아웃과 스타일을 다르게 적용할 수 있습니다.
- 접근성 및 SEO 향상: 올바른 CSS 사용은 웹 접근성을 높이는 데 기여하며, 구조와 스타일의 분리는 검색 엔진이 콘텐츠를 더 효율적으로 분석하는 데 도움이 됩니다.
CSS 기본 문법: 선언 블록과 속성-값 쌍
CSS는 매우 간단하고 직관적인 문법을 가지고 있습니다. CSS 규칙(rule)은 크게 선택자(Selector) 와 선언 블록(Declaration Block) 으로 구성됩니다.
선택자 {
속성(property): 값(value);
속성(property): 값(value);
/* ...더 많은 속성-값 쌍 */
}
- 선택자 (Selector): 스타일을 적용할 HTML 요소를 지정합니다. (예:
h1
,p
,.box
,#main-header
등) - 선언 블록 (Declaration Block): 중괄호
{}
안에 들어가는 부분으로, 선택된 요소에 적용할 스타일 규칙들을 포함합니다. - 속성 (Property): 변경하고 싶은 스타일의 종류를 나타냅니다. (예:
color
,font-size
,background-color
,margin
등) - 값 (Value): 해당 속성에 적용할 구체적인 값입니다. (예:
red
,16px
,#f0f0f0
,10px
등) - 세미콜론 (
;
): 각 속성-값 쌍의 끝에는 반드시 세미콜론을 붙여야 합니다. 마지막 속성-값 쌍에는 생략해도 오류는 아니지만, 일관성을 위해 붙이는 것이 좋은 습관입니다.
예시
h1 { /* h1 태그를 선택하여 스타일 적용 */
color: blue; /* 글자 색상을 파란색으로 */
font-size: 32px; /* 글자 크기를 32픽셀로 */
text-align: center; /* 텍스트를 가운데 정렬 */
}
p { /* p 태그를 선택하여 스타일 적용 */
line-height: 1.8; /* 줄 간격을 1.8배로 */
margin-bottom: 1em; /* 아래쪽 여백을 1em으로 */
}
CSS 적용 방법: HTML과 CSS 연결하기
CSS 스타일을 HTML 문서에 적용하는 방법은 크게 세 가지가 있습니다.
인라인 스타일 (Inline Style)
HTML 태그의 style
속성에 직접 CSS 코드를 작성하는 방식입니다.
- 장점: 특정 요소에만 즉시 스타일을 적용할 때 편리합니다.
- 단점: 코드 가독성이 떨어지고, 재사용이 불가능하며, 유지보수가 어렵습니다. 권장되지 않는 방법입니다.
<p style="color: red; font-size: 18px;">이 문단은 인라인 스타일이 적용됩니다.</p>
내부 스타일 시트 (Internal Style Sheet)
HTML 문서의 <head>
태그 안에 <style>
태그를 사용하여 CSS 코드를 작성하는 방식입니다.
- 장점: HTML 문서 하나에서 모든 스타일을 관리할 수 있어 간단한 페이지에 유용합니다.
- 단점: 여러 HTML 페이지에 동일한 스타일을 적용할 수 없으며, HTML 파일의 크기가 커집니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>내부 스타일 시트</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
h1 {
color: purple;
text-decoration: underline;
}
</style>
</head>
<body>
<h1>내부 스타일 시트 예시</h1>
<p>이것은 내부 스타일 시트가 적용된 문단입니다.</p>
</body>
</html>
외부 스타일 시트 (External Style Sheet)
별도의 .css
파일을 만들고, 이 파일을 HTML 문서에 연결하는 방식입니다. 대부분의 실제 웹 개발 프로젝트에서 사용되는 표준적인 방법입니다.
- 장점:
- HTML과 CSS 코드를 완벽하게 분리하여 가독성과 유지보수성이 매우 뛰어납니다.
- 하나의
.css
파일로 여러 HTML 페이지에 동일한 스타일을 적용할 수 있어 효율적입니다. - CSS 파일이 캐싱되어 웹 페이지 로딩 속도를 개선할 수 있습니다.
- 단점: HTML 파일과 CSS 파일 간의 링크가 깨지면 스타일이 적용되지 않습니다.
적용 방법:
-
CSS 파일 생성: HTML 파일과 같은 폴더 또는 하위 폴더(
css
폴더 등)에style.css
와 같은 이름으로 CSS 파일을 만듭니다.style.css
파일 내용:body { font-family: 'Malgun Gothic', sans-serif; background-color: #e6e6fa; } h1 { color: darkgreen; text-align: left; } p { font-size: 16px; }
-
HTML 파일에 연결: HTML 문서의
<head>
태그 안에<link>
태그를 사용하여 CSS 파일을 연결합니다.rel="stylesheet"
: 연결하는 문서가 스타일 시트임을 나타냅니다.href="경로/파일명.css"
: CSS 파일의 경로를 지정합니다.
index.html
파일 내용:<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>외부 스타일 시트</title> <link rel="stylesheet" href="style.css"> </head> <body> <h1>외부 스타일 시트 예시</h1> <p>이것은 외부 스타일 시트가 적용된 문단입니다.</p> <p>HTML과 CSS 파일이 분리되어 있어 깔끔합니다.</p> </body> </html>
CSS 선택자: 원하는 요소만 골라내기
선택자(Selector)는 CSS의 핵심 중 하나입니다. 수많은 HTML 요소 중에서 정확히 어떤 요소에 스타일을 적용할지 지정하는 역할을 합니다. 올바른 선택자 사용법을 익히는 것은 CSS를 효과적으로 다루는 데 필수적입니다.
기본 선택자
-
전체 선택자 (
*
)- 문서의 모든 HTML 요소에 스타일을 적용합니다.
- 초기화 스타일 등에 사용되지만, 성능 문제로 남용하지 않는 것이 좋습니다.
* { margin: 0; /* 모든 요소의 기본 마진 제거 */ padding: 0; /* 모든 요소의 기본 패딩 제거 */ }
-
태그 선택자 (Type Selector)
- 특정 HTML 태그 이름을 직접 사용하여 해당 태그의 모든 요소에 스타일을 적용합니다.
p { /* 모든 <p> 태그 */ color: #333; font-family: sans-serif; } h2 { /* 모든 <h2> 태그 */ border-bottom: 1px solid #ccc; }
-
클래스 선택자 (
.
) - 가장 많이 사용!- HTML 요소의
class
속성 값으로 요소를 선택합니다. 한 HTML 문서 내에서 여러 요소에 동일한 클래스를 적용할 수 있으며, 하나의 요소가 여러 클래스를 가질 수도 있습니다. .클래스명
형태로 사용합니다.
<h1 class="main-title">우리 회사</h1> <p class="section-text">회사 소개입니다.</p> <p class="section-text highlight">중요한 내용입니다.</p>
.main-title { /* class가 "main-title"인 요소 */ font-size: 40px; color: #2c3e50; } .section-text { /* class가 "section-text"인 요소들 */ line-height: 1.6; color: #555; } .highlight { /* class가 "highlight"인 요소들 */ background-color: yellow; }
- HTML 요소의
-
ID 선택자 (
#
)- HTML 요소의
id
속성 값으로 요소를 선택합니다.id
는 HTML 문서 내에서 유일해야 합니다. (하나의id
는 오직 하나의 요소에만 사용되어야 함) #ID명
형태로 사용합니다.- 특정 요소를 정확히 식별하여 스타일링할 때 유용합니다.
<div id="header"> <h1>환영합니다!</h1> </div> <div id="footer"> <p>저작권</p> </div>
#header { /* id가 "header"인 요소 */ background-color: #f8f8f8; padding: 20px; } #footer { /* id가 "footer"인 요소 */ text-align: center; font-size: 14px; color: #888; }
💡 ID vs. Class
id
: 문서 내에서 고유한 하나의 요소에 적용 (주로 JavaScript에서 특정 요소에 접근할 때 사용)class
: 여러 요소에 반복적으로 적용 가능 (주로 CSS 스타일링에 사용)
- HTML 요소의
복합 선택자
여러 선택자를 조합하여 더 구체적인 요소를 선택할 수 있습니다.
-
하위 선택자 (Descendant Selector) (공백)
- 부모 요소 안에 있는 모든 자손 요소(하위 요소)를 선택합니다.
부모선택자 자손선택자
형태로 사용합니다.
<div class="menu"> <ul> <li><a href="#">메뉴 1</a></li> <li><a href="#">메뉴 2</a></li> </ul> </div> <p>일반 문단</p>
.menu ul li a { /* class가 "menu"인 요소 내부의 ul 내부의 li 내부의 a 태그 */ text-decoration: none; /* 밑줄 제거 */ color: #4CAF50; /* 초록색 */ }
-
자식 선택자 (Child Selector) (
>
)- 부모 요소의 바로 아래에 있는 자식 요소만 선택합니다.
부모선택자 > 자식선택자
형태로 사용합니다.
<div class="container"> <p>자식 문단 1</p> <span> <p>손자 문단</p> </span> <p>자식 문단 2</p> </div>
.container > p { /* class가 "container"인 요소의 직계 자식인 <p> 태그만 */ border: 1px solid blue; } /* 위의 CSS는 "손자 문단"에는 적용되지 않습니다. */
-
인접 형제 선택자 (Adjacent Sibling Selector) (
+
)- 바로 다음에 오는 형제 요소(같은 부모를 가진 요소)를 선택합니다.
형제1선택자 + 형제2선택자
형태로 사용합니다.
<h1>제목</h1> <p>첫 번째 문단</p> <p>두 번째 문단</p> <div>다른 요소</div> <p>세 번째 문단</p>
h1 + p { /* <h1> 태그 바로 뒤에 오는 <p> 태그 */ font-weight: bold; color: red; } /* 이 스타일은 "첫 번째 문단"에만 적용됩니다. */
-
일반 형제 선택자 (General Sibling Selector) (
~
)- 다음에 오는 모든 형제 요소들을 선택합니다.
형제1선택자 ~ 형제2선택자
형태로 사용합니다.
h1 ~ p { /* <h1> 태그 다음에 오는 모든 <p> 태그들 */ font-style: italic; } /* 이 스타일은 "첫 번째 문단", "두 번째 문단", "세 번째 문단" 모두에 적용됩니다. */
속성 선택자
- 특정 속성을 가지거나 특정 속성 값을 가진 요소를 선택합니다.
[속성명]
: 해당 속성을 가진 모든 요소[속성명="값"]
: 해당 속성이 특정 값을 가진 요소[속성명^="값"]
: 해당 속성 값이 특정 문자열로 시작하는 요소[속성명$="값"]
: 해당 속성 값이 특정 문자열로 끝나는 요소[속성명*="값"]
: 해당 속성 값이 특정 문자열을 포함하는 요소
a[target="_blank"] { /* target="_blank" 속성을 가진 모든 <a> 태그 */ background-color: lightblue; } input[type="text"] { /* type="text" 속성을 가진 모든 <input> 태그 */ border: 1px solid gray; } img[alt*="로고"] { /* alt 속성 값에 "로고"가 포함된 모든 <img> 태그 */ border: 2px solid green; }
가상 클래스 선택자 (Pseudo-classes)
- 요소의 특정 상태나 위치에 따라 스타일을 적용할 때 사용합니다.
:
(콜론)을 사용하여 정의합니다.:hover
: 마우스 커서가 요소 위에 올라갔을 때:active
: 요소를 클릭하는 동안:focus
: 폼 입력 필드처럼 요소에 포커스가 있을 때:link
: 방문하지 않은 링크:visited
: 방문한 링크:first-child
: 부모의 첫 번째 자식 요소:last-child
: 부모의 마지막 자식 요소:nth-child(n)
: 부모의 n번째 자식 요소 (n은 숫자,odd
,even
사용 가능):not(selector)
: 지정된 선택자가 아닌 요소
a:hover { /* 링크에 마우스 올렸을 때 */ color: orange; text-decoration: underline; } input:focus { /* input 필드에 포커스 있을 때 */ border-color: blue; box-shadow: 0 0 5px rgba(0, 0, 255, 0.5); } li:first-child { /* 목록의 첫 번째 항목 */ font-weight: bold; } li:nth-child(even) { /* 목록의 짝수 번째 항목 */ background-color: #f2f2f2; } button:active { /* 버튼 클릭 시 */ transform: translateY(1px); /* 살짝 눌리는 효과 */ }
가상 요소 선택자 (Pseudo-elements)
- 요소의 특정 부분에 스타일을 적용할 때 사용합니다.
::
(이중 콜론)을 사용하여 정의합니다. (단일 콜론도 허용되지만, 구분을 위해 이중 콜론이 권장됩니다.)::before
: 요소의 콘텐츠 앞에 가상 콘텐츠를 생성::after
: 요소의 콘텐츠 뒤에 가상 콘텐츠를 생성::first-letter
: 텍스트의 첫 글자::first-line
: 텍스트의 첫 줄::selection
: 사용자가 텍스트를 드래그하여 선택했을 때
p::first-letter { /* <p> 태그의 첫 글자 */ font-size: 2em; color: #ff5733; float: left; /* 드롭캡 효과 */ line-height: 1; margin-right: 5px; } a::after { /* <a> 태그 콘텐츠 뒤에 화살표 아이콘 추가 */ content: " →"; font-size: 0.8em; vertical-align: super; }
실습: 외부 스타일 시트와 선택자 활용하기
지금까지 배운 CSS 기본 문법과 다양한 선택자들을 활용하여 간단한 HTML 페이지에 스타일을 적용해 봅시다.
-
프로젝트 폴더 구조
web-dev-practice/ ├── index.html └── css/ └── style.css
-
index.html
파일 작성index.html <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CSS 기본 문법과 선택자 실습</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <header id="main-header"> <h1 class="page-title">내 웹사이트</h1> <nav> <ul> <li class="menu-item"><a href="#">홈</a></li> <li class="menu-item"><a href="#">소개</a></li> <li class="menu-item"><a href="#" target="_blank">외부 링크</a></li> <li class="menu-item"><a href="#">연락처</a></li> </ul> </nav> </header> <main> <section class="content-section"> <h2>환영합니다!</h2> <p>이곳은 CSS 선택자 연습을 위한 <span class="highlight">샘플 페이지</span>입니다. 다양한 요소에 CSS가 어떻게 적용되는지 확인해 보세요.</p> <button class="call-to-action">자세히 알아보기</button> </section> <section class="content-section"> <h3>CSS 학습 리스트</h3> <ul> <li>기본 문법</li> <li>선택자</li> <li>속성</li> <li>레이아웃</li> </ul> <p class="small-text">이 목록은 CSS로 스타일링되었습니다.</p> </section> <section class="form-section"> <h3>문의하기</h3> <form> <label for="name">이름:</label> <input type="text" id="name" name="name" placeholder="이름을 입력하세요" required><br> <label for="email">이메일:</label> <input type="email" id="email" name="email" placeholder="email@example.com"><br> <button type="submit">문의 제출</button> </form> </section> </main> <footer> <p>© 2025 웹 개발 학습. 모든 권리 보유.</p> <p class="small-text">CSS 기본을 배우는 중입니다.</p> </footer> </body> </html>
-
css/style.css
파일 작성css/style.css /* 1. 전체 선택자: 기본 여백 제거 */ * { margin: 0; padding: 0; box-sizing: border-box; /* 패딩과 보더가 요소의 너비/높이에 포함되도록 설정 */ } /* 2. 태그 선택자: 기본 폰트 및 배경 색상 */ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f0f2f5; color: #333; line-height: 1.6; } /* ID 선택자: 헤더 스타일링 */ #main-header { background-color: #2c3e50; color: white; padding: 20px 0; text-align: center; } /* 하위 선택자: 헤더 내부의 h1 */ #main-header .page-title { font-size: 2.5em; margin-bottom: 10px; color: #ecf0f1; } /* 태그 선택자: 네비게이션 ul 초기화 */ nav ul { list-style: none; /* 목록 기호 제거 */ } /* 자식 선택자: nav 바로 아래 ul의 자식 li */ nav > ul > li { display: inline-block; /* 메뉴 항목을 가로로 배열 */ margin: 0 15px; } /* 클래스 선택자: 메뉴 아이템 링크 */ .menu-item a { color: #f1c40f; /* 노란색 */ text-decoration: none; /* 밑줄 제거 */ font-weight: bold; transition: color 0.3s ease; /* 호버 효과를 부드럽게 */ } /* 가상 클래스 선택자: 링크 호버 시 */ .menu-item a:hover { color: #f39c12; /* 오렌지색 */ } /* 속성 선택자: target="_blank" 속성을 가진 링크 */ a[target="_blank"]::after { /* 가상 요소 선택자: 외부 링크 뒤에 아이콘 추가 */ content: " ↗"; font-size: 0.8em; vertical-align: top; color: #f1c40f; } /* 메인 콘텐츠 영역 */ main { max-width: 900px; margin: 20px auto; padding: 20px; background-color: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } /* 클래스 선택자: 섹션 공통 스타일 */ .content-section { margin-bottom: 30px; padding: 20px; border: 1px solid #e0e0e0; border-radius: 5px; background-color: #ffffff; } /* 하위 선택자: .content-section 내부의 h2 */ .content-section h2 { color: #2980b9; margin-bottom: 15px; border-bottom: 2px solid #2980b9; padding-bottom: 5px; } /* 클래스 선택자: 하이라이트 텍스트 */ .highlight { background-color: #ffeaa7; /* 연한 노란색 */ padding: 2px 5px; border-radius: 3px; font-weight: bold; } /* 클래스 선택자: 버튼 스타일 */ button.call-to-action { background-color: #27ae60; color: white; padding: 12px 25px; border: none; border-radius: 5px; cursor: pointer; font-size: 1.1em; transition: background-color 0.3s ease; margin-top: 20px; } button.call-to-action:hover { background-color: #229954; } /* 태그 선택자: ul 내부의 li (목록 기호 색상 변경) */ .content-section ul li { list-style-type: square; /* 사각형 기호 */ color: #555; margin-left: 20px; } /* 가상 클래스 선택자: 짝수 번째 li */ .content-section ul li:nth-child(even) { background-color: #f9f9f9; } /* 인접 형제 선택자: input 바로 뒤의 button */ input + button { margin-left: 10px; /* input과 버튼 사이 여백 */ } /* 폼 섹션 스타일 */ .form-section { background-color: #ebf5fb; } .form-section label { display: block; /* 레이블을 블록 요소로 만들어 줄바꿈 */ margin-bottom: 5px; font-weight: bold; color: #444; } .form-section input[type="text"], .form-section input[type="email"] { width: calc(100% - 120px); /* 레이블과 버튼을 고려한 너비 */ padding: 8px; margin-bottom: 10px; border: 1px solid #a9d9f5; border-radius: 4px; } .form-section input[type="text"]:focus, .form-section input[type="email"]:focus { border-color: #007bff; outline: none; box-shadow: 0 0 5px rgba(0, 123, 255, 0.3); } .form-section button[type="submit"] { background-color: #007bff; margin-top: 10px; } .form-section button[type="submit"]:hover { background-color: #0056b3; } /* 푸터 스타일 */ footer { background-color: #34495e; color: white; text-align: center; padding: 20px 0; margin-top: 30px; border-radius: 8px; } /* 클래스 선택자: 작은 텍스트 */ .small-text { font-size: 0.8em; color: #aaa; } /* 가상 클래스: input 필드에 포커스 있을 때 */ input:focus { border-color: #007bff; box-shadow: 0 0 5px rgba(0, 123, 255, 0.3); }
-
결과 확인
- Live Server를 통해
index.html
파일을 열어보세요. - HTML 파일에 아무런
style=""
속성도 없지만,style.css
파일에 정의된 다양한 스타일 규칙들이 적용되어 웹 페이지가 훨씬 보기 좋게 변한 것을 확인할 수 있을 것입니다. - 각 선택자들이 어떤 요소에 어떻게 적용되었는지 CSS 코드와 브라우저 화면을 비교하며 확인해 보세요. 특히 마우스를 올렸을 때(hover), 입력 필드에 클릭했을 때(focus), 외부 링크 옆에 화살표가 붙는(::after) 효과들을 관찰해 보세요.
- Live Server를 통해
이번 장에서는 CSS의 가장 기본적인 문법과 외부 스타일 시트를 이용한 적용 방법을 학습했습니다. 특히 HTML 요소에 스타일을 적용하기 위한 핵심적인 개념인 선택자(Selector) 의 다양한 종류와 활용법을 심도 있게 다루었습니다. 태그, 클래스, ID 선택자부터 복합 선택자, 속성 선택자, 가상 클래스, 가상 요소 선택자까지, 이 모든 선택자들을 숙달하는 것이 CSS를 자유자재로 다루는 첫걸음이 될 것입니다.