css

organization

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.

Solution 1

This is a very good question. Everywhere I look, CSS files tend to get out of control after a whileespecially, 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 <ul>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 layoute.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 pagelike these three menustry 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: <body class='contactpage'> 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:

    <ul class="mainmenu">
     <li class="item_first item_active item_1"> First item </li> 
     <li class="item_2"> Second item </li> 
     <li class="item_3"> Third item </li> 
     <li class="item_last item_4"> Fourth item </li> 
    </ul>
    

    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.

Solution 2

Here are just 4 examples:

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.

Solution 3

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

Solution 4

Have a look at 1. SASS 2. Compass

Solution 5

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)

Solution 6

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.

Solution 7

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;
}

Solution 8

I find the difficult thing is translating the required design for a site into a series of rules. If the sites 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 dont make much sense, theres not a lot you can do about that in the CSS.

I tend to organise my CSS files roughly like this:

  1. CSS reset, based on Eric Meyers. (Because otherwise I find that, for most elements, Ive got at least one or two rules that are just resetting default browser styles most of my lists dont look like the default HTML style for lists, for example.)

  2. Grid system CSS, if the site calls for it. (I base mine on 960.gs)

  3. Styles for components that appear on every page (headers, footers, etc)

  4. Styles for components that are used in various places across the site

  5. Styles that are only relevant on individual pages

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

Solution 9

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.

Solution 10

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.

Solution 11

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.

Solution 12

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.

Solution 13

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.

Solution 14

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

Solution 15

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.

Solution 16

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

  1. ALWAYS use External CSS via a <link> tag. External CSS is far superior to "embedded" <style> and "inline" element styles <span style="color:blue;">my text</span> simply because external styles downloaded to the browser are cached for every page in your website and affect all web pages, not just one. Consider moving all those styles sprinkled throughout your website to CSS classes in your sheets. Make sure you add selectors to increase their weight in cases where they might have cascaded over earlier inherited styles. Note: Many JavaScript API's like Angular and others use embedded CSS which means they are slower and have to reload CSS every refresh or revisit to the site. Bad design!
  2. ALWAYS use a "Reset" Style Sheet for all your basic HTML Elements. Most CSS packages like Bootstrap and others come with a reset or reboot sheet. These restyle all your HTML element selectors so they look decent across all browsers and user agents. This saves you the nightmare of having to restyle and customize design across basic elements like form controls, layouts, text, etc. I wrote my own "reset" sheet years ago. I am going to post it on GitHub under "Universal CSS Framework" soon if you would like mine. Works in all the old and new browsers.
  3. Remember, all text-based styles cascade and inherit naturally down through the sites elements! So, you should rarely need to repeat font styles, line-heights, etc. Most young developers forget this. Text-based styles are inherited down the HTML tree so only have to be written one time in a parent. Often the <body> element is the best placed to set basic font styles, etc.
  4. Because of #3 you do NOT need CSS precrocessors like SASS to reorganize or manage your style sheets. Stay away from these third-party dependencies. CSS can be written to inherit or cascade styles through the site so you do not have to repeat the same font styling or properties across CSS classes, etc.
  5. Group your Block Level/Layout styles that control design. Use ID selectors (#myid) on top level HTML blocks to separate sections and use those in CSS selectors to manage items specific to that page or website section (#main .someclass {...}). These have the advantage that they are easy to track and easy to segregate, but ID selectors have very high selectivity or weight. ID selectors have a 1-0-0 or 100 weight over class which has 0-1-0 or 10 weight. This prevents any later style shifts from damaging your previous custom styles in specific protected sections.
  6. Design all CSS around a Single CSS Class that can be Reused. Avoid attaching more element and chains of classes in CSS selectors until you absolutely need to override a common shared class with a custom one. Example: .articlelink{...} would be the shared universal style everyone can access. .block1 .area2 .articlelink{...} would allow you to create a custom version throughout a section without creating a new class or changing the HTML.
  7. Use CSS Comments! /* My New Styles */ ...followed by blocks of related CSS or just use comments to explain what is not intuitive in your code.
  8. If you have big projects, have each developer write their own custom CSS sheets for their sections, but inherit the main site style sheets. First, make sure all sections of the website link to your basic reset and base site sheets first. This allows basic element styles, font settings, layout, page design, forms, and colors to be enforced by the base sheets first so developers only add new styles needed rather than reinventing the same wheel. As you update the base sheets all developers inherit, those appear naturally across all sections of the project with no effort, and the teams can see those instantly.

Remember, you are working with cascading style sheets, not style sheets! That means most text-based styles are designed to inherit from all the parent elements, then cascade those same styles down into your trees of HTML across thousands of pages with no extra code. Most new web developers fail to grasp the simplicity of CSS, so struggle with SASS and other tools to fix it. It just is not needed. CSS was designed this way over 20 years ago by very smart people that solved all these issues for you.

If you really start to use CSS the right way, you find you can erase most of the styles, SASS, minimization, and other external routines and extra code your website once used, while enjoying the cascading effects of CSS that were designed to make minimal coding possible long ago.

<html>
  <body style="color:blue;">
    <main>
      <section>
        <div>
          <div>
            <div>
              <p>hello blue world</p>
            </div>
          </div>
        </div>
      </section>
    </main>
  </body>
</html>

Peace