Archive for the ‘css’ Category

Border Weirdness in Internet Explorer

While helping a friend rework his Vintage Board Games site (rework not live yet), we came across an interesting IE bug. In a nutshell, in some cases, IE was placing a CSS background image relative to the outside of an element’s border instead of the inside.

The simplified markup of the bug and CSS are as follows:

1
2
3
4
5
<div class="content">
	<div class="left"></div>
	<div class="right"></div>
	<div style="clear: both;"></div>
</div>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.container {
	width: 420px;
}
.content {
	border: solid 10px #3570d6;
	background: white url( background_invert.gif ) left center no-repeat;
}
.left {
	float: left;
	width: 200px;
	height: 300px;
	margin-left: 25px;
	background-color: green;
}
.right {
	float: right;
	width: 100px;
	height: 200px;
	margin-right: 25px;
	background-color: cyan;
}

Basically, it’s a two column layout with the columns wrapped in a div that has a large border. (That div also has a background image set on it. The .container div seems extraneous in this example but was a requirement for the layout.) The desired rendering of this markup should look something like the following: (Note: the black/brown box is the background image.)

ie_correct.gif

But in IE, we get this:

ie_bug.gif

If you don’t trust my images, please try for yourself.

We quickly found two solutions to this problem, the first involved altering the alignment of the background image to be center instead of left:

3
4
5
6
7
8
...
.content {
	border: solid 10px #3570d6;
	background: white url( background_invert.gif ) center center no-repeat;
}
...

This is how we actually solved the problem on the site. The second solution I found while attempting to narrow down the cause of this problem. For this solution we simply set a min-height on the .content div:

3
4
5
6
7
8
9
...
.content {
	min-height: 1px;
	border: solid 10px #3570d6;
	background: white url( background_invert.gif ) left center no-repeat;
}
...

I’m assuming this is some sort of hasLayout issue and giving the div a min-height (height in IE6, accomplished with conditional comments in my example) also gives it layout, but I honestly have no idea what causes this. Anybody have any thoughts?

Debugging the Client Side

By my definition of Web 2.0, one of the key requirements for any application is cross-browser compatibility. As a company, my employer defines this as IE 6+, Firefox 2+, and Safari 3 beta; all tested on Windows. It’s not ideal, but it covers a huge chunk of the market. This stack is pretty easy to test, but occasionally one of the browsers will throw a curve-ball and that’s where a typical the members of my team, or J2EE developers in general, get lost.

When somebody comes across some weird client-side error and they come looking for my help, I start with three questions:

  1. Does it validate? (Is it a strict doctype?)
  2. Is it in quirks mode?
  3. Did you separate content from presentation from behavior?

I think one and two are pretty obvious, if you’re not following the standards the browser can (and will) do what it wants with your page. Follow the rules and your playing field becomes a lot more level. Number three is a design choice that I prefer for keeping things clean; if your layers are separated, you know what behavior is coming from where. What does this mean? It means style is always stored in an external StyleSheet, JavaScript is always stored in an external JS file, and your HTML markup has no inline event handlers, script blocks, or style attributes. Not only does this make things easier to find and debug it also encourages progressive enhancement and accessible design.

Now that you’ve made sure those three cases are taken care of, do you still have the problem? I’d say 50% of the time the problem is solved, for the rest, here’s what I do. (First things first, make sure your toolbox is in order.)

For debugging CSS, use Firebug’s Inspect tool to make sure the correct CSS rules are applying to your element, this will show you which rules are applying and more importantly, which one is winning in the case of a conflict. If the problem is not showing up in Firefox, I’m guessing it also works in Safari, so it has be an IE issue. Check your floats, check your widths, and make sure you’re not relying on anything IE doesn’t support, like min-height or max-height. If you’re still not sure what’s going on, checkout the Microsoft Developer Toolbar. To get it, go to Microsoft.com and search for “Developer Toolbar,” I’d post a link, but every time I try bookmarking the page it moves, so it’s probably just easier to search for it. The Developer Toolbar works similarly to Firebug, but is definitely lacking. If your problem is in Safari, get a copy of the Webkit Nightly and enable the Web Inspector. It’s definitely better than the IE Developer Toolbar, but still not Firebug. In a pinch, try out the WestCiv XRAY and MRI bookmarklets which are easy enough to install and uninstall on a workstation that is not your own.

If you’re debugging JavaScript, the Firebug console is definitely the way to go for tracing, and you can even make it work on other browsers with their handy JavaScript-based utility. For IE specific errors you can try your luck with the Microsoft Script Debugger (again, search for it), but I find it to be a little bloated. At the time of this writing Webkit offers its own debugger in the form of Drosera, but it’s Mac-only, so unless you’ve got one you’re out of luck there. Finally, you can try out Aptana Studio which offers JavaScript debugging in Firefox (also in IE if you’re willing to pay for it), but I haven’t had a chance to really give it a test drive and at initial glance it seems a little clunky when working with J2EE.

There’s a ton of tools out there for debugging client-side problems, and with a little practice you’ll be debugging like a pro in no time at all. But please, remember one thing, the best offense is a good defense, separate your layers, avoid CSS hacks, and do things the right way the first time.

CSS Things I Learned The Hard Way — Absolute Positioning

While there’s no substitute for learning something by first making all of the mistakes, it doesn’t hurt to learn from somebody else’s. In today’s issue, we’re going to talk about absolute positioning.

absolute
The element’s box is laid out in relation to its containing block, and is entirely removed from the normal flow of the document. The containing block of the absolutely positioned element is the nearest ancestor element with a position other than static. If no such ancestor exists, then the containing block is the root element of the document.

Eric A. Meyer. Cascading Style Sheets 2.0 Programmer’s Reference. California: Osborne/McGraw-Hill, 2001.

In truth, the solution was in front of my face the entire time, I just never understood it! (Or possibly I just skimmed the paragraph and only read the first sentence, but that’s a different issue altogether!) The problem I was seeing was that my absolutely positioned (position: absolute; top: 0; left: 0;) element was appearing in the upper left of the viewport, not the upper left of its containing element.

The simple solution was just to set the position property of my containing element to relative. This is a valid solution because a relatively positioned element behaves exactly like a statically positioned element, except that the position properties (top, right, bottom, and left) are used to offset the element by the specified amount. So, as long as the position properties are left with their default values, to make a container element, all you need is position: relative.