'리액트를 다루는 기술' 9장, 컴포넌트 스타일링

Jake_Young·2020년 8월 23일
1
post-thumbnail

😀 가장 흔한 방식, 일반 CSS

  • 컴포넌트를 스타일링하는 가장 기본적인 방식

이름 짓는 규칙

  • 클래스 이름은 "컴포넌트이름-클래스" 형태로 지어야 충돌이 나지 않는다.

CSS Selector

  • ".App header .logo" 처럼 작성하는 방법

😁 Sass 사용하기

  • Syntactically Awesome Style Sheets
  • 자주 사용되는 CSS 전처리기 중 하나로 확장된 CSS 문법을 사용하여 CSS 코드를 더욱 쉽게 작성할 수 있도록 해준다.
  • .scss와 .sass의 두 가지 확장자 지원
  • 두 확장자는 아래와 같은 차이가 있습니다.
// .sass
$font-stack: Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-folor

//.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-folor;
}

😂 CSS Module

  • 스타일을 작성할 때 CSS 클래스가 다른 CSS 클래스의 이름과 절대 충돌하지 않도록 파일마다 고유한 이름을 자동으로 생성해 주는 옵션
  • 파일이름클래스이름해시값 형태로 자동으로 변경해주는 기술
  • .module.css 확장자로 파일을 저장하면 자동으로 CSS Module이 적용됨
import React from "react";
import styles from "./CSSModule.module.css";
// import classNames from "classnames";

// const cx = classNames.bind(styles)

export default function CSSModule() {
  // export default function CSSModule({highligted, theme) {
  return (
    <div className={`${styles.wrapper} ${styles.inverted}`}>
      {/* <div className={cx("wrapper", "inverted")}></div> */}
      {/* <div className={classNames("MyComponent", { highlighted }, theme)}> */}
      {/* <div className={`MyComponent ${theme} ${highlighted ? 'highlighted' : ''}`}> */}
      {/* <div className={[styles.wrapper, styles.inverted].join(' ')}> */}
      Hi <span className="something">CSS Module</span>
    </div>
  );
}
// 설명은 생략한다.

😃 styled-components

  • 스타일을 자바스크립트 파일에 내장시키는 방식으로 스타일을 작성함과 동시에 해당 스타일이 적용된 컴포넌트를 만들 수 있게 해준다.
  • 이 방식의 가장 큰 장점은 props 값으로 전달해 주는 값을 쉽게 스타일에 적용할 수 있다는 것입니다.
  • 스타일 코드 여러 줄을 props에 따라 넣어주어야 할 때는 css를 불러와서 입력해야 한다.
  • 그렇게 하지 않고도 바로 입력할 수 있지만 그럴 경우에는 신택스 하이라이팅이 제대로 이루어지지 않는다.
  • 그리고 무엇보다도 tagged 템플릿이 아니면 함수를 받아 쓰지 못하고 props를 받아 쓰지 못한다.
import React from "react";
import styled, { css } from "styled-components";

const sizes = {
  desktop: 1024,
  tablet: 768,
};

const media = Object.keys(sizes).reduce((acc, label) => {
  acc[label] = (...args) => css`
    @media (max-width: ${sizes[label] / 16}em) {
      ${css(...args)};
    }
  `;
  return acc;
}, {});

const Box = styled.div`
  /* props로 넣어 준 값을 직접 전달해 줄 수 있다 */
  background: ${(props) => props.color || "blue"};
  padding: 1rem;
  display: flex;
  width: 1024px;
  margin: 0 auto;
  ${media.desktop`width: 768px`}
  ${media.tablet`width:100%`}
`;
/* @media (max-width: 1024px) {
  width: 768px;
}
@media (max-width: 768px) {
  width: 100%;
} */

const Button = styled.button`
  background: white;
  color: black;
  border-radius: 4px;
  padding: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-size: 1rem;
  font-weight: 600;
  /* & 문자를 사용하여 Sass처럼 자기 자신 선택 가능 */
  &:hover {
    background: rgba(255, 255, 255, 0.9);
  }
  /* 다음 코드는 inverted 값이 true일 때 특정 스타일을 부여해 줍니다 */
  ${(props) =>
    props.inverted &&
    css`
      background: none;
      border: 2px solid white;
      color: white;
      &:hover {
        background: white;
        color: black;
      }
    `}
  & + button {
    margin-left: 1rem;
  }
`;

export default function StyledComponent() {
  return (
    <Box color="black">
      <Button>Hi</Button>
      <Button inverted={true}>Only Outline</Button>
    </Box>
  );
}
profile
자바스크립트와 파이썬 그리고 컴퓨터와 네트워크

0개의 댓글