책임감 있는 반응형 디자인 #3. 지속성 있는 감지 방법

Seo·2020년 7월 13일
0

목록 보기
3/8

목차

  1. 서문
  2. 책임감 있는 디자인
  3. 지속성 있는 감지 방법
  4. 성능 고려하기
  5. 책임감 있게 전달하기

3. 지속성 있는 감지 방법

요즘 브라우저들은 워낙 다양하기 때문에 각 기능과 제약 사항을 감지하는 기능은 사용자 경험을 제대로 전달하는데 매우 중요한 요소가 되었다.
감지 기능은 다양한 방식으로 구현할 수 있지만, 특히 사용자 경험을 좀더 책임감 있게 제공할 수 있는 몇가지 방법이 있다.

3.1 디바이스 감지 : 꼼수의 진화

특정 디바이스에 종속적인 로직이 들어가 있으면 장기적으로 지속성을 위협하는 요인이 되므로 좋지 않다.

3.1.1 모든 것을 감지하기

브라우저에서 request할 때 브라우저의 사용자 에이전트 정보(user agent)를 담아서 보낸다.
파이어폭스14, 크롬 25 등 브라우저 이름, 버전 정보 os정보 등 다양한 정보가 항목별로 텍스트 문자열에 담겨져 있다.
이러한 절차를 사용자 에이전트 스니핑(user agent sniffing) 또는 디바이스 감지(device detection)라고 한다.

3.1.2 헛다리 짚기

그러나, 사용자 에이전트 정보를 통해 파악한 브라우저 환경이 현재 사용자의 브라우저 환경과 같다고 확신할 수 없다.(언제든지 변경가능한 부분이기 때문에)
매우 많은 모바일 디바이스에서 이미 변경하여 사용해오고 있는 이력이 있다.

3.1.3 '설정하고 잊어버리기'는 잊어버리자

안정성은 지속성에 비해 사소한 문제다.
현존하는 디바이스, 브라우저에 대해서만 작성할 수 있을 뿐 새로 나온 브라우저는 속수무책이다.
디바이스 감지는 도박과 같다. 그러므로 잊어버리자.

3.2 희소식 : 이런 상황에 대처할 수 있다.

클라이언트 측 기술(html, css, js)을 활용하면 이런 동적 브라우저 환경에서 '실제로' 일어나는 일을 확인할 수 있으면 더 책임감 있게 대처할 수 있다.

3.2.1 디바이스보다는 기능과 제약 사항

디바이스와 브라우저를 폼팩터(물리적인 속성)만으로 분류하면 웹을 디자일할 때 고려해야 할 정작 중요한 요인인 '속성'과 '제약 사항'을 놓치기 쉽다.

3.2.2 책임감 있게 미디어 쿼리하기

이단 마콧이 처음 제시한 반응형 디자인 워크플로 원칙에는
조건부 CSS 문장을 통해 콘텍스트에 따라 스타일을 적용하는 CSS3 미디어 쿼리를 사용한다는 점이다.
(처음 제시했던 것은 데스크탑을 우선으로 구성했다. 즉, 가장 큰 레이아웃부터 제작 후 미디어 쿼리를 통해 작은 화면에 맞춰나간다는 것을 의미한다.)

3.2.3 반응형으로 방향 전환하기

이단 마콧이 쓴 <반응형 웹디자인>을 보면 뒤로 갈수록 미디어 쿼리에 대한 원칙이 모바일 우선 또는 작은 화면 우선으로 변화는 것을 볼 수 있다.
즉 작은 것부터 시작해서 공간이허용하는 범위에서 좀더 복잡한 레이아웃을 구축하는 방식과 맞아떨어진다.

@media 쿼리에 대한 지원이 없다는 것 자체가 첫 번째 @media 쿼리다.

3.2.4 CSS 적용 여부 검사하기

미디어 쿼리 같은 최신 기능을 지원하는 브라우저에 적용할 수 있는지 검증하는 기능을 넣는 것이 좋다.
only all과 같은 미디어 쿼리로 감싸는 것도 한 가지 방법이다.

  • all은 CSS 1.0을 지원하는 브라우저라면 어디서나 인식
  • only는 미디어 쿼리를 지원하는 최신 브라우저에서만 동작
