Painless CSS Development Guide - (By Alexander Podgorny)
Painless CSS Development Guide - (By Alexander Podgorny)
Purpose
As we all know, css is not the most straight-forward of the languages.
There are several dimensions of inheritance. There are different browsers to write for. There are hacks
that defy logic. Etc.
Needless to say, css can get very messy and intangled. Not a surprize that it often treated like garbage,
semi-intentionally swept under the couch.
Sometimes, it gets pushed into the most unpredictable places: html, js, php, java and sometimes even
SQL. Good luck debugging this!
The purpose of this guideline is to introduce a set of clear and simple rules that, if followed, will:
1. Void most of the headache.
2. Bring beauty and structure to our CSS development cycle.
3. Minimize size of CSS load.
4. SIGNIFICANTLY ease the code maintenance.
1. Clear separation
Treat CSS like any other language - separate it into it's own tier, let it shine on it's own.
Example:
[ CORRECT ]
myButton.onMouseOver = function() { myButton.addClass('my-button-over'); }
[ WRONG ]
myButton.onMouseOver = function() { myButton.setStyle('background-
color','red'); }
1.2 DO NOT use ids (#id) notations in CSS, reserve them for JavaScript identification. Instead use CSS
classes (.myclass).
1.3 If JS needs to use CSS classes, they must be prepended with "js-" notation, and NEVER be used to
apply styles with CSS to avoid introducing bugs in
JavaScript when CSS selector is changed.
Example:
Consider a dialog widget that is used in multiple places across the site.
For a specific dialog that will, say, display a user profile information, the specific css file will be
called module.dialog.profilepopup.css.
This file will contain styling properties of the profile displayed within the dialog. It may or may
not override styles inherited from module.dialog.skin1.css.
The module.dialog.profilepopup.css can be compared to an OOP subclass of
module.dialog.skin1.css.
This way, we will have only one file that defines the generic looks of the dialog, and multiple
specific files for any specific dialog. And no extra CSS.
This will spare you firebugging, greping and searching your entire codebase for styles that
correspond to your module or widget. You will know EXACTLY the file you need.
4. CSS Selectors
4.1. Use dashes instead of underscores in your selectors.
This is just a widely accepted web standard.
4.2. Add a CSS class to the outmost HTML tag of your module/widget/layout that has the SAME NAME
as <module_name> or <module_name>-<module_specific> your CSS file
(replacing underscores with dashes, of course)
4.3. Use short but descriptive names for classes in any other inner tag. (Further referred to as "inner
classes")
4.4. ALWAYS define inner classes through the class of the outmost tag.
Examle:
Inside of our dialog_skin1.css file we need to skin a title bar and four corners:
[ CORRECT ]
.dialog-skin1 {
/* define css properties to inherit within the skin: font, background, etc */
background-color: #CCC;
}
.dialog-skin1 .title {
background-color: #666;
color: #FFF;
font-weight: bold;
}
.dialog-skin1 .corner-n {
width: 15px;
height: 15px;
background: url(images/dialog_corner_north.gif) no-repeat;
}
Prepending style selector with the widget/module/layout identifier will make sure that these
styles will NEVER interfere with any other style outside the module.
[ WRONG ]
Inside of our dialog_skin1.css file we need to skin a title bar and four corners:
.dialog-skin1 {
background-color: #CCC;
}
.title {
background-color: #666;
color: #FFF;
font-weight: bold;
}
.corner-n {
width: 15px;
height: 15px;
background: url(images/dialog_corner_north.gif) no-repeat;
}
There is a great chance that ".title" or ".corner-n" may be defined elsewhere in the
application and you will end up overriding it.
Example:
selector1 {
}
selector1 selector2 {
}
selector1 selector2 selector3 {
}
selector1 selector4 {
}
selector1 selector5 {
}
This way you will ALWAYS know where in the file to look for a specific style.
You will clearly see the style inheritance structure.
You can at-a-glance identify how your CSS applies to HTML (vertical readability)
6. Grids
6.1. Use grid classes to define positioning of your HTML elements. (Documentation coming soon)
.myClass {
width: 100px; /* Affects: FF, Safari, Opera, IE5, IE6, IE7, Targeting: FF, Safari, Opera */
.width: 102px; /* Affects: IE5, IE6, IE7, Targeting: IE7 */
_width: 101px; /* Affects: IE6, IE5, Targeting: IE6, IE5 */
}
IE8 Support
The best (google and facebook approved) solution is to make IE8 behave like IE7 by adding the
following meta tag: