Timber

A faster and easier way to build Virto Commerce themes

Download Timber Theme

Latest build: v2.1.1View Source on GithubView Demo Store

Built for all devices

Develop on top of a responsive, mobile-first and flexible foundation.

Documented

All the basic liquid and templating tags, well documented for you.

Customizable

Add and remove components easily and build the store you want.

1.1 Who Is This For

Timber is a front-end framework which makes building Shopify themes quick and easy. It can be used by theme creators of any skill level for themes of any scope. Seasoned pros and newbies alike can benefit from the starter templates, liquid markup, modules, and CSS frameworks provided in Timber.


1.2 What is Included


1.3 Download Timber

Download Timber.zip v2.1.1 or clone the latest master branch from the GitHub repo:

git clone https://github.com/VirtoCommerce/Timber.git

Dev Notes

Timber tested and working in IE 8+, Safari, Chrome, Firefox, Opera, Safari IOS, Browser and Chrome Android.

Demo Store

The demo has fake products inserted so you can see what a populated site would look like. To see what your brand new site will look like when you install the theme, check out our empty store demo.


1.4 Theme Editing

Once you've downloaded your theme it's time to get it onto your store. Upload the zip to your-url.com/admin or use VS.NET to open and change theme. Either way, you can use your text editor of choice.


1.5 Sell Your Theme

You can sell your theme in Virto Commerce Apps Store.


2.1 Sass

Timber is built with Sass, but you don't have to know it to use it. The compiling is all done on the Shopify server, so edit the .scss.liquid file just as you would CSS and watch the magic happen on your site.


2.2 Breakpoints

Define your breakpoints once, and Sass handles the rest. All breakpoints are defined in the Breakpoint and Grid Variables section of timber.scss.liquid. Easily change, add, or remove the breakpoints and names to suit your needs. These are the default breakpoints:

  • Small: 480px
  • Medium: 768px
  • Large: 769px

$breakpoints is broken down into four lines, each a breakpoint: 'small', 'medium', 'medium-down', and 'large'. These are the names used in your classes to define each column width. A .grid__item div with a class of large--one-half will span 50% of its parent above 769px. Any screen size below that breakpoint will default to (mobile-first) 100%.

$viewportIncrement: 1px;

$small: 480px;
$medium: 768px;
$large: 769px;

$postSmall: $small + $viewportIncrement;
$preMedium: $medium - $viewportIncrement;
$preLarge: $large - $viewportIncrement;

/* The following are dependencies of csswizardry grid */
$breakpoints: (
  'small' '(max-width: #{$small})',
  'medium' '(min-width: #{$postSmall}) and (max-width: #{$medium})',
  'medium-down' '(max-width: #{$medium})',
  'large' '(min-width: #{$large})'
);

2.3 Grid

This grid is based on csswizardry grids, though with some slight modifications. Built with Sass, the grid is fully integrated into your timber.scss.liquid stylesheet and has no external dependencies. Helper classes are generated by custom functions added to default grid Sass. Class names are created based on the $breakpoints variable in timber.scss.liquid.

1

2.1

2.2

2.3

2.4

2.5

2.6

3.1

3.2

3.3

3.4

3.5

3.6

3.7

<div class="grid">

  <div class="grid__item">
    <p class="grid-demo">1</p>
  </div>

  <div class="grid__item">
    <div class="grid">

      <div class="grid__item large--one-half medium--one-third">
        <p class="grid-demo">2.1</p>
      </div>

      <div class="grid__item large--one-quarter medium--one-third">
        <p class="grid-demo">2.2</p>
      </div>

      <div class="grid__item large--one-quarter medium--one-third">
        <p class="grid-demo">2.3</p>
      </div>

      <div class="grid__item large--one-third medium--one-whole">
        <p class="grid-demo">2.4</p>
      </div>

      <div class="grid__item large--one-third medium--one-half small--one-half">
        <p class="grid-demo">2.5</p>
      </div>

      <div class="grid__item large--one-third medium--one-half small--one-half">
        <p class="grid-demo">2.6</p>
      </div>

    </div>
    // End sub grid
  </div>
  // End grid__item

  <div class="grid__item">
    <div class="grid">

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.1</p>
      </div>

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.2</p>
      </div>

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.3</p>
      </div>

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.4</p>
      </div>

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.5</p>
      </div>

      <div class="grid__item large--one-twelfth one-sixth small--one-third">
        <p class="grid-demo">3.6</p>
      </div>

      <div class="grid__item large--one-half one-whole">
        <p class="grid-demo">3.7</p>
      </div>

    </div>
    // End sub grid
  </div>
  // End grid__item

</div>
// End grid

Columns and Sub Grids

Each column — or .grid__item — should be a direct child of a .grid container. This grid is easily nestable. A .grid__item column can contain another .grid, which would consist of its own children. View the sub grid in Example 2 below.

Example 1: Two column grid

1.1

1.2

Example 2: Two column with sub grid

1.1

1.2

1.3

1.4

// Two column grid
<div class="grid">
  <div class="grid__item one-half">
    <p class="grid-demo">1.1</p>
  </div>
  <div class="grid__item one-half">
    <p class="grid-demo">1.2</p>
  </div>
</div>

// Two column with sub grid
<div class="grid">
  <div class="grid__item large--one-half">
    <p class="grid-demo">1.1</p>
  </div>
  <div class="grid__item large--one-half">
    <div class="grid">
      <div class="grid__item large--one-third">
        <p class="grid-demo">1.2</p>
      </div>
      <div class="grid__item large--one-third">
        <p class="grid-demo">1.3</p>
      </div>
      <div class="grid__item large--one-third">
        <p class="grid-demo">1.4</p>
      </div>
    </div>
  </div>
</div>

Class Names

  • A grid__item will default to a 100% width, a moblie-first approach
  • Class names use an easy to read variation of the BEM naming convention
  • Class name format: breakpoint--column-width - e.g. large--one-half

Grid Variations

You can make use of no-margin grids with grid--full.

Create custom alignments with push classes, push--large--one-third.

1.1

1.1

1.1

2.1

2.2

// No margin grid
<div class="grid--full">
  <div class="grid__item large--one-third">
    <p class="grid-demo">1.1</p>
  </div>
  <div class="grid__item large--one-third">
    <p class="grid-demo">1.2</p>
  </div>
  <div class="grid__item large--one-third">
    <p class="grid-demo">1.3</p>
  </div>
</div>

// Push classes
<div class="grid">
  <div class="grid__item large--one-half push--large--one-quarter">
    <p class="grid-demo">2.1</p>
  </div>
  <div class="grid__item large--one-quarter push--large--one-quarter">
    <p class="grid-demo">2.2</p>
  </div>
</div>
        

Silent Classes

If you don't know what silent classes are, you can ignore this section. The biggest point of contention for many grid systems is how many classes are required in your markup. With Sass, you can use silent classes to handle all .grid__item widths in your stylesheet.

Set $use-silent-classes to true in timber.scss.liquid, and use the following code to set the widths:

.foo {
  @extend %grid__item;
  @extend %small--one-half;
  @extend %large--one-quarter;
}

2.4 Helper Classes

Note: These helper classes use !important to override any previous styling.

Each breakpoint you define as part of $breakpoints in timber.scss will have helper classes with the same names generated. Let's work with our default breakpoints:

Small devices
<480px
Medium devices only
>481px & <768px
Medium and small devices
≤768px
Large devices
≥769px
.small--show Visible
.medium--show Visible
.medium-down--show Visible Visible Visible
.large--show Visible
.small--hide Hidden
.medium--hide Hidden
.medium-down--hide Hidden Hidden Hidden
.large--hide Hidden

Basic Text Alignment

Basic helper classes to align an elements text.

  • .text-left
  • .text-right
  • .text-center

Breakpoint-specific Text Alignment

Change text alignment at any breakpoint with the following class format:

  • .breakpoint + --text-left
  • .breakpoint + --text-right
  • .breakpoint + --text-center
<div class="large--text-center medium--text-right small--text-center">
  This will be center aligned on large devices, right aligned on medium-sized devices, and center aligned on small ones.
</div>
This will be center aligned on large devices, right aligned on medium-sized devices, and center aligned on small ones.

Basic Floats

  • .left
  • .right

Breakpoint-specific Floats

  • .breakpoint + --left
  • .breakpoint + --right
<div class="large--right">
  This will float right on large screens, and not at all at other breakpoints.
</div>
This will float right on large screens, and not at all at other breakpoints.

2.5 Sass Mixins

Shopify liquid files don't support @import. This means you can't rely on helpers like Compass or Bourbon. Instead, there is a section called Sass Mixins in timber.scss.liquid that provides a few of these helpers that you may be looking for.

Breakpoint Mixin

Mixin based on: http://blog.grayghostvisuals.com/sass/sass-media-query-mixin/

Note: Standard media queries will obviously work as well if you'd rather not use the at-query mixin.

Use this simple mixin to create media queries. Breakpoints are defined under Breakpoint and Grid Variables in timber.scss.liquid. This mixin can wrap class declarations (Example 1 below), or be placed within them (Example 2 below).

Make use of $min or $max variables for the constraint and the breakpoint variables defined under #Breakpoint and Grid Variables for the viewports.

$min: min-width;
$max: max-width;
@mixin at-query($constraint_, $viewport1_, $viewport2_:null) {
  ...
}
Name Type Description
$constraint String Options: min-width, max-width, or null
$viewport1 String If $constraint is set to max-width:
  • $viewport1 will be your media query's max-width
If $constraint is set to min-width or null:
  • $viewport1 will be your media query's min-width
$viewport2 String If set, this becomes the media query's max-width
Default: null

Example 1 | Max-width query

@include at-query($max, $small) {
  .foo {
    font-size: 0.8em;
  }
}

Output:
@media screen and (max-width: 480px) {
  .foo { font-size: 0.8em; }
}

Example 2 | Min and max-width query

The first parameter is optional when creating in-between queries. The two following snippets generate the same output.

.foo {
  @include at-query(null, $postSmall, $medium) {
    font-size: 0.8em;
  }
}

.foo {
  @include at-query($postSmall, $medium) {
    font-size: 0.8em;
  }
}

Output:
@media screen and (min-width: 481px) and (max-width: 768px) {
  .foo { font-size: 0.8em; }
}

Helper Sass Mixins

Since we can't rely on Compass or Bourbon includes, there are a few mixins to get you started. Add any others you want to use under Sass Mixins in timber.scss.liquid.

  • clearfix
  • prefix($property, $value) - no default
  • transition($transition) - default 0.1s all
  • gradient($from, $to, $fallback)
  • backface($visibility) - default hidden
Clearfix Input:
.foo {
  @include clearfix();
}

Ouput:
.foo {
  *zoom: 1; // oldIE
}
.foo:after {
  content: "";
  display: table;
  clear: both;
}

Prefix Input:
.foo {
  @include prefix('user-select', 'none');
}

