Применение стилей от родителя

Предположим, у меня есть компонент с этим шаблоном:

<div class="frame">
  <span class="user-defined-text">{{text}}</span>
</div>
<style>
  span { font-size: 3em; }
  .frame { ... }
</style>

Как я могу объединить стили, примененные к компоненту, например.

<custom-component [text]="'Some text'">
<style>custom-component { font-weight: bold; }</style>

чтобы окончательный вывод «Некоторый текст» был выделен полужирным шрифтом и размером 3em?

Еще лучше, есть ли способ получить вычисляемые стили для элемента хоста, чтобы, например, я мог применить background-color хоста к border-color некоторого элемента в моем шаблоне?


person Soumya    schedule 29.01.2016    source источник
comment
Вам не кажется, что было бы неплохо поместить таблицу стилей на глобальный уровень, чтобы вы могли использовать свойство styleUrl. или вы хотите добиться этого только таким образом?   -  person micronyks    schedule 29.01.2016
comment
Идея состоит в том, чтобы в разных местах компонент можно было повторно использовать с разными стилями. Например. кнопка, выделенная жирным шрифтом в некоторых местах или увеличенный текст в некоторых местах. Angular2, кажется, останавливает все стили в компоненте, поэтому они не распространяются дальше.   -  person Soumya    schedule 29.01.2016
comment
Селектор :children или аналогичный, который позволяет компоненту получить доступ к своим дочерним элементам, был бы довольно удобной функцией. Это также должно быть возможно с инкапсуляцией эмулированного представления, но я не уверен, что они хотят сделать что-то, что сильно отличается от родного теневого дома, поскольку использование родного — это будущая цель.   -  person Erik Honn    schedule 29.01.2016


Ответы (4)


  • установите encapsulation: ViewEncapsulation.None, чтобы разрешить применение стилей извне.
import {Component, ViewEncapsulation} from '@angular/core';

@Component({
  selector: 'custom-component',
  encapsulation: ViewEncapsulation.None
})
export class Custom {
  • используйте styleUrl, чтобы добавить файл CSS в сочетании с селектором хоста
:host(.someClass) {
      background-color: blue;
}

<custom-component class="someClass"></custom-component>

применять стили в зависимости от класса, добавленного к элементу.

person Günter Zöchbauer    schedule 29.01.2016
comment
Предположим, я использую первую стратегию: я могу избежать конфликтов имен, используя префикс для имен классов. Однако, если я также не отключу инкапсуляцию для родительского компонента, все его стили по-прежнему ограничены только его элементами и не будут распространяться дальше. (т. е. все они имеют квалификатор [ng...] при использовании эмулированной инкапсуляции) - person Soumya; 29.01.2016
comment
Emulated и Native предназначены для инкапсуляции стилей. Вы должны отключить его везде, чтобы иметь возможность применять глобальные стили. В любом случае я бы предложил вторую стратегию. Таким образом, вы можете иметь как инкапсуляцию, так и глобальные стили. Вы можете добавить несколько styleUrls к каждому компоненту. Добавьте глобальный везде и локальный, где это необходимо. Если вы сначала добавите локальный, вы сможете переопределить локальные стили глобальными, чтобы настроить стиль по умолчанию (еще не пробовал, если это работает, я бы посчитал это ошибкой, если это не так). - person Günter Zöchbauer; 29.01.2016
comment
Что касается второй стратегии, разве дочернему компоненту не нужно знать всех возможных родителей, чтобы настроить определенные экземпляры? - person Soumya; 29.01.2016
comment
Не уверен, что вы имеете в виду. Прямой родитель должен добавить класс к компоненту (где <custom-component> добавляется в его шаблон. <custom-component> затем применяет стиль с соответствием .someClass. :host {} означает себя, а :host(.someClass) означает себя с классом someClass - person Günter Zöchbauer; 29.01.2016
comment
Я имею в виду, что если я хочу, чтобы пользовательский компонент имел color: red, то родителю нужно было бы применить что-то вроде class="color-red", а дочернему — :host(.color-red) span { color: red; }. Это означает, что мне нужно знать все такие возможные классы... или я что-то упускаю? - person Soumya; 29.01.2016
comment
Это правильно. Я не понимаю, как это связано с необходимостью знать всех возможных родителей. Я бы не стал использовать class="color-red". Это должно быть больше похоже на class="warning", и тогда стиль будет выглядеть как :host(.warning) {color: red; background-color: yellow; border: 3px solid red; }. - person Günter Zöchbauer; 29.01.2016
comment
Я не пробовал это сам, но из того, что я видел, глобальные стили, использующие имя элемента вместо :host, также должны работать, но его необходимо добавить к styleUrls элементам, к которым вы все равно хотите применить стили. - person Günter Zöchbauer; 29.01.2016
comment
Предположим, у меня есть компонент графика, который я хочу, чтобы другие могли использовать в своих приложениях и настраивать обводку и заливку. Я хотел бы просто унаследовать любой штрих и заливку, определенные в компоненте, для пути svg, который является графиком. Использование таких классов, как предупреждение или ошибка, в этом случае не поможет. - person Soumya; 29.01.2016
comment
Я понимаю. Я не пробовал, работает ли в этом случае явное задание свойств стиля на inherit. В противном случае лучшим вариантом будет просто использование encapsulation: None и добавление стилей к ближайшему родителю, у которого нет encapsulation Emulated или Native. - person Günter Zöchbauer; 29.01.2016

Я знаю, что это старо, но я чувствую, что это должно быть более заметным. Вы можете использовать селектор /deep/, чтобы применить стиль вниз по дереву дочерних компонентов во все представления дочерних компонентов. Селектор /deep/ работает с любой глубиной вложенности компонентов и применяется как к дочерним элементам представления, так и к дочерним элементам содержимого компонента.

Я чувствую, что это намного чище и проще в реализации.

родительский.css

/deep/ .class {
    background-color: red;
}

https://angular.io/docs/ts/latest/guide/component-styles.html

person Mike    schedule 07.11.2016
comment
не применяется к директивам - person Brad Kent; 08.03.2017
comment
/deep/ устарело в полимере и Chrome (вероятно, скоро в angular). И должен использоваться только с эмулированной инкапсуляцией представления. - person titusfx; 04.07.2017
comment
До Angular 4.3 вместо ::ng-deep использовалось /deep/ или ›››. Обе нотации устарели в браузерах, поэтому ::ng-deep теперь является временным обходным путем. alligator.io/angular/styles-between-components-angular - person azulay7; 30.07.2017

Что касается CSS, компоненты поддерживают теневой DOM. Это означает, что их стили изолированы. Режим по умолчанию изолирован. Поэтому вам нужно определить стили CSS в компоненте (свойство стилей).

Вы также можете изменить режим инкапсуляции на ViewEncapsulation.None. Таким образом, ваш компонент сможет видеть стили родительского компонента:

@Component({
  selector: 'child',
  encapsulation: ViewEncapsulation.None,
  (...)
})
export class MyComponent {
  (...)
}

Надеюсь, это поможет вам, Тьерри.

person Thierry Templier    schedule 29.01.2016

Используйте селектор псевдокласса :host для стилизации любого файла <custom-component>.

Мы не можем написать стиль CSS для пользовательского элемента, используя class.

Пример

<custom-component class="custom-comp" [text]="'Some text'">

.custom-comp {
  font-weight: bold;
  color: green;
}

Для этой цели мы можем использовать селектор :host для стилизации, как показано ниже.

@Component({
  selector: 'custom-component',
  templateUrl: './custom-component.html',
  styleUrls: ['./custom-component.scss']
})

В пользовательском компоненте.scss

:host {
  font-weight: bold;
  color: green;
}

Вы можете узнать больше о стиле элемента :host в официальных документах Angular4.

person RAJA    schedule 01.09.2017