[CSS] 반응형 웹 디자인 적용하기 (styled-component에서 media query 적용)

Ko Seoyoung·2022년 1월 16일
20
post-thumbnail

들어가며

현재 기술블로그를 직접 만드는 개인 프로젝트를 진행중이다.
원래는 데스크탑 유저를 타겟으로 만들었지만 모바일에서도 볼 수 있도록 반응형으로 만들어보고 싶어 반응형 웹 디자인에 대해 공부해보았다.

1. meta 태그

  • viewport: 웹 페이지에서 사용자의 보이는 영역을 말하며, 이는 기기별로 달라진다.

viewport 설정

<meta name="viewport" content="width=device-width, initial-scale=1.0">

viewport는 meta 태그를 이용해 설정할 수 있다.
name="viewport"인 meta 태그는 페이지의 크기와 배율을 제어하는 방법에 대한 브라우저 지침을 제공한다.

뷰포트 meta 태그 속성들

  • width: 뷰포트의 가로크기를 정한다. width=device-width는 뷰포트를 장치의 화면 너비로 설정한다는 뜻이다.
  • initial-scale: 페이지에 처음 접속했을 때 보여질 확대/축소 배율을 설정한다. initial-scale=1.0이면 CSS 픽셀과 화면에 보여질 픽셀이 1:1이다. 하지만 1보다 큰 값을 갖는 경우 페이지는 확대되어 보이고, 1보다 작은 값인 경우 축소되어 보인다.
  • user-scalable:
    사용자의 축소/확대 허용 여부. yes 또는 no가 들어갈 수 있다.
  • minimum-scale: 뷰포트의 최소 배율값 (0~10)
  • maximum-scale: 뷰포트의 최대 배율값 (0~10)

2. media query

미디어 쿼리는 CSS3에 도입된 CSS기술로 반응형 웹을 만들기 위한 핵심 기술이다.

기본 동작

@media 키워드 옆에 나열된 조건이 true인 경우에만 css 속성 블록이 적용된다.

예시)

@media only screen and (max-width: 600px) {
  body {
    background-color: pink;
  }
}

브라우저 창이 600px이하인 경우 배경색이 pink가 된다.

중단점(Breakpoints) 설정

중단점이라하면 어떤 지점을 기준으로 기존 레이아웃 또는 스타일이 변경되는지를 결정한다.

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

3. styled-component에서 media query 적용하기

스타일 컴포넌트에서도 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)',
};

Refs

https://nykim.work/84
(+ scss 믹스인 사용해서 media query 작성)

그냥 javascript에서도 media query 값에 접근할 수 있는지 궁금했던 것 : https://webruden.tistory.com/314

profile
Web Frontend Developer 👩🏻‍💻 #React #Nextjs #ApolloClient

0개의 댓글