LayerVault Simple version control for designers. Try it free.

Implementing Progressive Reduction

After writing about Progressive Reduction for the first time on Tuesday, much of the feedback centers around “it’s too complicated.” For many, Progressive Reduction doesn’t work if you didn’t start off by building a minimal interface in the first place. This post will talk about how we took the idea of PR and turned it into code.

Backend

We build the LayerVault site in Rails with a smattering of NodeJS components. Ruby is a great expressive language, and Rails makes building web applications a cinch. The two in tandem help fit a complicated idea like Progressive Reduction into a few lines of code.

There are two components to the backend: the determining of the levels of each user for each feature and the coordination of that information in the view.

First, the model. We use an ActiveRecord::Concern to mix in the functionality to our main User class. Here’s the file:

module UserLevels
  extend ActiveSupport::Concern
  included do
    def signposting_level
      signpost_count = Signpost
        .where(user_id: self.id)
        .where('created_at > ?', 3.months.ago)
        .count

      return 3 if signpost_count > 60
      return 2 if signpost_count > 30

      1
    end

    def signposting_level_class
      "SignpostLevel#{signposting_level}"
    end

    # ... More levels and classes
  end
end

Each class is then attached to the body element of each page. We use the content_tag in ERB for this:

<%= content_tag(:body, {
  class: [
    current_user.signposting_level_class
  ]
} %>
  <%# The rest of the page %>
<% end %>

The View

From here, it’s just an exercise in HTML and CSS. But we’re grownups and use SCSS, which makes something like this even sweeter.

First the HTML:

<div id="TimelineSignpostButton" class="TimelineButton">
  <span class="ButtonIcon">Signpost</span>
</div>

Next, a selection of the SCSS to get an idea:

#TimelineSignpostButton {
  .TimelineButton {
    text-indent: 60px; // Allows label text to be hidden when button shrinks
  }

  .SignpostLevel1 &.TimelineButton {
    width: 116px; // Wide button with label
  }

  .SignpostLevel1 &.TimelineButton,
  .SignpostLevel2 &.TimelineButton {
    background: $official_white image-url('signpost-dark.svg');
    background-size: 24px 24px;
  }

  .SignpostLevel2 &.TimelineButton,
  .SignpostLevel3 &.TimelineButton {
    width: 60px; // Smaller button hides the label
  }

  .SignpostLevel3 &.TimelineButton {
    background: image-url('signpost-light.svg') no-repeat 8px 6px;
    background-size: 24px 24px;
  }
}

And that about wraps it up. Our Timeline is self-contained and clutter-free, so we don’t have to worry about elements clashing or overlapping with each other.

Implementing Progressive Reduction is the coordination of many small parts in a sensible manner. It starts with a simple design and yields itself as a simple implementation in the Model and View layers.

Not so bad, is it?

  1. felipeonate reblogged this from layervault
  2. gameraboy reblogged this from layervault and added:
    Followup to the interesting Progressive Reduction post
  3. iodic reblogged this from layervault
  4. webhazard reblogged this from layervault
  5. aboutaaaron reblogged this from layervault
  6. noxdzine reblogged this from layervault and added:
    After writing about Progressive Reduction for the first time on Tuesday, much of the feedback centers around “it’s too...
  7. brentg reblogged this from layervault
  8. layervault posted this