deute의 모든 글

CSS3 Media queries Vol.1

얼마전에 One Web 에 대해서 잠깐 언급한적이 있었는데.. One Web 을 구현하기 위해 꼭 알아야 하는 기술인 CSS3 Media queries Module 에 대해서 아주 조금 건드려 볼까 합니다. 예전에 스터디에서 했던 주제를 고친것으로 계속 발전시켜 볼 예정입니다.

개요

HTML4.01 과 CSS2 에서 이미 media type에 대응하는 스타일 시트를 따로 구성할 수 있는 방식을 지원하고 있었지만, 미디어에 대한 특징이나 범위를 명확하게 지정할 수 없었기 때문에, screen, print, handheld 정도만 사용 되었던것이 사실이었습니다. 그래서 CSS3에서는 좀 더 미디어의 특징을 잘 표현할 수 있는 방법을 확장하고 세분화한 스팩을 제공하게 되었습니다. 그것이 CSS3 Media Queries Module 이 되겠습니다. 앞서 언급했지만 HTML4, CSS2에서도 media type에 따른 css를 분기하는 방법은 지원하고 있었습니다. 그예를 보면 HTML4.01 에서는 스타일 시트 정의 시에 media를 선택 할 수 있습니다.


<STYLE type="text/css" media="projection">
    H1 { color: blue}
</STYLE>
<link rel="stylesheet" type="text/css" media="screen" href="sans-serif.css">
<link rel="stylesheet" type="text/css" media="print" href="serif.css">

참고 URL 은 다음과 같습니다.

CSS2에서 정의된 media type 정의방법은 다음과 같습니다.


@media screen {
    * { font-family: sans-serif }
}

참고 URL은 다음과 같습니다.

  • http://www.w3.org/TR/CSS21/media.html

위의 방법은 출력될 media의 type만 결정 할 수 있기 때문에 같은 미디어의 다양한 환경을 모두 수용하기에는 어려움이 많습니다. 하지만 CSS Media queries Module을 이용하면 디바이스의 종류뿐만 아니라 다양한 조건을 이용하여 Style을 분기할 수 있게 됩니다.

문법 및 사용법

미디어 쿼리의 문법 및 사용법은 다음과 같습니다.

media_query_list: <media_query> [, <media_query> ]*
media_query: [[only | not]? <media_type> [ and <expression> ]*]
| <expression> [ and <expression> ]*
expression: ( <media_feature> [: <value>]? )
media_type: all | aural | braille | handheld | print |
projection | screen | tty | tv | embossed
media_feature: width(가로 너비) | min-width(최소 가로 너비) | max-width(최대 가로 너비)
| height(높이) | min-height(최소 세로 높이) | max-height(최대 세로 높이)
| device-width(디바이스의 기본 가로 너비)
| min-device-width(디바이스의 기본 최소 가로 너비) | max-device-width(디바이스의 기본 최대 가로 너비)
| device-height(디바이스의 세로 높이) | min-device-height | max-device-height
| aspect-ratio(화면 비율) | min-aspect-ratio(최소 화면 비율) | max-aspect-ratio(최대 화면 비율)
| device-aspect-ratio(디바이스의 화면 비율)
| min-device-aspect-ratio(디바이스의 최소 화면 비율) | max-device-aspect-ratio(디바이스의 최대 화면 비율)
| color(색상당 비트수) | min-color(최소 색상당 비트수) | max-color(최대 색상당 비트수)
| color-index(user agent가 지원하는 팔레트의 색상 갯수)
| min-color-index(user agent가 지원하는 팔레트의 색상의 최소 갯수) | max-color-index(user agent가 지원하는 팔레트의 색상의 최대 갯수)
| monochrome(흑백 장치에서 픽셀 당 비트의 개수)
| min-monochrome(흑백 장치에서 픽셀 당 비트의 최소 개수) | max-monochrome(흑백 장치에서 픽셀 당 비트의 최대 개수)
| resolution(해상도) | min-resolution(최소 해상도) | max-resolution(최대 해상도)
| scan | grid

무슨소리인지 저도 잘모르겠습니다. ㅎㅎ 미디어 쿼리는 대소문자를 구별하지 않으며 알수없는 미디어의 경우에는 false 를 리턴한다고 합니다. 🙂

