Skip to content
atsengucla edited this page Jun 19, 2012 · 22 revisions

CSS Class Names

Eric proposes the following...

  • Reserve hyphens for module namespaces.
  • Use camelCase with first letter of first word lower cased.

CSS does not have "namespaces" in the sense of many object oriented languages like Java, C++ and PHP 5.3+. This naming convention comes from standards like the PEAR naming convention in PHP and early drafts of the PSR-0 specification before PHP 5.3 added the namespace construct explicitly.

Namespaces for Modules

Do we verbosely namespace modules or not?

This question arises comes from Research: Modular CSS

An example of namespaced modules might be <ol class="menu layout-col layout-col-six"><li class="menu-highlight">... whereas avoiding namespaces would be <ol class="menu col six"><li class="highlight">....

Advantages to module namespaces:

  • Easy to handle from the object-oriented approach in programming
  • Prevents side-effects when you're designing a module because you can't accidentally effect something else
  • If we provide a dynamic loader where you specify the modules you want as an end user, this makes a lot of sense

Disadvantages to module namespaces:

  • Unintuitive to an end user that isn't familiar with the modular implementation of the framework itself. This was the motivator for MWF 1.3 when we reduced a div like <div class="menu-full menu-padded menu-detailed"> to <div class="menu padded detailed">.
  • Goes against the idea of "pure semantics". If something is padded, it should be .padded regardless of which entity we're talking about.
  • Harder to create size-efficient stylesheets this way.

One option is that we provide some modules that require namespaces, and that these are the "dynamically included" ones that you specify when you compile the CSS or when you load the handler, whereas there are a set of base classes that are always available that we don't namespace. The idea would be if we did something like the MWF trigger/target library (see https://github.com/ucla/mwf/wiki/Roadmap%3A-Framework-v1.3%3A-JS-Interactivity), we could namespace that and you'd have to specify it in your handler, but that things like the fluid layout (with classes like .col and .six), we don't namespace because they're always included.

Naming Conflicts

If we do not prefix everything in some way, then an existing site may run into naming conflicts. For example, one might have an entity named .menu.

  • One option is to use the same approach that vendors use for CSS attributes where we prefix all of our class names with a hyphen. Our menu would then be .-menu. This is intuitive from a naming perspective, but is it too hard for an end user to remember when using our classes? For example, you might end up with a div like <div class="-menu -col -six">. Could also use an underscore here, but that requires holding the shift key while hitting the hyphen char, which is just an added bit of effort that "hardcore" coders don't like.
  • Another option is to actually prefix all of our elements with a single letter followed by a hyphen. This is less "weird" from a markup concept, and it fits with the namespacing idea listed above. You would end up with a div like <div class="f-menu f-col f-six">. We'd need to decide on a letter. An issue arises from the "hardcore" programmer perspective though where you're typing extra characters. I, for one, would rather program using just the hyphen in front and not worry about a letter.
  • Finally, we could just say "eff it" and go with unprefixed names and expect people to revise their markup.

[ALICE] on 6/19:

So for the most part I'm in agreement with what's being proposed here, except that I'm going to way in on a +1 for explicit namespacing. I've been prototyping our IT Services CSS deck with some of these ideas (Snook, Sullivan, etc.) and I'm finding a few things while I am working.

Yes, the explicit name-spacing causes a string of classnames that to a CSS newbie would be an adjustment. And I think I'm leaning towards Snook's take on this (a more minimal approach). He doesn't explicitly namespace entities that are what Sullivan calls "content objects" since his thoughts are that semantically they are pretty self-explanatory and for a pragmatic reason -- these modules are the most numerous. He does, however, explicitly namespace the other elements -- what Sullivan calls the "container" objects or the "skins". He uses a single letter namespace to convey things like l= "layout", s="state", etc. I'm also leaning towards this and here's why.

The OOCSS method of separation of "content from box" and "structure from skin" is really smart for reuse but also a very hard concept to understand for people who aren't used to working this way. I've been struggling with understanding which css rules belong in what category and the explicit namespacing is actually helping me identify this and write better more abstracted code.

In the old way, all the css elements (skin,containers,content, structure) all of it gets declared within one object. A .menu class would have the colors,type treatments, padding and positioning declared on that .menu. This of course means that if there were strong patterns for a particular positioning or color treatment/behavior etc. it couldn't be abstracted and reused/shared across other elements, but the plus was if I wanted to edit the .menu classes it was a snap -- look for .menu. So comes in the new way... .skinA .layout .menu .behaviorType ... OK ... as someone who isn't used to working this way it's really hard to pick out -- where am I looking for the padding elements for .menu if they are no longer in .menu?

As I've been working on the prototype, I've found that the explicit namespacing has been helping me with both debugging and authoring new code; I've been using v="visual" for skin elements and it actually helps me better isolate and remember when writing css that ... right ... the declarations for repeatable skin treatments -- separate them from the core/essential declarations that make an atomic "menu" a menu. In addition, as I work on the prototype, it really does help my debugging once I "get" that "l" = layout etc. I'm able to scan the code and if I am having issues with the padding in a specific area -- I know that it's gotta be in the l-name class.

Though at first sight the namespacing is "ugly" and "scary" I think when applied consistently to the principals of "separate structure from skin" and "separate content from container", it's actually something that works very elegantly and helps rather than hinders.

I'm a +1 for explicit namespacing from the practicality of someone who needs to grasp that the code for css (in this way of writing modular reusable code) needs to be separated into 4 domaines. I know there's a valid argument that if we get the classnames 'right' the concern for naming conflicts won't be necessary -- I can totally agree with this, but, I'm finding in reality, it's not simply about getting the class names perfect so they don't conflict. The namespacing actually helps me distinguish between the 4 domains. With a huge CSS deck -- it's just not pragmatic for me to be able to know by memory which names are associated with the layout, which are are behaviors and which are the content objects themselves -- explicit namespacing helps offload that need to for me to remember and I'm happily able to spot the prefixes and be on my way.

So, I agree that the layering of classes is hard for a newbie to parse ... but I'd say that the real hard part is the fragmented css elements (4 objects, instead of one object) and less the namespacing prefixes. I find that the prefixes actually help to give me a clue to this while I adjust to this new way of thinking.

I think the trick here is to make the namespacing prefixes as minimal and un-obstrusive as possible (single letter seems to be a common convention I see).

On Semantics for CSS

This comes from many valid arguments raised by the semantics folks regarding the problem with style/presentational frameworks such as in grid frameworks and twitter bootstrap. At the same time, there are many valid counter-arguments coming from scalable/modular css folks related to practical reuse and scaling of code. These issues were first brought up in the Frameworks Components Page and the Research: Modular CSS Page.

Particularly important to think through is the issue of what "semantic meaning" is when we are looking at css class names. By no means do we have to be either/or about it -- in fact many people are both recognizing a need to have reusable css styles that make sense to styles and for them to be more future proof and less brittle to changes. Many are looking to pre-processors to help with this issue while others are calling for a reconsideration of what "semantics mean for css".

So, my question is ... how are we defining semantics for CSS? If we are strictly holding css class names to "data/content" semantics than really, the only way we can achieve this and have reusable style-based components is to use a pre-processor like SASS or LESS. If, instead we expand on semantic meaning for css to allow for style (from the logic that style-elements have semantic meaning in the CSS context -- i.e. they are style sheets), then we can have sensibly future-proof class names that are semantic to styles and not only content/data.

Articles to consider: http://nicolasgallagher.com/about-html-semantics-front-end-architecture/ http://www.stubbornella.org/content/2010/06/12/visual-semantics-in-html-and-css/

Javascript Libraries

Eric proposes the following...

  • Base class with some prefix like _
  • Namespaces are implemented as objects like _.module.submodule
  • Use camelCase for functions and members in a module like _.module.submodule.funcName() or _.module.submodule.varName

Naming Conflicts

Using a single character base class is a common way to avoid cluttering the global namespace, and we need to do it. However, the question is whether we use a single character or a full name.

Options:

  • Single Symbol (_): This is similar to how jQuery uses $. However, because jQuery uses $, we wouldn't want to use this one. Instead, we could pick underscore as it's the other symbol that's allowed to start a Javascript name. The advantage is not much to type, but the disadvantage is that users often forget to include it and end up with Javascript errors - I (Eric) use this sort of convention a lot when I write my libraries, and even as the library writer, I sometimes forget to include the _ and then I get errors and have to go back and fix.
  • Single Character: If we use a single character in CSS (see ''CSS Class Names: Naming Conflicts''), I suggest we use the same single character here too. If we don't for CSS, we could still use it for Javascript. This has the advantage of being harder to "forget" than an underscore _ but the disadvantage is really that we have to pick a character that isn't likely to be used as a temporary (people often use letters like a, b, c, i, j, k, r, s, t, u, v, w, x, y, and z as temporaries and there might be others). It's far less likely people use an underscore as a temporary, because they don't even realize it's an allowed single character.
  • Multiple Characters: No matter what we go with in terms of a single character or symbol, it will be an alias to a multi-character name. jQuery does this with $ being equivalent to the object jQuery. We could forego a symbol/letter altogether and just provide a name, or we could even allow the user to run in "compatibility" mode, only using the full name if they find it creates a naming conflict in their particular app. We just need to settle on a name for the framework to decide this name.