Styled Components와 css function을 함께 사용하는 것이 좋습니다.

안녕하세요.고양이 기르는 엔지니어sotszk입니다.
이 기사는 YAMAP 엔지니어 어드벤트 칼렌다어 2020의 25일째다.끝났어.
https://qiita.com/advent-calendar/2020/yamap-engginers

독자 대상

  • 장년scss로 css를 쓴 사람
  • css in JS를 어떻게 쓰는지 모색 중인 사람
  • css in JS를 쓰려면 scss와 똑같이 쓰는 사람
  • 이 기사로 쓰겠습니다.

  • Styled Components, css function으로 scss에 적힌 코드를 쓰면 어떻게 됩니까
  • 이 기사에 쓰지 마라

  • StyledComponents, css function은 무엇입니까
  • StyledComponents, css function의 설정 방법
  • 내부에 무슨 일이 일어났는지
  • 실천 코드(이런 코드만 쓰기)
  • 메시지


    Styled Components, css function으로 scss가 쓴 코드를 쓰면 어떻게 될까요


    스타일 적용


    scss로 쓰면 다음과 같은 >.
    <div class="navbar">
      <ul class="navbar__link-list">
        <li class="navbar__link-list-item">
          <a class="navbar__link" href="">りんく</a>
        </li>
      </ul>
    </div>
    
    scss로 몸을 데치는 것이 이렇습니다.
    .navbar {
      border: 1px solid #666;
    }
    .navbar__link-list {
      display: flex;
    }
    .navbar__link-list-item {
      list-style-type: none;
      &:not(:first-child) {
        margin-left: 4px;
      }
      @media screen and (min-width: 768px) {
        &:not(:first-child) {
          margin-left: 8px;
        }
      }
    }
    .navbar__link {
      text-decoration: none;
    }
    
    Styled Components, css function을 사용하여 이것을 대체합니다.
    먼저 Styled Components 가 있습니다.
    const Navbar = () => (
      <Wrapper>
        <LinkList>
          <LinkListItem>
            <Link href="">りんく</Link>
          </LinkListItem>
        </LinkList>
      </Wrapper>
    );
    
    const Wrapper = styled.div`
      border: 1px solid #666;
    `
    const LinkList = styled.ul`
      display: flex;
    `
    const LinkListItem = styled.li`
      list-style-type: none;
      &:not(:first-child) {
        margin-left: 4px;
      }
      @media screen and (min-width: 768px) {
        &:not(:first-child) {
          margin-left: 8px;
        }
      }
    `
    const Link = styled.a`
      text-decoration: none;
    `
    
    다음은 css function.
    const Navbar = () => (
      <div css={styles.navbar}>
        <ul css={styles.linkList}>
          <li css={styles.linkListItem}>
            <a css={styles.link} href="">りんく</a>
          </li>
        </ul>
      </div>
    );
    
    const styles = {
      navbar: css`
        border: 1px solid #666;
      `,
      linkList: css`
        display: flex;
      `,
      linkListItem: css`
        list-style-type: none;
        &:not(:first-child) {
          margin-left: 4px;
        }
        @media screen and (min-width: 768px) {
          &:not(:first-child) {
            margin-left: 8px;
          }
        }
      `,
      link: css`
        text-decoration: none;
      `,
    }
    
    css 부분은 완전 scss입니다.
    Styled Components와 css function 두 가지 모드를 썼지만 실제로는 대부분의 경우 상황에 따라 구분해서 사용한다.

    variables


    css에서도 변수, 상수를 사용할 것 같습니다.
    CSS in JS의 경우theme에서도 대상을 일괄적으로 정의하고 context API를 사용하여 응용 프로그램 전체에 주입하는 방법이 있다.
    하지만 이번에는 scss$color-primary: red값의 사용 상황에서 Styled Components, css function을 어떻게 하는지 간단히 소개하겠습니다.
    참고로 themae 주입은 theming이라고 불리며 최근 몇 년 동안 다양한 프로그램 라이브러리에서 지원되고 있다.
    그럼 scss부터.
    $color-primary: red;
    
    Styled Components, css function 때는 이렇습니다.
    /* variables/colors.js */
    export const colors = {
      primary: 'red',
    }
    
    /* navbar.jsx */
    import { colors } from './variables/colors';
    // ...
    const Link = styled.a`
      color: ${colors.primary};
    `
    // theme を使うならこんな感じ
    const LinkWithTheme = styled.a(({ theme }) => css`
      color: ${theme.colors.primary};
    `);
    

    mixins


    예를 들면 이런 scss mixin이 있어요.
    @mixin buttonBase {
      display : inline-flex;
      white-space: nowrap;
      align-items: center;
      justify-content: center;
      padding: space(1) space(2);
      text-align: center;
      font-size: 1.4rem;
      border-radius: 4px;
      font-weight: bold;
      text-decoration: none;
      border: none;
      box-sizing: border-box;
      line-height: 1.6;
      background: transparent;
      cursor: pointer;
      transition-property: background, color;
      transition-duration: 100ms;
      transition-timing-function: ease-in;
    }
    
    @mixin buttonPrimary {
      @include btnBase;
      background: red;
      color: white;
      border: solid 1px red;
    }
    
    @mixin screenMax($break-point) {
      @media screen and (max-width: $break-point - 1) {
        @content;
      }
    }
    
    @mixin screenMin($break-point) {
      @media screen and (min-width: $break-point) {
        @content;
      }
    }
    
    .login-button {
      @include btnPrimary;
    }
    .ad {
      @include screenMin(768px) {
        display: none;
      }
    }
    
    Styled Components, css function을 사용하여 이러한 내용을 작성할 경우 이렇게 됩니다.
    const buttonBase = css`
      display : inline-flex;
      white-space: nowrap;
      align-items: center;
      justify-content: center;
      padding: space(1) space(2);
      text-align: center;
      font-size: 1.4rem;
      border-radius: 4px;
      font-weight: bold;
      text-decoration: none;
      border: none;
      box-sizing: border-box;
      line-height: 1.6;
      background: transparent;
      cursor: pointer;
      transition-property: background, color;
      transition-duration: 100ms;
      transition-timing-function: ease-in;
    `
    
    const buttonPrimary = css`
      ${btnBase};
      background: red;
      color: white;
      border: solid 1px red;
    `
    
    const screenOver = (px) => {
      return `@media (min-width: ${px}px)`;
    }
    
    const screenUnder = (px) => {
      return `@media (max-width: ${px}px)`;
    }
    `
    
    export const mixins = {
      buttonBase,
      buttonPrimary,
      screenOver,
      screenUnder,
    }
    
    그리고 이 구성 요소를 적용한 것은 다음과 같다.
    import { mixins } from './mixins';
    
    const Navbar = () => (
      <Wrapper>
        <LinkList>
          <LinkListItem>
            <Link href="">りんく</Link>
          </LinkListItem>
        </LinkList>
      </Wrapper>
    );
    
    // ...
    const LinkList = styled.ul`
      display: flex;
      ${mixins.screenUnder(767)} {
        display: block;
      }
    `
    const LinkListItem = styled.li`
      list-style-type: none;
      &:not(:first-child) {
        margin-left: 4px;
      }
      ${mixin.screenOver(768)} {
        &:not(:first-child) {
          margin-left: 8px;
        }
      }
    `
    const Link = styled.a`
      ${mixin.buttonPrimary};
    `
    

    사족


    > 탭에 css attribute를 직접 지정하면, 그룹이나 함수로 지정할 수도 있습니다.
    후자의 경우 (theme) => { ... }처럼 theme(theming의 경우)를 받을 수 있다.
    const LoginButton = () => (
      <button css={[mixins.buttonPrimary, css`
        font-size: 2em;
      `]}>Login</button>
    )
    

    끝말


    그게 다야.여러분께 조금이나마 도움이 되었으면 좋겠습니다.
    한편 YAMAP는 다양한 엔지니어들을 모집하고 있다는 찬사를 아끼지 않고 있다.만약 약간의 흥미가 있다면 언제든지 나와 상의하세요!
    https://www.wantedly.com/projects/517777
    https://www.wantedly.com/projects/536882
    후쿠오카는 밥이 맛있어서 이민도 추천합니다.
    그럼 새해 복 많이 받으세요.

    좋은 웹페이지 즐겨찾기