본문 바로가기

스터디/React

CSS 라이브러리를 사용하는 이유 (css scope)

반응형

목차

  1. Vanilla CSS 사용 시 발생하는 문제
  2. 스코프가 지정되지 않는 문제 해결하기
  3. 스타일 적용이 안 되고 줄이 그어져 있는 경우

Vanilla CSS 사용 시 발생하는 문제

Vanilla CSS로 코드를 작성할 때 주의해야 할 점이 있는데,   바로 Scope(범위) 문제이다.

다음의 코드를 살펴보면 scope 문제가 어떤 것인지 알 수 있다.   

// Button.css
.big {width: 100px;}
.small {width: 50px;}
.button {
	height: 30px;
    background-color: #525252;
}
// Button.js
import React from 'react'
import './Button.css'
export default function Button({size}) {
    if (size==='big') {
        return <button className='button big'>큰 버튼</button>
    } else {
        return <button className='button small'>작은 버튼</button>
    }
}
// Container.css
.big {width : 200px;}
.small {width : 100px;}
.box {
    height : 50px;
    background-color: #ff8282;
}
// Container.js
import React from 'react'
import './Container.css'
export default function Container({size}) {
    if (size === 'big'){
        return <div className='container big'>큰 박스</div>
    }else {
        return <div className='container small'>작은 박스</div>
    }
}

위에는 Button 컴포넌트의 css와 js 코드, Container 컴포넌트의 css, js코드가 있다. 

이 두 컴포넌트를 App.js에 불러온다.

// App.js
function App() {
  return (
    <div className="App">
      <Button size='big'></Button>
      <Button size='small'></Button>
      <Container size='big'></Container>
      <Container size='small'></Container>
    </div>
  );
}

위의 코드를 작성한 작성자는 각각의 컴포넌트에 있는 클래스 명에 지정한 CSS가 적용될 것이라고 생각한다.

즉, Button의 클래스 명(big/small)이 Button.css에 있는 클래스명으로 각각 적용되고,

Container의 클래스 명(big/small)이 Container.css에 있는 클래스명으로 각각 적용된다고 기대할 것이다.

그러나 실제 결과는 다르다.

먼저 작성한 컴포넌트인 Button의 클래스 명(big/small)에 의해

Container 컴포넌트의 클래스명이 중첩되어 Container.css에 있는 스타일이 적용되지 못한다.

이것이 Vanilla css에서 흔히 발생하는 Scope 문제이다.

 

흔히 착각하는 것이 컴포넌트에 파일을 분리하고 따로 import 해 온다고 해서

css 코드가 분리되고 해당 css가 그 컴포넌트에 스코핑 되는 것은 아니다.

리액트에서 index.css에 vanilla.css를 작성하고 크롬 개발자 도구를 열어보면

"요소" 탭에서 <header></header>태그 안에 index.css가 적용되고 있는 것을 볼 수 있다.

따라서 vanilla css로 코드를 작성하면 글로벌하게 적용된다는 것을 알아야 한다.

 

 

 

스코프가 지정되지 않는 문제 해결하기

그렇다면 이러한 스코핑이 지정되지 않는 문제를 해결하기 위해서는 어떻게 해야 할까?

첫 번째, 인라인 스타일로 작성한다.
 

리액트에서 인라인 스타일 작성하는 방법

| CSS 적용 방법 알다시피 CSS를 적용하는 방법에는 세 가지가 있다. 1. 인라인 스타일 : html태그마다 style속성으로 CSS 코드를 작성하는 방식 내용 2. 내부 스타일 시트 : head태그 안에 style태그를 넣

sol-aftercoding.tistory.com

인라인 스타일로 작성하면 스코핑 문제를 해결할 수 있지만 코드의 가독성이 떨어지고,

유지보수 및 재사용이 어렵다는 등 여러 문제가 존재하기 때문에 해당 방법은 권장하지 않는다.

두 번째, CSS Module을 사용한다.

 

CSS Module은 일종의 CSS 모듈화 방식으로,

CSS를 모듈 단위로 분리하고 로컬 스코프를 유지하도록 도와주는 기술이다.

CSS Module을 사용하면 각각의 CSS 클래스나 선택자는 고유한 이름이 자동으로 부여되어

CSS명이 중첩되거나 덮어씌워질 걱정은 하지 않아도 된다.

 

세 번째, CSS 라이브러리나 프레임워크를 사용한다.

 

CSS 라이브러리 중에는 대표적으로 styled-components가 있고,

CSS 프레임워크 중에는 Tailwind CSS를 말할 수 있다.

 

 

 

스타일 적용이 안 되고 줄이 그어져 있는 경우 

개발을 하다 보면 분명 나는 스타일을 지정했는데 화면에 적용되지 않고

크롬 개발자 도구로 들어가 살펴보면 줄이 그어져 있는 경우가 있을 것이다.  

이 때 고려해봐야 하는 것이 스타일 오버라이딩(overriding) 이다.

 

아래 코드는 내가 vanilla css를 styled-component로 바꾸려고 하다가 발생한 실수이다.

/*index.css*/
.controls label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #6b7280;
 }
// Login.jsx
// 핵심 코드를 제외한 나머지는 모두 생략합니다.

import styled from 'styled-components'

const Label = styled.label`
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1rem;
  text-transform: uppercase;
  color: #f87171;
`;


export default function Login() {

  //...생략...
  
  return (
  
  <div id="login-inputs">
      <div className="controls">
        <p className="paragraph">
          <Label> Email </Label>
          <input
            //...생략...
          />
        </p>
        //...생략...    
    </div>
  );
}

 

나는 index.css에 있는 코드를 그대로 둔 상태로 Login.jsx 파일 안에서 Label 컴포넌트를 새로 만들어서

새로운 컴포넌트를 Login 함수 안에 적용시켰다.

그런데 바뀐 색상(#f87171)이 적용되지 않고 여전히 #6b7280 색상 그대로 였다.

크롬 개발자 도구로 들어가서 살펴보니 Label 컴포넌트에 지정한 스타일이 모두 다음과 같이 줄이 그어져 있었다.

display: block;
margin-bottom: 0.5rem;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.1rem;
text-transform: uppercase;
color: #f87171;

 

한참을 고민하다가 index.css에 있는 스타일 값을 바꿔보고 나서야 덮어씌워졌다는 것을 알았다.

CSS 우선순위를 생각해보면 더 구체적이고 특정한 선택자가 더 높은 우선순위를 가진다.

index.css 에 있는 코드는 클래스명을 지정하고 있기 때문에 우선순위가 더 높다.

따라서 스타일이 덮어씌워진 것이다.

 

'스터디 > React' 카테고리의 다른 글

React Ref 개념과 사용하는 방법  (0) 2024.03.05
JSX란? / JSX 문법 정리  (0) 2023.08.11
리액트에서 인라인 스타일 작성하는 방법  (0) 2023.08.11