목록으로
CSS

반응형 웹 디자인 실전 기법

모바일부터 데스크톱까지 모든 화면에서 잘 보이는 웹을 만드는 방법을 알아봅니다.

반응형 디자인은 하나의 코드베이스로 모든 화면 크기를 지원하는 접근 방식입니다. 모바일 사용자가 절반 이상인 현재, 반응형은 선택이 아닌 필수입니다.

모바일 우선 설계

작은 화면부터 디자인하고, 큰 화면으로 확장합니다.

/* 기본 스타일 (모바일) */
.container {
  padding: 16px;
}

/* 태블릿 이상 */
@media (min-width: 768px) {
  .container {
    padding: 24px;
  }
}

/* 데스크톱 이상 */
@media (min-width: 1024px) {
  .container {
    padding: 32px;
    max-width: 1200px;
    margin: 0 auto;
  }
}

미디어 쿼리 브레이크포인트

/* 일반적인 브레이크포인트 */
@media (min-width: 640px) { }  /* sm: 모바일 가로 */
@media (min-width: 768px) { }  /* md: 태블릿 */
@media (min-width: 1024px) { } /* lg: 작은 데스크톱 */
@media (min-width: 1280px) { } /* xl: 데스크톱 */
@media (min-width: 1536px) { } /* 2xl: 큰 데스크톱 */

유연한 레이아웃

상대 단위 사용

/* 고정 값 대신 상대 값 */
.container {
  /* width: 1200px; */
  width: 100%;
  max-width: 75rem;
  padding: 0 1rem;
}

/* 폰트 크기 */
.title {
  /* font-size: 32px; */
  font-size: clamp(1.5rem, 4vw, 2.5rem);
}

clamp() 함수

최소값, 선호값, 최대값을 지정합니다.

.title {
  /* 최소 24px, 화면의 5%, 최대 48px */
  font-size: clamp(1.5rem, 5vw, 3rem);
}

.container {
  /* 최소 300px, 화면의 90%, 최대 1200px */
  width: clamp(300px, 90%, 1200px);
}

반응형 그리드

/* CSS Grid로 반응형 카드 */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}

/* Flexbox로 반응형 */
.flex-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.flex-item {
  flex: 1 1 300px; /* 최소 300px, 늘어날 수 있음 */
}

반응형 이미지

<!-- 기본 반응형 이미지 -->
<img
  src="image.jpg"
  alt="설명"
  style="max-width: 100%; height: auto;"
/>

<!-- 해상도별 이미지 -->
<img
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w
  "
  sizes="
    (max-width: 600px) 100vw,
    (max-width: 1200px) 50vw,
    33vw
  "
  alt="설명"
/>

<!-- 아트 디렉션 -->
<picture>
  <source media="(min-width: 1024px)" srcset="desktop.jpg" />
  <source media="(min-width: 768px)" srcset="tablet.jpg" />
  <img src="mobile.jpg" alt="설명" />
</picture>

반응형 타이포그래피

:root {
  /* 베이스 폰트 크기를 뷰포트에 맞게 조절 */
  font-size: calc(14px + 0.25vw);
}

/* 또는 각 요소별로 clamp 사용 */
h1 { font-size: clamp(2rem, 5vw, 4rem); }
h2 { font-size: clamp(1.5rem, 4vw, 3rem); }
h3 { font-size: clamp(1.25rem, 3vw, 2rem); }
p { font-size: clamp(1rem, 2vw, 1.125rem); }

반응형 네비게이션

/* 모바일: 햄버거 메뉴 */
.nav-menu {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: white;
  flex-direction: column;
  padding: 2rem;
}

.nav-menu.open {
  display: flex;
}

.hamburger {
  display: block;
}

/* 데스크톱: 가로 메뉴 */
@media (min-width: 768px) {
  .nav-menu {
    display: flex;
    position: static;
    flex-direction: row;
    padding: 0;
    gap: 2rem;
  }

  .hamburger {
    display: none;
  }
}

컨테이너 쿼리

부모 요소 크기에 따라 스타일을 변경합니다.

.card-container {
  container-type: inline-size;
}

.card {
  display: block;
}

@container (min-width: 400px) {
  .card {
    display: flex;
  }
}

테스트 방법

1. 브라우저 개발자 도구의 반응형 모드
2. 실제 디바이스 테스트 (가능하다면)
3. 320px ~ 1920px 범위에서 확인
4. 가로/세로 모드 전환 테스트
5. 폰트 크기 확대 테스트 (접근성)

마무리

반응형 디자인의 핵심은 유연함입니다. 고정값 대신 상대값을 사용하고, 콘텐츠가 자연스럽게 흐르도록 합니다.

모바일 우선으로 시작하면 불필요한 스타일을 줄일 수 있고, 핵심 콘텐츠에 집중할 수 있습니다.