CSS 전처리기가 하는 일은 간단하다. 여러 가지 기능들을 문법적으로 편리하게 작성할 수 있도록 제공하는 전처리기의 양식에 맞게 파일을 작성해두면, 그걸 최종적으로 실제 실행 전에 처리를 해줘서 브라우저가 읽을 수 있는 CSS 파일로 변환해 주는 일을 수행한다.
3-1) 라이브러리 설치
$ npm install sass
3-2) package.json 에서 sass 라이브러리 설치 확인하기
// package.json
{
"name": "westagram-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"sass": "^4.14.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-scripts": "3.4.3"
}
}
여기서 sass를 작성하는 문법은 두 가지로 나뉘어 있는데, .sass 파일은 sass 문법을 활용한 방법이고, .scss 파일은 scss 문법을 활용한 방법이다. 두 가지 문법을 보면 이름만 약간 달라보이지 사용하는데 큰 차이가 있어 보이지 않는다.
다만, 처음 sass가 등장했을때 sass 문법을 활용했는데, 현재는 sass보다 scss 문법을 사용하는 것을 권장하고 있다. 그 이유는 sass의 문법 개선을 통해 나온 것이 scss이기도 하고, 여러 가지 문법의 차이가 있지만 scss가 더 넓은 범용성과 CSS의 호환성 등의 장점이 있기 때문에 sass보단 scss 문법을 익히는 것이 좋기 때문이다.
기존의 css 파일이 있다면 React에서 사용하는 해당 파일 확장자를 scss로 변경한뒤 사용하면 되지만, 확장자명을 변경한뒤 실제 코드에서 확인해보면, 파일에서 적용했던 스타일이 잘 적용이 되는 부분도 있다 하더라도, 다른 스타일이 적용되어 스타일이 깨지는 모습을 보게 된다.
이유는 SPA(Single Page Application)과 연관되어 있다. MPA(Multi-Page Application)방식에서는 각각의 페이지 마다 CSS를 독립적으로 import 하기 때문에 선택자가 해당 페이지에서만 스타일이 적용될 수 있도록 중복되지 않도록 하면 됐는데, SPA 방식은 각각의 JSX 파일에서 독립적으로 CSS 파일을 import 했다 하더라도, Router.js에 모든 페이지 컴포넌트들이 모이고, index.js를 거쳐 결국 index.html에 모이게 되는 구조이기 때문에, 각각의 CSS 파일에서 겹치는 선택자가 있다면,스타일이 깨질 수 밖에 없는 문제가 생기는 것이다.
결국 이런 문제를 해결하기 위해선 className을 다르게 주거나 자손결합자를 사용하는 방법이 있다. className을 모두 다르게 주는 방법은 처음에는 가능할지 몰라도, 컴포넌트가 많아지고 관리하는 태그들이 많아지게 된다면 나도 모르게 중복해서 사용하는 className이 있을 수 있고, 그렇게 된다면 유지보수를 하거나 에러를 고치는데 상당히 복잡해질 수 있는 문제점이 발생할 수 있으므로 주의해야 한다.
// src/pages/Login/Login.js
import React from 'react';
import './Login.scss';
cosnt Login = () => {
return (
<div className="login"> // 1
<h1 className="title">로그인 페이지입니다.</h1>
</div>
);
};
export default Login;
// src/pages/Login/Login.scss
.login .title { // 2
color: red;
}
CSS 에서 주로 사용하는 자손 결합자를 이용하는 방법이 있는데 스타일을 적용하고자 하는 선택자 앞에 최상위 부모 태그의 className으로 부여했던 선택자를 작성해서 컴포넌트별로 스타일이 적용될 수 있도록 구현해준다. 위와 같은 방식으로 스타일을 적용하면 컴포넌트끼리 CSS가 겹치지 않고 원하는 스타일링을 적용할 수 있다.
CSS에선 자손 결합자를 이용해 스타일링을 적용시켜 코드의 가독성을 높일 수 있지만 그것만 으로도 모든 문제를 해결하기란 부족한점이 많다. SCSS에선 Nesting 이라는 기능을 이용해 부족한 점을 해결할 수 있도록 만들었다.
5-1) Nesting
예제 코드)
// Nesting 사용 예제)
.login { // 1
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title { // 2
color: blueviolet;
font-size: 50px;
}
.title2 { // 3
color: red;
font-size: 50px;
}
5-2) 변수
예제 코드)
// 변수 사용 예제)
$red: #ff1900; // red 변수 선언
$blue: #003cff; // blue 변수 선언
.login {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title {
color: $red; // red 변수 할당
font-size: 50px;
}
.title2 {
color: $blue; // blue 변수 할당
font-size: 50px;
}
}
5-3) 선택자(selector)
// 선택자(&:)
.button { // main 버튼
width: 150px;
padding: 15px;
&:hover {
cursor: pointer; // 버튼을 가져다 댔을때 마우스 포인터로 변환
}
}
/* Compile to CSS */
button {
width: 150px;
padding: 15px;
}
button:hover{
cursor: pointer;
width: 150px;
padding 15px;
}
5-4) mixin & include
// 사용 예제
// h1 변수 선언(@mixin)
@mixin h1 {
font-size: 30px;
color: green;
}
.login {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// h1 변수 사용(@include)
.title, .title2 {
@include h1();
}
}
- 그외 SCSS 공식문법은 공식문서 참조