As a web developer, there inevitably comes a time when we have to add responsiveness to an application. If you use Angular at your work, I've found some solutions that may help you deliver beautiful experience for multiple devices. Some of them are pretty basic, but they are still good practices you should follow.
PS. Every example below is written in CoffeeScript, SASS or SLIM.
This is the simplest solution that probably everybody knows about. We are using SASS, so the easiest way to work with media queries in a way that will organise your stylesheets is to create a few variables, the most basic being:
$desktop: 960px $tablet: 768px $mobile-large: 640px $mobile: 480px $mobile-small: 300px
and then you can just implement it like this:
@media only screen and (max-width : $desktop/$tablet/$mobile-large/$mobile/$mobile-small)
One pitfall that is common when developing a responsive app is creating another file called
responsive.sass that holds all media queries. Don't do this — it doesn't end up making your stylesheets more organized. Instead, just mix your media queries inside a class that you want to change. For example:
.item width: 25% display: inline-block @media only screen and (max-width: $tablet) width: 50% @media only screen and (max-width: $mobile-large) width: 100%
Inevitably, we sometimes need to disable certain features for mobile. To check the window width I recommend setting
$watch and creating a
$rootScope value for it. Then it can easily be checked without having to multiply one function in every directive/controller that you need.
$rootScope.$watch -> $rootScope.responsive = $window.outerWidth < 641
Just place it in
init.js.coffee in the .run function and then it will be working as expected.
I encountered one case when I needed to add a touch trigger for mobile devices. Detecting size or media queries wasn't enough, so I needed to detect the specific device, which the code below does.
detectMobile = () -> isMobile = (/android|webos|iphone|ipad|ipod|blackberry|windows phone/).test(navigator.userAgent.toLowerCase()) isMobile $rootScope.mobileDevice = detectMobile()
Again, put it in
init.js.coffee in the .run function.
It's really simple when you use jquery-ui.
All you have to do is add the code above to your 'Gemfile'. It will transform clicks to taps.
On mobile devices we have a problem with space, so we put elements under themselves. In a situation when we create a new object — which will create a new UI element on mobile — we need to scroll to that object. Using lodash and Angular's $watchCollection you can create something like this:
scope.$watchCollection 'exampleCollection', (newGroup, oldGroup) -> if newGroup?.length > oldGroup?.length elAdded = _.difference(newGroup, oldGroup) index = _.findIndex(newGroup, (group) -> group == elAdded) if index != -1 scrollvalue = angular.element(element).children().eq(index).offsetTop window.scrollTo(0, scrollvalue)
This sets a watch on
exampleCollection in the directive. If an object is added, the script checks the object's index, finds it in DOM and scrolls to it.
One time I had some strange issues on an iPad. I was displaying a number that could be interpreted as a phone number. When the device detected the number, the markup changed and a new anchor was added with the phone number instead of a plain number. To fix this, we can simply add this code into to head section.
Is Angular the pick for your next app?
Wondering if Angular is the best pick for your next project?