React로부터 들어온 className을 통해, CSS 구현
파일 확장명은 원래는 .sass
를 사용하였으나, 현재는 .scss
를 주로 사용
react를 기준으로 사용하고 싶으면 yarn이 설치된 상태에서,
yarn add node-sass
로 sass설치
import './fileName.scss';
scss파일을 읽기 위해선 .js파일에 위 처럼 import(파일명은 직접입력)
자기 자신을 가리킴
.Button{
&:hover{} // 는 .Button:hover{}와 같음
&.large // 도 .Button.large와 같음
}
참고로 주석은 CSS에선 /* */ 밖에 되지 않았지만, sass는 //도 가능
react에선 class 대신에 className을 사용
return <button className='Button'></button>;
class가 하나 밖에 없다면 문제가 없지만 숫자가 많아진다면,
return <button className=`Button ${size} ${color}`></button>;
이런식으로 설정해줘야 함 (Literal Template이라 ${}사용)
이때는 classnames라는 라이브러리를 사용하면 편함
yarn add classnames
로 설치하고
import classNames from 'classnames';
로 해당 파일에서 import
return <button className={classNames('Button', size, color)}></button>;
이런식으로 하면, 객체도 쉽게 넣을 수 있고 나열이 편해짐
Button.js를 꾸미는 파일을 Button.scss로 했다고 가정
import React from 'react';
import classNames from 'classnames';
import './Button.scss';
function Button({ children, size, color, outline }) {
return (
<button className={classNames('Button', size, color)}>{children}</button>
);
}
Button.defaultProps = {
size: 'medium',
color: 'blue'
};
export default Button;
위 처럼 Button.scss를 import하고, Button function은 button을 return
이 때, props로 받은 값중에 size가 있음
위 예제 코드처럼 size를 className안에 넣어주면, scss파일에서도 .
키워드를 이용해 쉽게 접근할 수 있음
현재 className을 풀어쓰면 다음과 같음
Button size color
물론 size와 color는 문자열이 아니라 값이기 때문에, large와 black을 넣어주게 되면 다음과 같음
Button large black
scss입장에서 large를 바꿔주려면, .large
혹은 .Button.large
가 필요
위에 &에도 적었지만 &.large
가 그걸 해결해줌
react의 경우 App.js파일로 부터 다양한 .js파일들이 props를 받아 className
에 넣어주게 되고, scss는 그 className
에 들어가있는 props들을 이용해 CSS 코드로 페이지를 디자인함
그러다보니 문제점이, props값이 예를 들어 color에 대한 값이면, color가 많은 값들이 들어올수록 CSS 코드가 너무나 길어질 우려가 있음
예: color="black", color="white", ... , color="dodgerblue"
다음과 같은 코드를 보면,
&.blue{
background: $blue;
&:hover {
background: lighten($blue, 10%);
}
&:active {
background: darken($blue, 10%);
}
}
color에 대한 props가 blue
일 경우는, 괜찮지만, 다른 값이 들어오면 이런 코드를 여러개 만들어 줘야함
&.blue {
background: $blue;
&:hover {
background: lighten($blue, 10%);
}
&:active {
background: darken($blue, 10%);
}
}
&.gray {
background: $gray;
&:hover {
background: lighten($gray, 10%);
}
&:active {
background: darken($gray, 10%);
}
}
&.pink {
background: $pink;
&:hover {
background: lighten($pink, 10%);
}
&:active {
background: darken($pink, 10%);
}
}
이런 불필요한 코드의 증가를 줄여주는게 mixin
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 10%);
}
}
@mixin
을 통해, 매개변수 $color
를 받아, 마치 함수에서 x값에 따라 y값의 결과가 달라지도록 만듦
&.blue {
@include button-color($blue);
}
&.gray {
@include button-color($gray);
}
&.pink {
@include button-color($pink);
}
부르는 쪽은 다음처럼 부르면 됨
만약 className에 visible과 같은 true, false 둘 중 하나의 값으로 갈리는 경우는 다음과 같이 사용할 수 있음
<button className={classNames('Button', size, color, {visible})}>
객체 형태로 만들면, visible이 true인 경우는 className이
Button size color visible
이 되고, false라면,
Button size color
가 됨
App.js
에서 props로 className
을 넘겨줄 수도 있음
<Button size="large" color="white" className="customized">
이런식으로 해주면 Button.js에서는 해당 className을 가지고 다음처럼 사용가능
.Button{
&.large{
font-size: 30px;
}
&.white{
color: white;
}
&.customized{
border: none;
font-size: 1.5rem;
}
}