888

Is it better to import a pre-written rule for each CSS style or to write your own rule (OOCSS)?

Question:

I was reading up a bit on <a href="http://www.stubbornella.org/" rel="nofollow">Nicole Sullivan</a>'s theory on <a href="https://github.com/stubbornella/oocss/wiki" rel="nofollow">Object-Oriented CSS</a>. In a nutshell, the basic idea is that instead of starting from scratch each time we style a website, it's probably better to use some already-written basic building blocks as classes and then <strong>extend</strong> them to fit our needs. ("Extending" encompasses adding more specific/overriding classes to HTML, due to the impossibility of CSS classes inheriting rules from each other... hopefully in CSS4? :) The OOCSS principle is inspired by the fact that you don't need to re-write the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html" rel="nofollow">Java Math class</a> every time you need to find the sine of a double number. The code has already been written (by someone), so why not use it?

While I think that's a great proposal in the abstract form, I'm having trouble grasping it from an applicable point of view. <em>[Read below for my specific question, but I'm always looking for reading material so feel free to stop for a minute and comment with some more links to OOCSS resources, e.g. benefits and criticisms of, etc.]</em>

Here's my stylesheet:

.heading {...} /* for all heading styles */ .alpha {...} /* specific changes for h1 */ .beta {...} /* specific changes for h2 */ .gamma {...} /* specific changes for h3 */ .delta {...} /* specific changes for h4 */ .epsilon {...} /* specific changes for h5 */ .zeta {...} /* specific changes for h6 */

Now the first selector is for any heading, with common properties such as font-family, letter-spacing, etc. And then each "subclass" (not really a subclass) has specific differences such as color, font-style, font-weight, etc. The fact that these "subclasses" are written <em>after</em> .heading in the stylesheet indicates that if any of them contain equal properties with unequal values, then the property in .heading will be overridden by that in the "subclass". To get my Heading 1, I would write:

<h1 class="heading alpha">Contact Me

In fact, I could style any element, such as span, with class="heading alpha", but indeed this is truly an h1 element.

<em>[Of course, I'd like to be able to say</em>

.heading {...} .alpha { extends: .heading; ... } ============================== <h1 class="alpha">Contact

<em>but we aren't quite at that point yet.]</em>

My question is, if heading alphas are normally left-aligned, what would I do to make this instance centered? Nicole would say that I should import her stylesheet and use her <a href="https://github.com/stubbornella/oocss/blob/master/core/table/table.css" rel="nofollow">.txtC {text-align:center;}</a> rule, so my code would become:

<h1 class="heading alpha txtC">Contact Me

But I think it's a little much to have basically a one-to-one correspondance with CSS rules and classes. If I used this method, then I wouldn't need to write any of my own stylesheets, but instead just add a bunch of small classes ("legos") to my HTML code, making it bulky and unreadable. Imagine having:

<p class="ital size-medium sans-ser txtJ med-height dark-blue">This is a size 12pt, italic, Arial, left-right justified, 1.2em line height, dark blue paragraph.

Wouldn't it make more sense to write one class specialParagraph <a href="https://stackoverflow.com/questions/1437527/css-camelcase-vs-under-score" rel="nofollow">(or paragraph-special or whatever)</a> and then assign all those rules in the CSS? No need for legos? In my case, <strong>couldn't I just add .alpha {text-align: center;} to the top of my Contact page? Or maybe even in-line?</strong>

Answer1:

The point of the OOCSS way isn't to primarily borrow CSS snippets from other libraries and only write new rules when you're doing something no one has done before. Obviously that would be impossible and probably not any better than rolling your own.

The point of OOCSS is to abstract your styles as much as possible. The more specific they are, the less reusable they are, and when you do that you end up writing much more CSS.

To put that in programming terms, instead of making a car class and then a truck class that share all sorts of common methods, you make a vehicle class and then car and truck extend from that.

The equivalent of that in CSS is to use classes as mixins. For example, if you're using a lot of <ul> elements and you find that you're constantly setting margin and padding to 0 and list style to none, you should probably write a .reset class that does that for you and apply the class to your <ul> instead of writing the same three rules over and over again for all your navigation and list items.

Another point is that you need to think about your abstractions from a visual standpoint, for example, if you find that most of the sections of your site live in boxes with borders around them, you could create a basic class like:

.bordered-box { border-style:solid; border-width:1px; margin-bottom:20px; padding:20px; }

Then you'd create other classes to mix in styles that aren't defined on .bordered-box such as color, and width, etc.

Think of your css classes as a toolbox that you're going to use to build a site instead of thinking of it merely as a list of properties you can add to elements to make them look a certain way.

To your point about HTML like this: class="ital size-medium sans-ser txtJ med-height dark-blue", it's important to distinguish between creating CSS classes that define visual objects and CSS classes that simply define CSS properties. The latter is ridiculous. If you're going to do that you may as well just use inline styles.

Answer2:

I think using something like .txtC or .dark-blue is against the spirit of CSS, where you are supposed to be able to change the entire look and feel of your site simply by using a different stylesheet.

For example of an issue that could arise, say you decide you want all your headers to be red instead of blue. Rather than simply updating your CSS to .header { color: red }, you have to go through every page of your HTML and replace the dark-blue class with red. Or you could change your CSS to dark-blue { color: red; }, but then the class name doesn't make any sense.

If you add a class for every rule imaginable, you'll just end up back in the dark ages of inline styles and align="center" on every element.

If you are going to use "object-oriented" CSS, it should be used in a way more like, you have your .header class that affects all your headers, but then if you wanted a different font color for your home page header, you would add an additional .header.home { color: cyan; } CSS rule. You want your CSS IDs and class names to describe the content it's affecting, rather than the styles it's providing.

Answer3:

"Object-oriented CSS" is really just a design pattern for how to get most out of your CSS and is basicly the same approach Jonathan Snooks calls <a href="http://smacss.com/" rel="nofollow">SMACSS</a>.

Whether you call it OOCSS or SMACSS, the key to the approach is that you create generic UI elements like the <a href="http://csswizardry.com/2011/09/the-nav-abstraction/" rel="nofollow">nav abstraction</a>. These UI elements can then be enhanced with more specific features by adding extra classes to the element and/or a container element. Or, as an alternative, you can add your own custom CSS rules using the element's ID or semantic classes.

<a href="http://cascade-framework.com/" rel="nofollow">Cascade Framework</a> is a brand new CSS framework based on this approach. It gives you optimal performance, optimal flexibility and optimal modularity with just a tiny footprint.

Recommend

  • WPF Slider control (NullReferenceException)
  • regex - wrap all integers in double quotes
  • Possible to use CodeIgniter output compression with to display code blocks?
  • In a django custom field, what does the SubfieldBase metaclass do?
  • Why the drawPolygon method in Graphics Class abstract and I can still use it
  • CUBA : entity inheritance
  • Is it OK to write code after [super dealloc]?
  • Change Font Style (bold, Italic, bold italic) in C# [duplicate]
  • Java catching exceptions and subclases
  • Extract text from “” HTML tag
  • How to make Java compiler generate line numbers in compiled code
  • Imagemagick set interline spacing?
  • What's the logic in HKObserverQuery background delivery?
  • Docker container for google cloudML on compute engine - authenticating for mounting bucket
  • Performance difference between accessing local and class member variables
  • WP7 - read from CSV file? Or what to do with the data?
  • Why does PHP appear to evaluate this condition incorrectly?
  • How to use arithmetic operators with SAS macro variables [duplicate]
  • reduce/reduce conflicts using ocamlyacc
  • How to write string.Contains(someText) in expression Tree
  • How to get the index of element in the List in c#
  • Add spaces between words in spaceless string
  • Netlink sockets and libnl - nl_recvmsgs_default returning -16 (EBUSY)
  • Rails AREL .where statement
  • Messed up characters in webpages (especially social media)
  • Xaml, wpf image position and crop issue
  • Using same constraints in multiple classes
  • LiveData is abstract android
  • Tell Git to stop prompting me for conflicts when none really exist?
  • Caching attributes in superclass
  • How reduce the height of an mschart by breaking up the y-axis
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • Return words with double consecutive letters
  • Android Google Maps API OnLocationChanged only called once
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs
  • Observable and ngFor in Angular 2
  • UserPrincipal.Current returns apppool on IIS
  • java string with new operator and a literal