zumba-small

We partnered with Zumba Fitness to help with the front-end development of their new responsive website’s home, shop, user authentication and checkout pages. They provided great looking mocks and guidelines and worked closely with our team throughout the project’s life cycle. The most notable requirement was their desire to use the Foundation responsive framework from Zurb.

We don’t typically use responsive frameworks so fitting Foundation into our workflow was a challenge at first, but ultimately turned out for the best.

Below are some of the more unique solutions we provided.

Utilizing Foundation

As mentioned above, the use of the Foundation framework was a bit new for us, but we quickly came to realize its full potential and put it to good use. One of our goals at the beginning of the project was to utilize as many modules and features of Foundation as we possibly could. It’s easy to write new CSS selectors without thinking about the vast options available in Foundation, so coming in with the mindset of making sure we were using as much of Foundation as possible really helped the project in the long run.

Grid

The most-used Foundation feature of the Zumba redesign was definitely the grid layout. Our approach was simple: use grid classes for layout and custom classes for style. The Foundation grid allowed us to keep our presentational styles separate from the layout styles, in a somewhat Object Oriented CSS approach.

Developing with the grid simply came down to the use of rows and columns. A .row element most always contained .columns elements. The .columns elements’ widths were then defined by using another Foundation class. Foundation’s “width” classes tie in directly with a global media query settings file, so adding the classes small-12 medium-8 large-6 to an element would position it full-width at small the breakpoint (the grid is composed of 12 columns), 2/3-width at the medium breakpoint, and half-width at the large breakpoint.

Off-canvas

On small screen sizes, the main navigation is tucked away in an off-canvas menu. Same with the shopping bag, although it’s triggered by clicking or tapping a shopping bag icon at all screen sizes. Initiating this off-canvas functionality was one of the easiest integrations that, although looks complicated, came down to simple markup structure and data attributes.

The structure for two off-canvas menus (left and right) looked something like this:

[html] <div class="off-canvas-wrap">
<div class="inner-wrap">
<aside class="left-off-canvas-menu">…</aside>
<a class="left-off-canvas-toggle hide-for-large-up" href="#">Navigation</a>
<a class="right-off-canvas-toggle hide-for-large-up" href="#">Shopping bag</a>

<aside class="right-off-canvas-menu">…</aside>
</div>
</div>
[/html]

As long as everything on the page lived inside the .inner-wrap element, it would seamlessly slide open and closed. No JavaScript writing required.

Dropdowns

Another Foundation component we utilized was the dropdown. Like the off-canvas component, dropdowns were instantiated by simple data attributes as well.

[html] <a href="#">Trigger</a>

<ul id="drop1" class="f-dropdown">
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
<li><a href="#">Item</a></li>
</ul>
[/html] Using Foundation allowed us to quickly create dropdowns with custom properties like opening on click instead of hover. The downfall to this component was how Foundation positioned the dropdowns absolutely on the page using inline styles detected by JavaScript. Definitely not ideal, but with our decision to stick closely to Foundation we let it slide.

Interchange responsive content

There are several areas in the site with photos that underwent quite the shift in size from small screens to large. Rather than displaying a large image on small screens (a bad performance decision), we utilized Foundation’s Interchange, which dynamically loads content based on media queries.

The markup for dynamically loading images based on media queries uses the same high level logic as the Picturefill polyfill. You just pass in what path at what media query.

Form validation

Client-side form validation was accomplished using Foundation’s HTML5 form validation library Abide. Setting up validation on forms is as simple as adding the data-abide attribute to the form element and then using the required attribute on the fields that need validation. Abide also comes with “patterns” that you can add to fields for more customized validation on special input types for credit card, email, date, color and more.

Media queries

We stuck pretty closely to the way Foundation handles mobil-first media queries. In a Foundation project, there is a _settings.scss file that contains all the default variables and mixins (commented out) for the framework. To override these, you just have to uncomment the declaration and add your own values. This is what we did with the media queries.

Foundation comes with three media queries: small, medium and large. As the project progressed we found the need to not only modify those values, but to add more breakpoints as well. We ended up with seven media query variables that could be used in both the CSS and the HTML classes. For instance, a variable called $large-range with a value of 64em, 67.9375em); could be used in the CSS via a mixin: @media #{$large-up} {…}. It could also be used as a class on an HTML element: <div class="“show-for-large-up”">…</div>. This approach to breakpoints and media queries really saved a lot of time and made for good organization of our breakpoints.

It should also be noted that the way we came up with the breakpoint values correlated directly to how the content behaved. If a module on the screen was getting too tight and looked uncomfortable, we’d first check to find the nearest breakpoint variable we had available. If none were close, we added new ones where it made sense (hence, our seven total breakpoints).

Modals

Zumba requested that modals be treated differently on mobile than on tablet and desktop sizes. On tablet and desktop, the modal is superimposed over the page and the content underneath is dimmed. However, on mobile, the page content needed to disappear and the modal would be shown instead.

To accomplish this, we utilized mediaCheck from Sparkbox to detect the viewport size and also added an active-modal class on the body tag when the modal was open.

After that, we simply utilized both the bp-small class that is added to the body on small viewports and active-modal to hide the page content with CSS when the modal was open.

Sticky

