✏️ 공부기록/CSS

rem 기반 반응형 설계

서카츄 2024. 10. 15. 22:11

 

 

 

rem 기반으로 전체 레이아웃 스케일 조절하기

 

CSS에서 폰트 크기, 여백, 너비 같은 값들을 전부 px로만 관리하다 보면,

반응형 디자인에서 한번에 전체 비율을 줄이고 늘리는 것이 어렵습니다.

 

오늘은 remhtml { font-size: ... } 설정을 활용해서,

“기준 값만 바꿔도 모든 요소가 비율에 맞게 함께 줄어드는 구조”를 만드는 방법을 정리해보려고 합니다.

 


 

1. rem, em, px 간단 정리

 

 

1-1. px

.title {
  font-size: 16px;
}

 

  • 화면의 물리적인 픽셀 기준(요즘은 논리 픽셀이지만, 어쨌든 고정값)
  • 계산은 쉽지만, 사용자 기본 폰트 크기 변경이나 확대/축소와의 연동이 떨어질 수 있음
  • 반응형에서 크기를 전부 다시 지정해야 해서 유지보수가 힘들어짐

 


 

1-2. em

.container {
  font-size: 16px;
}

.text {
  font-size: 1.5em; /* 부모(.container)의 1.5배 → 24px */
}

 

  • 부모 요소의 font-size 기준으로 배율이 결정
  • 장점: 상대적인 크기 조절이 가능
  • 단점: 중첩 구조에서 누적 계산이 됩니다.
.parent {
  font-size: 16px;
}

.child {
  font-size: 1.5em; /* 24px */
}

.grand-child {
  font-size: 1.5em; /* 24px의 1.5배 → 36px */
}

 

  • 이런 식으로 예상보다 값이 커지거나 작아져서, 큰 프로젝트에서는 관리가 어려울 수 있음

 


 

1-3. rem

.title {
  font-size: 1.6rem;
}

 

  • 항상 루트 요소(html)의 font-size를 기준으로 계산
  • 부모가 뭐든 상관없이, html에 지정한 값만 잘 관리하면 전체가 일정한 비율로 움직임
  • 중첩되어도 누적되지 않아 계산이 단순해짐

 


 

2. 왜 html { font-size: 62.5% }를 쓸까?

 

브라우저 기본 글꼴 크기는 대개 16px입니다.

여기에 62.5%를 곱하면:

16px × 62.5% = 10px

즉, 1rem = 10px으로 맞출 수 있습니다.

이렇게 되면 계산이 아주 간단해집니다.

html {
  font-size: 62.5%; /* 1rem = 10px */
}

.image {
  width: 12rem;    /* 120px */
}

.item {
  font-size: 1.6rem; /* 16px */
}

.copyright {
  margin-top: 5rem;  /* 50px */
}

 

  • 12rem120px
  • 1.6rem16px
  • 5rem50px

 

**“0 하나만 붙이면 px로 얼마인지 바로 보이는 구조”**라서

개발하면서 머리로 계산하기가 편해집니다.

 


 

3. 미디어쿼리 + rem으로 전체 레이아웃 축소/확대하기

 

위의 코드는 아직 “반응형”은 아닙니다.

핵심은 미디어쿼리에서 html의 font-size만 바꿔주면,

rem으로 지정한 모든 값이 한 번에 같이 줄어든다는 점입니다.

 

예시:

/* 기본: 데스크탑 / 태블릿 기준 */
html {
  font-size: 62.5%; /* 1rem = 10px */
}

.image {
  width: 12rem;        /* 120px */
}

.item {
  font-size: 1.6rem;   /* 16px */
}

.copyright {
  margin-top: 5rem;    /* 50px */
}

/* 750px 이하: 모바일 레이아웃 */
@media all and (max-width: 750px) {
  html {
    font-size: 50%; /* 1rem = 8px */
  }
}

이제 화면 너비가 750px 이하가 되는 순간:

 

  • 1rem = 8px이 됩니다.
  • 기존에 rem으로 지정한 값들이 일괄적으로 축소됩니다.

요소데스크탑 (1rem=10px)모바일 (1rem=8px)

.image 12rem = 120px 12rem = 96px
.item 1.6rem = 16px 1.6rem = 12.8px
.copyright 5rem = 50px 5rem = 40px

폰트 사이즈, 이미지, 여백 등 모든 값이 같은 비율로 작아지기 때문에,

“모바일 전용 사이즈를 하나하나 다시 지정하지 않아도 되는” 효과를 얻을 수 있습니다.

 


 

4. 실제 컴포넌트 예시

 

실제 UI 예제를 하나 만들어 보면 다음과 같습니다.

<body>
  <header class="header">
    <h1 class="logo">My App</h1>
    <button class="cta">시작하기</button>
  </header>

  <main class="hero">
    <img class="hero-image" src="..." alt="hero" />
    <div class="hero-text">
      <h2>스토리 기반 감성 경매 플랫폼</h2>
      <p>입찰과 사연이 함께 쌓이는 새로운 경험을 만들어보세요.</p>
    </div>
  </main>
