Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Incremental Design: A conversation with a desig...

Incremental Design: A conversation with a designer and a developer

Developers: how many times have you had to completely rip out your hard earned code for a totally new site design?
Designers: how many times has a re-design taken 4 times as long as the developer said it would and not looked good in the end?
Change all that by using an incremental approach to design. Set up your code to change all the buttons at once or prioritize design changes to make each small change good enough for production.
A designer and developer will talk about the challenges and joys of making this process work in two production sites.

Given at RailsConf 2013 4/29/13

Rebecca Miller-Webster

April 29, 2013
Tweet

More Decks by Rebecca Miller-Webster

Other Decks in Programming

Transcript

  1. @rmillerwebster REBECCA MILLER-WEBSTER SAVANNAH WOLF Ruby & Javascript Developer Lead

    Developer UX & Visual Designer Head of Design #incrementaldesign @savwolf Monday, April 29, 13
  2. Major Redesign? HOW DO YOU MAKE DESIGN CHANGES? Page by

    Page? Incremental Design! Monday, April 29, 13
  3. css. GENERATE .upgrade{ @extend .container; @extend .clearfix; margin-bottom: $thickUnit; width:

    $grid30; > header { @include trailer(2); @include bevelledSeperator; > h1 { @include serif; } } Monday, April 29, 13
  4. Variables ARE YOUR FRIEND $extra-small-font-size:11px; $small-font-size:13px; $medium-font-size:18px; $medium-large-font-size:23px; $large-font-size:27px; $extra-large-font-size:34px;

    $extra-extra-large-font-size:41px; $huge-large-font-size:51px; //Layout $defaultUnit:30px; $narrowUnit: $defaultUnit/3*2; $skinnyUnit: $defaultUnit/3; $thickUnit: $defaultUnit*2; $gridColumnWidth: $defaultUnit; Monday, April 29, 13
  5. Mixin IT UP. @mixin bevelledSeparator{ @include trailer(1); border-bottom: 1px solid

    rgba($darkBeige, .5); @include box-shadow(0 1px 0 #fff); } Monday, April 29, 13
  6. .pricing{ class: “#{offer.members_only ? ‘membersOnly’ : ‘’} #{additional_classes} “ -if

    offer.members_only -if offer.free_for_member? .price.free %strong Free Date %em for members only -else %strong.details Members %br Only %dl.price %dt.title Member %dd.value = “#{offer_member_price(offer, {unit_tag: ‘small’})}”.html_safe -else %strong.details Save %br #{saving_percentage(offer)} %dl.price %dt.title Member %dd.value = “#{offer_member_price(offer, {unit_tag: ‘small’})}”.html_safe %dl.price %dt.title Standard %dd.value = “#{offer_non_member_price(offer, {unit_tag: ‘small’})}”.html_safe get logic out of your views WHAT THE !#*K IS GOING ON?! Monday, April 29, 13
  7. 41 LINES of CODE .pricing{ class: “#{offer.members_only ? ‘membersOnly’ :

    ‘’} #{additional_classes} “ } -if offer.members_only -if offer.free_for_member? .price.free %strong Free Date %em for members only -else %strong.details Members %br Only %dl.price %dt.title Member %dd.value = “#{offer_member_price(offer, {unit_tag: ‘small’})}”.html_safe -else %strong.details Save %br #{saving_percentage(offer)} %dl.price %dt.title Member %dd.value = “#{offer_member_price(offer, {unit_tag: ‘small’})}”.html_safe %dl.price %dt.title Standard %dd.value = “#{offer_non_member_price(offer, {unit_tag: ‘small’})}”.html_safe .footer{ class: “#{‘darkSeparatorTop’ if add_separator}” } -if offer.booked?(offer) %strong.booked Booked -elsif offer.expired? %strong.expired =t(‘.expired’) -elsif offer.sold_out? %strong.sold_out =t(‘offers.offer.sold_out’) } Monday, April 29, 13
  8. 5 lines DOWN TO .pricing{ class: offer.price_classes } %strong.priceDetails= offer.price_details

    = offer.price_definition %footer{ class: offer.price_classes } = offer.status_tag Monday, April 29, 13
  9. classes. GENERATE def pricing_classes classes = classes << ‘membersOnly’ if

    member_only classes << (free_for_member? ? ‘free’ : ‘paid’) classes << ‘unavailable’ if !bookable? || h.offer_booked?(self) classes << ‘nonMembers‘ if !members_only && non_member_price > 0 classes.join(‘ ’) end Monday, April 29, 13
  10. copy GENERATE def pricing_details str - “” if members_only &&

    free_for_member? str = “Free Date <br/><em>for members only</em>” elsif members_only str = “Members <br/>Only” else str = “Save <br/>#{h.saving_percentage(self)}” end str.html_safe end def booking_form_attributes attrs = { url: h.offer_booking_path(self,secure: true), html: {id: ‘new_booking’ } } if h.current_user.has_booked_this_month? attrs[:html][:class] = ‘track_submit’ attrs[:html][:”data-event-name”] = “submit: upsell” end attrs end html attributes & Monday, April 29, 13
  11. Encapsulate REPETITION INTO Partials def pricing_definition unless free_for_member? && members_only

    (text = “”) << h.render(partial: ‘shared/offer_pricing_dl’, locals: {offer: self, member: true }) if !members_only text << h.render(partial: ‘shared/offer_pricing_dl’, locals: { offer: self, member: false}) end text.html_safe end end Monday, April 29, 13