ChatGPT解决这个技术问题 Extra ChatGPT

Managing CSS Explosion

I have been heavily relying on CSS for a website that I am working on. Right now, all the CSS styles are being applied on a per tag basis, and so now I am trying to move it to more of an external styling to help with any future changes.

But now the problem is that I have noticed I am getting a "CSS Explosion". It is becoming difficult for me to decide how to best organize and abstract data within the CSS file.

I am using a large number of div tags within the website, moving from a heavily table-based website. So I'm getting a lot of CSS selectors that look like this:

div.title {
  background-color: blue;
  color: white;
  text-align: center;
}

div.footer {
  /* Styles Here */
}

div.body {
  /* Styles Here */
}

/* And many more */

It's not too bad yet, but as I am a beginner, I was wondering if recommendations could be made on how best to organize the various parts of a CSS file. I don't want to have a separate CSS attribute for every element on my website, and I always want the CSS file to be fairly intuitive and easy to read.

My ultimate goal is to make it easy to use the CSS files and demonstrate their power to increase the speed of web development. This way, other individuals that may work on this site in the future will also get into the practice of using good coding practices, rather than having to pick it up the way I did.

This is a great question but for many companies a really unsolvable problem. Mainly because CSS is being authored and managed by graphic designers who may not be aware of the terms simplicity, complexity, maintenance, structure and refactoring.
@cherouvim - It's funny you should say that because my entire reason for asking this question started with seeing some scary CSS designed by a graphic artist. Maybe we need some better training for them?
My solution (in an ideal world) is to have dedicated people in your team cutting the PSD into html+css and maintaining afterwards. These people should be close to the programmers and designers.
@cherouvim Have to agree - that's pretty much the way agencies are going, especially as CSS becomes more complex.
@JasCav, Graphic artists should not be touching the CSS. Web Designers, and front-end Web Developers should deal with CSS. The Graphic Designer's job is to make the graphics.

2
20 revs, 6 users 90%

This is a very good question. Everywhere I look, CSS files tend to get out of control after a while—especially, but not only, when working in a team.

The following are the rules I myself am trying to adhere to (not that I always manage to.)

Refactor early, refactor often. Frequently clean up CSS files, fuse together multiple definitions of the same class. Remove obsolete definitions immediately.

When adding CSS during fixing bugs, leave a comment as to what the change does ("This is to make sure the box is left aligned in IE < 7")

Avoid redundancies, e.g. defining the same thing in .classname and .classname:hover.

Use comments /** Head **/ to build a clear structure.

Use a prettifier tool that helps maintain a constant style. I use Polystyle, with which I'm quite happy (costs $15 but is money well spent). There are free ones around as well (e.g. Code Beautifier based on CSS Tidy, an open-source tool).

Build sensible classes. See below for a few notes on this.

Use semantics, avoid DIV soup - use

    s for menus, for example.

    Define everything on as low a level as possible (e.g. a default font family, colour and size in the body) and use inherit where possible

    If you have very complex CSS, maybe a CSS pre-compiler helps. I'm planning to look into xCSS for the very same reason soon. There are several others around.

    If working in a team, highlight the necessity of quality and standards for CSS files as well. Everybody's big on coding standards in their programming language(s), but there is little awareness that this is necessary for CSS too.

    If working in a team, do consider using Version Control. It makes things that much easier to track, and editing conflicts that much easier to solve. It's really worth it, even if you're "just" into HTML and CSS.

    Do not work with !important. Not only because IE =< 7 can't deal with it. In a complex structure, the use of !important is often tempting to change a behaviour whose source can't be found, but it's poison for long-term maintenance.

    Building sensible classes

    This is how I like to build sensible classes.

    I apply global settings first:

    body { font-family: .... font-size ... color ... }
    a { text-decoration: none; }
    

    Then, I identify the main sections of the page's layout—e.g. the top area, the menu, the content, and the footer. If I wrote good markup, these areas will be identical to the HTML structure.

    Then, I start building CSS classes, specifying as much ancestry as possible as long as it is sensible, and grouping related classes as closely as possible.

    div.content ul.table_of_contents 
    div.content ul.table_of_contents li 
    div.content ul.table_of_contents li h1
    div.content ul.table_of_contents li h2
    div.content ul.table_of_contents li span.pagenumber
    

    Think of the whole CSS structure as a tree with increasingly specific definitions the further away from the root you are. You want to keep the number of classes as low as possible, and you want to repeat yourself as seldom as possible.

    For example, let's say you have three levels of navigational menus. These three menus look different, but they also share certain characteristics. For example, they are all <ul>, they all have the same font size, and the items are all next to each other (as opposed to the default rendering of an ul). Also, none of the menus has any bullet points (list-style-type).

    First, define the common characteristics in a class named menu:

    div.navi ul.menu { display: ...; list-style-type: none; list-style-image: none; }
    div.navi ul.menu li { float: left }
    

    then, define the specific characteristics of each of the three menus. Level 1 is 40 pixels tall; levels 2 and 3, 20 pixels.

    Note: you could also use multiple classes for this but Internet Explorer 6 has problems with multiple classes, so this example uses ids.

    div.navi ul.menu#level1 { height: 40px; }
    div.navi ul.menu#level2 { height: 20px; }
    div.navi ul.menu#level3 { height: 16px; }
    

    The markup for the menu will look like this:

    <ul id="level1" class="menu"><li> ...... </li></ul>
    <ul id="level2" class="menu"><li> ...... </li></ul>
    <ul id="level3" class="menu"><li> ...... </li></ul>
    

    If you have semantically similar elements on the page—like these three menus—try to work out the commonalities first and put them into a class; then, work out the specific properties and apply them to classes, or, if you have to support Internet Explorer 6, ID's.

    Miscellaneous HTML tips

    If you add these semantics to your HTML output, designers can later customize the look of web sites and/or apps using pure CSS, which is a great advantage and time-saver.

    If possible, give every page's body a unique class: this makes it very easy to add page-specific tweaks to the style sheet: body.contactpage div.container ul.mainmenu li { color: green }

    When building menus automatically, add as much CSS context as possible to allow extensive styling later. For example:

    This way, every menu item can be accessed for styling according to its semantic context: Whether it's the first or last item in the list; Whether it's the currently active item; and by number.

    Note that this assigning of multiple classes as outlined in the example above does not work properly in IE6. There is a workaround to make IE6 able to deal with multiple classes. If the workaround is not an option, you will have to set the class that is most important to you (item number, active or first/last), or resort to using IDs.


    @Andrew mainly because in a dynamic environment (like a CMS) using an ID could easily lead to collisions (say, a user renaming a page to "contact", leading to that name being used as the body's ID, colliding with the contact form also named "contact"). I generally recommend using IDs as sparingly as possible for that reason.
    @Pekka you should check out www.oocss.org a lot of it goes against what you've mentioned here but its the best way I've seen to manage CSS bloat. See my answer below too: stackoverflow.com/questions/2253110/how-to-manage-css-explosion/…
    @Sam thanks! I like it quite well, although I occasionally find these guidelines very hard to follow myself. CSS style sheets are so easy to screw up over time - a colour change here, a font-weight: bold there .... discipline is the only medicine :)
    Speaking as someone new to the study of css explosion, the phrase "unique class" is confusing. I'm getting the feeling that that isn't an id but it sure sounds like one. Maybe the concept could be clarified?
    @ari you're right that that could technically be an id, too.
C
Community

Here are just 4 examples:

CSS Conventions / Code Layout Models

Are there any CSS standards that I should follow while writing my first stylesheet?

What is the best method for tidying CSS?

Best Practices - CSS Stylesheet Formatting

On all 4 my answer has included the advice to download and read Natalie Downe's PDF CSS Systems. (The PDF includes tons of notes not in the slides, so read the PDF!). Take note of her suggestions for organization.

EDIT (2014/02/05) four years later, I'd say:

Use a CSS pre-processor and manage your files as partials (I personally prefer Sass with Compass, but Less is quite good as well and there are others)

Read up on concepts like OOCSS, SMACSS, and BEM or getbem.

