Over a million developers have joined DZone.

Writing Flexible CSS

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Being a css guy these days is not very exciting. Up until a few years ago, the css scene was brewing with activity, trying to overcome various browser bugs and css shortcomings. Every month there was a new method that fixed some or other nasty issue, saving us a whole lot of stress and cursing. But those days are over. Browsers have improved, most bugs are fixed (though some non-crucial ones remain) and peace has settled over the land of css once again.

Looking forward, there are many interesting css changes waiting to happen. Sadly, they've been waiting to happen for more than 5 years and it's hard to stretch the excitement for such a long period of time. Still, this is not a setback, merely another opportunity. Looking at the css that is written today, there is plenty of room for improvement. We might have learned to overcome the bugs, but we never really gotten past the point of getting it done.

When writing css, more often than not there are several ways to go about a certain problem. And between these choices are good ones and bad ones. Or at least, choices that are better and worse. Ways that allow us to write clean and easy to manage css and ways that result in messy, convoluted css. Surprisingly, hardly anyone seems to care thinking about these choices. You come across little snippets and sidetracks that suggest the superiority of certain techniques, but if you're looking for information on how to make your css more manageable and flexible, you will come up with very little.

This article highlights several methods to improve your css, chosen with flexibility and ease of adaptation in mind. They are not earth-shattering or revolutionary, but they will improve the flexibility of your css even if it is just a little bit. What follows is obviously not an exhaustive list of methods and is merely a start to get things rolling.

Think 'pages' And 'components'

A website is typically a combination of pages and components. Even though the (visual and functional) design is usually pretty well outlined when a site is in development, you never know what might happen in 6 months time. Redesigns can be pretty drastic, and "No, never." has a tendency to turn into "Yeah, well, but ...". It's always better to be prepared when it does.

Ideally, this would mean that every page on a site would have a unique identifier (a combination of id and class attribute values). This is of course a little too optimistic and near impossible to implement. Still, when you start laying out your html work, try to keep in mind that it would be safe to at least identify sections (and subsections) of a site no matter what the current design benefits might be. This will protect you from future changes and will leave you in power of the design simply by further specifying components on (sub)sections.

Use id attributes on the body element to identify unique sections within a site, class attributes can be used to further specify subsections (which then could be repeated through different sections - ie the use of classes). This will not result in the leanest html possible, but will improve the flexibility of your css options considerably.

Balance Your HTML And CSS

 /* messy css */  
.heading {font-size:108%; padding:0em 0.93em;}
/* clean css */
.heading {padding:0em 1em;}
.heading span {font-size:108%;}

Writing the leanest html possible is pretty passé, but even then it sometimes pays to add extra structural elements just to make the css work a little easier. In a perfect world, with perfect browser support and all css tools ready, this would not be a recommended practise. But this world does not exist, and while we try to keep our html as clean as possible, it often results in messing up our css instead.

The best example I found is to add an extra span tag inside each and every heading tag. Not only can it be used for image replacement techniques, it's also very valuable when adjusting the font-size of a heading. This way, you can keep margin and padding declarations on the heading tag without having to make time consuming calculations to make it all work out, assuming you're working on an em-based design (so no 0.93em margins when increasing the font-size to 108%).

The extra span element might seem superfluous, but it keeps the css cleaner and it makes the html more future-proof. Exactly what we were looking for.

Single Effect, Single Place, Single Value

 /* messy css */  
.parent {padding-left:0.5em;}
.parent .child {margin-left:0.5em;}
/* clean css */
.parent .child {margin-left:1em;}

Consider this to be a very important rule in css design, sadly one that is often overlooked. It's crucial for easy maintenance of css that you try to capture every (visual) effect in one css statement. The example above illustrates this rule. The net effect of both statements is the same, namely a 1em gap to the left of the content, but maintenance of the clean example is a lot easier as the css is more transparent. If someone asks you to adapt the 1em gap, it can be done in one place with one simple change.

Messy css like this is often the result of quick changes made during development. Rather than consider the best way to tackle a small change request, the first solution that springs to mind is applied. There's nothing inherently wrong with that as long as it is cleaned up afterwards. Needless to say, for most projects this is nothing more than an illusion and messy css like this ends up in the final deliverable.

It's a rule that cannot always be met, but should probably be in the back of your mind at all times, especially when working on paddings, margins, borders and other typical elements prone to messing up your css.


 /* example 1 */  
