Monthly Archives: March 2015

SUIT CSS practical implementation guide

SUIT CSS naming conventions

SUIT CSS relies on structured class names and meaningful hyphens (i.e., not
using hyphens merely to separate words). This helps to work around the current
limits of applying CSS to the DOM (i.e., the lack of style encapsulation), and
to better communicate the relationships between classes.

The primary architectural division is between utilities and components.

N.B: The majority of this file is taken from SUIT CSS Naming Conventions, except where indicated by an asterisk ( * ).

Anything marked with an * has been added by myself as a way to provide more detailed implementation notes.

Utilities

Low-level structural and positional traits. Utilities can be applied directly
to any element within a component.

Syntax:

u-[sm|md|lg-]<utilityName>
<a name="u-utilityName"></a>

u-utilityName

Utilities must use a camel case name. What follows is an example of how various
utilities can be used to create a simple structure within a component.

<div class="u-cf">
    <a class="u-floatLeft" href="{{url}}">
        <img class="u-block" src="{{src}}" alt="">
    </a>
    <p class="u-sizeFill u-textBreak">
    
    </p>
</div>

Responsive utilities

Certain utilities have responsive variants using the patterns: `u-sm-<name>`,
`u-md-<name>`, and `u-lg-<name>` for small, medium, and large Media Query
breakpoints.

Restrictions *

Utilities should be used sparingly in a project intended to go into production. They are there as a convenience to aid rapid development, but when used inside a Component, it’s far more useful to style an element based on it’s intended purpose. If you need to use more than one Utility to get the desired effect, then it’s less verbose to actually give that element it’s own class within the Component’s structure.

<!-- BAD -->
<div class="Component">
    <p class="u-textAlignLeft u-floatRight"></p>
</div>
 
<!-- Also Bad -->
<div class="Component">
    <p class="Component-bodyText u-floatRight"></p>
</div>
 
<!-- Good -->
<div class="Component">
    <p class="Component-bodyText"></p>
</div>

Components

The CSS responsible for component-specific styling.

Syntax:

[<namespace>-]<ComponentName>[--modifierName|-descendantName]

This has several benefits when reading and writing HTML and CSS:

* It helps to distinguish between the classes for the root of the component,
descendant elements, and modifications.
* It keeps the specificity of selectors low.
* It helps to decouple presentation semantics from document semantics.

namespace (optional)

If necessary, components can be prefixed with a namespace. For example, you may
wish to avoid the potential for collisions between libraries and your custom
components by prefixing all your components with a namespace.

.twt-Button { /* … */ }
.twt-Tabs { /* … */ }

This makes it clear, when reading the HTML, which components are part of your
library.

ComponentName
<a name="ComponentName"></a>

The component’s name must be written in pascal case. Nothing else in the
HTML/CSS uses pascal case.

.MyComponent { /* … */ }
<article class="MyComponent">
</article>

ComponentName–modifierName

<a name="ComponentName--modifierName">

A component modifier is a class that modifies the presentation of the base component in some form (e.g., for a certain configuration of the component).

Modifier names must be written in camel case and be separated from the component name by two hyphens.

The class should be included in the HTML in addition to the base component class.

/* Core button */
.Button { /* … */ }
/* Default button style */
.Button--secondary { /* … */ }
<button class="Button Button--secondary" type="button">…</button

ComponentName-descendantName

<a name=”ComponentName-descendantName”></a>

A component descendant is a class that is attached to a descendant node of a component. It’s responsible for applying presentation directly to the descendant on behalf of a particular component. descendant names must be written in camel case.

<article class="Tweet">
    <header class="Tweet-header">
        <img class="Tweet-avatar" src="{{src}}" alt="{{alt}}">
        
    </header>
    <div class="Tweet-bodyText">
    
    </div>
</article>

ComponentName.is-stateOfComponent

<a name=”is-stateOfComponent”></a>

Use `is-stateName` to reflect changes to a component’s state. The state name must be camel case. **Never style these classes directly; they should always be used as an adjoining class.**

This means that the same state names can be used in multiple contexts, but every component must define its own styles for the state (as they are scoped to the component).

.Tweet { /* … */ }
.Tweet.is-expanded { /* … */ }
<article class="Tweet is-expanded">
</article>

Notes and recommendations *

