미지정

[2018-04-27]Responsive Web을 위해 개발자가 꼭 알아야 하는 기술들

반응형 웹(Responsive Web) 개발은 이미 일상이 되어버린 2018년 봄에 이런 글을 쓰게될 줄은 몰랐는데, 최근에 몇가지 프로젝트를 진행을 하다가 대부분의 개발자들이 반응형 웹에 대한 개념은 있지만 어떻게 개발해야 하는지를 모른다는 사실과 직면하게 되었다.
그림1

  • 왜 이런 일이 발생했을까?
    친구들과 이야기들을 하면서 찾아가다보니 대부분 부트스트랩과 같은 CSS 웹 프레임워크를 쓰거나, 퍼블리셔의 영역이라고 생각하고 있다는 것을 알게 되었다. 영역에 대한 갑론을박은 나중에 하자. 이 포스팅에서는 다루지 않을 생각이다.
  • 그런데, 왜 지금에서야 이 문제가 되었을까?
    최신 개발을 진행을 하게 되면 대부분 리액트(React), 뷰(Vue), 앵귤러(Angular) 같은 웹 컴포넌트를 쓰게 된다. 그런데 개발자들이 이런 프레임워크들을 쓰게 되면서 제이쿼리(jQuery)에 대해서 반감(?)을 갖게 되었고 부트스트랩은 기본적으로 제이쿼리 기반으로 갖춰진 터라 배재하고 쓰기 시작하는데 반응형이라는 숙제 앞에서 대략난감(?)한 상황이 된 것이었다. 게다가 퍼블리셔가 회사에서 점점 사라져가는 개발 프로세스들(스케치와 제플린 콤보)이 정립되고 나니 개발자들이 반응형 웹의 영역을 떠 받게 되는 상황이 되었다.

지금 포스팅은 이런 상황에 직면한 개발자들을 위해 쓰여졌다. 하지만 유용할 것이라고 생각한다.

아래와 같은 순서로 포스팅은 진행된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
- 반응형 웹의 정의
- 반응형 웹의 기술들
1. 픽셀의 정의와 viewport metatag
2. 반응형 레이아웃
2.1. 미디어 쿼리
2.2. 레이아웃 패턴과 중단점
2.3. flexbox
3. 반응형 리소스
3.1. 이미지
3.2. 텍스트
3.3. 폰트(em,rem)
3.3. 반응형 CSS 로딩
4.개발자 도구 툴 활용

반응형 웹이란

반응형 웹(Responsive Web)을 정의할때면 언제난 적응형 웹(Adaptive Web)에 대한 이야기가 같이 나온다.
모바일 환경이 시작되면서 장치도 같이 다양해 지기 시작했다. 해상도의 크기도 다르고 비율이 달라지는 일들이 벌어졌다. 그 전에는 모니터에 맞춰서 1024x768, 1280x960 등의 동일 비율의 크기에 대한 대응만 하면 되던 일들이 아예 비율도 달라지고 해상도는 굉장히 높은데, 모바일 디바이스의 경우는 픽셀의 크기자체가 모니터의 크기랑 비교가 안되게 작아지는 일들이 생겨서 페이지를 설계하는데에 고려할 사항들이 많이 늘어 났다.
반응형 웹이 필요한 장비들

이런 상황에 적응할 수 있도록 반응형 웹 기술과 적응형 웹 기술이 탄생했다. 적응형 웹은 기본적으로 서버사이드에서 미리 클라이언트의 정보를 받아서 클라이언트가 모바일인지 웹인지를 파악해서 리소스를 선택해서 내려주는 형태를 이야기한다. 예를 들어 모바일 폰으로 네이버에 접속할 때를 생각해보면 쉽게 이해가 될 것이다. www.naver.com을 쳤지만 모바일 브라우저로 접근하면 m.naver.com로 리다이렉트 하고 렌더링하는 리소스들도 전혀 다르다. www.naver.com 의 크기를 늘였다 줄여도 레이아웃이 전혀 변경되지 않는다.
네이버는 적응형과 반응형의 조합
하지만 반응형 웹은 같은 페이지 리소스를 가지고 오지만 해당 페이지의 크기에 따라서 다르게 보이는 것을 이야기 한다. 하지만 삼성 SDS 사이트의 경우는 브라우저의 사이즈를 줄일 수록 레이아웃 자체가 바뀌는 것을 볼 수 있다.
SDS는 반응형 홈페이다

