Styled-Components

송나은·2021년 6월 12일
0

React

목록 보기
6/9

styled-components란

Javascript 파일 내에서 CSS를 사용할 수 있게 해주는 대표적인 CSS-in-JS 라이브러리로 React 프레임워크를 주요 대상으로 한 라이브러리이다.

웹팩에서 빌드할 때 하나의 파일로 합쳐지면 className이 전역에서 작동하여 중복된 className이 충돌할 수 있다.
-> 스타일을 컴포넌트 내부에 정의하면 className을 자동으로 생성해주어 전역에서 중복될 일이 없다.

  • install styled-components

src/styles

1. theme.js

프로젝트에서 사용할 공통 스타일을 정의한다.

const deviceSizes = {
  mobileS: "320px",
  mobileM: "375px",
  mobileL: "450px",
  tablet: "768px",
  tabletL: "1024px",
};

const device = {
  mobileS: `only screen and (max-width: ${deviceSizes.mobileS})`,
  mobileM: `only screen and (max-width: ${deviceSizes.mobileM})`,
  mobileL: `only screen and (max-width: ${deviceSizes.mobileL})`,
  tablet: `only screen and (max-width: ${deviceSizes.tablet})`,
  tabletL: `only screen and (max-width: ${deviceSizes.tabletL})`,
};

const colors = {
  main: "#6415b7",
};

export const theme = {
  device,
  colors,
  deviceSizes,
};

2. globalstyles.js

normalize와 common 스타일을 정의한다.

import { createGlobalStyle } from "styled-components";
import { normalize } from "styled-normalize";

export const GlobalStyle = createGlobalStyle`
${normalize}

@mixin flex($direction: 'row', $align: 'center', $justify: 'center') {
    display: flex;
    flex-direction: $direction;
    align-items: $align;
    justify-content: $justify;
  }

html,
body {
  padding: 0;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

a {
  color: inherit;
  text-decoration: none;
}

input, button, select {
    background-color: transparent;
    border: none;
    outline: none;
  }

* {
  box-sizing: border-box;
}
`;

reset과 normalize의 차이

  • reset
    브라우저별로 각가 태그에 대한 기본 스타일링이 다르기 때문에, 기본적인 것들은 초기화해서 사용한다.
  • normalize
    기존의 브라우저별 스타일을 모두 리셋시키는 방법이 아니라 이를 유지하고, 이용하려는 스타일링 방법.

src/App.js

App.js 에서 styled-components 설정하기!

  • theme.js에서 설정한 스타일을 props로 내려준다.
  • globalstyle.js에서 설정한 스타일로 components를 감싸준다.
import { ThemeProvider } from "styled-components";
import { GlobalStyle } from "../styles/globalStyle";
import { theme } from "../styles/theme";
import HeaderContainer from "../components/header";

function MyApp({ Component }) {
  return (
    <ThemeProvider theme={theme}> 
      <GlobalStyle />
      <HeaderContainer />
      <Component />
    </ThemeProvider>
  );
}

export default MyApp;

하위 컴포넌트에서 사용하기

import styled from 'styled-components';

const Component = () => {
  return (
    <StyledComponent />
  )
};

export default Component;

const StyledComponent = styled.div`
 color: ${({ theme }) => theme.colors.main} /* "#6415b7" */
`;

props 넘겨주어 js 로직 사용하기

import styled from 'styled-components';

const Component = () => {
  return (
    <StyledComponent active={false}/>
  )
};

export default Component;

const StyledComponent = styled.div`
 color: ${(props) => (props.active ? props.theme.colors.main : "white")} // "white"
`;

Extending

기존에 정의한 컴포넌트의 스타일을 가져와, 중복되는 속성은 override 되어 적용된다.

import styled from 'styled-components';

const Component = () => {
  return (
    <Button1 />
    <Button2 />
  )
};

export default Component;

const Button1 = styled.button`
 color: ${({ theme }) => theme.colors.main};
 font-size: 1em;
 margin: 1em;
 padding: 0.25em 1em;
 border: 2px solid ${({ theme }) => theme.colors.main};
 border-radius: 3px;
`;

const Button2 = styled(Button1)`
 color: white;
 border-color: white
`;

Ampersand(&) 활용하기

import styled from 'styled-components';

const Component = () => {
  return (
    <Button />
    <Button />
    <Button />
  )
};

export default Component;

const Button = styled.button`
 color: blue; 
 &:hover { color: red; }
 & ~ & { color: yellow;	} // 건너서 있을때 -> <Button> <div> <Button>
 & + & { color: green; } // 바로 옆에 있을때
 && { color: blue; } // 전역 스타일 무시 }
`;

Mixin

  • Globalstyle로 정의하는 방법과, 컴포넌트 내에서 정의하는 방법이 있다.
import styled from 'styled-components';

const Component = () => {
  return (
    <MixinFlex />
  )
};

export default Component;

const flexcenter = css`
 display: flex;
 justify-content: center;
 align-items: center;
`;

const MixinFlex = styled.div`
 ${flexcenter}
 border: 0.0625rem solid rgb(100, 21, 183);
`;

Reference

profile
그때그때 공부한 내용과 생각을 기록하는 블로그입니다.

0개의 댓글