아티클

CSS3 media query에 대하여

2011-07-05 17:52:15

미디어 타입(media type)은 단말기의 종류에 따라 각각 다른 스타일시트를 적용하게 하는 기능이며 CSS 2.1 부터 추가되었습니다. 하지만 실제로 많이 사용되지 않았는데, 미디어 타입 만으로는 해당 기기의 특성을 정확히 파악하여 알맞은 스타일을 적용시키기 어려웠던 문제점이 있었기 때문입니다.
CSS3에는 미디어 타입을 개선하여, 더 구체적인 조건에서 필요한 스타일을 정확하게 적용할 수 있도록 확장하였는데, 이를 미디어 쿼리(media query)라고 합니다.


적용방법

미디어 쿼리를 적용하는 방법은 크게 3가지가 있습니다.

(1) 마크업에서 CSS파일 분기하기
스타일시트 파일을 분리하여 특정 조건에 부합할 경우 CSS파일을 로딩할 수 있습니다. 로딩하는 방법은 <link>태그, @import 속성, xml 방식을 사용할 수 있습니다.

<link rel="stylesheet" media="screen and (max-width:480px)" href="example.css">
<?xml-stylesheet media="screen and (max-width:480px)" rel="stylesheet" href="example.css" ?>
<style type="text/css">
@import url(example.css) screen and (max-width:480px);
</style>

(2) <style> 태그에서 media 선언하기
<style>태그를 선언할 때 media 속성에 조건을 선언해서 이 조건에 부합할때 해당 <style>태그 내의 css를 로딩할 수 있습니다.

