Maintaining Reusable Stylesheets: Overview of SMACSS

Created by Jonathan Snook, SMACSS, or Scalable and Modular Architecture for CSS, is one of a handful of working practices to promote the writing of consistent, maintainable, and understandable CSS. There might be further considerations to push towards more efficient code, however as the savings in processor time are minimal it is probably best to neglect this metric in favour of saving programmer time. SMACSS is distinguished from its competitors such as OOCSS and BEM, by its emphasis on using selector names which fall into categories determined by their type and function. Sticking to vanilla CSS, SMACSS starts from the principle of sticking to class selectors as much as possible to prescribing rules relating to, naming conventions, state changes, selector depth, and modularity.

Sticking to Classes

We want to stick to using classes, and classes only. Classes are reusable, which is good for modularity and future-proofing, and as for styling purposes ids give us no added benefits in terms selector performance. Although this practice places an absolute premium on our naming convention, provided we are consistent and plan ahead, using classes alone should not put us at any disadvantage.

Naming Conventions

SMACSS splits CSS selectors into five different categories: base, layout, module, state, and theme. This is our first line of defence in maintaining a DRY stylesheet, the categories relate as follows,

  • Base rules are defaults, usually provided by something like normalize.css. These are an exception to the rule above, as they usually apply to element tag selectors.
  • Layout rules are the containers for our module rules, these relate to the spatial divisions within our page. The class selectors for these rules follow the pattern l-<name> e.g. l-fixed.
  • Module rules are the mainstay of our stylesheet. These are highly reusable parts of stylesheet, we put anything we want shared across multiple distinct elements here. There isn’t such a straightforward naming convention to follow due to the frequency of use, however we do want to stick to semantically meaningful, generic, and reusable class names.
  • State rules determine styling for state changes such as user interactions, selector names follow the pattern is-<state-name> e.g. is-active.
  • Theme rules can add an additional layer of styling for customisation or typography.

To elaborate a bit on terming selectors “semantically meaningful”, class names should indicate how selectors relate to content on the page, and how they relate to one another. For instance indicating parent-child nesting by a shared prefix, we will cover this in more detail below. This practice both rules out using element selectors in general - although HTML5 gives us some help here - and more broadly, ensures that our class names clues us onto the function of a given selector.

State Changes

Naming state style rules is one thing, but applying them usefully is quite another. SMACSS doesn’t so much prescribe a particular way of rendering state changes so much as putting an emphasise on using the most appropriate way of handling the state change in question in keeping with our considerations for modularity etc. For instance, if we were to represent a state change using class names we would want to ensure the code is not heavily dependent on the DOM structure: rather than target a parent container with our CSS selectors stick with a sibling selector instead.

Selector Depth

The aim of the game is to go for as shallow a depth with as few selectors as possible. Taken together, this looks to make the styling as modular as possible: it will ultimately be very generic and be less dependent on the DOM structure.

A good practice is to avoid duplication, for instance the following,

  .classy-name div, .equally-classy-name div {
    /* funky styles */
  }

should be a cue to introduce a joint class name to target both elements.

The added benefit of using few selectors is that we needn’t make use of ids or !important overrides unless absolutely necessary. We would simply add in another class name to get the desired styling to render, this is important when considering sub-modules below.

Modularity

We’ve pretty much touched on modularity throughout, which is not particularly surprising considering its importance in SMACSS (it’s in the name!). However, we have not discussed sub-modules: when needs be, we might want to distinguish a particular module based on its location or use within the page e.g. a sidebar as opposed to a pop-up, with a common parent class selector. As before we want to keep our code as generic as possible. To do so we would use an additional class selector with a name that reflects its parent container, perhaps by using a shared prefix.

Wrapping Up

Admittedly there is very much more to cover, such as how to make the most of preprocessors using SMACSS and some other formatting considerations. Thankfully there is very much more information on the topic, not least the official website and book. I myself am very new to the practice, and am sure to return to the topic in the future.

As always, all the best,

Tom

Git Merge Conflicts with Binary Files

