Making Elements Contain Floated Children

posted by Kravvitz at 11:32 PM on Mon. Jul. 12th, 2010

Categories: HTML, CSS, Browsers, Bugs 0 comments

There are several ways to cause an element to expand in height to contain its floated descendants. Of course some are better than others. (This has been discussed elsewhere before, but since not everyone is a CSS expert, I thought I'd write down my own thoughts on the strategies for dealing with this issue.)

The Old Ways

The oldest way (pre-CSS) is to use a <br clear="all"> element. Besides the fact that the HTML "clear" attribute has been deprecated, that's really a misuse of that element anyway. Several <div class="clear"></div> or <div style="clear:both;"></div> elements sprinkled throughout a page is another common sight. Some people (including me) argue that adding extra elements, muddying the nice clean markup, to just fix a presentational (or stylistic, if you prefer) issue is a practice to be avoided. So what are the alternatives?

"Float Nearly Everything"

The simplest one is the "float nearly everything" technique. If you float the container element, then it will automatically grow in height with its floated descendants. I often use this approach on the page header container and the wrapper of content columns and then give the footer "clear:both".

The Aslett/PIE Technique

Another, albeit more complex, (and my second favorite) approach is the Aslett/PIE technique. (Here's a second article on it.) These days, you can use a cut-down version of the code for it, if you are not supporting IE5.0/Win and IE5/Mac. (In the interest of brevity, I won't explain the intricacies of how it works here, but if you have any questions, feel free to ask.)

.clearfix:after { /* for non-IE browsers and IE8+ */
  content:".";
  display:block;
  clear:both;
  height:0;
  visibility:hidden;
}
/* the next two rules for IE6-7 must be separate and be in this order */
.clearfix {display:inline-block}
.clearfix {display:block}

Or, if you prefer this:

.clearfix:after { /* for non-IE browsers and IE8+ */
  content:".";
  display:block;
  clear:both;
  height:0;
  visibility:hidden;
}
*:first-child+html .clearfix {min-height:1px} /* for IE7 */
* html .clearfix {height:1%} /* for IE6 */

I rarely actually apply that "clearfix" class to any elements. Typically, I add more selectors (e.g. "#nav:after, .container:after, .clearfix:after"), so that I can target elements that already have a class or ID.

The Overflow Control Technique

In 2005, Paul O'Brien discovered a new, simpler approach: "overflow:auto" or "overflow:hidden" will cause an element to contain floated descendants (assuming it doesn't have a specified height). It's clean and simple and definitely demonstrates his impressive level of expertise. (I've learned a great deal from him over the last few years.) However, I, for one, prefer not to hide overflow usually. Also there is a second unexpected side-effect that can also occur in some browsers.

Odd Side-effect of hiding overflow

The strange side-effect that can occur with the overflow property happens when a floated element is next to an element that has "overflow:auto" or "overflow:hidden" and has a margin on the same side as the float. The (left or right) margin will be doubled in Firefox 1-2, Safari 1.2+, Google Chrome, and Opera 9.5-10.1. Here's a little live demo: (The four blue boxes will not be the same width in the aforementioned browsers.)

right-floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element

Differences between HTML and XHTML

posted by Kravvitz at 11:18 PM on Mon. Jul. 12th, 2010

Category: HTML 0 comments

XHTML is HTML reformulated as an application of XML. What that means is that you've got the same elements and attributes in both languages, but XHTML follows the stringent rules of XML. (XHTML inherits additional attributes from XML though.) So in practice, there are a few differences.

