
rem 기반으로 전체 레이아웃 스케일 조절하기
CSS에서 폰트 크기, 여백, 너비 같은 값들을 전부 px로만 관리하다 보면,
반응형 디자인에서 한번에 전체 비율을 줄이고 늘리는 것이 어렵습니다.
오늘은 rem과 html { 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 */
}
- 12rem → 120px
- 1.6rem → 16px
- 5rem → 50px
**“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 */
}
}
여기서 주목해야 할 점:
- 모든 크기를 rem으로 통일
- 미디어쿼리에서는 대부분의 컴포넌트 스타일을 건들지 않고,
- 레이아웃 방향(flex-direction) 정도만 바꾸고 있음
- 실제 크기 축소는 html { font-size: 50%; } 한 줄로 거의 해결
5. 이 방식의 장점과 단점
장점
- 유지보수 용이
- 한 화면에서 여러 요소의 크기를 조정해야 할 때,
- html의 font-size만 조절해 비율을 맞출 수 있습니다.
- 일관된 크기 체계
- “1rem = 10px” 구조로 통일하면, 팀원들끼리도 숫자만 보고 감이 잘 맞습니다.
- 중첩에 강함
- rem은 항상 루트 기준이라, 복잡한 컴포넌트 구조에서도 값이 예측 가능합니다.
단점 / 주의점
- 사용자 기본 폰트 크기 무시 이슈
- 브라우저 기본 글꼴 크기에 의존하는 사용자(시력이 좋지 않아서 크게 설정한 경우 등)에게는
- 이 방식이 기본 설정을 일부 덮어쓸 수 있다는 지적이 있습니다.
- 접근성을 강하게 고려한다면 html { font-size: 100%; } 유지 + clamp() 활용도 많이 사용합니다.
- 디자인 시안과의 싱크
- 디자이너가 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 |