designing and developing trello for multiple devices

Post on 21-Apr-2015

46.888 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Designing and Developing Trello for Multiple Devices

Bobby Grace - March 2012

Thursday, March 22, 12

Our approach... one site and one codebase for all devices.

Thursday, March 22, 12

Why

Thursday, March 22, 12

People get a consistent experience.

No redirects. Links work seamlessly.

Can read pitch, watch video, sign up and start using it.

Don’t have to learn a new interface.

All the same features.

Thursday, March 22, 12

We can deliver updates seamlessly.

One place to deploy, easy updates.

Don’t have to retro-fit features for mobile.

Mobile site is always up-to-date.

Thursday, March 22, 12

Everything we do for mobile translates back to a better desktop experience.

Big, finger-friendly hit targets

Super fast

Intuitive interactions

Thursday, March 22, 12

What about native apps?

Thursday, March 22, 12

We love native apps!We have an iPhone app and are

working on an Android app.

Gives us native speed, native look and feel, push notifications, offline support...

Thursday, March 22, 12

But we didn’t want to ignore the mobile web because of native apps.

Thursday, March 22, 12

How

Thursday, March 22, 12

Optimizing UI Components for Mobile

Thursday, March 22, 12

Pop over menus Narrow enough for mobile devices

finger-friendly hit targets

280px

These context menus are used to log in, show card actions, view notifications, and lots more.

Thursday, March 22, 12

Only one menu is visible at a time. Simplifies navigation and works on mobile.

There are view transitions, though.

Back to Card Actions1. 2.

Thursday, March 22, 12

This is not going to work for us...Lots of hover events and complicated nesting. Will work for a desktop-only environment, though.

Thursday, March 22, 12

Dialog windows

Collapses to single column

Shows an action menu button

These layout elements are used for the “back” of cards, for user pages, and elsewhere.

Thursday, March 22, 12

Touch fallbacks

Would normally show up on hover on desktop.Always visible on mobile.

Thursday, March 22, 12

Icons

Thursday, March 22, 12

Sprite your icons.

Thursday, March 22, 12

We use Illustrator for icons so we can easily export high-res versions.

We load them with CSS media queries for high DPI devices like the iPhone 4 and the third-gen iPad.

Thursday, March 22, 12

.app-icon { background-image: embed(../images/icons-1x.png); background-position: -9999px -9999px; &.board-icon { background-position: -60px -30px; }}

@media screen and (-webkit-min-device-pixel-ratio: 1.5), screen and (-webkit-min-device-pixel-ratio: 2) { .app-icon { background-image: url(../images/icons-2x.png); background-size: 690px 144px; }}

The CSS looks like this... Our compiler embeds an inline base64 encoded datauri of the

image. One less request.

This image is 1380x288 (2x), but we use the 1x background-size so all the icon-specific

background-positions line up.

(This is LESS.)

Thursday, March 22, 12

Detecting Window Width

Thursday, March 22, 12

We listen for window resizes with JavaScript and add an appropriate class to the body element.

CSS takes care of everything else.

Thursday, March 22, 12

window.WindowSize = new class

calc: => width = $(window).width()

@fExtraLarge = @fLarge = @fMedium = @fSmall = @fExtraSmall = false

if width > 1280 @fExtraLarge = true else if width > 850 @fLarge = true else if width > 700 @fMedium = true else if width > 500 @fSmall = true else @fExtraSmall = true

$("body") .toggleClass("extra-large-window", @fExtraLarge) .toggleClass("large-window", @fLarge) .toggleClass("medium-window", @fMedium) .toggleClass("small-window", @fSmall) .toggleClass("extra-small-window", @fExtraSmall)

The code looks like this...

(This is CoffeeScript.)

Thursday, March 22, 12

body.extra-small-window body.large-window

For example...

Thursday, March 22, 12

if WindowSize.fLarge or WindowSize.fExtraLarge renderHugeThing()

This method gives us an easy way to check the window size in view code.

We also have a Browser.isTouch() method to selectively load components.

Thursday, March 22, 12

Views

Thursday, March 22, 12

We use Backbone for views. It makes views straightforward and keeps code flexible.

Thursday, March 22, 12

class CardView extends ViewWithId

className: "list-card"

events: "click .js-card-menu": "openCardMenu" render: => data = cardModel.toJSON()

$(@el).html( Mustache.to_html( templates.card_in_list, data ) )

openCardMenu: (e) => Util.stop(e) PopOver.toggle elem: e.target top: 23 view: cardModel.getView(CardMenuView)

A view look like this...

Thursday, March 22, 12

class CardMenuView extends EditableView

events: "click .js-change-members": "changeMembers" "click .js-edit-labels": "editLabels" "click .js-move-card": "moveCard" "click .js-due-date": "changeDueDate" "click .js-vote": "vote" "click .js-close-card": "close" render: => data = {foo: ‘bar’} $(@el).html( Mustache.to_html( templates.popover_card_menu, data ) )

changeMembers: (e) => Util.stop(e) PopOver.pushView view: model.getView(CardMemberSelectView)

# ... editLabels(), moveCard(), etc.

...and this.

Push another view (select members) onto the stack. PopOver will load the view and handle transitions.

Thursday, March 22, 12

Templates

Thursday, March 22, 12

We use Mustache for templates.They are strictly logic-less, which keeps code clean.

Thursday, March 22, 12

card_in_list.html-----------------

<div class="card-labels clearfix"> {{#labels}} {{#isActive}} <div class="card-label {{color}}-label"> </div> {{/isActive}} {{/labels}}</div>{{#__ed}} <span class="card-operation app-icon dark-hover small-icon menu-icon js-card-menu"></span>{{/__ed}}<a href="{{url}}" class="list-card-title clear"><span class="card-short-id hide">#{{idShort}} </span>{{name}}</a><div class="badges"></div><div class="list-card-members"></div>

Templates look like this...

Note: The view wraps this with an element with class View.className, in this case ‘.list-card’. Make good use

of className so you don’t end up with useless divs.

Dynamically loaded elsewhere in the view

Thursday, March 22, 12

top related