Frontend is 실전

[CSS] styled-components의 전역 스타일링

킹경후 2024. 4. 2. 18:50

프로젝트를 진행하면서, styled-components에 "전역 스타일링"이라는 기능이 있다는 것을 알게 되었다.

사실 개념만 모르고 있었던 것일 뿐, 그동안 알게 모르게(?) 전역 스타일링을 사용하고 있었는데

이제서야 정식으로 통성명을 하게 된 기념으로 글을 적어보도록 하자.


1. 전역 스타일링이란?

군인이 의무병역을 마치고 전역할 때 멋지게 꾸미고 나오는 것을 말한다
말 그대로 전역(Global) 스타일을 지정하는 것을 말한다.

기존의 styled-components(기니까 sc로 줄여 말하겠다)는 한 페이지에서 작성한 뒤, 해당 페이지에서만 사용했었다.

App.js에 정의한 컴포넌트는 상위 컴포넌트에서든, 하위 컴포넌트에서든 사용할 수 없고, 오직 App.js 안에서만 사용 가능했다는 말이었다.

하지만 전역 스타일링을 사용할 경우, 전역 컴포넌트로 생성된 컴포넌트는 정해진 범위 안에서는 자유롭게 사용 할 수 있게 된다.

이 범위는 App 전체가 될 수도 있고, App 내의 특정 컴포넌트가 될 수도 있다.

한편, 전역 컴포넌트는 무조건 컴포넌트여야 하는 것도 아니다. div, span 등의 HTML 태그는 물론, display, color, font-size등 스타일을 지정 하는 것도 가능하다.


2. 전역 스타일링 사용하기

전역 스타일링이 뭔지 알았으니, 실제로 사용하면서 한번 익혀보도록 하자.

sc는 당연히 설치 되어 있다고 가정하고, 전역 컴포넌트들을 지정할 폴더와 파일을 만들어준다.


import { createGlobalStyle } from "styled-components";

export const GlobalStyles = createGlobalStyle`
  *{
    margin: 0;
    padding: 0;
  }
`;


sc로부터 createGlobalStyle을 불러와주고, createGlobalStyle 컴포넌트를 하나 만들어 export해준다.

이 createGlobalStyle 안에 원하는 스타일링을 지정해 주면 된다.

위 코드는 * (모든 컴포넌트)에 margin, padding을 0으로 줬는데, 이는 전역 스타일링이 적용되는 범위 내 모든 컴포넌트는 margin과 padding이 0이 된다는 말이다.

만약 범위 내 모든 div에 테두리를 주고 싶다면


export const GlobalStyles = createGlobalStyle`
  *{
    margin: 0;
    padding: 0;
  }
  div{
    border: 1px solid black;
  }
`;


이런 식으로 스타일링을 추가해주면 된다.

전역 스타일링을 설정했으니, 이제 스타일이 적용될 범위를 설정해 주면 된다.


import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home/Home";
import Result from "./pages/Result/Result";
import { GlobalStyles } from "./styles/GlobalStyles";
function App() {
  return (
    <BrowserRouter>
      <GlobalStyles />
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/result/:apartmentId" element={<Result />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;


이렇게 전역 스타일을 불러와주고, 적용을 원하는 범위의 상위에 설정해주면 된다.

위 코드에서는 GlobalStyles가 브라우저 라우터 아래에 있으므로, 브라우저 라우터의 하위 컴포넌트부터는 모두 GlobalStyles가 적용된다.

App.js 전체에 적용하고 싶다면 index.js에 적용해주는 것도 방법이다.


 

3. 전역 스타일 만들기

사실, 이 부분은 뭐라 설명할 것도 없이 export와 import만 할 줄 알면 누구나 쉽게 할 수 있다.

sc로 컴포넌트를 하나 만들고, export해준 뒤, 사용하고 싶은 페이지에서 import 해와 사용하면 끝.

 

다만, 해당 컴포넌트를 특정 페이지에 만들어놓고 export 하면 나중에 수정하거나 다시 불러와야 할 때 위치가 헷갈릴 수 있으므로, GlobalStyles을 지정한 파일 내에 함께 만들어 두는 것을 추천한다(경험담)

 

//GlobalStyles.js
export const BlackContainer = styled.div`
  width: 100%;
  height: 100vh;
  background-color: black;
`

//App.js
import { BlackContainer } from "./styles/GlobalStyles";

function App() {
  return (
    <BlackContainer />
  );
}

export default App;

 

GlobalStyles.js에서 전역 컴포넌트를 생성한 뒤, App.js에서 import해와 쓰고 있다.

 

 

이번엔 컴포넌트가 아닌 전역 스타일을 생성하는 방법을 알아보자.

 

전역 스타일은 정렬이나 flex-direction 설정, 혹은 border, color 등의 속성을 여러 컴포넌트에 똑같이 적용해 줘야 할 때 매우 유용하다.

 

만약  flex-direction이 row이고 가로, 세로 모두 가운데 정렬이 되어 있는 컴포넌트들을 계속 만들어야 한다고 해보자.

 

display: flex;
flex-direction: row;
justify-content: center;
align-items: center;

 

이 코드들을 모든 컴포넌트마다 일일히 써주는 것은 매우 귀찮은 일이다.

하지만 전역 스타일링을 사용한다면 이러한 귀찮음을 한번에 날려버릴 수 있다는 사실!

 

//GlobalStyles.js
import { css, keyframes } from "styled-components";
export const rowCenter = css`
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
`
export const fadeInAnimation = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;

//App.js
import { rowCenter } from "./styles/GlobalStyles";

const NewDiv1 = styled.div`
  ${rowCenter}
`
const NewDiv2 = styled.div`
  ${rowCenter}
`
const NewDiv3 = styled.div`
  ${rowCenter}
  animation: ${fadeInAnimation} 0.5s ease-in-out forwards;
`

function App() {
  return (
    <NewDiv1 />
    <NewDiv2 />
    <NewDiv3 />
  );
}

export default App;

 

App.js의 세 NewDiv 모두 전역 스타일인 rowCenter이 적용되어 있다.

전역 스타일 역시 export-import 방식으로 사용하지만, 사용할 때 ${   }(표현식) 안에 넣어서 사용해 주어야 한다는 차이점이 있다.

그리고 컴포넌트와 다르게, sc에서 'css'를 import해와야 하며, 작성할 때도 styled.tag가 아니라 css로 작성해 주어야 한다.

 

은근슬쩍 끼워놨지만, 애니메이션을 만들 때 필요한 keyframes 역시 전역 스타일과 똑같이 생성 및 사용 할 수 있다.

 


 

프로젝트를 진행할 떄는 잘 몰랐지만, 여유가 생기니 프로젝트 중 생긴 궁금증들을 해결 할 수 있었다.

그동안 나름 sc를 잘 쓴다고 생각했는데 흠,.,.,.,

아직도 우물안 개구리였던 것 같다.

 

아무튼 이번 프로젝트를 통해 정말 많은 것을 배웠으니, 이들 역시 차차 적어 나가도록 하겠다.