반응형 웹 만들기 – 미디어 쿼리로 모바일 화면 대응하기
반응형 웹 만들기 – 미디어 쿼리로 모바일 화면 대응하기
지난 글에서는 Flexbox로 요소를 가로·세로로 자유롭게 정렬하는 방법을 배우고, 메뉴바와 카드 목록까지 직접 만들어 보았습니다. 그런데 그렇게 만든 페이지를 스마트폰으로 열어 보면 어떨까요? 글자가 깨알처럼 작게 보이거나, 메뉴가 화면 밖으로 삐져나가거나, 좌우로 스크롤을 해야 하는 불편한 화면이 나올 수 있습니다. 요즘은 인터넷 사용의 상당 부분이 스마트폰에서 이루어지기 때문에 PC와 모바일 모두에서 보기 좋은 페이지를 만드는 것은 선택이 아니라 필수입니다. CSS 기초 시리즈의 마지막 글인 오늘은 반응형 웹의 개념과 꼭 필요한 viewport 설정, 그리고 핵심 도구인 미디어 쿼리를 활용해 모바일 화면에 대응하는 방법을 정리해 보겠습니다.
1. 반응형 웹이란 무엇인가요?
반응형 웹(Responsive Web)은 하나의 웹페이지가 접속한 기기의 화면 크기에 맞춰 레이아웃을 자동으로 바꾸는 것을 말합니다. 넓은 PC 모니터에서는 카드 세 개가 가로로 나란히 보이다가, 태블릿에서는 두 개씩, 스마트폰에서는 한 개씩 세로로 쌓이는 식입니다. 물이 담기는 그릇의 모양에 따라 형태가 바뀌는 것처럼, 페이지가 화면 크기에 “반응”한다고 해서 반응형이라는 이름이 붙었습니다.
PC – 3칸
태블릿 – 2칸
모바일 – 1칸
예전에는 PC용 사이트와 모바일용 사이트(주소 앞에 m.이 붙는)를 따로 만들기도 했습니다. 하지만 이 방식은 두 개의 사이트를 관리해야 해서 수정할 때마다 일이 두 배가 됩니다. 반응형 웹은 HTML 하나, CSS 하나로 모든 기기에 대응하기 때문에 관리가 훨씬 쉽고, 지금은 대부분의 웹사이트가 이 방식을 사용합니다.
2. 반응형 웹이 중요한 이유
- 모바일 사용자의 증가 : 블로그나 쇼핑몰 같은 많은 사이트에서 방문자 대부분이 스마트폰으로 접속합니다. 모바일에서 불편한 사이트는 방문자가 곧바로 떠나 버립니다.
- 검색 엔진 평가 : 구글은 사이트의 모바일 버전을 기준으로 페이지를 평가하고 검색 순위를 정하는 방식(모바일 우선 색인)을 사용합니다. 모바일에서 보기 불편하면 검색 노출에도 불리할 수 있습니다.
- 유지보수의 효율성 : 한 번 만든 페이지가 PC, 태블릿, 스마트폰은 물론 앞으로 등장할 새로운 화면 크기에도 자연스럽게 대응합니다.
3. 반응형의 첫걸음 – viewport 메타 태그
반응형 웹을 만들 때 가장 먼저, 그리고 반드시 넣어야 하는 코드가 있습니다. HTML의 head 안에 다음 한 줄을 추가하세요.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
이 코드가 없으면 스마트폰 브라우저는 페이지를 약 980px 너비의 PC 화면이라고 가정하고 그린 다음, 그것을 작은 화면에 맞게 통째로 축소해서 보여줍니다. 그래서 글자가 깨알처럼 작아지고, 아무리 미디어 쿼리를 작성해도 스마트폰이 자신을 PC로 인식하기 때문에 적용되지 않습니다.
width=device-width는 “페이지 너비를 실제 기기 화면 너비에 맞춰라”, initial-scale=1.0은 “처음 열 때 확대·축소하지 말고 100%로 보여줘라”라는 뜻입니다. 지금까지 시리즈의 실습 코드에는 이 태그가 없었는데, 오늘부터는 모든 HTML 문서의 <meta charset="UTF-8"> 바로 아래에 함께 넣는 습관을 들이세요. 반응형 웹에서 가장 흔한 실수가 바로 이 한 줄을 빠뜨리는 것입니다.
4. 미디어 쿼리의 기본 문법
미디어 쿼리(Media Query)는 “화면이 특정 조건을 만족할 때만 이 CSS를 적용하라”고 지시하는 CSS 문법입니다. 프로그래밍의 조건문(만약 ~라면)과 비슷하다고 생각하면 됩니다.
/* 기본 스타일: 모든 화면에 적용 */
body {
background: white;
}
/* 화면 너비가 768px 이하일 때만 적용 */
@media (max-width: 768px) {
body {
background: lightyellow;
}
}
위 코드는 평소에는 흰 배경이다가, 화면 너비가 768px 이하로 줄어들면 연한 노란 배경으로 바뀝니다. 문법을 정리하면 다음과 같습니다.
- @media : 미디어 쿼리를 시작한다는 선언입니다.
- ( 조건 ) : 괄호 안에 적용 조건을 적습니다. 가장 많이 쓰는 조건은 화면 너비입니다.
- { CSS } : 조건을 만족할 때 적용할 CSS를 중괄호 안에 평소처럼 작성합니다. 중괄호가 두 겹이 되므로 짝을 잘 맞춰야 합니다.
미디어 쿼리 안의 스타일은 지난 CSS 기초 글에서 배운 우선순위 원리에 따라, 같은 선택자라면 나중에 작성된 것이 이깁니다. 그래서 미디어 쿼리는 항상 기본 스타일보다 아래쪽에 작성해야 합니다.
5. max-width와 min-width의 차이
미디어 쿼리에서 가장 헷갈리는 부분이 max-width와 min-width입니다.
| 조건 | 의미 | 쉽게 말하면 |
|---|---|---|
| (max-width: 768px) | 화면 너비가 768px 이하일 때 | “최대 768px까지” → 작은 화면용 |
| (min-width: 768px) | 화면 너비가 768px 이상일 때 | “최소 768px부터” → 큰 화면용 |
두 조건을 and로 연결하면 범위도 지정할 수 있습니다. 예를 들어 @media (min-width: 768px) and (max-width: 1023px)는 태블릿 크기에만 적용됩니다.
6. 브레이크포인트 정하기
레이아웃이 바뀌는 기준 너비를 브레이크포인트(Breakpoint)라고 합니다. 정해진 정답은 없지만, 많이 사용하는 기준은 다음과 같습니다.
| 구분 | 화면 너비 | 대표 기기 |
|---|---|---|
| 모바일 | 767px 이하 | 스마트폰 |
| 태블릿 | 768px ~ 1023px | 태블릿, 작은 노트북 |
| PC | 1024px 이상 | 노트북, 데스크톱 모니터 |
중요한 것은 특정 기기에 맞추기보다 내 페이지의 레이아웃이 어색해지는 지점을 기준으로 삼는 것입니다. 브라우저 창을 천천히 줄여 보다가 카드가 너무 좁아지거나 메뉴가 넘치기 시작하는 너비가 바로 브레이크포인트를 넣을 위치입니다. 처음에는 위 표처럼 두세 개 정도의 기준만 사용해도 충분합니다.
7. 모바일 퍼스트 – 작은 화면부터 설계하기
반응형 CSS를 작성하는 방식은 크게 두 가지입니다.
① 데스크톱 퍼스트 : PC 화면 스타일을 기본으로 작성하고, max-width 미디어 쿼리로 작은 화면을 수정합니다.
② 모바일 퍼스트 : 모바일 화면 스타일을 기본으로 작성하고, min-width 미디어 쿼리로 큰 화면을 추가합니다.
/* 모바일 퍼스트 예시 */
/* 기본: 모바일 – 카드를 세로로 쌓기 */
.cards {
display: flex;
flex-direction: column;
gap: 16px;
}
/* 768px 이상: 태블릿 – 가로로 나란히 */
@media (min-width: 768px) {
.cards {
flex-direction: row;
flex-wrap: wrap;
}
}
/* 1024px 이상: PC – 최대 너비 지정 */
@media (min-width: 1024px) {
.cards {
max-width: 960px;
margin: 0 auto;
}
}
요즘은 모바일 퍼스트 방식을 권장하는 경우가 많습니다. 작은 화면은 공간이 부족하기 때문에 정말 중요한 내용만 담도록 처음부터 고민하게 되고, 모바일 기기는 불필요한 큰 화면용 스타일을 덮어쓸 필요가 없어 효율적입니다. 다만 이미 PC용으로 만든 페이지를 반응형으로 고칠 때는 데스크톱 퍼스트 방식이 더 편할 수 있으니, 상황에 맞게 선택하면 됩니다. 중요한 것은 한 프로젝트 안에서 한 가지 방식으로 통일하는 것입니다.
8. 반응형에 강한 단위 사용하기
미디어 쿼리만큼 중요한 것이 고정된 크기를 피하는 것입니다. 모든 크기를 px로 고정하면 화면 크기가 바뀌어도 요소가 따라 변하지 않습니다. 반응형 웹에서는 다음과 같은 상대 단위를 적극적으로 활용합니다.
| 단위 | 기준 | 활용 예 |
|---|---|---|
| % | 부모 요소 크기 | width: 50%; (부모의 절반) |
| rem | 기본 글자 크기(보통 16px) | 글자 크기, 여백 |
| vw | 화면 너비의 1% | 화면 크기에 비례하는 제목 |
| vh | 화면 높이의 1% | min-height: 100vh; (화면 전체 높이) |
특히 다음 두 가지 패턴은 반응형의 기본 공식처럼 쓰입니다. 첫째, 본문 영역에 width: 700px 대신 max-width: 700px를 쓰는 것입니다. width는 화면이 700px보다 좁아도 700px을 고집해 화면 밖으로 넘치지만, max-width는 “최대 700px, 화면이 좁으면 그만큼 줄어든다”는 뜻이라 자연스럽게 대응합니다. 둘째, 이미지와 동영상 편에서 배운 img { max-width: 100%; height: auto; }로 이미지가 화면 밖으로 넘치지 않게 하는 것입니다.
9. 자주 쓰는 반응형 패턴
① 가로 배치를 세로로 바꾸기
가장 대표적인 패턴입니다. PC에서는 본문과 사이드바가 나란히 있다가 모바일에서는 위아래로 쌓이게 합니다. 지난 글에서 배운 Flexbox의 flex-direction만 바꾸면 됩니다.
.wrap {
display: flex;
gap: 24px;
}
@media (max-width: 767px) {
.wrap {
flex-direction: column;
}
}
② 글자 크기와 여백 줄이기
PC에서 시원하게 보이던 큰 제목과 넉넉한 여백이 모바일에서는 공간을 너무 많이 차지합니다. 작은 화면에서는 제목 크기와 padding을 조금씩 줄여 주세요.
h1 { font-size: 2.5rem; }
.section { padding: 60px 40px; }
@media (max-width: 767px) {
h1 { font-size: 1.8rem; }
.section { padding: 30px 16px; }
}
③ 특정 요소 숨기기
display: none을 사용하면 특정 화면에서 요소를 숨길 수 있습니다. 모바일에서 덜 중요한 사이드바 광고를 숨기는 식입니다. 다만 숨긴 내용도 HTML에는 남아 있으므로, 핵심 정보는 숨기지 말고 배치를 바꾸는 쪽을 먼저 고려하세요.
④ 터치하기 쉬운 크기로
모바일에서는 마우스 대신 손가락으로 누릅니다. 버튼과 링크가 너무 작거나 서로 붙어 있으면 잘못 누르기 쉬우므로, 터치 영역은 최소 44px 정도의 높이를 확보하고 링크 사이에 충분한 간격을 두는 것이 좋습니다.
10. 개발자 도구로 모바일 화면 확인하기
반응형 페이지를 만들 때마다 스마트폰으로 확인하기는 번거롭습니다. 크롬 브라우저의 개발자 도구를 사용하면 PC에서도 다양한 기기 화면을 쉽게 미리 볼 수 있습니다.
- 확인할 페이지에서 F12를 눌러 개발자 도구를 엽니다.
- 개발자 도구 왼쪽 위의 스마트폰·태블릿 모양 아이콘을 클릭하거나 Ctrl + Shift + M(맥은 Cmd + Shift + M)을 누릅니다.
- 화면 위쪽 메뉴에서 원하는 기기를 선택하거나, 화면 가장자리를 드래그해 너비를 자유롭게 조절합니다.
너비를 천천히 줄여 가며 레이아웃이 바뀌는 순간을 관찰하면 미디어 쿼리가 제대로 작동하는지 한눈에 확인할 수 있습니다. 다만 개발자 도구는 화면 크기만 흉내 내는 것이므로, 완성 후에는 실제 스마트폰으로도 한 번 열어 터치감과 글자 크기를 확인하는 것이 좋습니다.
11. 실습: Flexbox 페이지를 반응형으로 바꾸기
지난 글에서 만든 메뉴바와 카드 목록 페이지를 반응형으로 바꿔 보겠습니다. 이번에는 모바일 퍼스트 방식으로 작성했습니다. 아래 코드를 responsive.html로 저장해 브라우저에서 열고, 창 너비를 줄였다 늘려 보세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>반응형 실습</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: sans-serif;
background: #f5f7fb;
line-height: 1.7;
}
img { max-width: 100%; height: auto; }
/* ===== 기본: 모바일 ===== */
.navbar {
display: flex;
flex-direction: column; /* 로고와 메뉴를 위아래로 */
align-items: center;
gap: 10px;
padding: 16px;
background: #264de4;
}
.logo {
color: white;
font-size: 1.2rem;
font-weight: bold;
}
.menu {
display: flex;
gap: 20px;
}
.menu a {
color: white;
text-decoration: none;
padding: 8px 4px; /* 터치 영역 확보 */
}
.hero {
text-align: center;
padding: 32px 16px;
}
.hero h1 { font-size: 1.6rem; margin: 0 0 8px; }
.cards {
display: flex;
flex-direction: column; /* 카드를 세로로 쌓기 */
gap: 16px;
padding: 0 16px 32px;
}
.card {
background: white;
border-radius: 10px;
padding: 20px;
}
.card h3 { margin: 0 0 6px; }
/* ===== 768px 이상: 태블릿 ===== */
@media (min-width: 768px) {
.navbar {
flex-direction: row; /* 로고와 메뉴를 양 끝으로 */
justify-content: space-between;
padding: 16px 32px;
}
.hero { padding: 48px 32px; }
.hero h1 { font-size: 2.2rem; }
.cards {
flex-direction: row;
flex-wrap: wrap;
padding: 0 32px 48px;
}
.card {
flex: 1 1 45%; /* 한 줄에 2개 */
}
}
/* ===== 1024px 이상: PC ===== */
@media (min-width: 1024px) {
.hero h1 { font-size: 2.8rem; }
.cards {
max-width: 1000px;
margin: 0 auto;
}
.card {
flex: 1 1 30%; /* 한 줄에 3개 */
}
}
</style>
</head>
<body>
<nav class="navbar">
<div class="logo">코딩 공부</div>
<div class="menu">
<a href="#">HTML</a>
<a href="#">CSS</a>
<a href="#">문의</a>
</div>
</nav>
<section class="hero">
<h1>웹 코딩 기초 강좌</h1>
<p>PC에서도 모바일에서도 편하게 공부하세요.</p>
</section>
<div class="cards">
<div class="card"><h3>HTML 기초</h3><p>웹페이지의 뼈대를 배웁니다.</p></div>
<div class="card"><h3>CSS 기초</h3><p>페이지를 꾸미는 방법을 배웁니다.</p></div>
<div class="card"><h3>Flexbox</h3><p>요소를 자유롭게 정렬합니다.</p></div>
</div>
</body>
</html>
화면 크기에 따라 다음과 같이 바뀝니다.
모바일
PC
모바일에서는 로고와 메뉴가 가운데에 위아래로 놓이고 카드가 한 줄씩 쌓입니다. 768px 이상이 되면 메뉴바가 양 끝 배치로 바뀌고 카드가 두 개씩, 1024px 이상에서는 세 개씩 나란히 놓입니다. HTML은 전혀 바꾸지 않고 CSS의 미디어 쿼리만으로 세 가지 레이아웃이 만들어진 것입니다. 이것이 반응형 웹의 핵심입니다.
12. 반응형 웹에서 자주 하는 실수
- 스마트폰에서 미디어 쿼리가 안 먹혀요 : viewport 메타 태그를 빠뜨린 경우가 대부분입니다. head에 꼭 넣었는지 확인하세요.
- 미디어 쿼리를 위에 작성함 : 기본 스타일이 미디어 쿼리보다 아래에 있으면 미디어 쿼리 스타일을 덮어써 버립니다. 미디어 쿼리는 항상 CSS 맨 아래에 두세요.
- 좌우로 스크롤이 생겨요 : width를 px로 고정한 요소가 있거나, padding 때문에 100%를 넘은 경우입니다. max-width와 box-sizing: border-box를 활용하세요. 개발자 도구에서 화면 밖으로 튀어나온 요소를 찾아보면 원인을 쉽게 발견할 수 있습니다.
- 중괄호 짝이 안 맞아요 : 미디어 쿼리는 중괄호가 두 겹이라 닫는 괄호를 빠뜨리기 쉽습니다. 들여쓰기를 정확히 해 두면 실수를 줄일 수 있습니다.
- min-width와 max-width를 섞어 씀 : 한 파일 안에서 두 방식을 뒤섞으면 어떤 스타일이 언제 적용되는지 헷갈리게 됩니다. 모바일 퍼스트(min-width)나 데스크톱 퍼스트(max-width) 중 하나로 통일하세요.
마무리하며
오늘은 하나의 페이지로 PC와 모바일 모두에 대응하는 반응형 웹을 만드는 방법을 알아보았습니다. 반응형의 출발점은 viewport 메타 태그 한 줄이고, 핵심 도구는 화면 너비 조건에 따라 CSS를 적용하는 미디어 쿼리입니다. 여기에 고정 크기 대신 max-width와 상대 단위를 사용하고, 지난 글에서 배운 Flexbox의 방향 전환을 함께 활용하면 대부분의 반응형 레이아웃을 만들 수 있습니다. 앞으로 페이지를 만들 때는 처음부터 “스마트폰에서는 어떻게 보일까?”를 함께 고민하는 습관을 들여 보세요.
이번 글로 CSS 기초 시리즈를 마무리합니다. 지금까지 HTML로 뼈대를 세우고 CSS로 꾸미고 배치하는 방법까지 배웠으니, 이제 정적인 웹페이지는 혼자서도 충분히 만들 수 있습니다. 다음 글부터는 웹페이지에 생동감을 불어넣는 자바스크립트 기초를 시작하겠습니다. 첫 번째 주제는 변수와 자료형입니다. 궁금한 점은 댓글로 남겨 주세요!
댓글 0