ngClass и ngStyle ⚡️ Angular с примерами кода

ngClass

Директива ngClass позволяет определить набор классов, которые будут применяться к элементу. Например, определим следующий компонент:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { Component } from '@angular/core'
@Component({
  selector: 'my-app',
  template: `
    <div [ngClass]="{ verdanaFont: true }">
      <h2>Hello Angular 2</h2>
      <p [ngClass]="{ segoePrintFont: true }">
        Angular 5 представляет модульную архитектуру
        приложения
      </p>
    </div>
  `,
  styles: [
    `
      .verdanaFont {
        font-size: 13px;
        font-family: Verdana;
      }
      .segoePrintFont {
        font-size: 14px;
        font-family: 'Segoe Print';
      }
    `,
  ],
})
export class AppComponent {}

В секции styles у компонента определены два класса, которые устанавливают различные стилевые свойства шрифта:

verdanaFont и segoePrintFont.

В шаблоне для привязки класса к элементу применяется директива [ngClass]="{verdanaFont:true}". Эта директива принимает js-объект, в котором ключи — это названия классов. Этим названиям присваиваются булевые значения true (если класс применяется) и false (если класс не применяется). То есть в данном случае класс verdanaFont будет применяться ко всему блоку div.

Однако в блоке div есть параграф, и мы, допустим, хотим, чтобы к этому параграфу применялся другой класс. А по умолчанию вложенный параграф унаследует стили от родительского блока

div и также применяет класс segoePrintFont, в котором можно переопределить унаследованные стили.

В качестве альтернативы мы можем использовать следующие выражения привязки:

1
2
3
4
5
6
7
8
9
<div [class.verdanaFont]="true">
  <h2>Hello Angular 5</h2>
  <p
    [class. verdanaFont]="false"
    [class.segoePrintFont]="true"
  >
    Angular 7 представляет модульную архитектуру приложения
  </p>
</div>

Выражение [class.verdanaFont]="true" указывает, что класс verdanaFont будет применяться для данного элемента.

ngStyle

Директива ngStyle позволяет задать набор стилей, которые применяются к элементу. В качестве значения директива принимает js-объект, в котором ключи — названия свойств CSS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { Component } from '@angular/core'
@Component({
  selector: 'my-app',
  template: `
    <div
      [ngStyle]="{
        'font-size': '13px',
        'font-family': 'Verdana'
      }"
    >
      <h2>Hello Angular 5</h2>
      <p
        [ngStyle]="{
          'font-size': '14px',
          'font-family': 'Segoe Print'
        }"
      >
        Angular 5 представляет модульную архитектуру
        приложения
      </p>
    </div>
  `,
  styles: [
    `
      .
verdanaFont { font-size: 13px; font-family: Verdana; } .segoePrintFont { font-size: 14px; font-family: 'Segoe Print'; } `, ], }) export class AppComponent {}

Аналогично для установки стилей можно применять свойства объекта

style:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<div
  [style.fontSize]="'13px'"
  [style.fontFamily]="'Verdana'"
>
  <h2>Hello Angular 7</h2>
  <p
    [style.fontSize]="'14px'"
    [style.fontFamily]="'Segoe Print'"
  >
    Angular 7 представляет модульную архитектуру приложения
  </p>
</div>

Динамическое изменение стилей