.container {border-left:1px solid #000; border-right:1px solid #000;}
/* example 2 */
.container {border:1px solid #000; border-left:none; border-right:none;}

One of the most interesting applications of the previous rule is in the use of shorthands. Of course css shorthand declarations are used to make the css more compact, but we can do more with them if we wanted to.

By using shorthands responsibly, we can express relations between the styles of related elements. The statements above will again result in the same effect, but they express a different relationship between both borders. The first example defines them as separate elements. One can be styled differently from the other. The second statement defines them as related elements, where the style of both is supposed to remain the same at all times. The colour or width of both borders can be changed with one simple change.

 /* example 1 */  
.heading {padding:0.5em; background:#0f0;}
/* example 2 */
.heading {padding:0.5em 0.5em; background:#0f0;}

Another interesting example is the use of shorthands for paddings and margins. The options above define the padding for a heading. Since the heading is given a background colour, it's typical to apply a padding to keep the content from the sides. In the first example a general padding is given, the second example expresses a padding for top/bottom and left/right separately.

While the second example might look a little awkward at first, it's probably the best option to choose. In a case like this, the left and right padding of a heading are usually dependent on the outline of the content below the heading. This could vary along the line, but it will not have any impact of the top/bottom padding of the heading. Should you opt for the first option and the outline of the content below the heading changes, you will need to rewrite your css statement.

Trivial you say? Maybe, but still a good indication for people working on changes long after you have delivered the original css file, and you might even be surprised by the impact when you're working on a file that has 1000+ lines (1 css selector/line). These relations might not always be clear at first, but a quick sit-down with the designer and a fair share of experience should help you along nicely.

Margins And Paddings

 /* example 1 */  
.container {padding:0.5em;}
/*example 2 */
.container>* {margin:0.5em;}

Choose margins over paddings if you can. There are many cases were both properties will result in the same effect, but thinking back of the previously stated rule, working with margins will give you more flexibility. Once a padding is set, the only way to reach outside the padded box is to apply a negative margin. Not only is this technique flawed in IE, you will need to apply a margin that is opposite to the padding given on the parent container. When the padding needs to be changed, this also means changing value of the negative margin.

A setup which leaves you wide open for mistakes. Instead of adding padding to the parent, you can apply a margin to all elements inside. This will give you a proper and clean result with one single statement. This statement also anticipates all new components added to the container and will give them a default place which is clear from all other components.

There are still problems with switching to margins, like clipped backgrounds and general IE6 support, but from a flexibility point of view, margins are highly superior to paddings.

Element Selectors

 /* bad example */  
ul.breadcrumb {...}
/* good example */
.breadcrumb {...}

Finally, there's the choice of adding element selectors to css declarations. In the example above we have declared our breadcrumb styles on an ul element. By doing so, we have locked the css to the html.

This is okay as long as the html element is the semantic equivalent of the component it represents. In other words, as long as the semantic meaning of the html element used is an exact match for the component. In the case of a breadcrumb, we're using a simple html list. The list element is obviously not a semantic match for the breadcrumb, as it is way more generic, making it a lot safer to leave off the element selector.

This will become painfully obvious when you ever decide to replace the ul element with an ol element. A purely semantic html issue that should not involve changing the css, as the styling and behaviour of the component haven't changed at all.

Using element selectors is okay if you have the same class applied to different html elements or when the semantic meaning reflects the component it is used for (styling paragraphs for example). If not, leave the element selector off as it will only brings you trouble in the future.


The point of this article is not to convince you of the techniques and methods listed above. You don't have to agree with everything being said here, nor do you have to point out flaws or complications with the methods listed above. I know they are not perfect and will conflict with other interest you might have.

The point of this article is to make you aware of the impact on css flexibility each method has. Some methods listed here will involve more work setting up, they might involve planning ahead a little more and they might ask you to work in a more structured manner. But each of these methods requires little extra effort that will pay itself back later on, long after initial development has finished.

So don't think of these methods as definite recommendations, but remember to think of the flexibility a method might give you the next time you write something down in your css file. And think of this only as the beginning, I am sure there are many more interesting examples out there. It would be great to see the css scene mature a little, away from the semi-structured garbage heap it is today, into a more flexible and easy to maintain field.

Flexibility might be just one of the many factors we're dealing with when writing css, but it is still very much ignored, unrightfully so.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.


The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}