<style type="text/css" media="screen and (max-width:480px)">
.h2{color:#00ffff}
</style>

(3) CSS 내에서 @media 사용하기
@media 구문을 이용해서 css 내에 선택적으로 사용할 수 있습니다.

.h2{color:#00ffff}

@media all and (max-width:480px) { .h2{color:#ff0000} }

위 방법 중, 별도 분기파일을 사용하는 방법은 http request를 발생시켜 성능을 저하시키는 단점이 있고, <style>태그를 사용하는 방법도 html 파일에서 inline으로 적용해야 하기 때문에 유지보수의 어려움이 증가합니다.
따라서 CSS 내에서 @media를 사용하여 필요한 부분에 적용하는 것이 가장 좋은 방법이라고 할 수 있습니다.


문법

미디어 쿼리는 문장 내에 대소문자를 구분하지 않습니다. media 속성에는 다음과 같은 문법을 사용할 수 있습니다.

media_query
: [ONLY | NOT]? S* media_type S* [ AND S* expression ]* | expression [ AND S* expression ]

조금 어려운 문장으로 되어 있는데요, 쉽게 풀면 다음과 같이 정리할 수 있습니다.

[ONLY 또는 NOT] 미디어타입 [and (조건)] [and (조건)] ... , [ONLY 또는 NOT] 미디어타입 [and (조건)] [and (조건)] ..

기본적으로 미디어 타입이 지정되어야 하며, 필요할 경우에 AND 연산자로 조건을 적용하면 되며 이 조건은 필요에 따라 추가가 가능합니다. 또한 쉼표를 사용하면 새로운 미디어타입과 조건도 추가할 수 있습니다.

- ONLY 키워드는 미디어쿼리를 지원하는 웹브라우저에서만 조건을 인식하도록 하는 키워드입니다. 미디어쿼리를 지원하지 않는 웹브라우저의 경우 ONLY 키워드가 있으면 미디어 쿼리가 무시되어 실행되지 않아야합니다.
하지만, 현재 IE 이외에는 미디어쿼리를 지원하지 않는 웹브라우저(모바일 포함)가 드물고, IE도 media query 를 정확하게 해석하지 못해서 ONLY 키워드의 유무에 상관 없이 media query를 실행하지 못하고 있습니다. 따라서 현재는 ONLY 키워드가 큰 의미는 없지만, 미디어쿼리를 지원하는 브라우저만 대상으로 할 경우엔 ONLY 키워드를 적는 것이 좋습니다.
(참고자료 : http://blog.wystan.net/2011/06/27/only-keyword-for-css3-media-query)
- NOT 연산자는 해당 미디어타입만 제외한 다른 미디어타입에 대응할 경우에 사용합니다.

예) screen and (max-device-height:480px), print and (min-resolution:120dpi) and (max-resolution:300dpi)

한가지 주의할 점은 조건을 사용할 때 각 미디어타입에 맞는 조건을 사용해야 합니다. 가령 미디어 타입이 aural(음성합성장치) 인 경우 조건에 max-width:800px 와 같은 화면 넓이에 관한 조건은 음성 장치와 관련이 없어 사용할 수 없습니다. 물론 실제로 사용한다 해도 항상 부적합한 조건이기 때문에 내부의 CSS는 적용되지 않습니다.


미디어타입

미디어쿼리에서 사용할 수 있는 미디어 타입은 다음과 같습니다.

all

모든 미디어 타입

aural

음성 합성 장치

braille

점자 표시 장치

handheld

손으로 들고 다니면서 볼 수 있는 작은 스크린에 대응하는 용도

print

인쇄 용도

projection

프로젝터 표현 용도

screen

컴퓨터 스크린을 위한 용도

tty

디스플레이 능력이 한정된, 텔렉스(teletype), 터미날, 또는 수동 이동 장치 등, 고정 피치(fixed-pitch:폭이 일정) 글자를 사용하는 메디아를 위한 의도 “tty” 메디아 타입에서 제작자는 픽셀(pixel) 단위를 사용하여서는 안됨

tv

음성과 영상이 동시 출력되는 TV와 같은 장치

embossed

페이지에 인쇄된 점자 표지 장치

위 타입 중 실제로 많이 사용되는 것은 all, screen, print 입니다. all은 모든 미디어타입에 대응하고, screen은 대부분의 컴퓨터와 모바일 폰에서 사용하는 웹브라우저에 대응하며, print는 프린터에 대응합니다.
handheld의 경우 주의가 필요합니다. 휴대용 기기라고 해서 요즘의 스마트폰 등의 모바일 기기가 연상될 수 있는데, 실제로 아이폰이나 안드로이드에서는 screen에 대응하고 있습니다.


조건문

미디어 쿼리의 조건에는 다른 프로그래밍에서 사용하는 "=" ">" "<" 등의 연산자를 사용하지 않고 CSS에서 사용하는 ":"(콜론) 만을 사용합니다. 대신에 "max-" 또는 "min-" 등의 prefix 를 사용하여 최대값, 최소값을 통한 비교가 가능합니다.
예를 들면 device-width(단말기에서 지원하는 물리적인 가로 너비)는 다음과 같이 사용할 수 있습니다.

device-width:320px

기기의 가로 너비가 320px 일때

max-device-width:320px

기기의 최대 가로 너비가 320px 일때 (즉 320px 이하)

min-device-width:320px

기기의 최소 가로 너비가 320px 일때 (즉 320px 이상)

위와 같은 min, max 로 표현이 불가능하고 특정값만 가지고 있는 경우도 있습니다. 예를 들면 화면의 비율에 대응하는 "orientation"의 경우 portrait | landscape 두개의 값만 가지며, TV스캔 방식에 대응하는 "scan"은 [ progressive | interlace ] 값만 지정할 수 있습니다.

미디어쿼리에서 사용하는 조건은 다음과 같습니다.

(1) width, min-width, max-width (가로 너비)
웹페이지의 가로 너비, width로 판단합니다.

(2) height, min-height, max-height (세로 높이)
웹페이지의 세로 너비, height로 판단합니다.
height 는 미디어를 모두 포함한 높이를 기준으로 하기 때문에 미디어에 따라 다른 height가 검출됩니다. screen 같은 페이지 개념이 없는 미디어는 스크롤을 포함한 전체 문서의 높이를 기준으로 하며, print 미디어는 한 페이지의 높이를 기준으로 하기 때문에 의도와 다른 값이 나올 수 있으므로 사용에 주의해야 합니다.

(3) device-width, min-device-width, max-device-width (단말기의 물리적인 가로 너비)
단말기에서 기본적으로 제공하는 물리적인 가로 너비(단말기의 native width)를 판단합니다.
아이폰4나 안드로이드 단말기의 대부분이 실제 단말기의 해상도와 웹브라우저가 사용하는 기본 너비가 다릅니다.
아이폰 4의 실제 해상도는 640*960 이지만, 실제 브라우저에서 사용하는 너비는 320*480(2배 비율)이며, 안드로이드폰도 대부분 480*800 해상도를 사용하지만, 브라우저 너비는 320*533(1.5배 비율)입니다.

(4) device-height, min-device-height, max-device-height (단말기의 물리적인 세로 높이)
단말기에서 기본적으로 제공하는 물리적인 세로 너비(단말기의 native height)를 판단합니다.

(5) orientation (화면 회전)
max, min prefix를 사용하지 않으며, portrait, landscape 값을 지정할 수 있습니다.
width, height를 구하여, width가 길면 landscape, height가 길면 portrait 입니다. 대부분의 모바일 단말기의 경우 세로가 긴 형태이기 때문에 기본 상태는 portrait, 가로로 돌렸을 경우 landscape에 대응합니다.
주의할 점은 데스크톱은 대부분 가로/세로 모드에 대한 개념이 없기 때문에 orientation 속성이 모바일 전용으로 오해받는 경우도 있지만, 실제로는 모바일과 데스크톱의 구분을 할 수 없다는 점입니다.

(6) aspect-ratio, min-aspect-ratio, max-aspect-ratio (화면 비율)
width/height 비율에 대응합니다. 즉, width를 height로 나눈 값입니다.
직접 숫자로 사용할 수도 있고, 계산식을 사용할수도 있습니다.

aspect-ratio:1

화면 비율이 1:1 인 경우에 대응하며 예를 들면 320*320, 640*640 등이 대응합니다.

aspect-ratio:16/9

계산식으로 사용하였으며 HDTV에 일반적인 화면 비율인 16:9 인 경우에 대응합니다. (예: 1920*1080)

(7) device-aspect-ratio, min-device-aspect-ratio, max-device-aspect-ratio (단말기의 물리적인 화면 비율)
단말기의 물리적인 화면 비율에 대응합니다.

(8) color, min-color, max-color (색상당 비트수)
단말기에서 사용하는 최대 색상 수의 비트 수에 대응합니다. 단위는 자연수입니다.

color:1

2^1 = 2개 색상 사용

color:2

2^2 = 4개 색상 사용

color:3

2^3 = 8개 색상 사용

color:4

2^4 = 16개 색상 사용

(9) color-index, min-color-index, max-color-index (팔레트의 색상 갯수)
단말기에서 사용하는 최대 색상 수에 대응합니다. 단위는 자연수입니다.

(10) monochrome, min-monochrome, max-monochrome (흑백만을 사용하는 단말기에서 픽셀 당 비트 수)
흑백 컬러만을 사용하는 단말기에서 하나의 픽셀에 사용할 수 있는 비트 수에 대응합니다. 단위는 자연수입니다.
이 비트수의 의미는 흰색과 검은색의 사이에 얼마나 많은 단계를 지원하는지를 의미합니다. 즉 흑백 그라데이션(계조)이 얼마나 자연스럽게 표현되는지를 확인합니다.

monochrome:1

2^1 = 흰색과 검은색 사이에 2개의 단계 (즉 검은색과 흰색만 존재)

monochrome:2

2^2 = 흰색과 검은색 사이에 4개의 단계

monochrome:3

2^3 = 흰색과 검은색 사이에 8개의 단계

monochrome:4

2^4 = 흰색과 검은색 사이에 16개의 단계

(11) resolution, min-resolution, max-resolution (단말기의 해상도)
단말기에서 지원하는 해상도를 판단합니다. width, height와는 다른 값이며 대부분의 단위는 dpi(인치당 도트 수)를 사용합니다. dpcm(센티미터당 도트수)도 사용할 수 있습니다. 예를 들면 PC화면의 경우 대부분 96dpi를 사용하지만, 프린터의 경우 300dpi를 넘는 값을 사용할 수 있으며 dpi가 높아질수록 같은 크기에 더 세밀한 화면을 볼 수 있습니다.
같은 3.5인치 화면이면서 해상도가 다른 아이폰 3GS/아이폰 4를 연상하면 쉽게 이해할 수 있습니다.

(12) scan (스캔 방식)
tv 미디어 타입에만 대응하는 속성입니다. TV에서 스캔 방식에 따라 값을 지정할 수 있습니다.
프로그레시브 방식은 "progressive, 인터레이스 방식은 "interlace" 로 지정할 수 있습니다.

(13) grid (화면의 최소단위)
단 말기가 grid 방식인지, 또는 bitmap 방식인지에 대해 대응합니다. grid방식이란 화면 내의 최소 단위가 픽셀이 아닌 문자 하나인 경우를 말합니다. 예를 들면 터미널(tty) 등에서 사용하는 텍스트만 사용하는 통신 또는 구형 전화의 액정에서 사용하는 문자 단위로만 표시되는 단말기가 여기에 속합니다. 여기에 속할 경우 "1" 값에 대응하며 그 외의 비트맵 기반의 단말기의 경우 모두 "0"에 대응합니다.

grid:1

문자로만 표기되는 tty, 터미널, 전화 액정화면

grid:0

비트맵을 기반으로 하는 그래픽 표시 장치. 대부분의 컴퓨터와 스마트폰 웹브라우저에 해당됩니다.

(14) -webkit-min-device-pixel-ratio (단말기의 화소와 실제 화면의 pixel간의 비율)
웹킷 전용 속성이며 화면 내의 1px를 표현할 때의 실제 단말기의 픽셀의 비율에 대응합니다.
아이폰 4에 대응할 때 사용할 수 있는데, 아이폰4의 경우 실제 해상도는 640*960이지만 웹브라우저 해상도는 320*480 에 대응합니다. 따라서 아이폰4의 사파리의 경우엔 1px에 실제로는 단말기의 2화소가 대응하고 있으므로 이 값은 2입니다.
비슷하게 안드로이드 폰의 경우 실제 해상도 480*800 단말기에서 웹브라우저 해상도는 320*533으로 표현되는데, 이때의 비율은 1.5입니다.

<!-- 아이폰4 -->
<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" type="text/css" href="iphone4.css">

<!-- 안드로이드 -->
<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 1.5)" type="text/css" href="android.css">

FAQ

(1) 모바일 기기와 데스크톱을 CSS 미디어쿼리로 클라이언트 단에서 구별할 수 있는 방법은 현재 없습니다. 현재는 UA값으로 분기할 수 밖에 없습니다.
orientation(가로/세로 전환)의 경우 모바일 전용 속성이 아니며, 가로 길이와 세로 길이에 따라 나오는 값이기 때문에 실제 PC 에서도 웹브라우저의 세로가 길면 세로모드 (portrait), 가로가 길면 가로모드(landscape)로 인식합니다.

(2) 구형 모바일 브라우저인 폴라리스에서는 @media 구문을 무시하고 내부에 있는 CSS까지 그대로 적용되는 문제가 있습니다. 폴라리스의 경우 해당 구분이 폴라리스가 아닌 다른 브라우저를 위한 스타일이라고 해도 미디어쿼리를 사용하면 안되며 별도 파일로 분기해야 합니다.

(3) 미디어 쿼리를 사용하면 단말기의 특성에 따라 필요한 CSS를 적용시키거나 무시할 수 있습니다. 이 기능은 서버(Back-end) 단의 부담을 주지 않고, 클라이언트의 렌더링(Frong-end)에 영향을 줄 수 있지만, 적용되는 CSS구문이 추가되는 정도이며 유의미할 정도의 큰 부담이 아닙니다. 즉, 미디어 쿼리를 사용해도 전체적인 퍼포먼스에는 별 영향이 없습니다.

(4) 미디어 쿼리를 통해 여러 해상도에서 최적의 디자인을 보여주는 것이 가능합니다. 위 예제 사이트에서도 확인할 수 있지만, HTML 문서의 구조화가 잘되어있으면 같은 내용을 포함하면서 해상도에 따라 각각의 최적화된 화면을 보여줄 수 있습니다.
각 해상도 별로 디자인을 별도로 한 HTML문서를 만들 필요 없이 하나의 문서만으로도 모든 해상도에 대응할 수 있고, PC처럼 해상도를 변경할 수 있는 웹브라우저에서는 창 크기에 따라 동적으로 대응하는 것도 가능합니다.

(5) 하지만, 미디어 쿼리는 기능 상의 분기는 불가능합니다. 미디어 쿼리는 결국 CSS의 추가 로딩/CSS의 수정에만 영향을 주기 때문에 디자인에만 영향을 줄 수 있습니다. 기능 지원이 안되는 단말기의 특성을 파악하여 해당 섹션을 CSS의 display:none 등으로 가리는 것은 가능하지만, 근본적으로 해당 기능을 단말기에서 로딩하지 않는 등의 개발 분기는 어렵습니다.


관련자료 및 예시 사이트

http://www.w3.org/TR/css3-mediaqueries/ : 실제 CSS3의 표준을 제정하고 있는 w3에서 제공하는 미디어쿼리 매뉴얼입니다.
http://webdesignerwall.com/tutorials/css3-media-queries : 활용 예제와 예시 사이트
http://hicksdesign.co.uk : 브라우저 사이즈를 줄여보면 레이아웃이 변경됩니다.
http://colly.com : width에 따라 한줄에 나오는 리스트 수가 달라집니다.
http://www.alistapart.com/d/responsive-web-design/ex/ex-site-FINAL.html : width에 따라 레이아웃이 변경됩니다.
http://html.nhndesign.com : 웹표준화팀의 홈페이지입니다. 역시 width에 따라 컨텐츠의 배치가 달라지며, 모바일에서도 내용이 쉽게 파악되도록 레이아웃이 바뀝니다. :)

댓글 0
댓글을 작성하려면 해주세요.