Tailwind CSS - 반응형 디자인

김명원·2025년 1월 17일

learnTailwindCSS

목록 보기
4/10

Tailwind CSS - 반응형 디자인

반응형 디자인

데스크탑, 태블릿, 모바일 등 다양한 기기에서 웹사이트 기기의 화면 크기에 맞춰 자동으로 레이아웃을 조정하는 방법
어떤 기기를 사용하든 최적의 경험을 제공받을 수 있도록 합니다.


Tailwind CSS에서 반응형 디자인

Tailwind CSS는 미디어 쿼리를 사용하지 않고, 미리 정의된 브레이크포인트 유틸리티를 통해 손쉽게 반응형 디자인을 구현합니다.

PrefixMinimum WidthMedia QueryDescription
sm640px@media (min-width: 640px) {}최소 640px 이상 부터 sm 사이즈!
md768px@media (min-width: 768px) {}최소 768px 이상 부터 md 사이즈!
lg1024px@media (min-width: 1024px) {}최소 1024px 이상 부터 lg 사이즈!
xl1280px@media (min-width: 1280px) {}최소 1280px 이상 부터 xl 사이즈!
2xl1536px@media (min-width: 1536px) {}최소 1536px 이상 부터 2xl 사이즈!

브레이크포인트란, 웹사이트가 화면 크기에 따라 레이아웃이나 스타일을 변경해야 할 때 설정하는 기준이 되는 화면 너비입니다.

커스텀 브레이크포인트 설정

Tailwind CSS는 기본적으로 제공되는 브레이크포인트 외에도 사용자가 필요에 따라 커스텀 브레이크포인트를 추가할 수 있습니다.
위 방법을 통해 웹사이트에 맞는 맞춤형 반응형 디자인을 구성할 수 있습니다.

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    screens: {
      'tablet': '640px',   // 640px 이상일 때 적용
      'laptop': '1024px',  // 1024px 이상일 때 적용
      'desktop': '1280px', // 1280px 이상일 때 적용
    },
  }
}

Mobile-first (모바일 우선 접근 방식)

Tailwind CSS는 모바일 우선 접근 방식을 사용합니다.
이는 브레이크포인트가 없는 기본 유틸리티가 모바일 장치부터 모든 화면 크기에 적용된다는 뜻입니다.
이후, 더 큰 화면에서는 브레이크포인트 접두어를 붙여 화면 크기에 따라 스타일을 조정할 수 있습니다.

<div class="text-center sm:text-left">
  <p>모바일에서는 텍스트가 중앙 정렬되고, 큰 화면에서는 좌측 정렬됩니다.</p>
</div>
  • 이 코드에서는 text-center 클래스가 모든 화면 크기에서 텍스트를 중앙에 정렬하는 기본 스타일입니다.
  • sm:text-left는 화면이 640px 이상일 때(작은 화면 이상) 텍스트를 좌측 정렬하도록 합니다.

설명

  • 모바일 우선: Tailwind는 기본적으로 모든 화면에 적용되는 스타일을 먼저 설정하고, 더 큰 화면에서는 브레이크포인트를 통해 스타일을 덮어씁니다.
  • 즉, 브레이크포인트를 적용하지 않은 유틸리티는 모바일 장치부터 모든 화면 크기에 기본적으로 적용됩니다.
  • 이후 더 큰 화면에서는 sm, md, lg와 같은 브레이크포인트를 통해 추가 스타일을 지정할 수 있습니다.

브레이크포인트 범위 타겟팅

Tailwind CSS에서는 특정 화면 크기 범위 내에서만 스타일을 적용하고 싶을 때, 브레이크포인트와 max-* 수정자를 함께 사용할 수 있습니다.

<div class="md:max-2xl:flex"> 
  <!-- 이 요소는 중간 크기 화면에서만(2xl 미만!) flex로 적용됩니다. -->
</div>

설명

  • md:max-xl:flex는 화면 크기가 768px 이상 이면서 1280px 이하인 경우에만 flex가 적용됩니다.
  • 중간 크기(768px)부터 큰 화면(1280px 이하)까지만 해당 스타일이 적용 됩니다.

반응형 디자인 실습

마크업 (반응형 적용 전)

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Position - sticky</title>
    <script src="https://cdn.tailwindcss.com"></script>
  </head>
  <body>
    <header class="fixed left-0 right-0 bg-gray-800 text-white p-4 z-50">
      <nav class="container mx-auto flex justify-between items-center">
        <div class="text-2xl font-bold">MyShop</div>
        <ul class="flex space-x-4">
          <li><a href="#" class="hover:underline">Home</a></li>
          <li><a href="#" class="hover:underline">Products</a></li>
          <li><a href="#" class="hover:underline">Contact</a></li>
        </ul>
      </nav>
    </header>
    <main class="container max-w-5xl mx-auto px-4 pb-8 pt-24 flex gap-x-4">
      <section class="w-3/5">
        <div class="grid grid-cols-2 gap-4">
          <img
            src="https://via.placeholder.com/400x400.png?text=City"
            alt="City Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Landscape"
            alt="Landscape Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Mountain"
            alt="Mountain Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=River"
            alt="River Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Forest"
            alt="Forest Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Ocean"
            alt="Ocean Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Desert"
            alt="Desert Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Waterfall"
            alt="Waterfall Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Beach"
            alt="Beach Image"
            class="w-full h-full rounded-lg shadow-md"
          />
        </div>
      </section>
      <aside class="w-2/5">
        <div class="sticky top-16 p-6 border-2 border-gray-800 rounded-lg">
          <h2 class="text-xl font-bold mb-4">장바구니</h2>
          <div class="space-y-2">
            <div class="flex justify-between">
              <span>상품 1</span>
              <span>₩ 10,000</span>
            </div>
            <div class="flex justify-between">
              <span>상품 2</span>
              <span>₩ 20,000</span>
            </div>
            <div class="flex justify-between font-bold border-t pt-2">
              <span>총합계</span>
              <span>₩ 30,000</span>
            </div>
          </div>
          <button
            class="mt-4 w-full bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600"
          >
            결제하기
          </button>
        </div>
      </aside>
    </main>
  </body>
