The New Behance: Better, Faster, Stronger with Sass

The new Behance features a multitude of new ways to explore and discover creative work. But what about the code that powers everything you see and interact with? What’s making everything look so good and feel so smooth?

A big part of the answer is CSS. There have been a lot of advancements in web development recently, not only in terms of the HTML5 and CSS specs but also in the multitude of tools that have been created to assist in CSS development. We can build cooler websites in less time, and the rapid release schedules of popular browsers like Firefox and Chrome mean that web developers can deliver more awesome faster than ever before.

In a series of posts over the coming weeks, we’ll tell you all about how we’ve leveraged various CSS tools and techniques to do different things, along with tutorials including CSS transitions, flexbox, and icon fonts. But we’ll start with the thing that has had the biggest impact on front-end development here at Behance in recent times: the CSS pre-processor Sass.



Part 1. The Sass Way

By now you have probably heard all the rage about CSS pre-processors. They let you do things that CSS developers have been wishing for for ages: variables, nesting, functions, math and so much more. Sound excellent? That’s because it is!

One of the most important changes we made to the new Network is one you can’t see it all. All of the new CSS on Behance was written using Sass, a pre-processor that adds an incredible level of functionality to our CSS development. We had no problem writing plain CSS before, but all the tools Sass provides helped make our code cleaner, more efficient, more reusable and more maintainable. There is a lot of information about preprocessors out there, so instead of providing a tutorial, I’ll show you a few ways that we are using Sass to make our CSS development better.



- Mixins

Mixins allow you to define styles that can be re-used throughout the stylesheet without having to duplicate code. We use them to great effect for printing gradients or properties that require vendor prefixes. For example, your code for a gradient might look like this:

.gradient {
  background: #1e5799;
  background: -moz-linear-gradient(top, #1e5799 0%, #7db9e8 100%);
  background: -webkit-gradient(linear, left top, left bottom, 
    color-stop(0%,#1e5799), color-stop(100%,#7db9e8));
  background: -webkit-linear-gradient(top, #1e5799 0%,#7db9e8 100%);
  background: linear-gradient(top, #1e5799 0%,#7db9e8 100%);
}


In Sass, our code looks like this:

.gradient {
  @include gradient( #1e5799, #7db9e8 );
}



Much cleaner! Because our gradient mixin specifies all of the various syntaxes for us, the resulting output is the same as the CSS above, but our Sass file is considerably less cluttered and in turn much easier to read and maintain.



- Variables and Loops

You can use variables to store values for a number of data types in Sass: numbers, strings, colors, booleans and lists. One of the most important ways we use them is for positioning sprites. Take our featured ribbon sprite for example:




Every ribbon for every network appears in a row. Hand-written CSS for this would probably look like:

.featured-ribbon {
  display: block;
  background-image: url('ribbons.png');
  width: 36px;
  height: 59px;
}

.featured-ribbon-digitalart {
  background-position: 0 0;
}

.featured-ribbon-toydesign {
  background-position: -36px 0;
}

.featured-ribbon-typography {
  background-position: -72px 0;
}

.featured-ribbon-branding {
  background-position: -108px 0;
}



Continued on for 20-something more ribbons. So instead of copy/pasting a rule multiple times and manually changing the y-position of the sprite, we leverage variables and loops to build out the CSS for us, like so:

// in practice, this list is over 20 items long
$networks: digitalart, toydesign, typography, branding, webdesign, illustration;
$ribbon_x: 0;
@each $network in $networks {

   .featured-ribbon-#{$network} {
    background-position: $ribbon_x 0;
  }
	
  $ribbon_x: $ribbon_x - 36px;
	
} // @each



In 10 lines of code, we’re able to print out the position of every ribbon in the sprite without even having to think about it. And since our network of sites is always growing, all we have to do when a new ribbon is added to the sprite is add a name to the end of the $networks list. If the ribbons are changed to be 38px wide instead of 36px, we only have to change one value instead of many. It’s as easy as pie.



- Nesting

Nesting is a powerful, dangerous beast. The first time you start nesting things, it’s easy to get carried away. It just feels so right! But you have to remember that it still translates directly into CSS. You know that the more selectors you add, the less efficient your CSS becomes, so you don’t want to nest things any more than you would “nest” them in plain CSS. Additionally, since tools like the Webkit Inspector and Firebug can’t show you Sass line numbers out of the box, the more deeply nested your selectors are, the harder they are to find in the Sass file.

.sidebar-block {

  position: relative;
  padding: 32px 24px 20px 22px;
  border-top: 1px solid #fff;
  border-bottom: 1px solid #dfdfdf;
  
  &:first-child {
    border-top: none;
  }
  
  &:last-child {
    border-bottom: none;
  }
  
  .viral-icons {
    margin-bottom: -10px;
  }

} // .sidebar-block



Outputs to:

.sidebar-block {
  position: relative;
  padding: 32px 24px 20px 22px;
  border-top: 1px solid #fff;
  border-bottom: 1px solid #dfdfdf;
}

.sidebar-block:first-child {
  border-top: none;
}

.sidebar-block:last-child {
  border-bottom: none;
}

.sidebar-block .viral-icons {
  margin-bottom: -10px;
}



Nesting is beneficial in a lot of ways, especially in that it groups related code, but again, we are very careful not to over-nest. When too many lines of code are nested, it’s easy to lose track of where you are in the sequence, making editing more difficult. Too many nested selectors, and now your CSS selectors are unnecessarily overqualified and inefficient. A quick audit of the resulting CSS file can make any overly-nested selectors clear very quickly.



- Imports and partials

Sass has an @import option that will let you import the contents of any other file into your Sass file. Primarily, we use it for importing a file full of variables across many Sass files.

Partials are also useful for files containing more than just variables. A partial is a Sass file whose name begins with an underscore (e.g. _myfile.scss). This file does not directly compile, meaning it doesn’t get compiled into a corresponding CSS file. We use this to extremely great effect on the new (upcoming) Served sites, which will be a blog post unto itself, but we also use it in a few areas of the network where we have a small, specific set of CSS that is re-used in various unrelated parts of the site.

Take our multiple owners image grid for example: it appears on project pages and collection pages which, aside from the grid, do not share many common styles. Rather than including an additional CSS file on those two pages, we keep the CSS in “_multipleowners.scss” and @import it in the Sass files for the project page and the collection page separately. If the grid were ever added to another page on the site, we would simply add another @import line to another Sass file. This makes for much more modular (and thus, maintainable) code.



- Color operations

Sass also has a number of useful built-in color operations. One of my favorite use cases is for RGBA:

rgba( #ac1d1c, .5 );



which Sass processes and compiles to:

rgba( 172, 29, 28, .5 );



Not only are the days of pulling RGB values out of Photoshop over, but you can also use those handy variables you already set up to easily convert to their RGBA value. Additionally, we use functions like darken to mathematically darken a color by a certain percentage rather than specifying more color values.



- We love Sass!

Sass has changed the way we write CSS for the better. Overall our code is simpler, cleaner, more modular, and easier to write and maintain. I don’t feel that Sass should be a replacement for knowing the ins and outs of CSS, and it can be certainly be used in a way that produces bad code; but when used as a tool on top of your CSS knowledge to help you be more efficient, Sass is a CSS developer’s dream come true.

Have any questions about our CSS or the way we use Sass? Leave a comment below!

You can follow me on Twitter at @jackiebackwards.