반응형 웹 디자인 기본사항

인터넷에서 휴대전화 사용자 수가 증가함에 따라 웹 디자이너가 다양한 화면 크기에 적합한 방식으로 콘텐츠를 배치하는 것이 점점 더 중요해지고 있습니다. A List Apart에서 Ethan Marcotte에 의해 처음 정의된 반응형 웹 디자인은 사용 중인 기기에 맞게 사이트의 레이아웃을 변경하여 사용자의 요구사항과 기기의 기능에 반응하는 디자인 전략입니다. 예를 들어 반응형 사이트는 휴대전화에서는 단일 열 뷰로, 태블릿에서는 두 열로, 데스크톱 컴퓨터에서는 3~4열로 콘텐츠를 표시할 수 있습니다.

화면이 넓어지면 위젯의 모양이 이에 따라 변경됩니다.

인터넷 지원 기기의 화면 크기는 매우 다양하므로 사이트가 기존 또는 향후 화면 크기에 적응하는 것이 중요합니다. 최신 반응형 디자인은 터치 스크린과 같은 상호작용 모드도 고려합니다. 목표는 모든 사용자를 위해 환경을 최적화하는 것입니다.

표시 영역 설정

다양한 기기에 최적화된 페이지는 문서의 헤드에 meta viewport 태그를 포함해야 합니다. 이 태그는 페이지의 크기 및 배율을 제어하는 방법을 브라우저에 알립니다.

최적의 환경을 제공하기 위해 모바일 브라우저는 데스크톱 화면 너비 (기기마다 다르지만 일반적으로 약 980px)에서 페이지를 렌더링한 다음 글꼴 크기를 늘리고 콘텐츠의 배율을 조정하여 화면에 맞추는 방식으로 콘텐츠를 더 보기 좋게 만들려고 시도합니다. 이로 인해 글꼴이 일관되지 않게 보일 수 있으며 사용자가 콘텐츠를 보고 상호작용하기 위해 확대해야 할 수도 있습니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <meta name="viewport" content="width=device-width, initial-scale=1">
    …
  </head>
  …

meta viewport 값 width=device-width를 사용하면 표준 시각적 픽셀 단위 (고밀도 화면의 여러 물리적 픽셀로 구성될 수 있음)인 기기 독립적 픽셀(DIP)로 화면 너비에 맞게 페이지를 설정합니다. 이렇게 하면 페이지에서 다양한 화면 크기에 맞게 콘텐츠를 리플로우할 수 있습니다.

축소가 너무 되어 텍스트를 읽기 어려운 페이지의 스크린샷
뷰포트 메타 태그가 없는 페이지는 축소된 상태로 로드되어 텍스트를 읽기 어렵습니다. Glitch의 예시를 확인하세요.
읽을 수 있는 크기의 텍스트가 있는 동일한 페이지의 스크린샷
표시 영역 메타 태그를 설정하면 확대하지 않고도 페이지를 읽을 수 있습니다. Glitch의 예시를 확인하세요.

일부 브라우저는 가로 모드로 회전할 때 페이지 너비를 일정하게 유지하고, 재배치하는 대신 확대/축소하여 화면을 채웁니다. initial-scale=1 값을 추가하면 브라우저에 기기 방향과 관계없이 CSS 픽셀과 기기 독립적 픽셀 간에 1:1 관계를 설정하라는 지시가 전달되어 페이지에서 전체 가로 너비를 활용할 수 있습니다.

width 또는 initial-scale가 있는 <meta name="viewport"> 태그가 없음 Lighthouse 감사를 사용하면 HTML 문서에서 뷰포트 메타 태그를 올바르게 사용하는지 확인하는 프로세스를 자동화할 수 있습니다.

뷰포트에 맞게 콘텐츠 크기 조정

데스크톱 및 휴대기기에서 사용자는 가로가 아닌 세로로 웹사이트를 스크롤하는 데 익숙합니다. 전체 페이지를 보려면 사용자에게 가로 스크롤이나 축소를 강제로 수행하도록 하면 사용자 환경이 저하됩니다.

meta viewport 태그로 모바일 사이트를 개발하는 경우에는 지정된 뷰포트 내에 잘 맞지 않는 페이지 콘텐츠가 실수로 생성되기 쉽습니다. 예를 들어 뷰포트보다 넓게 표시되는 이미지는 가로 스크롤을 일으킬 수 있습니다. 이를 방지하려면 콘텐츠가 표시 영역에 들어맞도록 조정하세요.

콘텐츠 크기가 표시 영역에 맞지 않음 Lighthouse 감사를 사용하면 콘텐츠가 넘쳐나는 것을 감지하는 프로세스를 자동화할 수 있습니다.

