노트

반응형 웹 디자인

Responsive Web Design

프론트엔드#css#html · 연결된 개념 4개

쉽게 말하면

반응형 웹 디자인은 물이 그릇 모양에 맞춰 채워지듯, 한 페이지가 휴대폰부터 큰 모니터까지 화면 크기에 맞춰 레이아웃과 이미지, 글자 크기를 바꾸게 만드는 거예요. 기기마다 페이지를 따로 만들 필요가 없어요.

비유의 한계 물처럼 저절로 맞춰지진 않아요. 뷰포트 메타 태그가 없으면 휴대폰이 980px쯤의 데스크톱 화면을 가정하고 축소해 그려서, 미디어 쿼리가 의도대로 동작하지 않아요.

하나의 페이지가 화면 크기와 기기에 맞춰 레이아웃·이미지·글자 크기를 바꾸도록 만드는 접근. 미디어 쿼리(Media Query), 유연한 레이아웃(Flexible Layout), 반응형 미디어(Responsive Media)가 세 축이다.

미디어 쿼리와 모바일 우선

  • 레이아웃이 바뀌는 지점을 브레이크포인트(Breakpoint)라고 한다. 특정 기기 크기보다 콘텐츠가 깨지는 지점을 기준으로 정한다
  • 모바일 우선(Mobile First): 좁은 화면용 단일 열 레이아웃을 기본으로 쓰고, min-width 미디어 쿼리로 넓은 화면에서 열을 늘린다. 작은 화면에서는 넓은 화면용 규칙이 적용되지 않으니 덮어쓸 일이 줄어든다

유연한 레이아웃

  • Flexbox는 공간에 따라 아이템을 늘리고 줄인다
  • CSS Grid의 fr과 repeat(auto-fit, minmax())는 미디어 쿼리 없이도 열 수를 바꾼다
  • 다단 레이아웃(Multi-column Layout, columns)은 글을 신문처럼 여러 열로 흘린다

반응형 미디어

  • img, picture, video { max-width: 100%; }로 컨테이너를 넘지 않게 한다
  • srcset·sizes나 picture 요소로 화면 크기·해상도에 맞는 이미지 파일을 고르게 한다. 화면 밖 이미지는 loading 속성으로 늦춘다
  • 비율을 지키는 박스는 비율을 유지하는 박스 참고

srcset·sizes 읽는 법

<img
  src="/photo-800.jpg"
  srcset="/photo-400.jpg 400w, /photo-800.jpg 800w, /photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 50vw"
  alt="사진" />
  • 400w의 w는 CSS 너비가 아니라 이미지 파일의 실제 픽셀 너비다
  • sizes는 이미지가 화면에서 차지할 너비(슬롯)를 알려 준다. 앞에서부터 검사해 처음 맞는 조건을 쓰고, 조건 없는 마지막 값이 기본값이다. sizes를 빼면 100vw로 간주해 필요보다 큰 파일을 받을 수 있다
  • 브라우저는 후보 너비를 슬롯 너비로 나눠 밀도로 바꾼 뒤 화면에 맞는 것을 고를 수 있다. 뷰포트 1200px에서 슬롯은 50vw = 600px이고, 1200w ÷ 600px = 2x라서 기기 픽셀 비율(Device Pixel Ratio, DPR)이 2인 화면이면 photo-1200.jpg가 맞는다. 최종 선택은 브라우저 재량이다
  • 늘 같은 CSS 크기로 보이고 해상도만 다르면 srcset="logo.png, logo@2x.png 2x"처럼 x 디스크립터를 쓰고 sizes는 생략한다. 한 srcset에 w와 x를 섞으면 안 된다
  • 화면에 따라 잘라 낸 구도 자체를 바꾸는 아트 디렉션(Art Direction)은 <picture>의 <source media>로 한다

반응형 글자 크기

font-size: 6vw처럼 뷰포트 단위(Viewport Units)만 쓰면 사용자가 확대해도 글자가 안 커진다. calc(1.5rem + 3vw)처럼 rem 값에 vw를 더하거나 clamp()로 범위를 둔다.

뷰포트 메타 태그(Viewport Meta Tag)

<meta name="viewport" content="width=device-width, initial-scale=1" />

초기 스마트폰 브라우저는 데스크톱용 사이트를 보여 주려고 뷰포트를 980px쯤으로 가정하고 축소해서 그렸다. 이 태그가 없으면 지금도 그렇게 그려서 미디어 쿼리가 의도대로 동작하지 않는다. 반응형 페이지에는 항상 넣는다.

명세: HTML Standard — normalise the source densities

출처: MDN — Responsive design · MDN — Responsive images: 다른 크기 · MDN — Responsive images: 아트 디렉션 · MDN — img sizes

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 레이아웃 스래싱

    DOM을 바꾸고 곧바로 레이아웃 값을 읽기를 반복해서, 브라우저가 매번 리플로우를 강제로 실행하게 되는 현상. 쓰기 → 읽기 → 쓰기 → 읽기가 반복문 안에서 일어나면 요소 수만큼 레이아웃을 계산한다.

  • Flexbox와 Grid 비교

    flexbox는 한 방향으로 흐르는 1차원 배치, css-grid는 행과 열을 함께 다루는 2차원 배치다. 크기를 누가 정하느냐도 다르다. flex는 아이템과 콘텐츠가, grid는 컨테이너의 트랙이 정한다.

  • 리플로우(레이아웃 재계산)

    요소의 크기나 위치가 바뀌어 브라우저가 레이아웃을 다시 계산하는 일. 렌더링 파이프라인에서 대개 가장 비싼 단계이고, 리플로우가 일어나면 뒤따라 페인트와 합성도 다시 한다.

  • CSS 박스 모델

    브라우저는 모든 요소를 사각형 상자로 보고, 그 상자를 안쪽부터 콘텐츠(content) → 안쪽 여백(padding) → 테두리(border) → 바깥 여백(margin) 네 겹으로 계산한다. 레이아웃에서 요소가 차지하는 크기와 요소 사이 간격이 모두 이 네 겹에서 나온다.

  • 번들 크기 줄이기

    번들 다이어트는 사용자가 내려받는 JavaScript 양을 측정하고 줄이는 작업이다. 같은 용량이라도 JS는 이미지보다 비싸다. 이미지는 다운로드와 디코딩만 하면 되지만, JS는 다운로드·파싱·컴파일·실행을 모두 거친다.

보기 옵션