Let’s talk CSS. Not the uber sophisticated CSS designers use, but let’s focus on how a developer can manage their CSS and keep from going nuts. In particular, how to start thinking about modularizing the style selectors, file layout, and even some naming conventions. CSS is pretty simple in concept and a lot can be done with a little knowledge. But nightmares will plague you if you don’t think and plan out your CSS files.
Some people don’t seem to care too much about style. Developers often rejoice in not having design skills. And unless your working on a green field project or a site redesign, you probably rarely touch the CSS files. But when you do start making changes to the style problems arise in unexpected ways. Developers cope with unexplained behavior by experimenting and hoping some semi random tweak will work. And if all fails, write a new style to stop the madness by overriding cascading selectors.
I’m offering a tips that can help manage the madness. These modularizing tips are simple but hopefully will encourage people to plan out there CSS. Don’t balk at the simplicity. Simple means it can be implemented and maintained.
Many CSS resources exist and are only a Google search away. One of my favorite CSS sites is Zen Garden, which highlights the power of CSS. I am not a CSS expert in anyway, I just hate fighting against it when I know CSS could actually work elegantly.
Most experienced CSS authors partition their files and it’s worth looking at some of their code. Check out design centric websites and pick up ideas. A natural approach to start partitioning is to start with general and application wide settings. Zero out margins, remove borders, set default fonts, etc. This is usually the preamble to the main css file. The reason is to remove any unexpected behavior. Browsers historically interpreted borders, margins, and other properties a bit different and caused no end to the headaches when trying to herd pixles. So, tip 1, have a main CSS file named something like main.css.
The main.css should contain the styles that affect the app on the whole. The general look and feel of the site goes here. Fonts, colors, general containers and their spacing, etc are all defined in the file. Don’t litter this file with everything and anything. Just the major styles for the theme of the site.
I know, not a huge tip. You all probably already knew that one. But the real tip is not to make this file thousands of lines long which will impede your leveraging existing styles.
To prevent fustration when trying to find existing CSS styles to reuse in a gigantic file, think about partitioning the styles into multiple files. That’s tip 2. Like any good piece of software, the problem space is decomposed into smaller more manageable chunks. Same goes for CSS. Put related styles in to a it’s own file. This can be done at a feature or module level. What ever makes sense. This may be layout concerns for a checkout page, item details page, search results, etc. The style rules should be target specific page level concerns not generic ones. A container such as a panel or pane that is used on the page is probably generic and should have its own file dedicated to panes, panels, or containers. A site that has a public and private section, and/or an Admin area separate from the users may all have a slightly different look and feel. Separate these into a private theme CSS file or admin CSS file.
jQuery plugins come nicely packaged in modules. Packages typically contain a css file for whatever widget the plugin is providing. Think about your own HTML elements as widgets with their own CSS files. Layout your CSS in a way that the widgets work with parent CSS files and don’t restate rules that a parent rule already states. Some times it might require a little refactoring to spit apart an existing rule so your component can use part of an existing definition.
The general idea for tip 2 is to make many small decomposed files that can be mixed and matched and facilitate searching for relevant existing rules, and to limit unwanted rule clashing. It’s not rocket science, but it does take some thought.
Naming choices becomes important with all these files and widget selectors. Properly naming helps searching and preventing naming collisions. Not sure about you, but I often get frustrated when searching for some potential useful rule and find myself going on a snipe hunt instead. Less disciplined developers will end up creating new selectors rather than finding an existing one.
Tip 3 is to prevent collisions by name spacing your selector names. Prefix several components together to create a good selector name. A potential name spacing strategy may include the app name, feature name, widget name, and element name all concatenated. For instance “myapp-catalog-frame-header” would define a frame header for my apps catalogs. This would be a different header from the header used on the summary page, or the frame used in a different area of the app. Top level components would have shorter names while other lower level components would have longer names. Generic Layouts for catalog would start with “myapp-catalog”. I can find all the catalog styles in the catalog.css file instead of some ginormous CSS file that contains rules for everything. The Catalog may have rules for the frame, the frame headers, frame spacings, perhaps even unique button styling on this page, or perhaps custom message styles.
How do we go about naming our style selectors? I’ve seen class names like “blue”, “right”, “top”, etc. These names seem might seem ok when you first use them. As the saying goes, the two hardest problems in computer science is cache invalidation and naming things. I don’t invalidate caches on a regular basis, but I name things all day long. Get use to it, and make some attempt to make the names be meaningful. That’s tip 4. I think we can all agree that these names are horrible.
Suppose you have buttons and they have a style called blue attached to them. Your company is bought out and the site is re-branded. Blue buttons become green. What do you do? Update all the pages to include a green rule? Or perhaps, because you you used the DRY principle and only want to change the one rule that matters. You change blue rule to have the the color green. Wow. That would be bad, but is often done. Maybe we won’t get bought out or re-brand our site. That doesn’t negate the issue, it’s still bad.
So what do we do? We have to use names carefully. We don’t want to describe what it does. The details of the selectors do that. We want to give it a name that reflects what it is rather than what it does. This allows you to adjust the content as needed. Perhaps the class can be a “button”, a “checkout-button”, or a ‘signup-button’. Each one with it’s own styling. Perhaps the buttons styles cascade down from ‘button’ as well as some page specific style such as promotion that adds additional characteristics.
Small Selector Styles
Element styling doesn’t have to be defined in one giant rule. In fact it is probably better to break it into several smaller style rules to facilitate more flexibility and reuse. You guessed it. Tip 5. Segregate font and colors from spacing and alignments. Each get their own selector. How flexible do you want your CSS to be?
Cascade your style sheets
Did I really title this one that way? I find it interesting that a lot of good developers don’t actually leverage the C in CSS. They don’t cascade. Tip 6 is simply to embrace cascading. Stop fighting it. CSS gets very convoluted and difficult to debug when selectors are created to prevent cascading. I admit it isn’t always easy but it is more elegant if you do it right and things work better.
Yup. How could I not add that. the last tip is to keep it simple. Or maybe, simplify. Quit trying to man handle CSS by forcing the square pegs in the round hole, and using a hammer to smash CSS into submission. Take a step back and rethink the approach a bit. A simpler design is better.
- Put general site wide CSS styles into a main.css
- Break up your styles into module, features, or however you want to divide it up.
- Incorporate name spacing.
- Name selectors with meaningful names
- Break apart your styles into cohesive units
- Embrace the cascade
- Simplify your CSS
Going through all these hoops is a bit of a pain. Granted. But having a clean layout and sanely interacting CSS is a joy. Well maybe not a joy, but I assure you the opposite is true. Maybe you don’t fully agree, at least until you have had issues maintaining a project that had less than desirable CSS files. I know these tips weren’t earth shattering and not new. But I do think a lot of developers can use this info. Hopefully I reached one or two of them.
And in case you were wondering about the performance of serving out many small files, don’t worry too much about it. Modern Web Servers have techniques to combine files together to reduce the number of requests made for many small files. Find out what your web server provides and make sure it is implemented.
Just some thoughts