An improved user interface for FiNC’s eCommerce site

Saad Gul
FiNC Tech Blog
Published in
11 min readJun 15, 2017

FiNC eCommerce site FiNC Mall is part of our company’s focus on making health and wellness accessible to everyone. As a startup, we experiment with various ideas and Mall was an inspirational idea to turn a fuzzy world of health into a tangible (and saleable) concept. The idea was to sell unique products that literally define health and wellness: Genetic tests, customized supplements, fasting drinks based on unique fasting plans, etc. Our own dietitians, pharmacists and exercise professionals select products to address a range of our users’ needs.This all started sometime in later half of 2015 as a shopping site accessible to only FiNC’s customers. In September 2016 we opened the site up to the entire internet, making it possible for users without a FiNC account to make purchases.

From pond to the ocean

But we wanted to expand and in Nov, 2016 we opened the mall to the public. Now anyone could buy from the mall and we expected people ‘lining out on the streets’ to buy our products (some of our discounts were great). But the fanfare never really came. Our selected products started collecting dust instead of being stars of the company. Our first solution was to add more products, specialized but not ours. This worked somewhat but not to the extent we wanted. We subsequently tried various solutions from coupons and special offers to improved checkout experience. And of course marketing was relentless.

If its perfect, it might not sell, but if its not perfect, it definitely won’t sell

With a bit more experience, our team has turned its focus on a better User experience coupled with a very nice user interface. And this is complemented with a more robust system so that there are no long shipping delays or lost shipments or confusion about what is going on. Running a shop means lots of confusion but keeping it to manageable levels is essential. I believe that we have finally hit the right tune with our store. Working out a few kinks will put us within reach of obtaining new height on how to sell good wellness solutions.

I have divided my discussion into 2 parts: building the UI improvements and evaluating the impact of this new UI. This current story is about how we build the UI improvements using Javascript, CSS and the nuts & bolts used to get everything working. I will be talking about Bootstrap and how we made the layout of our page to give its awesome look in line with modern shopping sites.

In the next part of the story, I want to critically look at our design decisions and whether they made any effect or not on user behavior. That is, did our visitors get that twitch to just press that beautiful, red button inviting them to a short period of unearthly happiness? If not, then finding the reasons are also important as our user’s buying habit may have nothing to do with user interface.

Ugly outside beautiful inside

Our first product page was less than stellar. In fact it seemed down-right ugly. Don’t believe me? Have a look yourself:

Mall’s old product page
The variant selection user interface in the old product page

But inside all its ugliness there was something beautiful: A simple and intuitive interface. Anyone could understand and use the interface, even if they did not like it.

Our idea was that if a user liked a product, having an acceptable selection process would not hamper the person from buying the product. This was true for most part, especially for users who were familiar with us or were coming from our mobile application. But we want large number of new users and these have to come through channels where they will have little idea of FiNC or FiNC mall. One look at our site and they might run away. We want them to stay, so this is what we have now:

