반응형 디자인


노트북으로 페이지를 만들고 보기에 딱 맞아서 만족했는데, 누군가 그 페이지를 휴대폰으로 열어봅니다. 정성껏 맞춰놓은 열들이 좁은 조각으로 짓눌리고, 텍스트는 화면 밖으로 넘쳐나고, 있어서는 안 될 가로 스크롤바까지 나타납니다. 그렇다고 사이트의 휴대폰 전용 버전을 따로 만든 사람은 없습니다. 페이지는 하나뿐이고, 그 하나가 380픽셀짜리 휴대폰에서도, 1400픽셀짜리 모니터에서도 모든 것을 두 벌씩 만들지 않고 제대로 보여야 합니다. 이런 적응력이 바로 반응형 디자인이며, 대부분은 이미 여러분이 알고 있는 도구들로 만들어집니다.
반응형이라는 것과 뷰포트
반응형(responsive) 페이지란 어떤 화면에 놓이든 그에 맞춰 스스로 모양을 바꾸는 하나의 페이지를 말합니다. 같은 HTML과 같은 CSS가 휴대폰, 태블릿, 데스크톱을 모두 처리하며, 무엇도 넘치지 않고 무엇도 답답해 보이지 않도록 레이아웃이 조정됩니다. 사이트를 세 개 만드는 것이 아니라, 유연하게 휘어지는 하나를 만드는 것입니다.
이런 동작이 가능해지기 전에, 브라우저는 HTML 안에 지시 하나를 필요로 합니다. 예전에는 휴대폰이 마치 데스크톱만큼 폭이 넓은 것처럼 행동하며 페이지 전체를 축소해서 맞췄는데, 그래서 옛날 사이트들이 작고 축소된 뭉텅이로 보였던 것입니다. <head> 안에 들어가는 이 한 줄이 휴대폰에게 진짜 화면 폭을 그대로 쓰라고 알려줍니다.
<meta name="viewport" content="width=device-width, initial-scale=1" />이 줄이 없으면 CSS는 실제로 존재하지 않는 넓은 화면을 기준으로 스타일을 입히게 되고, 정성껏 만든 레이아웃은 제대로 보일 기회조차 얻지 못합니다.
먼저 유동적인 레이아웃부터
바로 휴대폰 전용 규칙을 만들고 싶은 마음이 들지만, 사실 규칙 하나 쓰기 전에도 반응형 동작의 많은 부분이 이미 공짜로 따라옵니다. 주어진 공간에 맞춰 늘어나고 줄어드는 값인 유동적인(fluid) 값으로 레이아웃을 만들면, 레이아웃은 이미 스스로 적응합니다.
이 효과를 좌우하는 습관은 두 가지입니다. 폭을 고정된 픽셀 수가 아니라 퍼센트로 지정해서 박스가 컨테이너의 일정 비율을 차지하게 하는 것, 그리고 max-width를 써서 작은 화면에서는 줄어들되 큰 화면에서는 읽기 편한 크기를 넘어 커지지 않게 하는 것입니다.
.container {
width: 90%; /* 주어진 공간의 90%를 차지함 */
max-width: 60rem; /* 하지만 큰 화면에서도 60rem을 넘지 않음 */
margin: 0 auto; /* 가운데 정렬 */
}휴대폰에서는 이 컨테이너가 좁은 화면의 90%가 됩니다. 모니터에서는 60rem에서 성장을 멈추고 가운데에 자리 잡습니다. 휴대폰용 규칙을 따로 쓴 것이 아니라, 값들이 스스로 적응한 것입니다.
max-width를 써서 휴대폰에서는 줄어들되 모니터에서는 너무 넓어지지 않게 하세요. 이 두 값만으로도 레이아웃은 스스로 적응합니다. 유동적인 레이아웃을 먼저 만들면, 뒤에 나올 휴대폰 전용 규칙이 훨씬 적게 필요합니다. 미디어 쿼리
가끔은 유동적인 값만으로 충분하지 않고, 특정 크기에서 레이아웃이 실제로 바뀌어야 할 때가 있습니다. 예를 들어 메뉴가 휴대폰에서는 세로로 쌓이지만 데스크톱에서는 한 줄로 나란히 놓이는 경우입니다. 이럴 때 필요한 것이 **미디어 쿼리(media query)**입니다. 화면이 여러분이 정한 조건을 만족할 때만 적용되는 CSS 블록입니다.
작은 화면용 스타일을 일반 CSS로 먼저 작성하고, 그 위에 넓은 화면에서 바뀌는 부분을 얹는 쿼리를 추가하세요.
.nav {
display: flex;
flex-direction: column; /* 작은 화면에서는 세로로 쌓임 */
}
@media (min-width: 40rem) {
.nav {
flex-direction: row; /* 공간이 생기면 나란히 배치됨 */
}
}@media (min-width: 40rem) 안의 규칙은 화면이 최소 40rem 이상일 때만 켜집니다. 그 아래에서는 평범한 .nav 규칙이 적용되어 메뉴가 세로로 쌓입니다.
@media (min-width: ...)로 큰 화면용 변화를 추가하세요. 그러면 휴대폰 화면이 나중에 덧붙인 것이 아니라 처음부터의 출발점이 됩니다. 브레이크포인트 정하기
**브레이크포인트(breakpoint)**란 미디어 쿼리가 발동해서 레이아웃이 바뀌는 폭을 말합니다. 하나를 정할 때 유혹적인 방법은 유명한 휴대폰이나 태블릿의 폭을 찾아보고 거기에 맞추는 것입니다. 이것이 함정입니다. 기기 크기는 수백 가지가 있고, 매년 바뀌기 때문에, 그것을 좇는 것은 절대 이길 수 없는 게임입니다.
더 좋은 질문은 "이 레이아웃이 정확히 어느 폭에서 나빠지기 시작하는가"입니다. 브라우저 폭을 천천히 넓혀보면서 지켜보세요. 한 줄 텍스트가 너무 길어져서 읽기 불편해지거나, 두 열이 너무 좁아질 때, 그 지점이 브레이크포인트가 있어야 할 곳이며, 그 숫자가 무엇이든 상관없습니다.
/* 여기서 텍스트가 너무 넓어졌기 때문에 정한 브레이크포인트이고, */
/* 휴대폰이 마침 이 크기라서 정한 것이 아님 */
@media (min-width: 45rem) {
.article { max-width: 38rem; }
}
