Reenvisioning branded content at Dollar Shave Club

Over a year ago, I was given the opportunity to work with a team to design and develop branded content for Dollar Shave Club. Dollar Shave Club and its affiliated company, Mel had been producing high-quality content along with beautiful art for approximately two years before under Josh Schollmeyer. This post will summarize the experience of my team and then go into more of my area of expertise—engineering.

To build a site that would be able to come close to the already set content, I was brought on under Darshit Desai to work with him and other team members—Erin Tag, Nick Lefty, Donny Smith, Justin Berg, Arvind Mishra, and Melissa Williams.

Branded content is not new conceptually. We were tasked with figuring out how to do it differently while creating something that was additive to the great content already being made at Dollar Shave Club. On top of that, our interface and to be normal so that writers could keep adding their content with ease.

Sometimes it is just Black and White

We spent time, refining outlook and answering questions that would have to last for a long period to come. What would be our design style? Could we create something that would allow the experience of each article feel like its own? How could we ensure that our content seemed like the good read it was/is and not like just branded content?

After about six months of prototyping and developing designs, we came to a few conclusions. We should have a simple palette of mainly blacks, greys, and whites to let imagery and articles stand out. We should be everything modularly so that we can more quickly add features. For the CMS for editing, we went with Wordpress so that writer would work with something that most were used to. The front end itself was separated using Wordpress's API.

The site must be fast

Images Matter: UX, design and engineering negotiated and came up with optimal image sizing and a standard ratio (16:9). Having a standard ratio allowed us to know image sizes and provide image placeholders before the image would load.

With the Imagesloaded Library, images can be added as they're available


export default function () {
  const loadImages = function loadImagesFunc() {
    document.querySelectorAll('.js-image-preload').forEach((el) => {
      // animate the image render after it's loaded
      el.imagesLoaded().progress(() => {
        setTimeout(() => {
        }, 250)
  // render load images when the document is ready
  // or when an ajax request is complete
  document.addEventListener('DOMContentLoaded', () => {

Less Fonts: We decreased the number of fonts used by computing some fonts using the font-weight: bold CSS property on fonts that were using a normal weight.

Computing a bold font to save on fonts used

.font {
  font: a-font-family 400 1rem;
  &--bold {
    font-weight: bold;

Cleaning up CSS:Purify CSS is used along with a config to makes that styles added via WordPress are there but nothing more. There are very few unused styles on the site.

Troubleshooting state CSS classes by adding a .config file for purifying CSS

<!-- now purify css knows not to remove it -->
<div class="some-state-class"></div>

JavaScript: 4 open sourced utility plugins were written (Reframe.js, Shave, ScrollDir, and Stickbits) while making this project along with jQuery but little else to ensure that the resulting JavaScript is lightweight.

The site must be searchable

To make the site more searchable, we made sure to use as much modern HTML as possible. We also used

Example of using semantic HTML and to clarify what objects are on the content site

<article class="post post--card style-card-hover" itemscope itemType="">
  <a href="/{{url}}" data-track-label="posts image: {{title}}" itemprop="url">
    <figure class="post__figure--card js-image-preload" itemscope itemtype="">
        class="post__image post__image--card"
  <div class="post__content--card">
    <a href="/{{url}}" data-track-label="posts title: {{title}}" itemprop="url">
      <time class="text__date text--grey" itemprop="datePublished">{{formatted_date}}</time>
      <h3 class="post__title--medium post__title--card text__title--medium" itemprop="headline">
        <span class="post__inline-text js-shave-card">{{title}}</span>

Check out the final product here.