Grow your CSS skills. Land your dream job.

Design Systems: Building for the Future

Published by Chris Coyier

The following is a guest post by Ara Abcarians (@itsMeAra). Ara is a UX Engineer at Media Temple and worked on the recent redesign of mediatemple.com. Here he shares the ideas, approach, and tech behind that work.

Full disclosure: Media Temple has long given me free hosting. I even use an affiliate link when I link to Media Temple, which I earn a little money from. But I'm not publishing for some backroom shoulder-rubbing reason. I'm publishing it because they did a good job with the redesign, Ara wanted to write it, and I think we all can benefit from his insights on an important large-scale redesign.

Now Ara.


The modern web design and development process is rapidly evolving, and responsive websites are quickly becoming the norm. Frameworks like Bootstrap and Foundation are showing us the value of creating robust systems of components to make building things on the web faster, better, and easier.

About a year ago, I joined LA-based web hosting and cloud services company (mt) Media Temple as a UX Engineer. Tasked with leading the front-end development of (mt)’s website redesign, I took the opportunity to slow down and revisit my front-end development approach. That’s how I realized that the way I was previously building large websites was a little flawed. I wanted to share some of my learning process and shed some light on the high-level approach I chose to take while learning about and building a design system.

But what exactly is a design system?

At FOWA 2013 in London, Mark Otto described a design system as “everything that makes up your product” (see his entire talk here: Build your own Bootstrap).

Everything? Everything. From typography, layouts and grids, colors, icons, components and coding conventions, to voice and tone, style-guide and documentation, a design system is bringing all of these together in a way that allows your entire team to learn, build, and grow.

At first, I wasn’t sure whether I should start building something custom or begin with an existing framework like Bootstrap. Ultimately, I decided against using the latter for a few reasons:

  • We already had a custom design. When I started at Media Temple, the visual designs for the new site were just about complete. If I used a framework, I’d have to significantly customize it to fit our designs.
  • I wanted to establish coding conventions and structure based on my team’s preferences. Again, I’d have to spend a ton of time re-naming classes or reorganizing things to fit our needs.

The amount of time I would spend essentially gutting the framework didn’t seem worth it. I felt like building our own framework would be beneficial to us in the long run, more maintainable, and, as a bonus, would be an incredible learning experience. It also helped that I had the time to do it, and an entire team that was excited to be a part of it.

Establish Top Level Goals

When rebuilding a legacy website, you're presented with the opportunity to improve a lot of things. Before I began any actual development, I started out by establishing some top level goals:

  • Organization: A messy codebase can become a nightmare to work with. Making sure we had a well thought-out structure and approach was very important.
  • Maintainability: Over time, there are going to be new developers jumping in to fix bugs and add features. We needed to have proper guidelines and conventions to make it easy for people to do things correctly.
  • Responsiveness: Having seen a steady rise in mobile/tablet traffic, it was very important to make the experience platform-agnostic.
  • Scalability: The company will grow in the future, and so should its website. Creating promotional pages and/or new product pages should no longer be an unpleasant (and near impossible) task.

My “a-ha” moment

With the top level goals in mind, I started doing extensive research. I began by reading about HTML semantics and front-end architecture and discovered the benefits of building flexible modules, not pages. That was my “a-ha” moment.

Previously, while building large websites, I was used to dividing the work by page templates. I’d tackle a set of related templates, then move on to another set. The problem with this approach is that, if the communication between the team isn’t exceptional, you’ll end up with many similar — sometimes identical — modules and components marked up and styled in different ways. If you don’t spend the extra time refactoring them, your codebase will turn into an absolute mess.

I decided to study two excellent — but different — projects very deeply: InuitCSS by Harry Roberts and Bootstrap by Mark Otto and Jacob Thornton, and I quickly realized the next step I needed to make was to establish guidelines around how our HTML, CSS, and JavaScript should be coded and what our overall front-end approach should be.

Coding Conventions and Guidelines

Inspired by Idiomatic HTML, CSS Guidelines, and Idiomatic JavaScript, I began adapting these into our own set of coding guidelines. In the process, I discovered and adopted an interesting naming methodology called BEM (Block, Element, Modifier). It’s essentially a clever way of naming your CSS classes to make them more meaningful and simpler to understand.

Our slightly modified convention is:

  • .block {} - Represents the main component.
  • .block-elementName {} - A child element that helps make up the component as a whole.
  • .block--modifier {} - A modifier class that is used to alter the state or appearance of the component.

