컴포넌트를 스타일링하는 가장 기본적인 방식
CSS 전처리기 중 하나로 확장된 CSS 문법을 사용
yarn add node-sass
sass파일은 변수, 믹스인, 애니메이션, 타이포 등등 구조화하여 작성하기 때문에 프로젝트 디렉토리가 점점 깊어진다.
sass-loader
설정을 통해 커스터마이징🤔 sass-loader가 뭐지?
sass loader는 sass,scss 파일을 로드하고 css로 컴파일한다.
🤔 그래서 어떻게 쓰지?
모듈 설치 → webpack.config.js 수정 (concat을 통해 커스터마이징된 sass-loader 설정으로 수정)
먼저 commit 할 내용이 있으면 commit 후 모듈 설치
> git add .
> git commit -m‘Commit before yarn eject‘
> yarn eject
yarn run v1.12.0
warning ../package.json: No license field
$ react-scripts eject
? Are you sure you want to eject? This action is permanent. (y/N) y
create-react-app으로 만든 프로젝트는 프로젝트 구조의 복잡도를 낮추기 위해 세부 설정이 모두 숨겨져 있다.
이를 커스터마이징 하려면 프로젝트 디렉터리에서 yarn eject
명령어를 통해 세부 설정을 밖으로 꺼내 주어야 하며, 한 번 eject을 하면 이전 상태로 돌아갈 수 없다.
webpack.config.js 수정
**[webpack.config.js에서 sassRegex 찾아서 아래 ‘sass-loader‘ 수정]**
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
‘sass-loader‘
),
sideEffects: true,
},
**[아래와 같이 ‘sass-loader‘ 수정]**
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders({
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap
}).concat({
loader: require.resolve(‘sass-loader‘),
options: {
includePaths: [paths.appSrc + ‘/styles‘],
sourceMap: isEnvProduction && shouldUseSourceMap,}
}),
sideEffects: true
},
@import 'index.scss';
로 줄여서 쓸 수 있다.
Sass의 장점 중 하나는 라이브러리를 쉽게 불러와서 사용할 수 있다는 것이다.
사용하는 방법으로는 아래와 같이 설치한 라이브러리를 상대경로를 사용하여 node_modules까지 들어가서 불러온다.
@import ‘../../../node_modules/library/styles‘;
../
를 대체하여 ~
를 사용하면 자동으로 node_modules에서 탐지하여 스타일을 불러올 수 있다.
예제로 sass 라이브러리 두가지를 설치하고 사용
반응형 디자인을 쉽게 만들어 주는 include-media(https://github.com/eduardoboucas/include-media)
매우 편리한 색상 팔레트인 open-color(https://www.npmjs.com/package/open-color)
yarn add open-color include-media
Sass 라이브러리를 불러올 때는 node_modules 내부 라이브러리 경로 안에 들어 있는 .scss 파일을 불러와야 한다. 보통 scss 파일 경로가 어디에 위치하고 있는지를 라이브러리의 공식 매뉴얼에서 알려 주지 않을 때가 많으니, 직접 경로로 들어가서 확인한다.
index.scss에 라이브러리 불러오기
// @import "../../node_modules/include-media/dist/include-media.scss";
// @import "../../node_modules/open-color/open-color.scss";
// 위의 코드와 같은 코드임!!
@import "~include-media/dist/include-media";
@import "~open-color/open-color";
SassComponent.scss에 불러온 라이브러리 사용하기
.SassComponent {
display: flex;
background: $oc-gray-2;
@include media("<768px") {
background: $oc-gray-9;
}
(…)
}
CSS 클래스가 중첩되지 않게 파일마다 고유한 이름을 자동으로 생성
/* 자동으로 class명이 고유하게 변할거기때문에 class명을 마음대로 가능함 */
/* 글로벌 CSS를 작성하고 싶다면 */
// 1. root 속 text를 전역으로 할 때
.root :global .text { ... }
// 2. local class 내에서 전역으로 할 때???
**:global** .something { ... }
:global(.something) { ... }
.wrapper {
background: black;
}
className= {styles.[클래스 이름]}
className={styles.wrapper}
//여러개의 class 넣어주는 2가지 방법
className={`${styles.wrapper} ${styles.inverted}`} //ES6 문법 템플릿 리터럴
className={[styles.wrapper, styles.inverted].join(‘ ‘)}
CSS Module이 적용된 스타일 파일을 불러오면 객체를 하나 전달받게 되는데
CSS Module에서 사용한 클래스 이름과 해당 이름을 고유화한 값이 키:"값"
형태로 들어 있습니다.
예를 들어 위 코드에서 console.log(styles)를 한다면 다음과 같은 결과가 나타납니다.
{ wrapper: “CSSModule_wrapper__1SbdQ” }
CSS 클래스를 조건부로 설정할 때 유용한 라이브러리 classnames
yarn add classnames
파라미터를 조합한 class 설정
import classNames from ‘classnames’;
classNames(‘one’, ‘two’); // = ‘one two‘
classNames(‘one’, { two: true }); // = ‘one two‘
classNames(‘one’, { two: false }); // = ‘one‘
classNames(‘one’, [‘two’, ‘three’]); // = ‘one two three‘
const myClass = ‘hello’;
classNames(‘one’, myClass, { myCondition: true }); // = ‘one hello myCondition‘
위에서 작성된 class 사용 예시코드
const MyComponent = ({ highlighted, theme }) => (
<div className={classNames('MyComponent', { highlighted }, theme)}>Hello</div>
);
**[라이브러리 사용하지 않을 때]**
const MyComponent = ({ highlighted, theme }) => (
<div className={`MyComponent ${theme} ${highlighted ? 'highlighted' : ''}`}>
Hello
</div>
);
classnames에 내장되어 있는 bind
함수를 사용하면 클래스를 styles.[클래스 이름]
형태를 사용할 필요가 없다.
미리 styles에서 받아 온 후 사용하게끔 설정해 두고 cx('클래스 이름', '클래스 이름2')
형태로 사용할 수 있다.
bind함수
사용 예시 파일
import React from 'react';
import classNames from 'classnames/bind';
import styles from './CSSModule.module.css';
const cx = classNames.bind(styles); // 미리 styles에서 클래스를 받아 오도록 설정하고
const CSSModule = () => {
return (
// ${styles.wrapper} ${styles.inverted}를 cx('wrapper', 'inverted')로 변경
<div className={cx('wrapper', 'inverted')}>
안녕하세요, 저는 <span className="something">CSS Module!</span>
</div>
);
};
export default CSSModule;
Sass 파일 이름 뒤에 .module.scss 확장자를 사용해 주면 CSS Module로 사용할 수 있다.
CSS Module에서 글로벌 클래스를 정의할 때 :global
을 사용했던 것처럼
CSS Module이 아닌 일반 .css/.scss 파일에서도 :local을 사용하여 CSS Module을 사용할 수 있습니다.
:local .wrapper {
/* 스타일 /
}
:local {
.wrapper {
/ 스타일 */
}
}
스타일을 자바스크립트 파일에 내장시키는 방식으로 스타일이 적용된 컴포넌트 생성
yarn add styled-components
CSS-in-JS: 자바스크립트 파일 안에 스타일을 선언하는 방식으로 관련된 라이브러리는 아래 주소 참고