어떤 것이 더 좋은지는 웹 페이지의 지향점에 따라 다르기 때문에 무엇이 더 좋다고 할 수는 없지만, 모바일 환경에서 반응형 웹 페이지를 고려해야 하는 것은 요즘에는 너무나 당연한 것으로 이야기 되어진다. 왜 그런지 알아보도록 하자.( 심지어 m.naver.com 으로 일단 진입하고 나면 레이아웃이 바뀌는 모습도 발견할 수 있다.)

반응형 웹 페이지를 만들기 위해 알아야할 개념들

그렇다면 이 반응형 웹 페이지를 만들기 위해서는 어떤 기술들을 알아야 할까요? 어떤 기술들이 있으면 반응형 웹 페이지를 만들 수 있는지, 모바일과 웹에서 같은 사용자의 경험을 가져갈 수 있는지 알아봅시다.

1. 픽셀의 정의와 viewport metatag

픽셀

먼저 픽셀에 대해서 알아보자.
웹페이지를 제작할 때에 대부분의 사이트가 width:600px 같은 형태로 픽셀을 기준으로 페이지를 그리고 있다. 픽셀은 화면을 구성하는 가장 기본이 되는 단위로 보통 Picture Element 혹은 화소라고도 불린다. 이른바 15인치 모니터에 1024x768이라고 하면 모니터의 수평으로 1024개의 픽셀이 수직으로 768개의 픽셀이 배치되어 있다고 보면 된다. 즉 786432개의 픽셀로 이루어진 셈이다.
픽셀을 형상화한 이미지.

하지만 모바일 환경에서는 이 픽셀을 그대로 사용하지는 않는다. 왜냐하면 손 안에 들어오는 작은 디스플레이에 같은 픽셀을 기준으로 적용을 할 수 없기 때문이다. 아이폰 3GS 시절만 해도 320x480 같은 저해상도의 디스플레이였기 때문에 대부분의 페이지가 화면을 넘어가는 문제로 해상도를 그대로 사용할 수 없었다면, 현재 갤러시 S9은 1440x2960 과 같은 해상도의 화면이기 때문에 깨알 같이 보이는 어려움이 있다.

이 문제를 처음 깨닫고 해결하려고 덤벼든 것은 당연히 가장 먼저 스마트 폰에서 제대로 된 웹 환경을 제공한 애플이다. 당시에는 지금처럼 사이트를 모바일 사이트로 만들지 않았고 웹 페이지가 기준이었으니까 가상 viewport 개념을 도입했다. 실제로는 320px의 디스플레이를 980px의 viewport를 그린 것이다. 아래 그림을 보면 이해가 더 편할 것으로 보인다. 아래 그림은 애플 개발자 사이트에서 viewport 부분을 캡처한 화면이다. 320px 에서는 다 보이지 않는 페이지들이 980px의 viewport 안에 보이게 브라우저가 작동을 하는 것을 볼 수 있을 것이다.
320px를 980 px로 렌더링하다.
출처 : 애플 개발자 사이트 - Configuring the Viewport

이 때부터 대부분의 모바일 브라우저의 virtual viewport는 980px로 고정이 되었다. ( virtual viewport는 진짜 해상도가 320px,1440px,1080px등 다양한 장비들이 width는 보시다시피 같은 너비 기준으로 렌더링한다. 모바일 웹페이지의 width height 들을 작성을 할때는 참고하자. )
현재도 그런지 시뮬레이터에서 다음의 소스로 확인해 보자.

1
2
3
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
alert(w);

보기와 같은 소스코드로 확인해 보면 최신의 장비도 아래와 같이 980px를 안드로이드와 iOS모두 고수하고 있음을 알 수 있다.
모두가 980픽셀
즉 우리가 보는 픽셀은 실제로 장비의 픽셀 너비는 980/(실제 장비의 pixel width) 임을 알수 있다.

그런데, 실제로 모바일 장비의 해상도는 더 커지고 다양해 지는데, 모든 장비에서 사람들에게 편안한 크기의 이미지를 제작하고 폰트를 제공하려면 어떻게 해야 될까? ( 그에 관련된 내용도 출처를 밝힌 위의 링크에서 확인해 볼수 있다. )

viewport meta tag

일단 데스크 탑 용 네이버 사이트를 980px에서 확인해 보자.
가독성이?
도저히 한눈에 들어오는 가독성은 아니다. 결국 사람이 익숙한 폰트도 12~16px의 폰트가 적당하다고 봤을때, 각각 장비별로 적정한 device-width를 정의하기 시작했고, 아이폰은 처음 시작은 320px를 device-width로 주고 meta 태그에 viewport라는 아래와 같은 옵션을 주면 장비의 가독성이 가장 좋은 viewport를 가지기 시작했다.

