<React> Styled-component 동적 Props / CSS Module 동적 스타일링

·2023년 5월 6일
0

React

목록 보기
6/23

Styled-component 동적 Props

스타일 컴포넌트에 props를 할당하여 아래 코드처럼 동적으로 스타일링을 적용할 수 있다.

const FormControl = styled.div`
  margin: 0.5rem 0;

  & label {
    font-weight: bold;
    display: block;
    margin-bottom: 0.5rem;
✅    color: ${(props) => (props.invalid ? "red" : "inherit")};
  }

  & input {
    display: block;
    width: 100%;
✅    border: 1px solid ${(props) => (props.invalid ? "red" : "#ccc")};
✅    background-color: ${(props) => (props.invalid ? "pink" : "inherit")};
    font: inherit;
    line-height: 1.5rem;
    padding: 0 0.25rem;
  }

  &input:focus {
    outline: none;
    background: #fad0ec;
    border-color: #8b005d;
  }
`;

// (이하 생략)const [isValid, setIsValid] = useState(true);
// (이하 생략)<FormControl invalid={!isValid}> // props로 invalid를 할당.
        <label>Course Goal</label>
        <input
          type="text"
          onChange={goalInputChangeHandler}
          value={enteredValue}
        />
    </FormControl>

border: 1px solid ${(props) => (props.invalid ? "red" : "#ccc")};

코드를 보면, isValid라는 state를 관리하고 있다. 이 state를 가지고 스타일 컴포넌트를 동적으로 관리할 수 있다.

Styled-Components in Media Query

기존 스타일 컴포넌트에 @media () {}만 추가해주면 된다.

import styled from "styled-components";

const Button = styled.button`
  width: 100%;
  font: inherit;
  padding: 0.5rem 1.5rem;
  border: 1px solid #8b005d;
  color: white;
  background: #8b005d;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.26);
  cursor: pointer;

  &:focus {
    outline: none;
  }

  &:hover,
  &:active {
    background: #ac0e77;
    border-color: #ac0e77;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.26);
  }

✅  @media (min-width: 768px) {
    width: auto;
    background: red;
  }
`;

export default Button;

미디어쿼리를 지정해줌으로써 해당 Button 컴포넌트는 width가 최소 768px 이상일 때, 버튼 색상이 red로 적용될 것이다.


CSS Module

CSS Module은 그 기능을 지원하도록 설정된 프로젝트에서만 사용 가능하다.브라우저에서 코드가 실행되기 전에 코드의 변환이 필요하기 때문이다.

다행히 React에서는 이미 CSS Module을 지원하도록 설정되어 있다.
(CRA로 프로젝트 생성시, 설정된다 :) )

❗️ css module을 import하는 컴포넌트에만 스타일이 적용된다.

스타일 적용하려면 import styles from "./Button.module.css"; 처럼 컴포넌트 상단에 import 해주기.

CSS Module 스타일 적용

CSS Module은 객체로 취급하기 때문에, 접근 방법이 기존 css와 다르다.

import styles from "./Button.module.css";

const Button = (props) => {
  return (
    <button type={props.type} className={styles.button} onClick={props.onClick}>
      {props.children}
    </button>
  );
};

위 코드처럼 styles로 module css를 가져왔으면, {}하고 {styles.className}으로 적용해주어야 스타일이 적용된다.

Ex ) Button.module.css 처럼 기존 css 파일에 .module.을 추가해주면 모듈화 끝 !

동적 스타일링

// Components.js ... 이하 생략
return (
    <form onSubmit={formSubmitHandler}>
      <div
     ✅  className={`${styles["form-control"]} ${!isValid && styles.invalid}`}
      >
        <label>Course Goal</label>
        <input
          type="text"
          onChange={goalInputChangeHandler}
          value={enteredValue}
        />
      </div>
      <Button type="submit">Add Todo</Button>
    </form>
  );

✅ className={`${styles["form-control"]} ${!isValid && styles.invalid}`}>
=> css module은 객체. styles에 접근하려면 [""]으로 가능하다.

stylesconsole.log 찍어봤는데, 현재 form-control과 invalid에 접근 가능함을 알 수 있다.

백틱``으로 styles 객체에 접근 가능하며, 동적으로(조건부) state에 따라 class를 붙히거나 떼어낼 수 있다.

/* Components.module.css ... 이하 생략 */

.form-control {
  margin: 0.5rem 0;
}

.form-control label {
  font-weight: bold;
  display: block;
  margin-bottom: 0.5rem;
}

.form-control input {
  display: block;
  width: 100%;
  border: 1px solid #ccc;
  font: inherit;
  line-height: 1.5rem;
  padding: 0 0.25rem;
}

.form-control input:focus {
  outline: none;
  background: #fad0ec;
  border-color: #8b005d;
}

.form-control.invalid input {
  border-color: red;
  background-color: rgb(237, 200, 206);
}

.form-control.invalid label {
  color: red;
}

CSS Module 핵심
고유한 클래스명을 생성하기 때문에, 클래스 이름 작명에 고민하지 않아도 된다. 독립성을 보장한다.

독립성?

  • 만약 button.module.css에서 container라는 class를 썼다. 이후에 article.module.css에서 container라는 동일한 class를 사용해도 충돌하지 않고, 각각 스타일이 잘 적용될 것임.

0개의 댓글