In my web app I use several CSS classes to write less code. I use them quite often in the markup to add single property or two in some cases.
These are the following
.clear { float: none; clear: both; }
.fl_l{ float: left; }
.fl_r{ float: right; }
.ta_l{ text-align: left; }
.ta_r{ text-align: right; }
.no_td:hover { text-decoration: none; }
What similar classes do you use? Have you ever seen this technique in other projects?
Sorry to post an answer on such an old question, but I think this is a bad idea. Maybe for a specific set of problems, it fits the bill. My thinking is that CSS is where the style information should be. By doing what you suggest, you are essentially just using the style attribute in html and therefore mixing content w/ style information. This is a bad idea because if one day you decide to change the style completely, you will have to go in and also update the HTML by removing most of the classes.
For example, if you have HTML like this (say for an abstract that is used many times within the page):
<p class="abstract ta_l mb10">
Lorem ipsum dolor set.
</p>
And one day you decide to change how that abstract looks: for example, you don't want it to be "text-aligned:left" anymore and no margin bottom (that's presumably what mb10 would be... i've seen this being used before), you would have to go in and change the HTML.
Now multiply this by 10 elements you have to change. What if it was 50? What if you were doing a complete redesign? shudder.
CSS provides a way to select multiple elements with one simple query and give them an appropriate style that is easily changed from a centralized location. By using these "helper" classes, you are making the maintenance of this project a nightmare for the next developer.
Instead, if you have HTML like this:
<p class="abstract">
You should sign in or something!
</p>
and CSS like this:
.abstract {
margin-bottom: 10px;
text-align: left;
}
you could just change that one rule to this:
.abstract {
text-align: right;
margin-bottom: 0;
}
and be done w/ it! For all 50 elements!
just my 2 cents
-- from someone who just got burned by this.
yeah, if you don't use common classes like you do then your CSS files get extremely large and every class becomes extremely specific
some other common classes...
.split { float: left; width: 50%; }
.center { text-align: center: margin: auto; display: block; }
.bold { font-weight: bold; }
.top { vertical-align: top; }
.bottom { vertical-align: bottom; }
Restore the flow after a floating element:
.clearfix:after
{
clear:both;
content:".";
display:block;
height:0;
line-height:0;
visibility:hidden;
}
Everyone has their own preferences and it also depends on the nature of your application. That said, I do personally tend to reuse a base.css that I port from application to application as a starter style component. Within it I also implement Eric Meyers css reset statements which make development across browsers much easier.
If you are genuinely interested in finding out how professional css frameworks are formed then its probably worth your while downloading and reviewing the following:
960 grid css framework
Blueprint css framework
I like to stay away from what you describe as common class names, keeping as much style-related information away from the HTML as possible. As mentioned by hunter, this does mean selector lists can sometimes get long, but I don't find it a problem.
If I were to use a common class name for clearing floats (the only one of the examples given that I usually might), I'd more often than not use something like .group - the word group at least has some small amount of semanticity attached to it (a group of things that likely belong together). This was suggested by Dan Cederholm.
There are sometimes other considerations that may mean it's either okay or not okay to use class names like this. For example, if your layout changes depending on viewport size via media queries, you may not want something to be styled the same at all times meaning the class name looses its usefulness as you have to be specific with your selectors anyway. Another example would be if the HTML is content-managed by a non-techie client who may not keep your classes intact.
Related
One feature I really love with LESS is nested rules. It makes the stylesheet much cleaner that way and you can find an element very quickly.
I was wondering if there's an option when compiling to optimize selectors. For example...
#global {
/* Styles here maybe */
.container {
/* Styles here maybe */
#sidebar {
/* Styles here maybe */
.title {
font-weight: bold;
}
}
}
}
will be compiled to #global .container #sidebar .title { font-weight: bold; }.
But the first two selectors are useless, since #sidebar should be unique in my page.
Is there a way to ask LESS to compile this to #sidebar .title { font-weight: bold; } instead?
Your assumption is wrong that multiple IDs in CSS are redundant. Imagine, as an example, a site where the CMS generates the page type into the output, like that it's the contact page:
<body id="contact">
<section id="content">Blah</section>
</body>
According to your logic, the following piece of CSS would be a candidate for 'optimization':
#contact #content {
background:red;
}
Now however, your home page has <body id="home"> of course in this imaginary CMS. And suddenly the content of your homepage has a red background because you decided to erroneously optimize that #contact selector out of the CSS, while it most certainly shouldn't have a red background according to this rule.
So no, LESS cannot do this because it would break code. If you don't want the selectors, don't use them and don't put them in your code.
Other answers, including the accepted one, have explained convincingly why LESS cannot simplify your nested selectors in the way you want.
Actually, SASS has the ability to do this:
#global {
.container {
#at-root #sidebar {
.title {
font-weight: bold;
The #at-root directive essentially ignores all the higher nesting selectors. I don't know if LESS has something similar. The above compiles into simply
#sidebar {
.title {
font-weight: bold;
But there is a deeper issue here, starting with the fact that you "love" nested rules in LESS. Stop loving them quite so much. I don't know about you, but most people love nested rules because they think it's cool to exactly mimic the hierarchical structure of their HTML. The SASS docs even claim this as a benefit:
Sass will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML.
So people with HTML such as
<div class="foo">
<ul>
<li class="item">
write LESS like
.foo {
ul {
li.item {
This is a horrible, horrible idea, It makes the structure of CSS completely dependent on the structure of the HTML. If you change one nesting level in the HTML, your CSS breaks. Often this approach is combined with a lot of rules defined against tag names such as ul instead of class names, which aggravates the dependency, so changing the ul to ol in the HTML breaks the rules again. Or it's combined with rules based on Bootstrap classes such as col-md-6, so if you ever change that to col-md-4 things break again.
CSS rules should be orthogonal to the HTML. They represent a different dimension. They represent styling concepts which are applied selectively throughout and across the HTML.
I am guessing that you wrote
#global {
.container {
#sidebar {
.title {
font-weight: bold;
because you are adopting this mistaken idea of mirroring the HTML structure in your LESS. Then, you notice that this compiles down to having selectors which contain multiple IDs, which you imagine must be inefficient (although, actually, the degree of inefficiency is minimal). You yourself are writing extraneous nesting levels in your LESS, then complaining that they may be slowing down performance!
Worse, you've hard-wired assumptions about the HTML structure into your CSS. It's of no consequence that the sidebar happens to fall inside a .container which is inside a global element. So don't write them. Perhaps at some point you decide to change the container class to container-fluid. Boom, instantly your CSS breaks. What is the point of conditionalizing the fact that the title should be bold on it being contained with a container class, which in any case is a layout-related class that has (or should have) nothing to do with styling? If you're going to duplicate your HTML structure in your CSS using preprocessor nesting, just go back to writing inline styles. At least that way you'll only have one file to change when you change your HTML around.
When designing CSS, you should think just as hard about the design of the rules as you do about the design of classes and methods when writing JS. In this case, you need to ask yourself, "What characterizes the situation where I want some title to be bold? What drives that? What is the nature of boldness? What am I indicating by boldness? What is the semantic notion indicated by boldness?"
Let's say that you want all titles to be bold. Then you simply say that:
.title { font-weight: bold }
Let's say that you want a title to be bold only when it's in the sidebar. Then you simply say that:
#sidebar .title { font-weight: bold; }
My suggestion here is to go cold turkey. Stop using nesting during a withdrawal period. Write rules with the minimum number of selector components. Refactor your classes to have semantic names (such as title-emphasis). Once you're "sober", you can go back to cautiously using LESS's nesting capability when it is useful, such as perhaps for hover:
#boo {
color: red;
&:hover {
color: blue;
}
}
This is actually useful and saves you from writing #boo twice, and groups the rules in an easy-to-understand way.
Note: I use the word Module which in BEM is called a Block. Also using modified BEM naming convention BLOCK__ELEMENT--MODIFIER, please use that in your answer as well.
Suppose I have a .btn module that looks something like this:
.btn {
background: red;
text-align: center;
font-family: Arial;
i {
width:15px;
height:15px;
}
}
And I need to create a .popup-dialog module with a .btn inside of it:
.popup-dialog {
...
.btn {
position: absolute;
top: 10px;
right: 10px;
}
}
In SMACSS and BEM, how should you handle positioning a module inside of a module?
In your answer, please identify the correct solution, and analyze the following approaches as well: (note that all of the examples below build upon or modify the above CSS)
Approach 1
[ override the original .btn class inside of .popup-dialog ]
CSS:
.popup-dialog {
...
.btn { // override the original .btn class
position: absolute;
top: 10px;
right: 10px;
}
}
Markup:
<div class="popup-dialog">
...
<button class="btn"><i class="close-ico"></i> close</btn>
</div>
Approach 2
[ add a subclass inside of .popup-dialog ]
CSS:
.popup-dialog {
...
.popup-dialog__btn {
position: absolute;
top: 10px;
right: 10px;
}
}
Markup:
<div class="popup-dialog">
...
<button class="btn popup-dialog__btn"><i class="close-ico"></i> close</btn>
</div>
Approach 3
[ subclass .btn with a modifier ]
CSS:
.btn--dialog-close {
position: absolute;
top: 10px;
right: 10px;
}
Markup:
<div class="popup-dialog">
...
<button class="btn btn--dialog-close"><i class="close-ico"></i> close</btn>
</div>
Approach 4
[ subclass .btn with a layout class ]
CSS:
.l-dialog-btn { // layout
position: absolute;
top: 10px;
right: 10px;
}
Markup:
<div class="popup-dialog">
...
<button class="btn l-dialog-btn"><i class="close-ico"></i> close</btn>
</div>
Having struggled with the issue in a recent large-scale project myself, I applaud you to bringing this to attention on SO.
I'm afraid that there's not a single 'correct' solution to the problem, and it's going to be somewhat opinion-based. However I will try to be as objective as possible and give some insight in regard to your four approaches on what worked for my team and what didn't.
Also I'm going the assume the following:
You're familiar with the SMACCS approach (you read the book and implemented it in at least one project).
You're using only the (modified) BEM naming convention for your CSS classnames, but not the rest of BEM methodology development stack.
Approach 1
This is clearly the worst approach and has several flaws:
It creates a tight coupling between .popup-dialog and .btn by using context-based selectors.
You are likely going to run into specificity issues in the future, supposed you will add additional .btn elements in the .popup-dialog in the future.
If somehow you'd need to use classnames unaltered, I'd suggest at least reducing the depth of applicability by using direct child selectors.
CSS:
.popup-dialog {...}
.popup-dialog > .btn {
position: absolute;
top: 10px;
right: 10px;
}
Approach 2
This is actually quite close to our solution. We set the following rule in our project and it proved to be robust: "A module must not have outer layout, but may layout its submodules". This is in heavily inspired by #necolas conventions from the SUITCSS framework. Note: We're using the concept, not the syntax.
https://github.com/suitcss/suit/blob/master/doc/components.md#styling-dependencies
We opted for the second option here and wrap submodules in additional container elements. Yes, it creates more markup, but has the benefit that we can still apply layout when using 3rd party content where we can't control the HTML (embeds from other sites, etc.).
CSS:
.popup-dialog {...}
.popup-dialog__wrap-btn {
position: absolute;
top: 10px;
right: 10px;
}
HTML:
<div class="popup-dialog">
...
<div class="popup-dialog__wrap-btn">
<button class="btn"><i class="close-ico"></i> close</button>
</div>
</div>
Approach 3
This might seem clean (extends instead of overwrites), but isn't. It mixes layout with module styles. Having layout styles on .btn--dialog-close will not be useful in the future if you have another module that needs to have a different layout for a close button.
Approach 4
This is essentially the same as approach 3 but with different syntax. A layout class must not know about the content it lays out. Also I'm not to keen on the l-prefix syntax suggested in the book. From my experience it creates more confusion than it helps. Our team dropped it completely and we just treat everything as modules. However If I needed to stick with it, I'd try to abstract the layout completely from the module, so you have something useful and re-usable.
CSS:
.l-pane {
position: relative;
...
}
.l-pane__item {
position: absolute;
}
.l-pane__item--top-right {
top: 10px;
right: 10px;
}
.popup-dialog { // dialog skin
...
}
.btn { // button skin
...
}
HTML:
<div class="popup-dialog l-pane">
<div class="l-pane__item l-pane__item--top-right">
<button class="btn"><i class="close-ico"></i> close</button>
</div>
</div>
I wouldn't fault anyone for this approach, but from my experience not all layouts can be abstracted in a reasonable manner and have to be set individually. It also makes it harder for other developers to understand. I'd exclude grid layouts from that assumption, they're easy enough to grasp and very useful.
There you have it. I'd suggest trying the modified Approach 2 for the reasons stated above.
Hoping to help.
BEM
If you don't modify .btn inside .popup-dialog first approach is the best.
If you need some .btn modifications, according to BEM methodology you have to use modificator class, like .btn_size_s
If you have modification not directlly connected with .btn, and you doubt whether may be reusable in future, for example you have to float .btn to right only in popup, you can use mixin like .popup-dialog__btn
SMACSS
Again if you need just place one block inside other -follow first approach.
If you need any modifications, there 2 ways : subclasses and descendant selectors.
If you modification may be reused in future - use subclasses, like .btn-size-s.
If modification is tightly connected with some specific module - better use descendant selectors.
UPDATE:
Add few points to clear my answer:
Firstly, Approach 4 is unacceptable - you mix module with layout it is bad practice, as Layout classes in charge of grids and page sections geometry, Module is independent from Layout and should know nothing about section it placed.
Now let me comment other approach and what is the best usage of it:
Approach 1 - Consider following case: You have Popup Module with 'close' Button Module. Popup do nothing with Button, no modification, no floats or margings, its just its child. This is the case this approach is best.
Approach 2 - Another case: Popup has child Button, but we have to add extra top margin and float Button to the right. As you can see this modification tightly coupled with Popup, and cant be usefull for other modules. Such 'local' modifications best usage of this approach. in BEM this approach as also known as mix
Approach 3 - Final case: Popup with child Button, but we need bigger Button, such modificated button can be reused and may be usefull for other Modules and pages.
In BEM its called modifier
To mark main difference between A2 and A3, lets remove Button from Popup and place it somewhere else . A3 will still affect Button, A2 not.
So to work with module as child you can use A1 or A2, A3 should be used in case on module modification independently from context.
First off, I want to clarify that a button, by definition in BEM, is an ELEMENT not a BLOCK. So if you were to tackle this problem using the BEM methodology then this issue becomes a bit simpler.
Secondly, I agree with mlnmln's solution (Approach 2) as it defines the element variation within the block, which is unique to the block itself. However, if an element variation like this button exists outside of the popup-dialog block, then you would want to take Approach 3 and apply a naming convention that allows for global usage.
There is another convention that maybe suits your needs: https://ncss.io
Goal:
A predictable grammar for CSS that provides semantic information about the HTML template.
What tags, components and sections are affected
What is the relation of one class to another
Example:
<div class="modal-dialog">
...
<div class="wrapper-button-dialog">
<button class="button-dialog">close</button>
</div>
</div>
I have a .scss file that, among other things contains this:
nav {
font-size: 0;
ul {
margin: $padding/3;
}
li {
z-index: 10;
position: relative;
display: inline-block;
font-size: $fontSize;
/**
* If we want separated, Uncomment!
margin: $padding/3;
#include border-radius(5px);
*/
&:first-child {
#include border-radius(0 5px 5px 0);
}
&:last-child {
#include border-radius(5px 0 0 5px);
}
padding: $padding/3 0;
#include background(linear-gradient(lighten($textColor, 10%), $textColor));
border: 1px solid lighten($textColor, 20%);
a {
color: $brightColor;
padding: $padding/3 $padding;
font-weight: bold;
text-decoration: none;
#include transition(.2s all);
}
//Nested menues
ul {
opacity: 0;
//display: none;
position: absolute;
margin: 0;
top: 0;
left: 0;
right: 0;
z-index: 5;
pointer-events: none;
#include transition(.2s all);
li {
#include background(linear-gradient(darken($brightColor, 10%), darken($brightColor, 30%)));
display: block;
border: 1px solid lighten($textColor, 20%);
&:first-child {
#include border-radius(0);
}
&:last-child {
#include border-radius(0 0 5px 5px);
}
a {
color: $textColor;
}
}
}
&:hover ul {
pointer-events: all;
top: 100%;
opacity: 1;
//display: block;
}
}
}
How bad/harmful it is in practice? I've heard many talks about "Don't go over 3 nested selectors!" But how harmful is it really? Does it have any visible impact on page loads? The benchmarks I've done say no, but is there anything I'm missing?
It depends on how much dynamic manipulation of the DOM and styles will go on after page load. It's not page loads (mostly) or slow selectors on initial layout that are at issue, it's repaints/reflows.
Now, Steve Souders says that on the average site it's simply not a real concern. However, on a web app or highly interactive site, poorly performing CSS rules can make your repaints slower than they have to be. If you have a lot of repaints...
Experts such as Nicole Sullivan, Paul Irish, and Steve Souders have covered the way CSS interacts with with JavaScript and how to write highly performant CSS selectors. It's more than depth (different selectors have different performance), but a good rule of thumb is to limit both depth and complexity to keep yourself out of trouble--but not so much performance trouble, read on.
However, as jankfree.org notes, it's not so much descendant or specific selectors as it is certain properties in certain contexts (html5rocks.com) that make paints expensive. I see long or complicated selectors more as a maintainability issue (Nicolas Gallagher) than a performance issue--keeping in mind that maintainability interacts with performance. Highly maintainable code can iterate faster and is easier to debug (helping you find and fix performance issues).
Now, as to Sass optimization. Yes, Sass can optimize your CSS. But it cannot optimize your selectors. A 4 level nested block will be output as a 4 level nested selector. Sass cannot change it without possibly making your CSS not work. You, as the author, have to optimize the way you write Sass to optimize your output. I, personally, use nesting only in a limited way (a killer feature in Sass for me is composing styles with #extend and placeholders). However, if you really love nesting you might be able to tweak your output to some degree using the Sass parent selector reference (or the newer #at-root).
So far as I know, neither Sass nor Compass has a built-in tool to analyze selectors and warn about them. It's probably possible to create a tool to do that (set a max depth and have your pre-processor warn you) utilizing an AST. More directly, Google Page Speed does have an existing feature that provides some information. SCSS Lint has a nesting option. There's also CSS Lint. (These can theoretically be added to run in your Compass config's on_stylesheet_saved if you're not already using something like Grunt or Gulp).
Just think about how you would want to write the actual css selector. Don't nest everything just because it is a child of the element.
nav li ul li a {
/* over specific, confusing */
}
.sub-menu a {
/* add a class to nested menus */
}
Once you start chaining that many selectors, it becomes a pain to override and can lead to specificity issues.
Don't nest CSS. We feel comfortable nesting css because that closely mirrors what we do in HTML. Nesting gives us context that .some-child is inside .some-parent. It gives us some control over the cascading. But not much else.
As SMACSS suggests, I would nest in class names instead. i.e, use .child-of-parent instead of .parent .child or .parent > .child
Nesting badly in practice can lead to extremely slow pages. See how github speeded up their diff pages.The least you should do is follow the inception rule which states that you shouldn't be nesting beyond 4 levels.
However, I would go one step further and say that we shouldn't nest CSS at all. I wrote a blog post with my opinions. Hope this is useful.
Just to chime in and enforce what others have said. It's a bad practice not necessarily from a performance point of view (It's probable you'll get better paint time increases from removing blurs/shadows and rounded corners than optimising selectors) but from a maintainability point of view.
The more heavily nested a selector, the more specific the resultant CSS rule (which you know already). Therefore, when you want to 'trump' that rule at some point you'll have to write a rule of equal (or greater) specificity further down the cascade to overrule the first. If you have an ID in there, that's going to make it FAR more specific too (so avoid unless you need them and know you won't need to override down the line).
To follow this to its logical conclusion, don't nest unless you need to. Don't have a rule like this:
.selector .another .yeah-another {}
When this would do the same job:
.yeah-another {}
It just makes life easier for everyone (including you) down the line.
My opinion:
You tell me which is worse on your eyes
from the op
nav li ul li a {color: $textColor;}
or as has been suggested
.nav-menuitem-menu-menuitem-link {color: $textColor;}
So...
The question is "Is it bad practice to hypernest in SCSS?" (or is it SASS?) I say no. But it's an ancillary argument.
The WORSE practice lies in leaving the SASS (or is it SCSS?) output, in it's machine-driven state, for production.
S*SS is a only a tool in your bag of tricks, no different than Notepad++ or Git or Chrome. It's role is to make your life a little easier by bringing some very general programming concepts to the point of building some css. It's role is NOT building your css. You can't expect it to do your job for you and create completely usable, readable, performing output.
Nest as much and as deep as you want, then follow Good Practice...
...which would be going thru your css afterwards and hand tweaking. Test, build, etc with your hypernested output. And when S*SS creates my first example above, give that anchor a class and call it with nav .class.
Although not directly an answer to your question, you can keep highly nested sass for your own purposes but still use #at-root. Check it out here.
.parent {
#at-root {
.child1 { ... }
.child2 { ... }
}
}
// compiles to ...
.child1 { ... }
.child2 { ... }
I gave up on using CSS for form styling when I hit snags like requiring 3 textboxes adjacent to one another (like a phone number) or a dropdown list next to a textbox. I just couldn't come up with a reliable way to style it without good ol' TABLES.
I'm thinking about going back to CSS for form styling; I don't know:
Whether it's more usable to have captions on top or on the left of the field.
How to style the things so they place nicely even with a couple of adjacent form elements.
References? Is this still a pipe dream?
You mean like this?
Basically we create a pseudotable
.mxrow {
clear: both;
width: 100%;
height: 50px;
}
.mxcell {
float: left;
padding-top: 10px;
padding-bottom: 10px;
height: 26px;
}
.mxcell_firstcell{
width: 25%;
}
And the markup would be
<div class = "mxrow">
<div class = "mxcell mxcell_firstcell"><input element /></div>
<div class = "mxcell mxcell_secondcell"><another form element/></div>
</div>
The individual cell classnames serve to apply specific css (my markup is a grid)
There are a couple of CSS templates designed specifically for laying out forms.
vessess.com
Uni-form
I hope this helps point you in a productive and awesome direction. Take care.
No, it is very possible, and I (and many others) have been doing it for years.
Look at float: (left|right) and display: (inline|inline-block).
Other people give you some valid suggestions... if you still have problems you can try a form css framework like formee... http://www.formee.org/
How does one go about establishing a CSS 'schema', or hierarchy, of general element styles, nested element styles, and classed element styles. For a rank novice like me, the amount of information in stylesheets I view is completely overwhelming. What process does one follow in creating a well factored stylesheet or sheets, compared to inline style attributes?
I'm a big fan of naming my CSS classes by their contents or content types, for example a <ul> containing navigational "tabs" would have class="tabs". A header containing a date could be class="date" or an ordered list containing a top 10 list could have class="chart". Similarly, for IDs, one could give the page footer id="footer" or the logo of the website id="mainLogo". I find that it not only makes classes easy to remember but also encourages proper cascading of the CSS. Things like ol.chart {font-weight: bold; color: blue;} #footer ol.chart {color: green;} are quite readable and takes into account how CSS selectors gain weight by being more specific.
Proper indenting is also a great help. Your CSS is likely to grow quite a lot unless you want to refactor your HTML templates evertime you add a new section to your site or want to publish a new type of content. However hard you try you will inevitably have to add a few new rules (or exceptions) that you didn't anticipate in your original schema. Indeting will allow you to scan a large CSS file a lot quicker. My personal preference is to indent on how specific and/or nested the selector is, something like this:
ul.tabs {
list-style-type: none;
}
ul.tabs li {
float: left;
}
ul.tabs li img {
border: none;
}
That way the "parent" is always furthest to the left and so the text gets broken up into blocks by parent containers. I also like to split the stylesheet into a few sections; first comes all the selectors for HTML elements. I consider these so generic that they should come first really. Here I put "body { font-size: 77%; }" and "a { color: #FFCC00; }" etc. After that I would put selectors for the main framework parts of the page, for instance "ul#mainMenu { float: left; }" and "div#footer { height: 4em; }". Then on to common object classes, "td.price { text-align: right; }", finally followed by extra little bits like ".clear { clear: both; }". Now that's just how I like to do it - I'm sure there are better ways but it works for me.
Finally, a couple of tips:
Make best use of cascades and don't "overclass" stuff. If you give a <ul> class="textNav" then you can access its <li>s and their children without having to add any additional class assignments. ul.textNav li a:hover {}
Don't be afraid to use multiple classes on a single object. This is perfectly valid and very useful. You then have control of the CSS for groups of objects from more than one axis. Also giving the object an ID adds yet a third axis. For example:
<style>
div.box {
float: left;
border: 1px solid blue;
padding: 1em;
}
div.wide {
width: 15em;
}
div.narrow {
width: 8em;
}
div#oddOneOut {
float: right;
}
</style>
<div class="box wide">a wide box</div>
<div class="box narrow">a narrow box</div>
<div class="box wide" id="oddOneOut">an odd box</div>
Giving a class to your document <body> tag (or ID since there should only ever be one...) enables some nifty overrides for individual pages, like hilighting the menu item for the page you're currently on or getting rid of that redundant second sign-in form on the sign-in page, all using CSS only. "body.signIn div#mainMenu form.signIn { display: none; }"
I hope you find at least some of my ramblings useful and wish you the best with your projects!
There are a number of different things you can do to aid in the organisation of your CSS. For example:
Split your CSS up into multiple files. For example: have one file for layout, one for text, one for reset styles etc.
Comment your CSS code.
Why not add a table of contents?
Try using a CSS framework like 960.gs to get your started.
It's all down to personal taste really. But here are a few links that you might find useful:
http://www.smashingmagazine.com/2008/08/18/7-principles-of-clean-and-optimized-css-code/
http://www.smashingmagazine.com/2008/05/02/improving-code-readability-with-css-styleguides/
http://www.louddog.com/bloggity/2008/03/css-best-practices.php
http://natbat.net/2008/Sep/28/css-systems/
Think of the CSS as creating a 'toolkit' that the HTML can refer to. The following rules will help:
Make class names unambiguous. In most cases this means prefixing them in a predicatable way. For example, rather than left, use something like header_links_object2_left.
Use id rather than class only if you know there will only ever be one of an object on a page. Again, make the id unambiguous.
Consider side effects. Rules like margin and padding, float and clear, and so on can all have unexpected consequences on other elements.
If your stylesheet is to be used my several HTML coders, consider writing them a small, clear guide to how to write HTML to match your scheme. Keep it simple, or you'll bore them.
And as always, test it in multiple browsers, on multiple operating systems, on lots of different pages, and under any other unusual conditions you can think of.
Putting all of your CSS declarations in roughly the same order as they will land in the document hierarchy is generally a good thing. This makes it fairly easy for future readers to see what attributes will be inherited, since those classes will be higher up in the file.
Also, this is sort of orthogonal to your question, but if you are looking for a tool to help you read a CSS file and see how everything shakes out, I cannot recommend Firebug enough.
The best organizational advice I've ever received came from a presentation at An Event Apart.
Assuming you're keeping everything in a single stylesheet, there's basically five parts to it:
Reset rules (may be as simple as the
* {margin: 0; padding: 0} rule,
Eric Meyer's reset, or the YUI
reset)
Basic element styling; this
is the stuff like basic typography
for paragraphs, spacing for lists,
etc.
Universal classes; this section
for me generally contains things
like .error, .left (I'm only 80%
semantic), etc.
Universal
layout/IDs; #content, #header,
or whatever you've cut your page up
into.
Page-specific rules; if you
need to modify an existing style
just for one or a few pages, stick a
unique ID high up (body tag is
usually good) and toss your
overrides at the end of the document
I don't recommend using a CSS framework unless you need to mock something up in HTML fast. They're far too bloated, and I've never met one whose semantics made sense to me; it's much better practice to create your own "framework" as you figure out what code is shared by your projects over time.
Reading other people's code is a whole other issue, and with that I wish you the best of luck. There's some truly horrific CSS out there.
Cop-out line of the year: it depends.
How much do you need to be styling? Do you need to change the aspects of alomost every element, or is it only a few?
My favorite place to go for information like this is CSS Zen Garden & A List Apart.
There are two worlds:
The human editor perspective: Where CSS is most easily understand, when it has clear structure, good formatting, verbose names, structured into layout, color and typesetting...
The consumer perspective: The visitor is most happy if your site loades quickly, if it look perfect in his browser, so the css has to be small, in one file (to save further connections) and contain CSS hacks to support all browsers.
I recommend you to start with a CSS framework:
Blueprint if you like smaller things
or YAML for a big and functional one
There is also a list of CSS Frameworks...
And then bring it in shape (for the browser) with a CSS Optimizer (p.e. CSS Form.&Opti.)
You can measure the Results (unpotimized <-> optimized) with YSlow.
A few more tips for keeping organized:
Within each declaration, adopt an order of attributes that you stick to. For example, I usually list margins, padding, height, width, border, fonts, display/float/other, in that order, allowing for easier readability in my next tip
Write your CSS like you would any other code: indent! It's easy to scan a CSS file for high level elements and then drill down rather than simply going by source order of your HTML.
Semantic HTML with good class names can help a lot with remembering what styles apply to which elements.