1
<meta name="viewport" content="width=device-width,initial-scale=1.0">

장비별로 viewport가 달라졌다.
최신의 아이폰들은 375px를, Pixel XL은 412px를 viewport로 가지고 있다.

이제 viewport 라는 개념이 헷갈리기 시작할텐데 다음과 같은 원칙으로 정의해 보자.

  • meta tag에 viewport에 대한 별 내용이 없으면 기본적으로 980px를 기준으로 웹 페이지는 렌더링한다.
  • 하지만 글자의 가독성이 떨어지므로 각 장비별로 가독성이 가장 좋은 device-width를 viewport에 셋팅할 수 있는 옵션이 있다.
  • 그 옵션을 정의하고 나면 각 장비별 device-width로 페이지는 렌더링 된다.

이해를 돕기 위해 가로 640px 세로 640px의 이미지를 렌더링 하는 코드를 여러 장비에서 한번 확인해 보자. 사용된 시뮬레이터는 왼쪽으로 부터 iPhone X 와 iPhone 6, 그리고 Pixel2 XL과 저해상도 안드로이드 장비다. (저해상도 안드로이드 장비는 아이폰 3GS 시절의 320x400이 동작하는 방식을 재현하기 위해서다. )

  • 일반적인 이미지보기를 할 때
    img 태그만 적용해서 확인을 해 보면 640px의 이미지가 출력이 되는데, viewport가 980px 이므로 저해상도 안드로이드 장비말고는 모두 오른쪽에 여백이 남는다. 각 이미지별로 사각무늬의 크기도 제각각이다.
    meta 태그 넣기 전의 모습

  • viewport 옵션을 적용한 이미지보기를 할 때
    meta 태그를 추가한 모습
    각 장비별로 이미지가 보이는 부분은 다르지만 사각무늬의 크기는 동일하게 나온다. 이것을 이용하면 어떤 장비든지 보기 좋고 동일한 UX를 만들 수 있을 것 같은 확신이 든다.

viewport의 옵션을 더 알아보자.
먼저 페이지에 들어가서 핀치투 줌 같은 사용자의 행동을 막기 위한 옵션을 줄 수 있다. 네이버나 다음 사이트에 들어갔을때 두 손가락으로 줌인 줌아웃이 안되는 것을 볼 수 있을 것이다. viewport를 마음대로 변경하면 서비스 사업자가 원하는 데로 서비스가 제공되지 않을 때 사용한다.
가장 좋은 예는 지도 앱의 경우는 두손으로 확대를 하면 지도가 확대가 되어야 하는데 웹 페이지가 확대되는 걸 본적이 있을 것이다. 이런 경우를 위해서 사용이 된다.

1
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

여기서 device-width이외에 추가된 부분들이 그 역할을 하는데, 최초의 scale을 기준으로 사용자가 임의로 스케일을 변경할 수 없음을 이야기 한다. scale은 각 장비의 가장 가독성이 높은 device-width의 배율로 정의하면 이해하기 편하다. 즉 0.5로 scale을 바꾸면 Pixel XL2의 경우는 824 픽셀이 나온다.(414/0.5)

이상의 내용을 잘 이해하면 앞으로 나올 반응형 레이아웃과 미디어쿼리등의 상황을 잘 적응할 수 있을 것으로 보인다.
참고로 landscape(핸드폰을 옆으로 뉘였을때)일 때도 980px가 기본 viewport width 이다. meta-tag 설정을 하면 어떻게 되는지는 각자 확인을 해보자. 안드로이드 에뮬레이터에서 데스크 탑의 localhost 를 접속하려면 10.0.2.2를 사용하는 것도 이번 포스팅을 알면서 알게된 좋은 성과다.

이번 포스팅을 통해서 기하급수적으로 늘어나는 모바일 디바이스에서 화면을 어떻게 적응 시키기 위한 노력들을 했는지 알아보았고 그에대한 대답으로 가상 뷰포트라는 것이 존재한다는 것과 실제 여러 디비이스에서 동일하게 폰트와 이미지 크기를 나오게 하기 위해서 viewport와 scale=1.0 옵션을 가지고 있다는 것을 알게 되었다. 이후에는 반응형 웹을 어떻게 만들 것인지에 대한 실체에 조금더 접근해 보자.

이어지는 포스팅에는 반응형 레이아웃에 대해서 알아보도록 하겠다.

공유하기