반응형 CSS, 뷰포트, 여러 단위(%, vw, em, rem), 미디어 쿼리
반응형 css를 처음 접하고 공부를 할 때, 뷰포트나 여러 단위(%, vw, em, rem) 등이 많아 되게 헷갈렸었는데,
개발 시에 어떤 식으로 적용이 가능한지 그리고 애매한 개념들에 대해 정리해 보겠습니다.
뷰포트(viewport)
뷰포트란 사용자가 브라우저에서 웹 페이지를 볼 수 있는 영역을 의미합니다.
일반적으로, 데스크탑에서는 브라우저의 크기에 따라 뷰포트의 크기가 변합니다.
웹 개발을 할 때 개발자 도구에서 확인해 보면 브라우저의 크기에 따라 html 태그의 크기가 변하는데,
html 태그의 width 기본값이 100%라서 그렇습니다.
html 태그의 넓이가 뷰포트 영역의 넓이와 같냐고 한다면, 꼭 그렇지는 않습니다.
스크롤바 또한 뷰포트 영역에 포함되기 때문에, 스크롤바가 있다면 html 태그의 넓이는 스크롤바의 넓이를 제외한
컨텐츠 영역의 넓이를 가지게 됩니다. 물론 html 태그에도 width 속성이 먹기 때문에, 기본값일 경우에만 해당됩니다.
브라우저를 최대화했다면, 뷰포트의 넓이는 모니터의 실제 해상도와 같게 되는데,
1920 x 1080 픽셀의 해상도를 가진 모니터에서 뷰포트의 넓이는 1920px입니다.
하지만 모바일 환경에서는 이 방식을 그대로 적용하기에 문제가 있었는데,
모바일 기기의 해상도가 PC 모니터에 비해 형편없었기 때문입니다.
이 때문에, 980px의 가상 뷰포트를 만들어 사용했는데,
위 그림처럼 980px의 가상 뷰포트에 웹 페이지를 렌더링 한 후 축소시켜
모바일 디바이스에서 보여주는 방식을 사용했다고 합니다.
실제로 개발자 도구에서 모바일 환경을 선택하고 width가 100%인 태그의 넓이를 확인해 보면 980px이 나옵니다.
메타태그?
그런데 980px의 뷰포트를 모바일 기기에 적용시키자 가독성의 문제가 발생했는데,
980px을 보여줄 만큼 모바일 기기가 크지 않았기 때문입니다.
그래서 많이들 보셨을 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
뷰포트 메타태그가 등장하게 되었는데, 모바일 기기의 넓이에 맞게끔 뷰포트의 크기를 바꾸겠다는 의미입니다.
메타태그를 넣자 div태그의 크기가 375px로 변하였습니다. iPhone SE가 375 x 667pt를 가지고 있기 때문입니다.
pt란 iOS 기본 좌표 단위입니다. iPhone SE의 실제 해상도는 750 x 1334px인데 375 x 667pt를 가지고 있다는 것은
한 좌표 안에 4px이 들어가 있다는 말과 같습니다. 웹 개발에 대해 적고 있기 때문에,
안드로이드의 좌표 단위인 dp와 iOS의 좌표 단위인 pt는 다음에 자세히 다루도록 하겠습니다.
initial-scale은 초기 줌 배율을 뜻합니다.
여기서 이상한 점은 모바일 기기의 뷰포트 넓이가 대부분 980px인데, px을 키워 보기 좋게 작업하면 되지 않을까요?
메타태그를 넣음으로써 모바일 환경에서 항상 동일한 비율을 가지던
px 단위가 일정하지 않은 비율을 가지게 돼 사용하기 힘들게 돼버립니다.
실제로 메타태그를 적용하기 전 300px은 모바일 환경에서 항상 같은 비율로 보이지만,
메타태그를 적용할 경우, 아래처럼 뷰포트의 크기가 바뀌어 300px의 비율이 달라지게 됩니다.
하지만 웹 사이트는 다양한 디바이스와 다양한 뷰포트 넓이를 가진 사용자들이 접속하기 때문에,
뷰포트 메타태그가 필요한 것이고, 뷰포트 메타태그를 사용한다면, 동일한 비율을 위해
px 단위의 사용이 힘들 수도 있게 됩니다.
다양한 반응형 단위(%, vw, em, rem)
%, vw, rem의 단위들은 어떠한 값이 변하면 따라 변하는 동적인 단위들입니다.
퍼센트는 부모 태그의 넓이에 비례해 값이 결정되고, vw는 뷰포트 영역에 따라 값이 결정됩니다.
em은 부모 태그의 폰트 크기에 따라 값이, rem은 최상위 태그의 폰트 크기에 따라 값이 결정됩니다.
확인해 보겠습니다.
해당 웹 페이지에서 body 바로 밑에 위치해있는 최상위 div 태그의 크기는 375px입니다.
최상위 div 태그에는 3개의 div 태그가 자식으로 존재하고 있는데 각 넓이가 50%, 50vw, 25rem으로 지정돼있습니다.
50%는 부모 태그의 375px의 절반이 적용되어 187.5px이 적용되었습니다.
50vw는 뷰포트의 크기가 375px이기 때문에 절반인 187.5px이 적용되었습니다.
25rem은 최상위 태그의 폰트 크기를 2vw로 지정해놨기 때문에, 2vw * 25인, 187.5px이 적용되었습니다.
12.5em은 부모 태그의 폰트 크기가 4vw이기 때문에 4vw * 12.5인 187.5px이 적용되었습니다.
이렇게 어떤 값에 따라 영향을 받는 단위를 사용한다면 브라우저와 모바일 환경에서 항상 같은 비율을 가지는
컨텐츠를 필요에 따라 만들 수 있게 됩니다.
위처럼 글씨 크기도 가변으로 두어 항상 같은 비율을 가지게 할 수도 있고, 글씨 크기만 px로 두어 넘치는 컨텐츠는
컨테이너의 높이를 auto로 두어 밑으로 보낼 수도 있겠지요.
미디어 쿼리
다양한 단위를 사용함에 따라 뷰포트의 크기에 따라 컨텐츠의 크기도 가변으로 만들 수 있었습니다.
하지만 뷰포트의 크기에 따라 바꿔야 하는 것이 크기가 아니라 컨텐츠의 형태나 컬러 등의 속성이라면
바로 미디어 쿼리를 사용해야 합니다.
@media (max-width: 600px) {
.media {
background-color: blue;
}
}
위 미디어 쿼리는 뷰포트가 600px 이하라면 media라는 클래스를 가진 태그의 배경색을 파란색으로 바꿉니다.
601일 때는 배경색이 default입니다.
600일 때는 파란색으로 배경색이 바뀌는 모습을 보실 수가 있습니다.
이렇게 뷰포트 메타태그, 가변 단위, 미디어 쿼리 등을 이용하면 디바이스 별로 최적화된
웹 페이지를 보여줄 수 있게 됩니다. 테스트에 사용되었던 파일들은 모두 업로드 해놓겠습니다.