현재 기술블로그를 직접 만드는 개인 프로젝트를 진행중이다.
원래는 데스크탑 유저를 타겟으로 만들었지만 모바일에서도 볼 수 있도록 반응형으로 만들어보고 싶어 반응형 웹 디자인에 대해 공부해보았다.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
viewport는 meta 태그를 이용해 설정할 수 있다.
name="viewport"
인 meta 태그는 페이지의 크기와 배율을 제어하는 방법에 대한 브라우저 지침을 제공한다.
width
: 뷰포트의 가로크기
를 정한다. width=device-width는 뷰포트를 장치의 화면 너비로 설정한다는 뜻이다.initial-scale
: 페이지에 처음 접속했을 때 보여질 확대/축소 배율
을 설정한다. initial-scale=1.0이면 CSS 픽셀과 화면에 보여질 픽셀이 1:1이다. 하지만 1보다 큰 값을 갖는 경우 페이지는 확대되어 보이고, 1보다 작은 값인 경우 축소되어 보인다.user-scalable
:minimum-scale
: 뷰포트의 최소 배율값 (0~10)maximum-scale
: 뷰포트의 최대 배율값 (0~10)미디어 쿼리는 CSS3에 도입된 CSS기술로 반응형 웹을 만들기 위한 핵심 기술이다.
@media
키워드 옆에 나열된 조건이 true인 경우에만 css 속성 블록이 적용된다.
예시)
@media only screen and (max-width: 600px) {
body {
background-color: pink;
}
}
브라우저 창이 600px이하인 경우 배경색이 pink가 된다.
중단점이라하면 어떤 지점을 기준으로 기존 레이아웃 또는 스타일이 변경되는지를 결정한다.
W3C에 소개된 일반적인 장치 중단점은 다음이 5개로 나뉜다.
https://www.w3schools.com/css/css_rwd_mediaqueries.asp
/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {...}
/* Small devices (portrait tablets and large phones, 600px and up)
*/
@media only screen and (min-width: 600px) {...}
/* Medium devices (landscape tablets, 768px and up) */
@media only screen and (min-width: 768px) {...}
/* Large devices (laptops/desktops, 992px and up) */
@media only screen and (min-width: 992px) {...}
/* Extra large devices (large laptops and desktops, 1200px and up) */
@media only screen and (min-width: 1200px) {...}
나도 이 중단점을 참고하여 desktop 1200px, tablet 768px, phone 600으로 정했다.
{
desktop: 1200,
tablet:768,
phone:600
}
참고로 이 크기가 결정되는 배경은 통계적인 원인이 가장 크다.
이 사이트를 보면 전세계 태블릿 사용자 중 가장 많은 비율이 768x1024 크기의 태블릿을 사용한다는 것을 알 수 있다.
더 많은 media 규칙보기: https://www.w3schools.com/cssref/css3_pr_mediaquery.asp
스타일 컴포넌트에서도 css 적용과 동일한 방법으로 미디어 쿼리를 적용할 수 있다.
const Title = styled.h1`
color: black;
@media only screen and (max-width: 600px) {
body {
color: pink;
}
}
`
하지만 태블릿은 768px, 모바일은 600px 등 breakpoint를 매번 외워서 사용하는 것은 번거롭기도하며 예상치 못한 ui 깨짐을 발생시킬 수도 있다.
찾아본 결과 아래 블로그 글들처럼 다양한 방법으로 breakpoint를 변수화하여 사용할 수 있다.
그 중 내가 사용한 방법은 이 블로그 포스팅과 같이 template literals을 만들어서 함수처럼 사용하는 방식이다.
// src/styles/media.ts
import { css, CSSObject, SimpleInterpolation } from "styled-components";
type DeviceType = "desktop" | "tablet" | "phone";
const sizes: Record<DeviceType, number> = {
desktop: 1200,
tablet: 768,
phone: 600,
};
const media = Object.entries(sizes).reduce((acc, [key, value]) => {
return {
...acc,
[key]: (
first: CSSObject | TemplateStringsArray,
...interpolations: SimpleInterpolation[]
) => css`
@media (max-width: ${value}px) {
${css(first, ...interpolations)}
}
`,
};
}, {}) as Record<DeviceType, any>;
export { media };
사용 예시
import { media } from "@src/styles/media";
const Article = styled.article`
padding: 2.4rem 1.6rem;
max-width: 80%;
margin: 0 auto;
${media.tablet`
padding: 1.6rem 1.4rem;
max-width: 100%;
`}
`;
추가적으로 airbnb css-in-javascript 네이밍 가이드에선 특정 디바이스를 칭하는 네이밍 사용을 지양한다. 왜냐하면 기기별 정해진 크기와 실제 기기의 크기가 다를 수도 있기 때문이다. 예를들어 768px이 꼭 태블릿이 아닐 수도 있고 데스크탑일 수도 있다. 따라서 아래와 같이 사이즈로 네이밍을 하도록 권장한다.
const breakpoints = {
small: '@media (max-width: 639px)',
medium: '@media (max-width: 1047px)',
large: '@media (min-width: 1048px)',
};
https://nykim.work/84
(+ scss 믹스인 사용해서 media query 작성)
그냥 javascript에서도 media query 값에 접근할 수 있는지 궁금했던 것 : https://webruden.tistory.com/314