리액트 컴포넌트를 스타일링할 때는 다양한 방법이 있습니다. 자신이 필요하거나 회사가 원하는 방식으로 만들면 됩니다. 이번 포스트에서 알아볼 스타일링 방식은 다음과 같습니다.
- 일반 CSS : 컴포넌트를 스타일링하는 가장 기본적인 방식
- Sass : 자주 사용되는 CSS 전처리기(prev-processor) 중 하나로 확장된 CSS 문법을 사용하여 CSS를 더욱 쉽게 작성할 수 있음
- CSS Module : 스타일을 작성할 때 CSS 클래스가 다른 CSS 클래스의 이름과 충돌하지 않도록 고유의 이름을 지정하는 옵션
- styled-components : 스타일을 자바스크립트 파일에 내장시킴, 해당 스타일이 적용된 컴포넌트를 스타일을 작성함과 동시에 만듦
이번 실습은 다음과 같은 순서로 진행합니다.
- 프로젝트 준비하기
- 일반 CSS 사용하기
- Sass 사용하기
- CSS Module 사용하기
- styled-components 사용하기
터미널에 다음의 코드를 입력하여 프로젝트를 새로 만들어 봅시다.
$ yarn create react-app styling-react
$ cd styling-react
$ yarn start
📌 가장 흔한 방식, 일반 CSS
프로젝트는 일반 CSS 방식으로 만들어져 있습니다. 기존의 스타일링이 불편하지 않다면 일반 CSS를 계속 사용해도 됩니다.
방금 만든 프로젝트를 보면 src 디렉터리에 App.js 파일과 App.css 파일이 있습니다.
CSS를 작성할 때 가장 중요한 것은 CSS 클래스가 중복되지 않게 만들어야합니다. 이름을 지을 때 특별한 규칙을 사용하거나, CSS Selector 를 활용하여 중복되지 않는 이름을 지을 수 있습니다.
📚 이름 짓는 규칙
/* App.css */
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
( ... )
- 프로젝트에 자동 생성된 App.css를 읽어보면 클래스 이름이 컴포넌트 이름-클래스 형태로 지어져 있음 (예: App-logo)
- 클래스 이름에 컴포넌트 이름을 포함하여 중복되는 클래스를 만드는 것을 방지함
비슷한 방식으로 BEM 네이밍(BEM Naming)이라는 방식도 있습니다. CSS 방법론 중 하나로, 이름을 지을 때 일종의 규칙을 준수하여 클래스가 어디에서 어떤 용도로 쓰이는지 명확히 밝힙니다. (예: .card_title-primary)
📚 CSS Selector
CSS Selector 를 사용하면 CSS 클래스가 특정 클래스 내부에 있는 경우에만 스타일을 적용합니다.
.App 안에 들어있는 .logo에 스타일을 적용하려면 다음과 같이 작성해야합니다.
.App .logo {
animation: App-logo-spin infinite 20s linear;
height: 40vmin;
}
다음의 규칙을 적용하여 App.css와 App.js를 다시 작성해봅시다.
/* App.css */
.App {
text-align: center;
}
/*A pp 안에 있는 .logo */
.App .logo {
height: 40vmin;
pointer-events: none;
}
/* .App 안에 들어 있는 header
header 클래스가 아닌 header 태그 자체에
스타일을 적용하기 때문에 .이 생략되었습니다. */
.App header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
/* .App 안에 들어 있는 a 태그 */
.App a {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
수정된 컴포넌트에 맞게 App.js 역시 컴포넌트의 JSX 부분을 수정해야합니다.
// App.js
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header> // 변경
<img src={logo} className="logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
컴포넌트 최상위 html 요소에는 컴포넌트 이름으로 클래스 이름을 짓고(.App), 그 내부에서는 소문자를 입력하거나(.logo), header와 같은 태그를 사용하여 클래스 이름을 생략할 수도 있습니다.
📌 Sass 사용하기
Sass(Syntactically Awesome Style Sheets) (문법적으로 매우 멋진 스타일 시트)는
- CSS 전처리기로 복잡한 작업을 쉽게하도록 하고,
- 스타일 코드의 재활용성을 높여주며,
- 코드의 가독성을 높여 유지 보수를 쉽게 해줍니다.
Sass 에서는 두 가지 확장자 .scss .sass를 지원합니다. 두 확장자는 문법이 꽤 다릅니다. 코드를 확인하여 문법 차이를 느껴보세요
/* .sass */
$front-stack: Helvetica, sans-serif
$primary-color: #333
body
font: 100% $front-stack
color: $primary-color
/* .scss */
$front-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $front-stack;
color: $primary-color;
}
주요 차이점으로는
- .sass : 중괄호({})와 세미콜론(;)을 사용하지 않음
- .scss : 기존 CSS를 작성하는 방식과 비교해서 문법이 크게 다르지 않음
- .scss가 더 많이 사용되므로 이 방식을 사용할 예정
Sass를 CSS로 변환시켜주는 sass라는 라이브러리를 설치해봅시다.
(터미널에서 해당 디렉터리로 이동 하여 설치 후, 서버를 재 부팅해야합니다.)
$ yarn add sass
설치 후 SassComponent.scss 를 작성해보세요.
/* SassComponent.scss */
// 변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;
// 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있음)
@mixin square($size) {
$calculated: 32px * $size;
width: $calculated;
height: $calculated;
}
.SassComponent {
display: flex;
.box { // 일반 CSS에서는 .SassComponent .box와 마찬가지
background: red;
cursor: pointer;
transition: all 0.3s ease-in;
// .red 클래스가 .box와 함께 사용되었을 때
&.red {
background: $red;
@include square(1);
}
&.orange {
background: $orange;
@include square(2);
}
&.yellow {
background: $yellow;
@include square(3);
}
&.green {
background: $green;
@include square(4);
}
&.blue {
background: $blue;
@include square(5);
}
&.indigo {
background: $indigo;
@include square(6);
}
&.violet {
background: $violet;
@include square(7);
}
// .box에 마우스를 올렸을 때
&:hover {
background: black;
}
}
}
이 Sass 스타일 시트를 사용하는 SassComponent.js도 만들어봅시다.
// SassComponent.js
import './SassComponent.scss'
const SassComponent = () => {
return (
<div className='SassComponent'>
<div className='box red' />
<div className='box orange' />
<div className='box yellow' />
<div className='box green' />
<div className='box blue' />
<div className='box indigo' />
<div className='box violet' />
</div>
);
};
export default SassComponent;
이 컴포넌트를 App 컴포넌트에서 보여줍시다.
// App.js
import { Component } from "react";
import SassComponent from "./SassComponent";
class App extends Component {
render() {
return(
<div>
<SassComponent />
</div>
);
}
}
export default App;
서버를 재부팅하면 다음과 같은 결과를 얻을 수 있습니다.
📚 utils 함수 분리하기
여러 파일에서 사용되는 Sass 변수와 믹스인은 다른 파일로 분리하여 작성하고, 필요한 곳에서 불러와 사용할 수 있습니다.
src 디렉터리에 styles라는 디렉터리를 생성하고, 그 안에 utils.scss 파일을 만들어 봅시다. 이 파일에는 기존 SassComponent.scss에 적힌 변수와 믹스인을 옮겨둡니다.
/* src/styles/utils.scss */
// 변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
$yellow: #fcc419;
$green: #40c057;
$blue: #339af0;
$indigo: #5c7cfa;
$violet: #7950f2;
// 믹스인 만들기(재사용되는 스타일 블록을 함수처럼 사용할 수 있음)
@mixin square($size) {
$calculated: 32px * $size;
width: $calculated;
height: $calculated;
}
utils.scss 파일에서 선언한 변수와 믹스인을 다시 SassComponent.scss 에서 사용해봅시다.
/* SassComponent.scss */
@import './styles/utils';
.SassComponent {
display: flex;
.box { // 일반 CSS에서는 .SassComponent .box와 마찬가지
( ... )
}
}
- @import 구문을 이용하여 다른 scss 파일을 불러올 수 있습니다.
📚 sass-loader 설정 커스터마이징하기
이 작업은 필수는 아니지만 하면 좋은 작업입니다.
@import를 할 때 절대 주소나 상대 주소로 파일의 경로를 지정할 때, 구조가 깊어지면 상위폴더를 한참 올라가야합니다.
@import '../../../styles/utils'
sass-loader의 설정을 커스터마이징하여 이 문제를 해결할 수 있습니다. create-react-app으로 만든 프로젝트는 프로젝트 구조의 복잡성을 낮추기 위해 세부 설정이 모두 숨어져 있습니다. yarn eject 명령어를 통해 세부설정을 밖으로 빼 커스터마이징할 수 있습니다.
create-react-app에는 기본적으로 Git 설정이 되어있어 먼저 커밋을 진행해봅시다.
VS Code 좌측에 있는 Git UI를 사용하거나 명령어를 통해 작업을 커밋할 수 있습니다.
$ git add .
$ git commit -m 'Commit before yarn eject'
이후 yarn eject 명령어를 사용해봅시다
$ yarn eject
$ react-scripts eject
이제 프로젝트 디렉터리에는 config라는 디렉터리가 생겼을 것입니다. webpack.config.js를 열어 "sassRegex"라는 키워드를 찾아보세요(ctrl+F) 두 번재 탐색 결과에서 다음과 같은 코드를 찾을 수 있을 것입닏나.
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
‘sass-loader‘
),
sideEffects: true,
},
여기서 use:에 있는 'sass-loader' 부분을 지우고, 뒷부분에 concat을 커스터마이징된 sass-loader 설정을 넣으세요.
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders({
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}).concat({
loader: require.resolve('sass-loader'),
options: {
sassOptions: {
includePaths: [paths.appSrc+'/styles'],
},
additionalData: "@import 'utils';",
},
}),
sideEffects: true
},
- 설정 파일을 저장하고 서버를 재부팅하면 utils.scss 파일을 불러올 때 앞부분에 상대 경로를 입력할 필요가 없습니다.
📚 node_modules 에서 라이브러리 불러오기
Sass 의 장점은 라이브러리르 쉽게 불러올 수 있다는 것 입니다. yarn 을 통해 설치한 라이브러리는 상대 경로를 통해 node_modules에서 불러와야합니다. 때문에 ../를 많이 적어야하는데 대신 물결 문자(~)를 사용할 수 있습니다.
@import '../../../node_modules/library/styles'
@import '~/library/styles'
연습삼아 유용한 Sass 라이브러리를 설치해봅시다.
- 반응형 디자인 : include-media (https://include-media.com)
- 색상 팔래트 : open-color (https://www.npmjs.com/package/open-color)
yarn 명령어로 다음의 라이브러리를 설치해봅시다.
$ yarn add open-color include-media
설치를 마쳤다면 utils.scss 파일을 열고 물결 표시를 열어 라이브러리를 불러오면 됩니다.
// utils.scss
@import '~include-media/dist/include-media';
@import '~open-color/open-color';
Sass 라이브러리를 불러올 때는 node_modules 내부 라이브러리 경로 안에 있는 scss 파일을 불러야합니다. 직접 경로로 들어가 확인해보는 과정이 필요합니다.
.SassComponent {
display: flex;
background: $oc-gray-2;
@include media('<768px') {
background: $oc-gray-9;
}
- 이 코드는 SassComponent의 배경색을 open-color 팔레트 라이브러리에서 불러온 후 설정
- 화면 가로 크기가 768px 미만이 되면 배경을 어둡게 만듭니다.
'프레임워크 > REACT' 카테고리의 다른 글
[React] 11. 컴포넌트 성능 최적화 (0) | 2022.12.25 |
---|---|
[React] 10. 일정 관리 웹 애플리케이션 만들기 (0) | 2022.12.19 |
[React] 8장. Hooks (0) | 2022.12.12 |
[React] 07. 컴포넌트의 라이프사이클 메서드 (0) | 2022.11.14 |
[React] 06. 컴포넌트 반복 (0) | 2022.11.07 |