Object Oriented CSS: Should It Matter

Object oriented CSS: should it matter?

Is it relevant?

I think so, it's basically putting a name to an approach used by the CSS author, in much the same light as creating styleguides. Is it useful? Yes. Is it easy to inherit someone else's OOCSS work? Probably not.

What are the benefits of OOCSS?

Abstracting style attributes of a certain component is always good for style consistency over the whole of the site. Say you want to change the border style of the components for a fresh new look: You'd typically change a few lines concerning the border-style master style.

An example

I created a UI Developers styleguide (or style vocabulary) concerning all the 'widgets' in our web app. Each widget would be classified according to its intended contents. Each widget could have any number of predefined box-styles, background-styles. Each widget could also lay out its contents different depending on what parent element it was placed under.

This amounted to code like: <div class="free bg_neutral form_search"> being used for each wrapper / container, with each class being: "Box Style, Background Style, Content" respectively.
The developers working on the HTML / Views could then easily switch out any of the predefined styles and replace them with more appropriate ones. e.g. replacing bg_neutral with bg_gradient_fff_eee for a gradient background instead.

I think we saved countless lines of CSS code, because we could use interchangeable properties on a few core 'widgets', rather than defining each and every unique incarnation of each 'widget'. It also makes cross-browser fixing much easier, because you can tackle the 'widgets' styles independently. (Most browser bugs are related to box dimensions and position/layout)

In my opinion, more UI folks need to go thru a StyleGuide / Style Vocab exercise when designing and implementing the front-end of their sites. Create consistency in the visual elements used on the site. Consistent visuals usually result in consistent and efficient CSS!

Hope that helps,
nd

OOCSS Separation of Container and Content?

I think you are right in the sense that yes, in your specific example.. perhaps doing it your way would be easier. But then again, if you look at the first sentence in the OOCSS page:

How do you scale CSS for thousands of pages?

In that context.. the second principle makes perfect sense.. so using your same example (ie let's assume we implemented your solution).. let's say that a year down the road your company decides to create light grey buttons in the black footer having black text:

<!-- inside footer -->
<a class="button lightGrey">link</a>

in this case.. all the a tags will be white because they're covered by your cascading. So then we will have to go create another sytle just to undo what your solution did:

.footer a.button.lightGrey {
color: #000; /* huh? but i thought we did this before with a {color: #000;} ?*/
}

where as if we simply made a decision that all a tags by default are black (see last note):

a{ color: #000; }

then in the footer we will create a special type of link that are supposed to be white:

.footerLinks { color: #FFF }

then a year later some of the links are still white.. others within the greyLight button will be black:

<a class="button lightGrey">link</a>

then here we don't have to worry about undoing anything.. a tags have a default color.. and that's it. if 2 years later someone decides that the links inside the lightGrey buttons (anywhere on the site, not only withen the footer.. which is the whole point of OOCSS) should be red.. then this would be the OOCSS approach:

.redLink {
color: red;
}

and the html will be

<a class="button lightGrey redLink">link</a>

in this case it won't matter if we take out the .lightGrey class, or we can have this code within or not within a footer .. it's all the same.. it results in more predictable and re-usable code.. which is OOCSS (I'm very glad that they're finally formalising this.. thanks a lot for the post btw).

One last note: To be pure OOCSS, one shouldn't change the default color of a ie a {color: #000;} is wrong!, it should be left to it's default color (which is blue).. whenever anyone wants to change that color.. then they must specify it ie

<a class="redLink">..</a>

so in this case it's more like the default a is the parent class.. and everything else subclasses it and overrides its default behaviour..

update - response to comments:

reputable site argument:

such initiatives are almost always driven by the community then adopted by reputable companies.. and even when they are adopted by larger companies it usually happens from the bottom up through enthusiastic developers who advocate for such change.. I for one was such an advocate when I was working in Amazon. And even when it's adopted.. it's usually at a small scale and not across all units in the org. it wouldn't even be a good idea for the Googles and the Amazons and the facebooks etc to enforce such a rule b/c there will always be a difference of opinion.. not to mention that such micromanagement would constrain the engineer's creativity.. there could be a guideline in a wiki for a team (ie we had one for the Amazon Kindle Touch app store) but to enforce that rule across 10,000 engineers working across the company wouldn't be practical nor desirable.

So in short if you see value in OOCSS, and start implementing on your site, and advocating it to your fellow web devs, and then it becomes a trend, that's when it eventually becomes an industry wide best practice and that's when you can expect to see it on facebook etc.

example:

take a look at this:

simple: http://jsfiddle.net/64sBg/

a bit more detailed: http://jsfiddle.net/64sBg/2/

without going too much detail (I'm sure you will see the pattern) you can see that the granularity in css descriptions allows for subtle changes without any redundancy in style definition. So notice the left arrow vs right arrow.. also the .red and .blue styles can be subsequently applied to tables etc..

also notice that there isn't a single cascading in my css.. so my styles can be completely independently applied (ie implementing the rule An object should look the same no matter where you put it)

lastly.. there is still use for cascading.. you can definitely use it in your jQuery selectors for example.. also cascading happens by default (ie without you having to explicitly set it in your css styles).. so if you take look at the css below.. you will notice that the font properties of body has cascaded down to all the buttons.

<a class="button blue dark">
<div class=" arrowDownWhite rightArrow">Analytics</div>
</a>

<a class="button red dark">
<div class=" arrowDownWhite leftArrow">Actions</div>
</a>

<a class="button grey light">
<div class=" arrowDownRed leftArrow">options</div>
</a>

and css:

body 
{
font-family: Trebuchet MS,Liberation Sans,DejaVu Sans,sans-serif;
font-size: 15pt;
}

.button
{
padding: .5em 1em;
display: inline-block;
text-decoration: none;
}
.dark {
color: white;
}

.light{
color: #E40E62;
}
.blue
{
background-color: #51C8E8;
}
.red
{
background-color: #E40E62;
}
.grey
{
background-color: #E0E0E0 ;
}
.arrowDownWhite
{
background-image:url(http://s2.postimage.org/ywam7ec4l/small_Arrow_Down_White.png);
background-repeat:no-repeat;

}

.arrowDownRed
{
background-image:url(http://s2.postimage.org/je5743t2d/small_Arrow_Down_Red.png);
background-repeat:no-repeat;
}

.leftArrow
{
padding-left: 1em;
background-position: left center;
}

.rightArrow
{
padding-right: 1em;
background-position: right center;
}

Easy to maintain CSS or lightweight HTML?

I'm a frontend dev on a corporate web software project, with about 50 people writing code, most of them backend. Initially I agreed with having as few classes as possible to make the code lighter, using lots of inheritance in the css. So we've been using the "as few classes as possible" approach.

A1: With the few classes approach, lots of css definitions will use element names to add style, something like .left-column section li a this makes life easier for devs, but actually makes the css slower, as css is analysed from right to left. In my example, the browser first checks all the links, then all the list elements, and so on. If I just had a.lc-link the css would be faster to use, having fewer elements to look for.

Another problem we run into is the lack of modularity. I can style a nice element, let's call it .flight-dates and it works great. Then a new use-case comes along and someone wants to use in the middle of a form, not a s a primary page-module. But the form was built to use a single class on the form tag and everything else uses inheritance. All the inheritance pollutes .flight-dates so I need to go back and add higher specificity to the css, so all the .flight-dates styles have an extra definition for when they're a child of the form.

That kind of thing happens 3 or 4 times a week. Less classes = less flexibility + ugly stylesheets with very high specificity, is what I've taken away from it.

A2: With the amount of javascript happening on the pages, the amount of classes used is now almost irrelevant. It doesn't make any difference to DOM manipulation speeds that I'm aware of. So we've already lost any advantage we may have gained from the few classes approach.

With reference to your tests, remember, downloading css and parsing css are not the same thing.

Also, the afore-mentioned css amendments have actually made things slower for both backend and frontend devs. Because we tried to use as few classes as possible to make things easier for backend, backend are left with components which cry like a baby if you put them in a new context, and frontend have to change css they wrote 6 months ago. I personally have wasted weeks.

I'd say it's made the work slower, and there's no performance advantage worth talking about.

A3: Things like Sass and Less tend to lead to common patterns in css. Also, a lot of good grids and related css frameworks use common class names. Think jQuery ui or 960 grids.

If you want to learn from our mistake, listen to your frontend guy.
Your backend folks will be happier because components will always behave the way they expect them to.
Your frontend folks will be happier because they'll be able to write robust, fire-and-forget css, that they won't have to rehash for new use-cases every time they pop up.
Your html will be a little bigger, but honestly the difference will be neglible, I don't believe it's going to lead to any significant bottleneck.
Your css will run quicker.
Work will ultimately take less time to do.

Large CSS vs Large HTML

I'd argue large CSS over large HTML any day. Your CSS will be cached, so your pages will load much faster with smaller HTML. More classes does mean more flexibility, but you'd be surprised at how much you can accomplish using CSS selectors. The only time I see bulking up the HTML as something that is useful is for SEO; see microformats for an example of what I mean.

Accuracy should not be a question whatsoever (even if you factor in human error, you should be able to immediately catch your mistake). As far as speed goes, I doubt it has an effect on performance. Keep in mind all the rendering is done client-side so you don't need to worry about the server doing any more work because of more complex CSS selectors.

Are good CSS design and IE6 / IE7 support mutually exclusive?

To be fair, you can't blame it all on IE (though Microsoft certainly is by far the worst transgressor). Part of the problem with such large & rapidly-evolving standards is that it's too much of a moving target to be perfectly implemented in a timely fashion. Unfortunately, the release cycles of web browsers do not coincide with the release of new web specifications. So all browser developers can do is try to implement as many features as they can from the latest W3C recommendations, selecting what they think will be the most commonly used features to implement first.

However, things are clearly improving, and it is possible to support IE6/7 and still use proper CSS design. It's just... difficult. Take a look at this comparison of layout engines & CSS support. If you look at the overall trend, you'll see that most browsers (even IE) do tend to comply with established standards in the long-run, it just takes some browsers longer than others to implement a standard after its introduction.

And sometimes it's not that one browser is "less" standards-compliant than another. With new standards the problem is often that different development teams chose to adopt different parts of the new specification. So even though CSS3 is already beginning to be implemented by most browsers, we'll probably have to wait until CSS4 is published before seeing consistent support across all major rendering engines. And if you try to use the latest CSS3 features right now, you'll have a hard time establishing compatibility across all major browsers. But if you're using features introduced in CSS1, it's no problem at all.

Therefore, the only option--aside from using ugly CSS hacks--is to stick with well-established older specifications. Then the problem is no longer trying to conform to web standards while supporting a particular browser. Instead the problem simply becomes trying to resist the urge to use the latest & greatest CSS features.

Aside from that, the only permanent solution I see to this recurring situation is for the W3C to prioritize different parts of newly introduced specifications so that the new features can be implemented in discrete phases synchronized across all the major browsers. So, for instance, grammar rules might be given the highest priority along with a set deadline for its implementation. After that would come the second phase, which could be element & attribute selectors, and so on and so forth.

This would require a tremendous level of cooperation between the W3C and development teams, but it would be worth it. After all, it does users and web developers no good for IE to implement one subset of features from CSS3 while Firefox implements a different subset and the Webkit browsers yet another subset. A "standard" is no good until it's actually standardized across all the major rendering platforms. It's better for each browser to support fewer new features but have them all be the same features, than for them to separately introduce a ton of their own features that aren't universally supported.

Should css class names like 'floatleft' that directly describe the attached style be avoided?

It's great until you re-design, and narrow is highlighted yellow, center converts better left-justified, and the image you called floatleft now belongs on the right.

I'll admit to the sin of using floatleft and clear as CSS class names, but it is much easier to maintain your CSS if you choose names that relate to the semantic meaning of the content, like feedback and heroimage.

Should CSS selectors include elements from the DOM?

My 2 cents

Specific enough to target only what needs targeting (as others have said) is the general rule.

I agree with lonesomeday that "difference in performance will be minimal," but every added element in the chain is one more check to be done.

So Think About How to Reduce It


Are the ID's needed?

I disagree with Spudley that "there should never be a need to specify more than one ID in a selector." If your site is set up to have different display on different pages, and so #page1 #content is different than #page2 #content for displaying, then that is a legitimate case of two id's in one selector. However,

  1. If all pages are #container #content then the drop the #container.
  2. Also, if all p.bread elements are inside #content, then drop that selector also.

Are element names needed?

  1. Is .bread intended to be used on anything other than a p? If not, drop the p.
  2. Is .external intended to be used on anything other than an a (probably linking to an external site)? If not, drop the a.

Is the decedent relation of classes needed?

Is the .bread .external significant for display? That is, does .external exist outside of a .bread parent and does it change because of that parent? If so, then keep the relation. Otherwise, if the important thing is only the .external (no matter where it is), then that is the only selector you need.



Related Topics



Leave a reply



Submit