Take a look at how popular CSS frameworks like Bootstrap and Zurb Foundation are structured. And don't discount less popular frameworks - Inuit is an interesting one but there are plenty others.

Combine/minify your files with a build step on a continuous integration server and/or a task runner like Grunt or Gulp.


CSS pre-processors are the cause of the problem rather than the solution. Master the cascading concept truly and you'll reduce bloat.
@DanielSokolowski any improperly used tool can be a problem rather than a solution. But 100% agree on the point of mastering the cascade.
H
Hemerson Varela

Don't write headings in CSS

Just split sections into files. Any CSS comments, should be just that, comments.

reset.css
base.css
somepage.css
someotherpage.css
some_abstract_component.css

Use a script to combine them into one; if necessary. You can even have a nice directory structure as well, and just have your script recursively scan for .css files.

If you must write headings, have a TOC at the start of the file

The headings in the TOC should be perfectly equal to headings you write later. It's a pain to search for headings. To add to the problem, how exactly is anyone suppose to know you have another header after your first header? ps. don't add doc-like * (star) at the start of each line when writing TOCs, it just makes it more annoying to select the text.

/* Table of Contents
   - - - - - - - - -
   Header stuff
   Body Stuff
   Some other junk
   - - - - - - - - -
 */
...
/* Header Stuff 
 */
...
/* Body Stuff 
 */

Write comments with or within the rules, not outside the block

First off, when you edit the script there is a 50/50 chance you'll pay attention to what is outside the rule block (particularly if it's a big glob of text ;) ). Secondly there is (almost) no case where you would need a "comment" outside. If it is outside, it is 99% of the time a title, so keep it like that.

Split the page into components

Components should have position:relative, no padding and no margin, most of the time. This simplifies % rules a lot, as well as allowing for much simpler absolute:position'ing of elements, since if there's a absolute positioned container the absolute positioned element will use the container when computing top, right, bottom, left properties.

Most DIVs in a HTML5 document are usually a component.

A component is also something that can be considered a independent unit on the page. In laymen's terms treat something like a component if it makes sense to treat something like a blackbox.

Going with the QA page example again:

#navigation
#question
#answers
#answers .answer
etc.

By splitting the page into components, you split your work into manageable units.

Put rules with a cumulative effect on the same line.

For example border, margin and padding (but not outline) all add to the dimensions and size of the element you are styling.

position: absolute; top: 10px; right: 10px;

If they are just not that readable on one line, at least put them in close proximity:

padding: 10px; margin: 20px;
border: 1px solid black;

Use shorthand when possible:

/* the following... */
padding-left: 10px;
padding-right: 10px;
/* can simply be written as */
padding: 0 10px;

Never repeat a selector

If you have more instances of the same selector, there's a good chance you'll inevitable end up with multiple instances of the same rules. For example:

#some .selector {
    margin: 0;
    font-size: 11px;
}
...
#some .selector {
    border: 1px solid #000;
    margin: 0;
}

Avoid using TAGs as selectors, when you can use id/classes

First off the DIV and SPAN tags are the exception: you should never use them, ever! ;) Only use them to attach a class/id.

This...

div#answers div.answer table.statistics {
    border-collapse: collapsed;
    color: pink;
    border: 1px solid #000;
}
div#answers div.answer table.statistics thead {
    outline: 3px solid #000;
}

Should be written like this:

#answers .answer .statistics {
    border-collapse: collapsed;
    color: pink;
    border: 1px solid #000;
}
#answers .answer .statistics thead {
    outline: 3px solid #000;
}

Because the extra dangling DIVs there add nothing to the selector. They also force a unnecessary tag-rule. If you were to change, for example, .answer from a div to a article your style would break.

Or if you prefer more clarity:

#answers .answer .statistics {
    color: pink;
    border: 1px solid #000;
}
#answers .answer table.statistics {
    border-collapse: collapsed;
}
#answers .answer .statistics thead {
    outline: 3px solid #000;
}

The reason being the border-collapse property is a special property that only makes sense when applied to a table. If .statistics is not a table it should not apply.

Generic rules are evil!

avoid writing generic/magic rules if you can

