Skip to content

Instantly share code, notes, and snippets.

@hugooliveirad
Last active June 2, 2017 11:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save hugooliveirad/8a8decd1c561c919304a to your computer and use it in GitHub Desktop.
Save hugooliveirad/8a8decd1c561c919304a to your computer and use it in GitHub Desktop.
Composing styles

Composing styles

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:

  1. Style an element to look like .nav-primary.
  2. 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.

@csswizardry
Copy link

I actually do this quite a lot! It works great when we are looking at (grid-style) layout specifically 👍

@hugooliveirad
Copy link
Author

Can you give another example where composition isn't a good pattern?

@csswizardry
Copy link

I don’t think it’s ever actively a bad idea, but sometimes you might not actually need grid-like layout contexts :)

@hugooliveirad
Copy link
Author

We can use composition with other things too. On the original example you could have a .page-head__nav-container to apply the float and the margin.

@csswizardry
Copy link

Yep yep! I’ve used .page-head__[major|minor] before, for placing a logo to the left, nav to the right (for example). I’ve also used:

<header class="page-head">
  <a href="/" class="page-head__logo  site-logo">...</a>

  <nav href="/" class="page-head__nav  nav-primary">...</nav>
</header>

Definitely not a solved problem yet!

@hugooliveirad
Copy link
Author

I would rather use the .page-header__whatever to wrap the site logo.

Definitely not a solved problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment