본문으로 바로가기

Responsive Web

반응형 웹 디자인은 모바일 혹은 데스트탑의 모든 기기와 크고 작은 모든 스크린 사이즈에서 적절하게 작동하는 웹사이트를 만드는 것입니다. 

반응형 웹 디자인은 모든 사람에게 직관적이고 만족스런 경험을 제공하는 것에 초점을 두며, 데스크탑 유저와 폰 유저 모두에게 같은 이익을 제공하게 하는 것입니다. 

반응형 웹 디자인 responsive web design 용어는 Ethan Marcotte가 만들어냈습니다.


Food Sense는 아름다운 웹사이트이며, 모든 다른 뷰포트 사이즈에 반응합니다. 

크건 작건 뷰포트에 웹사이트가 조절되어 자연스런 사용자 경험을 만듭니다. 

이 Food Sense 웹을  참고해 보시기 바랍니다.





Responsive vs. Adaptive vs. Mobile

Responsive(반응형)adaptive(적응형) 웹 디자인은 밀접하게 연관되며, 종종 같은 의미로 사용되기도 합니다. 

반응형은 일반적으로 어떤 변화에도 빠르고 적극적으로 반응하는 것을 의미하는 반면 적응형은 (변화와 같은) 새로운 목적이나 상황에 쉽게 변경되는 것을 의미합니다. 

반응형 디자인에서는 웹사이트가 뷰포트 너비와 같은 요인에 지속적으고 유동적으로 변하지만, 적응형 웹사이트는 미리 정해진 요인들에 맞추어 만들어집니다. 

두 가지의 결합이 이상적이며, 기능적 웹사이트를 위한 완벽한 공식을 제공합니다. 

어떤 용어가 사용되는가가 특별히 커다란 차이를 만들지는 않습니다. 


Mobile 은 일반적으로 모바일 유저만을 위한 새 도메인에 별도의 웹사이트를 만드는 것을 의미합니다. 

모바일 웹사이트는 극도로 가벼울 수 있지만 새 코드 베이스와 브라우저 스니핑에 의존하고 있습니다. 

이는 개발자와 유저 모두에게 장애물이 될 수 있는 소지가 있습니다.

(Browser sniffing : 유저의 브라우저가 어떤 것인지 판별하는 것)


현재 가장 인기있는 기술은 다른 브라우저와 기기 뷰포트에 따라 레이아웃과 컨텐츠가 변하면서 생동적으로 적응하는 디자인을 선호하는 반응형 웹 디자인에 있습니다. 

이러 해법은 반응형, 적응형과 모바일 모두의 이점을 가지고 있습니다.




Relative Viewport Lengths 

CSS3에서는 몇 개의 새로운 상대 길이 단위가 도입되었습니다. 

이는 브라우저나 디바이스의 뷰포트 크기와 특히 관련된 것이며, vw, vh, vmin, vmax 등을 포함합니다. 

이러한 새로운 단위들에 대한 전체적인 지원은 훌륭하진 않으나 확대되고 있고, 조만간 반응형 웹사이트를 만드는 데에 커다란 역할을 하게 될 것임에는 틀림 없습니다.

  • vw : Viewports width 
  • vh : Viewports height 
  • vmin : Minimum of the viewport’s height and width 
  • vmax : Maximum of the viewport’s height and width

다음의 링크에서 위 단위에 대한 내용인  CSS Units 를 참고해 보시기 바랍니다.


가변 레이아웃은 픽셀이나 인치와 같은 고정 측정 단위를 지원하지 않습니다. 

기기마다 뷰포트 높이와 너비가 지속적으로 변하기 때문입니다. 

웹사이트 레이아웃은 이런 변화에 적응할 필요가 있으며 고정 값은 너무 많은 제약이 있습니다. 


다행히 Ethan이 상대값을 사용한 가변 레이아웃의 비율을 선언하는 것을 도와주는 쉬운 공식을 밝혀냈습니다. 

그 공식은 엘리먼트의 목표(target) 너비를 부모 엘리먼트의 너비로 나누어 목표 엘리먼트의 상대적인 너비를 구하는 것이다.

반응형 디자인 공식 : target ÷ context * 100 = result




Flexible Grid(유동적인 그리드)

반응형 디자인 공식이 두 열(column) 레이아웃 안에서 어떻게 동작하는지 살펴보겠습니다. 

아래에서 container 클래스의 부모 div가 section과 aside 엘리먼트를 감싸고 있습니다. 

section을 왼쪽으로 aside를 오른쪽으로 위치하면서 둘 사이에 같은 마진을 갖게하는 것이 목표입니다. 

보통 이러한 레이아웃의 마크업과 스타일은 다음과 유사할 것입니다.

Fixed Grid Demo

html
<div class="container">
  <section>...</section>
  <aside>...</aside>
</div>
css
.container {
      width: 660px;
 }
 section {
      float: left;
      margin: 10px;
      width: 420px;
 }
 aside {
      float: right;
      margin: 10px;
      width: 200px;
 }


Flexible Grid Demo

가변 그리드 공식을 사용하여 길이의 고정 단위를 상대 단위로 변경할 수 있습니다. 아래 예제에선 퍼센트를 사용하겠지만 em 단위도 동일하게 작동할 것입니다. 부모 container의 너비에 상관없이 section과 aside의 마진과 너비는 비율적으로 크기가 변동될 것입니다.

css
.container {
    max-width: 660px;
}
section {
    float: left;
    margin: 1.51515151%;   /*  10px ÷ 660px = .01515151 */
    width: 63.63636363%;   /* 420px ÷ 660px = .63636363 */
}
aside {
    float: right;
    margin: 1.51515151%;   /*  10px ÷ 660px = .01515151 */
    width: 30.30303030%;   /* 200px ÷ 660px = .30303030 */
}


가변 레이아웃 개념과 공식을 갖고 그리드의 모든 부분에 재적용하면 완벽하게 동적인 웹사이트를 만들 수 있습니다. 

위의 부모 container에서 했듯이 min-width, max-width, min-height, max-height 속성을 수단으로 가변 레이아웃에서 훨씬 더 많은 컨트롤을 할 수 있습니다.


하지만 가변 레이아웃 접근법만으론 충분치 않습니다. 

브라우저 뷰포트의 너비가 너무 작을 때는 레이아웃의 크기를 비율적으로 조절하더라도 열의 크기가 너무 작아 컨텐츠를 효과적으로 표시할 수 없을 수도 있습니다. 

레이아웃이 너무 작거나 크면 텍스트는 읽기 어렵게 되고, 레이아웃이 깨지기 시작할 것입니다. 

이런 경우엔 미디어 쿼리가 더 나은 경험을 만드는데 도움이 될 수 있습니다.




Media Queries

미디어 쿼리는 개별 브라우저와 디바이스 환경(예를 들면 뷰포트 너비 혹은 기기 오리엔테이션 등)에 각기 다른 스타일을 제공할 수 있는 확장 기능입니다. 

타겟 스타일을 독자적으로 제공할 수 있다는 것은 반응형 웹 디자인에 기회와 수단을 많이 부여해 주고 있습니다.


Initializing Media Queries

미디어 쿼리를 사용하는 방법은 두 가지가 있습니다. 

기존의 스타일 시트에 @media 룰을 사용하고 @import 룰을 사용하여 새로운 스타일 시트를 들여오거나(import), HTML 문서 안에서 별도의 스타일을 링크하는 것입니다. 

일반적으로 추가적인 HTTP 요청을 피하기 위해 기존 스타일 시트안에 @media 룰을 사용하는 것이 권장되고 있습니다.


html
<!-- Separate CSS File -->
<link href="styles.css" rel="stylesheet" media="all and (max-width: 1024px)">
css
/* @media Rule */
@media all and (max-width: 1024px) {
      ...
}

/* @import Rule */
@import url(styles.css) all and (max-width: 1024px) {
      ...
}


각 미디어 쿼리는 하나 또는 그 이상의 표현이 뒤따르는 미디어 타입을 포함할 수 있습니다. 

일반적인 미디어 타입은 all, screen, print, tv, braille을 포함합니다. 

HTML5 사양(specifition)은 3d-glasses도 포함하는 새로운 미디어 타입을 포함하고 있습니다. 

미디어 타입을 명시하지 않으면 미디어 쿼리는 미디어 타입을 screen으로 기본으로할 것이다. 


미디어 쿼리 표현식은 다른 미디어 특성과 값을 포함할 수 있으며 그리고나서 참(true) 혹은 거짓(false)를 할당합니다. 

미디어 특성과 값이 참으로 할당될 때 해당 스타일이 적용되며, 거짓이면 해당 스타일은 무시됩니다.


Logical Operators in Media Queries

미디어 쿼리에서 논리적 연산자(logical operator)는 강력한 표현식을 만들 수 있게 해줍니다. 

and, not, only의 세 개의 연산자를 사용할 수 있습니다.


and 논리 연산자를 사용하여 브라우저나 기기가 a,b,c 등으로 지정하여 추가적인 조건을 추가할 수 있습니다. 

여러 개의 개별 미디어 쿼리는 콤마로 분리될 수 있으며 암묵적인 or 연산자처럼 동작하게 됩니다. 

아래 예는 800과 1024 픽셀 너비의 모든 미디어 타입을 선택합니다.

css
@media all and (min-width: 800px) and (max-width: 1024px) {
     ...
}


not 논리 연산자는 명시된 것을 제외한 모든 쿼리를 특정하여 선언된 쿼리를 부정합니다. 

아래 예에서는 표현식은 컬러 스크린을 갖지 않는 모든 디바이스에 적용됩니다. 

즉, 흑백이나 모노 스크린에 적용되게 됩니다.

css
@media not screen and (color) {
     ...
}


only 논리 연산자는 새로운 연산자이며 HTML4 알고리즘을 사용하는 유저 에이전트로는 인식되지 않으므로, 미디어 쿼리를 지원하는 않는 기기나 브라우저에선 스타일이 나타나지 않습니다. 

아래에서 표현식은 세로 편향(portrait orientation)인 스크린만을 선택합니다.

css
@media only screen and (orientation: portrait) {
    ...
}


Omitting a Media Type

not과 only 논리 연산자를 사용할 땐 미디어 타입을 쓰지 않을 수 있습니다. 이 경우 미디어 타입은 all로 전제됩니다.


Media Features in Media Queries

미디어 쿼리 문법과 논리 연산자의 작동법을 아는 것은 미디어 쿼리에 대한 훌륭한 입문이나, 실제 작업은 미디어 특성과 함께 합니다. 

미디어 쿼리 표현식 내에서 어떤 속성이 목표될지를 미디어 특성이 지정합니다.


Height & Width Media Features

가장 많이 사용되는 미디어 특성 중 하나는 하나의 디바이스나 브라우저 뷰포트에 하나의 높이나 너비를 결정하는 것에 관련됩니다.

height, width, device-height, device-width의 미디어 특성을 사용해서 높이와 너비는 찾을 수 있습니다. 

각 미디어 특성은 min 혹은 max 수식어로 접두될 수 있어 min-width 혹은 max-device-width과 같은 특성을 만들 수 있습니다.


heightwidth 특성은 (브라우저 창과 같은) 뷰포트 렌더링 영역의 높이와 너비에 기반하며, 한편 device-heightdevice-width 특성은 (실제 렌더링 영역보다 더 클 수 있는) 출력 기기의 높이와 너비에 기반하고 있습니다. 

이 높이와 너비 미디어 특성 값은 (상대적이거나 절대적인) 어떠한 길이 값도 될 수 있습니다.

css
@media all and (min-width: 320px) and (max-width: 780px) {
     ...
}

반응형 디자인에서는 min-widthmax-width를 포함하는 특성이 가장 많이 사용됩니다. 

이것들은 기기 특성에 혼동을 피해 데스크탑과 모바일 기기에 동일하게 반응형 웹사이트를 만드도록 도와줍니다.


