Skip to main content

데스크톱에서만 예쁜 페이지는 아직 절반만 완성된 페이지입니다. 실제 웹페이지는 휴대폰, 태블릿, 노트북, 큰 모니터처럼 다양한 화면에서 읽히고 눌려야 합니다. 그래서 웹은 화면 크기에 따라 자연스럽게 모양을 바꾸는 능력이 필요합니다. 이 능력을 만드는 대표 도구가 바로 미디어 쿼리입니다.1

반응형 웹이 필요한 이유

같은 페이지라도 작은 화면에서는 요소를 세로로 쌓는 편이 읽기 쉽고, 큰 화면에서는 가로로 넓게 배치하는 편이 시원합니다. 글자 크기, 카드 개수, 메뉴 방향, 여백도 화면에 맞게 달라져야 합니다. 반응형 웹 디자인은 이렇게 다양한 화면 크기에 맞춰 레이아웃과 표현을 조정하는 방식입니다.2

핵심은 어렵지 않습니다. 기본 스타일을 만들고, 특정 조건에서만 스타일을 덮어쓴다는 생각이면 됩니다.

시작 전에 꼭 넣을 것: viewport

모바일에서 반응형이 제대로 동작하려면 HTML의 <head> 안에 아래 코드를 넣어야 합니다.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

이 코드는 브라우저에게 기기의 실제 화면 너비를 기준으로 페이지를 보여 달라고 알려 줍니다. 이것이 없으면 모바일 브라우저가 페이지를 축소해서 보여 줄 수 있어, 만든 반응형 스타일이 어긋나 보일 수 있습니다.3

미디어 쿼리 문법 익히기

미디어 쿼리는 @media로 시작합니다.

@media (min-width: 768px) {
  body {
    background: #f7f7f7;
  }
}

이 뜻은 아주 단순합니다. 화면 너비가 768px 이상이면 중괄호 안의 CSS를 적용하라는 뜻입니다.

반대로 작은 화면에만 적용하고 싶다면 이렇게 씁니다.

@media (max-width: 767px) {
  .menu {
    flex-direction: column;
  }
}

처음에는 min-width와 max-width가 헷갈릴 수 있습니다. 이렇게 기억하면 편합니다.

  • min-width: 이 값 이상

  • max-width: 이 값 이하

  • @media: 조건이 맞을 때만 적용

모바일 퍼스트로 생각하기

초보자에게 가장 편한 방식은 모바일 퍼스트입니다. 먼저 작은 화면 기준으로 기본 스타일을 만들고, 화면이 넓어질 때 필요한 스타일만 추가하는 방식입니다.2

.menu {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

@media (min-width: 768px) {
  .menu {
    flex-direction: row;
  }
}

이렇게 하면 작은 화면에서는 메뉴가 위아래로 쌓이고, 큰 화면에서는 옆으로 나란히 놓입니다. 좁은 화면부터 먼저 생각하면 레이아웃이 덜 꼬이고, 필요한 변화도 더 분명하게 보입니다.

중단점은 기기가 아니라 콘텐츠로 정하기

미디어 쿼리가 적용되는 기준 너비를 중단점이라고 합니다. 많은 사람이 휴대폰, 태블릿, 데스크톱 크기를 외우려고 하지만, 더 좋은 기준은 콘텐츠가 불편해지는 순간입니다.3

예를 들어 카드 3개가 너무 비좁아져 읽기 힘들어지는 순간이 있다면, 그 지점에서 2개 또는 1개 열로 바꾸면 됩니다. 즉, 중단점은 기계 이름이 아니라 내 내용이 답답해지는 시점에 맞춰 잡는 것이 좋습니다.

실전 예제: 카드 3개를 화면에 맞게 바꾸기

먼저 모바일 기준으로 카드가 한 줄에 하나씩 쌓이게 만들어 보겠습니다.

HTML

<section class="course-list">
  <article class="course-card">
    <h2>HTML 기초</h2>
    <p>웹페이지의 구조를 차근차근 익힙니다.</p>
  </article>

  <article class="course-card">
    <h2>CSS 기초</h2>
    <p>색, 여백, 배치와 반응형의 기본을 배웁니다.</p>
  </article>

  <article class="course-card">
    <h2>Flexbox 입문</h2>
    <p>실무에서 자주 쓰는 가로·세로 배치를 연습합니다.</p>
  </article>
</section>

CSS

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 20px;
  background: #f8fafc;
  font-family: sans-serif;
}

.course-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.course-card {
  padding: 20px;
  border: 1px solid #dbe2ea;
  border-radius: 16px;
  background: white;
}

