2007-02-08

CSS Hacks, browser updates, and the Holy Grail

CSS Hacks generally work in one of the following ways:

  1. Hide CSS that is rendered buggily from the offending browser, using perfectly valid code read by (all) other browsers
  2. Feed CSS 'corrections' to a browser that only it needs, exploiting valid, but nonsensical code that all other, standards-compliant browsers will ignore.

In a perfect world, where browsers that correctly parsed valid CSS also correctly rendered 100% of CSS, hacks would be safe.  Hacks are also safe against browsers that are 'dead' (no longer supported or developed).  But dead browsers should eventually die out and disappear, right? Well, they should still be taken into consideration. My simple amateur solution is to hide as much CSS from such browsers as I can (wholesale, using an @import 'shield'). I find it ironic that some 'dead' broswers are more commonly used than new ones, but that's a different matter.

The problem with hacks arises when they backfire. The following conditions could cause hacks to backfire:

  1. A browser is updated that correctly renders the CSS, but does NOT parse the code correctly.  This is ok, as the browser is still fed rules that are 'safe', from a design point of view: it's not the full design, but it's a baseline that works.  It worked before, and will continue to do so, unless new rendering bugs have been introduced.  
  2. A browser is updated that correctly parses the CSS, but does not fix all the (well-known) rendering problems.  This is problematic and what I would call a 'backfire'.  This is exactly what ppk warned us about back in 2003.

I say all this again because of my frustrations from the following:

  • The point of standards is t not have to worry about differences in implementation: a 'standard' should apply to everything that subscribes to it.  This is not the case with CSS, sadly, even 10 years after it's introduction.  
  • I want to write CSS code and design layouts that conform to the standards.
  • BUT, the single-most popular browser out there remains, unfortunately, Internet Explorer for Windows.  Because it comes conveniently bundled with the most popular operating system for average computer users.  Because most of those users don't know there are better alternatives, and they don't care.  And when they visit a site that looks garbled, they blame the designer, not the browser.  Perhaps they should, at least in part, but it is very frustrating for amateurs who want to put up their own web page, and may even have some neat design ideas, but get frustrated by how difficult it can be to accomplish.

Yes, I am frustrated.  Every time I dip my brain back into this world, I get frustrated by these facts.  I have come to loath Internet Explorer and resent it's simultaneous popularity and bugginess.  I sometimes consider giving up, using a stock design, and not wasting my time worrying about it.  But, I'm stubborn, and a bit of a perfectionist, even when it comes to my hobbies.  "If you can't learn to do something well, learn to enjoy doing it poorly".

All this leads me to my point here.  My usual approach has been to design to standards, use as much clean code as possible (without going mad with testing), and only worry about the most common browsers that I can easily test in: the rest don't get to even see the layout CSS code.  Yes, I use a Mac, because I have yet to find a better alternative that just works (I'm less of a fanatic than I used to be, but I still think it's the best alternative I've seen).  As such, I generally test in Firefox, because I like the de-bugging features it has (DOM tree inspector, better code view, error reporting, etc.).  I also test in Safari, because I actually use that most of the time for browsing, and it's fairly standards compliant, albeit a little idiosyncratic at times.

But eventually, I have to resign myself to test in IEwin (that's Internet Explorer for Windows). *sigh* So, I usually add the 'fixes' to the code to make it work in IEwin, but these are generally corrections that I hide from other browsers using CSS hacks: the star-html hack (and more complex offspring, the 'modified Simplified Box Model hack'), and occasionally the child selector.  The star-html types of hacks follows the second approach I mentioned at the start, while the child selector follows the first.

This used to be safe, until Microsoft started working on IE version 7, and decided to be more standards-compliant.  This is good news.  However, they regretfully decided to fix the parsing behaviour, without fixing the CSS rendering problems.  Now, the hacks may backfire!  gah!  I'm going to take a moment to complain about this decision and respectfully suggest that browser makers follow a few simple rules when updating the browsers:

  • Fix the rendering bugs first, then the code-parsing problems.  It's safer to implement something before having multiple ways of triggering it.
  • When fixing the code-parsing bugs, add support for CSS declarations before removing support for quirky ones.  The decision to remove IE7's recognition of the star-html selector has caused endless code-rewriting for people who have used this hack.  Adding support for things that weren't recognized before is good and responsible.  Adding support for the child and other selectors allows IE7 to do a bit more: hacks that fall under the first approach above will backfire, but it also opens new possibilities and makes these selectors more broadly useful than a simple browser shield.  This also means the second approach to CSS hacks should be safer (if this rule is followed).  Otherwise, lots of 'corrections' end up rotting in stylesheets and never get to the user agents that need them.  Ideally, removing support for quirky code shoudl be done after fixing the rendering issues first.

Perhaps the best approach after all was to move all IE-related statements to a separate stylesheet and feed it to IE using code in conditional comments.  This makes style-switching a bit more complicated, but rock-solidly reliable for design & walk-away sites.

I admit, I was / am lazy.  I don't have time to test things endlessly, fix, then clean up afterwards.  I'm an amateur, I like doing this in my spare time, and I want simple solutions.  Then again, if it were that easy, lots of professional web designers would be out of work.  But, surely, there must be a place for amateur designers, without having to lose too much sleep or feeling overwhelmed by the miasma of browser incompatibilities.

Perhaps, I should study compatibility tables more often before committing to a certain CSS approach, and only use 'safe' methods, and no hacks.  But that can take a lot of work, and would require changing how I approach CSS coding, and restricting myself to a potentially tiny subset of well-supported methods.  My challenge, and humble request, to the standards-based webdesign gurus, is to spend a little time describing such safe methods, thus pointing out the safe tools for amateurs to play with, without having to face the power tools so early on.  The pros can continue to come up with cool effects and layout tricks, but it sure would be nice to have a stable way to make a 2 or 3 column basic layout.  There are some good columns at A List Apart, which is a start, but there is still much variation, and always the caveats.  It's a start, but

There are a few code-generators out there, but I'm skeptical of them.  Perhaps that's hypocritical, but what I want is something in-between: demonstrations of basic techniques and simple CSS code that works, which I can combine, or add to (not modify, because then it might break).  I wish I could have my cake and eat it.  I want simpler, fewer choices, fewer pitfalls.  Am I asking for too much?

Ideally, a CSS-based layout should only need a few basic, semantic (X)HTML tags.  I don't mind adding semantic divs, but not empty ones or redundant wrapper divs.  A wrapper that contains more than one div might make sense, but that's as far as I'm willing to go.  I don't like layouts that require extra HTML tags for the CSS to play with.  That's leading back towards something analogous to nested tables and resulting tag-soup.  The Holy Grail remains to be able to do everything you need to each box independently, without the need for additional wrapper boxes for the non-standard buggy browsers that force you to restrict the CSS to a tiny subset of the specs.  I've sometimes considered using Javascript to add the DOM elements the CSS relies on, but that's dangerous because then the CSS relies on a piece of JavaScript, whose sole purpose is to support the style.  Not best practices, where content is separate from style and behaviour.

2007-02-03

Email Obfuscation

Although it's customary to allow readers of your web pages to send messages to you, there is a danger to posting your email address on the web, for bots to extract and add your email address to a spammer's list. The safest thing is probably to never put your email out in the first place. But if you still want to give readers the opportunity to contact you, one option could therefore be a web-form, which sends the contents back to the server, which then runs a script that sends you an email. The address is, in theory, never "visible" to people filling in the form, or automatic bots.


I'm not that well versed in server-side scripting, and I'm not even sure I am allowed to have scripts running on the server where my pages are hosted. So, I recently discovered what looks to me like an ingenious alternative: using JavaScript to de-obfuscate an "encoded" email address in a mailto: link.


I found the following script on The WaSP website (in the code).



/* SETMAJER_DEOBFUSCATE 1.0
de-obfuscates an email address in a MAILTO: link;
PARAMETERS
--
MARKUP NEEDED
- anchor (A) tag with a MAILTO: URL as the value of the HREF attribute
- the @ in the email addy should be replaced with the string '-REPLACE_WITH_AT_SYMBOL-'
- the body of the email should be set to 'replace%20-REPLACE_WITH_AT_SYMBOL-%20in%20the%20to:%20address%20with%20@'
using the query string method (i.e. ?body= or &body= depending on whether the subject has been defined
STYLES NEEDED
--
*/
function setmajer_deobfuscate() {
var anchors,numAnchors,currAnchor,i
// get an array of the anchors in the document
anchors = document.getElementsByTagName('A');
numAnchors = anchors.length;
// iterate through the anchors
for (i = 0; i < anchors.length; i++) {
currAnchor = anchors [i];
// if the anchor is a MAILTO:, replace the obfuscation slug with the '@' symbol
if (currAnchor.href.match(/mailto:/i)) {
currAnchor.href = currAnchor.href.replace(/-REPLACE_WITH_AT_SYMBOL-/,'@')
currAnchor.href = currAnchor.href.replace(/([?&]|\&)body=replace%20-REPLACE_WITH_AT_SYMBOL-%20in%20the%20to:%20address%20with%20@/,'')
}
}
}

Neat. I modified it slightly for myself to also replace a '-[dot]-' with a period, just for some extra obfuscation. I've seen other methods out there, some of which can be found via a simple search for "Email obfuscation" or somesuch. I also admit that I don't really understand the need for the second replacement (of the email body specified in the href. I can't wait to try this out.

2005-12-28

Visions of Non-grid Layouts

Just read a very inspiring article at A List Apart:
Thinking Outside the Grid by Molly E. Holzschlag

This article highlights the possibility that CSS can enable web page layouts that do not follow the standard table-like grid that is traditional for this media. This is really inspiring, partly because most work around CSS-layouts has been focused on getting it to behave the way we are used to tables behaving. It is an excellent point that we all apparently needed to be reminded of: CSS is not tables. We never expected CSS to function like them, so why have we been so determined to make it behave like them.

This is also inspirational because it means there are many more possibilities for layout I would have never considered before, given the free-flowing independence of boxes in CSS. Nevertheless, I was disappointed by many of the examples shown in the article of "non-grid" layouts. One of them is even based on table tags! Oh well, it's the product, not the process she is primarily arguing. Also, many of the other examples are somewhat garbled and, I find, difficult to read and extract information visually. They are visually interesting, though the novelty accounts for most of the appeal, but not terribly useful, or user-friendly.

Is the grid the ultimate layout scheme for usability? Molly Holzschlag does acknowledge that a grid has been the meat-and-potatoes of layout schemes for the web (and, in fact, most text-based media) precisely because they lend themselves to being easy to navigate, and predictable, thus making it easier for users to get to the content they want. And the customer, or user, is always right. However, I also envision non-grid layouts that can be both visually interesting and functional for users.

I haven't the time to fully illustrate or explore them, but here are some descriptions of what I envision:

  • Elements positioned in regular patterns that are not grids. For example:
    • list elements in a circular, or hemispherical pattern, within a block on the screen. Not cheating, the way one might using tables in the old days, but actually using the position: absolute (or relative) attribute to place things where they ought to be. A specific case would be to take an ordered list (1-12) and place each item in a circle, forming a clock. The order of each item is maintained by the markup, but the spacial arrangement is provided by CSS.
    • elements staggered in a regular way, such as diagonally down a page, or creating a wave effect (horizontal, or vertical)
    • Since I'm lazy, I could even see JavaScript being used to calculate positions of elements in such a scheme automatically, or more accurately, mathematically. Maybe even randomly. Woah, that one might need to be constrained or managed to some degree to prevent unreadable layout.
  • Dynamic layouts (possibly grid-based, but not necessarily), that react to user "behaviour". Some might argue this is best left to javaScript. Nevertheless, this is already common to some extent, especially with navigating menus; the kind of thing that used to be done with javaScript now works even better with CSS. An idea I remember from a very early project in the 90s was something like a bunch of cute-looking bubbles on the screen that expanded to reveal their contents when the cursor moved over them, and retracted when the cursor leaves. This is easy to apply in CSS (using the :hover pseudoclass), but could never be accomplished with tables. I've already seen a variation on this idea.
  • Is there a way to rotate elements in CSS? Or the text inside them? This would be another way of breaking out of the grid, and could actually be useful in tables with long column headings.
  • And, of course, there's always the extreme versatility CSS allows, enabling styles to be changed, and be even more dynamic than a table ever could, but that's nothing revolutionary.
  • That's all I can think of right now.

For now, I also have to agree with many others that really interesting and novel-looking pages are ones that can also break out of the rectangle, as well as the grid. A page doesn't have to look like Lego blocks. Non-rectangular elements are, naturally, the next step.