Skip to content

4. Angular Custom Breakpoints


1. Screen Size

src/app/screen-size.ts
export enum SCREEN_SIZE {
  XS,
  SM,
  MD,
  LG,
  XL,
}


2. Resize Service

src/app/resize.service.ts
import { Injectable } from "@angular/core";
import { distinctUntilChanged, Observable, Subject } from "rxjs";
import { SCREEN_SIZE } from "./screen-size";

@Injectable({
  providedIn: "root",
})
export class ResizeService {
  private resizeSubject: Subject<SCREEN_SIZE>;

  constructor() {
    this.resizeSubject = new Subject();
  }

  onResize(size: SCREEN_SIZE) {
    this.resizeSubject.next(size);
  }

  get onResize$(): Observable<SCREEN_SIZE> {
    return this.resizeSubject.asObservable().pipe(distinctUntilChanged());
  }

  getClassName(size: SCREEN_SIZE) {
    let dSize: String = "";

    switch (size) {
      case 0:
        dSize = "d-xs";
        break;
      case 1:
        dSize = "d-sm";
        break;
      case 2:
        dSize = "d-md";
        break;
      case 3:
        dSize = "d-lg";
        break;
      case 4:
        dSize = "d-xl";
        break;
    }

    return dSize;
  }
}


3. SizeDetector Component

import {
  AfterViewInit,
  Component,
  ElementRef,
  HostListener,
} from "@angular/core";
import { ResizeService } from "../resize.service";
import { SCREEN_SIZE } from "../screen-size";

@Component({
  selector: "app-size-detector",
  templateUrl: "./size-detector.component.html",
  styleUrls: ["./size-detector.component.css"],
})
export class SizeDetectorComponent implements AfterViewInit {
  prefix = "is-";
  sizes = [
    { id: SCREEN_SIZE.XS, name: "xs", css: `xs` },
    { id: SCREEN_SIZE.SM, name: "sm", css: `sm` },
    { id: SCREEN_SIZE.MD, name: "md", css: `md` },
    { id: SCREEN_SIZE.LG, name: "lg", css: `lg` },
    { id: SCREEN_SIZE.XL, name: "xl", css: `xl` },
  ];

  constructor(
    private elementRef: ElementRef,
    private resizeSvc: ResizeService
  ) {}

  @HostListener("window:resize", [])
  private onResize(): void {
    this.detectScreenSize();
  }

  ngAfterViewInit(): void {
    this.detectScreenSize();
  }

  private detectScreenSize(): void {
    const currentSize = this.sizes.find((x) => {
      const el = this.elementRef.nativeElement.querySelector(
        `.${this.prefix}${x.id}`
      );

      const isVisible = window.getComputedStyle(el).display != "none";

      return isVisible;
    });

    this.resizeSvc.onResize(currentSize!.id);
  }
}
<div *ngFor="let s of sizes" class="{{ s.css + ' ' + (prefix + s.id) }}"></div>


4. Styles CSS

src/styles.css
/* You can add global styles to this file, and also import other style files */
@media screen and (max-width: 359.98px) {
  .xs {
    display: block !important;
  }
  .sm {
    display: none !important;
  }
  .md {
    display: none !important;
  }
  .lg {
    display: none !important;
  }
  .xl {
    display: none !important;
  }
}

@media screen and (min-width: 360px) and (max-width: 719.98px) {
  .xs {
    display: none !important;
  }
  .sm {
    display: block !important;
  }
  .md {
    display: none !important;
  }
  .lg {
    display: none !important;
  }
  .xl {
    display: none !important;
  }
}

@media screen and (min-width: 720px) and (max-width: 1079.98px) {
  .xs {
    display: none !important;
  }
  .sm {
    display: none !important;
  }
  .md {
    display: block !important;
  }
  .lg {
    display: none !important;
  }
  .xl {
    display: none !important;
  }
}

@media screen and (min-width: 1080px) and (max-width: 1919.98px) {
  .xs {
    display: none !important;
  }
  .sm {
    display: none !important;
  }
  .md {
    display: none !important;
  }
  .lg {
    display: block !important;
  }
  .xl {
    display: none !important;
  }
}

@media screen and (min-width: 1920px) {
  .xs {
    display: none !important;
  }
  .sm {
    display: none !important;
  }
  .md {
    display: none !important;
  }
  .lg {
    display: none !important;
  }
  .xl {
    display: block !important;
  }
}


5. Hello Component

import { Component, OnInit } from "@angular/core";
import { ResizeService } from "../resize.service";

@Component({
  selector: "app-hello",
  templateUrl: "./hello.component.html",
  styleUrls: ["./hello.component.css"],
})
export class HelloComponent implements OnInit {
  dSize?: String;

  constructor(private resizeSvc: ResizeService) {
    this.resizeSvc.onResize$.subscribe((x) => {
      this.dSize = this.resizeSvc.getClassName(x);
    });
  }

  ngOnInit(): void {}
}
<h1 class="{{ dSize }}">Hello {{ dSize }} !!</h1>


6. App Module

src/app/app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { SizeDetectorComponent } from "./size-detector/size-detector.component";
import { HelloComponent } from "./hello/hello.component";

@NgModule({
  declarations: [AppComponent, SizeDetectorComponent, HelloComponent],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}


7. App Component

src/app/app.component.html
<app-hello></app-hello> <app-size-detector></app-size-detector>

References