가장 간단한 미디어 쿼리의 모습은 아래와 같다.
@media media-type and (media-feature-rule) {
/* CSS rules go here */
}
media type : 이 코드가 사용될 미디어의 종류를 브라우저에게 알려준다.
media feature rule : CSS가 적용되기위해 통과되야하는 미디어 표현식이다.
CSS rules : 미디어 표현식이 참 이고 media type이 올바른 경우에 적용되는 CSS 규칙이다.
미디어 타입의 종류는 다음과 같다.
all
print
screen
레벨 3 미디어 쿼리 사양에 정의된 여러 가지 다른 미디어 타입들이 있다.
하지만 이것들은 더 이상 사용되지 않으므로 피해야 한다.
미디어 타입은 생략 가능하다.
생략할 시all
값으로 적용된다.
반응형 디자인을 만들기 위해 가장 자주 감지하는 기능은 뷰포트의 너비이다.
min-width
, max-width
, width
기능을 사용하여 특정 너비 또는 정확한 너비보다 크거나 낮으면 각각 다른 CSS를 적용할 수 있다.
하지만 max-
, min-
접두사를 붙인 최대, 최소값을 사용하는 것이 반응형 설계에 훨씬 더 유용하기 때문에 width
, height
단독으로 사용하는 경우는 거의 볼 수 없다.
레벨 4 사양에서는
max/min-
접두어 대신 사용할 수 있는 범위 연산자가 추가되어서30em <= width <= 50em
과 같이 사용할 수 있기 때문에 이런 경우width
단독으로 사용될 수 있다.
장치가 가로 화면인지 세로 화면인지 알려주는 기능도 있다.
orientation: landscape
는 가로 방향, orientation: portrail
은 세로 방향을 뜻한다.
레벨 4 사양의 일부로 hover
기능이 도입되었다.
사용자가 hover 를 할 수 있는 포팅인 장치를 사용하고 있다는 것을 의미한다.
터치스크린 및 키보드 탐색에서는 동작하지 않는다.
@media (hover: hover) {
body {
color: rebeccapurple;
}
}
다음은 hover
를 적용한 PC 화면의 모습이다.
다음은 hover
를 적용한 스마트폰 화면의 모습이다.
스마트폰 화면일 때는 미디어 쿼리가 적용되지 않았다.
hover: none
로 설정하면 반대로 동작한다.
또한 레벨 4 사양에는 pointer
기능도 있다.
pointer
가 가질수 있는 값들은 다음과 같다.
none
: 포인팅 장치가 없음을 뜻한다.
fine
: 마우스나 터치패드와 같은 작은 영역을 정확하게 겨냥할 수 있는 미세 포인터 장치
coarse
: 터치스크린의 손가락과 같이 넓은 영역을 겨냥하는 장치
hover
기능과 pointer
기능을 적절히 사용하면 사용자의 장치에 따라 더 나은 인터페이스를 설계할 수 있다.
다른 미디어 쿼리들을 결합하거나 리스트를 만들 수 있다.
and
연산자는 미디어 타입과 미디어 기능을 연결하는 곳에 사용되었다.
그 뿐 아니라 미디어 기능끼리 결합하는 데에도 사용된다.
스타일을 screen에만 적용하고 싶다면 미디어 기능을 screen 미디어 타입에 체인해서 사용한다.
@media screen and (min-width: 600px) and (orientation: landscape) {
body {
color: blue;
}
}
쉼표를 사용하여 미디어 쿼리를 리스트화한다.
여러 쿼리들 중 최소한 하나가 참이면 적용된다.
@media screen and (min-width: 600px), screen and (orientation: landscape) {
body {
color: blue;
}
}
레벨 4 사양에서는
or
연산자가 추가되었다.
미디어 타입과 미디어 기능을 포함하는 쿼리 전체를 리스트화 하는 쉼표 연산자와 달리or
연산자는 미디어 기능 끼리 연산을 한다.
@media (not(color)) or (hover)
처럼 사용한다.
not
연산자를 사용해서 전체 미디어 쿼리의 의미를 반전시킬 수 있다.
@media not all and (monochrome) {
/* … */
}
이 코드는
@media (not all) and (monochrome) {
/* … */
}
가 아니라
@media not (all and (monochrome)) {
/* … */
}
로 해석된다.
또한 쿼리 리스트에 not
연산자를 사용하면 단일 쿼리에만 적용된다.
@media not screen and (color), print and (color) {
/* … */
}
는
@media (not (screen and (color))), print and (color) {
/* … */
}
로 해석된다.
레벨 4 사양에서는 쿼리 대상으로 반전하는
not
연산자와 달리 미디어 기능만을 대상으로 하는not()
이 추가되었다.
예를들어@media (not(hover))
와 같이 사용할 수 있다.
only
키워드는 미디어 쿼리를 지원하지 않는 옛 브라우저가 스타일을 적용하지 못하도록 막는 역할을 한다.
즉, 미디어 쿼리를 지원하지 않는 브라우저는 다음의 스타일이 적용되지 않는다.
@media only screen and (color) {
/* … */
}
예전에는 각각의 장치에 대해서 스크린 설계를 했지만 이제는 그렇게 하기에는 크기가 다양한 장치들이 매우 많다.
모든 화면 크기에 대해 콘텐츠 크기를 지정하는 접근법 보다는 화면 크기에 따라 콘텐츠의 모양이 깨지는 방식으로 설계하되 깨지는 지점에서 더 나은 디자인으로 변경하는 것이 더 좋은 접근법이다.
이 접근법은 장치의 정확한 치수가 무엇인지 중요하지 않으며 모든 범위가 제공된다는 장점을 갖는다.
콘텐츠 모양이 깨져서 다른 디자인으로 변경되는 지점을 breakpoint라고 한다.
일반적으로 반응형 설계에 대해 두 가지 접근법을 사용할 수 있다.
큰 화면에서 시작하여 breakpoint를 추가하여 뷰포트가 작아지는 방향으로 작업하는 접근법과
반대로, 작은 화면에서 시작하여 breakpoint를 추가하여 뷰포트가 커지는 뱡향으로 작업하는 접근법이 있다.
이 중 두 번째 접근법은 mobile first responsive design 이라 불리며 권장하는 best 접근법이다.
매우 작은 장치는 단일 컬럼으로 설계된다.
기본적으로 HTML 코드만 잘 짜놓는다면 별 다른 레이아웃 작업을 하지 않아도 읽기 좋은 레이아웃을 갖추게 된다.
단일 컬럼으로 설계를 한 후 화면을 점점 키워보다보면 빈 공간이 많이 생기고 글씨 라인이 길어지는게 불편해보일 때가 있다.
그 때 breakpoint를 설정하여 디자인을 변경해주면 된다.
주의할 점은 min-width: 40em
과 같이 단위에 relative unit을 사용하는것이 좋다.
사용자는 브라우저의 폰트 크기를 설정할 수 있는데 폰트 크기에 따라 변경되도록 미디어 쿼리를 짜놓아야 문제가 발생하지 않기 때문이다.
만약 픽셀과 같이 절대 단위로 짜놓는다면 디자인과 폰트 크기가 따로 놀기 때문에 반응형이란 말이 무색해 질 수 있다.
HTML 소스 코드를 보면 문서의 head 부분에 다음과 같은 엘리먼트가 포함되어 있다.
<meta name="viewport" content="width=device-width,initial-scale=1" />
이는 뷰포트 메타 태그이다.
모바일 브라우저가 콘텐츠를 렌더링 하는 방법을 제어하기 위해 존재한다.
기본적으로 대부분의 모바일 브라우저는 뷰포트 너비에 대해 거짓을 말하기 때문에 필요하다.
모바일 장치 및 기타 좁은 화면은 일반적으로 화면보다 넓은 가상 창 또는 뷰포트(보통 980px)에서 페이지를 렌더링한 다음 렌더링된 결과를 축소하여 한 번에 모두 볼 수 있게 한다.
그런 다음 사용자는 페이지의 다른 영역을 보기 위해 이동하고 확대할 수 있다.
이 가상 뷰포트는 일반적으로 모바일에 최적화되지 않은 사이트를 좁은 화면 장치에서 더 잘 보이게 하는 방법이다.
그러나 미디어 쿼리를 사용하여 좁은 화면에 최적화된 페이지에는 이 메너니즘이 적합하지 않다.
예를들어 가상 뷰포트가 980px이면 640px 또는 480px 이하에서 시작하는 미디어 쿼리는 절대 사용되지 않으므로 반응형 설계 기술의 효율성이 제한된다.
뷰포트 메타 태그는 좁은 화면 장치에서 가상 뷰포트의 이러한 문제점을 해결한다.
위의 HTML 코드는 브라우저에게 "980px가 아닌 실제 장치 너비를 사용하여 렌더링 하고 더 나은 일관성을 위해 초기 확대 레벨을 100%로 설정하시오"를 말해준다.
Flexbox, Grid, Multi-column layout은 모두 미디어 쿼리 없이도 유연하고 반응형 구성요소를 만들 수 있는 방법을 제공한다.
이러한 레이아웃 방법으로 미디어 쿼리를 추가하지 않고도 원하는 것을 얻을 수 있는지 고려해볼 가치가 있다.
최신 레이아웃 방법을 잘 사용하면 최상의 결과를 얻을 수 있다.
[참고] : MDN