리액트는 웹 애플리케이션 개발에 사용하는 라이브러리이다. 그러므로 스타일링에는 물론 웹 개발과 동일한 CSS
를 사용할 수 있다.
npx create-react-app my-app-style --template=typescript
컴포넌트 사용을 보기 위해서는 css는 넘어가도 됨
연습을 위해 public에 temp.css
파일을 추가하고 수정한다.
.App-header{
background-color: red !important;
}
제대로 적용되는지 확인하기 위해 App-header
클래스의 배경에 강제적으로 빨간색을 표시하도록 했다
그럼 이제 public의 index.html
를 수정하자
<link rel="stylesheet" href="%PUBLIC_URL%/temp.css"/>
<title>React App</title>
보통의 웹서비스처럼 태그를 사용해서 temp.css
파일을 불러왔다
create-react-app으로 만든 프로젝트의 public폴더에는 %PUBLIC_URL%
을 사용해서 지정해야한다. css가 적용되었는지 확인하자
npm start
으악
리액트 프로젝트가 문제 없이 실행되면 빨간색 배경의 페이지가 열리는 것을 확인 할 수 있다. 이렇게 보통의 웹 페이지처럼 css를 추가해서 웹 서비스의 스타일링을 할 수 있다.
하지만 리액트는 보통의 웹서비스 개발과는 다르게 💡컴포넌트 중심으로 개발한다. 그러므로 이렇게 모든 css를 한 곳에서 관리하게 되면 어떤 컴포넌트에서 어떤 스타일으 활용하는지 쉽게 알 수 없기 때문에
css파일도 리액트 컴포넌트 파일에서 import하는 방식으로 💡스타일도 컴포넌트 중심으로 설계할 수 있도록 한다.
기본적으로 생성된 프로젝트에서 역시 import를 한 것을 볼 수 있다.
리액트는 위와같이 JSX파일에서 직접 CSS를 import하는 것으로 해당 리액트 컴포넌트가 어떤 스타일을 사용하는지 알 수 있도록 하고 있다. 해당 스타일이 적용되고 있는지 확인하기 위해 ./src/App.css
파일을 열어 배경 색을 강제적으로 되돌리도록 수정해보자
.App-header {
background-color: #282c34 !important;
시뻘건 색이었던 배경이 다시 원래 색으로 되돌아 왔다.
이렇게 리액트에서는 link태그를 통해 css를 사용할 수 도 있고 컴포넌트에서 css를 import해 사용할 수도 있다.
보통 리액트는 컴포넌트를 기반으로 개발하게 되고 컴포넌트 별로 css를 갖는 형식으로 스타일을 관리하게 된다.
모든 css를 한곳에서 관리하지 않다 보면 vss의 클래스명이 중복되어 잘못된 스타일이 적용될 수 있다.
반면에 한 곳에서 모든 스타일을 관리하다보면 어떤 스타일이 컴포넌트에 적용되고 있는지 한눈에 알 수 없다.
이런 문제를 해결하고자 styled-components 라이브러리가 탄생했고 리액트에서 이걸 사용해 스타일을 적용할 수 있다
my-app-style>cd my-app-style
npm install --save-dev @types/styled-components jest-styled-components
App.tsx
파일을 열어 import한다import './App.css';
import Styled from 'styled-components';
...
import Styled from 'styled-components';
const Container = Styled.div`
`;
...
💡 styled-components를 사용하여 리액트 컴포넌트를 생성하기 위해서는 Styled.[HTML 태그]형식과 자바스크립트의 탬플릿 리터럴(Template literals,`)를 사용한다. 이 템플릿 리터럴 기호 안에 다음과 같이 스타일을 작성함으로써 컴포넌트의 스타일링을 하게 된다.
...
const Container = Styled.div`
text-align: center;
`;
...
function App() {
return (
//<div className="App">
<Container>
...
</Container>
//</div>
);
}
기존에 있던
브라우저는 아무 변화 없이 잘 돌아간다.
...
const Container = Styled.div`
text-align: center;
`;
const Header = Styled.header`
background-color:#282c34 !important;
min-height:100vh;
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
font-size:calc(10px+2vmin);
color:white;
`;
...
앞에서 만든 Container 컴포넌트와 마찬가지로 Styled[HTML태그]와 탬플릿 리터럴을 사용해 Header 컴포넌트를 정의했다
App.tsx
파일을 수정한다....
function App() {
return (
//<div className="App">
<Container>
{/*<header className="App-header">*/}
<Header>
...
</Header>
{/*</header>*/}
</Container>
//</div>
);
}
역시 비교하기 쉽게 하려고
태그를 삭제하지 않고 주석 처리 했다. 그리고 styled-components로 만든 Header 컴포넌트를 태그 대신 사용했다App.tsx
...
const AppLogo = Styled.img`
height: 40vmin;
pointer-events: none;
`;
...
실제 사용하는 부분도 수정해 준다.
...
{/*<img src={logo} className="App-logo" alt="logo" />*/}
<AppLogo src={logo} alt="logo" />
...
로고는 나오지만 애니메이션은 적용하지 않았기 때문에 회전하지는 않는다.
...
const AppLogo = Styled.img`
height: 40vmin;
pointer-events: none;
@media (prefers-reduced-motion: no-preference){
animation: App-logo-spin infinite 20s linear;
}
@keyframes App-logo-spin{
from{
transform:rotate(0deg);
}
to{
transform:rotate(360deg);
}
`;
...
이것 역시 App.css
파일을 복붙한건데 차이가 있다면 css는 애니메이션을 사용할 클래스명이 다르다
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
반면 styled-components에서는 해당 컴포넌트가 직접 애니메이션을 수행하므로 클래스명을 특별히 지정하지 않아도 된다.
...
const AppLogo = Styled.img`
...
@media (prefers-reduced-motion: no-preference){
animation: App-logo-spin infinite 20s linear;
}
...
`;
이렇게 수정한 후 브라우저를 확인해 보면 이전과 같이 로고가 잘 회전하고 있는걸 볼 수 있다.
이렇게 애니메이션이 한 곳에서만 사용되는 경우, 하나의 컴포넌트에 전부 선언하여도 된다.
하지만 여러곳에서 같은 애니메이션을 사용한다면 styled-components의 keyframes을 사용해 분리할 수 있다. App.tsx
import Styled, {keyframes} from 'styled-components';
그리고 keyframes를 사용해 로고 이미지에서 사용할 회전 애니메이션을 선언한다.
const spin = keyframes`
from{
transform:rotate(0deg);
}
to{
transform:rotate(360deg);
}
`;
실제 애니메이션을 사용하는 부분에 keyframes를 적용한다.
const AppLogo = Styled.img`
height: 40vmin;
pointer-events: none;
@media (prefers-reduced-motion: no-preference){
animation: ${spin} infinite 20s linear;
}
`;
styled-components는 자바스크립트의 탬플릿 리터럴을 사용하기 때문에 위와 같이 문자열 중간에 자바스크립트 변수를 사용할 수 있다. 이처럼 자주 반복되어 사용되는 애니메이션은 keyframes를 사용해 미리 정의하고 필요한 부분에서 불러와 사용하면 된다.
태그에는 어떤 스타일도 적용되어 있지 않으니 패스하고 `.App-link`클래스를 변경해보자
App.tsx
...
const AppLink = Styled.a`
color: #61dafb;
`;
...
<AppLink
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</AppLink>
스타일에 관예하는 모든 css 내용을 수정했다 이제 import를 해제해도 그대로 메인 페이지가 잘 보인다.
그럼 이제 이 코드가 제대로 동작하는지 확인해보자. 이전에 사용했던 코드들을 사용할 것이다.
--업데이트 됨