28
Building Progressive UIs with Grails Rob Fletcher Energized Work

GR8Conf 2011: Building Progressive UIs with Grails

  • Upload
    gr8conf

  • View
    107

  • Download
    1

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: GR8Conf 2011: Building Progressive UIs with Grails

Building Progressive UIs with Grails

Rob FletcherEnergized Work

Page 2: GR8Conf 2011: Building Progressive UIs with Grails

Who am I?

Page 3: GR8Conf 2011: Building Progressive UIs with Grails

Examples

gr8-examples.cloudfoundry.com

github.com/robfletcher/gr8-examples

Page 4: GR8Conf 2011: Building Progressive UIs with Grails

What is Progressive Enhancement?

Approach to building web UIs that emphasizes:• Semantic markup• Separation of markup, appearance, behaviour• Rich appearance and

behaviour applied selectively• Adaptive design for cross-browser & cross-

device support• Distinct from 'graceful degradation’

Page 5: GR8Conf 2011: Building Progressive UIs with Grails

Designing with Progressive Enhancement

http://filamentgroup.com/dwpe/

Page 6: GR8Conf 2011: Building Progressive UIs with Grails

Is this worth the effort?

• Cross-browser compatibility• SEO compliance• Mobile device support• Support for assistive devices e.g.

screenreaders• Low bandwidth environments• Maintainable structure• Testability

Page 7: GR8Conf 2011: Building Progressive UIs with Grails

Fundamentals

• JavaScript and CSS separated from markup• Script reads and enhances markup• Presentational markup injected by script

Page 8: GR8Conf 2011: Building Progressive UIs with Grails

dowebsitesneedtolookexactlythesameineverybrowser.com

Page 9: GR8Conf 2011: Building Progressive UIs with Grails

Don’t Break The Web!

Page 10: GR8Conf 2011: Building Progressive UIs with Grails

<a href="/foo”

onclick="return doSomething()">

Click me

</a>

Markup:<a href="/foo" class="profile">Click me</a>

External script file:$('a.profile').click(doSomething);

Separation of markup & behaviour

Page 11: GR8Conf 2011: Building Progressive UIs with Grails

<a href="/foo" class="popup">Click me</a>

$('a.popup').click(function() {

    displayInPopup('/foo');

    return false;

});

<a href="/foo" class="popup">Click me</a>

$('a.popup').click(function() {

    displayInPopup($(this).attr('href'));

    return false;

});

Read and enhance markup

Page 12: GR8Conf 2011: Building Progressive UIs with Grails

EXAMPLEForm enhancements and dialogs

Page 13: GR8Conf 2011: Building Progressive UIs with Grails

The X-Ray Perspective

1. Map design components to basic HTML2. Build markup with simple styles & no JS3. Layer visual & interaction enhancements

using JS & CSS

Page 14: GR8Conf 2011: Building Progressive UIs with Grails

EXAMPLEData visualisation

Page 15: GR8Conf 2011: Building Progressive UIs with Grails

How can Grails help?

request.xhr• different response for AJAX requests• render template / view• disable SiteMesh• forward rather than redirectwithFormat• respond with different data typesWebUtils.isIncludeRequest• tailor response for full page or content section

Page 16: GR8Conf 2011: Building Progressive UIs with Grails

Varying output for AJAX

def show = {

def model = // … whatever

if (request.xhr) {

render template: "basket", model: model

} else {

return model

}

}

Page 17: GR8Conf 2011: Building Progressive UIs with Grails

Disabling SiteMesh for AJAX

<!doctype html>

<html>

<head>

<g:if test="${!request.xhr}">

<meta name="layout" content="main">

</g:if>

Page 18: GR8Conf 2011: Building Progressive UIs with Grails

EXAMPLEPagination -> infinite scroll

Page 19: GR8Conf 2011: Building Progressive UIs with Grails

Test-driven progressive enhancement

Use browser capability detection to…• activate script-driven behaviour• activate 'polyfills' on less capable

browsers• selectively load JavaScript and CSS files• apply advanced CSS rules to capable

browsers

Page 20: GR8Conf 2011: Building Progressive UIs with Grails

<html class="js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop no-websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity no-cssanimations csscolumns cssgradients no-cssreflections csstransforms no-csstransforms3d csstransitions fontface video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">

.dialog {

background-color: #ccc;

}

.rgba .dialog {

background-color: rgba(0, 0, 0, 0.3);

}

if (Modernizr.geolocation) {// use native geolocation

} else {// activate JavaScript polyfill

}

Modernizr

Page 21: GR8Conf 2011: Building Progressive UIs with Grails

EXAMPLEFOUC prevention

Page 22: GR8Conf 2011: Building Progressive UIs with Grails

Yepnope.js

yepnope({

test : Modernizr.geolocation,

yep : 'normal.js',

nope : ['polyfill.js', 'wrapper.js’]

});

Page 23: GR8Conf 2011: Building Progressive UIs with Grails

EXAMPLEAJAX-enhanced pagination

Page 24: GR8Conf 2011: Building Progressive UIs with Grails

• Build for mobile devices first• Layer up to desktop using media queries• Prevent large images & supplementary

content sections loading

body {    background: url(low-res-image.png);}

@media screen and (min-width: 480px) {    body {        background: url(hi-res-image.png); max-width: 1140px;    } #main, #sidebar { float: left; } #main { width: 65%; } #sidebar { width: 35%; }}

Mobile-first progressive enhancement

Page 25: GR8Conf 2011: Building Progressive UIs with Grails

What to avoid in Grails

AJAX tags:• g:formRemote

• g:remoteField

• g:remoteFunction

• g:remoteLink

Page 26: GR8Conf 2011: Building Progressive UIs with Grails

Resources plugin & templates

<r:use module="div-enhance-script"/>

• Useful for highly modular apps• Script included at end of page• Can be used multiple times & script is

only included once

Page 27: GR8Conf 2011: Building Progressive UIs with Grails

Resources plugin & yepnope.js

<r:script disposition="head">

    yepnope({

        test : Modernizr.geolocation,

        yep  : "${r.resource(uri: 'normal.js')}",

        nope : [

            "${r.resource(uri: 'polyfill.js')}",

            "${r.resource(uri: 'wrapper.js')}"

        ]

    });

</r:script>

Page 28: GR8Conf 2011: Building Progressive UIs with Grails

Thank you!

@rfletcherEW

adhockery.blogspot.com

www.energizedwork.com