Vue 프로젝트를 진행하다 보면 vuetify나 quasar 등 매우 다양한 프레임워크나 컴포넌트를 사용하게 됩니다.
그러면서 그 컴포넌트를 내 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)를 사용해야 합니다.
딥셀렉터를 적용하는 방법은 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같은 전처리기에서는 잘 인식이 되지 않는 경우가 있습니다.