Skip to content Skip to sidebar Skip to footer

SMACSS, Semantic Class Names And Nested Elements

I've just read Scalable and Modular Architecture for CSS and it's got me thinking about a few things. Snook's two principle tennets are: Increase the semantic value of a section o

Solution 1:

I prefer using a class like .title rather than selecting just the h5 element, as I feel it decouples the HTML from the CSS some more. If, for whatever reason, you decide an h4 or and h6 is more appropriate for the document outline, or some other element/reason, you would have to refactor your CSS if you are selecting the element(h5) vs select a class(.title).

This is why I prefer to class ALL THE THINGS vs. element selectors because the markup may change over time. If your working on a smaller site that isn't seeing many updates, this may not be a concern, though it's good to be aware of.

As far as if there is anything wrong with using the same class in completely different contexts if you know it will be namespaced by a previous item in the selector, I have mixed thoughts on it.

On one side, some concerns come to mind, for instance the use/meaning/role of .title could be empty without it's parent selector. (.pageHeader .title) While I think that .title is a perfectly fine class name, it may be difficult for other devs to understand it's meaning comes from a parent selector like .pageHeader .title

Another concern is if you are using the class .title for multiple instances of "titles" in a module, you can run into issues. The basic idea is that the local scoping descendant selectors provide can sometimes be too restricting if trying to stretch the reusability of .title within the module. I set up a code demo to show what I'm talking about here.

On the other side, descendant selectors are one of the most used selectors, specifically for their scoping purpose.

Tim Murtaugh, who is one of the developers (not sure if he is the lead dev or not) for A List Apart uses descendant selectors for the majority of his styles on his personal site.

I've recently been exploring this and BEM and would agree with your conclusion, "this is preferable to namespacing each classname."

I prefer .pageHeader .title{...} vs. .pageHeader__title{...} but there are always instances where one approach may be more beneficial in a situation over the other.

As with most things, it depends, but I think if you don't let the nesting go too deep and are thoughtful with how you use them, descendant selectors are powerful and good solution for providing locally scoped styles while also offering a solution for globally scoping styles.

For example:

/* Globally scoped styles for all .title(s) */
.title{
   font-family: serif;
   font-weight: bold;
}

/* Locally scoped styles for individual .title(s) */
.pageHeader .title {
    color: #f00;
}

.leadArticle .title {
    color: #00f;
}

.productPreview .product .title {
   color: #0f0;
}

Solution 2:

I think there's very little to say about this. What you're doing is fine, though it's not the only approach to organizing your markup for CSS. The important thing to understand is that class names are not part of CSS, they're part of HTML.

So the classes applied to an element are not, in HTML terms, "namespaced" by their ancestors in the DOM tree, but stand in their own right. So it is reasonable that you use "title" for the class names of each of the elements in your example because they are all alike in being titles.

A contrary example would be to say use the class name of "note", where on one element it signals a type of comment, but on another element a musical note, and then assuming that their meanings can be distinguished by inspection of an ancestor element. That's not how HTML classes are supposed to work.

It's also work noting that there's nothing unsemantic about <h5>. Use of element names in your CSS selectors is just another way of describing the relationship between the elements you want to style. .product h5 as a selector means "style fifth level headings in the context of the sub tree of the class 'product' like this ...". That's a different statement from .product .title which mean "style elements of class 'title' in the context of the sub tree of the class 'product' like this ...". Both statements are useful.


Solution 3:

One very important thing to note is that browsers read CSS right-to-left, not left-to-right so if you structure your selectors few levels deep then it's more work for browsers to do.

.pageHeader .title {}
.leadArticle .title {}
.productPreview .product .title {}

So this is one .title but in a different context. Browser while rendering will check if the child element is placed inside of particular parent element and then it will apply corresponding rules.

.pageHeader-title {}
.leadArticle-title {}
.productPreview .product-title {}

Here we have 3 very different titles (not one!) so browser wont do any extra calculations nor checks if the child is a child of particular parent. What we have here is also more flat structure of modules which is always nice.

Always remember that nesting your selectors and naming them in the same way but in different context has impact on the performance which does not mean anything if you're writing small personal website but if you need to plan and deliver solution that will be viewed by millions then it's important to know how to properly structurize your markup.


Solution 4:

It's sometimes referred as "parent-child relation" (http://thesassway.com/advanced/modular-css-naming-conventions) and often recommended to go with .page-header-title.

In your case .page-header can be treated as a component and .title as a component part. RCSS (https://github.com/rstacruz/rscss/) standard advocates .page-header > .title. I personally find it as not a really good idea. Consider following:

<header class="page-header">
<h2 class="title">
  <span class="tooltip">
    <span class="title">..</span>
  </span>
</h2>
</header>

.tooltip > .title unintendedly inherits from .page-header > .title.

So I would go with .page-header-title.

When you do intend the heading to inherit from a base class, just add class to the HTML element

<header class="page-header">
<h2 class="page-header-title title">
</h2>
</header>

Now page-header-title contains component specific styles and title augments with abstract title styles. Yes, it is verbose, but safe. Here, if any interest, my detailed opinion on how to keep style cascading sane and to have clean and obvious abstraction https://github.com/dsheiko/pcss


Post a Comment for "SMACSS, Semantic Class Names And Nested Elements"