</body>
/* =========================
   1. 기본 설정
   ========================= */
html {
  font-size: 62.5%; /* 1rem = 10px */
}

body {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  margin: 0;
  padding: 0;
  background: #f4f4f7;
  color: #1f1f25;
}

/* =========================
   2. 레이아웃 & 타이포
   ========================= */
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2rem 3rem;     /* 20px 30px */
  background: #ffffff;
  box-shadow: 0 0.2rem 0.4rem rgba(0, 0, 0, 0.05); /* 2px 4px */
}

.logo {
  font-size: 2.4rem;      /* 24px */
  font-weight: 700;
}

.cta {
  padding: 1rem 2rem;     /* 10px 20px */
  font-size: 1.4rem;      /* 14px */
  border-radius: 999rem;
  border: none;
  cursor: pointer;
  background: #a3bce5;
  color: #ffffff;
}

.hero {
  display: flex;
  align-items: center;
  gap: 4rem;               /* 40px */
  padding: 5rem 3rem;      /* 50px 30px */
}

.hero-image {
  width: 24rem;            /* 240px */
  border-radius: 1.6rem;   /* 16px */
}

.hero-text h2 {
  font-size: 3rem;         /* 30px */
  margin-bottom: 1.6rem;   /* 16px */
}

.hero-text p {
  font-size: 1.6rem;       /* 16px */
  line-height: 1.6;
}

/* =========================
   3. 반응형 (모바일)
   ========================= */
@media all and (max-width: 750px) {
  html {
    font-size: 50%; /* 1rem = 8px */
  }

  .header {
    padding: 1.5rem 2rem;  /* 12px 16px (기본 대비 축소) */
  }

  .hero {
    flex-direction: column;
    align-items: flex-start;
    padding: 3rem 2rem;    /* 24px 16px */
    gap: 2rem;             /* 16px */
  }

  .hero-image {
    width: 20rem;          /* 160px */
  }
}

여기서 주목해야 할 점:

 

  1. 모든 크기를 rem으로 통일
  2. 미디어쿼리에서는 대부분의 컴포넌트 스타일을 건들지 않고,
  3. 레이아웃 방향(flex-direction) 정도만 바꾸고 있음
  4. 실제 크기 축소는 html { font-size: 50%; } 한 줄로 거의 해결

 


 

5. 이 방식의 장점과 단점

 

 

장점

 

  1. 유지보수 용이
    • 한 화면에서 여러 요소의 크기를 조정해야 할 때,
    • html의 font-size만 조절해 비율을 맞출 수 있습니다.
  2. 일관된 크기 체계
    • “1rem = 10px” 구조로 통일하면, 팀원들끼리도 숫자만 보고 감이 잘 맞습니다.
  3. 중첩에 강함
    • rem은 항상 루트 기준이라, 복잡한 컴포넌트 구조에서도 값이 예측 가능합니다.

 

 

단점 / 주의점

 

  1. 사용자 기본 폰트 크기 무시 이슈
    • 브라우저 기본 글꼴 크기에 의존하는 사용자(시력이 좋지 않아서 크게 설정한 경우 등)에게는
    • 이 방식이 기본 설정을 일부 덮어쓸 수 있다는 지적이 있습니다.
    • 접근성을 강하게 고려한다면 html { font-size: 100%; } 유지 + clamp() 활용도 많이 사용합니다.
  2. 디자인 시안과의 싱크
    • 디자이너가 Figma 등에서 px 단위로 주는 경우,
    • 실제 구현에서는 rem 값으로 변환하는 규칙(10px = 1rem)을 팀 내에서 합의해야 합니다

 


 

6. 정리

 

  • rem루트 폰트 크기를 기준으로 하는 상대 단위이다.
  • html { font-size: 62.5%; }로 설정하면
  • 1rem = 10px이 되어 계산이 쉬워진다.
  • 요소 크기를 모두 rem으로 통일해두면,
  • 미디어쿼리에서 html의 font-size만 변경해도 전체 레이아웃 비율을 한 번에 조정할 수 있다.
  • 접근성과 팀 규칙을 고려해,
  • 62.5% 방식 / 100% + clamp() 방식 중 프로젝트에 맞는 방식을 선택하면 된다.

 

이렇게 설정해 두면 “폰트, 여백, 이미지 크기를 한 번에 스케일링” 할 수 있어서,

반응형 UI를 만들 때 훨씬 편하게 레이아웃을 관리할 수 있다.

 

'✏️ 공부기록 > CSS' 카테고리의 다른 글

모바일 비율 계산 사진 한장 정리  (0) 2025.12.10
Tailwind prettier 플러그인 추가하기  (0) 2025.06.21
clamp 속성  (0) 2024.09.15
Tailwind CSS divide-y 속성  (0) 2024.09.06
Next SCSS 설치와 가이드  (0) 2024.08.20