unless it's for a CSS-reset/unreset, all your generic magic should apply to at least one root component

They don't save you time, they make your head explode; as well as make maintenance a nightmare. When you're writing the rule, you may know where they apply, however that has no guarantee your rule won't mess with you later on.

To add to this generic rules are confusing and hard to read, even if you have some idea of the document you're styling. This is not to say you shouldn't write generic rules, just don't use them unless you truly intend for them to be generic, and even them add as much scope information into the selector as you can.

Stuff like this...

.badges {
    width: 100%;
    white-space: nowrap;
}

address {
    padding: 5px 10px;
    border: 1px solid #ccc;
}

...has the same problem as using global variables in a programing language. You need to give them scope!

#question .userinfo .badges {
    width: 100%;
    white-space: nowrap;
}

#answers .answer .userinfo address {
    padding: 5px 10px;
    border: 1px solid #ccc;
}

Basically that reads as:

components                   target
---------------------------- --------
#answers .answer   .userinfo address
-------- --------- --------- --------
domain   component component selector 

I like using IDs whenever a component I know is a singleton on a page; your needs may be different.

Note: Ideally, you should write just enough. Mentioning more components in the selector however is the more forgiving mistake, compared to mentioning less components.

Lets assume you have a pagination component. You use it in many places across your site. This would be a good example of when you would be writing a generic rule. Lets say you display:block the individual page number links and give them a dark gray background. For them to be visible you have to have rules like this:

.pagination .pagelist a {
    color: #fff;
}

Now lets say you use your pagination for a list of answers, you may encounter something like this

#answers .header a {
    color: #000;
}
...
.pagination .pagelist a {
    color: #fff;
}

This will make your white links black, which you don't want.

The incorrect way to fix it is:

.pagination .pagelist a {
    color: #fff !important;
}

The correct way to fix it is:

#answers .header .pagination .pagelist a {
    color: #fff;
}

Complex "logic" comments don't work :)

If you write something like: "this value is dependent on blah-blah combined with height of blah-blah", it's just inevitable you'll make a mistake and it will all fall down like a house of cards.

Keep your comments simple; if you need "logical operations" consider one of those CSS templating languages like SASS or LESS.

How do you do I write a color pallet?

Leave this for the end. Have a file for your entire color pallet. With out this file your style should still have some usable color-pallet in the rules. Your color pallet should overwrite. You chain selectors using a very high level parent component (eg. #page) and then write your style as a self sufficient rule block. It can be just color or something more.

eg.

#page #header .description,
#page #categories .description,
#page #answers .answer .body
{
    color: #222; background: #fff; 
    border-radius: 10px;
    padding: 1em;
}

The idea is simple, your color pallet is a stylesheet independent of the base style, which you cascade into.

Less names, requires less memory, making the code easier to read

Using fewer names is better. Ideally use very simple (and short!) words: text, body, header.

I also find combination of simple words is easier to understand then having a soup of long "appropriate" words: postbody, posthead, userinfo, etc.

Keep the vocabulary small, this way even if some stranger coming in to read your style-soup (like yourself after a few weeks ;)) only needs to understand where words are used rather where every selector is used. For example I use .this whenever a element is supposedly "the selected item" or "the current item", etc.

Clean up after yourself

Writing CSS is like eating, sometimes you leave a mess behind. Make sure you clean up that mess, or the garbage code will just pile up. Remove classes/ids you don't use. Remove CSS rules you don't use. Make sure everything is nice a tight and you don't have conflicting or duplicated rules.

If you, as I suggested, treated some containers as black-boxes (components) in your style, used those components in your selectors, and kept everything in one dedicated file (or properly split a file with a TOC and headers), then your work is substantially easier...

You can use a tool such as the firefox extension Dust-Me Selectors (tip: point it to your sitemap.xml) to help you find some of the junk hidden in your css nukes and carnies.

Keep a unsorted.css file

Say you are styling a QA site, and you already have a stylesheet for the "answers page", which we will call answers.css. If you now need to add a lot of new css, add it to the unsorted.css stylesheet then refactor into your answers.css stylesheet.

Several reasons for this:

