CSS 독학 가이드 6 - 반응형 디자인
반응형 디자인이 필수인 이유
2025년 현재, 웹사이트 방문자의 70% 이상이 모바일로 접속해요. 데스크톱에서만 잘 보이는 웹사이트는 절반 이상의 사용자를 잃는 거죠.
반응형 디자인(Responsive Web Design)은 하나의 HTML로 모든 기기에 대응하는 기술이에요. 모바일 앱 따로, 웹사이트 따로 만들 필요 없이 CSS만으로 해결합니다!
뷰포트 메타 태그 (필수!)
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
설명:
viewport 메타 태그가 없으면: 모바일에서 데스크톱 화면이 축소되어 표시됨
viewport 메타 태그가 있으면: 기기 너비에 맞춰 적절하게 표시됨
이게 없으면 모바일에서 데스크톱 화면이 축소되어 보여요. 모든 웹사이트에 필수!
width=device-width: 기기 너비에 맞춤initial-scale=1.0: 초기 확대 배율 1배
미디어 쿼리 기본
특정 화면 크기에서 다른 CSS를 적용해요.
/* 기본 스타일 (모든 화면) */
.container {
padding: 20px;
}
/* 768px 이하 (태블릿, 모바일) */
@media (max-width: 768px) {
.container {
padding: 10px;
}
}
주요 브레이크포인트
/* 모바일 (0~480px) */
@media (max-width: 480px) {
/* 스타일 */
}
/* 태블릿 (481~768px) */
@media (min-width: 481px) and (max-width: 768px) {
/* 스타일 */
}
/* 데스크톱 (769px~) */
@media (min-width: 769px) {
/* 스타일 */
}
/* 대형 데스크톱 (1200px~) */
@media (min-width: 1200px) {
/* 스타일 */
}
실무에서 자주 쓰는 브레이크포인트:
- 480px: 모바일
- 768px: 태블릿
- 1024px: 작은 데스크톱
- 1280px: 일반 데스크톱
Mobile First vs Desktop First
Desktop First (예전 방식)
/* 기본: 데스크톱 */
.container {
width: 1200px;
}
/* 작은 화면에서 수정 */
@media (max-width: 768px) {
.container {
width: 100%;
}
}
Mobile First (현대적 방식) ⭐ 추천
/* 기본: 모바일 */
.container {
width: 100%;
padding: 10px;
}
/* 큰 화면에서 확장 */
@media (min-width: 768px) {
.container {
width: 750px;
padding: 20px;
}
}
@media (min-width: 1024px) {
.container {
width: 1000px;
}
}
Mobile First가 좋은 이유:
- 모바일이 기본이 되는 시대
- 성능 최적화 (작은 화면부터 시작)
- 점진적 향상 (Progressive Enhancement)
유동 레이아웃
고정 크기 → 상대 크기
/* ❌ 나쁜 예 (고정 크기) */
.container {
width: 1200px;
}
/* ✅ 좋은 예 (상대 크기) */
.container {
width: 90%;
max-width: 1200px;
}
% vs vw/vh
/* 부모 기준 */
.box {
width: 50%; /* 부모의 50% */
}
/* 뷰포트 기준 */
.hero {
width: 100vw; /* 뷰포트 너비의 100% */
height: 100vh; /* 뷰포트 높이의 100% */
}
언제 뭘 쓸까?
%: 일반적인 레이아웃vw/vh: 전체 화면 섹션 (히어로 이미지 등)
반응형 이미지
1. 기본 방법
img {
max-width: 100%;
height: auto;
}
이것만 해도 이미지가 컨테이너를 벗어나지 않아요!
2. srcset 속성
<img
src="image-small.jpg"
srcset="image-small.jpg 480w,
image-medium.jpg 768w,
image-large.jpg 1200w"
sizes="(max-width: 480px) 100vw,
(max-width: 768px) 50vw,
33vw"
alt="반응형 이미지"
>
브라우저가 자동으로 적절한 크기 선택!
3. picture 태그
<picture>
<source media="(max-width: 480px)" srcset="mobile.jpg">
<source media="(max-width: 768px)" srcset="tablet.jpg">
<img src="desktop.jpg" alt="반응형 이미지">
</picture>
화면 크기별로 완전히 다른 이미지 사용 가능!
실전 예제 1: 반응형 네비게이션
<nav class="navbar">
<div class="logo">MyLogo</div>
<button class="menu-toggle">☰</button>
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #333;
color: white;
}
.menu {
display: flex;
gap: 2rem;
list-style: none;
}
.menu-toggle {
display: none; /* 데스크톱에서 숨김 */
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
}
/* 모바일 */
@media (max-width: 768px) {
.menu {
display: none; /* 기본 숨김 */
position: absolute;
top: 60px;
left: 0;
right: 0;
flex-direction: column;
background: #333;
padding: 1rem;
}
.menu.active {
display: flex; /* 토글 시 표시 */
}
.menu-toggle {
display: block; /* 햄버거 버튼 표시 */
}
}
JavaScript로 .active 클래스만 토글하면 됩니다!
실전 예제 2: 반응형 그리드
<div class="grid">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
</div>
.grid {
display: grid;
gap: 20px;
padding: 20px;
}
/* 모바일: 1열 */
@media (max-width: 480px) {
.grid {
grid-template-columns: 1fr;
}
}
/* 태블릿: 2열 */
@media (min-width: 481px) and (max-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 데스크톱: 3열 */
@media (min-width: 769px) and (max-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* 대형 데스크톱: 4열 */
@media (min-width: 1025px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
미디어 쿼리 없는 자동 반응형:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
이게 훨씬 간단하죠!
실전 예제 3: 반응형 타이포그래피
/* 기본 (모바일) */
body {
font-size: 14px;
}
h1 { font-size: 1.8rem; }
h2 { font-size: 1.5rem; }
p { line-height: 1.5; }
/* 태블릿 */
@media (min-width: 768px) {
body {
font-size: 16px;
}
h1 { font-size: 2.2rem; }
h2 { font-size: 1.8rem; }
p { line-height: 1.6; }
}
/* 데스크톱 */
@media (min-width: 1024px) {
body {
font-size: 18px;
}
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
p { line-height: 1.7; }
}
clamp() 함수로 유동 타이포그래피:
h1 {
font-size: clamp(1.8rem, 5vw, 2.5rem);
/* 최소 1.8rem, 이상적 5vw, 최대 2.5rem */
}
화면 크기에 따라 자동으로 조정!
컨테이너 쿼리 (최신 기능)
요소의 크기에 따라 스타일 변경 (뷰포트가 아닌!)
.sidebar {
container-type: inline-size;
}
.card {
padding: 1rem;
}
@container (min-width: 400px) {
.card {
padding: 2rem;
display: grid;
grid-template-columns: 1fr 1fr;
}
}
사이드바가 넓어지면 카드 레이아웃이 바뀝니다! (2024년부터 주요 브라우저 지원)
숨기기/보이기 패턴
/* 모바일에서만 보임 */
.mobile-only {
display: block;
}
@media (min-width: 768px) {
.mobile-only {
display: none;
}
}
/* 데스크톱에서만 보임 */
.desktop-only {
display: none;
}
@media (min-width: 768px) {
.desktop-only {
display: block;
}
}
터치 기기 감지
/* 터치 기기 (모바일, 태블릿) */
@media (hover: none) and (pointer: coarse) {
.button {
min-height: 44px; /* 터치하기 쉽게 크게 */
min-width: 44px;
}
}
/* 마우스 기기 (데스크톱) */
@media (hover: hover) and (pointer: fine) {
.button:hover {
background: #0056b3;
}
}
다크 모드 대응
/* 라이트 모드 (기본) */
body {
background: #fff;
color: #333;
}
/* 다크 모드 */
@media (prefers-color-scheme: dark) {
body {
background: #1a1a1a;
color: #e0e0e0;
}
}
사용자의 시스템 설정을 자동으로 따라갑니다!
성능 최적화 팁
1. 불필요한 미디어 쿼리 줄이기
/* ❌ 나쁜 예 */
@media (max-width: 768px) {
.box { padding: 10px; }
}
@media (max-width: 768px) {
.card { margin: 5px; }
}
/* ✅ 좋은 예 */
@media (max-width: 768px) {
.box { padding: 10px; }
.card { margin: 5px; }
}
2. min-width 우선 사용 (Mobile First)
/* 기본: 모바일 */
.container { padding: 10px; }
/* 확장: 큰 화면 */
@media (min-width: 768px) {
.container { padding: 20px; }
}
3. CSS 변수 활용
:root {
--spacing: 10px;
--container-width: 100%;
}
@media (min-width: 768px) {
:root {
--spacing: 20px;
--container-width: 750px;
}
}
.container {
padding: var(--spacing);
max-width: var(--container-width);
}
반응형 체크리스트
- viewport 메타 태그 추가
- 이미지에 max-width: 100%
- 고정 크기 대신 상대 크기 사용
- Mobile First 접근
- 터치 타겟 최소 44x44px
- 가로 스크롤 방지
- 실제 기기에서 테스트
- 개발자 도구로 여러 화면 크기 확인
디버깅 팁
Chrome DevTools
- F12 → 기기 툴바 토글 (Ctrl+Shift+M)
- 상단에서 기기 선택 (iPhone, iPad 등)
- 커스텀 크기도 입력 가능
반응형 테스트 사이트
- Responsive Design Checker
- BrowserStack (실제 기기 테스트)
- Mobile-Friendly Test (Google)
다음 단계
반응형 디자인을 마스터했으니 이제 애니메이션과 전환 효과를 배울 차례예요. 움직임을 추가하면 사용자 경험이 훨씬 좋아집니다!
다음 글에서는 transition, transform, animation을 다룰 거예요. 버튼 호버 효과부터 복잡한 애니메이션까지!
실습 과제:
- 네비게이션 바를 모바일에서 햄버거 메뉴로 바꿔보기
- 3열 그리드를 모바일에서 1열로 변경하기
- 타이포그래피를 화면 크기별로 다르게 설정하기
- 실제 휴대폰에서 웹사이트 확인해보기
시리즈 네비게이션
- 이전글: CSS 독학 가이드 - 색상과 타이포그래피
- 현재글: CSS 독학 가이드 - 반응형 디자인
- 다음글: CSS 독학 가이드 - 애니메이션과 전환 효과