반응형 레이아웃
고친 사람 github-actions[bot]
반응형 레이아웃은 화면 크기에 맞춰 화면 배치를 스스로 바꿉니다. 휴대폰에서는 내용을 세로로 쌓습니다. 넓은 모니터에서는 같은 내용을 옆으로 나란히 놓습니다. 크기마다 화면을 따로 만들 필요가 없어집니다.
쉽고 빠른 이해
무슨 일을 하나 — 화면 크기에 따라 배치를 바꿉니다. 휴대폰에서 한 줄에 하나씩 보이던 상품 카드가 모니터에서는 한 줄에 넷씩 보입니다.
왜 이렇게 하나 — 같은 서비스를 휴대폰, 태블릿, 노트북, 큰 모니터에서 엽니다. 한 크기에 맞춰 짜면 다른 크기에서 글이 잘리거나 빈 곳이 커집니다. 크기마다 화면을 따로 만들면 고칠 곳이 그만큼 늘어납니다.
어떻게 도나
- 글·그림·버튼 같은 요소의 너비를 고정 값 대신 화면에 대한 비율로 정합니다
- 화면이 조금 변하면 요소가 비율대로 늘고 줄어듭니다
- 미리 정한 너비를 넘으면 배치 자체를 바꿉니다. 세로로 쌓던 것을 옆으로 놓습니다
대가 — 화면 크기마다 제대로 보이는지 따로 확인해야 합니다. 작은 화면은 숨겨 둔 내용이나 큰 그림까지 그대로 내려받기도 합니다. 그만큼 데이터가 낭비됩니다.
상세
이사를 가면 같은 책을 새 책장에 다시 꽂습니다. 넓고 낮은 책장이면 한 칸에 길게 한 줄로 꽂습니다. 좁고 높은 책장이면 여러 칸에 나눠 위로 쌓습니다. 책은 바뀌지 않고 꽂는 방식만 달라집니다.
반응형 레이아웃은 화면의 내용을 이 책처럼 다룹니다. 이 절은 화면 크기가 왜 문제인지부터 봅니다. 그다음 블로그 글 페이지 하나를 예로 들어, 비율로 늘고 주는 배치와 정해진 너비에서 배치를 바꾸는 경계를 따라갑니다. 끝에서는 모바일 앱에서의 쓰임, 닮은 방식과의 차이, 대가를 봅니다.
하나가 아닌 화면 크기
화면 위에 글, 그림, 버튼 같은 요소를 어디에 얼마만 한 크기로 놓을지 정한 것이 레이아웃입니다. 메뉴는 위에, 본문은 가운데에 두는 결정이 레이아웃입니다.
너비를 픽셀 같은 고정 값으로 못 박아 둔 배치를 고정 레이아웃이라고 합니다. 그 너비보다 좁은 화면에서는 페이지 일부가 잘려서 옆으로 밀어 봐야 합니다. 그보다 넓은 화면에서는 양옆이 텅 빕니다.
지금은 같은 서비스를 휴대폰, 태블릿, 노트북, 큰 모니터에서 엽니다. 한 기기 안에서도 크기가 바뀝니다. 브라우저 창을 끌어 줄이거나 휴대폰을 가로로 돌리면 화면 너비가 달라집니다.
기기마다 화면을 따로 만들면 이 문제는 풀립니다. 대신 같은 기능을 여러 벌 고치고 시험해야 합니다. 반응형 레이아웃은 화면 하나가 크기에 맞춰 모양을 바꾸게 해서 이 수고를 덜어 줍니다.
비율로 늘고 주는 배치
반응형 레이아웃의 첫 도구는 비율입니다. 요소의 너비를 「300 픽셀」처럼 못 박지 않고 「화면 너비의 절반」처럼 정합니다. 화면이 넓어지면 요소도 넓어집니다. 화면이 좁아지면 요소도 함께 좁아집니다.
픽셀처럼 길이가 정해진 단위를 절대 단위라고 합니다. 반대로 다른 것의 크기를 기준으로 삼는 단위를 상대 단위라고 합니다. 화면 크기가 달라질 때 요소가 따라 변하게 하려면 상대 단위가 있어야 합니다.
화면의 요소는 상자 안에 상자가 든 모양으로 겹겹이 담깁니다. 어떤 요소를 담고 있는 바깥 요소를 부모라고 합니다. 부모 안에 담긴 요소는 자식이라고 합니다. 페이지 전체를 담은 상자가 부모라면, 그 안의 메뉴와 본문은 자식입니다.
퍼센트가 대표적인 상대 단위입니다. 퍼센트로 정한 너비는 부모의 너비를 기준으로 삼습니다. 부모가 넓어지면 자식도 따라 넓어집니다.
브라우저 창 안에서 페이지가 보이는 영역을 뷰포트라고 합니다. 주소창과 탭 줄을 뺀, 페이지가 실제로 그려지는 사각형입니다. 브라우저 창을 줄이면 뷰포트도 함께 줄어듭니다.
뷰포트의 너비나 높이를 기준으로 삼는 상대 단위도 있습니다. 이것이 뷰포트 단위입니다. 부모가 아니라 뷰포트를 따르므로, 창을 줄이면 이 단위로 정한 크기도 같이 줄어듭니다.
비율은 칸을 나눌 때도 씁니다. 화면을 세로 칸 몇 개로 나누고 칸마다 너비를 비율로 정한 틀이 유동 그리드입니다. 블로그 글 페이지라면 글 본문 칸에 너비의 3분의 2를, 관련 글 칸에 3분의 1을 줍니다. 화면이 넓든 좁든 두 칸이 이 비율대로 너비를 나눠 가집니다.
이미지도 같은 원리를 따릅니다. 이미지의 최대 너비를 부모의 너비로 묶어 두면, 부모가 좁아질 때 이미지도 따라 줄어듭니다. 이미지가 부모 밖으로 삐져나가 가로 스크롤을 만드는 일이 사라집니다.
화면 크기에 맞는 해상도의 이미지 파일을 골라 보내는 기법을 반응형 이미지라고 합니다. 작은 화면에 큰 파일을 보내지 않으니 전송량이 줄어듭니다. 서버와 이미지 저장소가 같은 그림을 크기별로 여러 벌 갖고 있어야 쓸 수 있습니다.
브레이크포인트
비율만으로는 한계가 있습니다. 칸 셋을 휴대폰 너비에 넣으면 칸마다 몇 글자밖에 안 들어가 읽을 수가 없습니다. 반대로 칸 하나를 큰 모니터에 펼치면 글줄이 지나치게 길어져 눈이 다음 줄을 놓칩니다.
그래서 너비가 어느 값을 넘으면 배치 자체를 바꿉니다. 이 경계가 되는 너비를 브레이크포인트라 합니다. 좁은 화면에서는 요소를 한 칸에 쌓습니다. 경계를 넘으면 칸을 둘로 나눕니다.
아래 두 그림은 앞에서 본 블로그 글 페이지를 두 너비에서 본 모습입니다. 좁은 화면에서는 메뉴, 글 본문, 관련 글이 위에서 아래로 쌓입니다.
block-beta columns 1 a["메뉴"] b["글 본문"] c["관련 글"]
브레이크포인트를 넘은 넓은 화면에서는 메뉴가 맨 위를 가로로 차지합니다. 그 아래에서 글 본문과 관련 글이 나란히 섭니다.
block-beta columns 3 a["메뉴"]:3 b["글 본문"]:2 c["관련 글"]:1
경계에서는 배치가 바뀝니다. 경계와 경계 사이에서는 앞에서 본 비율대로 요소가 늘고 줄어듭니다. 두 도구를 함께 써야 어느 너비에서도 화면이 매끄럽게 이어집니다.
경계에서 바꾸는 것은 칸 수만이 아닙니다. 흔히 바꾸는 것을 모으면 아래와 같습니다.
| 바뀌는 것 | 좁은 화면 | 넓은 화면 |
|---|---|---|
| 칸 배치 | 한 칸에 위아래로 쌓음 | 두세 칸을 나란히 놓음 |
| 메뉴 | 아이콘 하나 뒤로 접어 둠 | 메뉴 항목을 모두 펼침 |
| 글자와 여백 | 작게 | 크게 |
| 덜 중요한 요소 | 숨김 | 보임 |
표의 접힌 메뉴는 대개 가로줄 세 개짜리 아이콘을 눌러 엽니다. 이 아이콘을 모양을 따서 햄버거 메뉴라고 부릅니다.
웹에서 쓰는 도구
웹 페이지의 모양은 CSS(Cascading Style Sheets)로 정합니다. CSS 는 요소의 색, 크기, 배치를 적는 언어입니다. 페이지의 내용과 떼어 적기 때문에 내용은 두고 모양만 바꿀 수 있습니다.
여기서는 웹에서 반응형 레이아웃을 짜는 도구 넷을 짧은 코드 하나와 함께 봅니다. CSS 의 미디어 쿼리, 플렉스박스, CSS 그리드, 그리고 휴대폰 브라우저에 주는 설정 하나입니다. 웹 페이지에 반응형 레이아웃을 쓰는 설계 전반은 반응형 웹 디자인 항목이 다룹니다.
브레이크포인트는 CSS 의 미디어 쿼리로 적습니다. 미디어 쿼리는 「창 너비가 얼마 이상일 때만」 같은 조건을 겁니다. 조건이 맞을 때만 그 안에 적은 규칙이 적용됩니다.
요소를 늘어놓는 데는 플렉스박스를 씁니다. 플렉스박스는 부모 안의 자식 요소들을 한 줄로 늘어놓는 배치 방식입니다. 부모에 display: flex 를 적으면 이 방식이 켜집니다.
아래 코드는 앞 그림에서 글 본문과 관련 글을 담은 부모를 적은 것입니다. flex-direction 은 그 줄을 세로로 놓을지 가로로 놓을지 정합니다.
.content {
display: flex;
flex-direction: column; /* 세로로 쌓음 */
}
@media (min-width: 600px) {
.content {
flex-direction: row; /* 옆으로 놓음 */
}
}
창 너비가 600 픽셀보다 좁으면 첫 규칙만 적용되어 두 요소가 세로로 쌓입니다. 600 픽셀 이상이면 미디어 쿼리 안의 규칙이 앞 규칙을 덮어써서 옆으로 놓입니다. 600 은 예로 고른 값입니다. 실제 경계는 내용이 언제 비좁아 보이는지를 보고 정합니다.
이 코드는 좁은 화면용 규칙을 기본으로 적었습니다. 넓은 화면용 규칙은 그 뒤에 덧붙였습니다. 이렇게 작은 화면부터 짠 뒤 큰 화면으로 넓혀 가는 순서가 모바일 우선입니다. 거꾸로 큰 화면부터 짠 뒤 좁은 화면에서 덜어 내는 순서도 쓰입니다.
칸을 나누는 데는 CSS 그리드도 씁니다. 플렉스박스는 요소를 한 줄로 늘어놓습니다. CSS 그리드는 가로와 세로 칸을 함께 정해 바둑판처럼 놓습니다.
휴대폰 브라우저에는 챙길 것이 하나 더 있습니다. 휴대폰 브라우저는 아무것도 알려 주지 않으면 페이지를 넓은 화면용으로 여깁니다. 그래서 페이지를 축소해서 보여 줍니다. 이때는 뷰포트 너비가 넓게 잡혀서 좁은 화면용 규칙이 안 걸립니다.
페이지 머리에 메타 뷰포트 태그를 넣으면 이 문제가 풀립니다. 이 태그는 뷰포트를 기기 너비에 맞춰 잡으라고 브라우저에 알립니다. 그래야 미디어 쿼리가 뜻대로 동작합니다.
모바일 앱에서의 반응형 레이아웃
앱에서도 같은 생각을 씁니다. 휴대폰과 태블릿은 화면 크기가 다릅니다. 한 기기 안에서도 기기를 가로로 돌리는 화면 방향 전환이 일어나면 앱이 받는 너비가 바뀝니다.
앱은 운영체제가 내준 창 안에 화면을 그립니다. 웹 페이지가 브라우저 창 안에 그려지는 것과 같습니다. 이 창의 크기가 쓰는 도중에 크게 바뀌는 기기도 있습니다.
폴더블은 접힌 화면을 펼치면 창이 크게 넓어집니다. 분할 화면에서는 운영체제가 화면을 나눠 앱마다 창 하나씩 줍니다.
그래서 앱은 기기의 화면 크기가 아니라 자기가 받은 창의 크기를 보고 배치를 골라야 합니다. 큰 태블릿이라도 분할 화면 속 앱은 휴대폰만큼 좁은 창을 받을 수 있습니다. 「태블릿이니 넓은 배치」처럼 기기 종류로 고르면 이때 화면이 깨집니다.
창 크기가 바뀌면 운영체제가 앱에 알립니다. 화면 크기나 방향처럼 앱이 도는 환경이 바뀌는 일을 구성 변경이라고 합니다. 앱은 이 알림을 받고 새 크기에 맞는 배치로 화면을 다시 짭니다.
앱의 브레이크포인트는 흔히 창 너비를 좁음, 중간, 넓음 같은 몇 구간으로 나눠 정합니다. 넓은 구간에서는 왼쪽에 목록을, 오른쪽에 고른 항목의 내용을 함께 띄우기도 합니다. 메일 앱이 넓은 화면에서 메일 목록과 본문을 나란히 보이는 배치가 목록-상세 레이아웃입니다.
적응형 레이아웃과의 차이
반응형 레이아웃과 자주 나란히 나오는 말이 적응형 레이아웃입니다. 둘 다 화면 크기에 맞춰 배치를 바꿉니다. 바꾸는 방식이 다릅니다.
| 비교 | 반응형 레이아웃 | 적응형 레이아웃 |
|---|---|---|
| 배치를 만드는 방식 | 배치 하나가 너비에 따라 늘고 줆 | 너비 구간마다 배치를 따로 만들어 둠 |
| 경계 사이에서 | 요소가 비율대로 늘고 줆 | 크기가 고정된 채 머묾 |
| 경계에서 | 칸 수나 순서가 바뀜 | 미리 만든 다른 배치로 갈아 끼움 |
실무에서는 두 방식을 섞어 쓰는 일이 많습니다. 그래서 둘 사이의 선을 사람마다 다르게 긋습니다.
웹에는 적응형 레이아웃과도 다른 셋째 방식이 있습니다. 서버가 기기를 가려 휴대폰에는 아예 다른 페이지를 보냅니다. 이렇게 휴대폰용으로 떼어 둔 사이트를 별도 모바일 사이트라고 합니다.
브라우저는 요청마다 자기가 어떤 브라우저이고 어떤 기기에서 도는지를 헤더에 적어 보냅니다. 이 값이 사용자 에이전트 문자열입니다. 서버는 이 문자열을 읽어 휴대폰이면 모바일용 페이지를 돌려줍니다.
이 방식은 페이지와 주소를 기기별로 두 벌 관리해야 합니다. 반응형 레이아웃은 모든 기기에 같은 페이지를 보냅니다. 배치는 브라우저가 고릅니다. 서버 쪽에서는 기기를 가릴 일이 사라집니다.
반응형 레이아웃의 대가
반응형 레이아웃은 화면 하나로 여러 크기를 맞추는 대신 그 화면이 할 일을 늘립니다. 늘어나는 부담은 셋입니다. 끝에서는 이 부담을 질 까닭이 적은 경우도 봅니다.
첫째로 확인할 화면이 늘어납니다. 브레이크포인트마다, 그리고 경계 사이의 너비마다 요소가 겹치거나 잘리지 않는지 봐야 합니다. 이 확인을 자동으로 하려고 너비를 바꿔 가며 화면을 찍어 견주는 스크린샷 테스트를 돌리기도 합니다.
둘째로 작은 화면이 쓸데없는 데이터를 받을 수 있습니다. CSS 로 숨긴 요소는 화면에 안 보일 뿐 페이지에는 들어 있어서 함께 내려받습니다. 큰 이미지를 화면에서 줄여 보이기만 하면 파일 크기는 줄지 않습니다. 앞에서 본 반응형 이미지가 이 낭비를 덜어 줍니다.
셋째로 설계가 어려워집니다. 디자인을 한 장으로 끝낼 수 없습니다. 너비마다 배치가 어떻게 바뀔지 정해야 합니다. 좁은 화면에서 무엇을 보여 주고 무엇을 숨길지 고르는 판단도 따라옵니다.
화면 크기가 한 가지로 정해진 경우에는 이 수고를 들일 까닭이 적습니다. 매장 계산대 단말처럼 기기가 하나로 고정된 화면이나, 사무실 모니터에서만 여는 사내 관리 도구가 그런 예입니다. 반대로 누가 어떤 기기로 들어올지 모르는 서비스는 대개 반응형 레이아웃으로 짭니다.
반응형 프로그래밍과 겹치는 이름
「반응형」이라는 같은 우리말이 다른 기술에도 붙습니다. 반응형 프로그래밍은 영어로 reactive programming 입니다. 값이 바뀌면 그 값에 걸린 계산이 따라 바뀌도록 짜는 방식입니다.
반응형 레이아웃의 영어 이름은 responsive layout 입니다. 화면 크기에 맞춰 배치를 바꾸는 일이라서 반응형 프로그래밍과는 이름만 겹칩니다. 문서에서 「반응형」을 만나면 화면 배치 이야기인지 값의 흐름 이야기인지부터 가려 읽으면 됩니다.
관련 항목
반응형 레이아웃을 이루는 구성 요소
유동 그리드 · 상대 단위 · 뷰포트 단위 · 브레이크포인트 · 반응형 이미지 · 유동 타이포그래피
반응형 레이아웃을 웹에서 구현하는 CSS 기능
CSS · 미디어 쿼리 · 컨테이너 쿼리 · 플렉스박스 · CSS 그리드 · 메타 뷰포트 태그 · 뷰포트
반응형 레이아웃을 대신할 수 있는 다른 수단
적응형 레이아웃 · 고정 레이아웃 · 별도 모바일 사이트 · 사용자 에이전트 탐지
반응형 레이아웃이 받아 내는 화면 변화
화면 방향 · 구성 변경 · 분할 화면 · 폴더블 · 멀티 윈도 · 화면 밀도
반응형 레이아웃을 짤 때 따르는 설계 기법
모바일 우선 · 목록-상세 레이아웃 · 햄버거 메뉴 · 점진적 향상
반응형 레이아웃을 시험하는 방법
스크린샷 테스트 · UI 테스트 · 브레이크포인트 테스트 · 개발자 도구
반응형 레이아웃이 속하는 상위 분야
레이아웃 · 반응형 웹 디자인 · 프론트엔드 · 모바일 개발 · 사용자 인터페이스
반응형 레이아웃과 이름만 겹치는 개념
반응형 프로그래밍 · 반응형 시스템 · 리액티브 스트림
다른 이름: responsive layout · 리스폰시브 레이아웃