Here is an example of an alert box using this approach:

/* Main 'alert' component */
.alert {}

  /* Sub-components that make up the 'alert' */
  .alert-text {}
  .alert-close {}

/* Modifiers for various styles of the 'alert' */
.alert--warning {}
.alert--error {}
.alert--success {}
.alert--info {}

I also finalized a set of tools to help us along the way, including LESS for our CSS pre-processing needs, and Grunt to compile our LESS files and compress, minify, and concatenate our code.

Developing Base Styles

An example of base styles
Base HTML elements courtesy of HTML Ipsum

Similar to InuitCSS and Bootstrap, I created a primary stylesheet called mt-global.less which would import all of the site styles together and create the final mt-global.css file. In an effort to keep things organized, I created a few folders:

  • core - This would hold our custom variables and mixins.
  • vendor - For vendor utilities used, such as LESSHat and REMixins.
  • base - For all of the underlying base styles like typography, colors, and structure.

I started out with normalize.css, adapting it as needed, and continued styling general elements such as headings, links, lists, form elements, and tables.

Identify and Build Components

With the base styles in place, it was time to take a look at the website as a whole, and start identifying individual components. I started building a custom grid system based on the grid used for the designs. From there I continued on to common elements like buttons, call to action links, hero units, and navigation.

An example of the featurette component

As I was building components, I started figuring out ways to abstract common styles into reusable objects, similar to the media object. InuitCSS was a huge help here as it contains tons of useful objects. All of these styles were put into folder called components.

Identify and Build Modules

Breakdown of homepage modules

With most of the components ready to go, it was time to use these building blocks to create each page’s various modules. I created another folder called modules, and began putting them together, starting with global modules like the site header, footer, and hero unit.

Establishing Patterns

An example of the preliminary style-guide
Sections of the preliminary style-guide.

As I was building components and modules I started to plug them into a style guide using the Style-Guide Boilerplate. The result was a single point of reference for any team member interested in learning how to contribute to the website. Once the whole team had access to the style guide, building page templates was a breeze. It was just a matter of mixing and matching modules, and extending or customizing them when necessary.

In Conclusion

Building a design system is a long process filled with trial and error. Established frameworks can save you weeks of development time, but if you’ve built your web project with a framework that has since gone through many releases, maintaining it can be difficult. Do you upgrade your codebase with each release? What if you have customized it so much that updating it isn’t even an option?

If you have the opportunity to rebuild a site from the ground up, building a custom solution solves a lot of issues: It helps establish a custom tailored system enabling your entire team to quickly and easily learn how to contribute to your project; it’s built by you and specifically for your company’s needs; and, most importantly, it’s built for the future. Without being tied down to another project’s evolution and direction, it’s free to scale at your companies pace.

Research. Build. Learn. Repeat.
- John Polacek

Above all, it was an incredible learning experience and a great source of pride for our team. I encourage everyone to study the many resources available about design systems and the ever changing web design process.

Comments

  1. Permalink to comment#

    I’ve successfully used a BEM variant on a couple projects and I felt that it made support quite a bit easier. I strongly recommend using __ as a separator between blocks, elements, and subelements. It allows you to use standard hyphenated names for blocks and elements.

    I find foo-bar and foo-bar__baz easier to read than fooBar and fooBar-baz, but YMMV.

    That said, it takes some getting used to and can be easy to mess up. Developers new to BEM often forget that they need to add both the block and block--modified classes to elements, or will mix up modifiers by using something like:

    <!-- THIS IS WRONG, DON'T DO IT THIS WAY -->
    <div class="block block--modified">
        <div class="block__element block__element--modified">...</div>
                              <!-- ^^^^^^^^^^^^^^^^^^^^^^^^ -->
    </div>
    

    The correct way would be to use block--modified__element:

    <!-- THIS IS THE RIGHT WAY -->
    <div class="block block--modified">
        <div class="block__element block--modified__element">...</div>
                              <!-- ^^^^^^^^^^^^^^^^^^^^^^^^ -->
    </div>
    
    • Andrew Jones
      Permalink to comment#

      This article is inspirational. I’ve recently moved away from Drupal and modifying pre – existing themes, and the information contained here will help me a lot.

    • Mark
      Permalink to comment#

      If you are yousing this “flag style” way, sure, you gotta reference the base block__element in the class attribute.

      But for big projects, it’s easier to just include or extend the class via sass/less, instead of cluttering the class attribute.

  2. Permalink to comment#

    This made a lot of sense to me, and I don’t think this applies to just large projects.

    And on a side note about the new look MT site, I like the way the ‘sub menu’ scrolls up and then stays fixed, nice.

  3. I’m still fairly new to web design, but I would love to get this concept down. Your article answers several questions I’ve had regarding designing systems, namely where to begin. You’ve posted some great inspirational links.

    The idea of designing systems feels intimidating, I will admit, but this helps clarify how to develop my own workflow. I have one question, though. Do you think a team of one would benefit from this approach, e.g. building a personal website/blog?

    • Certainly! In the worst case scenario, you’ll quit the idea, will use a framework like Foundation and have learned a lot about design systems. In any case it is a win.

      Also you’ll polish it every time you use it and have an awesome boilerplate for your next projects!

      I’ve already used a lot of – great – frameworks, but now I’ve done my own boilerplate with the minimal code necessary and I’m more than happy with the end results of my projects. It’s easier to maintain and performances much better than any other framework I ever used (bytes count and real time performance).

    • Good points, Elton. Thanks for the response!

    • Permalink to comment#

      I’d have to agree with what Elton said! :)

      It really is an incredible learning experience and because you’d be working on your own personal project, you have a lot more room to make mistakes, take your time, and learn.

  4. Sealth Reinhold
    Permalink to comment#

    Inspiring as always Ara. Tremendous job on the redesign! I learned a lot from this post, so thanks to Chris and Ara for making it happen. Cheers!

  5. Great article. We share the thinking that it is – a lot of times – a better idea to build your own “framework”. It is not that hard if you focus in the real needs of the project. Use others framework as a reference is a good thing too.
    I think that the important is to have a coding convention (whatever it is BEM, OCSS or anything else), be organized and think about performance and maintainability.

    It’s good to see a case of success of anyone not using a framework! Keep up the good work!

  6. Great job… except not. I love the methodology and process and system and whatnot, but that new home page is 1.8Mb on a big screen and 2.4Mb on a small screen. They need to get that under control.

  7. Permalink to comment#

    Its a very nice topic and good information shared by you. Thanks a lot for sharing this with us.

  8. Permalink to comment#

    Great read. A lot of good points.
    I recently did something similar at work.

  9. This post is so timely for me. In recent days I’ve been considering what my “position” is on using prebuilt frameworks for a large website design project. I was close to leaning towards that being a great idea because they have solved many problems with their components/modules that they saw as patterns. The issue is, the problems were solved in the context of their design. Their design problems won’t necessarily be the same as my large project’s design problems. However, I really resonate with your approach of still learning from these excellent frameworks. And I also love the idea that, in the end, the team that has built the framework from the ground up will feel more rewarded from both seeing the fruit of their work and being confident in their ability to continue maintaining and customizing it effectively.

    Again, this post was timely. Thanks Chris and Ara!

  10. Luca
    Permalink to comment#

    Great, great article.

    I have one question though:

    I really gare the BEM child element syntax ( the __ ). I think it’s just too inelegant.

    So I wowed at your modified syntax, which sports a single “-” for children elements.

    But then I wondered (and here’s the question): what about elements composed of 2 words? Camel casing is just about as ugly as double underscores, so what’s your proposition? Maybe avoid 2-words elements at all?

    • Luca
      Permalink to comment#

      By “gare” I meant “hate”, of course. Italian auto-correction. ;)

    • Permalink to comment#

      Hey Luca,

      I too didn’t like the BEM double underscore syntax when I was first learning about it. I actually do like camel case though, so that is what we stuck with for two-word elements.

      It really just comes down to you and your teams preference at the end of the day. Another method may be separating two-word elements with a single underscore instead?

      .block {...}
      .block-element_name {...}
      

      Harry Roberts has a great article on BEM: http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/

      He has a section in there that talks about the “ugliness” of BEM that really opened my eyes about it and helped me kind of look passed it a bit. :)

  11. Mario
    Permalink to comment#

    I used to distinguish between components and modules, too. But those categories are often very vague. It is often not clear whether something should be considered a module or a component. You could say anything that is used by modules should be a component but that didn’t always work for me.

    Another question: Where do you put basic layout styles? E.g. wrapper elements for sticky footers, main element (could be also considered a module with submodules)

  12. Thank you so much for the useful article. Will certainly try and use these resources for upcoming tasks. We face a similar situation at work where we used a previous version of the framework and the framework has been refactored quite a bit in the next release. We decided to stay back.

  13. Scott Williams
    Permalink to comment#

    This is pretty uncanny. After playing around with OOCSS, BEM and SMACSS. I’ve pretty much formed the exact same pattern as you guys even down to the way that you structure your modifiers and children with — and -. I’m really happy with this approach it’s simple enough that it doesn’t get in your way and still keeps everything nicely structured. Thanks for the great article.

  14. Permalink to comment#

    I would love to do this at work, but I’ve been getting no support for the idea despite how badly it’s needed. We have multiple designers who code the designs and hand them off for polishing, so it’s non-coders all coding differently, essentially. I feel like this would save soooo much time and headaches!

    I do have to say that double dashes in class names scare me, though. Other than that, I totally structure my personal code like that, a semantic item and its sub-items all named similarly. I never have to keep looking back to remember a class name. ;)

  15. Excellent article Ara. I actually just finished a complete front-end redesign for my company myself, and it’s amazing how similar our thought processes are. From similar goals, to using the LESS pre-processor, all the way to conceptualizing page elements using BEM methodology. I chose to use a slight variant of the BEM naming convention though, by prefixing modifiers with a double underscore instead:

    block--element__modifier
    

    A popular practice is to separate skin from structure, did you try this? Personally I found that keeping both skin and structure styles within the same selector was more convenient (as opposed to having to switch between multiple stylesheets/locations to style the same element). Instead, for most of my resuable “skin” related styles, I opted to abstract them into mixins and variables.

    • Luca
      Permalink to comment#

      I also tried to separate skin from structure in SASS. Didn’t work for me either, I was always asking myself “is this property in the structure or in the skin?”. It was a matter of seconds, but in the end it wasn’t worth it.

      I found way more useful to create a set of variables at the beginning of the file, which managed both the structure (height, padding, etc) and the presentation (color, borders, etc). Cleaner and easier to maintain, IMO.

  16. camper67
    Permalink to comment#

    Hi Ara – This is a great article, thanks!

    How large was your team, including you?

  17. lio
    Permalink to comment#

    Great design tutorial article, Thanks!

  18. Permalink to comment#

    Very interesting article. I love the strap-line of “Create your own Bootstrap”. I always learn from resources like Bootstrap but rarely use them on projects as i prefer to keep the code as waste-less as possible.

  19. Dan Smith
    Permalink to comment#

    Congratulations on taking the plunge, and thanks for a nice positive summary of what you and your team accomplished. I’ve been inventing systems like this for the past few years and there is a lot to consider to truly keep the system modular and prevent it from becoming a white elephant.

    My own ‘a-ha’ moment has been a slow realisation that it is a highly complex system that needs input, buy-in and support from more than just myself. Researching what is out there and discussing your ideas and assumptions with other people is really important to ensure that what you build is truly useful rather than just an expensive showpiece, and isn’t reinventing a wheel that already exists.

  20. Mark Simchock
    Permalink to comment#

    Great stuff. Thanks for the inspiration. No doubt this gets filed under: “If it were easy, everyone would do it.”

    A couple thoughts:

    1) While I appreciate the effort to develop your own framework, if you think of the entire effort as an integrated end-to-end system then to me it makes more sense to maintain modularity across all vectors within the system. A specific example would be the human resources slice and training. That is, finding someone who is Bootstrap-centric is going to be much easier than finding someone who knows your system (i.e., which is no one aside from the people you hire and train). Yours might be a better mouse trap, but does the benefit outweigh the added friction?

    2) Mind you, I understand there were extenuating circumstance, but to build out a framework because design was done in a silo / void also feels a bit “out of character” to me. Or as I like to ask: Name me a successful product company that does product design without any consideration for manufacturing. Toyota, for example, certainly doesn’t design a product (i.e., car) and then ask, “Okay, how are we going to build this? At a price the market will bear?” It’s an integrated system, not a series of silos connected by some spit & scotch tape process., yes?

    3) Which leads me to: Ara (or Chris) is any any chance of taking these concepts and ideals and doing an article / series to discuss how to (best) apply them in an agency setting? That is, one team (read: some core, some revolving) servicing many clients / brands? What are the must-dos, the watch-out-fors, etc.? How do you build a core tool box and then extend and customize that for individual projects and/or clients?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".