미디어 쿼리를 사용하다가 css level4의 범위 구문 문법을 이제 모든 브라우저에서 지원해준다는 점을 알게되었다. 관련 내용과 문법들도 더 알아볼 겸 반응형 웹디와 관련된 내용들을 정리해놓고자 한다.
1. viewport meta tag
애플이 아이폰, 아이패드 등 자사의 모바일 브라우저의 뷰포트(viewport) 크기 조절을 위해 만들었다.
viewport란 웹페이지의 가시영역을 의미한다. 즉, 웹페이지가 사용자에게 보여지는 영역을 의미한다. 좀 더 정확히 말하자면, 화면에서 내가 스크롤을 움직이지 않고 볼 수 있는 네모 안쪽 영역을 의미한다(아래 사진에서 빨간 네모 박스). PC에서는 브라우저 창의 크기를 변경함에 따라서 viewport의 크기를 바꿀 수 있다. viewport는 디바이스에 따라 차이가 있다.

meta tag 는 브라우저 혹은 검색엔진 최적화(SEO)를 위해 검색엔진에게 메타데이터를 전달하기 위해 사용된다.
그 중 viewport meta tag는 브라우저의 화면 설정과 관련된 정보를 제공한다.
| 프로퍼티 | Description | 사용 예 |
| width | viewport 너비(px). 기본값: 980px | width=240 |
| width=device-width | ||
| height | viewport 높이(px) | height=800 |
| width=device-height | ||
| initial-scale | viewport 초기 배율 | initial-scale=1.0 |
| user-scale | 확대 축소 가능 여부 | user-scale=no |
| maximum-scale | viewport 최대 배율 | maximum-scale=2.0 |
| minimum-scale | viewport 최소 배율 | minimum-scale=1.0 |
meta tag에서는 px단위를 사용하며 단위 표현은 생략한다. 복수개의 프로퍼티를 사용할 때는 쉼표(,)로 구분한다.
일반적으로 viewport meta tag는 모바일 디바이스에서만 적용된다. meta tag:MDN
<meta name="viewport" content="width=device-width, initial-scale=1.0">
위 예제는 가장 일반적인 viewport 설정이다. 가로폭을 디바이스의 가로폭(`device-width`)에 맞추고 초기 화면 배율(`initial-scale`)을 100%로 설정하는 것을 의미한다.
viewport meta tag 에 대한 자세한 사용법은 아래 링크 2개를 참조하면 될 듯 하다.
(🔗링크 - 8년전꺼)
(🔗링크2 - 영상제공)
2. @media
이것은 서로 다른 미디어 타입(print, screen…)에 따라 각각의 styles을 지정하는 것을 가능하게 한다. 다음은 일반 화면(screen)과 인쇄장치 별로 서로 다른 style을 지정하는 예이다.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@media screen {
* { color: red; }
}
@media print {
* { color: blue; }
}
</style>
</head>
<body>
<h1>@media practice</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
반응형 웹디자인에 사용되는 핵심 기술은 `@media`이다.
`@media`을 사용하여 미디어 별로 style을 지정하는 것을 Media Query라 한다. 디바이스를 지정하는 것뿐만 아니라 디바이스의 크기나 비율까지 구분할 수 있다.
미디어 쿼리 구문은 css 내부에 삽입하는 방법과 링크로 연결하는 방법이 있다.
css 내부에 삽입하기
@media screen and (min-width: 480px) {
body {
background-color: lightgreen;
}
}
링크로 연결할 때
/* test.css 파일 안에는 아래 미디어 쿼리 구문이 들어가야 한다. */
<link rel="stylesheet" media="(max-width:700px)" href="test.css" />
Media Query의 문법
css에서
@media not|only mediatype and (expressions) {
CSS-Code;
}
링크로 연결할 때
<link rel="stylesheet" media="mediatype and|not|only (media feature)" href="test.css" />
media query 연산자
`and`|`not`|`only`|`,(쉼표)`|`or`
를 사용할 수 있다.
- `and` 연산자 : 여러 미디어 특징들을 하나로 결합함 .
- `,` 또는 `or`연산자: 쉼표로 분리된 각 목록은 각각 개별 미디어 쿼리임. `or`연산자는 Media Queries Level 4 에 추가되었음. `,`와 `or`연산자는 완전 동일. 의미는 '또는' 이라고 생각하면 쉽다.
- `not` 연산자 : 전체 미디어 쿼리를 부정하기 위해 사용 함.
- `only` 연산자 : 미디어 쿼리를 지원하지 않는 브라우저가 주어진 스타일을 적용하는 것을 방지
* not이나 only를 사용하려면 미디어 타입을 규정해야 함.
* 미디어 쿼리는 대소문자 구별하지 않는다.
* 미디어 타입이 생략됐을 때 미디어 타입의 기본값은 `all`이다.
예를 들어 `@media (min-width: 700px){...}`는 `@media all and (min-width: 700px) {...}` 과 같다.
and 연산자의 사용
새로운 미디어 특징들을 추가할 때마다 `and`연산자를 사용한다.
`@media (min-width: 700px) and (orientation: portrait) { ... }`
위 예는, 모든 유형의 장치이며 최소 너비 700px 이상이며, 방향이 세로 모드일 때만 적용한다는 뜻
`@media print and (min-width: 700px) and (orientation: landscape) { ... }`
프린트 장치이며, 최소 너비가 700px이상이며, 방향이 가로일 때 적용함.
쉼표(,) 연산자의 사용
쉼표(,)는 각각 개별 미디어 쿼리로 인식한다.
`@media (min-width: 700px), print and (orientation: landscape) { ... }`
모든 장치에서 최소너비 700px이상일 때 적용하거나, 프린트 장치에서는 가로 방향일 때만 적용하겠다는 뜻.
not 연산자의 사용
`@media not all and (color) { ... }`
not은 전체 미디어 쿼리를 수식한다. 즉 not은 all and (color)를 포함하여 부정함.
@media not (all and (color)) { ... } 와 같은 말
모든 색상 장치에서 이 스타일을 적용하지 않겠다는 뜻.
쉼표로 분리하여 사용할 때, 미디어 구문은 개별 미디어 쿼리로 인식하므로 not은 쉼표 이후에 영향을 미치지 않는다.
`@media not screen and (color), print and (color)`는
위 예는, 모든 스크린 색상 장치에서 적용하지 않거나, 프린트 색상 장치에서 적용하겠다는 뜻
`@media screen and (min-width: 700px) { ... }` 는 700px 이상의 스크린에서 적용되는 반면,
`@media not screen and (min-width: 700px) { ... }` 은 700px 이하의 스크린에서 적용된다.
- @media Level3 모듈의 `not` 연산자
단일 미디어 기능(media feature)을 부정할 수 없으며 전체 쿼리만 부정 가능하다.
...
그런데 `not`연산자를 `and` 연산자 뒤에 적어서 실험했을 때도 동일한 효과를 줬다.(분명 level3는 안된다고 했는데 되는 이유를 좀 더 찾아볼 필요가 있어보임. 이유 찾음. 글 맨 밑 media query level4 참고)
예시
`@media not screen and (min-width: 700px) { ... }` ✅
`@media screen and not (min-width: 700px) { ... }` 🚫 👉 현재(css media level4가 완전 적용됨)는 가능(✅)하다. 글 맨 밑 참고.
only 연산자 사용
`<link rel="stylesheet" media="only screen and (color)" href="test.css" />`
`only` 연산자는 전체 쿼리가 일치할 때만 스타일을 적용할 때 사용하며 오래 된 브라우저가 스타일을 잘못 적용하지 못하도록 방지할 때 유용하다. only 키워드는 모던 브라우저에서 문법 그 자체로는 붙이기 전과 비교했을 때 미디어 쿼리 결과에 아무런 영향을 미치지 않는다.
`only`를 사용하지 않은 `screen and (max-width: 500px)` 쿼리를 가정했을 때, 구형 브라우저는 쿼리를 단순히 screen으로만 읽고 뒷부분(and (max-width: 500px))은 무시한 채 스타일을 적용해버린다.
예시
`@media only screen and (min-width : 320px) { ... }`
media type(미디어 종류)
`all`|`print`|`speech`|`screen`
- all : 기본값. 모든 미디어 장치에 사용됨
- print : 프린터에 사용(인쇄 결과물 및 출력 미리보기 화면에 표시 중인 문서)
- screen : 컴퓨터 스크린, 테블릿, 스마트폰 등
- speech : 페이지를 읽어주는 화면 낭독기(음성 합성 장치 대상)
media feature(미디어 특징)
아래의 표는 Media Query의 표현식에서 사용할 수 있는 media feature(미디어 특징)이다.
`*` 표시는 `mix-`, `max-` 접두어 사용 가능을 표시한 것이다.
| 프로퍼티 | Description | 예시 |
| *width | viewport너비(px) | |
| *height | viewport 높이(px) | |
| *device-width | 디바이스의 물리적 너비(px) | `<link rel="stylesheet" media="screen and (max-device-width: 450px)" />` |
| *device-height | 디바이스의 물리적 높이(px) | |
| orientation | 디바이스 방향 (가로 방향: landscape, 세로방향: portrait) |
`@media all and (orientation: portrait) { ... }` 오직 세로 방향에서만 적용. |
| *aspect-ratio | 화면 영역의 가로 세로 비 기호 '/'을 사용하여, 앞에는 수평 픽셀 비율. 뒤에는 수직 픽셀 비율 (양수이며 정수) |
`@media screen and (min-aspect-ratio: 1/1) { ... }` 가로 세로 화면 비가 1:1 이상일 때 적용. 즉, 화면이 직사각이거나 세로일 때만 적용 |
| *device-aspect-ratio | 디바이스의 물리적 width/height 비율 | `@media screen and (device-aspect-ratio: 16/9) { ... }` 장치 가로 세로 비가 16:9일 때 적용. |
| *color | 디바이스에서 표현 가능한 최대 색상 비트 수 | |
| *color-index | 장치가 표시할 수 있는 색상 수 | `<link rel="stylesheet" media="all and (min-color-index: 256)" href="test.css" />` 최소 256 색상을 지닌 모든 장치에 적용 |
| *monochrome | 흑백 디바이스의 픽셀 당 비트 수 | |
| *resolution | 디바이스 해상도 해상도는 dpi (dots per inch)나, dpcm(dots per cintimeter)로 지정 |
`@media screen and (min-resolution: 300dpi) { ... }` 최소 300dpi 이상 해상도를 지닌 장치에 적용 |
orientation을 제외한 모든 프로퍼티는 min/max 접두사를 사용할 수 있다.
W3C > Media Queries > Media features
일반적으로 반응형 웹 디자인은 viewport 너비(width 프로퍼티)를 기준으로 한다.
viewport의 width 프로퍼티를 이용하여 viewport 너비에 따라 반응하는 범위(breakpoint)를 지정할 수 있다.
미디어 쿼리 작성 예시들
방법이 2가지가 있는데 보통 2번 방법을 사용해서 크기별로 선택자를 다수 집어넣는다.
/* 방법 1 */
.circle {
background-color: #ba55d3;
width: 200px;
height: 200px;
@media screen and (min-width: 768px) {
background-color: #2ecc71;
}
}
/* 방법 2 */
.circle {
background-color: #ba55d3;
width: 200px;
height: 200px;
}
@media not screen and (min-width: 768px) {
.circle {
background-color: #2ecc71;
}
}
/*========== Mobile First Method ==========*/
/* All Device */
/* Custom, iPhone Retina : 320px ~ */
@media only screen and (min-width : 320px) {
}
/* Extra Small Devices, Phones : 480px ~ */
@media only screen and (min-width : 480px) {
}
/* Small Devices, Tablets : 768px ~ */
@media only screen and (min-width : 768px) {
}
/* Medium Devices, Desktops : 992px ~ */
@media only screen and (min-width : 992px) {
}
/* Large Devices, Wide Screens : 1200px ~ */
@media only screen and (min-width : 1200px) {
}
/*========== Non-Mobile First Method ==========*/
/* All Device */
/* Large Devices, Wide Screens : ~ 1200px */
@media only screen and (max-width : 1200px) {
}
/* Medium Devices, Desktops : ~ 992px */
@media only screen and (max-width : 992px) {
}
/* Small Devices, Tablets : ~ 768px */
@media only screen and (max-width : 768px) {
}
/* Extra Small Devices, Phones : ~ 480px */
@media only screen and (max-width : 480px) {
}
/* Custom, iPhone Retina : ~ 320px */
@media only screen and (max-width : 320px) {
}

