Utilities are your helper classes and typically your last resort when needing to apply styles to an element.
They apply really common CSS styles either as a single declaration e.g. float
an element to the right: .u-float-right
, or a very simple, universal pattern
(multiline declaration) e.g. hide an element but only visually:
.u-hide-visually
.
There scope is only ever one element i.e. utilities can't affect child elements of the element they're being applied too and they never have any styles that are concerned with cosmetics.
Utilities follow the single responsibility principle and the open/closed principle.
http://s.codepen.io/chris-pearce/full/WbMgMp (work in progress)
Utilities exist because every UI consists of really common styles that will need to be applied many times, therefore it makes sense to abstract these styles into nice reusable CSS snippets i.e. utilities. It's the same reason why objects and layout modules exist. The difference though with utilities is that they sit right at the bottom of the food chain—so to speak—in comparison to the other Scally sections, because they're so simple and low-level, and aren't too far away from inline styles.
With that said and even though it's rare they'll always be the need to apply utilities to a UI as not everything can be a component or taken care of by objects and layout modules. In these scenarios, if utilities didn't exist, we would have issues like:
- Where do these types of styles live in our CSS architecture?
- Lots of micro components that aren't true components.
- CSS not being as DRY and maintainable as it could be because we would have to keep writing the same styles over and over again.
Utilities help keep our CSS DRY and maintainable and more performant—resulting in drastically smaller stylesheets. And utilities allow you to make far-reaching changes to your UI with simple modifications to a single utility as you have the confidence in your changes because edits to a utility only ever alter one responsibility.
Each utility applies a single style e.g.
// Center align text
%u-text-align-center,
.u-text-align-center {text-align: center;}
Or a very simple, universal pattern (multiline declaration) e.g.
// Pin an element to all corners of its parent
%u-position-pin-all,
.u-position-pin-all {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
Utility classes are applied directly to the HTML element or @extend
ed via
it's Sass silent placeholder selector.
If the element already has a component class e.g. .c-box
then utility classes
shouldn't be applied to the element as the styling needs to be taken care of by
the component itself in order to keep the component nicely self-contained, see
the section below: Applying to components.
It should be acknowledged—like with most things CSS related—that the above is not completely black and white, what matters is that you know when you're overusing utilities.
They're two exceptions to utilities being your last resort: the
Spacing utility and the
Percentage widths utility. The Percentage widths
utility is a fundamental part of the Grid layout module giving the grid items
their percentage based widths e.g. .u-one-half
, .u-three-quarters
, etc. The
Spacing utility which includes a lot of spacing rules via the margin
and
padding
properties and should be used to apply spacing to the outside
(margin
) of elements especially components.
If we look at a snippet of the UI from this home page:
We can construct almost all of it using a mixture of:
- Base styles for things like headings, links, paragraphs, etc.
- Grid layout module to layout the sets of 2 and 4 columns.
- Container layout module to group this set of content, center align it and apply the global width.
- Button component for the More ... CTA buttons.
- Theme styles to apply the dark background and white text/yellow links.
The missing treatment is the center alignment of all the text and this is where
using a utility—one of the Text alignment utilities:
.u-text-align-center
—would make sense, otherwise we'd have to a) create a
micro component/object that just applies text-align: center
which is
overkill and doesn't fit the criteria of a component/object OR b) just
hack that style into our CSS architecture somewhere which can get real messy
quick.
We could just apply the utility to the main container element which would be the container layout module, like so:
<div class="l-container l-container--full-bleed u-text-align-center">
<div class="l-container">
[ ... ]
</div>
</div>
Note how the utility class comes last in the class attribute? The order is:
- Components
- Layout modules
- Objects
- Utilities
Preferably separated by 2 empty spaces to improve readability.
It's quite rare to apply utilities in the context of components as components
are discrete custom elements of a UI that enclose specific semantics and
styling therefore applying lots of utilities to them doesn't make them as
self-contained, portable, and maintainable as they need to be. The exception to
this is when we need to apply really common universal patterns which are
multiline declaration blocks e.g. hide an element but only visually:
.u-hide-visually
. When these types of utilities are needed you would apply
the utility via its Sass silent placeholder selector using the @extend
directive, rather than applying the utility class to the component HTML, however
some utilities can be applied to the component HTML:
As mentioned already the most important thing with utilities is knowing how to use them appropriately.
If we had a Modal dialog component and part of that component was the
overlay that sits behind the dialog—covering the entire viewport—we could make
use of one of the Position utilities: .u-position-pin-all
which will pin
an element—in this case the overlay—to all corners of it's parent—in this case
the main viewport.
A code example:
HTML
<div class="c-modal-dialog__overlay"></div>
CSS
.modal__overlay {
@extend %u-position-pin-all;
[ ... ]
}
And we may have to provide some text in this component for users of assistive technology e.g. screen reader users. In this case we can apply the utility class direct to the HTML as the element we're applying it too only exists for this reason therefore it's overkill to have to create a new component class just for this, especially when we may have to apply this treatment a few times. So it might look something like this:
<div class="c-modal-dialog__header">
<span class="u-hide-visually">Beginning of dialog window. It begins with a heading 1 called "Registration Form". Escape will cancel and close the window. This form does not collect any actual information.</span>
<h1 class="c-modal-dialog__title">Registration Form</h1>
[...]
</div>
Do not @extend
single declarations as there is no benefit in doing
this, components only need to make use of utilities when they're applying
universal patterns which are multiline declarations.
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.
To ensure this Scally does the following:
- Applies the
!important
keyword to all utilities to boost their specificity. - Declares all utilities last in the Scally framework so they're compiled after everything else.
All utility classes, silent placeholder selectors, settings, and filenames
are prefixed with u-
so that they're easily identifiable e.g.
.u-text-align-center
%u-text-align-center
$u-text-apply-at-breakpoints
_u-text.scss
Make sure to read the documentation within each utility Sass partial file as it will contain information about the specific utility and it's implementation.