Jordan Lewis

Making the Envato Marketplaces Responsive

The first Envato Marketplace was started in 2006 (and 7 others have followed since then) and now we’re a good sized online business with a lot of traffic (well over 100m page views per month). Over the same period the mobile revolution has and continues to happen and like many other online businesses we want the user experience of our sites to be far better on mobile devices by making them responsive.

While broadly this is not a unique challenge, we do have some nuances that we think make us a little bit different. In addition to a fairly large and evolving code base, some of the key pages on our sites like our item page (the equivalent of a product page on a typical e-commerce site and thus super important for conversion) are based around user generated content and assets.

Although we are a while off being fully responsive I’d like to share our journey and some solutions we have developed to progressively convert the Marketplaces to be responsive.


Where to begin?

“A journey of a thousand miles began with a single step” - Lao Tzu

Our first goal was to take one page and make it responsive. We decided to build a new comments dashboard page as there was demand from authors wanting an easy way to manage comments on mobile devices, plus we could limit this new page to beta access.

At first this may not sound like a few months worth of work, but in order to make one page responsive it required a complete re-think and re-engineering of our entire front-end.

Another important decision we made was to adopt a mobile-first approach. The added complexity of converting a legacy grid-less website to be mobile-first is mind boggling as there is a long period of time that most pages are a hybrid.

“Mobile first means designing an online experience for mobile before designing it for the desktop Web — or any other device”

With all this in mind we sat down and identified the all the key tasks required to meet our goal:

  • Build a switch to limit which pages are responsive
  • Select a mobile-first grid framework
  • Serve separate CSS for responsive pages
  • Conditional media-queries to force desktop styles on non-responsive pages
  • Complete re-build header with off-canvas nav for mobile devices
  • Complete re-build of footer
  • Build responsive modules
  • Build and launch first responsive page

Responsive switch

We prefer to release smaller features in quick cycles, so building a new responsive front-end from the ground up wasn’t an option. So whenever we are updating a page or module we are making sure that we are coding it to be responsive even though we may not enable the responsiveness for a while.

The ‘switch’ is actually a very simple variable in each page’s controller which looks a little something like this:

1
2
3
def show
  @responsive = true
end

Using this approach we are able to enable the switch based on conditions such as environment, page, feature-flip, user roles, A-B testing etc.

Although we can set individual pages to be responsive like the comments dashboard or envatomarketplaces.com, the reality is for UX and browsing consistency the Marketplaces will go responsive by flipping a switch when every page has been converted.


Choosing a grid framework

Deciding on an appropriate grid framework was our first big decision. We needed a mobile-first grid framework without all the extra bells and whistles like Bootstrap or Zurb Foundation.

After reviewing lots of grids we settled on Susy as it best met our needs:

  • Pure grid framework
  • Grids applied with mixins (no grid classes required in HTML)
  • Highly configurable
  • Works with Rails + Compass
  • Written with Sass
  • IE7+ compatibility (legacy fallback is desktop version)
  • Can change grid columns at different breakpoints
  • Actively developed and maintained

Conditional CSS

Leveraging our responsive switch we serve up different CSS files depending if the page has the responsive switch enabled or not. Until the site goes fully responsive, users will only download the one CSS file in most cases.

layouts/application.html.erb
1
2
3
4
5
6
<%= if @responsive %>
  <link href="application-responsive.css" rel="stylesheet" />
  <meta name="viewport" content="width=device-width,initial-scale=1">
<% else %>
  <link href="application.css" rel="stylesheet" />
<% end %>

The responsive and non-responsive style sheets are generated from the same Sass files and the only difference is that the responsive version has a variable set in the config to enable media-queries.

application-responsive.sass
1
2
$responsive: true
@import 'application.sass'

Conditional media-queries

In order to progressively adopt a mobile-first approach we needed the ability to compile both the desktop style sheets (no media-queries) and the responsive style sheets (with media-queries) from the same Sass files. After a bit of head scratching we achieved this using Susy’s powerful inbuilt helpers.

Susy is a fantastic responsive grid framework and it gives you a lot of magic out of the box with the ability for advanced configuration.

“Susy provides the power-tools, what you build is up to you.”

We rely on Susy’s at-breakpoint Sass mixin to handle all our media-queries and as an added bonus this allows us to take advantage of it’s $ie-fallback feature.

Although it’s called $ie-fallback this feature allows us to remove any media-query applied with the at-breakpoint mixin if the <html> has a certain class. This essentially allows us to force render the desktop version of any page on any browser or device.

In our case we use our switch to set a class of fixed-layout on the <html> when the responsive switch is enabled or for legacy browsers (< IE9).

1
2
<!--[if lte IE 8]> <html class="lt-ie9 fixed-layout"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="<%= 'fixed-layout' unless @responsive %>"> <!--<![endif]-->

Example Sass module