다음은 임의로 해상도를 3단계로 구분하여 breakpoint를 정의한 예제이다.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* 801px ~ */
* { color: black; }
/* ~ 800px */
@media screen and (max-width: 800px) {
* { color: blue; }
}
/* ~ 480px */
@media screen and (max-width: 480px) {
* { color: red; }
}
</style>
</head>
<body>
<h1>@media practice</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
다음은 화면이 세로일 때, 가로일 때를 구분하는 예제이다.
🚨주의할 점은 데스크탑은 언제나 가로 화면이기 때문에 `device-width`로 스마트폰의 해상도를 지정하지 않으면 스마트폰을 위해 분리한 css 선언인데도 불구하고 데스크탑에서도 가로화면 style이 적용되는 문제가 발생한다.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
/* 세로 */
* { color: black; }
/* 가로 */
/* Desktop의 화면은 가로화면(landscape)이므로 아래 rule이 적용된다. */
/*
@media screen and (orientation: landscape) {
{ color: blue; }
}
*/
/* Landscape */
@media screen
/* 디바이스가 모바일일때(device-width 0 ~ 768px) */
and (max-device-width: 760px)
/* 가로 */
and (orientation: landscape) {
* { color: blue; }
}
</style>
</head>
<body>
<h1>@media practice: orientation</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
미디어 기능 특정하기
어떤 스타일을 와이드스크린 모니터에만, 마우스를 사용하는 컴퓨터에만, 저광도 환경에서 사용 중인 장치에서만 적용하게 할 수 있다.
`@media (hover: hover) { ... }`
위 코드는 사용자의 주 입력 방식(마우스 등)이 요소 위에 호버할 수 있으면 스타일을 적용한다.
🚀CSS @media Level 4에서 향상된 기능들🚀
(브라우저 호환성을 위해 @media browser compatibility table을 참조해서 사용해야 한다.)
몇 가지를 보도록 하자
범위 구문 지원(Range syntax)
`@media (max-width: 30em) { ... }` 이런 구문을 미디어 쿼리 lever 4에서는 다음과 같이 쓸 수 있다.
`@media (width <= 30em) { ... }`
`min-`과 `max-`를 사용하여 사용자가 두 값 사이에서 폭 값을 시험해 보고 싶은 상황이라면:
`@media (min-width: 30em) and (max-width: 50em) { ... }` 을 Level 4 구문에서는 이렇게 표현할 수 있다:
`@media (30em <= width <= 50em ) { ... }`
`not`으로 기능 부정
기존(CSS level3)에는 media query 구문 전체를 부정하는 것만 가능했지만,
CSS @media Level 4부터는 media feature를 `not()`을 사용하여 부정할 수 있다.
`@media (not(hover)) { ... }`
위 코드 블럭은 hover를 할 수 없는 장치에 스타일을 적용하는 구문이다.
`or`
`or`을 사용하면 다수의 기능 가운데 맞는 것이 하나라도 있는지를 테스트하여, 그중에 맞는 것이 하나라도 있으면 `true` 값을 반환하게 할 수 있다. `true` 값이 반환된다는 뜻은 media query 선언 블록 안의 css를 적용하겠다는 뜻이다.
`@media (not (color)) or (hover) { ... }`
위 코드 블럭은 흑백화면인지 혹은 hover가 가능한 지를 시험하고 있다.