Understand css Positioning element

Positioning is tough to understand when you’re first starting out with CSS. Your choices are

  1. Static
  2. Relative,
  3. Absolute,
  4. Fixed.

Static is the default option and is positioned according to the normal page flow.

Relative item is positioned relative to itself, meaning you can move it up, down, left or right, based on where it would normally sit.

Absolute allows you to place an item anywhere on the page, and is the most misused positioning statement. The values you set for it will be relative to the last parent item with relative or absolute, and if there aren’t any, it defaults back to the html tag, allowing you to position it anywhere by declaring top left right or bottom values.

Fixed is positioned relative to the browser window, so an item will stay in place if a user has to scroll. Learning how to use positioning correctly is important, but shouldn’t be used excessively. I rarely use these at all in my stylesheets.

Some usefull css tips, tricks

CSS font shorthand rule

When styling fonts with CSS you may be doing this:

font-size: 1em;
line-height: 1.5em;
font-weight: bold;
font-style: italic;
font-variant: small-caps;
font-family: verdana,serif;

There’s no need though as you can use this CSS shorthand property:

font: 1em/1.5em bold italic small-caps verdana,serif

Much better! Just a couple of words of warning: This CSS shorthand version will only work if you’re specifying both the font-size and the font-family. Also, if you don’t specify the font-weight, font-style, or font-varient then these values will automatically default to a value of normal, so do bear this in mind too.

2. Two classes together

Usually attributes are assigned just one class, but this doesn’t mean that that’s all you’re allowed. In reality, you can assign as many classes as you like! For example:

<p class="text side">...</p>

Using these two classes together (separated by a space, not with a comma) means that the paragraph calls up the rules assigned to both text and side. If any rules overlap between the two classes then the class which is below the other in the CSS document will take precedence.

3. CSS border default value

When writing a border rule you’ll usually specify the colour, width and style (in any order). For example, border: 3px solid #000 will give you a black solid border, 3px thick. However the only required value here is the border style.

If you were to write just border: solid then the defaults for that border will be used. But what defaults? Well, the default width for a border is medium (equivalent to about 3 to 4px) and the default colour is that of the text colour within that border. If either of these are what you want for the border then you can leave them out of the CSS rule!

4. !important ignored by IE

Normally in CSS whichever rule is specified last takes precedence. However if you use !important after a command then this CSS command will take precedence regardless of what appears after it. This is true for all browsers except IE. An example of this would be:

margin-top: 3.5em !important; margin-top: 2em

So, the top margin will be set to 3.5em for all browsers except IE, which will have a top margin of 2em. This can sometimes come in useful, especially when using relative margins (such as in this example) as these can display slightly differently between IE and other browsers.

(Many of you may also be aware of the CSS child selector, the contents of which IE ignores.)

5. Image replacement technique

It’s always advisable to use regular HTML markup to display text, as opposed to an image. Doing so allows for a faster download speed and has accessibility benefits. However, if you’ve absolutely got your heart set on using a certain font and your site visitors are unlikely to have that font on their computers, then really you’ve got no choice but to use an image.

Say for example, you wanted the top heading of each page to be ‘Buy widgets’, as you’re a widget seller and you’d like to be found for this phrase in the search engines. You’re pretty set on it being an obscure font so you need to use an image:

<h1><img src="widget-image.gif" alt="Buy widgets" /></h1>

This is OK but there’s strong evidence to suggest that search engines don’t assign as much importance to alt text as they do real text (because so many webmasters use the alt text to cram in keywords). So, an alternative would be:

<h1><span>Buy widgets</span></h1>

Now, this obviously won’t use your obscure font. To fix this problem place these commands in your CSS document:

h1
{
background: url(widget-image.gif) no-repeat;
}
h1 span
{
position: absolute;
left:-2000px;
}

The image, with your fancy font, will now display and the regular text will be safely out of the way, positioned 2000px to the left of the screen thanks to our CSS rule.

6. CSS box model hack alternative

The box model hack is used to fix a rendering problem in pre-IE 6 browsers, where by the border and padding are included in the width of an element, as opposed to added on. For example, when specifying the dimensions of a container you might use the following CSS rule:

#box
{
width: 100px;
border: 5px;
padding: 20px;
}

This CSS rule would be applied to:

<div id=&quot;box&quot;>...</div>

This means that the total width of the box is 150px (100px width + two 5px borders + two 20px paddings) in all browsers except pre-IE 6 versions. In these browsers the total width would be just 100px, with the padding and border widths being incorporated into this width. The box model hack can be used to fix this, but this can get really messy.

A simple alternative is to use this CSS:

#box
{
width: 150px;
}

#box div
{
border: 5px;
padding: 20px;
}

And the new HTML would be:

<div id=&quot;box&quot;><strong><div></strong>...<strong></div></strong></div>

Perfect! Now the box width will always be 150px, regardless of the browser!

7. Centre aligning a block element

Say you wanted to have a fixed width layout website, and the content floated in the middle of the screen. You can use the following CSS command:

#content
{
width: 700px;
margin: 0 auto;
}

You would then enclose <div id=&quot;content&quot;> around every item in the body of the HTML document and it’ll be given an automatic margin on both its left and right, ensuring that it’s always placed in the centre of the screen. Simple… well not quite – we’ve still got the pre-IE 6 versions to worry about, as these browsers won’t centre align the element with this CSS command. You’ll have to change the CSS rules:

body
{
<strong>text-align: center</strong>;
}

#content
{
<strong>text-align: left</strong>;
width: 700px;
margin: 0 auto;

}

This will then centre align the main content, but it’ll also centre align the text! To offset the second, probably undesired, effect we inserted text-align: left into the content div.

8. Vertically aligning with CSS

Vertically aligning with tables was a doddle. To make cell content line up in the middle of a cell you would use vertical-align: middle. This doesn’t really work with a CSS layout. Say you have a navigation menu item whose height is assigned 2em and you insert this vertical align command into the CSS rule. It basically won’t make a difference and the text will be pushed to the top of the box.

Hmmm… not the desired effect. The solution? Specify the line height to be the same as the height of the box itself in the CSS. In this instance, the box is 2em high, so we would insert line-height: 2em into the CSS rule and the text now floats in the middle of the box – perfect!

9. CSS positioning within a container

One of the best things about CSS is that you can position an object absolutely anywhere you want in the document. It’s also possible (and often desirable) to position objects within a container. It’s simple to do too. Simply assign the following CSS rule to the container:

#container
{
position: relative;
}

Now any element within this container will be positioned relative to it. Say you had this HTML structure:

<div id=&quot;container&quot;><div id=&quot;navigation&quot;>...</div></div>

To position the navigation exactly 30px from the left and 5px from the top of the container box, you could use these CSS commands:

#navigation
{
position: absolute;
left: 30px;
top: 5px;

}

Perfect! In this particular example, you could of course also use margin: 5px 0 0 30px, but there are some cases where it’s preferable to use positioning.

10. Background colour running to the screen bottom

One of the disadvantages of CSS is its inability to be controlled vertically, causing one particular problem which a table layout doesn’t suffer from. Say you have a column running down the left side of the page, which contains site navigation. The page has a white background, but you want this left column to have a blue background. Simple, you assign it the appropriate CSS rule:

#navigation
{
background: blue;
width: 150px;
}

Just one problem though: Because the navigation items don’t continue all the way to the bottom of the screen, neither does the background colour. The blue background colour is being cut off half way down the page, ruining your great design. What can you do!?

Unfortunately the only solution to this is to cheat, and assign the body a background image of exactly the same colour and width as the left column. You would use this CSS command:

body
{
background: url(blue-image.gif) 0 0 repeat-y;
}

This image that you place in the background should be exactly 150px wide and the same blue colour as the background of the left column. The disadvantage of using this method is that you can’t express the left column in terms of em, as if the user resizes text and the column expands, it’s background colour won’t.

At the time of writing though, this is the only solution to this particular problem so the left column will have to be expressed in px if you want it to have a different background colour to the rest of the page.

stop using CSS hacks

With the imminent launch of IE7 your usual CSS hacking methods are going to fail. If you want to save web design, as we know it, it’s time to take some drastic action.

CSS has experienced a colourful and unusual history. From historic slow adoption to the current slow rate of development, ugly hacks have meant filling in the gaps is par for the course.

With CSS1, we had a simple and elegant styling language that was supposed to be friendly to even non-programmers. Hence decisions like, say, lack of variables and constants, or conditional logic. (My kingdom for an if statement!)

Then CSS2 came along and provided us with some powerful layout tools. Except some browsers completely disagreed on how to implement them (the box model and floats are two examples that come to mind). Us web designers took care of that problem however, thanks to our lovely CSS hacks and filters. Using perfectly valid CSS, we were able to exploit a browser’s parsing error and specifically serve (or hide) our CSS to it. Problem solved. Lucky us.

