이번 시간에는 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방식을 시도해보는 건 어떨까 🙂
반응형
'개발 기술 > 개발 이야기' 카테고리의 다른 글
[CSS] 스타일 우선순위를 정하는, Cascade Layer(@layer) (0) | 2022.09.11 |
---|---|
[JS] 애니메이션을 만드는 2가지 방법(setInterval, requestAnimationFrame) (0) | 2022.08.06 |
Stylelint 설정하는 법(feat. node, vue) (0) | 2022.07.10 |
[JS] DOM을 감시하는, MutationObserver (0) | 2022.04.17 |
eslint 적용시 이슈(rules 무시, 우선순위) (0) | 2022.04.12 |
댓글