노트

반응형 웹 디자인

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 속성으로 늦춘다
  • 비율을 지키는 박스는 비율을 유지하는 박스 참고

반응형 글자 크기

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쯤으로 가정하고 축소해서 그렸다. 이 태그가 없으면 지금도 그렇게 그려서 미디어 쿼리가 의도대로 동작하지 않는다. 반응형 페이지에는 항상 넣는다.

출처: MDN — Responsive design

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 레이아웃 스래싱

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

  • Flexbox와 Grid 비교

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

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

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

  • 사용자 수에 따른 규모 확장

    사용자가 늘어날 때 서버 한 대짜리 시스템을 단계적으로 키워 가는 전형적인 경로. 처음부터 다 갖추는 게 아니라, 병목이 보일 때마다 한 단계씩 더한다(galls-law).

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

보기 옵션