Директивы ngClass и ngStyle позволяют устанавливать привязку к выражениям, благодаря чему мы можем динамически менять стили или классы. Например:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { Component } from '@angular/core'
@Component({
  selector: 'my-app',
  template: `
    <div [ngClass]="{ invisible: visibility }">
      <h2>Hello Angular 5</h2>
      <p>
        Angular 5 представляет модульную архитектуру
        приложения
      </p>
    </div>
    <button (click)="toggle()">Toggle</button>
  `,
  styles: [
    `
      .
invisible { display: none; } `, ], }) export class AppComponent { visibility: boolean = true // переключаем переменную toggle() { this.visibility = !this.visibility } }

Выражение [ngClass]="{invisible: visibility}"

устанавливает для класса invisible привязку к значению переменной visibility. По нажатию на кнопку мы можем переключать это свойство, тем самым управляя видимостью блока.

В качестве альтернативы также можно было бы использовать следующее выражение:

<div [class.invisible]="visibility"></div>

Либо также можно было бы написать так:

<div
  [style.display]="visibility==true?'block':'none'"
></div>

Классы и идентификаторы в HTML и CSS

В предыдущем уроке в качестве селекторов правил CSS мы использовали имена тегов HTML. Например, для абзаца у нас было следующее правило:

p {
  font-size: 18px;
  font-family: Verdana, Arial, sans-serif;
} 

Оно действовало для всех элементов p документа. Но что делать, если какие-то из них надо оформить по-другому?

Более тонкая разметка страницы и настройка ее элементов выполняется с помощью использования классов, идентификаторов, комбинированных и других селекторов. В этом уроке мы рассмотрим только классы и идентификаторы.

У открывающих или одиночных тегов HTML может быть атрибут class, которому присваивается произвольное (вами придуманное) имя класса. Например:

<p>…текст…</p>

Теперь в CSS, чтобы оформить этот абзац по особому, в таблице стилей мы обращаемся к нему с помощью такого синтаксиса:

.название_класса {
    ...
}

То есть перед именем класса ставим точку, само имя в кавычки не берем.

По смыслу скорее именно в CSS мы определяем класс и создаем для него правило, а в HTML обращаемся к нему с помощью атрибута class, то есть применяем какой-то класс к элементу. Другими словами, делаем элемент принадлежащим определенному классу.

Одному классу может принадлежать множество html-элементов.

На скрине выше два абзаца и один раздел принадлежат классу addition.

Если мы хотим ограничить применимость класса только к одному типу элементов, а не к любому, то в css-правиле перед точкой следует указать этот элемент. Например:

p.addition {
  font-size: 18px;
  font-weight: bold;
  color: DimGrey;
  margin-left: 15px;
}

В таких случаях назначение класса другим элементам бессмысленно (ошибки не будет, но стилевое правило класса не будет применено):

<div>
  Содержимое раздела
</div>

Однако для другого элемента в таблице стилей может быть свой класс с таким же именем:

div.addition {
  border-style: ridge;
}

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

Вернемся к нашему исходному примеру, в котом один класс может применяться к разным html-элементам:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
 
  body {
    background: WhiteSmoke;  
  } 
 
  p {
    font-size: 20px;
    font-family: Verdana, sans-serif;
  } 
 
  . addition {
    font-size: 18px;
    font-weight: bold;
    color: DimGrey;
    margin-left: 15px;
  }
 
</style>
</head>
<body>
 
<p>Первый абзац</p>
 
<p>Второй абзац</p>
 
<p>Третий абзац</p>
 
<p>Четвертый абзац</p>
 
<p>Пятый абзац</p>
 
<div>
  Содержимое раздела
</div>
 
</body>
</html>

Если вы присмотритесь к абзацам класса addition, то заметите, что семейство их шрифта такое же как у обычных абзацев, то есть один из вариантов sans-serif – шрифта без засечек. В то же время у раздела div начертание serif – с засечками.

Дело в том, что согласно концепции специфичности языка CSS, к элементу применяется более специфичное правило. Класс в этой иерархии имеет более высокий приоритет и переопределяет стиль с более низким приоритетом.

В нашем случае, когда класс применяется к абзацу, более низкий приоритет оказывается у правила с селектором имени тега

p. Но это не значит, что к элементу не применяется стиль, обладающий меньшей специфичностью. Правило с более высоким приоритетом (более специфичное) как бы накладывается на него.

Таким образом, к абзацам с классом было применено правило с селектором p и затем правило с селектором .addition. Если какое-либо свойство описывалось в обоих правилах, то применялось значение этого свойства для класса addition.

Что касается элемента div, то его семейство шрифта нами не менялось, оно осталось в варианте по-умолчанию, заданном браузером. Правило с селектором p для div неприменимо.

Взаимоотношения между селектором-тегом и селектором-классом можно было бы назвать наследованием, когда непереназначенные свойства берутся из менее специфичного правила (условно родительского), в более специфичном переопределяются лишь некоторые, остальные наследуются. Однако в концепции CSS наследованием называют другое: когда некоторые свойства элемента-контейнера наследуются для вложенных в него элементов. Например, размер и семейство шрифта можно задать для body, и эти значения будут работать для всех элементов страницы. Но при этом мы можем переопределять их для отдельных.

Теперь перейдем к идентификаторам. Их применение похоже на то, как это происходит с классами. Однако вместо html-атрибута class используется id, при этом в правиле CSS селектор с идентификатором записывается через решетку.

<!DOCTYPE html>
<html>
<head>
<style> 
 
  body {
    background: WhiteSmoke;  
  } 
 
  p {
    font-size: 20px;
    font-family: Verdana, sans-serif;
  } 
 
  #special {
    font-size: 22px;
    border-style: dotted;
    border-width: 2px;
    color: Red;
    padding: 15px;
  }
 
</style>
</head>
<body>
 
<p>Первый абзац</p>
 
<p>Второй абзац</p>
 
<p>Особенный абзац</p>
 
<p>Четвертый абзац</p>
 
<p>Пятый абзац</p>
 
</body>
</html>

Смысловое (на самом деле вы можете прописать один идентификатор нескольким элементам) отличие идентификаторов от классов заключается в следующем: класс применим ко множеству элементов на странице, конкретный идентификатор следует использовать только с одним элементом. Другими словами, для каждого элемента на странице подразумевается свой уникальный идентификатор.

Обращение к элементам через идентификаторы часто используется в JavaScript. Например, при нажатии на одну кнопку вызывается определенная функция, которая что-то изменяет на странице. При этом не надо, чтобы эта функция вызывалась при нажатии на любую другую кнопку или иной элемент.

К элементу может применяться несколько классов. В таких случаях они указываются через пробел в атрибуте class. У элемента может быть и идентификатор, и класс/классы:

<p>...</p>

Специфичность идентификатора выше, чем у класса; то есть, если у элемента есть как идентификатор, так и класс, то значения свойств первого переопределят значения второго.

При применении к элементу нескольких классов мы касаемся такого понятия в CSS как каскад (на то они и каскадные таблицы стилей – Cascading Style Sheets): последующее определение свойства в одинаковом по специфичности селектора правиле переопределяет ранее объявленное. В примере ниже элементы, использующие оба класса, будут синими:

.addition {
  font-size: 18px;
  font-weight: bold;
  color: DimGrey;
  margin-left: 15px;
}
 
.another {
  color: Blue;
}

В данном случае второй классовый стиль переопределит свойство color первого. Просто потому, что он описан после него. Это касается таблицы CSS, но не упоминания классов в атрибуте class тега. Так в нижеследующих абзацах нет никакой стилевой разницы:

<p>...</p>
<p>...</p>

Также обратим внимание на то, что некоторые html-элементы обычно используются на странице единожды. Например, многие семантические теги: main, article, footer и др. В таких случаях нет смысла указывать для них идентификаторы, и при создании css-правила в качестве селектора проще писать имя тега.

С другой стороны, если имеется определенный элемент, требующий уникального оформления, которое вряд ли будет использоваться где-либо еще, даже на других страницах сайта, и обращаться к которому мы не планируем посредством JavaScript, то предпочтительно описывать его стиль в самом элементе с помощью атрибута style.

<p>
Первый абзац
</p>

Специфичность добавленных непосредственно в тег css-объявлений самая высокая. Она выше, чем у идентификатора, тем более класса.

Атрибут style – это еще один из способов добавления CSS-кода к HTML-коду. До этого мы использовали только вставку таблицы стилей между тегами <style></style>.


Добавить класс к нескольким элементам — Отзывы о продукте — Форум

Will_Specht (Уилл Шпехт) 1

Есть ли способ легко добавить класс к нескольким элементам? Как добавить класс к каждому элементу списка в списке после того, как список уже составлен?

В противном случае было бы неплохо добавить эту функцию в менеджер стилей. Добавьте кисть рядом с каждым стилем. Если вы щелкнете кистью и щелкнете по элементу, он получит этот стиль. Это действительно поможет, если вы добавляете стили или забываете добавить их при их создании.

2 лайков

Морди_Леви (Морди Леви) 2

отличная идея, может просто выделить несколько элементов с зажатым шифтом (как в проводнике) и потом всем подписать класс? У меня была эта проблема, и я просто учусь сначала создавать класс, а не копировать и вставлять элементы

Drennen (Дреннен Браун) 3

БУМП. Сегодня искал эту функцию. Та же проблема. Разработан длинный список. Создайте новый класс, хотите вставить его в остальные элементы.

PixelGeek (Нельсон) 4

Я переместил эту тему в список желаний.

В настоящее время у нас нет способа применить один класс к нескольким элементам. Это отличное предложение, и мы должны рассмотреть его в будущем.

спасибо

1 Нравится

Бисквит (Отметка) 5

Я думаю, что нам нужны селекторы Child и Pseudo, поэтому все

тегов внутри элемента — n-й дочерний элемент. Это сделало бы чистый css и помогло бы, когда cms добавляется к элементам стиля, поступающим из cms.

пиявка (Клемент Синс) 6

Я бы тоже хотел!

шонк (Шон Уоткинс)