Inline Style
먼저 React 컴포넌트를 별도의 CSS-in-JS 라이브러리 없이 순수하게 CSS로만 스타일하는 가장 기본적인 방법을 알아보겠습니다.
가장 간단한 방법은 React 컴포넌트에 CSS 인라인 스타일을 바로 적용하는 것입니다.
하지만 React는 자바스크립트로 작성하기 때문에 웹페이지에서 인라인 스타일을 적용할 때와 약간의 차이점이 있습니다.
- style 속성값에 일반 문자열이 아닌 Javascript 객체가 할당되야 합니다.
- CSS 속성명이 camelCase로 작성되야 합니다.
인라인 스타일은 CSS에서도 그렇듯이 React에서도 유지 보수나 성능 상으로 이유로
권장되지 않는 방법
입니다.
직접 사용해보면 매번 CSS 속성명을 camelCase로 바꿔줘야 하며, 무엇보다 :hover와 같은 pseudo selector도 사용할 수 없습니다.
External Stylesheet
다음 방법은 별도의 파일에 스타일을 정의해놓고, React 컴포넌트 파일에서 해당 CSS 파일을 import하는 방법입니다.
그 다음, 엘리먼트의 className 속성을 이용해서 외부 파일에 정의된 스타일을 맵핑시켜주는 것입니다.
보통 CSS를 직접 작성하지 않고 Bootstrap과 같은 외부 CSS 라이브러리를 사용할 때 자주 쓰입니다.
class는 자바스크립트에서 클래스 정의 용도로 사용되는 키워드이기 때문에 className를 사용해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
/* Button.css */
.btn {
color: white;
background: teal;
padding: 0.375rem 0.75rem;
border: 1px solid teal;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
}
1
2
3
4
5
6
import React from "react";
import "./Button.css";
function Button() {
return <button className="btn">External</button>;
}
CSS Module
외부 스타일시트를 사용할 때 2개의 CSS 파일에 동일한 클래스에 대한 스타일이 정의되어 있다면, 해당 클래스가 적용된 엘리먼트는 2개의 스타일에 모두 영향을 받게 됩니다.
CSS Module은 각 CSS 파일에 고유의 네임 스페이스를 부여하기때문에 겹치는 문제를 해결할 수 있습니다.
React 컴포넌트에 CSS 모듈을 통해서 스타일을 적용하는 순서
- .module.css 확장자를 사용합니다.
- React 컴포넌트 파일에서 import할 때, CSS 모듈의 이름을 명시적으로 지정해줍니다. (import modlue_name from “./my/style.module.css”)
- Element의 className 속성을 할당해줄 때, 해당 클래스가 어느 CSS 모듈 소속인지 알려줍니다. (module_name.class_name)
- 예시
1
2
3
4
5
6
7
8
import React from "react";
import styles from "./Button.module.css";
function Button() {
return <button className={styles.btn}>Module</button>;
}
export default Button;
CSS in JS
CSS in JS는 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법입니다.
React나 Vue와 같은 라이브러리들은 컴포넌트 기반 개발 방법을 주로 사용하기때문에 웹 개발시 HTML, CSS, JS를 분리하지않고 한번에 작성하는 방법을 사용합니다.
React는 JSX를 사용해 JS안에 HTML을 포함하고있습니다.
따라서, CSS in JS 라이브러리를 사용하면 JS안에 HTML과 CSS가 모두 작성된 형태를 취할 수 있습니다.
styled-components
Javascript 파일 내에서 CSS를 사용할 수 있게 해주는 대표적인 CSS-in-JS 라이브러리로 React 프레임워크를 주요 대상으로 한 라이브러리입니다.
설치
1
npm i -s styled-components
Tagged Template Literals
Template Literals
백틱(`) 을 사용하여 문자열과 변수를 함께 사용해서 문자열을 처리합니다.
Tagged Template Literals
템플릿 리터럴의 발전된 형태로써, 함수 형태로 사용할 수 있습니다.
문자열에서 정적 데이터, 동적 데이터라고 구분지을 수 있습니다.
1 2 3 4 5 6
function transform(staticData, ...dynamicData) { console.log(staticData); // ["Hi, ", " and I am ", "."] console.log(dynamicData); // ["Mygumi", 20] } transform`Hi, ${userName} and I am ${age}.`;
동적 데이터의 타입은 String 이 원래의 형태로 타입이 유지됩니다.
즉, Tagged Template Literals 문법을 사용하면 타입에 상관없이 Function, Number, Array, Object 등을 전달하고 이를 실행할 수 있게 됩니다.
styled-components 기본 사용법
먼저 설치한 styled-components 패키지에서 styled 함수를 import합니다.
그런 다음 HTML 엘리먼트나 React 컴포넌트 중 어떤 것을 스타일링 하느냐에 따라 달라집니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근합니다.
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
// React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 import 후 인자로 해당 컴포넌트를 넘기면 됩니다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
두가지 모두 ES6의 Tagged Template Literals을 사용해서 스타일을 정의합니다.
styled 함수는 해당 스타일이 적용된 HTML 엘리먼트나 React 컴포넌트를 반환합니다.
1
2
3
4
5
import styled from "styled-components";
styled.button`
font-size: 1rem;
`;
위 코드는 아래의 CSS 코드가 적용된 <button>
HTML Element를 반환합니다.
1
2
3
button {
font-size: 1rem;
}
styled-components의 props 사용하기
styled components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공합니다.
Tagged Template Literals을 사용하기 때문에 함수도 문자열 안에 포함시킬 수 있다는 점을 이용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from "react";
import styled, { css } from "styled-components";
// div테그를 스타일링해서 Circle컴포넌트에 넣습니다.
// color props를 받아 사용합니다.
const Circle = styled.div`
width: 5rem;
height: 5rem;
background: ${(props) => props.color || "black"};
border-radius: 50%;
${(props) =>
props.huge &&
css`
width: 10rem;
height: 10rem;
`}
`;
// 여러 줄의 css코드를 조건식으로 넘겨
function App() {
return <Circle color="blue" huge />;
}
export default App;
styled-components 스타일 확장
기존에 만든 스타일에 몇가지를 추가해 확장한 새로운 스타일을 만들고 싶다면 아래의 방법을 이용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
const StyleButton = styled.button`
display: inline-flex;
outline: none;
border: none;
border-radius: 4px;
color: white;
`;
//StyleButton값은 세팅이 되어 있는 상태에서 새로운 스타일을 추가할 수 있습니다.
const RedButton = styled(Stylebutton)`
color: red;
`;