일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- TypeScript
- wai-aria
- 비트연산자
- 디자인
- 카드뉴스
- programmers
- 제로베이스 프론트엔드 스쿨
- JavaScript
- 프로그래머스
- 알고리즘
- leetcode
- 웹접근성
- react-query
- html&css
- react
- 정규표현식
- Today
- Total
記錄
[React 스터디 - 6] 리액트 CSS 적용 방법 본문
01 Inline style
html 태그 안에 직접 입력하는 방법으로, style={ } 형식으로 입력한다. 안에는 json 형식으로 { 속성명: '속성값' } 으로 입력한다. 일반적인 css 문자열을 작성할 때 사용하는 케밥 케이스(kebab case)가 아닌 camelCase를 사용하는데, JSX에서는 인라인 스타일을 자바스크립트 객체로 받아들이기 때문이다.
//html, kebab case
<h1 style="background-color: purple">텍스트</h1>
//jsx, camelCase
<h1 style={{ backgroundColor: "purple" }}>텍스트</h1>
다음과 같이 Javascript 객체를 이용해 작성할 수도 있다.
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')'
}
function HelloWorldComponent(){
return <div style={divStyle}>Hello World!</div>
}
숫자 인라인 스타일 프로퍼티일 경우, px를 자동으로 추가하기 때문에 다른 단위를 원하면 그 단위를 따로 입력해야 한다.
//px를 단위로 자동 추가
<div style={{ height: 10 }}>10px</div>
//다른 단위를 명시적으로 입력
<div style={{ height: '10%' }}>10%</div>
+ 인라인 스타일 적용은 가장 높은 우선순위를 가지나, 복잡한 컴포넌트에서 스타일 작성이 어려워지기 때문에 권장하지 않는다.
+ 인라인 스타일도 삼항연산자를 이용한 조건부 렌더링이 가능하다.
02 CSS, SASS
CSS 또는 SASS를 이용해 파일을 분리해서 class를 설정해 그 class에 적용할 각종 스타일을 작성하고, 리액트 컴포넌트 파일에 css를 import하는 방식이다.
@import './button.css';
//scss
@import './button.scss';
SASS 사용 시에는 프로젝트 디렉터리에 node-sass 라는 패키지를 설치해야 한다. SASS는 전처리기이기 때문에 그 자체로는 웹에서 동작하지 않으며, node-sass 패키지를 사용하여 Sass를 CSS로 컴파일 후 컴파일된 CSS가 웹에서 동작한다. SASS를 사용할 시 CSS에서 변수, 연산자, 함수, extend, import 등을 사용할 수 있기 때문에 코드의 재사용성 및 가독성이 높아지고, 유지보수가 용이해진다.
//npm
npm install -g node-sass
//yarn
$ yarn add node-sass
className을 통해 조건부 렌더링이 가능하다.
*조건부 렌더링: 특정 조건에 따라 다른 결과물을 렌더링 하는 것으로, props나 state에 css 클래스를 의존해 JavaScript의 조건 처리처럼 동작하는 것
//active 상태면 menu-active 라는 클래스를 추가
render() {
let className = 'menu';
if (this.props.isActive) {
className += ' menu-active';
}
return <span className={className}>Menu</span>
}
03 CSS Modules
공식 문서1: https://create-react-app.dev/docs/adding-a-css-modules-stylesheet/
공식 문서2: https://github.com/css-modules/css-modules
css는 기본적으로 전역(global namespace)이기 때문에 일반적은 css 파일로 작성할 시 class 중복이 생기지 않도록 신경써줘야 한다(=해당 모듈만이 아닌 전체 모듈에 css가 적용되기 때문). CSS-module은 css를 모듈처럼 만들어줘서 css 클래스명이 충돌하는 것을 방지할 수 있고, 컴포넌트 단위로 css를 적용할 수 있다. camelCase 사용을 권장하나 강제는 아니다.
css 모듈은 js 모듈에 import할 때 하나의 객체로 받아들일 수 있도록 맵핑하고, 클래스 명에 hash값이 붙어 고유한 값으로 변경되어(naming convention) 각 모듈 별로 css가 적용되도록 한다.
import styles from './Button.module.css' //모듈
import './another-stylesheet.css' //일반 css
class Button extends Component {
render (){
return <button className={styles.error}>Error Button</button>;
}
}
//style.error 이런 식으로 접근하기 때문에 일반 css에 있는 error 클래스와 충돌이 발생하지 않음
Composition
다른 클래스에 해당하는 코드에서 compose하면 그 코드를 그대로 사용 가능하다. 같은 css 또는 다른 css에서도 가져올 수 있다.
.className {
color: green;
background: red;
}
.otherClassName {
composes: className;
color: yellow;
}
React 에 CSS Module 추가
create-react-app 으로 환경설정했으면 별다른 설정 없이 바로 사용 가능하지만(webpack 에서 사용하는 css-loader 에서 지원), 아닐 경우 추가적인 세팅을 해야 한다.
CRA를 사용한다면, 기존 [name].css를 [name].module.css로 확장자명을 변경해주면 된다. (scss도 동일하다)
import Style from './Component1.module.css';
export const Component1 = () => {
return (
<div className={Style['component-class01']}>
<p>Component1</p>
</div>
);
};
전역적인 클래스명이 필요할 경우, CSS Module에서 :global을 이용하면 된다.
:global .page-wrap {
// ...
}
classNames
동적인 클래스 작성을 위해서는 classNames라는 패키지를 사용한다. classNames의 bind 기능을 이용하면 좀 더 편리하게 조건부 스타일링을 할 수 있다. CSS 클래시 이름을 지정해 줄 때 cx('클래스이름') 과 같은 형식으로 편하게 사용 할 수 있어 여러 개의 클래스를 사용하거나 조건부 스타일링을 할 때 사용한다.
$ npm install classnames
$ yarn add classnames
import Style from './Component1.module.css';
import classNames from 'classnames/bind';
const cx = classNames.bind(Style);
export const Component1 = () => {
return (
<div className={cx('component-class01', { type01: true })}>
<p>component1</p>
</div>
);
};
//기본적으로 component-class01이라는 클래스 명이 있으면서 true/false 조건에 따라 type01이라는 클래스가 부여되게 된다
04 CSS-in-JS : Styled-component
공식문서1: https://styled-components.com/
공식 문서2: https://ko.reactjs.org/docs/faq-styling.html
말 그대로 외부에 css 파일을 따로 분리해 작성하는 것이 아니라 JavaScript 파일에 css를 작성하는 방법이다. 기본적으로 지원되는 기능이 아니라 라이브러리를 설치해야 한다. 가장 대중적인 CSS-in-JS 라이브러리는 styled-component다.
//npm
$ npm install --save styled-components
//yarn
$ yarn add styled-components
위에서 설치한 styled-components 패키지에서 styled 함수를 import해서 리액트 컴포넌트에 원하는 스타일을 적용한다.
import React from 'react';
import styled from 'styled-components';
//h1 태그에 스타일을 작성
const Title = styled.h1`
font-size: 1.5rem;
text-align: center;
color: palevioletred;
`;
//wrapper 스타일 작성
const Wrapper = styled.section`
padding:4em;
background: papayawhip;
`
//출력
function Main(props) {
return(
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
)
}
export default Main;
styled-component는 ES6의 Tagged Template Literals을 사용해서 스타일을 정의한다. styled 함수는 해당 스타일이 적용된 컴포넌트를 반환한다.
Tagged Template Literals
이 개념을 이해하기 위해서는 Template Literal 에 대한 이해가 필요하다. Template Literal은 ES6 에서 새롭게 도입된 기능으로, 백틱(`) 을 사용하여 문자열과 변수를 함께 사용할 수 있어 동적인 문자열 처리에 유용한 기능이다.
//untagged-단순 문자열
`string text`
//대체 가능한 expression 포함된 문자열
`string text ${expression} string text`
//tagged template literal
//파라미터로 expression 으로 구분된 문자열 배열과 expression 이 순서대로 들어간 형태로 호출
func `string text ${expression} string text`;
Tagged Template literal은 템플릿 리터럴의 발전된 형태로써, 함수 형태로 사용할 수 있다. Tagged Template Literals 문법을 사용하면 타입에 상관없이 Function, Number, Array, Object 등을 전달하고 실행할 수 있다. 또한 props를 사용해서 동적으로 변화하는 값을 넣어 가변 스타일링을 적용할 수 있다.
import React from 'react';
import styled from 'styled-components';
const Button =styled.button`
color: ${ props => props.dark ? "white": "dark" };
background: ${ props => props.dark ? "black" : "white" };
border: 1px solid black;
`
function ChangeButton(props){
return (
<div>
<Button>Light</Button>
<Button dark>Dark</Button>
</div>
)
}
export default ChangeButton;
넘겨야 할 prop 값이 많아질 경우, ...props 구문(rest parameter)을 사용해서 children 외 모든 prop을 전달할 수도 있다.
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
기존에 작성한 styled-components의 스타일을 확장할 수도 있다.
const Button=styled.button`
//기존 속성
`;
const RoundedButton = styled(Button)`
//추가할 속성
`;
참고자료
https://react.vlpt.us/styling/02-css-module.html
https://pxd-fed-blog.web.app/css-module/
https://goddaehee.tistory.com/304
https://mygumi.tistory.com/395
https://www.daleseo.com/react-styled-components/
'FRONTEND STUDY > React' 카테고리의 다른 글
JSON-SERVER (0) | 2023.02.20 |
---|---|
[React 스터디] SPA, Routing (0) | 2023.01.09 |
[React 스터디-5] List, Key (0) | 2022.12.18 |
[React Study - 5] Life cycle, useEffect() (0) | 2022.12.11 |
[React 스터디 - 4] State (0) | 2022.12.04 |