it's faster to refactor in after you're finished, then it is to search for rules (that probably don't exist) and inject code

you will write stuff that you will remove, injecting code just makes it harder to remove that code

appending to the original file easily leads to rule/selector duplication


non-tag selectors are much slower that tag-based ones. All browsers have native methods to get a 'div' for example (or any other tag). If you let it be too generic ('.class'), the rendering engine will have to walk all elements of the DOM to see if a match exists.
@Miguel Why would the rendering engine not have to walk all elements in the DOM to see if they are a DIV? If there is some special a optimization why isn't it applied to classes/ids? Do you have a source? The only visible performance killer I've noticed with CSS was due float spam -- it can cause the rendering engine to lag horribly on some browsers when scrolling the page (probably too many calculations).
I was going to vote this up for saying not to target tagNames (yay!) but then there was the part about not being generic (boo!)
@Miguel, it doesn't work that way. Browsers read a CSS string backwards, so it would take: "div .myclass" and find all ".myclass" classes, and then check if it is an ancestor of a div.
Comparing generic rules to global variables is the greatest misconception I've ever heard about CSS.
Z
Zimbabao

Have a look at 1. SASS 2. Compass


A million times this. Using Sass has made me a more organized & powerful css wrangler than ever. It lets me organize styles across multiple files, nest styles, use variables, etc., etc., etc.
sass, compass and less all produce normal CSS at the end of the day which could still be ugly and exploded. Its not a solution to CSS bloat in and of itself.
@Moin_Zaman In my humble opinion, sir, your statement is pure humbug. you write in sass/compass/less and organize your code in their files. you don't care about how the output css looks like. also, at least less (via less app) can minify the output which is great.
@bzx you're proving my point :) A browser does not understand sass/compass/less. all of these need to be compiled down to plain old CSS either clientside, or as part of your build. Using tools like these without knowing what they produce as CSS in the end makes it very easy to abuse them unknowingly and end up with larger than optimal CSS files.
That's where gzip compression comes into play… Most web servers and browsers will communicate with gzipped content when possible. If you end up repeating a selector fragment multiple times, that will be zipped into a single hash table entry. The only real issue then is the amount of RAM necessary to parse the CSS rules in the browser.
M
Moin Zaman

The best way I've seen to counter CSS bloat is using Object Oriented CSS principles.

There's even an OOCSS framework out there that's pretty good.

Some of the ideologies go against a lot of what's been said here in the top answers but once you know how to architect CSS in an object oriented fashion you'll see it actually work at keeping code lean & mean.

The key thing here is to identify 'Objects' or building block patterns in your site and architect with them.

Facebook hired the creator of OOCSS, Nicole Sullivan to get a lot of savings in their front end code (HTML / CSS). Yes you can actually get savings not only in your CSS, but in your HTML too, which by the sound of it, is very possible for you as you mention converting a table based layout into a lot of div's

Another great approach is similar in some aspects to OOCSS, is to plan and write your CSS to be scalable and modular from the start. Jonathan Snook has done a brilliant write up and book/ebook about SMACSS - Scalable and Modular Architecture for CSS

Let me hook you up with some links:
5 mistakes of massive CSS - (Video)
5 mistakes of massive CSS - (Slides)
CSS Bloat - (Slides)


R
Robusto

You should also understand the cascade, and weight, and how they work.

I notice you are using only class identifiers (div.title). Did you know that you can use IDs as well, and that an ID carries more weight than a class?

For example,

#page1 div.title, #page1 ul, #page1 span {
  // rules
}

will make all those elements share a font-size, say, or a color, or whatever your rules are. You can even make all the DIVs that are descendants of #page1 get certain rules.

As to weight, remember that the CSS axes move from most-general/lightest to most-specific/heaviest. That is, in a CSS selector an element specifier is overruled by a class specifier is overruled by an ID specifier. Numbers count, so a selector with two element specifiers (ul li) will have more weight than one with only a single specifier (li).

Think of it like digits. A 9 in the ones column is still less than a one in the tens column. A selector with an ID specifier, a class specifier, and two element specifiers, will have more weight than a selector with no ID, 500 class specifiers and 1,000 element specifiers. This is an absurd example, of course, but you get the idea. The point is, applying this concept helps you clean up a lot of CSS.

