Archive for January, 2007

IE6 Ordered List Bug

Wednesday, January 31st, 2007

This is, without a doubt, the strangest IE 6 bug that I’ve ever encountered (and, I’ve encountered just about every one). Here’s the gist of it: when a list item (<li>) in an ordered list (<ol>) has layout, it can’t keep track of it’s correct number any more. That’s right: every item in an ordered list will be item 1. Insane.

How do you get this crazy behavior? Do things like give an <li> width or height. Due to IE’6 wonky list rendering in general, it will also probably no longer display the number indicator entirely, but this can be fixed by using list-style-position:inside or giving the <ol> in question some margin-left. Once that number displays, if it wasn’t already, it will be "1." Over and over and over again.

How can you combat this bug? Well, you can give width to the parent <ol> and use padding to acheive the width you’d like. (Also, you’ll probably need to give the parent <ol> some negative left margin to combat the crazy margin you’ll need to use to get the list item numbers to display in the first place).

Confusing? Yes. Just remember: width and height on <li> tags can lead to strange behavior in IE6.

technorati tags:, ,

Stretchy background gradient with CSS

Thursday, January 25th, 2007

In some cases, a design calls for a column with a background color blending into a gradient (or blending into gradient fading into white for a little "fade out" effect). That’s not terribly difficult to do when you’ve got a column with a fixed height: just cut a one-pixel-wide background image and use background-repeat:repeat-x in your CSS. That will create the effect you’re looking for: a full column width and column height gradient. But, what if you’re trying a background gradient in a column with a liquid height?

Here’s an example of what we’re trying to do, with CSS and HTML created by yours truly at the day job. Check out the left column. Essentially, we’re using the two-column layout described here and we’d like one of our liquid height columns to have a background gradient (or, in TheLadders example, a solid background color moving into background gradient fading out to solid white). It’s easy to do in four lines of CSS. This is the basic premise:

  1. The Setup: From your design, slice your gradient at the point where the solid background color ends and the gradient shift begins. Leave a pixel or two for a buffer. This will allow us to use CSS to specify the background color, and our gradient image to live as our gradient.
  2. The CSS: The CSS isn’t very complicated at all. You’ll just be letting background-repeat do its thing, and prevent your background gradient image from tiling. In our case, we’ll need to specifiy background-color, background-image, background-position, and finally background-repeat for the effect. By using these properties, we’ll ensure that we have a solid color and a non-tiled background sitting right at the bottom of our column, no matter how tall it gets.

What does all that code look like? Something like this:

div#leftColumn{
    background-color:#333;
    background-image:url(images/gradient.gif);
    background-position:bottom;
    background-repeat:no-repeat;
}

Pretty simple, eh? background-position ensures our gradient sits at the bottom of our column no matter how tall it is, while background-repeat ensures we only see it once. You’d like a top-down gradient? Use background-position top. As the example shows, we get a pretty little visual from some pretty short code.

Ruby strftime without leading zeros

Wednesday, January 10th, 2007

Ah. Saved me some thinking time.

technorati tags:,

The iPhone bandwagon. Usability? Accessibility?

Wednesday, January 10th, 2007

Yes, Apple’s iPhone is cool. But, will it have a cool experience?

Dan Saffer, in the Adaptive Path blog, wonders whether or not the lack of tactile and haptic responses will harm the experience, despite the device’s feature set.

The same discussion has broken out at 456 Berea St.

I’ll grant that the device is certainly cool. But, how long will it take to retrain oneself to use a different method of "keying in" data? Is it worth it just for a – albeit very cool – phone? Those are questions that are probably answered when you see the thing up close (or, in our case, see pictures of it online): "I’ll gladly relearn how to dial to use these apps on the go."

Is this new interface, and its potential clashes with accessibility and usability, a design mistake by Apple? I don’t think so. In fact, it seems that they’re designing primarily (or, singularly) for their target audience, who will buy out this product when it launches and will take the time to train themselves to "do things a new way on their phones." Apple’s primary user base will be elated with the new gadget, and will plunk down millions the moment they go on sale. Apple’s primary user will be tech- and design-savvy enough to have few problems using and adapting to the new product; it’s designed for them. However, in creating a design that may – we don’t know the details of the product’s specifications yet – lock out a whole group of users with different needs, is Apple valuing the business over the experience for all?

technorati tags:, ,

Styling Form Controls with CSS

Tuesday, January 9th, 2007

Roger Johansson presents tyling form controls with CSS, revisited. It’s a look at just what CSS can do when used on nearly every single element you’d stock in your forms, and is good for a view if you plan on attempting to add style to your forms any time soon.

technorati tags:,

Unix is usable?!

Saturday, January 6th, 2007

Most people (I think it would be safe to assume) would state a usable interface must be a visual interface. While not necessarily crammed with graphics or cool effects, a usable interface, they would argue, is one that you can interact with using your mouse and screen, seeing updates and feedback as those things happen. Unix, then, with its text-only command line and sometimes-cryptic editors, would be the opposite of a usable interface: almost 100% of command line applications work mysteriously, accomplishing some goal sometimes silently at the completion of some often-cryptic keystrokes. So, Unix can’t be usable, right? Wrong!

How can it be??? A usable product is not necessarily one with an amazing visual design, or any visual component whatsoever: a tight visual design can be – and often is – part of a usable product, but it is still just a piece of the larger puzzle. A usable product – in a certain sense – is a product that supports users, making it easy, quick, and delightful for them to accomplish their goals.

A usable product is a product that does exactly what it’s supposed to do, and makes it easy to do so. Dan Saffer, in a blog post discussing Neal Stephenson’s In the Beginning … was the command line, talks about a command line application traders used while he worked at Datek. While it did have a learning curve, it turned out to be very supportive of users who took the time to learn it. The product made users’ jobs easier, making trading a quick series of keystrokes and punch of the enter key. It was nothing more than a textbox.

Slashdot features an article on the birth of Unix editor vi. Vi was designed, the article states, "so that you could edit and feel productive when it was painting slower than you could think." In this, it did what is a very key component of many interfaces (and what a great many interfaces fail to do): it overcomes technological restriction to make users forget that those restrictions exist; it lets users simply do their jobs in the most productive way possible, despite the underlying technology they’re using. This captures the essence of a usable product: it lets users accomplish their tasks without them having to worry about what’s going on in the background.

Usable products, to expand our really limited definition from early, also support varying levels of users, from beginners to power users. Certainly, Dan’s Datek application and vi have learning curves, but they do support users of all types, and do what many "modern" interfaces do not: they reward users for learning more about them and practicing with them. Take a look at the comments in the Slashdot post. Hundreds of people have commented on their favorite editor, with many talking about how the keyboard commands are now firmly ingrained in their memory and permanently boost their productivity. They’d never switch to a graphical editor, because they’re reaping the rewards of learning: their favorite editor has a productivity reward for power users that few interfaces really can capture.

Most interfaces are built for occasional use; should you limit your users to a small set of commands because you believe they’ll only use your product occasionally, or should you build in levels of commands, rewarding users for repeatedly using and learning your product? If it’s a product users’ are paying to use, I’d strongly recommend the latter: if I’m paying for a product, I expect to be using it frequently and am glad to learn ways to speed up and improve my workflow. I’d like a vi, a product that rewards and supports power users.

Sometimes, usable, supportive technologies go almost sight-unseen. A truly usable product does not need a lot of glimmer, or even any glimmer at all. A usable product simply needs to let users accomplish what they’re trying to accomplish, while providing users with the opportunity to benefit from becoming power users of that product, reaping the rewards of really learning about what that product can do. Perhaps, like those hundreds of Slashdot comments would suggest, we should look to Unix for usability guidance.

technorati tags:, ,

IE7 conditional comment

Friday, January 5th, 2007

If you, like me, are using conditional comments to apply CSS "fixes" to Internet Explorer here’s the one you’ll need to detect IE 7:

<!--[if IE 7]>

<![endif]–>

technorati tags:, , ,

Equal-height, 100% height columns with CSS and JavaScript

Friday, January 5th, 2007

Yes, that title was a mouthful. But, you know the idea: you have a CSS-based two-column layout, and you want both columns to always be the exact same height. Maybe you have a narrow left navigation column with a background color (or a gradient) and a wide right content column; if you want that background color to appear for the entire height of your content column, then you’ll need this trick, otherwise, it’ll stop when it reaches the height of its container.

