[CSS3] 미디어 쿼리(Media Query)의 only 키워드

CSS3 미디어 쿼리 모듈은 웹의 미래에 있어서 굉장히 중요한 의미를 갖습니다. 미디어의 종류(type)별로만 스타일을 다르게 줄 수 있었던 이전과는 달리 미디어 각각의 특성(feature)에 맞춰서 스타일에 변화를 줄 수 있기 때문이지요.

그 배경에는 웹에 접근할 수 있는 장치의 다양성이 점점 커지는 현상과, 이렇게 다양한 장치에서의 뷰를 효과적으로 컨트롤하기 위한 W3C의 고심이 있습니다.

그리고 놀랍게도 W3C의 고심은 우리가 생각하는 것보다 훨씬 일찍 시작되었습니다. 우리에게 익숙한 오래된 표준, 즉 HTML 4.01에서 이미 이런 미래를 고려한 장치를 만들어 놓았기 때문입니다. HTML 4.01이 표준이 된 게 1999년이니 벌써 10년도 전이네요.

HTML 4.01 이전에도 관련된 내용이 있을지도 모르지만 확인은 안 해봤습니다.

이 글에서는 HTML 4.01이 미디어 쿼리를 위해 어떤 대비를 했는지, 그리고 그 결과 만들어진 미디어 쿼리의 only라는 키워드에 대한 얘기를 해볼까 합니다. 미디어 쿼리가 무엇이고, 또 어떻게 사용하는지에 관해서는 이미 웹에 많은 정보가 있으니 다루지 않습니다.

HTML 4.01에서 적용할 미디어를 결정하는 방식

HTML 4.01에서 link 요소를 사용해서 외부 CSS 파일을 불러올 때 대상(target) 미디어는 아래처럼 결정됩니다.

† 원문 링크: HTML 4.01 6.13 Media descriptors

미래의 HTML에서는 새로운 미디어 종류가 추가될 수 있고, 대상 미디어를 제한하는 기준이나 값(parameterized values)도 도입될 수 있다. 이런 확장에 대비해서 표준에 부합하는 사용자 에이전트(conforming user agent)는 media 속성을 반드시(MUST) 아래처럼 해석해야 한다.

  1. 결과 값은 미디어 종류를 쉼표(,)로 구분한 리스트이다. 예를 들어서,

    media="screen, 3d-glasses, print and resolution > 90dpi"

    이 속성 값은 아래처럼 변환된다.

    "screen"
    "3d-glasses"
    "print and resolution > 90dpi"
  2. 각각의 항목은 영문 대소문자, 0~9까지의 숫자, 하이픈이 아닌 첫 번째 문자 바로 앞에서 끊는다. 위 항목은 아래처럼 정리된다.

    "screen"
    "3d-glasses"
    "print"
  3. 각각의 항목은 대소문자를 구별해서 HTML 4.01에 정의된 미디어 종류인지 검사한다. 사용자 에이전트는 대소문자가 맞지 않는 항목을 무시할 수도 있다(MAY). 위 예에서는 screenprint가 최종적인 대상 미디어가 된다.

두 번째 단계가 쉽게 와 닿지 않을 수도 있습니다. 왜 띄어쓰기 앞에서 정리할까 의아하게 생각할 수도 있는데요. 그 이유는 상위 호환성(forward compatibility)을 고려했기 때문입니다. 그럼 상위 호환성이란 무엇일까요?

상위 호환성

위키피디아는 상위 호환성을 이렇게 설명하고 있습니다.

상위 호환성이란 어떤 시스템이 미래 버전의 시스템을 위해 만들어진 입력을 적절하게(gracefully) 받아들이는 능력을 말한다. 상위 호환성을 갖는 기술의 도입은 오래된 장치가 새로운 장치에서 생성된 데이터의 일부를 인식할 수 있다는 의미를 내포한다. [중략] 상위 호환성을 지원하는 표준은 구 버전이 새로운 표준의 데이터를 받고(receive), 읽어들이고(read), 표현하고(view), 실행(play or execute)할 수 있다.

상위 호환성과 확장성(extensibility)은 비슷한 개념이지만 둘은 동일하지 않다. 상위 호환성을 갖는 시스템은 미래 버전 시스템의 데이트를 받아들일 수 있고, 받아들인 데이터 중에서 “현재 알고 있는” 부분만 골라낼 수 있다. 예를 들어서 텍스트만 인식하는 워드 프로세서는 미래 버전 문서로 만든 이미지 데이터를 무시한다. 확장성 있는 시스템은 새로운 입력 형식을 완전히 다룰 수 있도록 업그레이드 가능한 시스템을 말한다. 예를 들어서 확장성 있는 텍스트 기반 워드 프로세서는 이미지를 다룰 수 있도록 업그레이드가 가능하다.

여기서 말하는 상위 호환성의 핵심은 미래 버전의 데이터 중에서 자신이 이해하는 부분만 인식한다는 점입니다. 앞에서 설명한 예 중 "print and resolution > 90dpi"를 미래 버전의 데이터라고 생각해보면 그 중 자신이 이해하는 부분, 즉 "print" 부분만 인식한다는 점이지요.

† 지금은 미디어 쿼리가 일반화되어 있지 않아서 모든 장치에 적용할 스타일 시트를 지정하고, 미디어 쿼리는 선택적으로만 적용하는 경우가 많습니다. 하지만 미래에는 모든 외부 스타일 시트를 미디어 쿼리를 사용해서 불러올 수도 있습니다. 그런 상황에서 미디어 쿼리를 지원하지 않는 브라우저가 있다면 스타일 시트를 전혀 인식하지 못할 수도 있기 때문에 이렇게 해서 상위 호환성을 고려하는 것이 아닐까 하는 생각이 듭니다.

미디어 쿼리의 대응

이렇게 HTML 4.01의 media 속성 해석 방식이 상위 호환성을 갖기 때문에 우리가 일반적으로 의도하지 않은 문제가 생깁니다. 바로 미디어 쿼리를 지원하지 않는 브라우저의 문제이지요.

예를 들어서 아래처럼 미디어 쿼리를 사용했다고 생각해보겠습니다.

<link rel="stylesheet" type="text/css" media="all and (min-width:600px)" href="test_media_query.css" />

미디어 쿼리를 지원하는 브라우저라면 뷰포트 크기가 600px 이상인 미디어에서만 test_media_query.css 파일을 읽게 됩니다. 하지만 HTML 4.01은 지원하지만 미디어 쿼리라는 새로운 표준을 지원하지 않는 브라우저라면 어떨까요? CSS를 읽어 들일까요? 아니면 읽지 않을까요?

미디어 쿼리를 지원하지 않는 브라우저는 위에 설명한 방식의 결과 값, 즉 and 앞 띄어쓰기 앞까지만 읽어서 all로 적용 대상을 인식합니다. 따라서 all 뒤에 있는 조건과 상관 없이 CSS를 읽게 됩니다.

하지만 미디어 쿼리를 쓰는 경우 대부분은 미디어 쿼리를 지원하지 않는 브라우저에서는 인식하지 않기를 바랄 것입니다. 이런 상황을 고려해서 미디어 쿼리 표준은 only라는 키워드를 지원합니다.

only는 단어의 의미 그대로 미디어 쿼리를 지원하는 브라우저에서만 스타일 시트를 인식하게 한다는 뜻입니다. only는 두 가지 방식으로 처리됩니다. 먼저 미디어 쿼리를 지원하는 브라우저는 미디어 쿼리 표준에 따라서 only가 없는 것처럼 해석합니다. 말 그대로 대상 설정에는 아무 의미가 없는 것이죠.

그 다음으로 미디어 쿼리를 지원하지 않는 브라우저에서는 HTML 4.01 표준에 따라서 해석됩니다. 예를 들어서 아래처럼 지정했다면,

<link rel="stylesheet" type="text/css" media="only all and (min-width:600px)" href="test_media_query.css" />

대상 미디어의 결과 값은 첫 번째 띄어쓰기 앞인 only가 되고, 이 값은 HTML 4.01에 정의된 미디어 종류가 아니므로 무시됩니다.

브라우저의 지원

길게 설명했지만 제가 얘기하려는 의도는 하나입니다. 미디어 쿼리를 지원하는 브라우저만 고려한다면 반드시 only 키워드를 사용해야 한다는 점입니다. 그런데 미디어 쿼리를 설명하는 내용에 only 키워드는 빠지지 않고 들어가지만 막상 예제를 보면 사용하는 경우가 많지 않습니다. 왜 그럴까 궁금해서 테스트를 해봤습니다.

그러려면 먼저 미디어 쿼리를 지원하지 않는 브라우저를 확인해야 하는데요. 먼저 인터넷 익스플로러(이하 IE) 6, 7, 8은 위에서 설명한 HTML 4.01의 media 속성 해석 방식을 지키지 않았습니다. 그냥 전체를 인식해서 알고 있는 미디어 종류가 아니니 무시하는 것으로 생각합니다.

IE를 제외하면 미디어 쿼리를 지원하지 않는 브라우저 찾기가 정말 어렵습니다. 억지로 찾아낸 브라우저가 파이어폭스(이하 FF) 3.0.17 버전인데 IE와 달리 위에 설명한 방식대로 media 속성을 지원하는 것으로 판단했습니다.

그리고 크롬 브라우저도 확인을 해봤는데 2008년에 처음 발표된 1.0 버전도 제한적으로 미디어 쿼리를 지원하더군요. 그래서 제대로 해석하는지 확인을 못했습니다.

정리하자면 IE 8 이하 버전을 제외하면 대중적인 모든 브라우저가 미디어 쿼리를 지원합니다. 그리고 IE 8 이하 버전은 media 속성을 제대로 해석하지 않기 때문에 only 키워드를 사용하지 않아도 별다른 문제가 없습니다. 대부분의 미디어 쿼리 예제들이 only 키워드를 사용하지 않는 것도 현실적으로 문제가 없기 때문이라고 생각했습니다.

테스트 케이스

아래 소스의 렌더링 결과를 IE 8, FF 3.0.17, FF 4.0.1 버전에서 각각 확인해봤습니다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>[Test] CSS media query</title>
<link rel="stylesheet" type="text/css" media="all and (min-width:9999px)" href="test_media_query.css">
<style type="text/css">
@media all and (min-width:600px) {
	div {background:blue; color:#fff;}
}
</style>
</head>
<body>
	<div style="width:600px; height:10px; background:maroon !important;"></div>
	<div>
		media query test!
	</div>
</body>
</html>

test_media_query.css 파일에는 아래와 같은 스타일을 지정했습니다.

div {background:yellow; color:green; font-weight:bold;}

아래에 브라우저 각각의 렌더링 결과를 이미지로 볼 수 있습니다. 모든 결과는 뷰포트 width가 601px 이상, 9998px 이하인 상태로 캡처했습니다.

브라우저별 미디어 쿼리 테스트 결과

IE 8: 미디어 쿼리를 지원하지 않고 media 속성도 제대로 해석하지 않는 브라우저

외부 스타일 시트와 style 요소로 지정한 문서 스타일 시트 모두 해석하지 않아서 스타일이 아무 것도 적용되지 않습니다.

FF 3.0.17 : 미디어 쿼리를 지원하지 않지만 media 속성은 제대로 해석하는 브라우저

only 키워드가 없고 media 속성을 정확히 해석하기 때문에 min-width:9999px 조건과 상관 없이 외부 스타일 시트를 인식합니다. 하지만 문서 스타일 시트는 인식하지 않는 결과를 볼 수 있습니다. 그 이유는 문서 스타일 시트의 style 속성 내부는 HTML이 아닌 CSS의 영역이기 때문입니다. 미디어 쿼리를 지원하지 않는 브라우저라면 CSS 2를 기준으로 @media 규칙을 해석할 것이고, CSS 2에는 위에 설명한 방식을 정의하지 않고 있기 때문입니다.

FF 4.0.1 : 미디어 쿼리와 media 속성 모두를 제대로 해석하는 브라우저

min-width:9999px 조건을 만족하지 못하기 때문에 외부 스타일 시트는 인식하지 않습니다. 하지만 style 요소에 지정한 스타일은 min-width:600px 조건을 만족하기 때문에 정확하게 적용되는 것을 볼 수 있습니다(외부 스타일 시트를 인식하지 않는 것은 font-weight가 적용되지 않는 것으로 확인할 수 있습니다).

† 미디어 쿼리를 지원하지 않는 브라우저가 의외로 별로 없어서 다양한 환경에서 테스트해보지 못했습니다. 그러니 테스트 케이스를 바탕으로 내린 결론에는 오류가 있을 수 있습니다.

마치며

테스트 케이스에서 하나의 소스를 세 가지 브라우저가 전부 다르게 랜더링하는 것을 볼 수 있습니다. 만약 문서 제작자의 의도가 미디어 쿼리를 지원하는 브라우저에만 스타일을 적용하려는 것이어서 only 키워드를 사용했다면 의도했던 결과, 즉 FF 4.0.1에만 스타일이 적용됐을 것입니다. 새로 만들어질 브라우저가 HTML 4.01을 지원하면서 미디어 쿼리는 지원하지 않을 가능성을 100% 배제할 수는 없습니다. 그렇기 때문에 미디어 쿼리의 only 키워드가 중요합니다.

그리고 프로그래밍에 관한 격언 중 이런 것이 있습니다.

명시적인 것이 암시적인 것보다 낫다(Explicit is better than implicit).

명시적인 코드는 작정자의 의도를 분명히 표현하기 때문에 그 처리 결과도 분명합니다. 하지만 암시적인 코드는 내부의 처리 방식을 명확하게 이해하지 않고 사용하면 때때로 예상치 못한 결과를 가져올 수도 있습니다. 위에서 예로 든 media="only all and (min-width:600px)media="all and (min-width:600px)보다 명시적이고 좋은 방법이라고 생각합니다.

사실 only 키워드를 쓰지 않더라고 현실적으로 큰 문제는 없습니다. 하지만 미디어 쿼리에서 개인적으로 인상적인 부분이어서 포스팅했습니다. 표준은 당장의 현실뿐 아니라 미래까지도 고려해서 만들어지는 것이라고 생각해왔는데 이번에 HTML 4.01을 보면서 새삼 그렇다는 것을 느끼게 되었네요.

댓글 8개가 달렸습니다. 태그: , , ,

  1. 황규연 | 2011-06-28 08:16

    오랜만에 올라온 글 반가운 마음에 댓글을 달았습니다.
    현재 미디어 쿼리는 주요관심사인데 이렇게 간과했던 부분을 콕 얘기해주시니
    더할 나위없이 좋은 정보를 얻게되서 감사합니다.(^^)

  2. Wise | 2011-06-28 10:31

    글 잘 읽었습니다. 미디어 쿼리에 관심이 많은 요즘 좋은 정보가 되었어요 ^^/

  3. 부르 | 2011-06-28 10:46

    역시.. 쏙쏙 들어오게 글 잘쓰세요..^^

    근데 한가지..
    <link rel=“stylesheet” type=“text/css” media=“all and (min-width:9999px)” href=“test_media_query.css”>

    여기서 max-width:9999px 아닌가요?

    내용에서 9998px 이하라고 해서..^^

  4. HYLA | 2011-06-28 10:54

    잘지내시죠?
    오랜만에 좋은글 읽고 갑니다~

  5. 부르 | 2011-06-28 10:55

    흐흐 .. 설명 감사해요..^^
    전혀 다른 의미의 조건이었군요..ㅡㅡ;

  6. myeon | 2011-10-24 10:32

    잘 읽었습니다~~
    부르님 말대로 max-width:9999px 가 맞는거 같아요~ 제 생각에도 ^^

  7. Hans | 2011-12-12 10:33

    myeon님, 위에 보시면, min-width:9999px 의 조건은,
    외부 스타일 시트를 읽지 말라는 조건처럼보이는데,
    max-width:9999px 엿다면, ff3.0과 4.0이 같은 모습을 보여주지 않았을까요 ~?

  8. 웹디자인 강좌 | 2015-04-02 21:10

    흐흐 .. 설명 감사해요..^^
    CSS 블로그 글 매우 도움이되었습니다.

댓글이 닫혔습니다.