CSS 강좌 / 미디어 쿼리와 콘텐츠 기준 분기점 만들기
미디어 쿼리(media query)는 뷰포트 폭 등 환경 조건이 맞을 때 CSS 규칙을 적용하는 기능입니다. 기본 배치를 좁은 화면에 맞춰 만들고, 콘텐츠가 여러 열로 들어갈 공간이 확보될 때만 열 수를 늘리는 방식으로 사용하면 됩니다. 분기점은 특정 기기의 이름보다 실제 내용이 읽히는 폭을 기준으로 선택합니다.
기본 스타일과 조건부 스타일의 관계
미디어 쿼리 밖의 선언은 모든 화면의 기본값입니다. 조건 안에 들어간 선언은 조건이 참일 때 CSS 적용 후보에 추가됩니다. 폭이 커졌다고 기본값이 없어지는 것이 아니라, 같은 속성에 대한 선언들이 캐스케이드 규칙에 따라 함께 평가됩니다.
.cards { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 33rem) {
.cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
여기서는 같은 선택자를 쓰고 작은 분기점을 먼저 배치했으므로 뒤의 조건부 선언이 해당 속성을 덮어씁니다. 모든 경우에 “아래 코드가 무조건 이긴다”고 일반화하면 안 됩니다. 중요도, 캐스케이드 레이어와 선택자의 우선순위 등이 같을 때 선언 순서를 비교합니다. 조건이 맞는데 변화가 없다면 개발자 도구에서 다른 규칙에 취소선이 생기는지도 확인하세요.
카드의 내용으로 분기점 계산하기
먼저 한 장의 카드가 읽기 어려워지기 시작하는 폭을 확인합니다. 실습에서는 카드의 테두리·안쪽 여백을 포함한 최소 폭 목표를 16rem으로 정합니다. 이것은 모든 사이트에 맞는 표준값이 아니라 이 예제의 디자인 조건입니다. 긴 제목과 설명을 넣어 보고 실제 글꼴과 내용에 맞춰 바꿔야 합니다.
두 열에 필요한 콘텐츠 폭은 16rem×2에 열 간격 1rem을 더한 33rem입니다. 본문 좌우 안쪽 여백이 각각 1rem이면 필요한 뷰포트 폭은 35rem입니다. 따라서 이 강의의 전체 예제에서는 두 열 시작점을 35rem으로 정합니다. 세 열은 16rem×3 + 간격 1rem×2 + 좌우 여백 2rem으로 52rem이 필요합니다.
| 열 수 | 카드 합계 | 열 간격 합계 | 좌우 여백 | 분기점 |
|---|---|---|---|---|
| 1열 | 폭에 맞춰 줄어듦 | 0 | 2rem | 기본값 |
| 2열 | 32rem | 1rem | 2rem | 35rem |
| 3열 | 48rem | 2rem | 2rem | 52rem |
카드 내부의 여백을 표 계산에 다시 더하지 않는 이유는 최소 폭 목표 16rem에 이미 포함했기 때문입니다. 반대로 본문이 사이드바와 폭을 나누면 뷰포트만으로 카드 공간을 보장하기 어렵습니다. 그럴 때는 바깥 레이아웃 조건을 다시 계산하거나, 부품 내부 배치를 컨테이너 쿼리로 판단하는 방법을 검토합니다.
rem 조건과 경계값 읽기
min-width는 지정한 폭과 같거나 클 때, max-width는 같거나 작을 때 성립합니다. 초기 글꼴 크기가 16px이면 35rem은 560px, 52rem은 832px입니다. 사용자나 브라우저의 초기 글꼴 설정에 따라 환산 값이 달라질 수 있으므로 rem을 항상 고정된 px 값처럼 설명하지 않습니다.
미디어 쿼리의 상대 길이는 페이지 CSS로 바뀐 글꼴 크기가 아닌 초기 값을 사용합니다. 예를 들어 CSS에 html { font-size: 32px; }를 추가했다고 35rem 조건이 자동으로 1120px 조건이 되는 것은 아닙니다. 본문의 rem 크기 변화와 미디어 조건 변화는 구분해야 합니다. CSS 미디어 쿼리 명세의 단위 기준에 이 원칙이 설명되어 있습니다.
/* 560px에서도 두 조건이 모두 성립합니다. */
@media (max-width: 560px) { /* 좁은 화면 규칙 */ }
@media (min-width: 560px) { /* 넓은 화면 규칙 */ }
위와 같이 경계가 같은 최소·최대 조건은 일치 지점에서 겹칩니다. 기본값과 최소 폭 조건을 단계적으로 추가하면 이 문제를 줄일 수 있습니다. 두 열과 세 열 조건도 넓은 화면에서 모두 참이지만, 전체 예제처럼 같은 선택자와 같은 속성을 사용하고 세 열 규칙을 나중에 적으면 의도한 단계가 만들어집니다.
전체 예제: 1열에서 2열과 3열로 확장하기
media-breakpoint.html 파일로 저장해 브라우저에서 여세요. 외부 파일은 필요 없습니다. 제목과 링크가 포함된 카드 세 장을 배치하고, 긴 문자열도 넣어 글이 조금 길어져도 읽을 수 있게 했습니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>media-breakpoint.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 70rem); margin-inline: auto; padding: 1rem; }
.cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; }
.card { min-width: 0; padding: 1rem; border: 1px solid #789; background: #eef5fa; overflow-wrap: anywhere; }
.card h2 { font-size: 1.25rem; } .card a { display: inline-block; padding: .5rem; }
@media (min-width: 35rem) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 52rem) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
</style>
</head>
<body>
<main class="content"><h1>콘텐츠 기준으로 분기점 정하기</h1>
<p>이 실습의 카드 최소 폭 목표는 테두리와 안쪽 여백을 포함해 16rem입니다.</p>
<div class="cards">
<article class="card"><h2>작업 전 준비할 파일과 화면 설정</h2><p>제목이 여러 줄이 되더라도 설명과 링크가 자연스럽게 아래로 이어져야 합니다.</p><a href="#result">첫 번째 설명 확인</a></article>
<article class="card"><h2>화면이 좁을 때의 선택</h2><p>무조건 글자를 줄이기보다 열 수를 줄여 필요한 공간을 확보합니다.</p><a href="#result">두 번째 설명 확인</a></article>
<article class="card"><h2>영문 식별자</h2><p>ARTICLE_REFERENCE_WITHOUT_SPACES_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p><a href="#result">세 번째 설명 확인</a></article>
</div><p id="result">링크와 키보드 포커스가 화면 안에서 보이는지 확인하세요.</p></main>
</body>
</html>
minmax(0, 1fr)과 카드의 최소 폭 해제는 긴 콘텐츠 때문에 열이 화면 밖으로 커지는 것을 막습니다. 다만 글자만 억지로 맞추기보다 먼저 열 수를 줄이는 것이 이 예제의 목적입니다. 본문 최대 폭 70rem에서는 열이 계속 끝없이 넓어지지 않고 카드 세 장이 남은 공간을 나눕니다.
경계 앞뒤에서 결과 비교하기
- 초기 글꼴 크기가 16px인 환경에서 559px, 560px, 561px를 비교합니다. 559px는 1열, 560px부터 2열이어야 합니다.
- 831px, 832px, 833px를 비교합니다. 831px는 2열, 832px부터 3열이어야 합니다. 정확히 분기점에 도달했을 때도 카드 폭이 16rem 이상인지 확인합니다.
- 두 열 분기점만 35rem에서 30rem으로 바꿉니다. 480px에서 카드 폭이 목표보다 작아지고 제목 줄 수가 늘어나는지 관찰한 뒤 35rem으로 복구합니다.
- 브라우저 기본 글꼴 설정을 크게 바꾼 조건과 CSS의 html 글꼴만 바꾼 조건을 각각 기록합니다. 같은 실험으로 취급하지 말고 각 조건에서 폭과 카드 배치를 다시 확인합니다.
반응형 조건에는 폭 외에도 방향, 입력 장치, 동작 감소 선호 등이 있습니다. 그러나 화면이 좁다는 이유만으로 터치 장치라고 가정하거나, 넓다는 이유로 마우스가 있다고 단정하면 안 됩니다. 이 강의에서는 폭에 따른 배치를 먼저 완성하고, 다른 조건은 해당 기능에 필요한 상황에서 추가합니다. 문법과 환경 조건은 MDN의 미디어 쿼리 사용 안내에서 확인할 수 있습니다.










