React/Style

React - Styled Components

고코모옹 2021. 6. 6. 20:18
  • Styled Components 모듈 설치
    • npm i styled-components
// StyledButton.jsx
import styled from 'styled-components';

const StyledButton = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;
  font-size: 20px;
`;

export default StyledButton;

  • Styled Components 기능 확장
    1. props 전달
      • Component에 props를 전달하여 스타일을 다르게 표현
      • styled-components는 JavaScript Template literals 방식으로 표현하기 때문에 ${} 이용하여 로직 처리
    // App.js    
    import StyledButton from './components/StyledButton';
    import styled, { createGlobalStyle } from 'styled-components';
    
    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <p>
              <StyledButton>Button</StyledButton>
              <StyledButton primary>Button</StyledButton>
            </p>
          </header>
        </div>
      );
    }
    
    // StyledButton.jsx
    import styled, { css } from 'styled-components';
    
    const StyledButton = styled.button`
      background: transparent;
      border-radius: 3px;
      border: 2px solid palevioletred;
      color: palevioletred;
      margin: 0 1em;
      padding: 0.25em 1em;
      font-size: 20px;
    
      ${(props) =>
        props.primary &&
        css`
          background: palevioletred;
          color: white;
        `}
    `;
    
    export default StyledButton;
    // App.js
    const MyButton = (props) => (
      <button {...props} children={`MyButton ${props.children}`} />
    );
    
    const StyledMyButton = styled(MyButton)`
      background: transparent;
      border-radius: 3px;
      border: 2px solid ${(props) => props.color || 'palevioletred'};
      color: ${(props) => props.color || 'palevioletred'};
      margin: 0 1em;
      padding: 0.25em 1em;
      font-size: 20px;
    
      :hover {
        border: 2px solid red;
      }
    
      ::before {
        content: '@';
      }
    `;
    
    function App() {
      return (
        <div className="App">
          <GlobalStyle />
          <header className="App-header">
            <p>
              <StyledMyButton>button</StyledMyButton>
              <StyledMyButton color="green">button</StyledMyButton>
            </p>
          </header>
        </div>
      );
    }


    1. Styled Components 함수 실행하여 컴포넌트 확장
      • 이미 존재하고 있는 Element는 . 를 통해 접근 가능하지만, 동적으로 생성된 컴포넌트의 경우 styled로 실행하고 추가적은 스타일은 Template literals 방식으로 추가
    // App.js
    import StyledButton from './components/StyledButton';
    import styled, { createGlobalStyle } from 'styled-components';
    
    const PrimaryStyledButton = styled(StyledButton)`
      background: palevioletred;
      color: white;
    `;
    
    function App() {
      return (
        <div className="App">
          <GlobalStyle />
          <header className="App-header">
            <p>
              <StyledButton>Button</StyledButton>
              <StyledButton primary>Button</StyledButton>
              <PrimaryStyledButton>Button</PrimaryStyledButton>
            </p>
          </header>
        </div>
      );
    }


    1. as Props를 사용하여 Element 변경
      1. Element Tag 지정
        • Element Tag를 지정하면 지정한 태그와 같이 동작 및 attribute 사용
      // App.js
      import StyledButton from './components/StyledButton';
      import styled, { createGlobalStyle } from 'styled-components';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <p>
                <StyledButton>Button</StyledButton>
                <StyledButton primary>Button</StyledButton>
                <PrimaryStyledButton>Button</PrimaryStyledButton>
                <StyledButton as="a" href="/">
                  Button
                </StyledButton>
              </p>
            </header>
          </div>
        );
      }
      1. Component 지정
        • 컴포넌트를 지정하여 스타일은 동일하지만 속성을 다르게 표현 가능
      // App.js
      import StyledButton from './components/StyledButton';
      import styled, { createGlobalStyle } from 'styled-components';
      
      const UppercaseButton = (props) => (
        <button {...props} children={props.children.toUpperCase()} />
      );
      
      function App() {
        return (
          <div className="App">
            <GlobalStyle />
            <header className="App-header">
              <p>
                <StyledButton>Button</StyledButton>
                <StyledButton primary>Button</StyledButton>
                <PrimaryStyledButton>Button</PrimaryStyledButton>
                <StyledButton as="a" href="/">
                  Button
                </StyledButton>
                <StyledButton as={UppercaseButton}>Button</StyledButton>
              </p>
            </header>
          </div>
        );
      }

  • Global 스타일 지정
    • createGlobalStyle을 사용하여 Global 스타일 지정 가능
    // App.js
    import styled, { createGlobalStyle } from 'styled-components';
    
    const GlobalStyle = createGlobalStyle`
      button {
        color: yellow;
      }
    `;
    
    function App() {
      return (
        <div className="App">
          <GlobalStyle />
          <header className="App-header">
            <p>
              <StyledButton>Button</StyledButton>
              <StyledButton primary>Button</StyledButton>
              <PrimaryStyledButton>Button</PrimaryStyledButton>
            </p>
          </header>
        </div>
      );
    }

  • styled-component에 Element Attribute 지정
    • Element Attribute를 props로 전달하여 지정 가능
    // StyledA.jsx
    import styled from 'styled-components';
    
    const StyledA = styled.a.attrs((props) => ({
      target: '_blank',
    }))`
      color: ${(props) => props.color};
    `;
    
    export default StyledA;
    
    // App.js    
    import styled, { createGlobalStyle } from 'styled-components';
    import StyledA from './components/StyledA';
    
    function App() {
      return (
        <div className="App">
          <GlobalStyle />
          <header className="App-header">
            <p>
              <StyledA href="https://google.com">태그</StyledA>
            </p>
          </header>
        </div>
      );
    }