But now that Internet Explorer 7 is looming, we’re getting ready to deal with the first really major upgrade to a browser’s rendering engine since we’ve started using CSS-based layouts in earnest. (The launch of Safari didn’t really count, since it was so capable right out of the gate.) The truth is that when IE 7 comes most of our usual hacking methods are going to fail. Afraid yet?

Here’s the nasty little secret of CSS-based development over the past few years: we’ve had a stable target. Because of IE6’s limitations, we’ve been fairly conservative in our usage. There’s really no such thing as cutting-edge CSS, since the CSS2 spec has been final since the late 90’s and CSS3 is off somewhere in the future. Anything we’ve done to date has been able to degrade as gracefully as possible in IE, so we’ve held back on even the more interesting bits of CSS2.

Sure, there are great advanced demos in the form of the CSS Playground, or CSS/edge, or even various CSS Zen Garden designs. But for production-based sites that we create for clients? Conservative CSS use has reigned supreme.

Except … some of us have been a little more than liberal in our hack usage, haven’t we? You might argue that those hacks were necessary to make any sense of the messy browser landscape we were presented with. At the end of a long day of coding, loading that beautiful new site in Internet Explorer has always been a soul-crushing experience. Almost none of us want to spend the time necessary to wrap our minds around just how on earth IE has decided to mangle our code. A few dashes of * html [1] here or _width [2] there and the problem goes away. The short term fix we applied three years ago, however, now threatens to come back and bite us in the rear.

Conditional Comments

IE7 will fix a lot of traditional CSS hacks. The Internet Explorer team has publicly expressed disapproval of the whole idea of hacks, in favour of an IE-proprietary method known as conditional comments. Instead of code like this to filter a rule to Win/IE:

* html #selector {
	width: 100px;
}

We should instead be using an HTML comment syntax to selectively serve up a link to an external CSS file, which will contain a similar rule. The syntax looks like so

<!--[if IE]>
	<link rel="stylesheet" href="ie-specific-file.css" />
<![endif]-->

And then the IE-specific CSS file in question might contain the following rule:

#selector {
	width: 100px;
}

In theory, this system works much better than CSS hacks ever did. Instead of specifically exploiting bugs in a browser, bugs that will obviously one day get fixed, conditional comments are an officially-sanctioned feature of the browser that won’t ever go away. They validate, and even though they’re proprietary, when used with discretion they allow us to accomplish exactly the same thing as CSS hacks.

Sidebar

The question is begged, of course: why are conditional comments implemented only in HTML, and not in CSS? I have it on good word this is something the IE team may look into for future releases. For now, we must place our conditional comments in our HTML files.

Future Updates

But this is simply one single browser updating, and there’s a larger issue here which we’re going to have to start thinking about sooner or later. I’d prefer sooner.

All popular browsers are improving at a frequent clip again. We’re not stagnating anymore; the improvements are going to keep coming. CSS3 isn’t finished yet, but various modules of it are being implemented already. The future is just around the corner.

As the modern browsers update, in what other interesting and creative ways will our code break? How are we going to test them? How are we going to selectively serve up code to various versions?

Take Safari. Version 2.0 was recently released. Apple has no provision for installing and running multiple versions side by side however, much the same as Microsoft has always done with Internet Explorer.

The practical implication here is that I simply can’t test my work in Safari 1.0 any longer. How do we test now, without needing to own a separate computer for each individual version of a browser? Microsoft suggests we buy Virtual PC and multiple Windows licenses to maintain multiple versions of IE (more of my thoughts on that here), an expensive proposition. Apple hasn’t suggested anything.

Causing web developers to buy more software and hardware simply to test seems an unlikely scenario; but somehow, test we must.

Versioning

And the problem will amplify over time, as more incremental updates are released, and the browser share fragments. In one sense this won’t be 1998 all over again with its 85 different versions of Netscape 4, thanks to browser auto-updating keeping most users current. But, not every user will keep up to date. I can’t count how many times I ignore the update nag message on my own machine, so they can hardly be blamed.

What are the odds that all those early adopters of Firefox 1.0 or 1.2 have kept updating, and made it to version 1.5? Likely not as high as we’d hope. Are we going to continue testing in each of them? How will we fix rendering issues that affect 1.0 and 1.2, but not 1.5? No CSS hack I’m aware of can address that discrepency.

Now, let’s be clear. Ever since CSS1, there’s been a very simple versioning control built into the language. If a browser can’t understand a selector or a rule, it simply ignores it. The theory being, as browsers add new support for a particular CSS property or selector, they’ll simply start rendering the rule they previously ignored all along.