A few similar requirements we had to tackle were the sticky header, sticky sidebar on the shop pages, and the sticky “Find a Class” module on the home page. In these instances we made use of the mediaCheck classes we set up to check the current viewport width. We used JavaScript to add the proper class or inline CSS.

In the case of the header, it only needed to be sticky at the largest breakpoint. With JavaScript, we checked if the user has scrolled past the header, if so, and if the body has the bp-large class then the header gets the class of sticky. If the user scrolls back up, the sticky class is removed.

The shop sidebar worked the same way except we had to stop it at some point so it did not break out of its parent when scrolling down. This was done by checking the user’s scroll position, the sidebar height, and where the bottom of the parent is on the page. Using some simple subtraction we determined when the sidebar should stop scrolling (which can vary depending on page-height and the user’s viewport width).

The “Find a Class” module was a little different. It needed to stick to the bottom of the page instead of the top, and only if the user is scrolled above the module. Even though it was different the JavaScript here was very similar. We checked for the appropriate breakpoint, checked to see if the user was above the module, and applied the inline style. Additionally, we measured the module title for use in the inline style, since it was the only part that should be shown when it’s stuck to the bottom and we checked the original position of the module. That way we know when to remove the inline styles so the module seems to fall into place as the user scrolls down the home page.

Quick shopping

To make online shopping quicker and easier for users, Zumba redesigned the “quick shop” components that are displayed on the home and shop pages. Hovering over a product reveals an alternate image along with a shopping bag icon. Clicking the icon then triggers the quick shop module to be shown (replacing the previous image). From here, a user can quickly select their size and options and add it to their bag.

The development of this was pretty straightforward on desktop devices. We used FlexSlider for the products on the shop pages to slide through the different color swatches and simple JavaScript click events to toggle an “open” class when the bag icon is clicked. The behavior on touch devices went through a few revisions, but the ultimate decision was to disable the swiping and quick shop functionality altogether.

Responsive videos

A prominent component on the home page is the large slider that plays videos in some of the slides. Making these videos respond fluidly was a bit tricky, but the fact that Zumba needed the ability to display a video from three sources at any given time was made it really tricky. The three sources were YouTube, Ooyala and static video files. To add to the responsive aspect, we were given custom player designs for the video skin.

The solution we settled on was VideoJS for static and YouTube videos, and Ooyala’s API and player for Ooyala videos. By utilizing VideoJS methods like play and stop, we were able to control the video on a more custom level than if we had just embedded, say, a YouTube video.

To actually make the videos responsive, we utilized a little positioning and padding trick, to create an “intrinsic ratio”. Essentially, the video element itself is positioned absolute with a top value of 0. Then the container encompassing the video element is positioned relative with a padding-top equivalent to the height of the slider. The padding-top value changes at a few breakpoints, as it starts out percentage-based on small screens until it reaches the largest breakpoint with a fixed height for the slider. At that point, the padding-top becomes a hard em value. The logic behind this approach is that the percentage used for the padding makes the height of the container equal to that percentage of its width, thus keeping a consistent aspect ratio.

Playing nice with IE8

Foundation dropped support for IE8 in version 5, the version we used for the Zumba site. However, Zumba still has a solid business case for supporting IE8, as many online purchases from their customers come from the outdated browser. This meant that a lot of the core functionality of Foundation fell flat in IE8 and we had to provide fallbacks and fixes to make it as user friendly as possible.

Since IE8 does not know what media queries are and Foundation is built mobile first, the first thing we did was add Respond.js as a polyfill for media queries. Next, we included Modernizr and used the classes it outputs on the html tag to add special fixes for IE8 (only when absolutely necessary) and provide fallbacks for browsers that don’t support SVG and other modern browser technologies.

Another issue that arose was Foundation’s use of double colon pseudo class selectors. IE8, does not support the double colon syntax, so we used the single colon syntax to satisfy IE on our custom classes.

Lastly, since we used Foundation’s Interchange responsive content in several areas, we had to provide a fallback since it’s not supported in IE8. The fallback, at least for responsive images, was rather simple: declare a default image src.

Knowing when enough Foundation is enough

Foundation has great features like the grid, Interchange, off canvas and more. However, because Foundation is opinionated, it can also be difficult to modify behavior — specifically JavaScript-based — for a custom experience. One example of these difficulties involved “Orbit”: Foundation’s responsive image slider.

Orbit easily takes a group of images, builds a slider out of them, optionally adds pagination, and is fully responsive. However, Zumba wanted a more custom slider experience than Foundation could offer.

The first problem with Orbit is it does not support Internet Explorer 8, Safari 6, and iOS 6. We tried to fix the compatibility issues, but many of the issues could be traced to the very core of Orbit. Adding missing browser support was getting cumbersome.

Another problem with Orbit was creating links within slides. Orbit’s touch events hijack the ability to interact with the slides content. If a slide contained a link to another page, a user could not tap the slide and be redirected.

Adding these hacks did not help us make Orbit fit Zumba’s needs. We discussed these issues with the client and decided to swap Orbit completely with Flexslider. Flexslider gave us the customization and browser support we needed without adding hacks to make the old solution work.

An important part of using a framework is to know what limitations it has. You may be creating more work by forcing functionality that was never intended to exist. Knowing the framework is just as important as actually using it.