Media Type

CSS3 Media Queries Module 에서 정의하는 Media의 종류는 다음과 같습니다.

  • all : 모든 미디어 타입
  • aural : 음성 합성 장치
  • braille : 점자 표시 장치
  • handheld : 손으로 들고 다니면서 볼 수 있는 작은 스크린에 대응하는 용도
  • print : 인쇄 용도
  • projection : 프로젝터 표현 용도
  • screen : 컴퓨터 스크린을 위한용도
  • tty : 디스플레이 능력이 한정된, 텔렉스(teletype), 터미날, 또는 수동 이동 장치 등, 고정 피치(fixed-pitch:폭이 일정) 글자를 사용하는 메디아를 위한 의도 “tty” 메디아 타입에서 제작자는 픽셀(pixel) 단위를 사용하여서는 안됨
  • tv : 음성과 영상이 동시 출력되는 TV와 같은 장치
  • embossed : 페이지에 인쇄된 점자 표지 장치

뭔가 겁네 많은것 같아요. 일단 대충 이정도로 알아보고 실제 사용해보면서 알아보는거로 하는게 좋겠어요.

사용예

외부 파일을 사용하는법


&lt;link rel="stylesheet" media="screen and (min-device-width: 200px)" href="example2.css" /&gt;
&lt;link rel="stylesheet" media="screen and (min-device-width: 800px)" href="example1.css" /&gt;

예제) 아이폰과 웹브라우저에서 비교 http://mydeute.com/media_queries/1.html
디바이스의 가로값이 최소 200px이상이면 example2.css를 로드, 디바이스의 가로값이 최소 800px이상이면 example1.css도 같이 로드함

<style> 태그를 이용하는법.


&lt;style type="text/css" media="screen and (min-device-width: 200px)"&gt;
body { background-color: #0F0; }
&lt;/style&gt;
 &lt;style type="text/css" media="screen and (min-device-width: 800px)"&gt;
body { background-color: #F00; }
&lt;/style&gt;

예제) 아이폰과 웹브라우저에서 비교 http://mydeute.com/media_queries/2.html

CSS 파일내에서 사용하는 방법


&lt;style type="text/css"&gt;
@media screen and (min-device-width: 200px) {
body { background-color: #0F0; }
}
@media screen and (min-device-width: 800px) {
body { background-color: #F00; }
}
&lt;/style&gt;

예제) 아이폰과 웹 브라우저에서 비교 http://mydeute.com/media_queries/3.html

only, not

media type 을 선별하는 과정중에 선택할 수 있는 접두어

only

@media only handheld {
body { background-color: #F00; }
}
not

@media not screen {
body { background-color: #F00; }
}

features

width

user-agent의 현재 width 값에 대응해서 반응


@media screen and (width: 980px) {
body { background-color: #F00; }
}

예제) 아이폰과 브라우저에서 비교 http://mydeute.com/media_queries/4.html user-agent의 가로너비가 980px일때 배경이 빨간색으로 표현

min-width

최소 가로 너비를 지정하고 지정된 값보다 너비가 길면 그값에 대해 반응


@media screen and (min-width: 981px) {
body { background-color: #F00; }
}

예제) 아이폰과 브라우저에서 비교 http://mydeute.com/media_queries/5.html user-agent의 가로너비가 981px 이상 일때 배경이 빨간색으로 표현

max-width

최대 가로 너비를 지정하고 지정된 값보다 너비가 좁은 경우에만 그 값에 대해 반응


@media screen and (max-width: 980px) {
body { background-color: #F00; }
}

예제) 아이폰과 브라우저에서 비교 http://mydeute.com/media_queries/6.html user-agent의 가로너비가 980px 이하 일때 배경이 빨간색으로 표현

응용 1

조합이 가능해짐 0~ 320px 까지는 배경이 파란색 321px~ 800px 까지는 배경색이 빨간색 801px이상의 너비에서는 녹색 배경을 만들고 싶다면


@media screen and (max-width: 320px) {
body { background-color: #00F; }
}
@media screen and (min-width: 321px) and (max-width: 800px) {
body { background-color: #F00; }
}
@media screen and (min-width: 801px) {
body { background-color: #0F0; }
}

예제 브라우저의 가로 너비를 조절해보면서 보면 됨 http://mydeute.com/media_queries/7.html

응용 2

브라우저 화면의 가로 너비에 따라 레이아웃을 변경할수도 있음


@media screen and (max-width: 320px) {
#wrap { width:320px }
#left {  border:2px solid #F00; width: 316px }
#contents{ border:2px solid #0F0; width: 316px }
#right { border:2px solid #00F; width: 316px }
}
@media screen and (min-width: 321px) and (max-width: 800px) {
#wrap { width:800px }
#left {  float: left; border:2px solid #F00; width: 196px }
#contents{ float: left;border:2px solid #0F0; width: 596px }
#right { clear:both;border:2px solid #00F; width: 796px }
}
@media screen and (min-width: 801px) {
#wrap { width:100% }
#left {  float: left; border:2px solid #F00; width: 23% }
#contents{ float: left;border:2px solid #0F0; width: 50% }
#right { float: left;border:2px solid #00F; width: 23% }
}

예제) http://mydeute.com/media_queries/8.html

아주 기본적인 미디어 쿼리의 사용법에 대해 알아보았습니다.
이 다음에는  제가 현재 제블로그 스킨을 좀 바꿔보려고 하고 있으므로 실제 적용기를 다뤄볼까 합니다.

그럼 그동안 즐거웠어요

작업의 범위와 웹 접근성 그리고 웹 접근성 품질마크

2002년말 당시에  저는 모 에이전시에서 초대형 사이트의 리뉴얼 프로젝트 진행 했었습니다. 이 사이트는 그 당시에도 IE6 뿐 아니라 IE5.5, IE5,IE4,NS4.7, MAC IE5.2 등등 그당시의 소위 잘나가던 브라우저들을 모두 맞춰야했었던 프로젝트였습니다. 페이지의 레이아웃을 테이블로 사용하긴 했지만 크로스브라우징은 구현하려고 노력을 많이 했던 프로젝트 였습니다.

그런데  사실 제가 다녔던 그회사는 좀 특이했습니다. 크로스 브라우징은 기본으로 해야한다는 마음가짐을 가진회사였고 제가 첫번째로 다닌 회사가 그 곳이었기 때문에 저는 크로스 브라우징에 대한 생각이 너무 당연 했습니다. 그런데 그다음에 옮긴 두번째 회사에서는 굳이 크로스 브라우징은 클라이언트가 원하지 않으면 신경쓰지 않아도 된다였습니다.

뭐 알았다고 했지만 이미 몸에 밴 습관(라인을 위한 1*1px 빈이미지, padding margin 트릭등)들은 변하지 않았습니다. 오히려 크로스 브라우징이 IE6만 신경쓰는것보다 더 쉬웠을 정도였으니까요. 공수가 많이 드는일도 아니었습니다. 내가 기본이라고 생각하는 범위가 넓으면 넓을수록 내가 얻어가는것과 결과물의 퀄리티는 넓어 질 수 밖에 없다고 생각합니다.

요 몇해사이 웹 접근성 품질마크가  나름 이슈가 되고 있습니다. 웹 접근성 연구소온라인 자문 서비스라는 것이 있는데요. 부족하지만 저도 자문을 조금씩 하고 있는데, 자문을 좀 하다보니 웹 접근성 제고와 방법에 대한 자문 요청이 아닌 NIA에서 시행하는 웹 접근성 품질마크의 기준이나 방법에 대한 자문 요청이 많아 지더라구요. 그만큼 웹 접근성 품질마크가 한국 웹 접근성에 큰 영향을 주었다고 생각되기도 하지만, 웹 접근성의 향상을 위한 토론과 문의등을 해야하는 게시판에서 품질마크의 기준에 대해서 문의가 나오는것은 좀 문제가 있다고 봅니다. 이 문제는 자문을 요청하는 사람도, 자문을 하는사람도, 그리고 게시판을 관리하는사람 그리고 품질마크를 담당 하는사람 모두에게 조금씩 문제가 있다고 봅니다.

일단 제가 몇번 얘기했지만 한국의 웹 접근성은 웹 접근성 품질마크가 전부가 아닙니다. 웹 접근성 품질마크는 최소한의 것이라고 생각합니다. 웹 사이트를 만들어서 납품하는 분들은(까놓고 말하겠습니다.) 웹 접근성을 고려해 웹 사이트를 만드는것인지 웹 접근성 품질마크를 고려해서 웹 사이트를 만드는것인지 잘모르겠습니다. 대부분의 업체들은 웹 접근성을 고려해 웹 사이트를 만들다 보니 부가적으로 품질마크 획득도 가능했다 정도겠지요:) 정말 이런것이길 바라겠습니다.

서론에서도 말한것과 같은 느낌으로 내가 항상 웹 접근성을 지켜서  웹사이트를 만들것이고 그것을 위해 노력하겠다라고 한다면 만들어진 웹페이지의 접근성의 퀄리티는 훨신 좋아 질것이고 쉽게 생각이 들것입니다. 웹 접근성을 고려한 사이트를 만들때 “어느부분까지만 지원하면 되”가 아니라 “이부분도 지원하면 더 좋아져”가 항상 드는 생각이기를 바랍니다.

웹 접근성  품질마크는 언제나 최종목적이 아닌 웹 접근성 구현을 위한 작은 한 단계 또는 부가적으로 얻어지는 작은 선물이라고 보시는게 좋을것 같습니다.

또한 웹 접근성 품질마크측에서도 좀더 능동적인 자세를 보여주었으면 하는 바램입니다. 자문게시판에 평가 카테고리가 있긴하지만 제 생각에는 품질마크는 별도의 게시판을 따로 구성하여 관리하는것이 좋을것 같습니다. 너무 영향력이 커져버린 웹 접근성 품질마크이기 때문에, 좀더 능동적이고 개방적인 제도가 되었으면하는 개인적인 바램입니다. 우리나라의 웹 접근성 향상을 위해 노력을 많이 해주셨는데 맨날 불평 불만만 말씀드려서 죄송합니다.

자문을하는 저도 좀더 열심히 공부하고 다각도로 생각의 폭을 넓혀서 항상 더 많은 도움을 드릴수 있도록 노력하겠습니다. 제가 아직은 많이 부족하지만 열심히 하는 모습은 보여드릴려고 노력하겠습니다.

올해는 만들어지는 모든 사이트가  웹 접근성은 기본으로 지켜지는 그런 한해가 되었으면 좋겠습니다.

웹 페이지의 내실을 다져야 할때

예전에 웹 사이트를 만들때 사람들이 흔히 하던 얘기가 “한국은 네트워크 속도가 빠르니, 페이지 용량은 그렇게 신경쓰지않아도 괜찮아!” 라는 것이었습니다. 그래서 사람들은 퀄리티 좋고 화려한 사이트를 만들기 시작했죠. 플래시도 사용하고, 큰 이미지도 쓰고 해서 화려한 사이트를 만들기 시작 했는데;….

갑자기 스마트폰이니 아이폰이니 하는 상대적으로 느린 네트워크를 이용하고 작은 화면을 사용하는 환경이 추가가 되었습니다. 그래서 사람들은 작은 화면과 느린 네트워크에 최적화를 시킨 모바일 전용 사이트를 만들기 시작 했습니다. 작은 화면에 맞추려다보니 콘텐츠가 빈약해지기도 했습니다. 그래도 많은 모바일 전용 사이트가 생겨서 그냥 그런데로 사용을 했죠. 그런데 이제는 아이패드나 갤럭시탭 같은 화면은 크지만 이동하면서 사용하는 환경이 추가 되었습니다. 이제 웹 사이트를 만드는 사람은 어떻게 대응할까요? 또 아이패드 전용, 갤러시탭 전용 페이지를 만드시겠습니까?

물론 환경이 되고 돈이 가능하고 그렇다면 각 환경에 맞는 웹 페이지를 따로 만드는것이 가장 좋은 방법일지 모릅니다. 각 환경별 사이트를 만드는데 곱절의 시간이 들고 그 사이트들을 관리하는데 또 곱절의 시간과 인력이 투입 되어야 합니다. 그냥 원래 페이지를 내용에 충실한, 그리고 어떤기기에서도 무리없이 이용할 수 있게 만들수 있지 않을까요?

제가 보기에 모바일 사이트들을 보면 구멍난 곳을 계속 그때 그때 땜빵하는 처리 방식으로 밖에 안보입니다. 앞으로 얼마나 다양한 환경에서 웹페이지를 보게 될지는 아무도 모릅니다. TV에서도 보고 냉장고에서도 볼지 모릅니다. 손목시계만한 곳에서 웹 페이지를 볼지도 모릅니다. 그럴때마다 전용 페이지를 만들 수는 없죠. 현재는 타겟 기기가 얼마 안되지만 이제는 몇몇 기기만 대응해서 웹 페이지를 만들어서는 안될것입니다. 그래서 One Web 이 중요합니다.

이미 CSS3의 미디어 쿼리등의 기술이 많이 소개 되었고 많은 곳에서도 적용이 되고 있습니다. 하나의 페이지를 만들어서 다양한 환경에서 웹을 볼수 있게 해주는 방법은 얼마든지 있습니다. 또한 특정기기에 종속적인 기술은 웹 페이지에서는 더 이상 사용해서는 안될지도 모릅니다. 아님 사용하더라도 그러한기술들이 표현되지 않을때의 대안을 준비해야 할것입니다. 이렇게 만든 페이지는 어떤 환경에서도 웹 페이지로서의 역할을 충실히 해낼것 입니다. 저는 그런 웹 페이지가 많이 생기길 바라고 있습니다.

중국출장

중국 북경 출장을 1주일간 다녀왔습니다. 해외를 안가본것은 아니었지만 중국은 처음이었고 갑자기 일정이 잡혀서 사전에 정보를 전혀 알아보지 않고 갔습니다. 북경에 대한 일차적인 소감은

  1. 사람들이 머리를 잘 안감는다(아침에 머리 떡져서 출근하는 사람들이 많습니다.)
  2. 냄새가 좀난다.(한국사람의 마늘냄새와는 다른 약간 )
  3. 생각보다는 도시가 잘 정비되어있다.
  4. 지하철이 싸다.
  5. 공기가 상당히 안좋다.
  6. 교통신호를 잘지키지 않는다.(뭔가 암묵적인 시스템이 있어보이나 1주일 만에 마스터 하기란…)
  7. 차가 겁네 많다 한국 차도 많다
  8. 영어쓰기는 쉽지않다; 중국어 모르면 힘들다;

입니다.

주말에는 천안문 광장과 자금성을 갔는데 흠 모랄까  크기는 엄청 큰데… 보존이 잘 안된 느낌도 들고 암튼 저는 우리나라의 경복궁이 훨신 좋더라구요 🙂

역시 썰렁하여 사진 몇장 올립니다.

중국산 맥주들;자금성 앞에서 또라이 듀트자금성 옆길천안문후

밤 12시의 자금성LED 천장북경의 지하

먹은 음식들은 나중에;;;

img에 onerror이벤트를 tag의 속성이 아닌 자바스크립트로 등록하기

img가 로드가 안될때 기본이미지를 보여주고 싶을때 onerror를 사용합니다.


&lt;img src="기본이미지.png"  alt="대체텍스트" onerror="this.src='대체이미지.png';" /&gt;

이런식으로 사용을 하는데;  문제는 validator 에서 onerror은 에러로 뱉어내버리죠…
그냥 안쓰거나 밸리데이터 따위 무시해주면 되겠지만 onerror도 사용하고 밸리데이터도 통과해야하는 경우가 얼마든지 있을수있죠.
그래서 그냥 이벤트를 자바스크립트로 등록하는것을 만들어봤습니다.

핵심은 IE와 IE외의 브라우저가 이벤트 등록하는것이 다르다는것입니다.
IE의경우에는 attachEvent 를 이용해서 onerror를 등록하고  일어난이벤트의 srcElement의 src값을 변경해주면 됩니다.


"이미지DOM".attachEvent("onerror",function(e) { e.srcElement.src ="images/pic_noimg.gif"})

그외 Opera, FF, safari, chrome 에서는


"이미지DOM".onerror = function(e) { e.target.src = "images/pic_noimg.gif";};

이렇게 해주니 되더라구요. 사실 addEventListener를 사용해볼까 했었는데 귀찮아서 패스=_=
그럼 이만(제목에 비해 겁네 포스팅이 허접하군요=_=/ )