Using Minimum & Maximum Prefixes

min과 max 접두어는 꽤 많은 미디어 특성에서 사용될 수 있습니다. min 접두어는 보다 크거나 같은 값을 가리키며, max 접두어는 더 적거나 같은 값을 가리킵니다.

min과 max 접두어는 일반적인 HTML 문법과 충돌되지 않아 특별히 꺽쇠 심볼을 사용하지 않습니다.


Orientation Media Feature

orientation 미디어 특성은 기기가 landscapeportrait 편향(orientation)인지를 결정합니다.

landscape 모드는 화면이 가로 모드일 때, portrait 모드는 화면이 세로 모드일 때이며, 모바일 기기에서 널리 사용되고 있습니다.

css
@media all and (orientation: landscape) {
      ...
}


Aspect Ratio Media Features

aspect-ratiodevice-aspect-ratio 특성은 목표 렌더링 영역 혹은 출력 기기의 width/height 픽셀 비율을 지정합니다. 

min와 max 접두어가 사용될 수 있습니다. 종횡비(aspect ratio) 값은 /로 분리되는 두 개의 양의 정수로 구성됩니다. 

첫 정수는 픽셀 너비를, 두번째 정수는 픽셀 높이입니다.

css
@media all and (min-device-aspect-ratio: 16/9) {
     ...
}


Pixel Ratio Media Features

종횡비 특성에 더해 pixel-ratio 미디어 특성도 있습니다. 이 특성은 device-pixel-ratio 특성을 포함하며, min과 max 접두어도 가집니다. 특히 픽셀비 특성은 레티나 디스플레이와 같은 고해상도 기기를 지정할 때 훌륭하며, 다음처럼 보여질 것입니다.

css
@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min-device-pixel-ratio: 1.3) {
    …
}


Resolution Media Feature

resolution 미디어 특성은 DPI(dots per inch)로 알려진 픽셀 밀도로 출력 기기의 해상도를 지정합니다. min과 max를 접두할 수 있습니다. 게다가 resolution 미디어 속성은 dots per pixel (1.3dppx), dots per centimeter (118dpcm)와 같은 길이 기반 해상도 값을 가질 수도 있습니다.

css
@media print and (min-resolution: 300dpi) {
     ...
}


Other Media Features

color, color-index, monochrome 특성은 출력 색상을, grid 특성은 비트맵 기기를, scan 특성은 텔레비전의 스캐닝 처리를 지정하며, 자주 사용하지는 않지만 필요할 땐 도움이 될 것입니다.



Media Query Browser Support

불행하게도 미디어 쿼리는 인터넷 익스플로러 8 이하와 고전적인 브라우저에서는 작동하지 않습니다. 

그러나, 자바스크립트로 쓰여진 두 개의 알맞는 땜빵,충전솜(polyfill)이 있습니다. 

Respond.js는 min/max-witdh 타입만을 위한 가벼운 땜빵이며, 미디어 쿼리 타입만 사용된다면 완벽할 수 있습니다. 

CSS3-MediaQueries.js는 더 많이 개발되고 더 무겁지만 더 복잡한 미디어 쿼리의 더 큰 배열을 지원하는 땜빵용입니다. 

추가적으로 어떠한 땜빵이라도 성능 문제를 가져올 수 있으며, 잠재적으로 웹사이트를 느리게 할 수 있다는 것을 명심해야합니다. 

주어진 폴리필이 성능과 맞바꿀만한지 확인한 후에 도입해야 할 것입니다.



Media Queries Demo

이제 미디어 쿼리를 사용하여 전에 만들었던 가변 레이아웃을 다시 코딩해 봅니다. 

데모의 현재 문제점 중 하나는 aside가 아주 작은 뷰포트에서 사용할 수 없을 정도로 작아진다는 것입니다. 

420 픽셀 너비 아래의 뷰포트를 위해 미디어 쿼리를 추가하여 float를 꺼버리고 section과 aside의 너비를 변화시키는 레이아웃으로 변경할 수 있을 것입니다.

