Skip to: Navigation | Content | Sidebar | Footer


Full Archives

WE04

September 25
Off to WE04

Leaving for the airport in a few hours, so here's the plan. A brief flight to LA and a bit of a layover will be followed by the long trek across the Pacific, Equator, and International Date Line—all in the same flight.

Scheduled arrival time in Sydney: the future. Something like early the 27th, all I know is that I'll completely miss the 26th of September. (Aw, my favorite day of the year, too.)

Plan for Sydney: a day of sleeping. Two days of exploring. And then the whole reason for the trip, WE04. Can't wait to meet everyone, it's going to be an invigorating couple of days.

Afterwards a drive down to Melbourne (yes, I'm aware it's a big spread-out country... but remember where I live) and a few days enjoying the sights. Yes, I'd love to have lunch/coffee/whatever with the local Melbourne crowd. Here's the catch—I'd rather not coordinate it. Leave your contact details in the comments, and have a type A personality take the ball and figure it all out, and I'll be there. Good day to plan for: the 5th.

So that's that. Don't expect much activity on here until mid-October. Take care, and enjoy the turning leaves for me.

Permalink › | 26 comments

min-height: fixed;

September 16

After one too many times wistfully wishing I could scale fixed-size elements according to their content in a cross-browser friendly way, I did something about it. Presenting min-height, without the min-height.

If I had a penny for every time I've run into a situation where I really needed a block of content with a specific height, but decided not to due to the issues involved... well, I'd have a few bucks anyway.

There's no reliable way to place elements inside a parent and then have it expand gracefully along with the elements, if the parent has a starting height value. This is precisely the problem min-height solves, but it's frustrating that it's so unusable.

The Test Case

Take this demo page, for example. Placing the navigation where it is requires a header of an exact height, otherwise the proportions matching the photo and the rest of the header are completely off.

Example site

But if the list of nav items grows, or the user has a larger font size, or anything at all happens that would require the nav's height to expand, it expands outside of the header and overlaps into the content area below within browsers that adhere to the spec for height property.

Example site with overlapping header

The Problem

min-height is the logical choice for finding a solution that would allow the header to expand gracefully as the nav does, but it isn't supported by Internet Explorer or, unfortunately, Safari.

I say unfortunately because there's a fantastically easy way around the issue in IE, but not Safari—height is basically treated as min-height. With a bit of filtering, it's a snap to craft a solution that works between IE and Mozilla. But once you throw Safari in the mix, it's not that simple.

Since min-height itself is unusable, there have only been a few possible ways of dealing with situations like this. Take this example page with four stacked, variable-sized divs. The content itself dictates the height of each, which may be fine for most purposes. But like the graphical example above, sometimes it makes more sense visually for the content to fit within a certain-sized area.

Let's say the divs should be a minimum of 200px high. If we apply a height attribute directly to each, well, the results aren't quite what we'd hope—scroll to the third & fourth divs to see them overlapping.

The problem is evident in anything but IE; the results are in fact exactly what we're hoping for in IE, just not actually correct according to the spec. When we're also trying to account for dynamic content (which could be any length) or scalable text (which could be any size), it's even harder to predict a box's optimal height. Defining specific heights will lead to overlap sooner or later, and that's no good.

Potential Solutions

We could try overflow: auto; and force scrollbars to avoid it in all situations, but that's a really kludgy workaround and no one likes scrollbars anyway. It's a technical fix to a technical problem that affects the design adversely. No good.

We might be able to script our way around the problem (or use a proprietary attribute like IE's expression property), but for the sake of validation and not relying on an external script, what about a fix using valid CSS alone?

Well, that pretty much exhausts the range of possibility. Or so I always believed.

I keep running into this problem in my own work, and I'm always unsatisfied by the eventual results. Letting the content dictate minimum size messes up proportions unless everyone and their dog is using the same default font size, which they're not, and it forces limitations on how much content you can place inside the block which, given the required flexibility of most web design tasks these days, is never a good idea.

I finally got fed up with this limitation and decided it was time to fix it once and for all. And by George I think that's exactly what I've done.

Solving It

My method of attack involved figuring out how to duplicate 200px of min-height without actually using min-height. I could see only one real way of going about it—I needed to prop open the parent element with some sort of 200px high spacer that wouldn't affect the internal layout (and thus allow the element to expand as the content does, but not collapse past 200px if the content is short).

So I tried a few things and spent a while thinking about it, and here's what ended up working. Take this construct:

<div class="box">
 <p>Lorem ipsum dolor sit amet.</p>
</div>

Applying 200px of top padding to the parent div guaranteed it would always be at least 200px high—that's half the battle right there.

.box {
 padding-top: 200px;
}

The child p element is pushed down below that initial gap, so moving it back up to the top of the parent became the new challenge. Relative positioning would work, but it would also leave a space for the element. The total height of the construct would be child height + 200px, no matter what size the child was. No good.

Instead, a negative top margin of 200px would effectively erase that initial lead, and allow the entire construct to size according to the child... except when the child was smaller than 200px. Then the containing parent's bottom edge would determine the size of the construct, which would always be 200px, which is our desired min-height effect.

.box {
 padding-top: 200px;
}
.box p {
 margin-top: -200px;
}

In Safari and Firefox, we've got it solved, but not IE. Remember that IE already does min-height though, because that's how it treats height, so a bit of browser-specific filtering should do it:

/* for Mozilla/Safari */
*>.box {
 padding-top: 200px;
}
*>.box p {
 margin-top: -200px;
}
/* for IE */
* html .box {
 height: 200px;
}

The problem is now IE5/Mac—it actually applies all three styles. It gets the first two right, but then it also has the same parsing bug that IE/Win does and applies the second one, which really makes a mess of things. So an extra filter for IE5/Mac is necessary:

/* for Mozilla/Safari */
*>.box {
 padding-top: 200px;
}
*>.box p {
 margin-top: -200px;
}
/* for IE, with IE5/Mac backslash filter \*/
* html .box {
 height: 200px;
}
/* end filter */

Is that it? Not quite yet, there's also Opera. Unfortunately it doesn't want to seem to keep our containing box open; it looks like the lack of an explicit height value collapses the entire parent element, padding included. We can keep it open and get our padding back by setting a min-height, though... any value will do:

/* for Mozilla/Safari/Opera */
*>.box {
 padding-top: 200px;
 min-height: 1px;
}
*>.box p {
 margin-top: -200px;
}
/* for IE, with IE5/Mac backslash filter \*/
* html .box {
 height: 200px;
}
/* end filter */

Final Notes

And there we have it. (Also, a fully-commented version) It's a bit messy, but it works in everything, and presumably it applies equally to the min-width property (although I haven't tested that yet). The only caveat seems to be Opera 6, which despite all that still collapses the parent. Oh well, Opera 6 is two years old now and Opera users ought to know better than that, so I'm not losing sleep; it degrades gracefully, anyway, and that's what's important.

The only real markup dependency is on a parent that contains a single child. The construct used in the example has a single p element; adding a second one would mess things up considerably though, so in cases where more elements are needed within the parent it's a better idea to add a secondary wrapper div as the child.

Example site with fixed header

And our example from above? Piece of cake. When the navigation is longer, the content bumps down to account for the larger header. When it's short, the header retains its minimum height.

Addendum: In theory, this should also work the same as the above method, but the syntax is a bit nicer. I'll test it more thoroughly, so for now there are no guarantees about the utility of this code. (Thanks to Henrik Lied for pointing out !important, which I always manage to forget about)

.box {
 padding-top: 200px !important;
 height: auto !important;
 height: 200px;
 min-height: 1px;
}
*>.box p {
 margin-top: -200px;
}

12/2/04 Addendum: maybe not. Faruk Ates reports the second example doesn't work in IE. However, Mitchell Stokely provides this further variation based on his Stokely hack which remains unverified and untested at the moment:

/*IE 6 and Safari Hack*/
/*read by Mozilla 1.0-1.4,IE6,Safari*/

html*.box{
[height:100%;/*necessary to hide from Mozilla*/
height:100%;/*read by Safari*/
]height:100%;/*only read by IE6*/
}
.dummyend[id]{clear: both;
/*end hack using dummy attribute selector for IE5 mac*/}

Permalink › | 57 comments

Understanding “Critical Understanding”

September 14

I suspected my point in "Critical Understanding" was buried in enough subtlety to warrant an explanation; here it is.

There was one point made, and one alluded to within that short piece. None of them had anything to do with what was being said, sorry to anyone who thought the article was about colour.

The point alluded to was caught by a few: Criticism without justification is purely subjective. The learning comes after the explanation, and when there is none forthcoming there's no real value in the critique. Perhaps in some cases it might be useful to aggregate opinions for the sake of trend analysis, but most designers are rarely concerned about anything larger than the work at hand when soliciting feedback.

But the real point being made lies in what wasn't said. A critique that attempts to justify or discredit work based on personal preference for design choices is laughably narrow in focus. The question the critic effectively answers is "Do I like the way this site looks?", which except in situations where that actually matters, is absolutely the wrong question for a successful critique to answer.

The question fails to take into account the design goals for the site. It doesn't consider the processes which evolved the site to the completion point. It misses that multiple decisions were made throughout development that, for better or for worse, have changed the original ideas. It can't possibly reflect the budget or working conditions.

(And it has absolutely no comprehension that the green was hand-picked by the CEO's wife.)

Permalink › | 18 comments

A Response

September 10

Jeff Croft points to an article published on ZDNet last week which implores standards advocates to drop the religion. It's a pretty big church...

In response to the launch of the Web Standards Project's Browse Happy campaign a few weeks back, John Carroll shared some thoughts about what alternative browsers ought to be doing to topple IE's lead.

Boiling down John's article reveals only a very small grain of actual suggestion: to challenge IE, other browsers must duplicate all its proprietary features. His final conclusion appears to be that standards are good, but slow, so why not use IE as the de facto standard and let the W3C play catch-up?

I'll tell you why not.

Because the legion of developers and designers clamoring for Microsoft to improve their standards support is growing daily. No one is begging Mozilla to implement ActiveX and the rest, John's pet issues aside.

Always remember the wisdom of Monkeyboy.

Permalink › | 25 comments

Critical Understanding

September 9

An observation about critiquing work, if you'll indulge me...

I'm almost convinced that anyone whose critique of a redesign is as substantial as:

"I don't like the green."

...is someone who absolutely fails to understand the purpose of web design, and should give up any aspirations in the profession.

And my conviction would be just oh so much more forceful if I weren't so damned guilty of doing it myself.

(Update: A further explanation of this anecdote is available.)

Permalink › | 32 comments

GIF Hacking

September 8

Common knowledge says that modifying a compressed image is a bad idea. Not always, though.

A somewhat bad habit I've fallen into over time is making an adjustment to a GIF file without modifying the Photoshop source. I open a GIF directly, edit the pixels in situ, and then overwrite the original. The GIF becomes my source, as the original PSD file that it was generated from falls further out of synch.

Of course, the classic wisdom of common web file formats is that if you're going to edit an image, you have to re-create it from a master. Because web compression tends to be lossy, having the source PSD on hand is a must.

...but that's not always the case. JPG files are lossy, sure, and you'd never want to use a JPG as your master if it can be helped. But theoretically GIF is a lossless format, once you get around the 256 colour limitation. Provided you save the file with the same colour index each time, you won't lose any detail after each edit.

Take the following image for example. Let's say you've started with an overly large corner for your rounded boxes.

Original image on left, three variations on right.

There's probably no need for such a large image, so by cropping to look like the top right 'after' result, you can save a few bytes. Or if you need just the edge pieces, a quick crop can pull out the top and left edges as separate images, as shown in the bottom two 'after' results.

Point being, you've already optimized the larger image—you could go back to the original PSD and re-save, or you could drop it into Photoshop and just crop the smaller images out. They'll be (mostly) optimized, and you've saved about 3 steps in the middle between flattening your layer effects, cropping, optimizing and saving.

In fact, if all you're doing is cropping, resizing or the occasional pixel-level tweak, you don't even need to go through the whole File → Save For Web dialogue either. Open the GIF, modify the pixels without first converting to another colour space like RGB Mode, and then re-save using File → Save. If you haven't changed colour modes, the color index is preserved, your compression tweaks are re-calculated automatically, and you don't lose any detail because no new colour information has been added on top of the original GIF.

What if you've spent time applying a dither mask, or enabled lossy GIF compression, or a number of other variations that will affect the file size and quality of the original image? That's where it becomes muddy—if the starting GIF isn't of reasonable quality, you probably wouldn't want to use it on your site anyway, but there may be times when a GIF shouldn't be manipulated this way.

Assuming the starting image is workable though, the compression algorithm WILL pick up these effects on re-save and you won't have to spend time applying them again. Compression is applied after all other effects like dither and lossiness have worked their magic, so a dithered GIF will always be compressed the same way. (Try it if you don't believe me—dither a high-colour GIF, save, and then open and re-save without dither... if your colour settings match, the resulting files will be the same size.)

