Over the years I’ve had quite a few eureka moments when it comes to CSS, when pieces fall into place and I realise a much better way of doing things. It’s both extremely satisfying but also somewhat annyoing since having that knowledge earlier could have saved me hours and hours of frustration and effort.
1. Understanding specificity, inheritance and cascading
Having a clear understanding of which styles will apply in which context will save you a lot of time and headache. I can’t tell you how many times I’ve scratched my head trying to figure out why a style wasn’t being applied correctly to an element despite the fact that it was clearly in the stylesheet.
Specificity
Specificity determines which CSS rule is applied by the browser, depending on where a selector fits in specificity hierarchy it will either be ignored or override an less specific selector. When a rule isn’t being applied by the browser but you think it should then usually specificity is to blame (altough there is the occasional doh moment where you edit or preview the wrong file). Using Firebug or Chrome Code inspector can help you identify whether a style is picked up by the browser and which styles may be overriding it.
Inheritance
When you define styles on an element then these styles will typically be inherited by any elements contained within that element. So if you for example set the “font-family:Helvetica,Arial,sans-serif” on the body tag then everything on the page will inherit and use that font unless you override that with a more specific rule. Not all properties are inherited by default, but you can force inheritance by adding a property-value pair with the inherit value.
Cascading or “The Cascade”
The idea of a “cascade” is at core of CSS (Cascading Style Sheets). The Cascade ties in with Specificity and Inheritance and adds the source order into the mix to determine what rules are applied to what elements. So not only does specificity of selectors matter but also the order of the selectors and even the order the style sheets are included when using multiple stylesheets. When it comes to source order the last one to the party gets the last word.
Additional reading
CSS Specificity Wars. Great article explaining Specificity using Star Wars characters and analogies.
Smashing Magazine: CSS Specificity – Things You Should Know
Smashing Magazine: CSS Specificity and inheritance
NetTuts: Quick Tip Understanding CSS Specificity
W3 CSS3 Cascade
2. Understanding of how use CSS with the DOM (Document Object Model)
I still remember the eureka moment I had when I first came to the realisation that I didn’t have to apply a class to every single element I wanted to style. It was during a practical test in a job interview when I was forced to style a page based on a PSD mock-up, but I wasn’t allowed to touch any of the existing HTML. For the first time I had to re-think my approach, instead of my then bad habits of slapping a class on pretty much every element, and look at the structure of the HTML document. The hierachy of and structure of the document, what existing ids or classes could I use and how were the elements inside those structured. After the excercise I felt like my eyes had just been opened and I finally understood much more about what CSS was all about.
Instead of creating CSS completely reliant on classes or IDs you can free yourself up to a handful of “hooks” on container elements.
For example instead using specific classes for everything
.header .heading {} .content .heading {} .content .bluetext {}
You could use a single class as starting point then refer to all elements of a specific type within that container e.g. specify that all “h1”, “h2”, “p” or “div” inside a container should be styled differently. If you add a class to the body of the page or the main wrapper/container to uniquely idenity the page you can also use that to create different styles for individual pages just by adding a single class.
.header h1 {} .container h1 {} .content div p {} body.aboutpage h1 {}
3. Understanding the box model, margins and padding
One of the first things you should come to grips with when starting out with HTML and CSS is the box model.
The CSS box model describes the rectangular boxes that are generated for elements in the document tree and laid out according to the visual formatting model.
The main components of the box model are:
- Height
- Width
- Position
- Margin
- Border
- Padding
The slightly tricky bit to come to grips with for beginners is the dimensions for a block element in the box model. When you define the width as 200px then you’d expect that this would be the width. This is true, however if you have a 1px border around the block element then you have to add 1px + 1px, then if you have 10px padding you have to add another 10px + 10px so the total width would be 222px.
Almost everything you do in CSS and HTML will in one way or another be directly or indirectly impacted by the box model so I highly recommend taking some time to read up and understand it properly. It’ll save you a lot of trouble down the road.
Additional Reading
The CSS Box Model
W3 Box model
Box model for beginners
Sitepoint: Box Model reference
4. Using CSS floats
Float is a CSS position property and has been a common way of creating CSS layouts since the move away from table based layouts sometime back in the last millenium. It’s a powerful but very unintuitive way of doing this that can be hard to get your head around. The concept is similar to that of print layout where you have images set into the page with text wrapping around, but with CSS and HTML there are a lot more uses for it and quite a few pitfalls to look out for.
- You can float elements left or right (or set it to float: none;)
- When floating an element it will automatically be considered a block element
- Floated elements will float to the edge or the container elemnt they are in
- Floating elements does not trigger hasLayout, this can cause unwanted layout issues with floated elements overflowing their containers
- Defining a width or height and setting overflow:hidden or overflow:auto on a container element can overcome the hasLayout and overflow issue
- To center floated elements use margin: 0 auto;
- If there is room in the container all floated elements will try to fit side by side on the same “row” unless you “clear” the floats
- Use clear:left, clear:right; or clear:both; to force a floated element to appear on the next “row”
These are just some of the things to keep in mind when using floats, don’t worry after a few tries and probably a few more errors you’ll get the hang of it.
Additional Reading
All about floats
Smashing Magazine: Float Theory, things you should know
A List Apart: CSS Floats 101
Clearing Floats
CSS Float Clearfix
5. Display:inline-block
I’ll be honest I’m starting to really love using inline-block over floats for layouts. Sure there are a few issues with it but the workarounds aren’t that bad and in comparison to using floats for everything it feels so much more elegant.
Benefits
- Easy to center elements both horizontally and vertically. I cannot stress how much easier this can make your life for certain types of layouts
- You can vertically align blocks top or bottom. Awesome when using blocks with variable content size
- No overflow issues. Elements containing inline-block elements will trigger hasLayout without any problems.
- Possible to use margins, border, padding and all other block element rules.
Downsides
- Not supported in IE7 or below. However there is a relatively easy work around of IE7 and a similar but less effective workaround for IE6.
- Inline-block elements honor whitespace. Typically this isn’t a problem but if you want multiple block elements to be side by side you may end up with a 4px spacing between them. You can either use negative margins or remove the whitespace in your HTML code
Additional reading
Sitepoint: Give Floats the Flick in CSS Layouts
Ternstyle: Float vs. Inline-Block
Cross Browser Inline-Block
IE7/Win inline-block and hasLayout
6. The value of keeping your CSS properly formatted and well structured
One often overlooked aspect of CSS is code formatting and naming standards. Just like with PHP or Java having a set of code standars for CSS can help with maintenance, debugging or just make it easier come up with useful names for selectors. When collaborating with other people on CSS, the need for a common standard for naming and structuring your CSS becomes even more apparent.
To be honest it’s not really that important what coding standard you choose. Whether it’s one that your company prefers, just personal preference or a standard you find online. The important thing is that there is a a standard and that people that are contributing CSS are aware of it. Even if you’re the only one writing CSS, if you write and structure your code in a consistent manner it will help you in the long run when to comes to maintaining old code or re-using some CSS from one site to another.
Additional reading
ProCSSor is an advanced CSS Prettifier that lets you format CSS in the exact way you want
WordPress CSS Coding Standards
7. Go beyond the standard class and ID selectors
Most of us are familiar with the standard .class and #id selectors in CSS and of course the plain tag selector but it doesn’t end there. There are :pseudoClasses, descendant selectors, adjacent selectors (x + y), selectors for direct children (x > y), attributes selectors y[attribute] and many many more. Learning a few more (or all of these) will open up for a lot more ways targeting specific areas with CSS rules without having to add additional classes to the HTML.
Additional reading
NetTuts: 30 CSS selectors you must memorize
8. Using CSS shorthand
CSS supports several different ways or writing the same rules, by using
The most common CSS short codes are:
- background: colour url(….) no-repeat top left; e.g. background:#ccc;
- font: font-style font-variant font-weight font-size/line-height font-family; e.g. font: normal 0.8em/1.5em verdana, helvetica, sans-serif;
- border: 1px solid #ccc;
- padding: top right bottom left; e.g. padding:5px 10px 0 10px; or just padding: 5px; = padding: 5px 5px 5px 5px;
- margin: top right bottom left; e.g. margin: 10px 0 5px 0; or just margin: 10px = margin: 10px 10px 10px 10px;
Personally I don’t use the font one that often as it’s a lot stricter than others and harder to read and I don’t often have to declare all the values for fonts. When do use the font short hand it’s usually on the body or main font style for the site and then everything else after that is overriding that with more specific rules for font-family, font-size, font-weight etc.
When overriding specificity more often than not you end up using more individual rules e.g.
- border-top:none;
- font-weight:normal
- padding-left: 0;
- background-color:#eee;
- and so on…
Additional Reading
9. Stacking classes
A HTML element is not restricted to having a single class or ID. You can apply multiple classes to the same HTML element but you can also define multiple selectors for the same CSS rule. Obviously this is a very simplified example but the general idea is that you if you can define a generic class or ID for a type of element and add an extra class for more specific instances of that type that needs to be styled differently. Instead of repeating all the property-value pairs for each rule your element will inherit the styles from the generic class and then add to or override it with the more specific class.
.container { display:inline-block; margin-right:10px; padding:10px; vertical-align:top; width:400px; } .container.wide { width:960px; margin:0; }
Note there is no space between the two class names in the example above. This means that it applies only to elements that have both the container and wide classes applied but it will still inherit all the styling from .container so there’s no need to repeat those property-value pairs. E.g.
<div class="container wide"> content </div>
Additional Reading
Multiple Class and ID selectors
10. Using some kind of CSS reset
The aim of using a CSS reset is to limit or reduce inconsistencies across browsers when it comes to things like default margins, font sizes of headings, line heights etc. Whilst the need for CSS resets is diminishing with modern browsers it’s still handy to include if your site needs to comply to older browsers.
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } /* remember to define focus styles! */ :focus { outline: 0; } body { line-height: 1; color: black; background: white; } ol, ul { list-style: none; } /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: separate; border-spacing: 0; } caption, th, td { text-align: left; font-weight: normal; } blockquote:before, blockquote:after, q:before, q:after { content: ""; } blockquote, q { quotes: "" ""; }
As important as it is to note which elements are included in the most popular CSS reset available today. It’s also important to note some of the elements that are deliberately excluded from this list:
- input
- button
- hr
These elements were excluded because their cross-browser differences are so vast that you would have to completely unstyle them to create a “bulletproof” element. They’re so weird, that even then, there’s no guarantee.
Additional reading
CSS Reset Reloaded by Eric Meyer
HTML5 Boilerplate is a great starting point for new HTML5 projects. It includes a CSS reset based on the latest reset by Eric Meyer.
Bonus: IE6 must die
Internet Explorer is the bane of Web Designers across the world, hell even Microsoft wants it gone.
The Triton rendering engine (Internet Explorer) has a nifty little feature that allows you to use IE specific HTML to target specific versions of the browser and then load a special style sheet just to deal with those issues.
<!--[if IE]> Target all versions of IE <![endif]–> <!--[if lte IE 7]> Target all versions of IE that are less than or equal to "7" <![endif]–> <!--[if IE 6]> Target IE 6 <![endif]–>
Using conditional comments to target IE and cut out your hacks, will slim down your main style sheet, and help load the page quicker in browsers that don’t need the correction code.
Some people argue that you should never need to use hacks, workarounds or special stylesheets if you just create standards compliant code. To that I have the following to say:
- IE6, IE7 and hell even IE8 are not standards compliant browsers.
- It is in theory possible to create HTML and CSS that will work in all browsers but to do so you’d limit yourself to the lowest common denominator and have to use older CSS and HTML. Your site may look the same or at least similar in older browser but it won’t win any innovation or design awards.
- Personally I think keeping a separate stylesheet for IE6 and/or IE7 is a much simpler, cleaner and elegant way of enabling at least basic support for IE without all the bells and whistles of CSS3 but still allowing your site to strut its stuff in modern browsers
If you’re not convinced consider progressive enhancement and graceful degradation techniques to allow your site to take advantage of features in modern browsers but degrade well for older browsers.
What are your favourite CSS tips or Eureka moments?
I hope you found this article helpful. If you’ve had your own aha moments when learning CSS feel free to share them in the comments below.
Well spoken! Just got my eye on inline-block, was so ‘amused’ by floats so inline-block seems like nice alternative.
stay sharp..
nice article, with great forwarding links. One quirk, though: ‘Inheritance’ is misspelled –second h4 after first h1– wich really doesnt diminish the article quality, but hey, those typos really jump to my eye…