# Возможности стилей SFC
# <style scoped>
Если использовать секцию <style>
с атрибутом scoped
, то CSS в ней будет применяться только к элементам текущего компонента. Это похоже на инкапсуляцию стилей в Shadow DOM. Есть некоторые оговорки, но зато не требуется никаких полифилов. Это достигается путём использования PostCSS для преобразования следующего:
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">привет</div>
</template>
2
3
4
5
6
7
8
9
В следующее:
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>привет</div>
</template>
2
3
4
5
6
7
8
9
# Корневые элементы дочернего компонента
При использовании scoped
, стили родительского компонента не будут проникать в дочерние компоненты. Однако, корневой элемент дочернего компонента будет подвержен влиянию как родительского scoped CSS, так и дочернего scoped CSS. Это сделано специально, чтобы родитель мог стилизовать корневой элемент дочернего компонента в целях вёрстки.
# Глубокие селекторы
Если требуется селектор в scoped
стилях, который должен быть «глубоким», т.е. влиял на дочерние компоненты, то можно воспользоваться псевдо-классом :deep()
:
<style scoped>
.a :deep(.b) {
/* ... */
}
</style>
2
3
4
5
Указанное выше будет скомпилировано в:
.a[data-v-f3f3eg9] .b {
/* ... */
}
2
3
Совет
Scoped стили не влияют на содержимое DOM, созданное с помощью v-html
, но его всё равно можно стилизовать с помощью глубоких селекторов.
# Селекторы слотов
По умолчанию scoped стили не влияют на содержимое, отображаемое <slot/>
, поскольку считается, что оно принадлежит родительскому компоненту, которые его передаёт. Чтобы явно указать на содержимое слота, можно использовать псевдо-класс :slotted
:
<style scoped>
:slotted(div) {
color: red;
}
</style>
2
3
4
5
# Глобальные селекторы
Если требуется, чтобы одно правило применялось глобально, то можно использовать псевдо-класс :global
, а не создавать отдельную секцию <style>
(см. ниже):
<style scoped>
:global(.red) {
color: red;
}
</style>
2
3
4
5
# Сочетание локальных и глобальных стилей
В одном компоненте можно вместе использовать как scoped, так и обычные секции style:
<style>
/* глобальные стили */
</style>
<style scoped>
/* локальные стили */
</style>
2
3
4
5
6
7
# Советы по использованию scoped-стилей
Scoped стили не устраняют необходимость в классах. Ввиду того, как браузеры отрисовывают различные CSS-селекторы,
p { color: red }
будет работать гораздо медленнее при использовании scoped (т.е. в сочетании с селектором атрибутов). Но если использовать классы или идентификаторы, например.example { color: red }
, в таком случае практически исключаете этот провал в производительности.Будьте осторожны с селекторами потомков в рекурсивных компонентах! Для правила CSS с селектором
.a .b
, если элемент, соответствующий.a
, содержит рекурсивный дочерний компонент, то все.b
в этом дочернем компоненте будут соответствовать правилу.
# <style module>
Секция <style module>
компилируется как CSS модуль (opens new window) и объявляет результирующие CSS-классы компоненту объектом под ключом $style
:
<template>
<p :class="$style.red">
Это должно быть красным
</p>
</template>
<style module>
.red {
color: red;
}
</style>
2
3
4
5
6
7
8
9
10
11
Полученные классы хэшируются во избежание коллизий, что позволяет добиться того же эффекта, что и при выборе scoped CSS только для текущего компонента.
Обращайтесь к спецификации CSS-модулей (opens new window) для получения более подробной информации, как например о глобальных исключениях (opens new window) и композиции (opens new window).
# Внедрение пользовательского имени
Можно настроить ключ свойства объекта с внедряемыми классами, указав значение атрибуту module
:
<template>
<p :class="classes.red">красный</p>
</template>
<style module="classes">
.red {
color: red;
}
</style>
2
3
4
5
6
7
8
9
# Использование с Composition API
Внедряемые классы доступны в setup()
и <script setup>
через API useCssModule
. Для секций <style module>
с пользовательским внедряемым именем, useCssModule
принимает в качестве первого аргумента соответствующее значение атрибута module
:
// по умолчанию, возвращает классы для <style module>
useCssModule()
// при указании имени, возвращает классы для <style module="classes">
useCssModule('classes')
2
3
4
5
# Динамический CSS с учётом состояния
Однофайловые компоненты в секциях <style>
поддерживают привязку значений CSS к динамическому состоянию компонента через CSS-функцию v-bind
:
<template>
<div class="text">привет</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style>
.text {
color: v-bind(color);
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Синтаксис работает с <script setup>
и поддерживает выражения JavaScript (должны быть обёрнуты в кавычки):
<script setup>
const theme = {
color: 'red'
}
</script>
<template>
<p>привет</p>
</template>
<style scoped>
p {
color: v-bind('theme.color');
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Фактическое значение будет скомпилировано в хэшированное пользовательское CSS-свойство, поэтому CSS останется статичным. Пользовательское свойство будет применено к корневому элементу компонента с помощью инлайн-стилей и будет реактивно обновляться при изменении исходного значения.