If you are building applications with Angular (with or without Angular Material), did you know that you have available a very practical way of making your layout responsive without having to write any media queries yourself?
Yes, that's right, no media queries. 😉
Not that there is anything fundamentally wrong with writing our own media queries, it's just that I find that it can become quickly messy, unpractical and hard to maintain.
So if I can, I prefer to avoid it or at least minimize the number of media queries that I have to write, and Angular allows us to do just that.
So how do we make an Angular component or application responsive?
Follow these steps to implement a responsive design with Angular:
- use the Angular BreakpointObserver to detect the size of the current device
- set member variables in your component that allow you to show or hide certain elements depending on the screen size
- Set responsive CSS classes in your component like
is-phone-portraitdepending on the screen size
- Use these special classes to make the CSS of your component responsive without writing media queries
For the full details on exactly how to do this, check out the rest of the post.
Table Of Contents
In this post, we will cover the following topics:
- The BreakpointObserver Service
- Using layout-related flags to show or hide responsive elements
- Writing CSS that only applies to certain screen sizes (without media queries)
So without further ado, let's get started learning everything that we need to know for making your Angular application responsive!
The BreakpointObserver Service
The key to making our application responsive without writing our own media queries is the Angular CDK BreakpointObserver service.
This service provides us with an observable-based API that notifies its subscribers of the current dimensions of the screen, and any changes to the screen orientation caused by switching the device from landscape to portrait mode.
This service will also emit new values when we simulate different screen sizes using the dev tools, which is ideal for testing multiple layouts during development.
Notice that this service is part of the Angular Component Development Kit and not part of Angular Material directly.
You can use it with Angular Material, but you can also use it without it.
Using this service does not imply having to import a lot of code into your application, as the CDK is very modular.
So how does this service work?
BreakpointObserver service comes with a series of pre-built CSS breakpoints, that identify different types of devices and screen form factors:
Each of these breakpoints corresponds to a CSS media query, carefully written and researched to accurately match a very broad range of devices.
This is a complete list, but I find that most of the time
HandsetLandscape is all we need for most use cases.
If you want to know exactly to which CSS media query each breakpoint corresponds to, you can simply print them out to the screen, as the breakpoints are just strings containing the text of the media query.
Here is the result that you will get in the console.
The good news is that you actually don't have to worry about these media queries at all.
You will never have to maintain these CSS media queries yourself:
Web (min-width: 840px) and (orientation: portrait), (min-width: 1280px) and (orientation: landscape) WebLandscape (min-width: 1280px) and (orientation: landscape) WebPortrait (min-width: 840px) and (orientation: portrait) Tablet (min-width: 600px) and (max-width: 839.98px) and (orientation: portrait), (min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape) TabletPortrait (min-width: 600px) and (max-width: 839.98px) and (orientation: portrait) TabletLandscape (min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape) Handset (max-width: 599.98px) and (orientation: portrait), (max-width: 959.98px) and (orientation: landscape) HandsetLandscape (max-width: 959.98px) and (orientation: landscape) HandsetPortrait (max-width: 599.98px) and (orientation: portrait) XSmall (max-width: 599.98px) Small (min-width: 600px) and (max-width: 959.98px) Medium (min-width: 960px) and (max-width: 1279.98px) Large (min-width: 1280px) and (max-width: 1919.98px) XLarge (min-width: 1920px)
TabletPortrait correspond perfectly to a standard size iPad screen.
Hanset breakpoints correspond to mobile phones such as iPhone or Android phones.
How does the
BreakpointObserver service work?
BreakpointObserver provides us with an observable-based API that allows us to be notified whenever any of these breakpoints are matched by the current device.
For example, here is how we subscribe to the service to get notified when the screen matches the
If you start the application on a normal size desktop, you will see that nothing gets printed out to the console, and this is normal.
But you can simulate mobile devices using the Chrome Dev Tools, by using the Device toolbar:
The button highlighted in red will turn on the device toolbar, which allows you to select the size of the screen.
In this case, we set the screen to the same dimensions as an iPhone in landscape mode.
And as we can see in the console, this time around the breakpoint was triggered as expected.
As you toggle on and off the Chrome dev tools or you switch screen sizes using the device toolbar, you will see that a new value gets emitted by the breakpoint observer.
You can also use the
BreakpointObserver to subscribe to multiple breakpoints at the same time:
Notice that there is a breakpoints map emitted by the
BreakpointObserver service, that contains all the currently matching breakpoints, and we can test for each breakpoint separately.
As we can see, this service provides the fundamental building blocks for making our Angular components responsive.
But how do we use it in practice? There are a couple of ways.
Using layout-related flags to show or hide responsive elements
One of the simples things that we can do, is to adapt certain member variables of our component according to the responsive breakpoints that are matched.
For example, let's say that we have a component that needs to hide a side menu if the device is a phone or tablet in portrait mode.
We could adapt the UI by setting the value of a
hideSideMenu boolean member variable according to the current breakpoints:
Notice how we need to reset the value of
hideSideMenu when receiving a new set of matching breakpoints. We need to set this value back to its default value, in case the device no longer matches any of the breakpoints.
We can then use the
hideSideMenu flag to show or hide the side menu in the component template using
Instead of a boolean flag, we can also set a variable that defines the number of columns in a grid, the height of an element or anything else we need.
But what if we want to adapt the component styling according to the device?
Writing CSS that only applies to certain screen sizes (without media queries)
Many times, we still want to be able to control our component behavior using plain CSS.
For example, we would like to be able to remove certain margins and padding on a mobile device, due to the lack of space.
We can still do this without having to write media queries in our components, by creating a few layout-specific boolean member variables in our component.
For example, let's imagine that we want our component to apply certain CSS styles only if the screen is in phone portrait mode (usually the most restrictive format).
We would start by adding a boolean flag
isPhonePortrait to our component:
Then, we can use this flag to apply a special
is-phone-portrait to a container div that wraps the whole content of our component, using
Using this special CSS class, it's now very simple to add responsive styles to the CSS of our component, without having to write media queries:
As we could see, the
BreakpointObserver service of the Angular Cdk makes it super simple to make our Angular components responsive, without having to write a single media query.
Again, not that there is anything fundamentally wrong with adding media queries directly to your components CSS, it's just that I find that this approach is easier to read and maintain in the long term.
For example, if you want to search for all the specific styles in your application that target a phone in portrait mode, you can just search for
is-phone-portrait, as opposed to searching for a media query where it's easy to miss certain styles due to formatting, spacing, indenting, etc.
I also find that if the responsive CSS of each component is written this way, its just easier to read and understand it, which helps the codebase remain maintainable over time.
I hope that you have enjoyed this post, if you would like to learn a lot more about Angular Material, we recommend checking the Angular Material In Depth course, where responsive design is covered in detail.
Also, if you have some questions or comments please let me know in the comments below and I will get back to you.
To get notified of upcoming posts on Angular, I invite you to subscribe to our newsletter:
And if you are just getting started learning Angular, have a look at the Angular for Beginners Course: