이번 포스트에서는 vue component의 <style scoped>의 동작에 대해서 살펴보자.
<style> vs <style scoped>
SFC와 style
SFC는 하나의 파일에 <template>, <style>, <script>가 들어간다. 문제는 최종적인 application은 SFC로 동작하지 않고 하나의 html 형태로 동작한다는 점이다.
이 상황에서 문제가 되는 것 중 하나가 <style>이다. CSS는 선택자 기반으로 동작하는데 StopWatch 컴포넌트에서 content라는 클래스에 적용된 CSS가 있을 때 우연히 GuguQuiz 컴포넌트에도 content 클래스가 있다면 두 개의 style은 충돌할 수밖에 없을 것이다.
<style scoped>
이 문제를 해결하기 위해서 Vue는 style 태그에 scoped 속성을 사용한다. scoped의 목적은 컴포넌트에 선언된 css를 그 컴포넌트에만 영향을 주게 하겠다는 것이다. scoped를 사용하면 생성되는 DOM 요소에 data-v-XXXX 형태의 특별한 attribute를 추가해준다.
scoped를 사용하지 않았을 때 DOM과 적용되는 CSS
scoped를 사용했을 때 DOM과 적용되는 CSS
하나의 component에는 여러 개의 <style>을 적용할 수 있다. 따라서 전역으로 모든 component에 적용할 필요가 있는 css는 <style>에 정의하고 해당 컴포넌트에만 한정하기 위해서는 <style scoped>로 작성해주면 된다.
부모 컴포넌트의 css
<style scoped>를 이용한 CSS 고립 작전은 상하 관계가 없는 경우에만 유효하다. 만약 상하 관계가 성립된다면 조상의 css는 자식에게 전달된다. 왜냐하면 조상의 attribute를 자식이 그대로 가지기 때문이다.
위와 같이 일부러 상위인 App에 scoped를 적용하고 오히려 하위인 StopWatch(자식1)에 scoped를 적용하지 않고 컴포넌트를 구성되었을 때 App의 DOM 은 아래와 같다. GuguQuiz는 자식 2이다.
따라서 자식들은 모두 부모에 적용된 CSS의 영향을 받게 된다.
CSS우선순위를 보면 scoped가 적용된 부모의 <style>이 더 나중에 적용되어 우선순위가 높은 것을 알 수 있다.