Requirements for writing XHTML markup:

  • Element names and attributes should be lowercase. (HTML is case-insensitive.)
  • Attributes should have a value. (In HTML certain — boolean — attributes, including "checked" and "selected" don't require a value.)
  • A pair of quotes, either single or double, should surround all attribute values. (HTML allows values that contain only certain characters to be unquoted.)
  • All elements must be closed (e.g. have an end tag). Empty elements, including <img> and <br>, should be self-closed like this: <img /> and <br />. (In HTML many end tags — and even some start tags — are optional.)
  • The xmlns attribute should be specified on the <html> start tag with the value "http://www.w3.org/1999/xhtml".
  • CDATA markers should be specified if "<" and/or "&" will be used inside <script> or <style> elements. (It's best to keep scripts and styles in external files anyway.)

One thing to keep in mind is that while in true XHTML documents all elements can be self-closed, most XHTML documents are served as HTML (with "Content-type: text/html") so HTML parsers are used. So to maintain compatibility, only elements that are empty by definition should be self-closed. One problem in particular arises if you try to self-close a <script> element (it causes major problems in IE). (Also empty <p>, <ul>, <ol>, and <li> elements are semantically unsound.)

More information:

Usability Lessons to Learn from Amazon and eBay

posted by Kravvitz at 7:51 PM on Sun. May. 2nd, 2010

Categories: Forms, Usability & UX 0 comments

Areas where Amazon and eBay do better than other online retailers, which I've found while doing some online shopping recently, are in the features provided for search refinement in both, and wish lists on Amazon.

Search Refinement

The first that comes to mind is that Amazon and eBay provide a way for shoppers to choose their own price range to look at. Amazon also suggests a few ranges, but one is not limited to those.

A second feature that comes to mind is that these sites allow you to look at multiple options under some option types. For example, you can pick which brands you're interested in when searching for shoes or clothing. Another example is that on eBay you can look at all items that are listed in New or Like New condition but ignore the ones in only "good condition".

Also on Amazon a buyer can see items that free shipping is offered for and other special options at the same time. On NewEgg, however, it's not obvious that a consumer can do that as well since you can only select a single item at a time from the drop-down list.

Wish Lists

Amazon's wish lists are great. With just two clicks on a product page, a shopper can add an item to any of his lists (or with a little more input, create a new one). Moving and copying items between lists is also a breeze.

This is in stark contrast to NewEgg where one clicks on the "add to wish list" button and then has to select which list should be used and select which items should be added to it, regardless of how many lists or items there are. Wouldn't it be so much easier if by default all of the items were selected and if there was only one list, it would be selected too? Also, as far as I can tell, there is no way to copy an item, one just has to add it again to another list. Similarly to move an item, one has to delete it from the first list and then add it to another list.

How to Prevent the "Unknown pseudo-class or pseudo-element [...]" Warning in Firefox

posted by Kravvitz at 11:28 AM on Thu. Mar. 25th, 2010

Categories: CSS, jQuery, Mozilla 0 comments

For several of jQuery's pseudo-selectors that aren't part of CSS3 Selectors, one can use ":nth-child()" (as suggested by SitePoint's Andrew Tetlaw), which is a CSS3 selector, instead. In many cases (but not always!), you can use ":nth-child()" instead of ":eq()", ":first" (which is the same as ":eq(0)"), ":even", and ":odd". For the first and second though, be careful that you add 1 to the index because ":eq()" uses a 0-based index, while ":nth-child()" uses a 1-based index. That also has the affect that odd and even are backwards, so be careful how you use this alternative. And whether the first element has an index of 0 or 1 is not the only difference, so I recommend you read the documentation for using ":nth-child()" in jQuery. For example, if you wanted to prevent the warning when using "ul.nav a:first", you would need to use "ul.nav li:nth-child(1) a" instead. Keep in mind that ":eq()" is more like ":nth-of-type()" than ":nth-child()", but still different, because ":eq()" isn't affected by whether all of the matched elements share the same (direct) parent or not.

Also to prevent this warning for ":checkbox", ":image", ":radio", ":file", ":password", ":radio", ":reset", and ":text" you can use the good ol' attribute selector. ":button" and ":submit" are similar but more complex because of certain browser bugs related to the type attribute of &lt;button&gt; elements.

I consider this to be a Firefox bug. I see no reason why Firefox should be checking JavaScript code for CSS Selectors and producing warnings when it finds a selector that it doesn't recognize. If you know why Firefox does this, I would very much like to hear the explanation.

PNG Images, Partial Transparency, and IE

posted by Kravvitz at 8:14 PM on Sun. Feb. 28th, 2010

Categories: CSS, JavaScript and DOM, IE, Bugs, Optimization 0 comments

According to this post on the YUI Blog by Stoyan Stefanov, both AlphaImageLoader (used to make alpha transparencies in PNG images display properly in IE6) and the alpha filter (IE's equivalent of the CSS3 opacity property, used to create partially transparent elements in IE/Win) use a lot of memory and can be a significant negative impact on browser performance in IE. The former even can make the browser completely unresponsive while they are processed sequentially. So what can one do about this, you may ask?

As Stoyan says, one solution is to use VML (Microsoft's proprietary solution for vector graphics). Apparently while IE6 doesn't properly support alpha transparencies normally, it does when the PNG image is used on a VML element. The tests Stoyan performed show that it runs about 10 times faster and uses about one-tenth of the memory — now that's a significant performance improvement!

So how does one use VML? Well lately, I've been using the script DD_belatedPNG by Drew Diller (which Jonathan Snook happens to mention in the comments for the YUI Blog entry). I switched to it because it supports using background-position and background-repeat, which AlphaImageLoader can't do. I'm pleased to find out that it apparently has a performance improvement as well over scripts such as Supersleight and Unit PNG Fix, which use AlphaImageLoader. Here's another script to automatically generate the VML elements in IE6. And of course, if someone really wanted to, one could statically embed the VML elements in the page's markup within a conditional comment to hide them from browsers that don't need (or even support) them.

I also mentioned the alpha filter. According to the YUI Blog entry, alpha filters also use a lot of memory, so I suggest you avoid them when you can and use VML and a PNG instead. When you can't avoid the use of the alpha filter, however, you might need to use AlphaImageLoader as well, to avoid the ugly rendering of alpha transparency in PNGs when the alpha filter is applied to it (which is a known limitation in IE7-8).

I hope you've enjoyed this second post on improving how you use PNG images for cross-browser compatibility and speed optimization.