</html>

실습코드 (반응형 적용 후)

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Position - sticky</title>
    <script src="https://cdn.tailwindcss.com"></script>
  </head>
  <body>
    <header class="fixed left-0 right-0 bg-gray-800 text-white p-4 z-50">
      <nav class="container mx-auto flex justify-between items-center">
        <div class="text-2xl font-bold">MyShop</div>
        <ul class="flex space-x-4">
          <li><a href="#" class="hover:underline">Home</a></li>
          <li><a href="#" class="hover:underline">Products</a></li>
          <li><a href="#" class="hover:underline">Contact</a></li>
        </ul>
      </nav>
    </header>
    <main class="container max-w-5xl mx-auto px-4 pb-8 pt-24 flex gap-x-4 mb-[74px] sm:mb-0">
      <section class="w-full sm:w-4/6">
        <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
          <img
            src="https://via.placeholder.com/400x400.png?text=City"
            alt="City Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Landscape"
            alt="Landscape Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Mountain"
            alt="Mountain Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=River"
            alt="River Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Forest"
            alt="Forest Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Ocean"
            alt="Ocean Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Desert"
            alt="Desert Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Waterfall"
            alt="Waterfall Image"
            class="w-full h-full rounded-lg shadow-md"
          />
          <img
            src="https://via.placeholder.com/400x400.png?text=Beach"
            alt="Beach Image"
            class="w-full h-full rounded-lg shadow-md"
          />
        </div>
      </section>
      <aside class="w-2/6 hidden sm:block">
        <div class="sticky top-16 p-6 border-2 border-gray-800 rounded-lg">
          <h2 class="text-xl font-bold mb-4">장바구니</h2>
          <div class="space-y-2">
            <div class="flex justify-between">
              <span>상품 1</span>
              <span>₩ 10,000</span>
            </div>
            <div class="flex justify-between">
              <span>상품 2</span>
              <span>₩ 20,000</span>
            </div>
            <div class="flex justify-between font-bold border-t pt-2">
              <span>총합계</span>
              <span>₩ 30,000</span>
            </div>
          </div>
          <button
            class="mt-4 w-full bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600"
          >
            결제하기
          </button>
        </div>
      </aside>
    </main>
    <div class="block sm:hidden p-4 fixed bottom-0 left-0 right-0 bg-white border-t-2 border-gray-800">
      <button
        class="w-full bg-green-500 text-white py-2 px-4 rounded hover:bg-green-600"
      >
        결제하기
      </button>
    </div>
  </body>
</html>

추가 설명

  1. 마크업(반응형 적용 전)

    • sectionw-3/5, asidew-2/5로 고정된 폭 비율을 갖습니다.
    • 이미지 영역도 grid-cols-2로 고정되어, 작은 화면에서 지면이 비좁아져도 2열 유지.
    • 모바일에서 aside와 section 레이아웃이 그대로 표시될 수 있어, 사용자 경험이 다소 불편할 수 있음.
  2. 실습코드(반응형 적용 후)

    • section에서 w-full sm:w-4/6를 사용해 화면이 작으면 너비가 전체(full)로 적용되고, sm 이상에서는 4/6로 변경됩니다.
    • grid-cols-1 sm:grid-cols-2 md:grid-cols-3를 통해 브레이크포인트에 따라 열이 1, 2, 3단으로 유연하게 변화합니다.
    • asidehidden sm:block을 사용하여, 작은 화면(sm 미만)에서는 숨기고 큰 화면(sm 이상)에서 표시하게 함. 작은 화면에서는 대신 하단에 고정된 결제 버튼(.block sm:hidden)이 노출됩니다.
    • 모바일, 태블릿, PC 화면에 따라 전혀 다른 레이아웃을 보여주기 때문에 사용자 경험이 크게 개선됩니다.

결론

  • 반응형 디자인은 다양한 화면 크기에 맞게 자동으로 레이아웃이 조정되도록 하는 중요한 기술입니다.
  • Tailwind CSS에서는 브레이크포인트 유틸리티(sm, md, lg, xl, 2xl)를 통해 손쉽게 반응형 스타일을 적용할 수 있습니다.
  • 실습 코드처럼, sm:, md:를 활용해 이미지 열 수요소 가시성 등을 자유롭게 조정할 수 있어, 모바일·데스크탑 환경에서 각각 최적화된 UX를 제공할 수 있습니다.
  • 추가로 Mobile-first 접근 방식을 이해하면 더욱 일관성 있고 효율적인 반응형 레이아웃을 구성할 수 있습니다.

오늘 배운 핵심
1. 브레이크포인트와 Mobile-first: Tailwind는 기본적으로 모바일 먼저 스타일을 적용하고, 큰 화면에서는 필요한 스타일만 덧씌웁니다.
2. 반응형 유틸리티: sm:, md:, lg: 등을 붙여 용도에 따라 유연하게 레이아웃을 바꿀 수 있습니다.
3. 마크업 vs 실습코드: 코드에 sm:grid-cols-2, md:grid-cols-3, hidden sm:block 등 반응형 클래스를 추가해 화면 크기에 따른 레이아웃 변화를 쉽게 구현했습니다.

profile
개발자가 되고 싶은 정치학도생의 기술 블로그

0개의 댓글