Unless you are planning on building a one page website or some sort of Angular/Ember JS webapp, its likely that you will spend the bulk of your time on the server side development of your project. And as is often the case, the CSS and Javascript may suffer as it can be seen as merely an implentation detail. Horrors may arise such as Javascript functions that seems to reference global functions in other files, or having to use !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.
CSS
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-title
versus .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-active
or 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.
JS
My biggest bugbears when it’s comes to bad javascript code are global scope abuse, lazy variable naming and unclear call order. This is why I’m a very big fan of the Module pattern. It very simply gives you a way of achieving private and public state and functions, a clear way to define the interface to an object, and therefore a way to initate any functionality. For instance I may have a Header
and Sidebar
object, to encapsulate different element bindings in both the #header>
and #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
Most of what we try to achieve with Javascript in 90% of webapps are adding or removing classes or state to various elements. This sort of encapsulation keeps your code DRY and therefore easiy to comprehend and refactor in the future.
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.
Conclusion
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!