이미지

고정된 크기의 이미지가 뷰포트보다 큰 경우 페이지가 스크롤됩니다. 모든 이미지에 max-width100%로 지정하는 것이 좋습니다. 이렇게 하면 이미지가 사용 가능한 공간에 맞게 축소되며 초기 크기를 초과하여 늘어나지 않습니다.

대부분의 경우 스타일 시트에 다음을 추가하면 됩니다.

img {
  max-width: 100%;
  display: block;
}

img 요소에 이미지의 크기 추가

max-width: 100%를 설정하는 경우에도 브라우저가 이미지가 로드되기 전에 이미지 공간을 예약할 수 있도록 <img> 태그에 widthheight 속성을 추가하는 것이 좋습니다. 이렇게 하면 레이아웃 변경을 방지할 수 있습니다.

레이아웃

CSS 픽셀에서 화면 크기와 너비는 기기마다 크게 다르므로(예: 휴대전화와 태블릿 간, 심지어 다른 휴대전화 간), 잘 렌더링되기 위해서는 콘텐츠가 특정 뷰포트 너비에 종속되어서는 안 됩니다.

이전에는 레이아웃 요소를 백분율로 설정해야 했습니다. 픽셀 측정을 사용하려면 사용자가 작은 화면에서 가로로 스크롤해야 합니다.

두 번째 열의 대부분이 뷰포트 외부에 있는 2열 레이아웃의 스크린샷
픽셀을 사용하는 플로팅 레이아웃입니다. Glitch의 예시를 확인하세요.

대신 비율을 사용하면 각 열이 항상 화면 너비의 동일한 비율을 차지하므로 소형 화면에서 열이 더 좁아집니다.

Flexbox, 그리드 레이아웃, 멀티컬럼과 같은 최신 CSS 레이아웃 기법을 사용하면 이러한 유연한 그리드를 훨씬 쉽게 만들 수 있습니다.

Flexbox

크기가 다른 항목이 여러 개 있고 이러한 항목을 한 행 또는 여러 행에 맞게 편안하게 배치하려는 경우 Flexbox를 사용하세요. 작은 항목은 더 적은 공간을 차지하고 큰 항목은 더 많은 공간을 차지합니다.

.items {
  display: flex;
  justify-content: space-between;
}

Flexbox를 사용하여 항목을 단일 행으로 표시하거나 사용 가능한 공간이 줄어들면 여러 행으로 래핑할 수 있습니다.

Flexbox 자세히 알아보기

CSS 그리드 레이아웃

CSS 그리드 레이아웃은 유연한 그리드를 만듭니다. 그리드 레이아웃과 컨테이너의 사용 가능한 공간의 일부를 나타내는 fr 단위를 사용하여 이전의 플로팅 예시를 개선할 수 있습니다.

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

그리드 레이아웃을 사용하여 최대한 많은 항목으로 일반 그리드 레이아웃을 만들 수도 있습니다. 화면 크기가 작아질수록 사용 가능한 트랙 수가 줄어듭니다. 다음 데모는 각 행에 들어맞는 만큼의 카드를 포함하고 있으며 최소 크기는 200px입니다.

CSS 그리드 레이아웃 자세히 알아보기

다중 열 레이아웃

일부 유형의 레이아웃의 경우 column-width 속성으로 반응형 열 수를 만드는 다중 열 레이아웃 (Multicol)을 사용할 수 있습니다. 다음 데모에서는 페이지에 다른 200px 열을 추가할 공간이 있으면 열이 추가됩니다.

Multicol 자세히 알아보기

응답성을 개선하기 위해 CSS 미디어 쿼리 사용

특정 화면 크기를 지원하기 위해 이전에 설명된 기법보다 레이아웃을 더 광범위하게 변경해야 할 수도 있습니다. 여기에서 미디어 쿼리가 유용합니다.

미디어 쿼리는 CSS 스타일에 적용하여 콘텐츠를 렌더링하는 기기 유형에 따라 스타일을 변경할 수 있는 간단한 필터입니다. 너비, 높이, 방향, 기기가 터치 스크린으로 사용 중인지 여부 등의 기기 기능에 따라 스타일을 변경할 수도 있습니다.

인쇄에 다양한 스타일을 제공하려면 출력 유형을 타겟팅하고 인쇄 스타일의 스타일 시트를 포함하면 됩니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <link rel="stylesheet" href="print.css" media="print">
    …
  </head>
  …

미디어 쿼리를 사용하여 기본 스타일 시트에 인쇄 스타일을 포함할 수도 있습니다.

@media print {
  /* print styles go here */
}

반응형 웹 디자인의 경우 가장 일반적인 쿼리는 기기 기능에 관한 것이므로 터치 스크린 또는 소형 화면에 맞게 레이아웃을 맞춤설정할 수 있습니다.

뷰포트 크기를 기반으로 하는 미디어 쿼리

미디어 쿼리를 사용하면 특정 화면 크기에 특정 스타일을 적용하는 반응형 환경을 만들 수 있습니다. 화면 크기 쿼리는 다음을 테스트할 수 있습니다.

  • width(min-width, max-width)
  • height(min-height, max-height)
  • orientation
  • aspect-ratio

이러한 모든 기능은 우수한 브라우저 지원을 제공합니다. 브라우저 지원 정보 등 자세한 내용은 MDN의 width, height, orientation, aspect-ratio를 참고하세요.

기기 기능을 기반으로 하는 미디어 쿼리

사용 가능한 기기의 범위를 고려할 때 개발자는 모든 대형 기기가 일반 데스크톱 또는 노트북 컴퓨터이거나 모든 소형 기기가 터치 스크린을 사용한다고 가정할 수 없습니다. 미디어 쿼리 사양에 새로 추가된 몇 가지 기능을 사용하면 기기와 상호작용하는 데 사용되는 포인터 유형, 사용자가 요소 위에서 포인터를 길게 누를 수 있는지 여부와 같은 기능을 테스트할 수 있습니다.

  • hover
  • pointer
  • any-hover
  • any-pointer

일반 데스크톱 컴퓨터, 휴대전화 또는 태블릿과 같은 다양한 기기에서 이 데모를 시청해 보세요.

이러한 최신 기능은 모든 최신 브라우저에서 잘 지원됩니다. hover, any-hover, pointer, any-pointer에 관한 MDN 페이지에서 자세히 알아보세요.

any-hoverany-pointer 사용

any-hoverany-pointer 기능은 사용자가 기기와 상호작용하는 기본적인 방법이 아니더라도 사용자가 요소 위로 포인터를 가져갈 수 있는지 (흔히 마우스 오버라고 함) 또는 포인터를 사용할 수 있는지 테스트합니다. 터치 스크린 사용자를 마우스로 강제 전환하지 않도록 하려면 이를 사용할 때 각별히 주의하세요. 그러나 사용자가 어떤 종류의 기기를 사용하는지 확인하는 것이 중요한 경우에는 any-hoverany-pointer가 유용할 수 있습니다. 예를 들어 터치 스크린과 트랙패드가 있는 노트북은 마우스 오버 기능 외에도 대략적인 포인터와 세밀한 포인터를 일치시켜야 합니다.

중단점을 선택하는 방법

기기 클래스, 제품, 브랜드 이름 또는 운영체제를 기준으로 중단점을 정의하지 마세요. 이렇게 하면 코드를 유지하기가 어렵습니다. 대신 콘텐츠가 컨테이너에 맞게 레이아웃이 변경되는 방식을 결정하도록 합니다.

처음에는 작게 시작하고 늘려나가는 방식으로 주요 중단점을 선택

먼저 작은 화면에 맞게 콘텐츠를 디자인한 다음 중단점이 필요해질 때까지 화면을 늘립니다. 이렇게 하면 페이지의 중단점 수를 최소화하고 콘텐츠에 따라 중단점을 최적화할 수 있습니다.

다음 예에서는 이 페이지 시작 부분의 일기 예보 위젯 예를 안내합니다. 첫 번째 단계는 작은 화면에서 예보가 잘 보이게 만드는 것입니다.

모바일 너비의 날씨 앱 스크린샷
좁은 너비의 앱

그런 다음 요소 사이에 너무 많은 공백이 있어서 위젯이 보기 좋게 표시될 때까지 브라우저의 크기를 조정합니다. 이 결정은 주관적이지만 600px보다 크면 확실히 너무 넓은 것입니다.

항목 간에 넓은 간격이 있는 날씨 앱의 스크린샷
이 크기에서는 앱의 레이아웃이 변경될 수 있습니다.

600px에서 중단점을 삽입하려면 구성요소의 CSS 끝에 두 개의 미디어 쿼리를 만듭니다. 하나는 브라우저가 600px 이하일 때 사용할 것이고 다른 하나는 600px보다 넓을 때 사용할 것입니다.

@media (max-width: 600px) {

}

@media (min-width: 601px) {

}

마지막으로 CSS를 리팩터링합니다. 600pxmax-width에 대한 미디어 쿼리 내에 작은 화면에만 적용되는 CSS를 추가합니다. 601pxmin-width에 대한 미디어 쿼리 내에 더 큰 화면에 관한 CSS를 추가합니다.

