태블릿, PC, 모바일 등 다양한 기기에서도 불편함 없는 서비스를 동일하게 제공하기 위해 각 해상도에 따라 레이아웃과 스타일의 변화를 주어 제공하는 웹이다.
미디어 쿼리는 CSS에서 나온 기술로 특정 조건이 성립됐을 때 CSS 속성을 적용할 수 있게 해주는 문법이다.
특정 조건이란 화면의 넓이나 높이와 같이 브라우저가 어떤 기기에서 실행되고 있는지를 파악해서 기기별로 서로 다른 스타일을 제공하는 방법을 선택하는데, 이것을 반응형 프로그래밍이다.
@media screen and (max-width: 768px) {
color: white;
background-color: black;
}
screen영역이 768px 전 까지의 width에서 속성이 적용된다.
라이브러리를 설치해서 사용하면 편리함은 있지만 라이브러리를 많이 설치하면 그렇게 좋지않아, 반응형 웹 작업에 ThemeProvider 사용을 하는 것이 스타일들을 관리하기에 효율적이다.
import { css } from "styled-components";
const breakPoints = {
tablet: 800,
laptop: 1200,
};
export default Object.key(breakPoints).reduce((acc, label) => {
acc[key] = (...args) => css`
@media (min-width: ${value}px) {
${css(...arg)}
}
`;
return acc;
}, {});
Object.keys()
Object.keys()메소드는 객체(typeof 연산자로 확인했을 때 object가 반환되는)의 프로퍼티들 중에서 key값, 다른 말로는 프로퍼티 이름들만 묶어서 배열로 반환하는 메소드 입니다.
const object1 = {
a: 'somestring',
b: 42,
c: false
};
const object1 = Object.keys(object1);
console.log(object1); // ["a", "b", "c"]
Object.keys()함수로 매개변수로 넘어간 breakPoints객체에 있는 enumerable 속성명을 가지고, reduce()의 리듀서 함수로 breakPoints에 정의된 값으로 acc 연산으로 각각의 media query의 속성들을 styled-components의 css 속성을 이용해서 만들어낸다.
그리고 그 속성 값들을 위에서 정의한 breakPoints객체에 있는 값들로 media query의 속성을 만드는데 ...args 문법으로 생성된 모든 args를 media query 내에 적용시켜준다.
const Box = styled.div`
/* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
/* 기본적으로는 1024px 에 가운데 정렬을 하고
가로 크기가 작아짐에 따라 사이즈를 줄이고
768px 미만으로 되면 꽉 채웁니다 */
width: 1024px;
margin: 0 auto;
@media (max-width: 1024px) {
width: 768px;
}
@media (max-width: 768px) {
width: 100%;
}
`;
styled-components에서 ThemeProider를 적용하기 위해 만들어둔 theme.js파일을 import해와서 적용하고자하는 컴포넌트들에 감싸야 한다.
import { ThemeProvider } from "styled-components";
import Router from "./shared/Router";
import GlobalStyle from "./styledComponents/Globalstyle";
import theme from "./styledComponents/theme/theme";
export default function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<Router />
</ThemeProvider>
);
theme={theme} -> theme={{...theme, ...media}}
const Box = styled.div`
/* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
background: ${props => props.color || 'blue'};
padding: 1rem;
display: flex;
width: 1200px;
margin: 0 auto;
${({ theme: { mediaQuery } }) => mediaQuery.tablet`
width: 800px;
`};
${({ theme }) => theme.mediaQuery.laptop`
width: 1200px;
`};
`;