Sunday, March 20, 2016

Material Design Lite

A short and incomplete review

Material Design Lite (MDL) is a Google project intended to deliver a “Material design” look and feel to websites. This HTML, CSS and JavaScript project is a work in progress so shortcomings experienced might well be short lived so please bear in mind that this limited review was based upon version 1.1.2.

The project FAQ makes the following point. “We optimise for websites heavy on content, such as marketing pages, articles, blogs and general web content that isn’t particularly app-y.” However the supplied layout components respond well to variations in screen size and thus provide a solid basis for web pages targeting smartphones alongside desktop browsers. Where things are a bit clunky at the moment is in the area of dynamic page changes after the initial load and it may be that this will prove to be an enduring issue as (after all) that could be considered somewhat app-y.

The layout components provide a good range of page formats that can include navigation, a drawer, tabs, a straightforward and responsive grid and a footer. There is inbuilt JavaScript support for most of the layout options – you just set out your mark-up as directed and you are good to go. Colour choice is deliberately restrained but you can select from a range of themes to build a ‘custom’ CSS file.

Other components include a good variety of buttons, excellent cards, lists, menus, sliders, toggles and text fields. There is a dialog component but this is limited by only partial browser support although there is a polyfill available. The only obviously lacking component is a <select> but I found a CSS only solution that filled the gap nicely.

There is full support for the Google Material Design Icons although for MDL I only used the icon font having previously used the SVG and CSS sprite versions on other projects. As expected the font more than met my requirements.

I have a fondness for the consistency and flexibility of jQuery when it comes to DOM manipulation (however untrendy) and can confirm that jQuery works happily with MDL as long as you remember that jQuery objects are a collection of elements and that when calling an MDL function you may need to pass the first (or selected) element of the relevant collection:

Which brings me nicely to the app-y bits.

I first drafted out a reasonably complex static page to get a feel for the components and how they are laid out. The results were pleasing with just enough animation to give the design some life. Next I set up a skeleton MDL layout and attempted to build the same page content from JSON using JavaScript in the browser. Once the DOM has been updated with the new elements then you must call the componentHandler.upgradeElement() utility to apply the MDL layout magic to the new DOM elements. This worked very well for the set of cards I inserted together with their <div>s, text and checkboxes.

I then started to build the layout for a “visual” form constructor and started to run into some limitations. I envisaged my form constructor being based upon multiple tabs with the user being able to add a new tab to start a new ‘form’. I was able to inject the same structures into the DOM as would be required to initialise an MDL tabbed page but calling the upgradeElement() utility only gave me a partial result lacking in any MDL script support.

Currently most of the MDL documentation consists of asking questions on Stack Overflow.

There I learned about the downgradeElements() utility (although it does get a mention on the MDL web pages) that should be applied to a container that has already been sprinkled with the MDL fairy dust prior to calling the upgradeElement() function to rebuild things with any new inclusions. Indeed user HR_117 has kindly supplied a CodePen demo of this being applied to a set of MDL tabs. Trouble is, I found this failed when the tab container was itself wrapped within an MDL header (reported as an improbable bug so the true cause was masked in some way). Could very well be that I missed a trick here but how many hours can you spend on just one issue? My workaround (horror) was to create a bunch of tabs up front and to hide them on page load until they were required (a remarkably low overhead in reality as I was able to recycle previously used and subsequently closed tabs).

I hit similar problems with the clever “Text with Floating Label” component when injected into a pre-existing layout. After a short losing battle (quite possibly my misunderstanding or whatever) I switched to using this http://clubdesign.github.io/floatlabels.js/ alternative jQuery plugin that was a very nice substitute well within the style and spirit of Material Design.

In the end I got a functional page although many interactive elements of the layout were untidy. I knew I was in for a long round of CSS tweaking to get things polished but then again I have hit similar walls when working with Bootstrap. It was one of the reasons I had my first dalliance with Polymer where, by default, you can avoid the intrusion of inherited CSS – and the overhead of tracking down and fixing localised layout glitches. So maybe I should have a bash at mixing Polymer components into an MDL ‘frame’ – now that sounds like a winner and indeed should be very doable. A definite if I get to re-visit this specific task.

I am convinced enough by MDL as it stands to be sure of using it for aspects a commercial project currently in development. If you can avoid bumping into the limitations (and they will fast retreat I am sure – or maybe future documentation will show me, at least, the error of my ways) then it is very effective and can support a responsive web page that is bang up to date in design terms.

The experiment with MDL was a nice opportunity to exercise my JavaScript muscles after a bit of a lengthy break where C#, Java and even a touch of VB.NET had been the required tools. JavaScript is always a delight to get back to, as I find it a very satisfying language to work with. You can take liberties that other languages could not support but in the end I always feel a certain obligation to refactor code until it is fit for public display – even though I then feed it through Closure * to optimise browser download and execution. I found the (reasonably) recent addition of the Array.forEach() functionality (Mozilla polyfill available) very effective in reducing code complexity and enhancing readability – looks like ECMA 5 is creeping into my code. Array.find() is also another great – er – find.


* I do hope that Closure is extended to be a compiler for WebAssembly when that gets support across the browser range (looking good so far).

Addendum:

In many ways it makes more sense to implement the (rather restricted) forms designer app-y page that highlighted the MDL issues above as an app. Mobile development platforms are obviously going to be happy with the design concepts but how about good old Windows?

There is a Material Design skin project on GitHub addressing Windows forms projects although it has been a while since there were any updates. There is also a WPF focused project that looks a lot more complete and is certainly active - maybe attention has drifted from the former to the latter.

A little experiment showed that some Material Design styling can be added to a pretty basic Windows Forms app by overriding the Paint() events on some of the key components. Turning a panel into a card, for instance, does not require a lot of effort.

So, for Windows, a bit of mix and match should do the trick...

No comments: