CSS Wizardry recently wrote a great post about styling: Contextual Styling: UI Components, Nesting, and Implementation Detail. He showed three ways to solve the problem of implementation details in a component's styles. I want to propose another way to solve this problem, one that uses composition.
The original styles of a .nav-primary
component are:
.nav-primary {
/* This is how the nav should always look: */
margin: 0;
padding: 0;
list-style: none;
font: 12px/1.5 sans-serif;
/* But this is implementation detail: */
float: right;
margin-left: 18px;
}
As CSS Wizardry wrote:
We have a group of styles which make
.nav-primary
look like the primary nav. These declarations are constant, and should remain intact whether .nav-primary is placed in our styleguide, or in our project, or in another project, or another one, and so on. We then have some styles who are responsible for making.nav-primary
float over to the right and have some leading margin on its left (presumably to stop it touching up to the site’s main logo). These styles are only needed when.nav-primary
is inside the project. This is implementation detail, and doesn’t really belong in this ruleset.
One way to abstract this implementation detail is through composition. We want to acomplish two thing:
- Style an element to look like
.nav-primary
. - Style an element to fit our header's (
.page-head
below) layout.
We can divide these two concerns in two components (using inuitcss BEM style):
<header class="page-head">
<div class="grid grid--one-third">
<img class="site-logo" ... />
</div>
<div class="grid grid--two-thirds">
<ul class="nav-primary">
...
</ul>
</div>
</header>
Here we used the .grid
component to manage the layout styles, freeing our .site-logo
and .nav-primary
components to only care about their own styles.
We can call them Pure Components, as they don't care about the outside world, just the inside.
I don’t think it’s ever actively a bad idea, but sometimes you might not actually need grid-like layout contexts :)