While the above provides good guidelines on naming structure, it doesn’t deal with “What to do when…”. Here we’ll try and draw out any unusual use cases and draw forth potential solutions to these. As mentioned before, this section has been asterisked to indicate that it’s my own recommendation. Please feel free to comment on this post if your approach would differ from what has been here documented.

SASS parent selector markup

In current versions of SASS, it’s possible to use the parent selector ‘&’ to create a new class composed of the parent and a suffix. This is especially useful for our purposes as it means we can create a self-contained Component block of SASS e.g.

.Component {
    &-descendantName {
        ...
 
        &--modifier {
            ...
        }
    }
}

This allows us to vastly reduce the amount of SASS we need to write, while also producing classes with a low specificity. For example, the above code produces the following 2 classes, each of which has a specificity of 10 (or 0, 1, 0 if you’re that way inclined).

.Component-descendantName {
    ...
}
.Component-descendantName--modifier {
    ...
}

Components within components

As far as I’m concerned, a Component should hold majesty over all who reside within it. In much the same way as the heart is it’s own structure with it’s own function, but when it’s inside a larger corporeal being, that body determines where it resides. I’ve seen a few examples where nested components are also given descendantName selectors e.g.

<!-- Not recommended -->
<div class="Component">
    <div class="AnotherComponent Component-anotherComponent">
        <p class="AnotherComponent-bodyText"></p>
    </div>
</div>

I think this is bad form, even though I can see the logic behind it. In this example, AnotherComponent may well exist in several contexts in an app, but this code specifically ties the DOM to this usage. The CSS for this is transparent enough, but I’d propose the following markup and SASS as an alternative:

<div class="Component">
    <div class="AnotherComponent">
        <p class="AnotherComponent-bodyText"></p>
    </div>
</div>

 

.AnotherComponent {
    &-bodyText {
        ...
    }
}
 
.Component {
    ...
    
    .AnotherComponent {
        ...
 
        &-bodyText {
            ...
        }
    }
}

In this way, Components can be used in any context (thus making their code portable and ‘directivable’ without needing to shoehorn extra classes in there), and any manipulations required due to the new context are handled by the responsible parent Component.

ComponentName-descendantName-descendantName

This approach is frowned upon – see this discussion, which revolves around the following use case:

 

<div class="Component">
    <header class="Component-header">
        <a class="Component-header-link" href=""></a>
        <!-- Or -->
        <a class="Component-headerLink" href=""></a>
    </header>
</div
At the end of the discussion, the most popular solution is to make ComponentHeader it’s own component within “Component”
<div class="Component">
    <header class="ComponentHeader">
        <a class="ComponentHeader-link" href=""></a>
    </header>
</div>
Happy to consider alternatives as you guys see fit although double-descendants don’t frighten me personally.

Modifier and state inheritance

Modifiers needn’t just affect the direct element they’re applied to – they can also change the appearance of any nested Components further down inside that DOM tree. This could lead to some convoluted-looking SASS. Take the following example:

<div class="Component Component--modifier">
    <div class="AnotherComponent">
        <p class="AnotherComponent-bodyText AnotherComponent-bodyText--modifier"></p>
    </div>
</div>

Say for example that the Component–modifier here was a theme for this component. This would change the theme for all nested components too, which means it would likely need to reach down into AnotherComponent-bodyText to alter it’s colour.

.Component {
    background: blue;
    
    .AnotherComponent {
        background: red;
        
        &--modifier {
            font-weight:bold;
            color: white;
        }
    }
    &--modifier {
        background: black;
    
        .AnotherComponent {
            background: white;
            
            &--modifier {
                color: black;
            }
        }
    }
}

As you can see here, modifiers are placed at the end of each declaration so ensure they are always the dominant style over any given base class.

Equally, States can affect descendants as well, although it is recommended to keep the class as close as possible to the area it’s going to affect e.g.

<div class="Button is-active">
    <span class="Button-icon"></span>
</div>
.Button {
    background: black;
    &-icon {
        color: black;
    }
    
    &.is-active {
        background: white;
 
        .Button-icon {
            color: black;
        }
    }
}

States also appear at the end of any given class definition, after any modifiers that may be applied. States are naturally more specific than modifiers (in the example above, if the Button had a modifier it would be of specificity of 10, whereas the generated class for .Button.is-active has a specificity of 20), so this is a very natural place for them to reside in the declarative order of things.