module.sass
1
2
3
4
5
6
7
8
9
10
11
.module
  // Mobile default
  background-color: red

  // Tablet
  +at-breakpoint($tablet-only)
    background-color: green

  // Desktop
  +at-breakpoint($desktop-and-above)
    background-color: blue

Output

application-responsive.css
1
2
3
4
5
6
7
8
9
.module { background-color: red; }

@media (min-width: 569px) and (max-width: 1024px) {
  .module { background-color: green; }
}

@media (min-width: 1025px) {
  .module { background-color: blue; }
}
application.css
1
2
3
4
5
6
7
.module { background-color: red; }

.fixed-layout .module { background-color: green; }

.fixed-layout .module { background-color: blue; }

 /* With breakpoints removed the desktop style (background-color: blue) will take precedence */

The drawbacks of this approach is that we still use a couple of media-queries on our desktop version which we want to keep, but this can be overcome by using raw media-queries rather than Susy’s mixins as they will remain untouched.

Ben Smithett has done a great job isolating our base Marketplace styles (minus responsive switch) into an open source github repo if you would like to look under the hood.


Rebuild header with off-canvas nav

The header is by far the most complex module we have in the Marketplaces as by it’s nature it is built to adapt to multiple user types and ten site variations with unique navigation scenarios. Rebuilding the header was our biggest challenge and therefore what we focussed most of our attention on to get right.

We purposely built the new header to look identical to the existing version, and since then we have been continually refining the design as part of a bigger site-wide visual refresh.

It’s very obvious there is a lot of navigation going on in the header and we knew pretty much straight away that we needed to implement an off-canvas nav that would allow easy navigation on a mobile device. We first prototyped an off-canvas nav in a Middleman app before bringing it across into the main Rails application. Whilst prototyping the off-canvas nav we ran into many browser edge-cases related to animation issues and in the end decided to opt for no sliding transitions.

We initially tried to reflow the navigation for the off-canvas version, but this proved to be an unmaintainable nightmare which would hinder any future updates. So on responsive pages we decided that outputting the navigation twice in different locations would be a good trade-off. We then use basic Javascript to toggle the classes for the active nav and let CSS do all the positioning and styling work.

Also currently in development we are trialling the use of the off-canvas nav to replace modals at certain breakpoints. This allows us to overcome all issues relating to modals on mobile devices and not to mention is much better for the user experience. I will go into more depth on our solution for conditional modals in another blog post soon.

Envato Marketplaces off-canvas navigation


Rebuild the footer

The footer was relatively straightforward to convert and because of this we ended up leaving it until last as we were able to do everything on our list without it.

Like the header, the mobile version is a completely new design and only the most important information is visible. Thanks to our modular approach we are able to serve a slightly different version for envatomarketplaces.com.


Responsive modules

A responsive module is coded to work anywhere and doesn’t care about or inherit styles from it’s parent container. At most, the parent container controls the position and dimensions of where the module will be used.

The header and footer are examples of some very complex responsive modules and in fact most of our site is broken up into much simpler self-contained modules which are designed to be used anywhere and adapt to any breakpoint.

A great example of a responsive module is the pagination module. On desktop there is room to display the first, last, next, previous and surrounding page numbers, however as we are restricted for space on smaller screens we just display the next, previous and a summary.

This module is used on many pages but is currently only responsive on pages that contain the responsive switch, such as the comments dashboard.

Responsive navigation module


Putting it all together

After re-engineering our front-end codebase and then creating all the responsive elements we needed we were finally able to assemble the first fully responsive page on the Marketplaces.

All along the way we did extensive browser and device testing which I wrote a whole article on - ‘Techniques for mobile and responsive cross-browser testing’.

Once we were ready we invited a group of authors to beta test the new comments dashboard page and provide feedback. We incorporated much of this feedback to improve the page and mobile experience.

Along our journey there were many other mobile best-practices which we also took the opportunity to address:

  • Icon fonts
  • Hi-res logos for retina
  • SVGs
  • Living style-guide
  • Reduced background sprites usage

Ongoing Challenges

One of the biggest challenges we still face in delivering an optimised responsive experience is how we present the generated user content. Most authors have image-heavy item and portfolio pages and a lot of these images are text-heavy and when resized to fit in a mobile view-port the text becomes illegible. We have a couple of ideas on how we tackle this, but we’re still working through this difficult problem.


Conclusion

Currently the Envato Marketplaces’ are 7 years old, and as we work on new and existing features we are taking every opportunity to bring the front-end code inline with our modern coding practices. In most cases this is a complete rebuild of a module’s HTML and CSS.

While we are still a while off making every page responsive the hard work going towards this goal is having massive benefits straight away. As we progressively update, modularize and responsify our front-end code we are freeing ourselves from any legacy front-end constraints, enabling us to ship new features and design changes much quicker, and eventually a mobile friendly Envato Marketplaces.