css
@media all and (max-width: 420px) {
    section, aside {
        float: none;
        width: auto;
    }   
}

미디어 쿼리 없이는 section과 aside 너무 작아집니다. 너무 작아서 어떤 실제 컨텐츠도 담을 수 없을 것입니다.

미디어 쿼리를 사용하여 float를 제거하고 너비를 변경하면, section과 aside가 뷰포트 전체 너비를 차지하고 기존의 컨텐츠에 충분한 공간이 생기게 됩니다.


Identifying Breakpoints

당신의 직관이 각기 다른 기기 해상도로 결정되는 공통적인 뷰포트 사이즈의 미디어 쿼리 분기점(320px, 480px, 768px, 1024px, 1224px 등)을 쓸지도 모르겠습니다. 

그러나 이건 좋지 못한 아이디어입니다. 

반응형 웹사이트를 만들 때는 기기만아니라 다른 뷰포트 사이즈의 배열에 맞추어 조정되어야 할 것입니다. 

웹사이트가 깨지거나 이상하게 보이기 시작할 때 혹은 경험이 방해받을 때에만 분기점(breakpoint)이 도입되어야 합니다. 

게다가 새로운 기기와 해상도는 항상 출시되고 있습니다. 

이러한 변화를 따라가려는 것은 끝없는 과정일 수 있다는 것을 상기하시기 바랍니다.




Mobile First

미디어 쿼리와 함께 가장 인기있는 기술은 mobile first 로 불리우는 것입니다. 

mobile first 접근법은 작은 뷰포트의 스타일을 기본 웹사이트 스타일로 한 다음 뷰포트가 커짐에 따른 스타일을 추가하기위해 미디어 쿼리를 사용하는 것입니다.

모바일 퍼스트 디자인의 배경에서 작동되는 믿음은 일반적으로 더 작은 뷰포트를 사용하는 모바일 기기 유저는 모바일 스타일을 덮어쓰기만을 위해 테스크탑 스타일을 로드할 필요가 없다는 것입니다. 

그렇게 하는 것은 대역폭(bandwidth)의 낭비입니다. 

쾌적한 웹사이트를 기대하는 어떤 유저에게도 귀중한 대역폭 일 것입니다. 


모바일 퍼스트 접근법은 모바일 유저의 제한을 염두에 두고 디자인하는 것을 말합니다. 오래 전에 인터넷 소비의 태반이 모바일 기기로 이루어질 것으로 예상되었으며 적절하게 그것을 계획하고 본질적인 모바일 경험을 할 수 있도록 개발해야 할 것입니다.


모바일 퍼스트 미디어 쿼리는 다음과 같을 것입니다.

css
/* Default styles first then media queries */
@media screen and (min-width: 400px)  {...}
@media screen and (min-width: 600px)  {...}
@media screen and (min-width: 1000px) {...}
@media screen and (min-width: 1400px) {...}


불필요한 미디어를 다운로드하는 것은 미디어 쿼리를 사용하여 중지시킬 수 있습니다. 

일반적으로 모바일 스타일에서 CSS3 그림자, 그라디언트, 변형(transform), 애니메이션 등을 피하는 것은 나쁜 아이디어가 아닙니다. 

지나치게 사용되면 로딩이 무겁게되고, 기기의 배터리를 빨리 닳게할 수도 있습니다.

css
/* Default media */
body {
  background: #ddd;
}
/* Media for larger devices */
@media screen and (min-width: 800px) {
  body {
    background-image: url("bg.png") 50% 50% no-repeat;
  }
}


Mobile First Demo

이전 예제에 미디어 쿼리를 추가하면 420 픽셀 너비 미만에서 더 나은 레이아웃을 얻기위해 약간의 스타일을 겹쳐써 보도록 합니다. 

모바일 스타일 퍼스트를 기본으로 사용하기 위해 코드를 다시 쓰고 420 픽셀 이상의 뷰포트에 맞추기 위해 미디어 쿼리를 추가하면 다음과 같습니다.

