Стили и инкапсуляция
У каждого компонента свои стили, и по умолчанию они действуют только на его шаблон. Это называется инкапсуляцией стилей: класс .done в списке дел не испортит кнопку с таким же классом в другом компоненте. Общие правила для всего сайта пишут в отдельном файле.
Стили компонента
Файл стилей лежит рядом с компонентом и подключён через styleUrl:
/* src/app/todo-item/todo-item.css */
.done {
color: gray;
text-decoration: line-through;
}<!-- src/app/todo-item/todo-item.html -->
<span [class.done]="todo().done">{{ todo().title }}</span>Выполненная задача станет серой и зачёркнутой. Элементы с классом done в других компонентах это правило не затронет.
Как это устроено
В режиме по умолчанию Angular добавляет элементам шаблона атрибут вида _ngcontent-abc-c12, а к селекторам в CSS — такое же условие. Откройте инструменты разработчика — у тега span будет этот атрибут, а правило выглядит как .done[_ngcontent-abc-c12].
Режим encapsulation | Поведение |
|---|---|
ViewEncapsulation.Emulated | По умолчанию: стили только для своего шаблона |
ViewEncapsulation.None | Стили становятся глобальными |
ViewEncapsulation.ShadowDom | Настоящий Shadow DOM браузера |
Режим задают в декораторе: encapsulation: ViewEncapsulation.None (ViewEncapsulation импортируется из @angular/core). Менять его приходится редко.
Глобальные стили
Шрифты, цвета, сброс отступов пишут в src/styles.css — этот файл подключён ко всему приложению:
/* src/styles.css */
body {
margin: 0;
font-family: system-ui, sans-serif;
}
a {
color: #1d4ed8;
}Эти правила действуют на все компоненты.
Селектор :host
:host — это сам тег компонента, например app-todo-item. По умолчанию такой тег строчный, и ему часто задают блочное отображение:
/* src/app/todo-item/todo-item.css */
:host {
display: block;
padding: 8px 0;
border-bottom: 1px solid #eee;
}Каждая задача станет отдельной строкой с линией снизу.
Классы и стили из данных
Кроме [class.имя] и [style.свойство] есть привязки сразу к нескольким значениям:
<!-- src/app/todo-item/todo-item.html -->
<span [class]="{ done: todo().done, urgent: todo().title.includes('!') }">
{{ todo().title }}
</span>
<span [style.font-size.px]="16">Размер в пикселях</span>Объект в [class] включает каждый класс, значение которого истинно. Суффикс .px в привязке стиля добавляет единицу измерения.
Частая ошибка
Пытаться из стилей родителя оформить элементы внутри дочернего компонента: правило app-todo-item span в todo-list.css не сработает — span принадлежит другому шаблону. Оформляйте элемент в стилях его компонента, а снаружи меняйте только сам тег компонента или передавайте вход. Старый обходной путь ::ng-deep устарел.