Recently I had to deal with a situation that I’ve some how managed to avoid for a surprisingly long time: merge conflicts due to mismatched binary files, in this case image files. Now Git being Git, there are a number of equally viable ways of resolving any given problem - and thinking back, I do slightly regret not giving more time to investigating the arguably cool-sounding git mergetool. In general, binary files can be a bit of headache with Git due to the difficulty of dealing with their diffs. This can be a cause for concern due to the need to manually resolve some issues further down the line, although there is help out there.

That said, diffs aren’t so much a problem with image files. In my case, I made use of git checkout using the --ours and --theirs options, for instance git checkout --ours -- myfile.png. Appending one or the other option to git checkout allows you to checkout your or their committed file respectively. This saves you the effort of resolving the merge conflict manually.

All the best,

Tom

The Path to Git Enlightenment Part 1

If my twitter feed is anything to go by, lately I’ve been spending some time looking at CSS regression testing using BackstopJS - more on that to come. Invariably though it led to some minor hiccups that really messed up my git-chi. For those who haven’t used BackstopJS in it’s current, rather nascent state, it can be a bit messy to get started for a relative noob like myself. Upon installation, its files sit in a bower_components/backstopjs directory, which is a-ok.

However, annoyances quickly followed as I tried to selectively ignore or track subdirectories and files of the new backstopjs directory. The project comes with it’s very own .gitignore file, which is all very well, unless of course you want to place everything into the one gitignore file at the root directory of your project. The solution I’ve come across is not particularly clean, but is well documented. For instance if you have a directory structure,

.
├── index.html
└── js
    ├── main.js
    ├── experiment.js
    └── lib
        └── ext.js

where we may very well want to track main.js, but ignore everything else. The documentation above makes it clear that we can’t just get away with adding an exception for main.js,

It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.

In other words, we need to specify the parent directory of every file we wish to track. Following this logic our .gitignore should look something like this,

*
!js
!main.js

An unfortunate consequence of this is that we would have to specific every parent directory for a given file if we wanted particularly fine-grained control over tracked files.

In the process I also learnt a neat trick with the git status command. If I wish to see all my untracked files, not just directories as per default, I need to add -u option. This will print out all the individual untracked files, which is particularly useful when specifying specific files as above.

All the best and happy New Year!

Tom

Sharing your Sublime Text Configuration

I’ve spent the past few days sorting out my configuration for a new macbook, one hurdle has been sorting out my Sublime development environment. Users of Sublime Text, myself included, do not typically use symlinked dotfiles to store their settings as is discussed here, but rather copy over settings files wholesale.

The simplest and safest way - it may not be wise to copy plugins - to do so,

  1. From your old workstation, make a copy of your current Preferences.sublime-settings and Package Control.sublime-settings both of which should be found in Packages/User/, and send to your new workstation,
  2. From your new workstation, install Package Control,
  3. Place the two copied files in the User directory.

My particular story did not end there: On an initial startup of Sublime I was greeted with alert “The package specified, Jasmine, is not available” or in other words we have a reference to a defunct package. To fix this, I deleted the named package from Package Control.sublime-settings.

Of course this is perhaps the most labour intensive way about it. Having searched around after the fact there are many alternatives to automate the process including this shell script.

All the best,

Tom

Jekyll: Add Caption to Image

Having only relatively recently started to blog using Jekyll, I’ve only just come across the problem of trying to add captions to images - sans plugin.

Fortunately Jekyll is very easily extensible with some straight-forward HTML/CSS. Of course, following the framework’s separation of concerns, we need to do three things: Add markup to our _includes folder, update our stylesheet, and finally include a reference to our markup in the blog post file.

In the _includes folder, I created a new file called image.html, which includes,

<figure class="center">
  <img src="{{ include.url }}" alt="{{ include.description }}"/>
  <figcaption>"{{ include.description }}"</figcaption>
</figure>

with a CSS class center with properties adjusted to taste.

Turning to the blog post, I want to add,

{% include image.html url="/path/image.png" description="Caption" %}

making use of Jekyll’s include tag. Everything should be self-explanatory, although it should be said that I’ve used a relative path to the image file as prefxing url with site.BASE_PATH led to a Liquid Exception. Et voilà,

Salt of the Earth character
Salt of the Earth character

and of course we can add any sort of customisation from here.

All the best,

Tom

