How we built the Minneapolis Yoga Conference website

Written by on

We built a website for the Minneapolis Yoga Conference taking place in March 2018. The website recently launched and we want to tell you how we built it.

Last year, the Minneapolis Yoga Conference website was made on Squarespace. Squarespace is easy for non-developers, but you can't always get everything just the way you want it. It's tough to fully customize unless you engage a developer who knows the platform. In the end, you might be stuck with a theme that looks ok, but isn't quite what you want.

Taking some of the positives of Squarespace, we knew we wanted to build something custom while still allowing non-developers a decent experience. Ultimately, that means non-developers should be able to edit content and they should be able to use tools they're familiar with.

To sum it up, a developer shouldn't be required to change a description of a class or a picture of a presenter.

We also wanted to build with the tools and frameworks we use every day. We use Rails and Bootstrap every day. So that's what we used here.

There are a few things we'd like to share with you. Before we built anything, we organized a style guide. Then, we enabled content editing with simple text files. Finally, we want to share how we learned to build horizontal touch scrolling for mobile devices.

Style Guide

If I had to choose one thing which contributed to the success of the project, the style guide would be my first choice. When you start a website, it's like a puzzle box with no pieces inside. Your designer might give you a picture of what the puzzle looks like when it's finished; but how do you get there? You could start building the pieces as you go, but what if you build the wrong ones?

That's where the style guide helps. By sticking your focus on the style guide, you build most, if not all of the pieces beforehand. Eventually, when you start the puzzle, you have a picture of what it should look like and all the pieces required to do so.

To give you an idea, here's what our style guide looks like:

Before we started building the Minneapolis Yoga Conference website, we translated the design into a style guide. These components were the pieces we needed to finish the puzzle. 

Before we started building the Minneapolis Yoga Conference website, we translated the design into a style guide. These components were the pieces we needed to finish the puzzle. 

It's not fancy, but it gave us a starting point to put things together.

As you can see, the style guide sort've follows the layout of the website; but it's a bit different. Nothing is functional. There's no javascript here. It's simply a breakdown of components we'll be using to build the website.

Each of these components is self contained. They aren't changed by their parent. An MYC Navigation Bar element looks the same regardless of where it's placed in the DOM. If you have a naming conflict in your stylesheets, you'll see it immediately on your style guide.

Is this style guide perfect? No. There are ways to take this much further. We aren't listing out colors and font sizes here, but that's something you could do. You could add descriptions to each component with declarations on when and where to use them.

Using a style guide has the added benefit of giving you a starting point for content you wish to add in the future. Is there a component you could re-use or modify slightly? Having all of your pieces in one box will help.

As an application gets larger, it's tough to remember all the different pieces you may be using. A style guide can be a quick reference to the various components used in your application.

Storing content in flat files

This website has a significant amount of content. That content will also change over time. Also, we don't always have control over when we receive that content.

As we were building it, we were still collecting bio and headshot information from instructors. We also knew we'd be getting new studio partners as the conference neared. We needed to do something so a developer was unnecessary when those content updates were required.

To help us with that, we stored content in YML files and rendered the content dynamically. Essentially, the website has a primitive database which can be updated easily with a text editor.

Here's what one of those files looks like:

- name: Jon Snow
  headshot: "john.png"
  bio_pic: "john-bio.jpg"
  bio: >
    Jon Snow is the son of Eddard Stark, Lord of Winterfell. He has five half-siblings: Robb, Sansa, Arya, Bran, and Rickon Stark. Unaware of the identity of his mother, Jon was raised at Winterfell. At the age of fourteen, he joins the Night's Watch, where he earns the nickname Lord Snow. Jon is one of the major POV characters in A Song of Ice and Fire. In the television adaptation Game of Thrones, Jon is portrayed by Kit Harington. Source: http://awoiaf.westeros.org/index.php/Jon_Snow
  facebook: https://www.facebook.com/GameOfThrones
  instagram: https://www.instagram.com/gameofthrones
  website: http://www.hbo.com/game-of-thrones

These files are accompanied by a simple Ruby class resembling an ActiveRecord model. We did this so we could write code as if we were accessing the database. In the future, we may find it useful to put the content in a different place. By doing it this way, we won't need to change the templates responsible for rendering the content.

class Myc::Presenter
  def self.all
    @all ||= YAML.load_file(Rails.root.join("config", "myc", "presenters.yml"))
  end
end

This allows us to use the following in our templates:

