Skip to content
This repository has been archived by the owner on Nov 9, 2022. It is now read-only.

Snooks Workshop Notes

atsengucla edited this page Jun 25, 2012 · 5 revisions

Notes SMACSS Workshop with Jonathan Snook

Overview:

SMACSS (Scalable and Modular Architecture for CSS) is a set of principles outlined by Snook after his experience working with enterprise applications. He was on a team of 3 front-end proto-typers serving 300 engineers and at the Yahoo Mail project. This set of principals sum up his experience with the pain-points that large projects and a large front-end-to-back-end ratio bring about.

Like others who work with large systems or where issues of scaling is critical, this approach to CSS deviates from traditional practices and long-agreed best-practice conventions for CSS.

At its core, this approach addresses 3 critical problems of CSS development that arises in large projects:

  1. The CSS Cascade

  2. CSS Specificity

  3. CSS Modules: Visual Patterns decoupled from HTML Semantic Structure

CSS Cascade: Tightly Target the Scope

Snooks takes a more moderate approach, but essentially agrees with Mark Otto (Twitter Bootstrap) http://www.markdotto.com/2012/03/02/stop-the-cascade/. Rather than “stop the cascade” Snook says his approach is to “target the cascade”. Essentially, the main problem with too wide a cascade scope is: a) it taxes the browser and kills efficiency b) more importantly, limiting the CSS cascade to small, targeted areas leads to small modular and robustly reusable css that is easier for novices to code and understand, much easier for teams to debug, and allows for parallel development with a team of CSS designers/engineers

Historically, Snook mentions that CSS has not been something that teams could work on collaboratively—and limited to the purview of 1 expert designer/css guru – the use of long complex selectors using html entities – though powerful and easy for 1 person on a small project, soon devolves to maintenance hell once you add just one more designer.

How does Snook approach this? Using mostly class selectors, and only relying on child selectors for any html entities for his CSS library. The scope of his modules are mainly on the class level with some instances where they target a direct child and rarely, if ever they target a direct grandchild (i.e. 2 –levels deep is almost too much!).

Along the same lines as targeted inheritance he does not favor CSS Resets, but prefers “CSS Normalization” (Nicholas Gallagher and Co. http://necolas.github.com/normalize.css/ ) – for the same issues -- they cause too many unforeseen consequences by targeting too wide, too early; Snook’s basic philosophy is to not touch anything, unless you absolutely need to, when you need to – he believes that traditional CSS Resets cause more harm than necessary.

Besides avoiding a wide scope, a through-line concept that recurs in Snook’s ideas is that each module/object should be very, very simple. Do one thing and one thing only. This will get touched upon later more in the idea of decoupling CSS from the html structure.

Incidentally, though targeting is seen as a useful principal, use of IDs are heavily cautioned – leading to the next point CSS Specificity.

CSS Specificity: Use Mostly Classes, avoid Ids

A recurring issue that projects see with teams of designers and with on-going maintenance is what many are terming “CSS Specificity Hell.” As a project team adds n team-members and n iterations/changes … eventually the CSS specificity devolves to such a complex situation that even the most highly skilled experts cannot productively make additional changes.

As unforeseen changes happen and inevitable CSS overwrites need to get declared eventually the path leads down to further and further greater level of specificity in CSS declarations to implement changes.

One of the main aims of not using Ids (unless absolutely necessary) is to prevent this specificity problem. With specificity html elements are ranked lowest, then classes, then Ids. No matter how many combination of classes one declares, it will never over-ride a single Id. Thus, SMACSS avoids Ids as a general rule and uses them very sparingly and in very targeted situations.

CSS Modules: Visual Patterns decoupled from HTML Semantic Structure

Foundational to these principals is the use of a library of CSS modules (or objects). There are specific tactics used in this vein (addressed in specific points mentioned later, such as name-spacing, pre-fixes, etc.) but the general points are: • keep the modules very simple; each module should do one thing and only one thing • CSS modules are repeatable “Visual Patterns” – Snook and others agree that these elements are style elements and should be distinct from the html context in which they affect to maintain a high level of re-use. Snook believes one should decouple CSS modules from the html structure. To the degree that you can reasonable foresee that the html structure will remain static (i.e. in the case of navigation) is the degree where you can flex – otherwise a tight coupling will result in a breakdown of your CSS libraries when faced with the inevitable changes that come with content and html structure. • As with Sullivan, Otto, and Gallagher -- Snook believes that CSS Semantics should be meaningful to “visual patterns” and not “context derived.” He cites Sullivan’s example of the Media Object as a case where the repeatable pattern is not based on a consistent data-model object but rather a repeatable rendered visual pattern: http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/. In his experience, capitalizing on noticing visual patterns (the front-end is about rendering the visual) will gain great efficiencies for front-end issues.

Specific Strategies:

1. Explicit Namespacing with structured domain prefixes.

Snook uses a revised and greatly simplified approach that essentially follows what BEM, Twitter, and OOCSS practice – he organizes his CSS into separate categories (such as base, layout, states, themes, modules, typography) and then he clarifies these categories (where it may be confused with others) with a prefix single letter. He tends to only use the letter prefix for layout and themes. l- for layout and t- for themes. Modules he prefixes by a root-base class and for states he always prefixes with a verb that signals its nature (i.e. is-hidden vs. not-hidden).

He agrees that mainly this is about agreement and that his method won’t distinguish between sub modules and module sub class extensions (like the BEM method does) – but he feels this is a workable compromise that helps “clarify intent” amongst the team without creating a namespace string that is un-readable.

The main point he likes to distinguish is between the modules from their layouts and themes – as Sullivan would say separate content from box and structure from skin. And feels that these simple prefixes help do that.

2. Namespacing with class extensions vs. implicit multi-class patterns.

Snook also explicitly name spaces with the root module name for all sub classes and sub modules related to the same module. This he believes is very important for helping CSS readers be able to associate related modules. Without this practice, he has seen and experienced teams searching through fragmented CSS decks trying to piece together what goes with what.

3. CSS classnames and semantic meaning.

Snook understands the objectors from the “pure data/context semantics” schools – but he offered this thought -- that from an object-model perspective there are patterns that are very different to the visual patterns that are meaningful in a front-end stack. He simply puts forth that when you are dealing with the front-end you are dealing with visual patterns. To deny this fact would be a great disservice to your ability to reuse these patterns at a gain to your project. He also believes that when done carefully you can add sematic value to your html data structure with your CSS class names and “clarify intent.”

He is against this approach -- http://mvcss.github.com/MVCSS/ -- which he believes will lead to an overly complex and hard to utilize/maintain library.

4. Using CSS pre-processors.

He personally uses SASS and with it Compass – which he favors due to its helper functions that are designed specifically with visual design in mind (color functions and type functions). He did a survey of the class and most were already using pre-processors (38/40) in their front-end teams with LESS having a slight gain in advantage over SASS.

Snook believes pre-processors can be a real gain but that it can also be easy to undo all your modular efforts if not careful.

He believes that it is important to do so while paying attention to limiting scope, watching specificity, and decoupling html structure from CSS modules and thus he cautions against deep nesting (2-levels is the max).

Also he advises against using extensions and mixins that span across different modules – coupling un-related modules rather than extending on a base module will lead to results that go against the point of having a modular CSS library.

5. Adopting Modular CSS to existing Projects & Teams.

• Work piecemeal – one module at a time. • Keep each module in a completely separate file – better for clarity, prototyping and better for thorough debugging; At production use the pre-processor to combine the separate files but the library should be a series of isolated small files (about 30-40 for core modules). This way you can work on a larger team. • Do code reviews regularly to have conversations and evolve your naming conventions and troubleshoot unforeseen issues. • The hard work is the core/base modules; once that is done – it’s just extensions.

6. Determining the Correct Scope for Modules.

• This is hard – along with naming the hardest parts • If you start having a lot of code in a particular CSS selector it’s a sign to break it apart as a module in its own file • Start it in the global category stylesheets and it you see a pattern break it out

7. Responsive Designs.

• These are handled well as state changes (which encompass media queries, javascript behaviors and CSS effects/animations) • Snook says its also very important to have “generic” module names and evolve away from names that are very “context/location” derived; The meaning or sidebar-right is much less robust than content-secondary when you deal with linearization of content that happens in mobile.
• Another point he makes is to keep your media queries organized with the modules they effect – not in their own separate files – global media queries will go in layout if effecting layout and states otherwise, but generally, media queries tend to need to target specific content items that need the transformation – and thus modules.

Clone this wiki locally