The big problem with working this way is source control; over time, the images for your site fall further and further out of synch with the master Photoshop files. I'm not actually convinced most designers could refer back to a contained set of source PSD files for all graphics anyway, especially later on in the course of a site's life... but that's another thought for another day.

Addendum: And all this applies to PNG too, of course.

Permalink › | 29 comments

A Different Kind of Permalink

September 5

On a lark, I've put up an archive of past versions of this site stretching back to 2001.

When Proton launched in May, I was careful to provide a style switcher that allowed a choice between the new and the old.

While it would be fun to carry that idea to its logical conclusion and never drop a design as this site evolves, the fact is that things change. Synchronizing a whole bunch of versions is no fun, and things that aren't fun don't get done. So instead of tying Proton and Radar (and the others) back into the markup structure of the new design, I've put them to bed as alternate styles.

But hey, history is progress and we all love looking through what was. So even though it hurts, I'm putting up archives of this site back to the beginning. Including the special temporary splash pages, since I still have even those.

v1 — The ‘undefined’ phase.

Nov 2001 – Jul 2002

Was it a portfolio piece? A publication? Something else? After mezzoblue was launched, the site itself lacked focus and frequent updates for some time. The thinking at the time was to create a publication of some sort that would feature a portfolio component. Heck, that part hasn't changed a bit—what has is that I've actually gotten around to the 'publication' component, and the portfolio seems to be an afterthought now.

Oh yeah, and check out that markup. Got the validity down, but the separation of structure and presentation was still a ways off. It was 2001 after all.

v2 — The weblog phase.

Nov 2002 – Feb 2003

A very lightly tweaked (but heavily designed) Movable Type install. Teeth-cutting experimentation at its finest, I’m still fond of this frustratingly inflexible design. mezzoblue as a weblog launched with v2.

One of my first real forays into committing to table-free code, although the ImageReady-generated mouseovers required one back then.

v3 — The IPO phase.

Feb 2003 – May 2004

The one where everyone came in. A long life paid off for this sturdy, dependable design, dubbed Radar. A lot of layout and content tweaks saw it evolve over the year it adorned mezzoblue; this snapshot comes from earlier in its life cycle.

Originally built with tables (albeit valid tables), I converted to a genuine CSS-based layout in August 2003.

v4 — The inscrutable phase.

May 2004 – Aug 2004

Some liked it; some didn’t. Proton was the cumulative result of a lot of thinking and re-thinking of various features. In fact, it got too big. Too much change resulted in a lack of direction and loss of the overall 'big picture' view near the end. The focus became just to launch it, not worry if it was a good idea or not. Is this a problem? 188 comments later, I'd say so!

Funny enough, I don't seem to have a complete archive on hand so this one is a bit broken yet.

v5 — The contemporary phase.

Aug 2004 – (present)

You are here. A result of learning from the problems of Proton, building on the successes of Radar, re-thinking the IA requirements of the site, and cumulatively creating something that is just plain better.

Permalink › | no comments