Example view of our site (https://mall.finc.com). We don’t sell fresh fruits but they do look great in photos.

And it looks good. We still haven’t patted ourselves on the back yet. The page needs to go through further updates as we want the friendliest and easiest interface available to the user. That may be a few more redesigns later but for now users can happily shop through the various varieties of the product types (which we refer to as ‘variants’).

It is also useful to see other good examples of product pages. Amazon has interesting product pages but the one I really like is on Chain Reaction Cycle’s site. Both their pages are shown below:

Amazon’s rather busy product page but options are clearly presented (link to page)
Chain Reaction Cycle’s product list page includes multiple options with manageable clarity (link to page)
Chain Reaction Cycle’s product page trying hard to make sense of multiple options (link to page)

Amazon’s product page is full of information but they manage to reduce the number of selectable options on their page. Hence the different options stand out and are relatively easy to understand. On the other hand, Chain Reaction Cycle’s site shows various options directly on the product list page. For example color, spec options and availability are a click or less away. On the product page there are even more options but is presently nicely and never becomes a distraction.

Not every page needs to be a masterpiece

Amazon and Chain Reaction Cycle’s product pages are great not because they look beautiful but because they do not hamper the shopping experience. Variations can be difficult to handle, and good sites make the extra effort to keep the complexity in control. In our website, our team has tried to give a clean look to the product variations. At the same time, we have added some extra features while trying to avoid overwhelming the user or cause our own management team problems.

With the requirements out of the way, lets see how we build our site. We used Ruby on Rails with bootstrap with the following versions:

Rails: version 2.4.7.1

Ruby: version 2.3.1

Bootstrap: v4.0.0.alpha3

jQuery: 2.2.4

We use alpha version of Bootstrap which was the latest and greatest of the stable versions when we started but now needs update. I should point out that the version of jQuery or Bootstrap should not make much difference. Also, Ruby and Rails are not important as this story focuses on layout and Javascript.

Best masterpieces are other people’s hard work

Bootstrap covers a wide variety of uses and to help make sense of it all, also provides many examples. For our case, we relied mainly on the following example for inspiration. Compared with other code examples this one does checkbox beautifully.

Checkbox buttons in bootstrap as selectable images

There are other examples that uses radio button such as the one below (link here). It shows radio button acting as group of buttons and linked images.

Radio buttons as images. Only one image can be selected (here first one is selected)

Step1: Image as radio button

The idea is simple: hide the radio button inside a bootstrap button. The buttons in a group will now act as radio boxes.

HTML:

<div class=’form-group’ data-toggle=’buttons’>
<label class='btn btn-primary btn-sq-sm image-btn'>
<img class='img-thumb' src='http://image.jpg' alt='orange'>
<input type='radio', name='cart[item_property[variant_id]' id='45' value='45' class='variant-checkable'>
</label>
</div>

CSS:

.btn-sq-sm {
width: 50px;
height: 50px;
margin: 0;
text-align: center;
padding: 0;
margin-top: 3px;
margin-bottom: 3px;
margin-right: 1px;
background-color: #D8D8D8;
overflow: hidden;
}
.image-btn {
outline: none;
border: none;
line-height: 1.3rem;
}
.img-thumb {
display: inline;
text-align: center;
width: inherit;
height: inherit;
object-fit: cover;
}
.image-btn.active {
border: 2px outset #fe7082;
}

Thanks to bootstrap, all we really need to do is put an image tag inside the bootstrap button’s div tag. No javascript needed (hurray!). The buttons function perfectly as radio boxes and return the correct value when we submit the form.

There is some CSS magic going on. Fortunately most of it is optional and depends on layout. For our case, we are using a square button with fixed width and height. Margins are defined and border is not. When a button is selected, a border is added to it. The overall effect is quite pleasant. To see it in action, play around with the example is in JSFiddle:

https://jsfiddle.net/saadg/hwktvftm/

Many of the details are also explained very well in Bootstrap guide on buttons. I suggested reading through it when working on your own bootstrap buttons.

Some might notice that the image seems to move a little to the left when selected. This is due to the use of borders. I like this effect but I could have used CSS property ‘outline’ to keep the images intact (heads-up: outline causes problem when buttons are arranged in a grid).

Step2: Fallback to drop down input

For some cases we may not want to use images. Perhaps our designers may be on holiday, or this feature may be brand new and the team needs time to start using it. Whatever the reason, what we need is a fallback case: a drop down box. If variants do not have images (or any other property), they should no be displayed as a list inside drop down box.

HTML:

<div class=’form-group’ data-toggle=’buttons’>
<label class='btn btn-primary btn-sq-sm image-btn'>
<img class='img-thumb' src='http://image.jpg' alt='orange'>
<input type='radio', name='cart[item_property[variant_id]' id='45' value='45' class='variant-checkable'>
</label>
</div>

CSS

.dropdown-selectable-property {
margin-top: 3px;
margin-bottom: 3px;
margin-right: 1px;
}

Creating a drop down box is simple, however, we need to decide if all variants have image or not. If they do not have images, the drop down must be selected. Our code uses ERB (Rails) to implement this logic and render the page properly. A generalized version of our code is below.

<% all_variants_have_image = variant.properties.all? { |vp| vp.thumbnail_image.present? } %>
<% use_dropdown = !all_variants_have_image %>
<% if use_dropdown %>
<%= select_tag dropdown_input_name,
options_for_select(selectors_options_hash_name_id_pair),
class: 'dropdown-selectable-property' %>
<% else %>
<div class='form-group' data-toggle='buttons'>
<% selectors_options_hash_button_input_label.each_with_index do |selector_label, index| %>
<label class='btn btn-primary btn-sq-sm image-btn'>
<%= image_tag(selectors_options_hash_radio_button_tag_thumbnail[index],
class: 'img-thumb') %>
<%= radio_button_tag radio_button_tag_name,
selectors_options_hash_radio_button_tag_id[index],
false,
class: '',
data: selectors_options_hash_radio_button_tag_data[index] %>
</label>
<% end %>
</div>
<% end %>

We first test if all variants have image using a model class ‘properties’ associated with variant. This stores images for that property. If all variants for a product have image through property, we render the image buttons with image. Otherwise, we render the drop down input. The drop down input requires a name-ID hash that must be setup beforehand. For our case, this is the variant name and variant ID.

In the above code, we are now creating multiple buttons using a loop. This requires creating an array of image sources and array of radio button name-ID hash beforehand. These are then iterated over and used with each button.

Step3: Colored box or box with text as radio button

Our variant selection system only uses image for now but we also want to show short text and simple colors. There require different CSS classes to achieve the required look and feel.

HTML:

<div class=’form-group’ data-toggle=’buttons’>
<label class='btn btn-primary btn-sq-sm image-color-btn colored-button'>
<input type='radio', name='cart[item_property[variant_id]' id='45' value='45' class='variant-checkable'>
</label>
</div>
<div class=’form-group’ data-toggle=’buttons’>
<label class='btn btn-primary btn-sq-sm abbreviation-btn'>
OR
<input type='radio', name='cart[item_property[variant_id]' id='50' value='50' class='variant-checkable'>
</label>
</div>

CSS:

.abbreviation-btn {
border: 2px solid rgba(0,0,0,0.0);
line-height: 45px;
}
.abbreviation-btn.active {
border: 2px outset #fe7082;
background-color: #D8D8D8;
}
.btn:hover,
.btn:focus,
.btn:active:focus,
.btn.active:focus {
background-color: #D8D8D8;
}

The CSS class image-btn has been renamed to image-color-btn.

Javascript:

$(function() {
$(document).ready(function() {
$('.colored-button').each(function() {
updateSelectorBackground($(this), $(this).children('.variant-checkable'));
});
});
});
function updateSelectorBackground(parent_element, element) {
var color = element.data('color');
if (color != null) {
parent_element.css('background-color', color);
parent_element.removeClass('uncolored-button');
parent_element.addClass('colored-button');
}
}

Here things get interesting as we finally see the first usage of javascript. This could have been avoided by setting style=‘background-color: rgb(250,0,0);’ on the <label> tag. However, it is best to avoid setting style from HTML (or ERB code). Instead a little javascript with HTML5 data attributes helps us to achieve this goal. A demonstration of the code is here:

https://jsfiddle.net/saadg/wn5gshws/

The CSS classes can be fine tuned to match the desired behavior. Also, each CSS class is written separately, but could also be nested if any of the two SASS flavors is allowed.

Step4: Dynamically update text on selection change

The buttons themselves may not be explanation enough for what each variant stands for. We will also need some text. This text can be handled as a label and updated using javascript on a variant selection.

Details are in the jsfiddle example:

https://jsfiddle.net/saadg/L1zdLsju/

The first thing that might seem different is the level of nested tags. Variant selection tags are buried deep in a nest of tags. This is the result of creating a detailed layout for the product page. However, some tags may ¥be removed after refactor so please consider the example code as a sample and modify according.

To create the text that changes with variant selection, we first define a label inside a table. Table helps to keep text ordered and aligned without extra trouble. To change the text in the label, we must now depend on javascript and HMTL data tag. The text to show with each variant is saved in data attribute and then accessed from javascript onClick() function. This text is written to the associated label.

Step5: Updating image set on selection

Just as we have updated text related to a variant, we want to also update pictures of the variant. The difference is that the pictures can be more than one so we cannot use HTML5 attributes. Another strategy is to create images in appropriate div tag and hide them. This is used in the example:

https://jsfiddle.net/saadg/d6bLn333/

The code has gotten quite large but the results are quite nice. We have to capture button click event in Javascript. This will then allow us to hide some of the images and unhide ones related to the selected variant.

Step6: Ready to go!

Our page still does not look like the product page on FiNC Mall. However, we have covered most aspects on how to make the mall. Lets recap what we have achieved:

  1. Radio boxes as buttons
  2. Buttons with image, label or color
  3. Link text with each button. A button press should update the text
  4. Create images that can be selected (thumb) and link their selection with a single large-size image.
  5. Update the thumb and large image when the Radio box button is pressed

There are some things in FiNC Mall’s product page that I have not mentioned. Talking about these will make the discussion long. I hope these will not pose much of a problem when creating your own amazing page. Drop me a comment if someone wants to know how to implement them. I will list some of them here:

  1. Updating price on selection
  2. Adding a quantity selector with ‘+’ and ‘-’ button
  3. Variants to be grouped into another header (variant selector of a variant selector)
  4. Full layout of Mall’s product page

Hopefully I have given enough information to generate your own awesome pages.

A view of our actual site. The English version is a priority for us (main language is Japanese) but is still a little light on information.

A page from our actual site https://mall.finc.com

Related work:
https://stackoverflow.com/questions/17541614/use-image-instead-of-radio-button

NOTE: All images shown in product pages are taken from pixabay.com (except for jawbone) and are under public domain.

--

--