!important in CSS files to override some deep tag based nesting.
Over the last year when I’ve worked on any project I’ve been trying to implement a couple of basic front-end paradigms, regardless of the size of the project, to make sure that down the line its easier for myself or other developers in my team to make changes without worrying about unexpected bugs.
Disclaimer: None of this is particularly new or ground-breaking, but keeping these simple methodologies in mind made it easy for different and new team members to confidently work on different parts of the front-end.
The basic premise I employ here is the scoping of your CSS and HTML in unison, creating modular blocks that have no knowledge of anything outside of them. This is to stop interference between different parts of the design that happen to have the same HTML elements. This is exactly what is proposed by BEM and SMACSS, and is evident in parts of Bootstrap, but without even adhering to these specific patterns you can keep things simple in this way and just putting a little thought into creating you front end code.
Whilst this can seem quite verbose, I believe the benefits you get from this approach outweigh the time taken to write it. The structure of each component is explicitly stated rather than loosely implied, there are no assumptions over which tag each class is associated with (for example
.box h2) and everything is encapsulated. Avoiding horror selectors such as
.box h2 span also means refactoring is much simpler.
Another thing I try to do is store state in the HTML element using classes such as
is-visible for elements that have ‘state’. Gone are the days of using jQuery to change CSS attributes directly (unless calculations are necessary) so toggling classes makes sense, especially with the rise of CSS3 transitions and keyframe animations. Prepending
is- to the class makes it obvious that this class implies state, and obvious which states an element has just by reading the stylesheet.
As an aside, these steps is even easier to do with pre processors like SASS, as you can share styles between elements without touching HTML by using directives such as
@extend, and use the & selector to nest state. For example:
SASS does however have the downside of making it very easy to create very complex and messy selectors through nesting. You want to make selectors as short as possible for speed, which should be simple with the explicit component naming I described eariler. If absolutely necessary, I normally say three levels deep at an absolute limit.
Finally, try not to use tag selectors, unless you are absolutely sure it saves more time than writing out many classes, e.g.
.nav li, .nav .submenu li. They are the slowest ones selectors as the last element in a selector that is read right to left.
Sidebar object, to encapsulate different element bindings in both the
#sidebar elements on my page, but also defining the interface to both these parts of the page.
I’ve implemented some skeleton code to that effect below. The important thing to note here is there’s no implied dependencies, every is explicitly declared. There’s no assumptions from the bining within the
Header object as to how the
#sidebar element should behave as it uses a clear interface
As an aside, when binding to specific elements, use
.js- prefixed classes to inform that that element is to be used in some sort of JS interaction, again a way of enforcing explicitness.
In both these cases I am essentially pushing encapsulation of the CSS and JS you use to the elements, essentially meaning that each HTML object, e.g. a header, and re-usable box element, is self-contained in all three aspects: content, style and interaction. Whilst somewhat verbose it does mean that every is less opaque and personally more enjoyable to write. This encapulation seems to be the way things are going with libraries such as Fruitmachine and React by Facebook, let alone the latest Web Components proposals and the Polymer library. Hopefully those that have bothered to read this far down have found this post useful, if you have any comments or you disagree please do let me know in the comments below!