.course-card h2 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 1.25rem;
}

.course-card p {
  margin: 0;
  line-height: 1.6;
  color: #475569;
}

이 상태에서는 작은 화면에서 카드가 위아래로 차곡차곡 놓입니다. 이제 화면이 조금 넓어졌을 때만 배치를 바꿔 보겠습니다.

@media (min-width: 768px) {
  .course-list {
    flex-direction: row;
  }

  .course-card {
    flex: 1;
  }
}

이제 768px 이상에서는 카드가 가로로 나란히 놓입니다. 중요한 점은, 기본 스타일을 전부 다시 쓰지 않고 바뀌는 부분만 덮어썼다는 것입니다.

한 단계 더: 카드 개수를 유연하게 바꾸기

반응형의 맛은 "한 번에 툭 바꾸기"보다 "너비에 맞춰 자연스럽게 바뀌기"에 있습니다. 그래서 실무에서는 width를 고정하는 대신 flex, %, minmax(), max-width 같은 유연한 값을 자주 씁니다.

아주 쉬운 예로, 카드가 너무 작아지면 자동으로 줄바꿈되게 만들 수 있습니다.

.course-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.course-card {
  flex: 1 1 220px;
}

이 코드는 카드가 한 줄에 무조건 몇 개라고 강제하지 않습니다. 대신 "가능하면 한 줄에 놓되, 각 카드는 대략 220px 정도를 시작점으로 삼아라"라고 말하는 셈입니다. 화면이 넓으면 3개가 나란히 놓일 수 있고, 좁아지면 2개, 더 좁아지면 1개로 자연스럽게 바뀝니다.

이 방식은 미디어 쿼리와 함께 쓰면 특히 강력합니다. 작은 변화는 유연한 단위로 해결하고, 큰 변화는 미디어 쿼리로 해결한다고 생각하면 정리가 잘 됩니다.

반응형에서 자주 쓰는 단위 다시 보기

반응형은 미디어 쿼리만으로 만드는 것이 아닙니다. 유연한 단위를 함께 써야 화면이 덜 뻣뻣해집니다.

  • width: 100% → 부모 너비에 맞춰 늘어남

  • max-width: 960px → 너무 커지지 않게 제한

  • padding: 1rem → 글자 크기 기준으로 자연스럽게 여백 조절

  • font-size: 1rem, 1.25rem → 기준 글자 크기에 맞춘 크기 조절

  • gap: 1rem → 화면이 바뀌어도 일정한 간격 유지

예를 들어 콘텐츠 영역은 보통 이렇게 많이 만듭니다.

.container {
  width: min(100%, 960px);
  margin: 0 auto;
  padding: 0 16px;
}

이 코드는 화면이 좁을 때는 거의 꽉 차게 쓰고, 넓을 때는 960px 이상 무한정 커지지 않게 막아 줍니다. 너무 넓은 본문은 읽기 힘들기 때문에 이런 제한이 중요합니다.

글자 크기도 화면에 맞게 다듬기

반응형에서 레이아웃만 바뀌고 글자 크기는 그대로면 어색할 때가 많습니다. 화면이 아주 좁은데 큰 제목이 두 줄, 세 줄로 깨지면 답답해 보이죠.

기본 제목 크기를 먼저 정하고, 넓은 화면에서만 조금 키워 보겠습니다.

.hero-title {
  font-size: 1.8rem;
  line-height: 1.2;
}

@media (min-width: 768px) {
  .hero-title {
    font-size: 2.4rem;
  }
}

이렇게 하면 작은 화면에서는 부담 없는 크기로 보이고, 큰 화면에서는 더 시원하게 펼쳐집니다.

초보자일수록 처음부터 화면마다 글자 크기를 너무 많이 나누기보다, 기본값 하나 + 넓은 화면용 한 단계 정도부터 시작하는 것이 좋습니다.

이미지도 반응형이어야 한다

반응형 페이지에서 이미지는 자주 사고를 냅니다. 고정 너비 이미지는 작은 화면에서 부모를 뚫고 나가기 쉽기 때문입니다. 그래서 가장 먼저 넣어 두면 좋은 기본값이 있습니다.4

img {
  max-width: 100%;
  height: auto;
}

이 두 줄은 이미지를 부모보다 커지지 않게 하고, 비율도 유지해 줍니다.

카드 썸네일처럼 일정한 높이가 필요할 때는 object-fit도 자주 함께 씁니다.

.card img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

이렇게 하면 이미지가 영역을 꽉 채우고, 모양도 일정하게 유지됩니다. 일부가 잘릴 수는 있지만, 카드 디자인은 훨씬 안정적입니다.

