CSS 개요
CSS(Cascading Style Sheets)는 HTML이나 XML과 같은 마크업 언어의 시각적 표현을 담당하는 스타일시트 언어입니다. 최신 표준인 CSS3를 통해 콘텐츠와 디자인을 완벽하게 분리할 수 있으며, 픽셀 단위의 정교한 레이아웃 제어, 다양한 타이포그래피 지원, 그리고 반응형 및 인터랙티브 디자인 구현이 가능합니다. 이 글에서는 웹 개발 시 자주 사용되는 CSS의 핵심 개념과 주요 스타일링 기법을 코드를 통해 살펴보겠습니다.
CSS 적용 방식과 우선순위
CSS는 크게 세 가지 방식으로 문서에 적용할 수 있습니다. 각 방식에 따라 우선순위가 달라지므로 상황에 맞게 선택해야 합니다. 우선순위는 인라인 스타일 > 내부 스타일시트 > 외부 스타일시트 순으로 높습니다.
1. 인라인 스타일 (Inline)
HTML 요소의 style 속성에 직접 스타일을 정의하는 방식입니다. 특정 요소에만 일회성으로 스타일을 적용할 때 유용하지만, 유지보수가 어렵다는 단점이 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>인라인 스타일 예제</title>
</head>
<body>
<section style="background-color: #3498db; color: #ffffff; padding: 20px; border-radius: 8px;">
인라인 스타일이 적용된 영역입니다.
</section>
</body>
</html>
2. 내부 스타일시트 (Internal)
HTML 문서의 <head> 영역 내 <style> 태그를 사용하여 스타일을 정의합니다. 단일 페이지에만 적용되는 스타일을 관리할 때 적합합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>내부 스타일시트 예제</title>
<style>
.content-box {
background-color: #2ecc71;
color: #2c3e50;
padding: 15px;
border-radius: 8px;
}
</style>
</head>
<body>
<div class="content-box">내부 스타일시트를 활용한 박스</div>
</body>
</html>
3. 외부 스타일시트 (External)
별도의 .css 파일을 생성하고 <link> 태그로 연결하는 방식입니다. 여러 페이지에서 스타일을 재사용하고 유지보수하기 가장 좋은 표준적인 방법입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>외부 스타일시트 예제</title>
<link rel="stylesheet" href="assets/css/main-theme.css">
</head>
<body>
<article class="external-styled">외부 CSS 파일이 적용된 아티클</article>
</body>
</html>
CSS 선택자 (Selectors)
선택자는 스타일을 적용할 대상을 지정하는 규칙입니다. 다양한 선택자를 조합하여 특정 요소만 정교하게 타겟팅할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>CSS 선택자 종합 예제</title>
<style>
/* 요소 선택자 */
article { color: #2980b9; }
/* ID 선택자 */
#main-header { font-size: 2.5rem; font-weight: bold; }
/* 클래스 선택자 */
.highlight-text { background-color: #f1c40f; padding: 4px; }
/* 하위 선택자 */
.card-wrapper .card-body p { color: #e74c3c; font-weight: 600; }
/* 그룹 선택자 */
.btn-primary, .btn-secondary { padding: 10px 20px; border: none; cursor: pointer; }
/* 속성 선택자 */
input[type="email"] { border: 2px solid #9b59b6; }
</style>
</head>
<body>
<h1 id="main-header">선택자 테스트</h1>
<article>
<p>이것은 <span class="highlight-text">요소 및 클래스 선택자</span>가 적용된 텍스트입니다.</p>
</article>
<div class="card-wrapper">
<div class="card-body">
<p>하위 선택자에 의해 스타일링된 단락입니다.</p>
</div>
</div>
<button class="btn-primary">Primary</button>
<button class="btn-secondary">Secondary</button>
<br><br>
<input type="text" placeholder="일반 입력">
<input type="email" placeholder="이메일 입력 (속성 선택자)">
</body>
</html>
배경 및 타이포그래피 스타일링
배경색, 배경 이미지, 텍스트 색상 및 폰트 크기를 설정하여 화면의 전반적인 톤앤매너를 구성합니다. 배경 관련 속성은 단축 속성(Shorthand)을 사용하면 코드를 간결하게 작성할 수 있습니다.
<style>
.bg-typo-demo {
/* 배경 단축 속성: 색상, 이미지, 반복여부, 고정여부, 위치/크기 */
background: #1abc9c url('assets/pattern.png') no-repeat fixed center/cover;
color: #ecf0f1;
font-size: 1.2rem;
padding: 50px;
}
.text-highlight {
background-color: rgba(255, 255, 255, 0.3);
color: #2c3e50;
font-size: 1.5rem;
}
</style>
<div class="bg-typo-demo">
<p>배경 이미지와 색상이 조화된 영역입니다.</p>
<span class="text-highlight">강조된 타이포그래피</span>
</div>
박스 모델과 테두리 (Box Model & Borders)
마진(Margin), 패딩(Padding), 테두리(Border)를 제어하여 요소의 크기와 간격을 조절합니다. 테이블의 테두리를 병합할 때는 border-collapse 속성을 활용합니다.
<style>
.box-model-demo {
border: 3px dashed #e67e22;
margin: 20px auto;
padding: 30px;
width: 300px;
box-sizing: border-box;
}
.data-table {
border-collapse: collapse;
width: 100%;
margin-top: 20px;
}
.data-table th, .data-table td {
border: 1px solid #bdc3c7;
padding: 12px;
text-align: left;
}
</style>
<div class="box-model-demo">박스 모델이 적용된 div 요소</div>
<table class="data-table">
<tr>
<th>항목</th>
<th>설명</th>
</tr>
<tr>
<td>테두리 병합</td>
<td>border-collapse: collapse 사용</td>
</tr>
</table>
레이아웃 및 포지셔닝 (Layout & Positioning)
요소를 화면에 배치하는 방식에는 플로트(Float), 플렉스박스(Flexbox), 그리고 포지션(Position) 속성이 있습니다. 아래는 플로트를 활용한 내비게이션 메뉴와 다양한 포지션 속성의 예시입니다.
<style>
/* 플로트를 활용한 수평 메뉴 */
.nav-menu { list-style: none; padding: 0; margin: 0; }
.nav-menu li { float: left; }
.nav-menu a {
display: block;
padding: 15px 25px;
background-color: #34495e;
color: white;
text-decoration: none;
}
.nav-menu a:hover { background-color: #16a085; }
.clearfix::after { content: ""; display: table; clear: both; }
/* 포지셔닝 */
.relative-box { position: relative; left: 30px; top: 10px; background: #f1c40f; padding: 10px; }
.absolute-box { position: absolute; top: 100px; right: 50px; background: #f39c12; padding: 10px; }
.fixed-box { position: fixed; bottom: 20px; right: 20px; background: #c0392b; color: white; padding: 10px; z-index: 100; }
</style>
<ul class="nav-menu clearfix">
<li><a href="#home">홈</a></li>
<li><a href="#about">소개</a></li>
<li><a href="#contact">연락처</a></li>
</ul>
<div class="relative-box">상대 위치 (Relative)</div>
<div class="absolute-box">절대 위치 (Absolute)</div>
<div class="fixed-box">고정 위치 (Fixed)</div>
오버플로우, 가시성 및 인터랙션
영역을 벗어난 콘텐츠를 처리하거나(overflow), 요소의 가시성을 제어하고(visibility), 마우스 커서 모양을 변경하는 등 사용자와의 인터랙션을 위한 스타일을 정의합니다.
<style>
.scroll-box {
width: 200px;
height: 100px;
background-color: #00FFFF;
overflow: auto; /* 콘텐츠가 넘칠 때만 스크롤바 표시 */
padding: 10px;
}
.hidden-element { visibility: hidden; }
.clickable-area { cursor: pointer; }
.clipped-image {
position: absolute;
clip: rect(0px, 60px, 100px, 0px); /* 이미지 특정 영역만 마스킹 */
}
</style>
<div class="scroll-box">
이 박스는 높이가 제한되어 있어 텍스트가 길어지면 세로 스크롤바가 자동으로 생성됩니다. 오버플로우 속성을 활용하여 레이아웃이 깨지는 것을 방지할 수 있습니다.
</div>
<p class="hidden-element">이 텍스트는 공간을 차지하지만 보이지 않습니다.</p>
<p class="clickable-area">마우스를 올리면 커서가 포인터로 변합니다.</p>
의사 클래스(Pseudo-classes)를 활용한 링크 상태 제어
링크의 상태(방문 전, 방문 후, 마우스 오버, 클릭 중)에 따라 다른 스타일을 적용할 수 있습니다. 의사 클래스는 반드시 :link, :visited, :hover, :active 순서로 정의해야 정상적으로 작동합니다.
<style>
a.state-link:link { color: #2980b9; text-decoration: none; font-weight: bold; }
a.state-link:visited { color: #8e44ad; }
a.state-link:hover { color: #e74c3c; text-decoration: underline; background-color: #f9e79f; }
a.state-link:active { color: #27ae60; }
</style>
<p>다양한 상태의 링크 테스트: <a class="state-link" href="#">여기를 클릭하세요</a></p>
실전 예제: 모달 오버레이 레이어 구현
CSS의 포지션, z-index, 그리고 투명도 속성을 활용하고 자바스크립트와 연동하여 화면을 덮는 모달 팝업 레이어를 구현하는 예제입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>모달 오버레이 레이어</title>
<style>
.modal-overlay {
display: none;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.6);
z-index: 999;
}
.modal-content {
display: none;
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: white;
padding: 30px;
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
z-index: 1000;
}
.modal-content h2 { margin-top: 0; }
.close-btn {
background: #e74c3c;
color: white;
border: none;
padding: 8px 16px;
cursor: pointer;
border-radius: 4px;
}
</style>
</head>
<body>
<button onclick="openModal()">모달 열기</button>
<div class="modal-overlay" id="overlay"></div>
<div class="modal-content" id="popup">
<h2>알림</h2>
<p>CSS와 JS를 활용해 구현한 모달 창입니다.</p>
<button class="close-btn" onclick="closeModal()">닫기</button>
</div>
<script>
function openModal() {
document.getElementById('overlay').style.display = 'block';
document.getElementById('popup').style.display = 'block';
}
function closeModal() {
document.getElementById('overlay').style.display = 'none';
document.getElementById('popup').style.display = 'none';
}
</script>
</body>
</html>