CSS

Structuring CSS Selectors With Sass Mixins

CSS naming can be one of the most challenging things in creating large-scale style systems in an application. There have been a lot of great practices, methodologies, and conventions that have arisen in the last few years to help.

Popular examples that you might have heard of include BEM, OOCSS, and SMACSS.

One that I would like to introduce to you is Sass. With the help of Sass, you can help enforce and modularize some of these naming conventions through mixins and selector nesting.

In this post, I will show why it’s a good idea to implement Sass to enforce BEM naming, including an introduction to native selector nesting and an example of Sass mixins. By following these practices, large-scale teams can write better and more scalable CSS.

Native Selector Nesting

In Sass v3.3, the native selector nesting feature was given to us. Boy was it embraced by the Sass community.

This feature is referenced by the & selector, and it can be used to reference and create part of a subclass name.

For example:

.block {
	// Styles for '.block'

	&__element {
		// Styles for '.block__element'
	}
}

This feature has been adapted for many BEM-like modules. One such example is the famous media object:

.media {
	&__image {

	}
	&__body {

	}
	&--rev {

	}
}

Which compiles to:

.media {}
.media__image {}
.media__body {}
.media--rev {}

As you can see, using Sass native selector nesting give us a very nice, structured naming convention for our modules.

But there can be some pitfalls for some newer developers of Sass when they come toe to toe with the & selector. It might be slightly confusing, if not scary, for developers that are not familiar with Sass. The & selector can also expose some not-Sass-savvy developers to bad nesting practices. As well as in regards to understanding the principles of BEM and correctly applying them to your selectors.

Readable BEM Mixins

In a large-scale Sass project, it may be hard to enforce naming conventions and principles for writing your Sass in BEM syntax. This can be difficult due to not having coding standards in place or varying levels of skill. Having built in coding standards built as mixins helps enforce these standards.

I came up with a few Sass mixins to help do just this very thing in a recent project I assisted on. Check it out:

@mixin class($name) {
    .{$name} {
        @content;
    }
}

@mixin has($name) {
    &__#{$name} {
        @content;
    }
}

@mixin when($name) {
    &--#{$name} {
        @content
    }
}

The whole idea behind this principle is to hide the Block-Element-Modifier jargon behind a common vocabulary that makes sense when read out loud. When used correctly, the code should read like story.

@include class("media") {
    // Styles for '.media' block

    @include has("image") {
        // Styles for '.media__image' element
    }

    @include has("body") {
        // Styles for '.media__body' element
    }

    @include when("rev") {
        // Styles for '.media--rev' modifier
    }
}

As you can see, the block above gives a clearer spoken outline of what the module is and the parts and modifiers of it. It keeps in-line with the BEM naming convention but makes it more developer-friendly when reading. This concept can be expanded upon to handle behavioral states, nesting, and much more.

Caveat

There is one caveat of implementing your selectors through a mixin dynamically like this. This approach prevents the selector code base from being searchable, as the selectors do not actually exist until they get generated by Sass.

For the project I was on, the sheer readability and uniformed selector creation outweighed this downside.

Final Thoughts

While the specific mixins from above may not be for everyone, BEM is undoubtedly an effective way to organize your front-end. I would encourage all front-end developers to explore the uses of native Sass selector nesting to help create modularized mixin systems to create a better application style strategy.

Reference: Structuring CSS Selectors With Sass Mixins from our WCG partner Keyhole Software at the Keyhole Software blog.

Lawrence Chabela

Front End Developer and Consultant at Keyhole Software by day | CSS3/HTML5 super hero by night I Content First Evangelist | Big Fan of Chex Mix
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button