MediaQuery

Jisoo Shin·2024년 1월 3일

Bigc인턴

목록 보기
14/19

Styled Components의 themeProvider

1. themeProvider

  • styled components의 themeProvider는 context api를 기반으로 만들어짐
  • ∴ themeProvider로 감싸진 component들은 theme 정보를 props형태로 넘겨받아서 사용이 가능

아래처럼 우선 theme.ts 파일을 생성해서 전역에서 쓰일 변수와 값을 정함

const windowSize = {
  small: 'screen and (max-width: '600px')',
  base: 'screen and (max-width: '768px')',
  large: 'screen and (max-width: '1024px')',
};

const fontSize = {
  xs: '0.5rem',
  sm: '0.75rem',
  base: '1rem',
  md: '1.25rem',
  lg: '1.5rem',
};

export default theme;
  

2. Provider 적용

import theme from './styles/theme'; //1.에서 만들어둔 theme
import { ThemeProvider } from 'styled-components';

function App() {

  return (
    <AppComponent>
      <ThemeProvider theme={theme}>
        <Routes>
          ...
        </Routes>
      </ThemeProvider>
    </AppComponent>
  );
}
  • 이런식으로 감싸주면, ThemeProvider로 감싸져있는 부분은 다 해당 theme에 접근이 가능해지는것

📌 mediaQuery

: 특정 조건이 성립되었을때, CSS 속성을 적용할 수 있게 해주는 문법

  • 화면의 넓이나 높이와 같이 브라우저가 어떤 기기에서 실행되고 있는지를 파악해서 기기별로 서로 다른 스타일을 제공해주는 방법
    (--> 반응형 프로그래밍)

  • ex) 미디어 쿼리를 활용해서 현재 뷰포트의 크기에 따라서 다른 디자인을 적용할 수 있게 조건을 걸어줄 수 있는 것

📌 방법1) MediaQuery 속성을 모듈화하기

1. theme.ts 생성하기

해당 파일을 만들고, 그 안에 2개의 객체를 생성하기
(1) size 객체 : breakpoint 즉 기기의 사이즈 값이 들어있는 객체
(2) device 객체 : media query의 속성값이 들어있는 객체

const deviceSizes = {
  mobile: 375,
  tablet: 768,
  laptop: 1024,
};

/*
{
  "legacyMobile": "300px",
  "legacyTablet": "640px",
  "legacyLaptop": "1320px",
  "legacyDesktop": "1920px",
  "mobile": "500px"
}
*/

const device = {
  mobile: `screen and (max-width: ${deviceSizes.mobile}px)`,
  tablet: `screen and (max-width: ${deviceSizes.tablet}px)`,
  laptop: `screen and (max-width: ${deviceSizes.laptop}px)`,
};

const theme = {
  device
};

export default theme;

2. styled-component에 적용하기

App.ts에서 ThemeProvider의 theme(export한 것)을 props로 전달해서 사용

import React from "react";
import styled, { ThemeProvider } from "styled-components";
import theme from "./theme";

const Wrapper = styled.div`
  //이 부분은 tablet에 정의된 크기보다 클때만 진행되는거
  @media ${({ theme }) => theme.device.tablet} {
    flex-direction: column;
  }

  width: 100vw;
  height: 100vh;
  background: wheat;
  display: flex;
  align-items: center;
  justify-content: center;
`;

📌 방법2) MediaQuery 자체를 모듈화하기

: 1번보다는 어렵지만 실제 적용할때는 편함

(1) media.ts 생성하기

: 미디어 쿼리 자체를 내보낼 파일!

import { css } from "styled-components";

const sizes = {
  mobile: 320,
  tablet: 768,
  laptop: 1024,
};

export default Object.keys(sizes).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media screen and (max-width: ${sizes[label]}px) {
      ${css(...args)};
    }
  `;
  return acc;
}, {});

예시1

@media screen and (max-width: 768px) {
  color: white;
  background-color: black;
}

screen 영역이 768px 이전까지의 width에서만 해당 속성이 적용

예시2

const LinkTreeWrapper = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  
  @media (min-width: ${(props) => props.theme.breakpoint.mobile}) {
    width: 100%;
    flex-direction: row-reverse;
    align-items: center;
    justify-content: space-between;
  }
`;

위 부분에서 주요한 부분들을 설명해보면 다음과 같다.
1. @media 쿼리를 통해서 미디어 쿼리를 정의하고 있음
2. @media (min-width: ${(props) => props.theme.breakpoint.mobile})

  • 뷰포트의 너비가 props.theme.breakpoint.mobile 이상일때만 해당 스타일을 적용하겠다는 미디어 쿼리!!
  • 이때, mobile은 theme.js || tailwind.config.js 파일에 정의된 mobile의 값을 참조

참고문헌

  1. themeProvider

  2. media query ❗️❗️❗️❗️

0개의 댓글