내비게이션을 반응형으로 바꾸기

메뉴는 반응형에서 아주 자주 바뀌는 요소입니다. 작은 화면에서는 세로 목록이 더 누르기 쉽고, 큰 화면에서는 가로 메뉴가 자연스럽습니다.

HTML

<nav class="site-nav">
  <a href="#" class="logo">CSS 기초</a>
  <ul class="menu">
    <li><a href="#">소개</a></li>
    <li><a href="#">예제</a></li>
    <li><a href="#">프로젝트</a></li>
    <li><a href="#">문의</a></li>
  </ul>
</nav>

CSS

.site-nav {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: #0f172a;
}

.logo {
  color: white;
  text-decoration: none;
  font-weight: 700;
}

.menu {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0;
}

.menu a {
  display: block;
  padding: 10px 12px;
  color: white;
  text-decoration: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
}

@media (min-width: 768px) {
  .site-nav {
    flex-direction: row;
    align-items: center;
  }

  .menu {
    flex-direction: row;
    margin-left: auto;
  }

  .menu a {
    background: transparent;
  }
}

이 예제에서 핵심은 두 가지입니다.

  • 작은 화면에서는 세로 메뉴로 두어 손가락으로 누르기 쉽습니다.

  • 넓은 화면에서는 가로 메뉴로 바꾸고, margin-left: auto로 오른쪽으로 밀어 보냅니다.

즉, 반응형은 단지 "줄바꿈"만이 아니라 사용 방식에 맞춘 배치 변경입니다.

너무 넓은 본문은 오히려 불편하다

초보자는 종종 반응형을 "작은 화면 대응"으로만 생각합니다. 하지만 큰 화면에서도 조절이 필요합니다. 본문 줄이 너무 길면 오히려 읽기 어려워지기 때문입니다.

예를 들어 글 본문은 이렇게 제한하는 것이 보통 더 편합니다.

.article {
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 16px;
}

이 코드는 큰 모니터에서도 텍스트가 지나치게 좌우로 길게 늘어지는 것을 막아 줍니다. 반응형은 "작아질 때 버티는 기술"이기도 하지만, 동시에 "커질 때 흐트러지지 않는 기술"이기도 합니다.

미디어 쿼리 안에서 무엇을 바꿔야 할까

처음에는 모든 것을 다 바꾸고 싶어집니다. 하지만 실제로는 아래처럼 의미 있는 변화만 고르는 편이 좋습니다.

  • flex-direction 변경: 세로 ↔ 가로

  • grid-template-columns 변경: 1열 ↔ 2열 ↔ 3열

  • font-size 조정: 제목이나 핵심 텍스트 크기 조절

  • padding, gap 조정: 답답함 완화

  • display 변경: 작은 화면에서 숨기거나 보여 주기

반대로 색상, 테두리, 버튼 스타일처럼 화면 크기와 크게 관련 없는 부분은 굳이 미디어 쿼리마다 다시 쓰지 않아도 되는 경우가 많습니다.

자주 하는 실수

반응형을 처음 배울 때 자주 나오는 실수를 미리 보고 넘어가겠습니다.

viewport를 빼먹는다

모바일에서 다 깨져 보이는데 CSS가 틀린 줄 아는 경우가 많습니다. 실제로는 meta viewport가 없는 경우가 정말 흔합니다.3

큰 화면 기준으로 먼저 만들고 나중에 우겨 넣는다

이렇게 하면 작은 화면에서 고칠 것이 많아집니다. 초보자라면 모바일 퍼스트가 훨씬 덜 헷갈립니다.2

고정 너비를 너무 많이 쓴다

카드, 이미지, 버튼, 컨테이너에 width: 400px, 500px를 남발하면 작은 화면에서 쉽게 넘칩니다. 가능한 한 %, max-width, rem 같은 유연한 값을 먼저 고려해 보세요.

미디어 쿼리를 너무 잘게 쪼갠다

처음부터 320px, 360px, 390px, 412px처럼 촘촘하게 나누면 관리가 어려워집니다. 우선은 콘텐츠가 실제로 불편해지는 몇 군데만 잡는 것이 좋습니다.

레이아웃만 바꾸고 간격은 그대로 둔다

작은 화면에서 가로 배치를 세로 배치로 바꿨는데 gap, padding, 버튼 크기를 그대로 두면 어색해질 수 있습니다. 레이아웃을 바꿀 때는 간격도 함께 확인하세요.

개발자 도구로 반응형 확인하기

반응형은 꼭 실제 기기가 많아야만 연습할 수 있는 것은 아닙니다. 브라우저 개발자 도구의 디바이스 모드를 활용하면 화면 너비를 쉽게 바꿔 볼 수 있습니다.5