css
section, aside {
  margin: 1.51515151%;
}
@media all and (min-width: 420px) {
  .container {
    max-width: 660px;
  }
  section {
    float: left;
    width: 63.63636363%;
  }
  aside {
    float: right;
    width: 30.30303030%;
  }
}

코드 양이 전과 같음을 주의깊게 보시기 바랍니다. 

여기서 유일한 예외는 모바일 기기는 하나의 CSS 선언만 렌더링해야만 한다는 것입니다. 

뒤따르는 나머지 스타일은 더 큰 뷰포트에서만 로드되고 어떤 선행 스타일을 겹쳐쓰지 않습니다.




CSS Viewport Rule

viewport 메타 태그는 웹사이트가 렌더링되어야 하는 스타일에 강하게 연관되어 있기 때문에 HTML 안의 메타태그보다는 CSS 안에서 @ 룰로 옮길 것을 추천합니다. 

이렇게 하는 것은 컨텐츠에서 스타일을 분리하여 보다 시맨택적으로 접근하는 것을 도와줍니다. 

현재 몇몇 브라우저는 이미 @viewport 룰을 적용했으나 전반적인 지원은 미흡한 상황입니다.

viewport 메타 태그는 다음 CSS에서의 @viewport 룰과 같이 보여질 것이다.

css
@viewport {
  width: device-width;
  zoom: 1;
}




Flexible Media

마지막 반응형 웹 디자인의 중요한 측면은 가변 미디어와 관련된 것입니다. 

뷰포트 크기가 변하기 시작하면 미디어가 항상 알맞게 따라오는 것은 아닙니다. 이미지, 비디오와 같은 미디어 타입은 뷰포트 변화에 맞추어 크기를 변화시킬 필요가 있습니다.

미디어 크기를 조절할 수 있게 하는 빠른 방법은 max-width 속성을 100% 값으로 주는 것입니다. 

그렇게 하면 뷰포트가 작아질 때 미디어의 크기가 컨테이너 너비에 맞추어 작아질 것입니다.

css
img, video, canvas {
  max-width: 100%;
}

Flexible Media Demo


Flexible Embedded Media

불행히도max-width 속성이 모든 미디어 실례에서 잘 작동하진 않습니다.

iframe과 같이 임베딩된 미디어에서 특히 그렇습니다. 

유투브와 같은 서드파티 웹사이트와 함께 할 때 아이프레임을 사용하여 미디어를 임베딩하면 엄청나게 실망하게 됩니다. 

다행히 우회 방법이 존재합니다. 


반응형을 완벽히 지원하는 임베딩된 미디어를 얻으려면 임베딩된 엘리먼트는 부모 엘리먼트 안에서 절대적으로 배치될(be absolutely positioned) 필요가 있습니다. 

뷰포트의 너비에 기반하여 크기 조절될 수 있도록 부모 엘리먼트의 width가 100%로 요구됩니다. 

또한, 인터넷 익스플로러에서는 hasLayout 매커니즘을 작동시키기 위해서 부모 엘리먼트의 height가 0로 요구됩니다. 

그런 후 부모 엘리먼트의 padding-bottom을 주고, 그 값을 비디오의 종횡비와 같게 설정해야 합니다. 

이렇게 하면 부모 엘리먼트의 높이가 너비에 비례하게 됩니다. 


이전의 반응형 디자인 공식을 기억하시고 계신가요? 

비디오의 종횡비가 16:9라면 9를 16으로 나누면 .5625가 되며, padding-bottom은 56.25%가 요구될 것입니다. 

padding-bottom이 사용되고 부모 엘리먼트는 절대적으로 배치된 엘리먼트로 다룹니다.

padding-top인터넷 익스플로어 5.5에서 깨지는 방지하기 위해 특별히 사용됩니다.

html
<div class='bogus-wrapper'><notextile><figure>
  <iframe src="https://www.youtube.com/embed/4Fqg43ozz7A"></iframe>
</figure></notextile></div>
css
figure {
  height: 0;
  padding-bottom: 56.25%; /* 16:9 */
  position: relative;
  width: 100%;
}
iframe {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}





Jaehee's WebClub