- What are they?
- Why have them?
- How to use
- Open/close principle
- Applying at breakpoints
- Specificity
- Namespace
- New utilities
- Demo's
- Further reading
Utilities are low-level. They have a very narrow scope and may end up being used frequently, due to their separation from the semantics of the document and the theming of what they're being applied too. Think of them as helpers.
Utilities can form a wide variety of UI patterns from simple principles meaning as CSS authors you don't have to keep writing the same styles over and over again, instead you can abstract those common styles into nice reusable modules.
A classic use case for a utility is when a HTML list (ul
or ol
) items (li
) need to render horizontally rather than their default vertically stacked rendering. If we were to write our CSS in a non-OOCSS way then we would have to repeat the CSS over and over again to achieve this simple UI pattern, but using OOCSS techniques and the concept of a Scally utility we just declare it once like so:
%u-list-inline,
.u-list-inline {
> li {display: inline-block;}
}
So utilities are extremely powerful and are the real work horses of any sort of UI build especially large-scale UI builds, and here are some reasons why:
- Your CSS will be a lot DRYer.
- You can make far-reaching changes to your UI with simple modifications to a single utility.
- You have confidence in your changes because edits to a utility only ever alter one responsibility.
- You can combine utilities to make a variety of UI layouts.
Each utility class modifies a single trait which might be an individual style e.g.
// Center align text
%u-text-align-center,
.u-text-align-center {text-align: center;}
Or a small collection of styles e.g.
// Pin to all corners
%u-position-pin-all,
.u-position-pin-all {
left: 0;
right: 0;
top: 0;
bottom: 0;
}
To apply a trait, or a combination of traits, add the corresponding class or classes directly to the HTML element.
So say you wanted an element to pin it's itself to all corners of it's container then you would apply like so:
<div class="u-position-absolute u-position-pin-all"> ... </div>
However if the above div
was part of a component e.g. Modal then we apply the traits via a Sass silent placeholder selector applied with the @extend
directive. This is done for the following reasons:
- It’s more robust compared to having to rely on applying classes at the HTML level as classes can be missed.
- It’s more readable and maintainable to have all of the styles enclosed in one place: the Sass component partial.
So the above div
would receive a specific component class which would apply the styles via the @extend
directive meaning we can remove all of the utility classes from the HTML e.g.
HTML
<div class="modal__cover"> ... </div>
CSS
.modal__cover {
position: absolute;
@extend %u-position-pin-all;
}
You can see that position: absolute;
is not being @extend
ed here as it's only a single-line declaration therefore it's overkill to @extend
it i.e. there isn't any value from a readability, performance, or just general maintainability point of view. This article (starting from the text: Another case of an abused @extend
looks a little like this) does a very good job at further explaining why this isn't a good idea.
Utilities are really powerful when used in conjuction with other utilities as they can construct entire UI patterns by themselves i.e. without the need to create specific components. Take this classic UI pattern:
This UI pattern can be entirely constructed using a number of Scally utilities and their modifiers:
The HTML:
<div class="u-side-by-side u-divider-bottom u-s-pb-base u-s-mb-base">
<div class="u-side-by-side__left">
<img src"{{src}}" alt="...">
</div>
<div class="u-side-by-side__right u-s-p-base">
<h2 class="u-text-transform-uppercase u-s-mb-none">Title</h2>
<p>Habitasse pellentesque turpis nunc cras, a tincidunt, elementum nunc lectus lacus</p>
</div>
</div>
<div class="u-side-by-side u-side-by-side--reversed">
<div class="u-side-by-side__left">
<img src"{{src}}" alt="...">
</div>
<div class="u-side-by-side__right u-s-p-base">
<h2 class="u-text-transform-uppercase u-s-mb-none">Title</h2>
<p>Habitasse pellentesque turpis nunc cras, a tincidunt, elementum nunc lectus lacus</p>
</div>
</div>
Utilities follow the open/close principle, which states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
So Scally utilities can only ever be used as is. If an existing Scally utility needs to do more than what it offers then typically you'll be wanting to create a new component, or maybe the need for a new utility? Either way it should be scrutinised over like everything with OOCSS.
When building responsive UI's it is a really common requirement to apply a style or a set of styles at a specific viewport, and utilities are the prime suspects for this treatment as they're used so extensively. So each utility comes with the ability to be applied at any of the set breakpoints or any custom breakpoint.
Scally makes this easy by the Generate at breakpoints mixin
and this feature is turned off by default in favour of leaner stylesheets, and not all UI's are responsive.
A real common use case for this application is hiding UI at certain viewport sizes, typically at a mobile size viewport or a non-mobile size viewport.
So if we wanted to hide a Call Us button on larger viewports we would use the Display utility to achieve this, applying these steps:
- Turn the feature on by changing the toggle setting to
true
:
$u-display-breakpoint-toggle-hide: true;
which will output (compile) the utility in a media query like so:
@media (min-width: 40.0625em) {
.u-hide-from-lap {display: none;}
}
- By default the feature uses the
lap
breakpoint but you can change this to another breakpoint or add more breakpoints via this setting which you do in your main stylesheet above the@import
:
$u-display-breakpoints: (lap, lap-large)
@import "bower_components/scally/utilities/u-display";
This will output (compile):
@media (min-width: 40.0625em) {
.u-hide-from-lap {display: none;}
}
@media (min-width: 56.3125em) {
.u-hide-from-lap-large {display: none;}
}
Utilities always need to win when it comes to specificity (CSS' first C; the cascade) as they should always just work otherwise they're not doing their job properly i.e. you should never be needing to override a utility's styles. If you are then you're not using them correctly, see.
That's why utilities are declared last when pulling in the Scally framework via your master stylesheet so they're compiled after everything else.
All utility classes and utility silent placeholder selectors should be prefixed with u-
so that they're easily identifiable.
You can create new utilities in your project specific CSS however because utilities are so focused it's probably better off in the Scally framework. So create a Scally GitHub issue to have it considered for inclusion into the framework or even better submit a PR.
http://codepen.io/team/westfieldlabs/full/xFHfk/
Make sure to read the documentation within each utility Sass partial file as it will contain information about the utility and it's implementations.