개발 기술/개발 이야기

CSS 모듈이란? (feat. vueJS)

by GicoMomg 2022. 7. 30.

이번 시간에는 CSS클래스 중복을 막아주는 CSS 모듈을 Vue3에서 사용해보았다!

 

1. CSS module이란?

  • CSS 모듈은 CSS를 모듈화하여 사용하는 방식을 말한다.
  • 클래스명은 모듈 컴파일러에 의해 고유한 클래스명을 가지게 된다.
  • 클래스명이 고유해지므로 CSS의 범위를 지역적으로 한정시킬 수 있는 장점이 있다.
  • CSS 클래스명을 생성할 때는 파일 경로, 파일 이름, 클래스 이름, 해쉬값 등이 사용된다.




2. Vue와 CSS module

CSS module을 사용하면 CSS의 적용범위를 지역적으로 한정시킬 수 있다고 했다. 하지만 Vue에서는 CSS에서 scoped를 사용하면 범위를 제한할 수 있는데 이 둘의 차이는 무엇일까?

1) scoped vs CSS module

  • Vue에서는 CSS에 scoped를 적용하며 CSS 적용범위를 지역적으로 제한할 수 있다.
<template>
  <div class="wrapper">
    <p>parent</p>
    <HelloWorld/>
  </div>
</template>

<!-- scoped: 스타일 적용 범위를 지역적으로 -->
<style scoped> 
.wrapper {
  outline: 2px solid blue;
}
</style>

 

  • 하지만, scoped에는 단점이 있는데 만약 하위 컴포넌트에 있는 클래스가 상위 컴포넌트에도 있는 경우, 상위 컴포넌트의 스타일이 하위 컴포넌트에 적용된다는 점이다!
  • 아래 예시처럼 Parent.vue.wrapper가 있다면, Child.vue에는 Parent.vue.wrapper가 적용된다.
| App.vue
|  Parent.vue => .wrapper
|   Child.vue => .wrapper(parent의 .wrapper도 적용됨)

 

 

  • 이와 같은 현상 때문에 vue에서 CSS를 작성할 때 해당 컴포넌트의 root 클래스명을 사용해 계층을 정해준다.

 

 

하지만 만약 CSS module을 사용하면 클래스명이 고유해져 예상치 못한 스타일이 적용되는 현상을 막을 수 있다!



2) CSS module 사용법

🤔 그렇다면 Vue3에서는 CSS module을 어떻게 사용할 수 있을까? 한 번 알아보자!

(2) 자체 선언해서 사용하기

  • Vue에선 CSS에 module을 적용하면, 모듈화하고 싶은 스타일을 선언할 수 있다.
<style lang="scss" module>
    .myClass {
      color: blue;
    }
</style>

 

  • 그러면 template에서는 아래와 같이 모듈화된 클래스를 사용할 수 있다!
<template>
  <h2>I'm parent component</h2>

  <div :class="$style.myClass">hello world</div>
  <p>using useCssModule: {{ $style.myClass }}</p>
  <P>using getCurrentInstance:{{ $style.myClass }}</P>

  <hr />
  <ChildComponent />
</template>

 

  • 적용된 클래스명을 보면, .myClass가 아닌 고유한 클래스명이 적용된 걸 확인할 수 있다. (demo 보기)

 

(2) import해서 사용하기

  • 두 번째 방법은 외부 Style 코드를 import하여 모듈화하는 방법이다.
  • 먼저, assets/utils.scss에 스타일을 지정한다.
/* assets/utils.scss */

.button {
  width: 200px;
  height: 20px;
  border: 2px solid gray;
}

 

  • 그 다음 module이 적용된 style@import를 사용하여 해당 CSS를 가져온다.
<style lang="scss" module>
@import '../assets/utils.scss';

.myClass {
  color: red;
}
</style>

 

  • template에서 @import한 스타일과, .myClass를 둘 다 접근할 수 있다. (demo 보기)
<template>
  <h2>I'm child component</h2>

  <div :class="[$style.myClass, $style.button]">hello world</div>
  <p>using imported scss : {{ $style.button }}</p>
  <p>using imported scss : {{ $style.myClass }}</p>
</template>




📌 오늘은 CSS 적용 범위를 지역적으로 제한하는 CSS Module에 대해 알아보았다. Vue에서는 기존에 scoped를 제공했지만 동일한 클래스명이 있는 경우 부모의 스타일이 자식에게 적용되는 문제가 있었다. 이 경우에는 CSS를 선언할 때 계층 방식을 써도 있지만 CSS Module방식을 시도해보는 건 어떨까 🙂

반응형

댓글