Here’s an example of what we’re looking to achieve in a layout I built at my day job over at TheLadders.com. In this case, the left-hand column has a solid color fading into a gradient at the bottom of our content block. Since the right column will stretch that block down, we need to force the left-column to have the same exact height as the right column. How do we go about doing that?

There are plenty of ways to do make equal height columns using crazy CSS hacks and other methods. They work well, but they’re not very clean. To make it nice and easy, we need to use JavaScript for its main purpose: controlling presentation. And, we’ll only need a few lines of code to do it.

The Set-up
Here’s some example CSS to get that two-column look:

div#container{
  width:800px;
}

div#container div#leftColumn, div#container div#rightColumn{
  float:left;
}

div#container div#leftColumn{
  background-color:#CCC;
  width:250px;
}

div#container div#rightColumn{
  margin-left:50px;
  width:500px;
}

There’s a two-column layout for you. Here’s what that would look like with some example, placeholder content.

The JavaScript
See? That right column extends far past the left column, but we can take care of that with a simple JavaScript function (I had to add a line wrap to fit everything in the page; remove it to actually use the function):

function equalColumns(){
  var l = document.getElementById('leftColumn');
  var r = document.getElementById('rightColumn');

  r.offsetHeight >= l.offsetHeight ? l.style.height =  \\ line wrap
  r.offsetHeight + "px" : r.style.height = l.offsetHeight + "px";
}

Let’s examine what this function does. First, we store references to our two columns. Then, we do the dirty work, using the ternary operator for our comparison. Let’s examine what it’s doing:

  1. offsetHeight is an element’s rendered height, the total height it takes up in the browser window.
  2. If the right column is taller than the left, we set the left column’s CSS style height property to the right column’s height, then add "px" since CSS demands a unit of measure, and offsetHeight is measure in pixels.
  3. What if the left column is taller than right right? We do the same thing: find the left columns offsetHeight in pixels, and assign that to the right column’s CSS height.

Now that we have this function, we’ll add it to window.onload or the body tag’s onload attribute. You can use the addEventListener / attachEvent combination, too. As soon as the body loads, our columns will snap to the same height.

There’s one problem with this little method: if your pages are larger in size you’ll see them finish rendering, the onload event will trigger, and you will see the columns’ height being set (the background image or gradient will jump from its orginal height to its new height). It looks choppy, like you see here.

Can we fix it? Of course! Why run that function onload when you can run it immediately after the columns load in the document?

We’ll move that onload function into a script tag, and place that script tag containing our function immediately after the close tag of our second column. This means that the script will run immediately after that second column loads in the document, and the user will never see anything choppy. The height will be set before content finishes rendering and appears in the browser. Case closed. And, you now have equal columns as seen here. (Unless you’re stuck with using onload?)

But what about that gradient?
If you’ve been looking at the gradient here, you’re probably wondering how that shows up. Well, that’s a topic for another article coming soon. :-) (It’s right here now.)

A Google search can turn up many, many equal height column sites, but, of those I looked at, here’s one of the best (and they have a script modified to take padding into account, something that I didn’t need when I wrote my version for TheLadders).

technorati tags:, , , ,

Stuck with using onload? We can smooth out the height jump by adding a few bits to our CSS and another line to our JavaScript. We’ll change our CSS to:

div#container div#leftColumn{
    width:250px;
}

    div#container div#leftColumn.bg{
        background-color:#CCC;
    }

And, we’ll add a single line to our JavaScript function (and remove that line break I had to add):

function equalColumns(){
  var l = document.getElementById('leftColumn');
  var r = document.getElementById('rightColumn');

  r.offsetHeight >= l.offsetHeight ? l.style.height \\ line wrap
  = r.offsetHeight + "px" : r.style.height = l.offsetHeight + "px";
  l.className = "bg";
}

Now, our background color is applied after the new height is set. This looks much more natural, almost as if a background image is being loaded and applied. If you’re using an image heavy site, odds are users will never notice.

I'm Reading…
Search This Site
You are currently browsing the A Modern Fable weblog archives for January, 2007.

AddThis Feed Button

Need great hosting?

Categories