React를 다루는 기술 10 - 컴포넌트 스타일링 - 1
React 컴포넌트에서 스타일링을 할 때는 다양한 방식을 이용해서 할 수 있다.
다만, 그 중 정해진 방식을 따라야 한다는 것은 없고 개개인 혹은 프로젝트의 상황에 맞추어 스타일링 방식을 정하고 혹은 여러 방식을 합치는 등 상황에 맞추어 사용하면 된다.
일반 CSS
가장 기본적인 스타일링 방식으로 React 프로젝트 혹은 ES6에 국한된 것이 아닌 모든 프로젝트에서 통용되는 방식이다.
기본인만큼 어떠한 상황에도 통용되며 실제 소규모 프로젝트나 새로운 스타일링 시스템을 도입하는 것이 불필요한 경우에는 일반 CSS 방식을 많이 사용한다.
일반 CSS 방식은 외부에 css파일을 만들어 css 코드를 작성하고 컴포넌트에서 이를 import해서 사용하게 된다.
// App.js
import React from 'react';
import './App.css'
const App = () => {
return (
...
)
}
/* App.css */
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 40vmin;
}
이렇게 CSS를 작성할 때 가장 중요한 것은 Class 이름이 중복되지 않게 하는 것인데 이를 위한 각자의 규칙이나 방법론 등을 정해두고 거기에 맞게 Class이름을 짓는 것이 필요하다.
보통은 컴포넌트 이름을 포함
시키거나 이름을 지을 때 해당 클래스가 사용되는 용도를 명확하게 작성
하는 방식을 통해 중복을 방지할 수 있다.
Sass
Sass(Syntactically Awesome Style Sheets)는 CSS 전처리기로 스타일 코드의 재사용성과 가독성을 높여 유지보수를 도와주는 방식으로 필수적으로 알아둬야하는 방식이다.
create-react-app을 통해 프로젝트를 생성한 경우 본래 Sass방식을 사용하기 위해서는 추가작업이 필요했으나 v2 버전부터는 기본적으로 사용이 가능해졌으며 만약 create-react-app 없이 수동으로 프로젝트를 생성한 경우에는 해당 라이브러리를 설치하고 Webpack.config.js 파일에서 설정을 추가해야한다.
Sass에서는 .scss, .sass의 2가지 확장자를 지원하는데 두 가지 확장자의 차이는 문법의 차이이다.
/* App.sass */
$font-stack: Helvetica
$primary-color: #333
body
font: 100% $font-stack
color: $primary-color
/* App.scss */
$font-stack: Helvetica;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
위처럼 sass의 경우에는 괄호와 세미콜론(;)이 존재하지 않고 scss는 기존의 일반 css와 크게 다르지 않은 형태로 작성되며 보통은 scss를 사용한다.
Sass를 사용하기 위해서는 우선 node-sass라는 라이브러리를 설치해줘야하는데 이는 Sass문법을 일반css문법으로 변환해주는 역할을 한다.
// 변수 사용하기
$red: #fa5252;
$orange: #fd7e14;
...
// 믹스인 (스타일 블록을 함수처럼 사용가능)
@mixin square($size) {
$calculated: 32px * $size;
width: $calculated;
height: $calculated;
}
.SassComponent {
display: flex;
.box { // 일반 css에서의 .SassComponent .box와 동일
background: red;
cursor: pointer;
&.red {
// .red 클래스가 .box 클래스와 함께 사용된 경우
background: $red;
@include square(1);
}
&.orange {
background: $orange;
@include square(2);
}
}
}
// SassComponent.js
import React from 'react';
import './SassComponent.scss';
const SassComponent = () => {
return (
<div className="SassComponent">
<div className="box red" />
<div className="box orange" />
</div>
)
}
위와 같은 형태로 CSS 내에서 변수, 함수의 사용이 가능해지며 해당 클래스의 하위에 위치한 클래스를 json을 작성하듯이 작성할 수 있기 때문에 가독성에서도 큰 차이를 보인다.
또한 scss 파일에서는 다른 scss 파일을 참조하여 사용하는 것도 가능하다.
@import './styles/utils';
.SassComponent {
display: flex;
.box {
background: red;
cursor: pointer;
&.red {
background: $red;
@include square(1);
}
&.orange {
background: $orange;
@include square(2);
}
}
}
이렇게 변수나 함수와 같은 다른 scss 파일에서도 공통적으로 사용될 법한 것들을 따로 모아두고 각각의 scss 파일마다 import하여 사용하는 것으로 정리할 수 있다.
그런데 위와 같이 각각의 scss 파일마다 상대경로로 import를 해오게 된다면 각각의 scss파일의 위치에 따라서는 '../../../../styles/utils'
와 같이 굉장히 경로가 길어지고 알아보기 힘들어질 수도 있다.
이러한 경우를 방지하기 위하여 sass-loader를 설정하여 해결할 수 있다.
sass-loader를 설정하기 위해서는 webpack.config.js 파일을 열어야하는데 create-react-app으로 프로젝트를 생성한 경우에는 이 파일이 숨겨져있다.
때문에 npm run eject(yarn eject)
명령어를 사용하여 webpack.config.js 파일을 찾아야한다.
$ npm run eject
$ react-scripts eject
프로젝트 폴더에서 이렇게 입력하면 디렉터리에 config 파일이 생성되며 내부에서 webpack.config.js 파일을 찾을 수 있다.
이제 여기서 sassRegex라는 단어를 찾아서 sass-loader를 설정할 수 있다.
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleloaders (
{
importLoaders: 2,
sourceMap: isEnvProudction && shouldUseSourceMap,
},
'sass-loader'
),
sideEffects: true
}
여기서 'sass-loader'
라고 적힌 부분을 지우고 concat을 통해 설정을 추가하여준다.
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleloaders (
{
importLoaders: 2,
sourceMap: isEnvProudction && shouldUseSourceMap,
}).concat({
loader: require.resolve('sass-loader'),
options: {
includePaths: [paths.appSrc + '/styles'],
sourceMap: isEnvProudction && shouldUseSourceMap,
}),
sideEffects: true
}
@import 'utils.css';
이렇게 해두면 import시에 파일경로 앞에 아무것도 붙이지 않는 경우 자동으로 styles폴더내에서 참조하게 되어 어디에서든 같은 경로만 붙여주면 되고 알아보기도 간편해진다.
Sass 라이브러리 불러오기
Sass의 또 하나의 장점으로는 라이브러리 쉽게 불러와서 사용할 수 있다는 점이다.
유용한 Sass 라이브러리를 npm을 통해 설치한 뒤 node_modules 폴더에서 라이브러리 디렉터리를 탐지하여 스타일을 불러오는 방식으로 이하와 같이 사용할 수 있다.
@import '~include-media/dist/include-media';
@import '~open-color/open-color';
경로 앞에 붙인 ~
는 상대경로로 일일히 작성할시 길어질 수 있는 경로를 줄여 자동으로 node_modules 폴더를 탐지하여 경로를 지정해주기 위하여 사용하는 것으로 이를 통해 include-media 폴더와 open-color 폴더를 찾아서 라이브러리를 가져오게 된다.
.SassComponent {
display: flex;
background: $oc-gray-2;
@include media('<768px') {
background: $oc-gray-9;
}
}
이렇게 위의 2가지 라이브러리를 import하여 오브젝트의 색깔과 미디어쿼리를 적용할 수 있다.
출처자료
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=209354690 (리액트를 다루는 기술(개정판))