<% Myc::Presenter.all.each do |presenter| %>
  <a class="blurb presenter">
    <div class="blurb-image">
      <div class="blurb-image-inner">
        <%= image_tag "myc/presenters/#{presenter["headshot"]}", size: "150x150", alt: "Presenter: #{presenter["name"]} Headshot" %>
      </div>
    </div>
  </a>
<% end %>

This gave us a distinct advantage. Once we programmed the content to pull from the flat files, a non-developer could handle content additions and updates. In other words, a developer could focus on pushing the implementation forward. They weren't distracted by an update to a headshot or bio.

The main reason non-developers could handle these content updates was GitHub. This was a lucky side effect of using GitHub for all of our projects.

Using the GitHub web interface, a non-developer was able to upload headshots and edit files; all inside a new pull request. When the pull request was ready, the new content was merged and the site updated without the help of a developer. This was helpful because of the effort involved with image production (cropping, optimization, etc.) and gathering content from many different people. The website was updated much faster this way.

Obviously this is just one approach to making content updates accessible to more people. We could have opted for a database based approach with a web interface. I'm sure you could use something like ActiveAdmin to achieve that.

However, we wanted something quick and dirty. We didn't want to spend a bunch of time learning some other system. We were able to quickly experiment with this method and determine it was going to work for us.

Horizontal Touch Menu

One of the trends on the mobile web is horizontal scrolling. Touch scrolling horizontally is a natural gesture.

You can see examples of horizontal touch scrolling in use on the websites and apps of Apple, Amazon, Facebook, Basecamp, and many others.

This is what our horizontal scrolling looks like on mobile. A person can swipe left and right to access more information. We fade out the left and right sides to indicate there's something more to see.

This is what our horizontal scrolling looks like on mobile. A person can swipe left and right to access more information. We fade out the left and right sides to indicate there's something more to see.

The key to all of this is a non-standard CSS rule called -webkit-overflow-scrolling. However, you still need a few more things to get this right.

We start with a set of three elements. In our case, we chose to use a div for the container, a nav to indicate navigation, and a ul to house the menu elements. Something like this should work.

<div class="touch-container">
  <nav class="nav">
    <ul class="nav-ites">
      <li>Home</li>
      <li>Blog</li>
      <li>About</li>
      <li>Contact</li>
    </ul>
  </nav>
</div>

You'll want to start by giving your ul element a list-style of none and the li elements a display of inline-block. For the purposes of this demo, we'll also increase the font-size and padding for the li elements. This will help us demonstrate horizontal touch scrolling.

<style>
  .nav-items {
    list-style: none;
    padding: 0;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
  }
</style>

Next, on the ul element, set overflow-x to auto and overflow-y to hidden. This will allow the browser to use a scrollbar if things overflow in the x direction. If anything overflows in the y direction, it will be hidden.

<style>
  .nav-items {
    list-style: none;
    padding: 0;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
  }
</style>

At this point, you can add -webkit-overflow-scrolling: touch; to your ul element. Congratulations. You now have a working version of a horizontal touch scrolling navigation. You could stop here, but there's one last trick that will make things look a bit nicer. You don't want that ugly scroll bar showing up when people swipe to the left and right.

The container div is responsible for hiding the horizontal scroll bar. Without it, a horizontal scroll bar will show when a person is interacting with your navigation. If you don’t care about that, you could get away with not using a container div. In our case, we wanted to hide the scroll bar. This container div works together with the ul to hide the scroll bar. To hide the scrollbar, you’ll be doing two things:

  • Setting a height and changing the overflow to hidden on the container div.
  • Giving the ul element a bottom padding (pushing the scroll bar out of view).

Once you've done all that, your CSS should look like this.

<style>
  .touch-container {
    overflow: hidden;
    height: 68px;
  }
  .nav-items {
    list-style: none;
    padding: 0;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  .nav-items > li {
    display: inline-block;
    font-size: 24px;
    padding: 12px 24px;
    padding-bottom: 50px;
  }
</style>

Wrapping Up

When all was said and done, we were satisfied with how things turned out. When we started the Minneapolis Yoga Conference website, we looked for ways to make progress more efficient. Coming from Squarespace, we had an opportunity to do things our way.

In the future, we'll continue to use style guides to help with development. We also want to continue exploring ways to bring non-developers closer to the release cycle. This may mean different things at different times. In the case of this website, it was quicker content updates. On a different project, it may mean something else.

Finally, if you haven't noticed horizontal touch scrolling before, I'm sure you will now. It's starting to be used in many different places. If you find a neat use of it, let us know in the comments below.