BTW, adding the element specifier to the class (div.title) is not necessary unless you are running into conflicts with other elements that have class="title". Don't add unnecessary weight, because you may need to use that weight later.


Using IDs is bad just like using global variables in your Visual Basic code.
@alpav: Sorry, that's incorrect. IDs are a terrific way to make like elements appear differently in different parts of a page without going nuts making up new class names.
@Robusto: Why making new ID name is harder than making new class name ?
@Robusto: making new class names is actually easier than ID names because with IDs you have to worry about global scope and with class names you need to worry only about uniqueness in local scope, same benefit as with local variables.
@alpav “That defeats the purpose of encapsulation - to be able to name locally without thinking globally.” Right, but CSS selectors are inherently global: when you write .myclass, you select everything with the class myclass. In CSS, classes are identical to ids in that respect.
A
Abhishek Mehta

May I suggest Less CSS Dynamic framework

It is similar to SASS as mentioned earlier.

It helps maintain CSS per parent class.

E.g.

 #parent{     
  width: 100%;

    #child1
    {    
     background: #E1E8F2;    
     padding: 5px;    
    }

    #child2
   {
     background: #F1F8E2;
     padding: 15px
   }
 }

What this does: Applies width:100% to both #child1 and #child2.

Also, #child1 specific CSS belongs to #parent.

This would render to

#parent #child1
{
 width: 100%;
 background: #E1E8F2;
 padding: 5px;
}

#parent #child2
{
 width: 100%;
 background: #F1F8E2;
 padding: 15px;
}

i use sass and it might be that this is a difference between sass and less, but i'm pretty sure it will compile as ` #parent { width: 100%; } #parent #child1 { background: #E1E8F2; padding: 5px; } #parent #child2 { background: #F1F8E2; padding: 15px; } `
P
Paul D. Waite

I find the difficult thing is translating the required design for a site into a series of rules. If the site’s design is clear and rules-based, then your class names and CSS structure can flow from that. But if people are, over time, randomly adding little bits to the site that don’t make much sense, there’s not a lot you can do about that in the CSS.

I tend to organise my CSS files roughly like this:

CSS reset, based on Eric Meyer’s. (Because otherwise I find that, for most elements, I’ve got at least one or two rules that are just resetting default browser styles — most of my lists don’t look like the default HTML style for lists, for example.) Grid system CSS, if the site calls for it. (I base mine on 960.gs) Styles for components that appear on every page (headers, footers, etc) Styles for components that are used in various places across the site Styles that are only relevant on individual pages

As you can see, most of that depends on the design for the site. If the design’s clear and organised, your CSS can be. If not, you’re screwed.


G
G-Wiz

My answer is high-level to address the high-level concerns you've raised in your question. There may be low-level organizational tricks and tweak you can do to make it prettier, but none of those can fix methodological deficiencies. There are several things that affect CSS explosion. Obviously the overall complexity of the site, but also things like naming semantics, CSS performance, CSS file organization, and testability/acceptability.

You seem to be on the right path with naming semantics, but it can be taken a step further. Sections of HTML that appear repeatedly on the site without structural modification (known as "modules") can be considered selector roots, and from there you can scope the internal layout relative to that root. This is the basic tenet of object-oriented CSS, and you can read/watch more about it in this talk by a Yahoo engineer.

It's important to note that this clean approach can run opposite of the concern of performance, which favors short selectors based either on id or tag name. Finding that balance is up to you, but unless you have a massive site, this should just be a guide in the back of your head reminding you to keep your selectors short. More about performance here.

Lastly, are you going to have a single CSS file for your entire site, or multiple files (a single base file used with per-page or -section files)? The single file is better for performance, but might be harder to understand/maintain with multiple team members, and might be harder to test. For testing, I recommend you have a single CSS-test page that includes every supported CSS module to test collisions and unintended cascading.

Alternatively you can have a multiple file approach, to scope the CSS rules to a page or a section. This requires the browser to download multiple files which is a performance issue. You can use server-side programming to specify and aggregate (and minify) the CSS files into a single file dynamically. But since these files are separate and the testing for them would be separate, you introduce the possibility of inconsistent look and feel across pages/sections. Thus testing becomes harder.

It's up to you to analyze the customer's specific needs, balance these concerns accordingly.


m
madr

As said before me: Get into OOCSS. Sass/Less/Compass is tempting to use, but until vanilla CSS is used the right way Sass/Less/Compass will only get things worse.

First of all, read up about efficient css. try Google Page Speed and read what Souders have written about efficient css.

Then, enter OOCSS.

Learn to work with the cascade. (After all, we call it Cascading Stylesheets).

Learn how to get the granularity right (bottom-up rather than top-down)

Learn how to separate structure and skin (what is unique, and what are the variations of these objects?)

Learn how to separate container and content.

Learn to love grids.

It will revolutionize every single bit about writing css. I am totally renewed and love it.

UPDATE: SMACSS is similar to OOCSS, but easier to adapt generally speaking.


"Sass/Less/Compass will only get things worse" - thats pretty subjective and project dependent. I would put forward that using one of these in conjunction with OOCSS would really benefit the maintainability of many large projects (especially those whose styles may be changed frequently)
Zach L: OOCSS (or for that matter, SMACSS) used correctly makes Compass/Less/Sass needed for vendor prefixes only.
I won't try to argue this too much (esp. since I don't currently use a pre-processor), but I'm pretty sure there are a bunch of people who DO find such things to be useful, even in combination with OOCSS/SMACSS outside of vendor prefix issues
J
Jack Kinsella

The core principles for sensible CSS, extracted from CSS Refactoring: From append-only to modular CSS

Write in SASS. You'd be insane to forego the advantages of variables, mixins, and so on. Never use an HTML ID for styling; always use classes. HTML IDs, when used correctly, appear only once in the whole page, which is the complete opposite of re-usability — one of the most basic goods in sensible engineering. Moreover, it's really hard to override selectors containing IDs and often the only way to overpower one HTML ID is to create another ID, causing IDs to propagate in the codebase like the pests they are. Better to leave the HTML IDs for unchanging Javascript or integration test hooks. Name your CSS classes by their visual function rather than by their application-specific function. For example, say ".highlight-box" instead of ".bundle-product-discount-box". Coding in this way means that you can re-use your existing style-sheets when you role out side-businesses. For example, we started out selling law notes but recently moved into law tutors. Our old CSS classes had names like ".download_document_box", a class name that makes sense when talking about digital documents but would only confuse when applied to the new domain of private tutors. A better name that fits both existing services — and any future ones — would be ".pretty_callout_box". Avoid naming CSS classes after specific grid information. There was (and still is) a dreadful anti-pattern in CSS communities whereby designers and creators of CSS frameworks (cough Twitter Bootstrap) believe that "span-2" or "cols-8" are reasonable names for CSS classes. The point of CSS is to give you the possibility to modify your design without affecting the markup (much). Hardcoding grids sizes into the HTML thwarts this goal, so it is advised against in any project expected to last longer than a weekend. More on how we avoided grid classes later. Split your CSS across files. Ideally you would split everything into "components"/"widgets" and then compose pages from these atoms of design. Realistically though, you'll notice that some of your website pages have idiosyncrasies (e.g. a special layout, or a weird photo gallery that appears in just one article). In these cases you might create a file related to that specific page, only refactoring into a full-blown widget when it becomes clear that the element will be re-used elsewhere. This is a tradeoff, one that is motivated by practical budgetary concerns. Minimise nesting. Introduce new classes instead of nesting selectors. The fact that SASS removes the pain of repeating selectors when nesting doesn't mean that you have to nest five levels deep. Never over-qualify a selector (e.g. don't use "ul.nav" where ".nav" could do the same job.) And don't specify HTML elements alongside the custom class name (e.g."h2.highlight"). Instead just use the class name alone and drop the base selector (e.g. the previous example should be ".highlight"). Over-qualifying selectors doesn't add any value. Create styles for HTML elements (e.g. "h1") only when styling base components which should be consistent in the whole application. Avoid broad selectors like "header ul" because it's likely that you have to override them in some places anyway. As we keep saying, most of the time you want to use a specific, well-named class whenever you want a particular style. Embrace the basics of Block-Element-Modifier. You can read about it for example on here. We used it quite lightly, but still it helped us a lot in organising CSS styles.


M
Mitchel Sellers

A lot of times I will see individuals break the file out into sections, with a heading comment between sections.

Something like

/* Headings and General Text */

.... stuff here for H1, etc..

/* Main page layout */

.... stuff here for layout page setup etc.

It works pretty well and can make it easy to go back later and find what you are working on.


This says nothing about the asker's concern about having "a separate CSS attribute for every single thing".
T
Toni Leigh

You should look at BEM.

Theory

BEM is an attempt to provide a set of instructions for organising and naming css selectors in an attempt to make things more re-usable and modular and to avoid clashes between selectors of the sort that often leads to spaghetti code and specificity headaches.

When it's used correctly it actually has some very positive effects.

Styles do what you expect when they're added to an element

Styles don't leak and effect only what they're added to

Styles are completely decoupled from document structure

Styles don't need to be forced to over-ride each other

BEM works well with SASS to bring an almost object oriented style to CSS. You can build modular files, that handle the display of a single UI element and contain variables, such as colours and 'methods' such as how internal elements are handled. While a hardcore OO programmer might balk at this idea, in fact, the applied concepts bring in a lot of the nicer parts of OO structures, such as modularity, loose coupling and tight cohesion and context free re-usability. You can even build in a way that looks like an encapsulated object by using Sass and the & operator.

A more in depth article from Smashing Magazine can be found here; and one from Harry Roberts of CCS Wizardry (who anyone involved in css should have a read of) is here.

In Practice

I've used this, several times, along with having used SMACSS and OOCSS meaning I have something to compare them too. I've also worked in some big messes, often of my own, inexperienced creation.

When I use BEM in the real world I augment the technique with a couple of extra principles. I utilise utility classes - a good example is a wrapper class:

.page-section {
    width: 100%;
}
@media screen and (min-width: 1200px) {
    margin: 0 auto;
    width: 1200px;
}

And I also rely somewhat on the cascade and specificity. Here the BEM module would be .primary-box and the .header would be the context for a specific over-ride

.header {
  .primary-box {
    color: #000;
  }
}

(I try my hardest to make everything as generic and context free as possible, meaning a good project almost everything is in the modules which are re-usable)

One final point I'd make here is that however small and un-complex your project may appear you should do this from the start, for two reasons:

projects increase in complexity, so laying good foundations is important, css included

even a project that appears simple because it's built on WordPress has little JavaScript can still be very complex in the CSS - OK, you don't have to do any server side coding, so that part is simple, but the brochure-wear front end has twenty modules and three variations of each: you've got some very complex css there!

Web Components

In 2015 we are starting to look at Web Components. I don't know a huge amount about these yet, but they look to bring all front end functionality together in self contained modules, effectively trying to apply the sorts of principles from BEM to the front end as a whole and componentise dispersed but wholly coupled elements such as DOM fragments, Js (MVC) and CSS that all build the same UI widget.

By doing this theyb will address some of the original issues that exist with css which we've tried to solve with things like BEM, while along the way making some of the other front end architecture more sane.

There's some further reading here and also a framework Polymer here which is well worth a look

Finally

I also think this is an excellent, modern best practice css guide - designed specifically for stopping large css projects from getting messy. I try to follow most of these.


N
Nightfirecat

I would recommend you to look at "Compass Style" CSS framework.


q
quinton

there is some great material here and some have taken allot of time in answering this question however when it comes to either seperate or individual style sheets I would go with seperate files for development and then move into have all your generic css used across the sited merged into a single file when deployed.

this way you have the best of both worlds, increases performance (less HTTP requests being requested from the browser) and seperation of code concerns while developing.


S
Stokely

I have been working with Cascading Style Sheets (CSS) for over 20 years. So below is my solution to help you:

ALWAYS use External CSS via a tag. External CSS is far superior to "embedded"