필요한 경우 하위 중단점 선택

레이아웃이 대폭 변경될 경우 주요 중단점을 선택할 수 있는 기능과 더불어, 사소한 변경에 대해 조정할 수 있는 기능도 유용합니다. 예를 들어 주요 중단점 간에 요소의 여백이나 패딩을 조정하거나 글꼴 크기를 늘려 레이아웃에서 더 자연스럽게 보이도록 하는 것이 유용할 수 있습니다.

이 예에서는 작은 화면 레이아웃 최적화부터 시작하여 이전 예와 동일한 패턴을 따릅니다. 먼저 뷰포트 너비가 360px보다 클 때 글꼴을 확대합니다. 그런 다음 공간이 충분하면 최고 기온과 최저 기온을 구분하여 같은 줄에 표시하고 날씨 아이콘을 더 크게 만들 수 있습니다.

@media (min-width: 360px) {
  body {
    font-size: 1.0em;
  }
}

@media (min-width: 500px) {
  .seven-day-fc .temp-low,
  .seven-day-fc .temp-high {
    display: inline-block;
    width: 45%;
  }

  .seven-day-fc .seven-day-temp {
    margin-left: 5%;
  }

  .seven-day-fc .icon {
    width: 64px;
    height: 64px;
  }
}

대형 화면의 경우 전체 화면 너비를 사용하지 않도록 예보 패널의 최대 너비를 제한하는 것이 좋습니다.

@media (min-width: 700px) {
  .weather-forecast {
    width: 700px;
  }
}

읽을 수 있도록 텍스트 최적화

전통적인 가독성 이론에 따르면 이상적인 경우 한 열에는 한 줄당 70 ~ 80자 (영어로 약 8 ~ 10단어)가 포함되어야 합니다. 텍스트 블록의 너비가 약 10단어를 넘어갈 때마다 중단점을 추가하는 것이 좋습니다.

휴대기기의 텍스트 페이지 스크린샷
휴대기기의 텍스트
데스크톱 브라우저의 텍스트 페이지 스크린샷
줄 길이를 제한하기 위해 중단점이 추가된 데스크톱 브라우저의 동일한 텍스트입니다.

이 예에서 1em의 Roboto 글꼴은 작은 화면에서는 한 줄당 10단어를 생성하지만 큰 화면에서는 중단점이 필요합니다. 이 경우 브라우저 너비가 575px보다 크면 이상적인 콘텐츠 너비는 550px입니다.

@media (min-width: 575px) {
  article {
    width: 550px;
    margin-left: auto;
    margin-right: auto;
  }
}

콘텐츠 숨기기 피하기 (:#avoid-hiding-content)

화면 크기에 따라 어떤 콘텐츠를 숨기거나 표시할지 선택할 때 주의를 기울이세요. 화면에 콘텐츠가 표시되지 않는다고 해서 콘텐츠를 숨기지 마세요. 화면 크기는 사용자가 보고 싶어 할 만한 항목을 예측하지 않습니다. 예를 들어 날씨 예보에서 꽃가루 개수를 삭제하면 외출 가능 여부를 결정하는 데 이 정보가 필요한 봄철 알레르기 환자에게 심각한 문제가 될 수 있습니다.

Chrome DevTools에서 미디어 쿼리 중단점 보기

미디어 쿼리 중단점을 설정한 후 사이트의 모양에 미치는 영향을 확인합니다. 브라우저 창의 크기를 조정하여 중단점을 트리거할 수도 있지만 Chrome DevTools에는 다양한 중단점에서 페이지가 어떻게 표시되는지 보여주는 내장 기능이 있습니다.

날씨 앱이 열려 있고 너비가 822픽셀로 선택된 DevTools의 스크린샷
더 넓은 표시 영역 크기로 날씨 앱을 보여주는 DevTools
날씨 앱이 열려 있고 너비가 436픽셀로 선택된 DevTools의 스크린샷
더 좁은 표시 영역 크기로 날씨 앱을 보여주는 DevTools

중단점이 서로 다를 때 페이지를 보려면 다음 단계를 따르세요.

  1. DevTools를 엽니다.
  2. 기기 모드를 사용 설정합니다. 기본적으로 반응형 모드로 열립니다.
  3. 미디어 쿼리를 보려면 Device Mode 메뉴를 열고 미디어 쿼리 표시를 선택합니다. 그러면 페이지 위에 중단점이 색상 막대로 표시됩니다.
  4. 막대 중 하나를 클릭하면 미디어 쿼리가 활성 상태에서 페이지를 볼 수 있습니다. 막대를 마우스 오른쪽 버튼으로 클릭하여 해당 미디어 쿼리의 정의로 점프합니다.