Designing a (Gay) Wedding

Part 2 — Building a Wedding Website

Sean McBride
Designing a (Gay) Wedding

--

Just joining us for this episode of Designing a (Gay) Wedding? Check out Part 1 to learn about the creation of our design system.

When my husband Steve proposed, he surrounded us with reminders of our relationship. Our favorite song (Lisztomania by Phoenix) played in the background. The first movie we saw together (Pixar’s Up) rolled silently on a small screen. A slideshow of snapshots from our five years together played on a laptop. We’re both technology nerds, so of course technology was a part of the proposal.

It may sound strange, but one of the most touching parts of the proposal was a webpage. Steve had secretly purchased a selection of potential domain names for our wedding website a whole year before he proposed. I’m usually the one who’s building webpages, but for the proposal, Steve pointed all of the domains he bought at a temporary page he made himself. Tucked into the simple HTML source was a comment he left for me:

<!-- Designed with LOVE. Coded with recklessness. (Until you do something better!) :) -->

What a guy! ☺

The first version of our wedding webpage that Steve built for the proposal. He even used web fonts from Typekit!

Yes, our wedding website was with us from the beginning, and it evolved along the way to support our needs. We wanted to do almost all wedding-related communication through the website, including all RSVPs. The only exceptions were the save-the-date and invitation, which we wanted to make compatible with refrigerators and magnets. Since I build websites for a living, of course I decided to build our website from scratch! Along the way, I learned a lot about Node.js, translating design between print and the web, and developing a website iteratively in response to changing needs.

Phase 1: Save the Dates

As I talked about in Part 1 of the series, one of the first things we did during the planning process was to put together a guest list and book a venue. After we did, the next step was sharing that information so our family and friends could actually save our date! While it’s easy to send an email or a text, we enjoy getting paper save the date postcards in the mail. Hanging them up on the fridge reminds us of the event and builds excitement as the date draws near. We decided that we’d send out paper cards with basic info and our website address.

At that point, we were still planning most of the events and info that would eventually appear on the website. All we could put up initially was a placeholder page that our guests could bookmark and come back to. Aiming to keep things simple, I started with a design that closely followed the paper save the date (which I’ll discuss in more detail in my next post). The translation didn’t go well.

Paper save the date on the left, with my naïve first web attempt on the right. You’ll notice that our design system isn’t finalized at this point — we used a temporary color palette.

My first hurried and naïve attempt translated elements directly from the print design to the web. I quickly ran into a predictable set of problems:

  • The print version was portrait, but web browsers are often landscape. The web version required a lot of scrolling on a desktop monitor.
  • The print version only needed to be one size, but web browsers can be stretched to any size and aspect ratio. The original print design wasn’t conceived as a responsive system, so it didn’t adapt well to different screen sizes — especially mobile phones and tablets.
  • The print version was built with Adobe InDesign. The web version used the native building blocks of the web — web fonts, border-images, CSS transforms — instead of using one big image. As a result, some more complex design elements like the repeating background or the curved text couldn’t be easily translated, and the result had less impact.

In retrospect, I should have known better that to try to translate a print design directly into a web page. I taught about the pitfalls of that approach in a talk I developed back in 2012. I should have followed my own advice: go back to the content and the design system, then develop another interpretation that takes advantage of the web’s unique qualities instead of being limited by them.

The second version of our save the date webpage. Still visually related to the paper version, but much better at being a webpage.

Much better! By going back to the drawing board, my second attempt was able to present the same content using many of the same elements, but without being rigidly constrainted by what had worked well on paper. The second version was much better at being a webpage instead of a slavish copy of a paper artifact.

Responsive design: small additions to the rules governing the layout allow the same design to work in many contexts.

Of course, a good webpage in the modern world needs to work well on more than just a computer monitor. We knew that guests were just as likely to visit the website from tablets and mobile phones as they were to visit from desktops and laptops. Following the principles of responsive web design, I was able to add a few additional CSS rules using media queries in order to ensure that elements reorganized themselves to fit the available space.

Great! With this first iteration — a simple, static webpage — in the bag, we could step away to work on other aspects of the planning process.

Phase 2: Schedule and Hotel Info

The next driver for updating the website came once we finalized arrangements for a block of hotel rooms. We needed to let out-of-town guests know how to book their rooms, and in order to plan their stay they also needed to know about their schedule of events. We planned to host some additional get-togethers for family and friends coming from far away, and these would affect travel plans.

At this point, we realized that we needed to move beyond a static webpage. We didn’t want all of the wedding info visible on the public Internet, so we decided to require guests to use an access code. In order to show each group of guests only the events they were invited to, we used different access codes to identify each invitation. We also needed a way to manage the invitations and events, so we decided to build a simple admin area.