Creating a GitHub Repo from a CLI

Having spent the past couple weeks wrestling with what to write about I’ve settled on this helpful tidbit. My constant need to refer to this basic workflow is some indication that (a) it’s useful, and (b) I really ought to have better recall. Although there are helpful command-line tools out there that steamroll over much of what is to follow, I myself am in a bit of Homebrew limbo, not to mention the following is arguably more enlightening.

Aim of the game: Create a repo from a command-line interface and push the local repo to GitHub. This gives us that much more control in setting up the initial directory structure before starting out on a project. Having run a git init in our root directory and made our first commit we can get started.

First we need to create the GitHub repo from the command-line. To do this we use the unix curl command, which allows us to interact with the server. Following the GitHub API we write,

  curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'

where we specify our GitHub username and the repo name in place of ‘USER’ and ‘REPO’ respectively. The option -u specifies the username (and password) to be used, and -d indicates a POST request. At a minimum we should specify our username and the repo name. We can easily include more information in the POST request as required. We can also specify further authentication following the -u parameter if desired. Following exactly as above, we will be prompted to type our password after entering the curl command.

Now to add the remote,

  git remote add origin git@github.com:USER/REPO.git

where ‘USER’ and ‘REPO’ are our GitHub username and the new repo name, as above. This creates an alias for the URL specified, in all subsquent push commands we need only specify our remote with origin, which will be understood as the full URL.

It should be said that this step require you to already have set up an SSH key with your GitHub account, if not you can follow the steps here. You can just as easily push to an HTTPS URL, which is this case would correspond to, https://github.com/USER/REPO.git.

And finally, we can push our new project to our remote repo,

  git push origin master

With any luck, we should have a commit in our newly minted remote repo.

All the best,

Tom

Updates and Whatnot

Hopefully I’ll be in a position to post actual factual content soon enough, so yay!

In the meantime I thought it would be useful to list all the resources I’ve used so far to get my blog in the state you see it in now.

Behind the scenes, I’ve added Thor following pretty much the same steps as per the linked blog post. Pretty obviously, this speeds up my workflow just a bit: getting rid of the need to add all the front matter by hand. One issue that I came across was how best to create nice looking URLs for each blog post. I haven’t found a definite answer so far, my solution was to add to my jekyll.thor file,

# Other code
  post.puts "permalink: \"#{title.downcase.gsub!(/\s/,'-')}\""
# More code

where title is the name I give the post from the command line. The permalink for each page will simply be constructed out of the title rather than the entire file name including the date. I’m using the jekyll-sitemap gem to automatically generate a sitemap for SEO goodness. Finally, maybe stating the obvious, but I’m hosting using GitHub Pages, for cost and ease of use with Github.

Upfront stuff: I’m really happy with the overall look and feel of the dbyll theme, looks great on mobile and easy to customise. I changed my gravatar using Pixen, ultimately I want to graduate to a decent looking 16 bit cat.

I purchased my domain name through Namecheap and followed the steps here.

Most of the other setup including adding Disqus and adding Google analytics went pretty much as per the available documentation. Further instruction can be found here. Other than that, there’s always this handy documentation.

All in all, it was a good learning experience with a shallow learning curve. I’d like to add more functionality in the future, but for the time being I need to make a start on content. Feel free to add in helpful pointers.

Tom

Hello World!

Hello there plucky internet user, this is my blog!

I am a junior developer working in London, UK with experience in Ruby, JavaScript and Python. This blog is very much in the spirit of personal/professional development insofar as many people, both older and wiser than I, preach the importance of deliberate and consistent application of oneself cough Cal Newport.

More about me, I’m very new to the world of development but have throughly enjoyed my experiences so far. I have gone through the increasing popular route of not majoring in computer science and instead going through a bootcamp at the start of this year. London is a very vibrant and exciting place to work as a developer, with a bustling startup scene and numerous meetups to boot.

If this blog has left you wanting more from yours truly, I tweet – or more accurately retweet, details, details – a fair bit as well as all the usual razzamatazz, see sidebar.

I hope to use this blog to write about technologies or techniques be they practical or more theoretical (not a CompSci major). Hopefully you too will be able to profit from this journey, so let’s get started!

Tom