Using Helper Classes to DRY and Scale CSS
You are starting a new web project and looking for a new CSS methodology that will help you scale your code. A growing set of techniques for writing modular CSS are available, including SMACSS, BEM, and a number of other similar methodologies, all based on Object-oriented CSS (OCSS). As you can see, there are lots of techniques to write and organize CSS.
Besides all these methodologies, there is something that can help us write DRY, less repetitive code: Helper classes (also called utility classes).
This concept was discussed some time ago in Thierry Koblentz’s article on Smashing Magazine, but I thought I would explain the method in my own words here.
What Are Helper Classes?
Helper classes can help remove repetition by creating a set of abstract classes that can be used over and over on HTML elements. Each helper class is responsible for doing one job and doing it well. Doing this will make your code more reusable and scalable for many features that will be added in the future. So whenever you want to create a new component, you’ll just need to combine some classes together to build it.
“Treat code like Lego. Break code into the smallest little blocks possible.” — @csswizardry (via @stubbornella) #btconf
— Smashing Magazine (@smashingmag) May 27, 2013
Let’s see a simple example of what utility classes look like and how we can use them. Look at the following snippet of code:
.left { float: left; }
.right { float: right; }
.text-left { text-align: left; }
.text-right { text-align: right; }
.text-center { text-align: center; }
Here we’ve created a set of CSS rules that we can use later when building new components. For example if you want to align some content to the left you can use the text-left
class. Likewise, you can use the left
or right
classes to float elements in the needed direction.
Let’s see another example of a box that needs to be on the left with its inner content centered.
We usually do something like this:
<div class="box">
</div>
With this CSS:
.box {
float: left;
text-align: center;
}
Instead, we can achieve the same thing using reusable and single-responsibility helper classes:
<div class="left text-center">
</div>
Notice how I removed the box
class and instead added our predefined classes left
and text-center
.
If you want to change the float and align directions, instead of doing this on the non-reusable .box
class, you can use other helper classes:
<div class="right text-right">
</div>
The grid system is a good example of helper classes in use. Here is an example from Foundation’s grid:
<div class="row">
<div class="small-2 large-4 columns"></div>
<div class="small-4 large-4 columns"></div>
<div class="small-6 large-4 columns"></div>
</div>
Foundation provides numerous classes that can be used and combined together to create a grid system with different widths for different screen sizes. This flexibility helps developers create new customized layouts faster, without editing any CSS for the grid itself. For example:
.small-2
and.large-4
classes will set the width of an element based on the screen size.- The
.row
class sets the width of the container that holds the columns. - The
.columns
class sets the padding and floats.
Now that you understand what helper classes are, let’s take a look at some reusable classes we can add to our projects, presented below in different categories. Note also that the example will use some Sass variables, but naturally these are not necessary.
Margins and Padding
Margins and padding are probably the most used properties in our CSS. Adding some abstract classes that can handle this will DRY our code.
We start by defining a variable (using Sass) for the base space unit for our design. Let’s start with 1em
and on top of that we can create classes for different space sizes.
$base-space-unit: 1em;
// Top margin
.margin-top-none { margin-top: 0; }
.margin-top-quarter { margin-top: $base-space-unit / 4; }
.margin-top-half { margin-top: $base-space-unit / 2; }
.margin-top-one { margin-top: $base-space-unit; }
.margin-top-two { margin-top: $base-space-unit * 2; }
// Top padding
.padding-top-none { padding-top: 0; }
.padding-top-quarter { padding-top: $base-space-unit / 4; }
.padding-top-half { padding-top: $base-space-unit / 2; }
.padding-top-one { padding-top: $base-space-unit; }
.padding-top-two { padding-top: $base-space-unit * 2; }
We can alternatively choose short class names, as in the example code below from Basscss
.m0 { margin: 0 }
.mt0 { margin-top: 0 }
.mr0 { margin-right: 0 }
.mb0 { margin-bottom: 0 }
.ml0 { margin-left: 0 }
Choose what works for you and your team. The long names will obviously make your HTML elements larger, but they are more readable in contrast to the short names, so you may need to look at your CSS to figure out how things work.
Width and Height
Imagine you want to set a section to be full height in different places on your website. The traditional way we did this was something like this:
<div class="contact-section">
<!-- Content here... -->
</div>
And our CSS:
.contact-section { height: 100%; }
For other sections we would repeat the code:
<div class="services-section">
<!-- Content here... -->
</div>
And the CSS:
.services-section { height: 100%; }
But we can reduce all of this with one class called full-height
:
<div class="full-height">
<!-- Content here... -->
</div>
Below are some similar examples, including the full-height
class used above:
.fit { max-width: 100%; }
.half-width { width: 50% }
.full-width { width: 100%; }
.full-height { height: 100%; }
Position and Z-index
Position-related properties can be combined with other properties like z-index
to create a complex layout. We can create a set of classes to set the exact position of any element in relation to the viewport or an ancestor element (right, left, top left, etc):
.fixed { position: fixed; }
.relative { position: relative; }
.absolute { position: absolute; }
.static { position: static; }
.zindex-1 { z-index: 1; }
.zindex-2 { z-index: 2; }
.zindex-3 { z-index: 3; }
.pin-top-right {
top: 0;
right: 0;
}
.pin-bottom-right {
bottom: 0;
right: 0;
}
The “pin” helper classes are inspired by Mapbox’s CSS.
Let’s extend the full-height example to contain an element positioned at the bottom right.
<div class="full-height relative">
<div class="absolute pin-bottom-right padding-one">
Text to bottom right
</div>
</div>
By combining more than one class, we can get the required result in less code. If you want to position the inner element at the top right, you can use the pin-top-right
instead of pin-bottom-right
. You might have noticed in the above code I also added another helper class: The padding-one
class ensures the element isn’t flush against the edge of the container or viewport.
Floated Elements
Floating elements left or right can be done using left
or right
classes. The well-known clearfix class can be used on the parent element to clear floats, shown below using Sass’s parent selector:
.left { float: left; }
.right { float: right; }
.clearfix {
&:before,
&:after {
content: "";
display: table;
}
&:after { clear: both; }
}
Aligning Elements
We can make text and other content align to any direction, using align-based helper classes:
.text-left { text-align: left; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.text-just { text-align: justify; }
.align-top { vertical-align: top; }
.align-bottom { vertical-align: bottom; }
.align-middle { vertical-align: middle; }
Visibility Classes
Visibility classes control the visibility of elements, depending on the screen size, device orientation, touch screen, or other factors. These can come in handy in responsive designs.
We could have the following classes inside of our media queries:
.hide-on-small { display: none; }
.show-in-large { display: block; }
And in our HTML:
<div class="hide-on-small show-in-large">
<!-- content here... -->
</div>
The above element will be hidden on small screens but will be visible on larger screens.
We can also use these classes to control elements on touch devices:
.touch .show-for-touch { display: none; }
.touch .hide-for-touch { display: inherit; }
In the example above, the .touch
class would come from the classes added to the <html>
element by Modernizr.
A good example of visibility classes are the ones in Foundation and Bootstrap’s responsive-utilities.
Typography
In typography you can create classes for things like font weight and text manipulation, like ellipsis text.
.bold { font-weight: bold; }
.regular { font-weight: normal; }
.italic { font-style: italic; }
.ell {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.break-word { word-wrap: break-word; }
.no-wrap { white-space: nowrap; }
Colors
Every application has different guides and brand rules which we can define in classes that essentially ‘skin’ our interface. This would include text color, backgrounds, and more.
Lets see how this can be translated to code. First let’s define our variables with Sass:
$white : #fff;
$gray : #2c3e50;
$dark-gray : #95a5a6;
$dark : #2c3e50;
$notice : #3498db;
$success : #1abc9c;
$alert : #e74c3c;
Then we define our helper classes, based on the variables:
// Colors
.white { color: $white; }
.gray { color: $gray; }
.dark-gray { color: $dark-gray; }
.notice { color: $notice; }
.success { color: $success; }
.alert { color: $alert; }
// Backgrounds
.white-bg { background-color: $white; }
.gray-bg { background-color: $gray; }
.dark-gray-bg { background-color: $darkgray; }
.notice-bg { background-color: $notice; }
.success-bg { background-color: $success; }
.alert-bg { background-color: $alert; }
Two good examples of using color and background helper classes are found in the Mapbox and the Google Web Starter Kit projects.
Another use case is the notification component. Let’s see how we can style this with background helper classes.
<div class="white p1 mb1 notice-bg">Info</div>
<div class="white p1 mb1 success-bg">Success</div>
<div class="white p1 mb1 alert-bg">Alert</div>
Lists
How many times have you wanted to get rid of the bullets and padding from the ul
element? A class called list-bare
, as used in inuitcss, can do that for you.
.list-bare {
padding: 0;
list-style: none;
}
Borders
Helper classes can be used to add borders to an element, whether for all sides or one side. So your CSS/Sass might look like this:
$border-color: #f2f2f2;
.border-all { border: 1px solid $border-color; }
.border-top { border-top: 1px solid $border-color; }
.border-bottom { border-bottom: 1px solid $border-color; }
.border-right { border-right: 1px solid $border-color; }
.border-left { border-left: 1px solid $border-color; }
Display Values
The following helper classes give us the ability to use the different values for CSS’s display
property:
.inline { display: inline; }
.block { display: block; }
.inline-block { display: inline-block; }
.hide { display: none; }
.flex { display: flex; }
Conclusion
Following this principle of abstraction might be a much different approach from what you are accustomed to when authoring CSS. But based on my experience, and that of others I can say this is a very good approach to consider on your next project.
You can check out all the helper classes from this post in a new library I created called css-helpers.
Relevant Library Links
You can learn from and explore the structure of the following projects:
- Mapbox styleguide – base.css
- Basscss
- Foundation Utility classes
- Bootstrap Helper classes
- Uikit utility classes