/* example */
@media only all{/* 미디어 쿼리를 지원하는 브라우저에 적용할 작은 뷰포트에 대한 스타일 */}
@media (min-width: 50em){/* 뷰포트 폭이 50em 이상인 스타일 */}
@media (min-width: 65em){/* 뷰포트 폭이 65em 이상인 스타일 */}

3.2.5 기본 브라우저에서도 스타일 유지하기

미디어 쿼리를 지원하지 않는 브라우저에서도 일정한 수준의 사용자 경험을 제공해야 한다.
only all 미디어 쿼리가 나오기 전에 배치하여 적용한다.

  • 안전한 스타일, 즉 font-weight, margin, padding 등은 거의 모든 브라우저에서 문제 없이 작동한다.
  • 물론 항상 테스트를 거치고 적용해야 한다.
/* example */
body{
  font-family: sans-serif;
  margin: 0;
} /* 기본 뷰포트용 스타일 */
@media only all{/* 미디어 쿼리를 지원하는 브라우저에 적용할 작은 뷰포트에 대한 스타일 */}
@media (min-width: 50em){/* 뷰포트 폭이 50em 이상인 스타일 */}
@media (min-width: 65em){/* 뷰포트 폭이 65em 이상인 스타일 */}

3.2.6 뷰포트 튼튼하게 만들기

전통적으로 렌더링할 폭을 다음과 같이 meta요소에 width-device-width를 지정하는 방식을 많이 사용했다.

W3C에서 뷰포트 스타일 정보를 지정하는 방식에 대한 표준을 마련했는데, CSS에서 처리한다.

@-webkit-viewport(width:device-width)
@-moz-viewport(width:device-width)
@-ms-viewport(width:device-width)
@-o-viewport(width:device-width)
@viewport(width:device-width)

@viewport를 지원하지 않는 브라우저에서는 기존 방법대로 사용할 수 밖에 없다.

cf: https://trentwalton.com/2013/01/16/windows-phone-8-viewport-fix/

3.2.7 다른 종류의 미디어 쿼리

3.3 자바스크립트로 기능 감지하기

자바스크립트를 이용한 기능 감지는 이미 오래전부터 있던 기법이다.
얼마 전까지만 해도 가장 기본적인 기능조차도 미리 확인한 뒤 사용해야 했다.

if(document.addEventListner){} /* 표준 방식 이벤트 리스터를 지원할 경우 */
else if(document.attachEvent){} /* 그렇지 않으면 IE의 attachEvent 를 사용한다. */

3.3.1 자바스크립트 기능 감지하기

다행히 웹 동향은 표준 API를 따르도록 유도하는 방향으로 발전하고 있다.
필요한 기능을 사용하기에 앞서 그 기능이 실제로 지원되는지 확인하는 작업을 자바스크립트의 기능 감지 기능으로 처리하는 사례가 흔해졌다.

// HTML canvas 요소가 지원되는지 확인하는 함수
function canvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

...

if(canvasSupported()){
  // 여기서 canvas API를 안심하고 사용할 수 있다.
}

3.3.2 CSS 기능 감지하기

CSS 기능을 테스트할 수 있는 enhance.js 스크립트는 페이지를 로딩하는 동안 다양한 진단 테스트 작업을 수행한다.
테스트를 통과하면 스크립트는 HTML 요소데 enhanced라는 클래스를 추가해 고급 CSS 속성을 사용하는 애플리케이션임을 구분하는데 사용한다.

3.3.3 기능 감지 프레임워크

표준 방식 웹사이트 테스트에 특화된 프레임워크로 모더나이저가 있다.(https://modernizr.com/)

모더나이저는 CSS의 특정 기능 지원 여부를 표시하기 위해 html 요소데 클래스를 추가하는 방식으로 간결하게 처리한다.

3.3.4 모더나이저 사용법

<script src="js/modernizr.js"></script>

모더나이저 테스트 작업이 실행되는 동안 프레임워크는 테스트 이름에 대한 자바스크립트 속성을 전역 오브젝트인 Modernizr에 보관하고 있다가 테스트를 통과하면 이 값을 true로 지정하고, 그렇지 않으면 false로 지정한다.

if(Modernizr.canvas){
  // canvas 기능이 지원될 경우
}
  • 모더나이저는 테스트 통과한 html요소에 테스트 이름으로 된 클래스를 추가
  • CSS 셀렉터를 이용해 특정 기능의 지원 여부를 검사
/* before */
.img-title{
  color: white;
  text-shadow: ...;
}

/* after */
.img-title{
  color: white;
}
.textshadow .img-title{
  color: blue;
  text-shadow: ...;
}

3.3.5 자바스크립트를 사용하지 않고 CSS 기능 감지하기

CSS 에서 사용

@supports 기능 사용 : 미디어 쿼리와 비슷한 문법

@supports ( display: flex){
  #content{
    display: flex;
  }
}

display: flex 스타일 기능을 사용할 수 있다면 적용하도록 하는 코드

JS에서 사용

CSS.supports API

if( CSS.supports( "(transition: none)" )) {
  // CSS transition이 지원되는 경우
}

3.3.6 supports를 위한 지원

@supports CSS 기능은 지원하지 않는 브라우저는 이 기능과 관련된 스타일을 그냥 무시해버리기 대문에 포함시켜도 문제가 발생하지 않는다.

그에 반해 JS에서 대응되는 기술인 CSS.supports는 이 기술 또한 지원되는지 확인하고 사용해야 된다.

3.3.7 사용자 에이전트 감지 : 다른 대안이 없을 때 최선의 방법

기능 지원 여부를 '감지할 수 없는' 원인은 브라우저마다 지원상태가 다르기 때문에 단순히 '예', '아니오'로 표현하기 힘든 경우가 있다.

이럴 때는 한 발 뒤로 물러서 기능 기반이 아닌 브라우저 기반 감지 기능을 사용하는 것이 현명한 선택이다. 그러나 이러한 경우는 최대한 피해야 한다.

그럼에도 불구하고 어쩔수 없이 사용해야 하는 경우 브라우저 기반이 아닌 기능 감지 기법을 최대한 동원해야 한다. 최후의 수단을 도입할 수 밖에 없는 경우의 예를 몇 가지 살펴보자

3.3.8 오버플로 지원 여부는 반드시 확인하기

CSS overflow는 지원 여부를 감지하는 자체가 거의 불가능 하다.
그 중에서 overflow: auto의 지원 여부를 콕 집어서 검사하려면 사용자의 개입이 필요하다.

overflow 감지 작업을 안전하게 사용할 수 있도록 도와주는 스크립트에 오버스로(Overthrow)라는 것이 있다.
1. overflow 기능 테스트를 수행
2. 사용자 에이전트 문자열을 점검
3. 테스트를 통과한 브라우저에 <html class="overthrow-enabled"> 항목 추가

이런 디바이스의 종속적인 기법은 브라우저에 독립적인 기능 감지 기법을 최대한 활용한 뒤 방법이 전혀 없을 때만 사용한다.

3.3.9 position: fixed를 조심하라

감지할 수 없는 위험한 CSS 속성의 또 다른 예로 position: fixed를 들 수 있다.
해결하기 위한 방법에 대해서는 fixed-fixed를 참고
(https://github.com/filamentgroup/fixed-fixed)

CSS 선택자에서 클래스 한정자를 이용해 처리한다.

.fixed-supported #header{
  position: fixed;
}

3.3.10 지원하지 않는 브라우저 지원하기

지원되지 않는 브라우저에서 기능을 에뮬레이션하는 심(shim, shimming) 폴리필(polyfill) 기법이 널리 사용되고 있다.

3.3.11 심

https://github.com/aFarkas/html5shiv
The HTML5 Shiv enables use of HTML5 sectioning elements in legacy Internet Explorer and provides basic HTML5 styling for Internet Explorer 6-9, Safari 4.x (and iPhone 3.x), and Firefox 3.x.

자바스크립트를 이용해 document.createElement 메서드로 생성된 모든 요소에 대해 다른 요소처럼 스타일을 적용할 수 있게 하는 우회 기법.

3.3.12 반응형 디자인 폴리필

오래된 브라우저에 폴백 기능을 제공하는 미래의 API를 흉내낸 심
-폴 아이리시-

항상 먼저 네이티브로 지원되는지부터 확인해야 한다.(꼭 폴리필이 필요한지 부터 확인)

사용여부를 결정하는 주요 기준 3가지

  1. 그 기능을 통해 UX가 얼마나 향상 되는지
  2. 페이지에 폴리필을 추가함으로써 성능 저하가 얼마나 발생하는지
  3. 코드베이스에서 이를 빠르고 문제없이 삭제할 수 있는지

3.3.13 매치미디어: 자바스크립트를 이용한 미디어 쿼리

https://developer.mozilla.org/ko/docs/Web/API/Window/matchMedia

if(window.matchMedia("(min-width: 45em)").matches){
  //@media (min-width: 45em)
}

3.3.14 IE에서 미디어 쿼리 사용하기: IE야, 제발 응답해줘

https://github.com/scottjehl/Respond

respond.js 사용

<!--[if lt IE 9]<script src="respond.js"></script><![endif]-->

3.3.15 정적 CSS를 이용한 폴리필 자제하기

오래된 IE에 미디어 쿼리 지원을 하기 위한 다른 방법으로 IE에 CSS 규칙을 추가로 제공해 반응형 디자인의 광범위한 중단점에서 스타일을 강제로 랜더링하게 만드는 방법이다.

대표적인 예로 Sass와 같은 CSS전처리기가 있다.

3.3.16 아무것도 하지 않기

마지막으로 반응형 사이트를 그대로 오래된 IE에 있는 그대로 제공하는 것이다.
max-width값을 적절히 설정하여 사용할 수도 있다.

3.4 책임감 있게 테스트하기

모든 사이트에서 잘 작동하게 하는 방법으로 실제 디바이스에서 직접 테스트하는 것만큼 확실한 것은 없다.

이런 디바이스를 모두 구매하는 것은 현실적으로 어렵고 비용도 많이 든다.

  • 디바이스 랩 : 그래서 여러 가지 디바이스를 테스트할 때 일반적으로 근처에 디바이스 테스트 랩을 활용할 수 있다.
  • 디바이스 에뮬레이터 : 물론 실제 디바이스와 다른게 나타나는 단점이 존재한다. 그러나 매우 신뢰할 만한 방식
  • 강력한 개발 도구가 갖춰진 브라우저 : 크롬, 파이어폭스 개발 도구

웹사이트 디자인 및 기능과 관련해 필자가 하는 질문들
1) 웹사이트가 로딩되어 나타나기까지 걸리는 시간이 적절한가?
2) 핵심 콘텐츠와 기능에 접근해서 사용하는 데 문제가 없는가?
3) 레이아웃을 개선한 사항이 해당 디바이스에 적합한가?
4) 텍스트를 쉽게 훑어볼 수 있는가? 라인의 길이가 가독성을 높이는가?
5) 디바이스에서 흔히 제공하는 입력장치(터치, 마우스, 키보드 등)에서 사이트를 조작하고 보는 데 문제가 없는가?
6) 사용자가 탭하는 과정에서 페이지 내 옆에 있는 다른 항목을 건드리지는 않는가?
7) 화면 방향이 바뀌거나 뷰포트 크기가 변하거나 폰트 크기가 달라져도 레이아웃이 깨지지 않는가?
8) (보이스오버와 같은) 보조 기술을 사용하는 디바이스에서 콘텐츠를 읽을 때 의미가 잘 전달되는가?
9) 페이지 스크롤을 효율적으로 처리하는가? 애니메이션도 자연스럽게 표현되는가?

profile
개발관심자

0개의 댓글