Tutorial

How To Detect Breakpoints Using the Angular CDK

Updated on August 9, 2021
author

Alligator.io

How To Detect Breakpoints Using the Angular CDK

Introduction

The Angular CDK has a layout package with services to detect viewport sizes and matches against media queries. This allows you full control over the UI and to adapt to different screen sizes.

In this article, you will apply the CDK’s layout module in Angular projects.

Prerequisites

If you would like to follow along with this article, you will need:

This tutorial was verified with Node v16.6.1, npm 7.20.3, @angular/core v12.2.0, and @angular/cdk v12.2.0.

Setting Up the Project

You can use @angular/cli to create a new Angular Project.

In your terminal window, use the following command:

  1. ng new AngularBreakpointsExample --style=css --routing=false --skip-tests

This will configure a new Angular project with styles set to “CSS” (as opposed to “Sass”, Less", or “Stylus”), no routing, and skipping tests.

Navigate to the newly created project directory:

  1. cd AngularBreakpointsExample

Next, install @angular/cdk:

  1. npm install @angular/cdk@12.2.0

Then import the layout module and and add it to your NgModule’s list of imports:

src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { LayoutModule } from '@angular/cdk/layout';

import { AppComponent } from './app.component';

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

You can now start using the available services and utilities in your components. Let’s discuss each of them.

Using BreakpointObserver.observe and BreakpointState

The observe method returns an observable of type BreakpointState and can be used to observe when the viewport changes between matching a media query or not.

Here’s an example where a message is logged to the console if the viewport size changes between being less than 500px and equal to or more than 500px:

src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import {
  BreakpointObserver,
  BreakpointState
} from '@angular/cdk/layout';

@Component({ 
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(public breakpointObserver: BreakpointObserver) {}
  
  ngOnInit() {
    this.breakpointObserver
      .observe(['(min-width: 500px)'])
      .subscribe((state: BreakpointState) => {
        if (state.matches) {
          console.log('Viewport width is 500px or greater!');
        } else {
          console.log('Viewport width is less than 500px!');
        }
      });
  }
}

Note: You may also need to remove {{ title }} from app.component.html to prevent an error.

The BreakpointState interface gives us a boolean property called matches.

Using Breakpoints

Instead of using hand-written media queries, we can also make use of the Breakpoints object, which gives us keys for common breakpoints:

src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import {
  BreakpointObserver,
  Breakpoints,
  BreakpointState
} from '@angular/cdk/layout';

@Component({ 
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(public breakpointObserver: BreakpointObserver) {}

  ngOnInit() {
    this.breakpointObserver
      .observe([Breakpoints.Small, Breakpoints.HandsetPortrait])
      .subscribe((state: BreakpointState) => {
        if (state.matches) {
          console.log(
            'Matches small viewport or handset in portrait mode'
          );
        }
      });
  }
}

This example uses the predefined breakpoints for Breakpoints.Small and Breakpoints.HandsetPortrait.

Using BreakpointObserver.isMatched

For one-off matching, we can use the isMatching method instead.

src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import {
  BreakpointObserver,
  BreakpointState
} from '@angular/cdk/layout';

@Component({ 
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(public breakpointObserver: BreakpointObserver) {}

  ngOnInit() {
    if (this.breakpointObserver.isMatched('(min-height: 40rem)')) {
      console.log('Viewport has a minimum height of 40rem!');
    }
  }
}

This will log a message if the viewport is at least 40rem tall when the component initializes.

Using MediaMatcher

MediaMatcher is a service that wraps around JavaScript’s matchMedia. As with BreakpointObserver.observe, it can also be used to observe changes in the viewport size against a given media query.

Here is an example that checks if min-width is 500px wide:

src/app/app.component.html
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MediaMatcher } from '@angular/cdk/layout';

@Component({ 
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  matcher!: MediaQueryList;

  constructor(public mediaMatcher: MediaMatcher) {}

  ngOnInit() {
    this.matcher = this.mediaMatcher.matchMedia('(min-width: 500px)');

    this.matcher.addEventListener('change', this.myListener);
  }

  ngOnDestroy() {
    this.matcher.removeEventListener('change', this.myListener);
  }

  myListener(event: { matches: any; }) {
    console.log(event.matches ? 'match' : 'no match');
  }
}

The difference with BreakpointObserver.observe is that MediaMatcher gives us access to the native MatchQueryList object, which may be needed in certain scenarios.

Note: Previously, this example used addListener and removeListener. addListener is deprecated and addEventListener is recommended for modern browsers. And removeListener is deprecated and removeEventListener is recommended for modern browsers.

Now you have everything you need to react or adapt your UI to different viewport sizes in Angular.

Conclusion

In this article, applied the CDK’s layout module in Angular projects.

Continue your learning with the documentation for the CDK’s layout module API reference.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products


About the authors
Default avatar
Alligator.io

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel