WEB개발이야기/웹퍼블리싱

자식 컴포넌트의 CSS(SCSS)를 정의할 수 있는 딥셀렉터(v-deep) 설정하는 방법

어쩌다보니여기까지~ 2021. 10. 20. 14:18
반응형

Vue 프로젝트를 진행하다 보면 vuetifyquasar 등 매우 다양한 프레임워크나 컴포넌트를 사용하게 됩니다.
그러면서 그 컴포넌트를 내 Vue 프로젝트의 자식 컴포넌트로 불러와서 사용하는 경우가 있는데 그 컴포넌트를 어떻게 CSS를 적용해서 내 입맛에 맞추어 스타일을 변경하고 싶으나 그게 생각처럼 되지 않는 경우가 있습니다. 그걸 되게 하는 방법을 설명해 보려고 합니다.

자식 컴포넌트의 CSS에 쉽게 접근이 되지 않는 이유

이렇게 되는 이유는 웹 컴포넌트의 중요한 측면인 스타일 캡슐화때문이라고 합니다.
다시말해서 현재 컴포넌트에 적용된 css(scss)가 현재의 컴포넌트에만 적용되고 다른 컴포넌트에는 간섭이 되지 않도록 하기 위함이라고 보시면 됩니다.
그래서 Vue컴포넌트에서 <style>를 정의할 떄 scoped를 작성하게 되면 해당 컴포넌트에만 css가 먹게됩니다. 만약 scoped를 빼버리면 해당 컴포넌트에 작성을 했다고 하더라도 전체(Global)에 영향을 미치게 됩니다.

<style scoped> .example {   color: red; } </style>
<style lang="scss" scoped> .example {   color: red; } </style>

그런데 scoped를 지정하게 되면 자식 컴포넌트에도 해당 스타일이 적용되지 않는다는 점입니다. 내가 만든 자식 컴포넌트라면 자식 컴포넌트로 가서 내가 바로 적용하면 되지만 남이 만들어 놓은 컴포넌트라면 이걸 수정하기는 쉽지 않습니다.

scoped를 유지하며 자식 컴포넌트에 css를 적용하기

컴포넌트를 만들때 스타일에 scoped를 적용하는 것은 중요하기 때문에 이걸 해제하지 않고 자식 컴포넌트의 css를 적용하려면 딥셀럭터(v-deep)를 사용해야 합니다.

Vue Loader 참조

딥셀렉터를 적용하는 방법은 3가지가 있습니다.

<style scoped> .a >>> .b { /* ... */ } </style>
<style scoped> .a /deep/ .b { /* ... */ } </style>
// 이 방법을 추천함 <style scoped> .a::v-deep .b { /* ... */ } </style>

이렇게 적용하면 모두 동일하게 아래와 같이 컴파일 되며 자식 컴포넌트까지 접근이 가능하게 됩니다.

.a[data-v-f3f3eg9] .b { /* ... */ }

딥셀렉터를 적용하는 3가지 방법 중 추천하는 방법은 마지막에 있는 .a::v-deep .b { /* ... */ }방법입니다.
나머지 2가지 방법은 css에서 사용은 문제가 없으나 scss, sass, less같은 전처리기에서는 잘 인식이 되지 않는 경우가 있습니다.