Skip to main content

Styling

This page covers best practices for styling in Angular, including structuring styles, using variables, scoping component styles, and avoiding common pitfalls.

General guidelines

Avoid repeating CSS styles.

Why?

If you do, it usually means that you need to make a component out of it.

Do use SASS (.scss).

Avoid inline styles.

❌ user.component.html
<div style="margin-top: 20px">...</div>
✅ user.component.scss
div { 
margin-top: 20px;
}

Do use snake-case for class and id names.

  • class="selectedItem"
  • class="selected-item"
  • id="add_button"
  • id="add-button"

Variables

Do use variables for theme related values.

SASS variables

Do use SASS variables for static values.

$color-danger: #FF0000;

p {
color: $color-danger;
}

Do add extra base path to import global SASS variables.

❌ user.component.scss
@use '../../../../../theme';
h1 {
color: theme.$primary;
}
✅ angular.json
{
"projects": {
"my-app": {
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"stylePreprocessorOptions": {
"includePaths": ["src"]
}
}
}
}
}
}
}
✅ user.component.scss
@use 'theme';
h1 {
color: theme.$primary;
}

CSS variables

Do use CSS variables for dynamic values that can change at runtime.

:root {
--app-font-size: 16px;
}

p {
font-size: var(--app-font-size);
}

.big-text-area {
--app-font-size: 24px;
}

Component styles

Do keep default style scoping.

  • encapsulation: ViewEncapsulation.None
  • encapsulation: ViewEncapsulation.Emulated

Consider using component style instead of global styles.

❌ styles.scss
.selected p > span {
color: $primary;
}
✅ user-card.component.scss
.selected p > span {
color: $primary;
}
Why?

Global styles often leads to unintended side effects. The larger the project, the more difficult it will be to modify these global styles, forcing you to override them in several places.

Do use :host to apply styles to the component root element.

✅ user.component.scss
:host { 
display: flex;
}

Consider defining component's CSS variables within the :host selector.

Do prefix component's CSS variable names with the component name.

✅ user.component.scss
:host { 
--user-title-color: theme.$primary;
}

Global styles

Do split global styles in partial SCSS files.

  • styles.scss as the entrypoint.
  • _default.scss for overriding default browsers styles.
  • _typography.scss for fonts and headings.
  • _form.scss for form fields.
  • ...

Consider defining global CSS variables within the :root selector.

Do prefix global CSS variable names by app-.

✅ user.component.scss
:root { 
--app-text-color: #131218;
}

Overriding styles

Consider CSS variables or component inputs to override your components styles.

Avoid using ::ng-deep.

❌ user.component.ts
:host ::ng-deep .mat-mdc-chip-action > .mdc-evolution-chip__graphic {
padding: 0;
}
Why?

If you are trying to override your own component, use CSS variables or inputs instead.

If you are trying to override an external component, you'll need to rely on private implementation details that may change at any time (without being mentioned in a changelog). So there's a good chance you app will break after a dependency update, which will result in either a painful migration and bugs, or no update at all.

External libraries often provide theming features to customise their components, try to use them. Use ::ng-deep only as a last resort.

Avoid using !important.

Why?

It usually means that you are trying to override either global styles or private implementation details. Try another technique mentioned above or use a more specific selector instead.

Responsive design

Do use MediaMatcher to listen for window width changes.

✅ layout.component.ts
this.mobileQuery = this.media.matchMedia('(max-width: 900px)');
const isMobile = this.mobileQuery.matches;