O612의 데브런닷 스튜디오

CSS와 CSS Module 비교

부제: 재귀적 inherit의 굴레
수정
featured image thumbnail for post CSS와 CSS Module 비교

Prologue

지난 편에서 CSS의 단점이 Class 이름이 중복되게 네이밍을 지을 위험성이 있고 JavaScript와 연동이 어렵다고 언급을 했습니다.

CSS Module은 개발자가 부여한 class 이름 뒤에 숫자나 알파벳이 자동으로 부여하여 class 이름이 중복되는 것을 방지합니다.


CSS

CSS.

h1 { font-weight: 700; }

Sass.

h1 font-weight: 700

이 코드에서는 클래스 선택자 없이 h1 태그 단독 스타일을 넣었습니다. 이렇게 작성하면 모든 h1에 대해 font-weight: 700이 적용됩니다.

전역(Global)적으로 적용하고 싶다면 이렇게 쓰는 게 맞습니다. 앞에 .container 같은 클래스 선택자를 사용해도 이론상으로는 전역적으로 작동합니다.

CSS.

.container h1 { font-weight: 700; }

Sass.

.container h1 font-weight: 700

어떤 페이지, 어떤 컴포넌트던지 .container 안에 h1이 사용된다면 font-weight: 700이 적용되니까요.

하지만 페이지마다 .container가 있고 h1이 있지만 모두 스타일이 다르다면? 머리에 쥐가나고 없던 두통이 오는 느낌적 느낌이 듭니다.

20211201 headattact

머리가 아파오는군

CSS Module

보통은 페이지 네임이 붙은 클래스 또는 id를 상단에 붙여서 쓰게 될 겁니다. 이것을 방지하기 위해서 나온 게 CSS Module 입니다.

import styles from './index.module.css'; function App() { return ( <> <div className="Container"> <h1>blah</h1> </div> <div className={styles.Container}> <h1>blah</h1> </div> </> ); } export default App;

Sass인 경우에는 .css 대신 .sass로 변경하면 됩니다.

className='Container'는 index.css 또는 index.sass에서 사용된 .Container의 코드를 가져옵니다. 이 방식은 종전 방식대로 전역으로 불러옵니다.

즉, 모든 페이지, 모든 컴포넌트에서 불러옵니다.

뒤에 작성된 className={styles.Container}는 현 컴포넌트에서만 사용됩니다. 개발자 인스펙터에서 해당 부분을 확인해보면 다음처럼 컴파일 된 것을 확인할 수 있습니다.

<div class="Container"><h1>blah</h1></div> <div class="app_Container__2ls0j"><h1>blah</h1></div>

전자는 CSS Module을 사용하지 않은 것(전역 설정)이고, 후자는 CSS Module을 사용한 것입니다. class 이름이 컴포넌트명_클레스명__랜덤값 형태로 붙어서 전역 처리되는 것을 방지하고 있는 것을 확인할 수 있습니다.

주의할 것은, CSS Module로 작성하더라도 태그(Element) 단독으로 작성되면 전역으로 적용된다는 겁니다.

a { font-size: 2rem; }

위 코드는 CSS Module로 작성되었지만 a 태그 앞에 선택자가 없기 때문에 전역으로 적용됩니다.


Epilogue

퍼블리셔, 프론트엔드 개발자들은 늘 전역으로 적용되면 안되는 것을 어떻게 사이드이펙트 없이 적용할 것인가에 대해 해결하려 노력해 왔는데 CSS Module이 고민을 한방에 해결해 줬습니다.

이전 포스팅에서 emotion에 대해 설명하는 글을 썼었는데 emotion에 대해 관심이 있다면 이전 포스팅도 확인하세요!

그럼 이만 이번 편을 마치고 다음 편에서 만나요! 다음 편 관많부! : )

FIN!

Copyright 2022 O612 DEV1L.studio develog w/ Devilish code