Hasn’t worked out so well, has it? One fatal flaw of this method is that it assumes that support for new selectors and properties will be perfect from the start. Need I even get into the problems that have resulted in browser implementation errors? Box model, anyone?

The other, more subtle flaw in this method is that it assumes the fallback is good enough. Simply not rendering a rule due to lack of support, however, causes adverse side effects in styles that depend on that rule. Side effects that can translate into major usability problems for your site’s visitors.

The most obvious example I can give you lies within the CSS3 text-shadow property, which is supported only by Safari at the moment. By using the drop shadow as an outline, we can do things previously impossible, like set white text on a white background.

Text Shadow Demo

To the left, you see the results in Safari; a perfectly legible pairing. To the right, you see almost nothing at all. This is what the text looks like in every other major browser, since they ignore the text-shadow property.

Is just ignoring the unsupported property a good enough fallback? Not in this case, and there are other potential problems in this vein. Point being, this all-or-nothing method of managing change simply doesn’t cut it. We need browser-specific filtration, to account for scenarios where the fallback causes more harm than good.

“A standard is a standard – you should be able to render the same code consistently in every browser,” I hear some cry. “Browser-specific authoring is a dead end.” And they have my emphatic agreement. I’d love it if the real world proved that were the case. But it’s not.

Legitimate Hack Use

No matter how browsers evolve over the next few years, one thing seems relatively safe to predict – there will always be differing levels of support for web standards, whether it be a difference in rendering between major browsers, or even between various versions of the same browser.

The legitimate need for hacks arose as we discovered major browser bugs that prevented us from adopting CSS in the first place; through the use of hacks, we were able to specifically target versions of browsers and force them to comply. Even those on the W3C CSS working group recognize the need for page authors to work around these bugs; wasn’t it Tantek Çelik who gave us the Box Model Hack, after all?

But our CSS hacks are meant for an older set of browsers that will become less relevant in the near future; we don’t have any new mechanisms for filtering the current stable of browsers. How will we deal with browser discrepancies going forward, in light of potential usability problems?

Coping

I see a few ways.

  1. Limit yourself to only those CSS properties and selectors that you know will work across all browsers without fail. In fact, you don’t even have to wait for this, you can start today. Sure, it’s frustrating when all browsers but a single one render on your intended effect, but we’ve pretty well gotten used to that with things like :hover support on non-anchor elements. So, hang on to that patience, because you’ll need it.
  2. Perhaps this may not even be an issue. If all browsers continually improve, and we never see another repeat of Internet Explorer’s stagnation over the past 5 years, then we simply need to be patient until the effects we seek become practical, and with any luck that won’t be long.
  3. We could discover a whole new bag of hacks and filters. With the number of people hacking away at CSS these days, the chances aren’t small that sooner or later we’ll be able to exploit other bugs in other browsers, and get ourselves right back into this situation. I think a lot of people would prefer we didn’t go this route again, but it’s almost inevitable that sooner or later, the first IE7 and Firefox 1.0 hacks will rear their heads.
  4. Let’s think pie-in-the-sky here: we could get a bit of recognition that this problem is legitimate, and an official W3C-sanctioned method of browser filtration. I suspect the browser manufacturers are well aware that this is a problem; the IE team has given us a method for filtering out their own browser in the form of conditional comments, after all. Suggestions for codifying a similar method within CSS have been made to the CSS working group many times over the years, and I have it on good authority that there has been at least one formal proposal made in the past on the subject, but as far as I know, nothing has developed from either.

The danger in going this route echos what we learned about HTTP user agent strings in the late 90’s, of course. Crappy browsers will force page authors to filter them somehow. Crappy filtering will cause browsers to pose as each other. Maybe it would be better this time around, since the base technologies have matured a little bit. Maybe it wouldn’t.

The Reality

So what do I think is actually going to happen moving forward? Quite likely, a bit of everything.

Many will certainly follow the path of least resistance and simply limit themselves to code that works cross-browser. Others won’t settle for the status quo, and instead will look high and low for new hacks that target specific versions of specific browsers.

And maybe, just maybe, we’ll get a reliable method of filtering on a per-browser basis. I’m not holding my breath on that last one, but stranger things have happened.

Notes

  1. The Tan Hack, or * html bug as it’s also known, causes only IE to parse the CSS within the selector to which it’s applied. It will be fixed in IE7.
  2. The underscore hack causes only IE to parse the CSS within the rule to which it’s applied. It also will be fixed in IE7.

Technorati Profile