Sass is now a common coding language in web development, and there are plenty of guides and tips out there. However, our developers have put together some guidelines for things they think are particularly important.

Key Concepts

Before getting down to specifics, there are a number of principles that are considered to be important enough to highlight.

Mobile-First

SuiteCommerce and SuiteCommerce Advanced are designed to be mobile-first; this means that (among other things) your Sass should be approached from the starting point of small-screen devices. In practice, this means that when you add new styles, you should first start with how the page should look on a mobile device and then add new styles for larger devices.

Take the following declaration as an example:

.my-class {
    position: absolute;
    top: 0px;
    width: 100%;
    text-align: center;
    height: 80%;

    @media (min-width: $screen-sm-min) {
        width: 50%;
        padding: $sc-base-padding;
        text-align: left;
        height: auto;
    }
}

In this example, we are declaring a number of styles and then embedding a media query for larger-screened devices with additional declarations. This means that the default styles are the mobile ones, and the tablet/desktop ones are the secondary ones.

Another important thing about this example is that the media query is inside the ruleset, and does not act a wrapper for them. This is important for modularization as the rulesets is there for the selector and not the screen width’s.

To give you another example:

/* Don't do this */
@media (min-width: $screen-sm-min) {
    .my-class {
        padding-right: $sc-base-margin;
    }
}

/* Do this instead */
.my-class {
    @media (min-width: $screen-sm-min) {
        padding-right: $sc-base-margin;
    }
}

Mobile-first isn’t just about media queries — it is a philosophy to keep in mind throughout all of your work. Another example of bad coding could be making excessive use of declarations like display: none to hide things from mobile users. This might be required now and then, but for crucial bits of functionality (or if you keep using it) then consider alternative experiences for mobile users. For example, you may be interested in push panes.

Keep it DRY

This means, “Don’t Repeat Yourself”.

A crucial part of Sass are keywords that cut out repetitive work; perhaps the chief among them is @extend because it takes the styles that apply to a previously specified selector and adds them to the current ruleset. This lets you build up common structures for your elements/molecules and then build them out for your classes as you need them. This means, for example, that we can provide a lot of base styles in our starting themes, and designers have a strong platform to get started on.

In practice, this means, for example, that styling buttons is super easy because you start by extending the base button classes (as appropriate) and then add in any additional styling you need.

.my-button {
    @extend .button-primary;
    @extend .button-medium;
    margin: $sc-small-margin 0;
}

This means that your element only needs one class (ie you don’t put my-button and button-primary and button-medium in its classes to get all of the styles).

There are some limitations to be aware of, however:

  • You cannot extend a nested selector
  • You cannot extend a selector that is wrapped in a media query (which is another reason to do this)

Use Semantic Class Names

By ‘semantic’ we mean ‘contextual’ — this means that when building up your template, you should use descriptive names for what the marked-up elements do. Here are some good semantic class names:

  • item-details-sku-container
  • header-menu-search-icon
  • profile-information-label

By looking at each of them, you can tell where they live and what they do.

As a contrast, compare them to the following names that some people may be inclined to use:

  • color-red
  • thick-border
  • text-center

These describe CSS properties and values. Some designers advocate (or advocated) for these sorts of ‘object-orientated’ class names with the intention that designers could then mark up elements with many of these to get the desired effect. In reality, this becomes very cumbersome and makes it much more difficult to account for different screen widths.

Consider another example: you mark up an element with a thick-border class to give it a thick border; if you want to change this, you need to change every instance where you have used it. Alternatively, classes that inherit from other classes can just be changed once and the result cascades through.

This approach creates modular Sass, which means that your styles should be able to pulled and swapped when the corresponding JavaScript module is removed or changed. Creating some generic class in one module and then using it another unrelated module later on could create dependency problems for you.

Variables

Another useful feature of Sass is variables. This lets you swap out hardcoded values in your styles for names that point to values instead. As mentioned above, this aids designers when site-wide changes need to be made (eg swapping out every instance of a color) and for ensuring consistency.

Variables are useful at a base level, and should be used for the following values:

  • Margins and padding (note also the * and / operators that let you multiply and divide values)
  • Font sizes, weights, and families
  • Colors (note that you can also use variables for lighter/darker variants of colors by using the lighten() and darken() functions)
  • Breakpoint widths for media queries

By default, in all our themes, we include a number of base variables that are used throughout the theme — you should modify these values when customizing your theme. You find them in BaseSassStyles/Sass/variables.

Avoid ‘Magic Numbers’

The term ‘magic numbers’ is used derogatorily to refer to a certain kind of hacky CSS code. They are used when a designer has tried to style something and has found that it is, for example, just a little too wide, or a little out of alignment. Rather than correct the mistake, the designer will then make an ad hoc change for the specific scenario.

In a lot of cases, these hacks will not be reliable either in future updates, or across multiple browsers/devices. It will also make extending these declarations difficult.

Create a Cheatsheet

If you find yourself struggling to remember your margins and padding, font sizes and colors, screen widths / breakpoints then make a single, easy-to-read page and have it in front of you when you’re coding. This could be digital or printed, or even hand-written. These notes will help keep you focused and streamlined when working.

Selectors

Deciding how to target your styling can get complicated in large applications like a web store.

Don’t Style IDs, and Avoid Element Tags

HTML IDs are meant to be used for unique elements, although in recent years they have also been reserved for JavaScript. Generally speaking, this is good advice as it creates a clear separation: JavaScript developers should feel at ease to add/edit/delete these when coding, and designers should instead aim classes.

When you select elements with IDs or tags, you either need to be making a very general and broad style, or you should revisit how your class naming convention (see above).

Here are a couple of examples:

// Don't do this
a.item-details-size-chart-link {
    ...
}

.look-item-cell {
    p {
        ...
    }
}

// Do this instead 
.item-details-size-chart-link { 
    // removed unnecessary element tag
    ...
}

.look-item-cell-description {
    // added new class on p tag, so I can target it directly
    ...
}

There are some exceptions to this, however:

  1. If you’re styling something where you don’t have access to the HTML (eg it’s been provided by a third-party) then sometimes all you can do is target IDs or HTML tags
  2. If you’re styling repeating elements (such as list items, table cells or rows, etc) then this is fine as long as you expect all of them to be the same (eg you may want to give all table header cells the same baseline styling, but then use classes to select individual ones with additional styling)

Reference Parent Selectors with &

You may have discovered, when trying to nest some selectors, that you run into difficulties with pseudo-selectors (such as :hover). It is possible to nest to these within the parent selector — you just need to use an ampersand (&).

Nested selectors are a shorthand way of writing a full declaration where the nesting acts a space. However, this is improper syntax in many situations — but that’s OK, you can reference the selector you’re currently in quite easily. For example:

.my-link-class {
    text-decoration: underline;

    &:hover,
    &:active {
        text-decoration: none;
    }
}

In this situation, the Sass will generate style declarations for the default, hover, and visited states without me having to specify them all directly.

Note that the ampersand effectively like a variable for the parent selector, so it can also be used at the end of a selector too:

// Example Sass
.my-parent-class {
    color: $my-color;

    .my-other-class & {
        color: $my-other-color;
    }
}

// Generated CSS
.my-parent-class {
    color: red;
}

.my-other-class .my-parent-class {
    color: blue;
}

This means you can keep all of this together and nested in the context of the parent selector.

But Don’t Overdo Nesting

I know I just told you how great it is, but it’s easy to do it too much. When you nest stuff, it can help make things modular, but it can also end up creating something fragile and difficult to read.

ul.menubar {
    list-style: none;
    > li {
        display: inline-block;
        > ul {
            padding: 10px 0;
            > li > a {
                color: black;
            }
        }
    }
}

This is valid but it runs against a number of guidelines. It takes a moment, but you can see that we’re trying to determine how to define the styling for nested list item objects. But we’re selecting elements too often; and what happens if there’s an ordered list instead of an unordered list?

To correct this, assign classes to your list and list item elements (and use variables for padding and colors).

.menubar {
    list-style: none;
    & li {
        display: inline-block;
    }
}

.nested-menu {
    padding: $sc-base-padding 0;
}

.nested-menu-item-link {
    color: $sc-color-copy-dark;
}

Consistent Style

If you are starting a new project (such as skinning a new site) then spend some time thinking about the best way for you and your team to work. If you’re going to set rules, then make sure you document them and share them with your team.

Here are some examples that you may want to follow.

Declare Variables at the Top of the Page (Or Use a Separate File)

We keep all globally important styles and variables in our BaseSassStyles module, and you are free to modify these as you need. If you require new variables, be deliberate when choosing where to put them. If they are module specific, keep them with the other files in that module; if they are global, consider a separate space. If they are just required in one file, put them at the top of that file.

Comma-Separate Selectors onto New Lines

In other words, avoid ‘long syntax’. The Sass compiler is happy for you to break up rule sets that have multiple selectors onto new lines. It improves readability, for example:

.my-class,
.my-other-class {
    padding: $sc-base-padding;
}

Consistent Indentation and Spacing

Everyone has preferences when it comes to two or four spaces (or even tabs); it doesn’t really matter, which one you use just so long as everyone uses the same.

Take time to agree which one you will use, communicate it to everyone, and then make sure your IDEs are set up to do it automatically.