These new requirements meant a lot of new technology decisions! I wanted to use the project as an opportunity to learn Node.js, a platform that makes it easy to build web servers using JavaScript. In order to focus on the basics of Node, I steered away from bigger frameworks providing higher-level abstractions. I chose Express — a minimal Node web framework — as my base with EJS for templates, Less for more efficient CSS, and static-asset for a basic asset pipeline.

We also needed a simple database to store event and invitation records. Because I’d been recently reading about the downsides of standard ORM patterns, I decided to try a different approach: simple objects that answer basic questions about only one type of data. I chose PostgreSQL as our database (using the pg library) with any-db for a bit of helpful abstraction, sql for easy query building, and db-migrate for database modifications.

The logged-out version at this phase looked much the same, but we had finalized our color palette.

Design-wise, not a lot changed at this phase for visitors without an access code. In the time between updates, we had finalized our color palette, so I incorporated those changes into the design. The only addition was a place for guests to provide their access codes and enter the full site.

The logged-in version added content for events and hotel info. The schedule was customized for each guest.

Once logged-in with their access code, guests were greeted with a customized schedule of events they were invited to and information about hotel booking. Our goal was to present everything necessary for our out of town guests to plan their travel. We kept everything on a single page, but since there were still only two sections, I decided not to add any navigation beyond scrolling. Once again, a few media queries and additional CSS rules allowed the page to work well on narrow screens.

Some media queries and additional CSS kept the page design responsive.

We hosted the website for free on Heroku, since they offer a basic PostgreSQL database and everything else we needed. We even built a tool in our admin area for sending automated emails to guests using Mandrill’s free Heroku integration. The emails were automatically customized with each guest’s name and unique access code, which saved a lot of time compared to sending them out by hand.

Intermezzo: Password Usability Stinks

When I initially designed our access code system, I assumed that people would write their access code down or search for one of the emails we sent in order to get back to the site later on. This ended up being a big pain for many of our guests, and we frequently fielded requests for access code reminders. It turns out that many people don’t think about searching their old emails, and guests were clicking the auto-login links without writing anything down. I realized we needed to go back to the drawing board.

This is what trying to fix design with small print looks like!

My first attempt was clearly just a band-aid: I added a message about how to search email for an access code. It’s no big surprise that this didn’t have an effect. If anyone even read the fine print, they didn’t (or didn’t know how to) search their email. The access code requests continued.

Adding the access code to the logged-in URL and allowing bookmarking.

Eventually, we hit upon a a more practical idea. Initially, the access code had been stored in each guest’s web browser via a cookie. However, switching computers or accessing the site via a phone or tablet meant that a guest didn’t always stay logged in. The breakthrough came when we heard from a guest who was bookmarking the site and expecting to be logged in when they clicked on the bookmark later.

I made a small change so that the access code was included as part of the logged-in URL. I also added a note to the top of the page inviting guests to add a bookmark. Visiting via the bookmarked URL would automatically include the access code, logging the guest back in. While not a good security practice, in this case convenience trumped security. Requests for access code reminders dropped off after that change.

Phase 3: Additional Info and Navigation

After getting the most important information out to traveling guests, we enjoyed a brief break from tight deadlines. We had planned to add some additional sections, so the first step was drafting and editing that content. Once the dust settled, we had additional information about our backstory, our wedding party members, the venue, things to do in San Francisco, and a basic primer on marriage equality in California. With these additional sections came a need for navigation and better section dividers to help guests get around. We also updated the photography with professional shots from Gavin Farrington, our talented wedding photographer.

The new section navigation started out just below the main header.

After brainstorming several options for navigation, I decided to keep the site as a single long-scrolling page and add navigation to allow guests to jump between sections. The navigation started out just below the main header area at the top of the page. As a guest scrolled down, the navigation would attach itself to the top of the viewport in order to remain visible.

As the page scrolled, the navigation attached to the top of the viewport.

Each section header featured an image from our photographer with a title, a short introduction, and some ornamental linework from our design system. The navigation at the top of the viewport would update to highlight the current section as each one scrolled into view.

On narrow screens, the navigation would show all sections at the top and then collapse to a single row as the guest scrolled.

On narrow screens, I added further styles to my existing media queries to ensure that the navigation and all the new content sections worked well on phones and tablets. The navigation presented a particular challenge, since the section names didn’t fit across a narrow screen in a single row. After trying various options like dropdown menus and next/previous links, I settled on something closer to the original design. At the top of the page, the section names in the navigation would wrap onto new lines so a complete overview of the site was visible. Once a guest scrolled down, the sections would collapse onto a single line which could be swiped back and forth with a finger on touch displays. In addition, the name of the visible section would always move itself into view horizontally as the page scrolled.

Phase 4: Invitations and RSVPs

The final stage in our wedding website’s evolution came when it was time to send out the formal invitations and RSVP cards. We had decided that we’d only accept RSVPs via the website, so each RSVP card contained only an access code and the website address. Of course, this meant that the website had to be ready to accept RSVPs before we could mail anything out. Talk about deadline pressure!

After sketching a bunch of different ideas, I decided that the RSVP flow should happen in stages, with additional questions (such as individual guests, food choices, and specific event RSVPs) appearing only when relevant. Thus, the initial view that guests were presented with was a single yes-or-no question: will your party be joining us?

A guest’s view of the RSVP section before responding.

Once that question was answered, additional questions were revealed. Some questions had default responses, such as setting all named guests to “attending” and all unnamed +1 spots to “not attending”. Other questions had no default and required a response, such as food choices and hotel accomodations. Finally, there were optional questions, such as food allergies and a note for the grooms.

Additional questions appear once the party RSVP is set to “yes”.

A few of the events that we planned weren’t hosted, such as a brunch on the morning after the wedding. If a guest replied yes to one of those, then a payment section appeared displaying the total cost and offering the ability to settle up via an online payment (using the excellent Stripe Checkout form) or an in-person payment at the event. We ended up collecting about 60% of payments through Stripe and the website, which made this aspect of the event logistics a lot easier.

Payments through Stripe Checkout for any events with an associated cost.

After answering the necessary questions and submitting the RSVP, guests would see a reminder of their responses instead of the full RSVP form. The guest could also expand the full form again to edit responses before the RSVP deadline.

Once the RSVP is submitted, guests see a reminder and can edit.

When a guest responded “no” for their party’s attendance, most of the subsequent questions were irrelevant, so they stayed hidden. These guests saw only a field for leaving an optional note to the grooms before submitting their response.

For parties that can’t attend, we omit most follow-up questions.

In order to implement this kind of rich client-side experience without a bunch of slow and tedious form submissions and page refreshes, I needed to bring in some additional JavaScript firepower. I chose to use Knockout.js, a lightweight library that makes it easy to implement interactive UIs in the browser with declarative data-binding between a JavaScript view model and HTML templates. There are many good options for libraries in this space, but I’m most familiar with Knockout.js, and I knew I could work with it quickly and productively.

There was also a lot of work behind the scenes in order to support the new RSVP system. We needed additional database tables and columns to handle things like individual guests and event responses. I was glad that I had included a database migration library earlier in the development process, since it made adding and deploying database changes much easier.

Along with these database changes came additions to the admin UI for managing the new types of information and a dashboard page where we could see the overall progress of our guests’ RSVPs. Later on, we ended up canceling one of the events that some guests had already RSVP’d and paid for, but thanks to Stripe’s API and our admin UI, issuing refunds and updating our records was an easy process.

The Finished Product

It’s easier to see a website in-person than to describe it second-hand. While the actual production version of our wedding website was limited to invited guests, I made a static copy of the final phase for both the logged-out version and the logged-in version so you can get investigate the details if you’re interested. Check it out!

When the wedding was over and done with, the website had served its purpose: we were able to communicate with our guests, share important information, gather RSVPs, and host a successful event. Although the site was only visited about 2,500 times during the entire year of 2014, it’s not the type of project where success is measured in pageviews.

It was a significant amount of work to build a website from scratch for a single event, but it paid dividends in learning, personalization, and our ability to respond to the planning process with just the right solutions.

I wouldn’t recommend that everyone build their wedding website from scratch, since there are great platforms like Squarespace that allow you to create something nice-looking with less work and know-how. However, if you already have some web development skills and are looking for a project to exercise them, building your own wedding website can be a great way to learn new things, express your style as a couple, and tailor your communication with your guests. Just make sure you have enough time to meet the important deadlines!

In the next post in this series, I’ll dive into the design and production of the printed assets for our wedding, including save the date cards, invitations, RSVP cards, programs, menus, and more. I’ll also talk about how we were able to use the website to automate the production of some of the printed materials, just as the printed materials influenced the design aesthetic of the website.

--

--

Sean McBride
Designing a (Gay) Wedding

Now: @RangeLabs! Previously: @Intercom, @Typekit (@Adobe), @Google, @OlinCollege. Frequently: web, design, code, cocktails, wine, skiing. Married to @sjcary!