확인할 때는 이렇게 보면 좋습니다.

  • 어느 너비에서 레이아웃이 갑자기 답답해지는가?

  • 카드가 너무 좁아지거나 글이 이상하게 줄바꿈되는가?

  • 버튼이 충분히 눌릴 만한 크기인가?

  • 이미지가 부모 밖으로 넘치지는 않는가?

  • 메뉴가 너무 촘촘해서 누르기 어렵지는 않은가?

중요한 것은 "아이폰 몇 픽셀"을 외우는 것이 아니라, 내 콘텐츠가 언제 불편해지는지 눈으로 찾는 것입니다.

미니 프로젝트: 간단한 반응형 소개 섹션

지금까지 배운 내용을 짧게 합쳐 보겠습니다.

HTML

<section class="intro-section">
  <div class="intro-text">
    <h1>작은 화면에서도 편안한 웹페이지</h1>
    <p>
      반응형 웹은 화면이 작아질 때 억지로 줄이는 것이 아니라,
      읽기 쉽고 누르기 쉬운 형태로 다시 정리하는 작업입니다.
    </p>
    <a href="#">예제 보기</a>
  </div>

  <div class="intro-image">
    <img src="https://via.placeholder.com/800x500" alt="노트북과 모바일 화면 예시">
  </div>
</section>

CSS

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: sans-serif;
  background: #f8fafc;
  color: #0f172a;
}

.intro-section {
  display: flex;
  flex-direction: column;
  gap: 24px;
  width: min(100%, 1100px);
  margin: 0 auto;
  padding: 24px 16px;
}

.intro-text h1 {
  margin-top: 0;
  margin-bottom: 12px;
  font-size: 1.9rem;
  line-height: 1.2;
}

.intro-text p {
  margin-top: 0;
  margin-bottom: 16px;
  line-height: 1.7;
  color: #475569;
}

.intro-text a {
  display: inline-block;
  padding: 12px 16px;
  border-radius: 10px;
  background: #2563eb;
  color: white;
  text-decoration: none;
  font-weight: 700;
}

.intro-image img {
  display: block;
  width: 100%;
  border-radius: 18px;
}

@media (min-width: 768px) {
  .intro-section {
    flex-direction: row;
    align-items: center;
  }

  .intro-text,
  .intro-image {
    flex: 1;
  }

  .intro-text h1 {
    font-size: 2.5rem;
  }
}

이 예제는 작은 화면에서는 위아래 배치, 큰 화면에서는 좌우 배치로 바뀝니다. 제목 크기도 함께 커집니다. 즉, 미디어 쿼리 하나로도 꽤 자연스러운 반응형 섹션을 만들 수 있다는 뜻입니다.

반응형을 보는 눈 키우기

이제부터 웹페이지를 볼 때 이런 식으로 관찰해 보세요.

  • 이 사이트는 메뉴 방향을 어디서 바꿀까?

  • 카드 개수는 어느 순간 줄어들까?

  • 본문 폭은 어디까지 허용할까?

  • 작은 화면에서 버튼은 더 커질까, 더 넓어질까?

이런 질문을 하며 사이트를 보면, 반응형은 갑자기 훨씬 현실적인 기술로 느껴집니다. 단순히 @media 문법을 외우는 것보다 훨씬 도움이 됩니다.

이번 장의 핵심

반응형의 출발점은 복잡하지 않습니다.

  • meta viewport를 넣는다.

  • 기본 스타일은 작은 화면 기준으로 만든다.

  • 화면이 넓어질 때 필요한 변화만 @media로 추가한다.

  • 중단점은 기기 이름보다 콘텐츠가 불편해지는 시점에 맞춘다.

  • 레이아웃뿐 아니라 글자, 간격, 이미지도 함께 본다.

결국 반응형은 "화면이 달라져도 같은 정보를 편하게 전달하는 방법"입니다. 같은 내용을 억지로 줄이는 것이 아니라, 그 화면에 맞는 더 좋은 정리 방식을 찾아 주는 것이죠.

다음 장에서는 이렇게 만든 레이아웃 안에서 자주 만나는 요소들, 즉 링크, 리스트, 이미지, 버튼, 폼을 더 실용적으로 꾸미는 방법을 배워 보겠습니다.

참고

1Using media queries - CSS | MDN

2Responsive design - Learn web development | MDN

3Responsive web design basics

4Responsive images - Learn web development | MDN

5View and change CSS | Chrome DevTools

책 목록

처음부터 끝까지 배우는 CSS 기초

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기