Output:
.foo {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

Prefix Input:
.foo {
  @include transition(opacity 50ms ease-in-out);
}

Output:
.foo {
  -webkit-transition: opacity 50ms ease-in-out;
  -moz-transition: opacity 50ms ease-in-out;
  -ms-transition: opacity 50ms ease-in-out;
  -o-transition: opacity 50ms ease-in-out;
  transition: opacity 50ms ease-in-out;
}

Gradient Input:
.foo {
  @include gradient(#900, #950, #900) // from red to orange, red fallback
}

Output:
.foo {
  background: #900;
  background: -moz-linear-gradient(top, #900 0%, #950 100%);
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#900), color-stop(100%,#950));
  background: -webkit-linear-gradient(top, #900 0%, #950 100%);
  background: -o-linear-gradient(top, #900 0%, #950 100%);
  background: -ms-linear-gradient(top, #900 0%, #950 100%);
  background: linear-gradient(top bottom, #900 0%, #950 100%);
}


3.1 Pagination

Documentation - http://docs.shopify.com/themes/liquid-variables/paginate

Note: The paginate liquid tag can limit how many articles are shown per page by wrapping the article loop with it.

Pagination will only work when you're trying to access an available object. The snippets below paginates through the blogs.news.articles object, so would only function properly on blog.liquid. View the documentation for other areas that can be paginated.


Default

Example 1 - Default

{% paginate blogs.news.articles by 5 %}
  <div class="pagination [pagination-custom]">
    {{ paginate | default_pagination }}
  </div>
{% endpaginate %}

Output:


Example 1 - Replace default text

{% paginate blogs.news.articles by 5 %}
  <div class="pagination">
    {{ paginate | default_pagination | replace: '« Previous', '← Newer articles' | replace: 'Next »', 'Older articles →' }}
  </div>
{% endpaginate %}

Output:


3.2 Tags

Documentation - http://docs.shopify.com/themes/liquid-variables/article

Get an article's tags with a simple for loop. The example below also adds a comma after each tag, unless it's the last one. The code lives in snippet/tags-article.

Tags: tag one, tag two

{% if article.tags.size > 0 %}
  <span>Tags:</span>
  {% for tag in article.tags %}
    <a href="{{ blog.url }}/tagged/{{ tag | handle }}">{{ tag }}</a>{% unless forloop.last %}, {% endunless %}
  {% endfor %}
{% endif %}

Documentation - http://docs.shopify.com/support/your-website/navigation/creating-a-breadcrumb-navigation

The code lives in snippet/breadcrumb.


3.4 Newsletter Form

Documentation - http://docs.shopify.com/support/configuration/store-customization/where-do-i-get-my-mailchimp-form-action

MailChimp is the go-to newsletter service for Shopify. Use the link below to find your MailChimp form action and insert it in your site settings.

<form action="#" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" target="_blank" class="input-group">
  <input type="email" value="" placeholder="Email address" name="EMAIL" id="mail" class="input-group-field">
  <span class="input-group-btn">
    <input type="submit" class="btn" value="Subscribe" name="subscribe" id="subscribe">
  </span>
</form>

4.1 Ajaxify Cart

Using the Ajax Cart plugin allows a user to add a product to their cart without leaving the current page. The cart will appear as a drawer on the right side of the page.

The cart plugin is enabled by calling ajaxCart.init({}) after jQuery is loaded. Pass in the parameters below to customize it.

Plugin Format

ajaxCart.init({ [options] })

Parameters

Name Type Default Description
formSelector Selector form[action^="/cart/add"]

Your add to cart form selector from the product page.

addToCartSelector Selector input[type="submit']
(within formSelector)

Your add to cart button selector from the product page.

A class of is-adding is added to the button once clicked. is-added will take its place and remain on the button after the product is successfully added.

cartContainer Selector #CartContainer

The template for your cart will be appended to an existing element on the page. By default, this element is in an off-screen drawer.

cartCountSelector Selector null

Update the number of items in the cart.

E.g. cartCountSelector: '.cart-count'

cartCostSelector Selector null

Update the total cart cost when products are added or removed.

E.g. cartCostSelector: '.cart-cost'

moneyFormat String ${{amount}}

Pass in your shop's currency with the liquid tag {{ shop.money_format | json }}.

disableAjaxCart Boolean false

Set to true if you want to disable the cart but still use the JS quantity selectors (see below).

enableQtySelectors Boolean true

Replace <input type="number"> elements with a JS quantity selector on your product and cart pages. Set to false to disable this and use the native elements.

Ajax Cart Callback

A custom event is fired when the cart has loaded in the DOM. To access it, set up a listener on the body element for ajaxCart.afterCartLoad. Use this callback in external files or below the initialize JS. Multiple callback listeners is also valid.

jQuery('body').on('ajaxCart.afterCartLoad', function(evt, cart) {
  // Bind to 'ajaxCart.afterCartLoad' to run any javascript after the cart has loaded in the DOM
  // cart is the result of /GET cart.js (https://docs.shopify.com/support/your-website/themes/can-i-use-ajax-api#get-cart)

  // Open Timber's drawer when cart is ready
  timber.RightDrawer.open();
});

Required Files

Required CSS is conditionally loaded in timber.scss.liquid, so you just have to include the JS. Place the following JS lines near the bottom of your theme.liquid layout file, after jQuery.

{{ 'handlebars.min.js' | asset_url | script_tag }}
{% include 'ajax-cart-template' %}
{{ 'ajax-cart.js' | asset_url | script_tag }}

Initialize

<script>
jQuery(function($) {
  ajaxCart.init({
    formSelector: '#AddToCartForm',
    cartContainer: '#CartContainer',
    addToCartSelector: '#AddToCart',
    cartCountSelector: '#CartCount',
    cartCostSelector: '#CartCost',
    moneyFormat: 
  });
});

jQuery('body').on('ajaxCart.afterCartLoad', function(evt, cart) {
  // Bind to 'ajaxCart.afterCartLoad' to run any javascript after the cart has loaded in the DOM
  timber.RightDrawer.open();
});
</script>

4.2 Drawers

Mobile-friendly navigation and the ajax cart are displayed in drawers. All drawer JS is included in timber.js.liquid.

Drawers can be opened by clicking on elements with class js-drawer-open-left or js-drawer-open-right.

Drawers are initialized in a global JS variable timber.LeftDrawer and timber.RightDrawer. You can use timber.RightDrawer.open() or timber.RightDrawer.close() from external JS to show and hide the drawers.


5.1 Typography

Headers and Body Text

Heading One

Heading Two

Heading Three

Heading Four

Heading Five
Heading Six

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper.

Suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat.


Blockquotes

Eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.

The author of the quote

List Types

No bullet ul
.no-bullets
  • One
  • Two
  • Three
  • Four
Round bullet ul (default)
.disc
  • One
  • Two
  • Three
  • Four
Square bullet ul
.square
  • One
  • Two
  • Three
  • Four
Inline List ul
.inline-list
  • One
  • Two
  • Three
  • Four
Numeric bullet ol (default)
  1. One
  2. Two
  3. Three
  4. Four
Alpha bullet ol
.alpha
  1. One
  2. Two
  3. Three
  4. Four

5.2 Forms

Vertical

To make long forms with block elements, add a class of .form-vertical to the parent.

You cannot add a class directly to most liquid form elements (e.g. {% form 'contact' %}). Instead, wrap the form in a div with the class .form-vertical to achieve the same effect.

Use class input-full

Checkboxes

Radios


Horizontal (default)


Invisible Labels

Note: The placeholder attribute only works in IE10+, so invisible labels are disabled in IE9 and below.

Add a class of hidden-label to a label to hide it, while keeping it accessible to screen readers. Use the placeholder attribute as your visible label.

<form>
  <label for="testInvisibleLabel1" class="hidden-label">First Name</label>
  <input type="text" id="testInvisibleLabel1" name="testInvisibleLabel1" placeholder="First Name">
</form>

Input Groups

Example 1

Example 2 - Mailchimp Integration

// Button on left
<div class="input-group">
  <span class="input-group-btn">
    <input type="submit" class="btn" value="Go">
  </span>
  <input type="text" name="q" value="" placeholder="Placeholder" class="input-group-field">
</div>

// Button on right
<form class="input-group">
  <input type="email" value="" placeholder="Email address" class="input-group-field">
  <span class="input-group-btn">
    <input type="submit" class="btn--secondary" value="Subscribe">
  </span>
</form>

5.3 Buttons

Timber offers a primary and secondary button to be used or customized as you need.

<!-- Primary -->
<a href="#" class="btn">Default Button</a>
<a href="#" class="btn btn--small">Small Default Button</a>
<!-- Secondary -->
<a href="#" class="btn--secondary">Secondary Button</a>
<a href="#" class="btn--secondary btn--small">Small Default Button</a>
<!-- Disabled -->
<a href="#" class="btn disabled">Disabled Button</a>
<a href="#" class="btn disabled btn--small">Small Disabled Button</a>
<!-- Sized -->
<a href="#" class="btn btn--full">Wide Button</a>

5.4 Notes and Errors

Use notes as helpers on forms, or brief messages to your customers.

This is a standard note
This is a success message

This is an error message.

  • Bullets can offer more insight to the error
<div class="note">
  This is a standard note
</div>
<div class="note form-success">
  This is a success message
</div>
<div class="note form-error">
  <p>This is an error message.</p>
  <ul class="disc">
    <li>Bullets can offer more insight to the error</li>
  </ul>
</div>

5.5 Misc. Elements

Horizontal Rules

Default

hr


Invisible

hr.hr--clear


Small

hr.hr--small



5.6 Icon Font

Timber offers a basic icon font for social and payment icons. Import assets/icons.json into IcoMoon to make any changes to the set. These icons are bulletproof, meaning they can have text fallbacks when @font-face isn't supported.

Payment Icons

  • American Express
  • Visa
  • PayPal
  • Discover
  • Master Card
  • Stripe
  • Interac
  • Cirrus
  • Google Wallet
  • DK
  • JCB
  • Maestro
  • Diners Club
  • Bitcoin

Social Icons

  • Tumblr
  • Vimeo
  • YouTube
  • Google
  • Twitter
  • Facebook
  • Pinterest
  • Instagram
  • Fancy
  • RSS

General Icons

  • Cart
  • Arrow Down
  • Grid View
  • List View
  • X
  • +/span>
  • -
  • Menu
<ul class="inline-list icon-font-demo">
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-american_express"></span>
      <span class="fallback-text">American Express</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-visa"></span>
      <span class="fallback-text">Visa</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-paypal"></span>
      <span class="fallback-text">PayPal</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-discover"></span>
      <span class="fallback-text">Discover</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-master"></span>
      <span class="fallback-text">Master Card</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-stripe"></span>
      <span class="fallback-text">Stripe</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-interac"></span>
      <span class="fallback-text">Interac</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-cirrus"></span>
      <span class="fallback-text">Cirrus</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-google_wallet"></span>
      <span class="fallback-text">Google Wallet</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-dankort"></span>
      <span class="fallback-text">DK</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-jcb"></span>
      <span class="fallback-text">JCB</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-maestro"></span>
      <span class="fallback-text">Maestro</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-diners_club"></span>
      <span class="fallback-text">Diners Club</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-bitcoin"></span>
      <span class="fallback-text">Bitcoin</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-tumblr"></span>
      <span class="fallback-text">Tumblr</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-vimeo"></span>
      <span class="fallback-text">Vimeo</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-youtube"></span>
      <span class="fallback-text">YouTube</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-google"></span>
      <span class="fallback-text">Google</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-twitter"></span>
      <span class="fallback-text">Twitter</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-facebook"></span>
      <span class="fallback-text">Facebook</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-pinterest"></span>
      <span class="fallback-text">Pinterest</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-instagram"></span>
      <span class="fallback-text">Instagram</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-fancy"></span>
      <span class="fallback-text">Fancy</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-rss"></span>
      <span class="fallback-text">RSS</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-cart"></span>
      <span class="fallback-text">Cart</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-arrow-down"></span>
      <span class="fallback-text">Arrow Down</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-grid-view"></span>
      <span class="fallback-text">Grid View</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-list-view"></span>
      <span class="fallback-text">List View</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-x"></span>
      <span class="fallback-text">X</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-plus"></span>
      <span class="fallback-text">+</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-minus"></span>
      <span class="fallback-text">-</span>
    </div>
  </li>
  <li>
    <div class="icon-fallback-text">
      <span class="icon icon-hamburger"></span>
      <span class="fallback-text">Menu</span>
    </div>
  </li>
</ul>