<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>stchur-BLOG &#187; CSS Related</title>
	<atom:link href="http://blog.stchur.com/category/css-related/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.stchur.com</link>
	<description>web / programming / javascript / css / html</description>
	<lastBuildDate>Sat, 16 Jan 2010 01:09:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fetch (a stand-alone CSS querying engine)</title>
		<link>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/</link>
		<comments>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 06:00:16 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Fetch]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[CSS Querying]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/?p=124</guid>
		<description><![CDATA[	I've started work on a new side-project called Fetch.  It's a stand-alone CSS querying engine, designed to be super lightweight and offer high performance across all modern browsers.
	It's still very much in development and the source is a bit sloppy, but it currently weighs in at only 2.5k compressed and gzipped and (in Firefox3) [...]]]></description>
			<content:encoded><![CDATA[	<p>I've started work on a new side-project called Fetch.  It's a stand-alone CSS querying engine, designed to be super lightweight and offer high performance across all modern browsers.</p>
	<p>It's still very much in development and the source is a bit sloppy, but it currently weighs in at only 2.5k compressed and gzipped and (in Firefox3) either outperforms or is on par with all other major Javascript libraries out there*.</p>
	<p>It's definitely not ready for production use, but when it is, it will become the new CSS querying engine for Gimme and will also be available as a stand-alone library, which will be extensible (so you can add your own rules) and which will also be guaranteed to play nicely with other libraries by not adding to the prototype of any native objects and only introducing one single global variable (fetch).</p>
	<p>For anyone interested, the current (i.e. sloppy) source is available on CodePlex: <a href = "http://gimme.codeplex.com/SourceControl/changeset/view/32017#399762">fetch.js</a>.</p>
	<p>As I said, it's not ready for prime time and the code is sloppy (and probably buggy).  Consider yourself warned.</p>
	<p>* <small>Fetch was not compared with libraries that use XPath or querySelectorAll, because it uses neither, but rather is a pure Javascript implementation.  Upon release, it will take advantage of querySelectorAll where appropriate, but will not use XPath.</small>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2009/03/06/fetch-a-stand-alone-css-querying-engine/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hello Old Friend</title>
		<link>http://blog.stchur.com/2008/10/10/hello-old-friend/</link>
		<comments>http://blog.stchur.com/2008/10/10/hello-old-friend/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 12:59:13 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[MiniPosts]]></category>
		<category><![CDATA[Web-related]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[font-size]]></category>
		<category><![CDATA[IE6]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/10/10/hello-old-friend/</guid>
		<description><![CDATA[More evidence that I was right when I wrote this post.

Won't be long now IE6...]]></description>
			<content:encoded><![CDATA[<p>More <a href = "http://orderedlist.com/articles/hello-old-friend" title = "font-size with pixels no longer considered harmful">evidence</a> that I was right when I wrote <a href = "http://blog.stchur.com/2008/01/15/ie5-is-dead-and-ie6-is-on-death-row/" title = "IE5 is Dead (and IE6 is on Death Row)">this post</a>.</p>

<p>Won't be long now IE6...</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/10/10/hello-old-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>In Honor of Caspian (enhancing Gimme)</title>
		<link>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/</link>
		<comments>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/#comments</comments>
		<pubDate>Sat, 17 May 2008 03:47:53 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Gimme]]></category>
		<category><![CDATA[Useful Functions]]></category>
		<category><![CDATA[]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[John Resig]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Shaun Inman]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/</guid>
		<description><![CDATA[	The Chronicles of Narnia: Prince Caspian arrived in theaters today, and for those of you who haven't noticed, all of the Gimme codename releases are named after characters from the Chronicles of Narnia, since it is the greatest fantasy series ever written (sorry Lord of the Rings and Harry Potter fans, but I'm afraid that [...]]]></description>
			<content:encoded><![CDATA[	<p><a href = "http://en.wikipedia.org/wiki/Prince_Caspian" title = "Prince Caspian">The Chronicles of Narnia: Prince Caspian</a> arrived in theaters today, and for those of you who haven't noticed, all of the Gimme codename releases are named after characters from the <a href = "http://www.narniaweb.com" title = "Narnia Web">Chronicles of Narnia</a>, since it is the greatest fantasy series ever written (sorry Lord of the Rings and Harry Potter fans, but I'm afraid that yes, Narnia, <em>is</em> better).</p>
	<p>Anyway, since the current beta release of Gimme is "Caspian" I figured I'd do a post today in honor of Gimme and the movie (ok, it helps that I also have something worth writing about too).</p>
	<p>So anyway, on to what this post is really about: enhancing Gimme.</p>
	<p>Not too long ago, <a href = "http://www.shauninman.com" title = "Shaun Inman">Shaun Inman</a> wrote about his proposal for <a href = "http://shauninman.com/archive/2008/05/05/css_qualified_selectors" title = "CSS Qualified Selectors">CSS Qualified Selectors</a>.</p>
	<p>It's a good idea; I've actually had the same idea and thought briefly about making it part of Gimme's core CSS selector engine.  Only, in my model, I have the left-hand-side and the right-hand-side of the <code><</code> symbol switched.  It feels more natural to me that way, because in most CSS selector rules, you can simply look to the far right of the selector rule and know what type of "thing" you're going to be selecting.</p>
	<p>Thus, I feel that this:</p>
	<div class="dean_ch" style="white-space: nowrap;">img &lt; a&nbsp; &nbsp; &nbsp;<span class="coMULTI">/* select all &lt;a&gt; elements that contain an &lt;img&gt; element */</span></div>
	<p>feels more natural than this:</p>
	<div class="dean_ch" style="white-space: nowrap;">a &lt; img&nbsp; &nbsp; &nbsp;<span class="coMULTI">/* same logic as above -- Shaun's approach */</span></div>
	<p>But this is just details; the idea is the same either way.</p>
	<p>So anyway, after Shaun published his idea, <a href = "http://www.ejohn.com" title = "John Resig">John Resig</a> chimed in and mentioned that <a href = "http://www.jquery.com" title = "jQuery">jQuery</a> supports this already via <a href = "http://ejohn.org/blog/qualified-selectors-in-jquery/" title = "jQuery :has(..)">pseudo :has(..)</a>.</p>
	<p>Well that's pretty cool, but since <a href = "http://codeplex.com/gimme" title = "The Gimme Javascript Library">Gimme</a> is my library, naturally, I feel compelled to make sure it stacks up against the competition, so I thought to myself: "self, can Gimme do this?" to which a mental reply came back "No, remember? You decided no to implement it."</p>
	<p>And I would have just left it at that, because after all, I decided not to implement it for a reason (and I figured that's where I <em>would</em> leave it).</p>
	<p>But then, today, my officemate surprised me by asking "Hey, I have a question about Gimme.  I'm working with a page where I need to select a &lt;table&gt; element that has an &lt;h1&gt;.  Can Gimme do this?"</p>
	<p>Well crap!  What are the odds that this would come up again so quickly?</p>
	<p>Not being one to disappoint, I said "You know what? I decided not to implement it, but I did put significant effort into making Gimme's selector engine extensible.  I bet we can write an extension really easily."</p>
	<p>So a few minutes later, we came up with this little gem:</p>
	<div class="dean_ch" style="white-space: nowrap;">Gimme.<span class="me1">Selectors</span>.<span class="me1">addPseudo</span><span class="br0">&#40;</span><span class="st0">'has'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>_elem, _pseudo<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> children = Gimme.<span class="me1">query</span><span class="br0">&#40;</span>_pseudo.<span class="me1">param</span>, _elem<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">return</span> children.<span class="me1">length</span> &gt; <span class="nu0">0</span>;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
	<p>Which means you can now use Gimme to do something like:</p>
	<div class="dean_ch" style="white-space: nowrap;">g<span class="br0">&#40;</span><span class="st0">'p:has(img.funny)'</span><span class="br0">&#41;</span>;&nbsp; <span class="co1">// select all &lt;p&gt;s that contain &lt;img&gt;s with class &quot;funny&quot;</span></div>
	<p>Unlike what John did, I didn't bother to map this back to the <code><</code> symbol.  I thought about it, and you could do it easily enough, but the more I think about it, the more I like how <code>:has(..)</code> reads.</p>
	<p>It's not likely that I'll make something like this part of the core Gimme library unless it start popping up everywhere.  It comes up occasionally, but not enough to warrant making it part of the core (at least, not enough in my personal experiences so far anyway).</p>
	<p>So there ya go!  Think of this as edition 1 of "Gimme can do that too" with (hopefully) many more editions to come.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/05/16/in-honor-of-caspian-enhancing-gimme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zen Garden / Coffee Break</title>
		<link>http://blog.stchur.com/2008/02/19/zen-garden-coffee-break/</link>
		<comments>http://blog.stchur.com/2008/02/19/zen-garden-coffee-break/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 01:03:24 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[MiniPosts]]></category>
		<category><![CDATA[Web-related]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/02/19/zen-garden-coffee-break/</guid>
		<description><![CDATA[I just noticed that my submission to the CSS Zen Garden is finally listed.  It didn't "make the cut" for the official list, but it's listed on page 2 of the archives for Other Submissions.

See the archives where my design is listed, or view my design, Coffee Break, directly.]]></description>
			<content:encoded><![CDATA[<p>I just noticed that my submission to the CSS Zen Garden is finally listed.  It didn't "make the cut" for the official list, but it's listed on page 2 of the archives for Other Submissions.</p>

<p>See the <a href = "http://www.mezzoblue.com/zengarden/alldesigns/others/page2/" title = "CSS Zen Garden / Other Submissions">archives</a> where my design is listed, or view my design, <a href = "http://csszengarden.com/?cssfile=http://www.stchur.com/personal/coffeebreak/coffeebreak.css" title = "Coffee Break by Stephen Stchur">Coffee Break</a>, directly.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/02/19/zen-garden-coffee-break/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Word-wrap for Mozilla (take 2)</title>
		<link>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/</link>
		<comments>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 07:18:16 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Mozilla-specific]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/03/01/word-wrap-for-mozilla-take-2/</guid>
		<description><![CDATA[	
This blog entry is a follow-up to my last blog entry, Emulating CSS word-wrap for Mozilla/Firefox.  In this entry, I work under the assumption that the reader has read the original post.   If you haven't, I highly encourage you to do so before reading this post, as the contents of this one [...]]]></description>
			<content:encoded><![CDATA[	<div class = "note">
This blog entry is a follow-up to my last blog entry, <a href = "http://ecmascript.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/">Emulating CSS word-wrap for Mozilla/Firefox</a>.  In this entry, I work under the assumption that the reader has read the original post.   If you haven't, I highly encourage you to do so before reading this post, as the contents of this one will be much more relevant if you do.
</div>
	<p>In my last entry, I discussed how one might achieve something similar to the CSS style rule: "word-wrap: break-word;" in Mozilla-based browsers.</p>
	<p>The technique I used to accomplish this centered around using a Mozilla binding to automatically insert an invisible unicode hyphen between the characters of a string contained within any element whose class was set to "wordwrap."  With this invisible character in place, Mozilla will happily wrap a long string whenever the element's content overflows its container.</p>
	<p>There was a catch with my approach though.  I wanted to be able to modify, not only any inner text of a "wordwrap" element, but I also needed the logic of my binding to leave in tact, any HTML that may have existed inside the given element.</p>
	<p>The logic I ended up using was to insert the unicode character between <em>each and every</em> character in the element's <code>.innerHTML</code> (including any HTML tags).  Obviously though, this would "mangle" the HTML tags thereby making them useless.  So, I then added a bit more logic which utilized regular expressions plus a callback function in a <code>.replace(..)</code> call to "unmangle" the HTML I screwed up in the first place.</p>
	<p>This worked, but as alert reader, Rich Birkby, kindly pointed out, there is an easier way.  A way that, as it turns out, is quite simple to implement and doesn't require "mangling" any of the HTML tags within the "wordwrap" element.</p>
	<p>Read on to learn more.</p>
	<p><span id="more-30"></span></p>
	<p>This superior technique (IMO) that Rich informed me of was the TreeWalker.  A TreeWalker is a an object that you can create in Mozilla-based browsers that allows you to navigate the document tree.</p>
	<p>The <code>document.createTreeWalker(..)</code> function takes 4 parameters which allow you to specify some specifics about exactly how the walker should "do its walking" (if you will).  Each parameter is explained in more detail below:</p>
	<ol>
	<li><strong>rootNode</strong>: The node in the document that is to serve as the root node for this tree walker.</li>
	<li><strong>whatToShow</strong>: An integer constant that specifies one of several built in filters for selecting nodes to be included in the tree.  Listed below are the acceptable values for this parameter:
	<ul>
	<li>NodeFilter.SHOW_ALL</li>
	<li>NodeFilter.SHOW_CDATA_SECTION</li>
	<li>NodeFilter.SHOW_DOCUMENT</li>
	<li>NodeFilter.SHOW_DOCUMENT_TYPE</li>
	<li>NodeFilter.SHOW_ENTITY</li>
	<li>NodeFilter.SHOW_NOTATION</li>
	<li>NodeFilter.SHOW_TEXT</li>
	<li>NodeFilter.SHOW_ATTRIBUTE</li>
	<li>NodeFilter.SHOW_COMMENT</li>
	<li>NodeFilter.SHOW_DOCUMENT_FRAGMENT</li>
	<li>NodeFilter.SHOW_ELEMENT</li>
	<li>NodeFilter.SHOW_ENTITY_REFERENCE</li>
	<li>NodeFilter.SHOW_PROCESSING_INSTRUCTION</li>
	</ul>
</li>
	<li><strong>filterFunction</strong>: This parameter can be a reference to a filter function.  Its purpose is to allow you to filter nodes even further than what the <code>whatToShow</code> parameter can provide.  If you have no need for this parameter, simply pass in <code>null</code>.  However, if you specify a function, it must accept a single node and return an integer value based on one of the following constants:
	<ul>
	<li>NodeFilter.FILTER_ACCEPT</li>
	<li>NodeFilter.FILTER_REJECT</li>
	<li>NodeFilter.FILTER_SKIP</li>
	</ul>
</li>
	<li><strong>entityRefExpansion</strong>: A boolean value that determines whether or not the content of the entity reference nodes should be treated as hierarchial nodes.  In most cases, this value will probably be <code>false</code>.</li>
	</ol>
	<h3>Updating the original code to use the TreeWalker:</h3</p>
	<p>For our purposes (emulating the word-wrap CSS property) we won't need to get very fancy with the TreeWalker at all.  All we really need to do is traverse the tree of the element that's been bound by our Mozilla Binding.  We'll make use of the SHOW_TEXT filter to ensure that we visit only text nodes (and not bother with any HTML elements).  This will allow us to insert the unicode hyphen between the characters of text nodes, while leaving in tact all other HTML inside the bound element.</p>
	<p>The code would look something like this:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> walker = document.<span class="me1">createTreeWalker</span><span class="br0">&#40;</span>_elem, NodeFilter.<span class="me1">SHOW_TEXT</span>, <span class="kw2">null</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;</p>
	<p><span class="kw1">while</span> <span class="br0">&#40;</span>walker.<span class="me1">nextNode</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> node = walker.<span class="me1">currentNode</span>;<br />
&nbsp; &nbsp;node.<span class="me1">nodeValue</span> = node.<span class="me1">nodeValue</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">''</span><span class="br0">&#41;</span>.<span class="me1">join</span><span class="br0">&#40;</span>String.<span class="me1">fromCharCode</span><span class="br0">&#40;</span><span class="st0">'8203'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
	<p>The above code is really a tremendous simplification from what I had originally written (thanks Rich!).  This technique allows us to walk only the text nodes of the bound element (skipping over any HTML tags).  That way, we can insert the unicode symbol only amongst the characters of raw text and not have to worry about mangling (and subsequently, unmangling) any HTML tags.</p>
	<h3>The "Gotcha:"</h3>
	<p>While the TreeWalker technique greatly simplifies the word-wrap binding code, there is still a caveat that you should be aware of if you plan to use this binding -- or a similar one you've written yourself -- in one of your projects (and this goes for the original version too).</p>
	<p>Inserting the unicode symbol between <em>every</em> character in a string is not necessarily ideal.  Take a perfectly normal string like "How are you today?"  This string already has spaces, and so it will naturally wrap where the browser sees those "soft" spaces.  Inserting the unicode hyphen into that aforementioned string doesn't do anything particularly useful, and in fact, it might even be considered harmful.</p>
	<p>It's quite possible that you would end up breaking the word "today" onto two pieces: "tod" and "ay" -- clearly not the desired effect.  What can be done about this?  Well... one option is careful and thoughtful use of the word-wrap binding.  Use it only for long <em>unbroken</em> strings of text (like a long URL for instance).  Another option might be to modify the code to abort the word wrap if a space is found within the string (far from a perfect approach though).</p>
	<p>Another idea I experimented with (but decided against blogging about because of its complexity) was measuring each "word" in the bound element.  If any given word were greater in width than the bound element's container, then <em>that</em> word would get unicode hyphens inserted into it.  All "short" words were left alone.</p>
	<p>This technique did actually work, but it involved recursively adding invisible, cloned elements wrapped in &lt;span&gt; tags to the DOM on the fly in order to properly measure the text.  Also, it did not account for a scenario where text should wrap because of a floated element, and this (IMO) is one of the more desirable way to utilize word-wrap.  Still, I think the concept has potential, and I may decide to revisit it at some point in the future.</p>
	<p>For now though, we have something that gets us close, is relatively simple to implement, and brain-dead easy to use.</p>
	<p>If you'd like, you can see a working demo of the <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take2/">updated word-wrap code</a>.</p>
	<p>If you're feeling extra adventurous, you can take a look at my <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take3/">word-wrap experiment (take 3)</a> where I try to measure text elements and only insert unicode hyphens where necessary (use this version at your own risk!)</p>
	<p>That'll do it for this entry.  Special thanks to Rich Birkby for enlightening me about the TreeWalker.  Be sure to check our Rich's ASPAdvice blog: <a href = "http://aspadvice.com/blogs/rbirkby/">http://aspadvice.com/blogs/rbirkby</a> and his <a href = "http://www.thundermain.com/rss">Microsoft Downloads RSS Feed</a>.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Emulating CSS word-wrap for Mozilla/Firefox</title>
		<link>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/</link>
		<comments>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 07:46:40 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Mozilla-specific]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/</guid>
		<description><![CDATA[	
	Be sure to check out the follow-up to this post:  Word-wrap for Mozilla (take 2).  It features a much simplified way of accomplishing the same thing, based on the comments from RichB.
	
	IE has one nice CSS feature that a lot of other browsers lack, which is the ability to use CSS to wrap [...]]]></description>
			<content:encoded><![CDATA[	<div class = "note">
	<p>Be sure to check out the follow-up to this post:  <a href = "http://ecmascript.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Word-wrap for Mozilla (take 2)">Word-wrap for Mozilla (take 2)</a>.  It features a much simplified way of accomplishing the same thing, based on the comments from RichB.</p>
	</div>
	<p>IE has one nice CSS feature that a lot of other browsers lack, which is the ability to use CSS to wrap long words.  It's easy to use.  Something like this will do the trick:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="re1">.wrapme</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;word-wrap: break-word;<br />
<span class="br0">&#125;</span></div>
	<p>Firefox lacks this feature, but it does offer some snazzy features of its own.  One in particular is <a href = "http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference"><abbr title = "Extensible Binding Language">XBL</abbr></a>.</p>
	<p>In this blog entry, I'm going to demonstrate how to use Mozilla Bindings to (sort of) emulate CSS word-wrap.  Since the ability to wrap a long series of unbroken characters is part of the CSS3 specification, I do expect to see this in future versions of Firefox.  Until then, this is the best I've got.</p>
	<h3>An outside-the-box solution</h3>
	<p>For a long time, I didn't think there was really anything you could do about Firefox's lack of support for <code>word-wrap</code>.  I figured the best you could do was set your containing element to hide overflowing data (which might be okay, but most likely not).</p>
	<p>Just recently though, a co-worker of mine found a web page that explained how you could insert an invisible unicode character (&amp;#8203;) at various points in a string to solve the Firefox word-wrap problem.  Since Firefox views this unicode symbol as a valid character upon which to "break" a string (if necessary) it servers as a convenient to way get Firefox to wrap long strings of characters (the symbol remains completely invisible to the end user).</p>
	<p>My co-worker first showed me a function he wrote which took a string parameter, inserted this unicode symbol every 5 characters, and then returned the modified string.</p>
	<p>This is a good first start, but I wanted something more.  I wanted a solution that didn't require me to execute a Javascript function, and I wanted a solution that could handle HTML intersperced throughout the string.</p>
	<p>It turns out, that creating a solution that <em>doesn't</em> require executing a Javascript function isn't the hard part at all!  In Firefox, this can be accomplished quite easily with <a href = "http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference"><abbr title = "Extensible Binding Language">XBL</abbr></a>.</p>
	<p>How does one utilize <abbr title = "Extensible Binding Language">XBL</abbr>? Glad you asked!</p>
	<p>From the Mozilla Developer page:</p>
	<blockquote><p>
Extensible Binding Language is a XML-based markup language to implement reusable components (bindings) that can be bound to elements in other documents. The element with a binding specified, called the bound element, acquires the new behavior specified by the binding. Bindings can be bound to elements using Cascading Style Sheets (CSS) or DOM. One element can be be bound to several bindings at once.<br />
</blockquote></p>
	<p>Setting up the binding is pretty easy, so let's tackle that part first:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="re1">.wordwrap</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;-moz-binding: <span class="kw2">url</span><span class="br0">&#40;</span><span class="st0">'./wordwrap.xml#wordwrap'</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
	<p>With the CSS in place, "binding" to the DOM element is trivial:  simply set the element's class property to "wordwrap".</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="sc3"><span class="re1">&lt;p</span> id = <span class="st0">&quot;myParagraph&quot;</span> class = <span class="st0">&quot;wordwrap&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp;SomeParagraphWithAVeryLongStringOfUnbrokenTextThatWillEventuallyWrap.<br />
<span class="sc3"><span class="re1">&lt;/p<span class="re2">&gt;</span></span></span></div>
	<p>With the CSS and HTML taken care of, all that's left to do is write the XBL file.  An XBL file is really nothing more than an XML with a specific structure so that Mozilla knows how to process it as a binding.  In fact, if you prefer, you can name the file with an <code>.xml</code> extension (like I did), instead of an <code>.xbl</code> extension.</p>
	<p>At its most basic, an XBL file takes the following form:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="sc3"><span class="re1">&lt;?xml</span> version = <span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;bindings</span> xmlns = <span class="st0">&quot;http://www.mozilla.org/xbl&quot;</span> xmlns:html = <span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="re2">&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;binding</span> id = <span class="st0">&quot;wordwrap&quot;</span> applyauthorstyles = <span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span></p>
	<p>&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;implementation<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;/* ECMAScript code here */<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;/constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;/implementation<span class="re2">&gt;</span></span></span></p>
	<p><span class="sc3"><span class="re1">&lt;/binding<span class="re2">&gt;</span></span></span></p>
	<p><span class="sc3"><span class="re1">&lt;/bindings<span class="re2">&gt;</span></span></span></div>
	<h3>The binding id attribute:</h3>
	<p>The root element of the file is &lt;bindings&gt;.  Within the root element, you'll have one or more &lt;binding&gt; elements, each with its own unique id.  Since an XBL file can have more than one binding definition, the id instructs the browser as to which binding we're interested in.  Remember, back when we specified the url for the -moz-binding property, we specified the binding id by appending to it, a "#" symbol followed by the binding id (in this case "wordwrap").  So the full url ended up being: <code>"./wordwrap.xml#wordwrap"</code>.</p>
	<h3>The applyauthorstyles attribute:</h3>
	<p>The "applyauthorstyles" attribute determines whether or not to allow styles from the document on the bound element (other than the -moz-binding).  The default value is false, but you're free to change this if you want (or need) to.</p>
	<h3>The &lt;implementation&gt; and &lt;constructor&gt;</h3>
	<p>Every binding has an &lt;implementation&gt; element and, within it, a &lt;constructor&gt; element.  This is where most of your ECMAScript code will go (in our case, this is where <em>all</em> of the ECMAScript code will go).</p>
	<p>With a <em>very</em> basic explanation of an XBL file's structure out of the way, we can now go ahead and write the implementation of our binding.</p>
	<p>It's important to note that all of the ECMAScript you write needs to go inside a CDATA block (this an XML file after all).  Other than that though, you don't have too many restrictions.  In fact, one nice thing about writing a binding, is that you have a great deal of flexibility.  Pretty much all of the ECMAScript you're used to writing is going to work inside the XBL file.  And to sweeten the deal even more, you've got some nice extras that aren't available in your normal, day-to-day ECMAScript (we'll look at one of them shortly).</p>
	<h3>Referencing the bound element:</h3>
	<p>Perhaps the most important thing you need to know (before you can do anything productive in your binding) is how access the bound element.  In other words, how do you access the element to which the class (in our case "wordwrap") was applied?  Fortunately, it turns out to be brain-dead easy.  You simply using the <code>this</code> keyword; that's it!</p>
	<p>Once you have a reference to the bound element, you can do most (if not all) of the things you'd normally do with a DOM element.  You could, for instance, wire up logic such that a particular function execute whenever the bound element is moused over, as in:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> elem = <span class="kw1">this</span>;<br />
elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'mouseover'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'The text of this element will eventually be wrapped!'</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;</div>
	<p>If you put the preceding code inside the &lt;constructor&gt; element of the binding definition, then any time a user moused over the &lt;p&gt; (#myParagraph), he would see an alert saying "The text of this element will eventually be wrapped!"</p>
	<h3>Making the text wrap:</h3>
	<p>At this point, it should be fairly clear what the plan of action is:</p>
	<ol>
	<li>Access the bound element's text.</li>
	<li>Insert the special unicode symbol between the characters of the string.</li>
	<li>Update the bound element's text with the newly modified text.</li>
	</ol>
	<p>From the instructions above, I've made it sounds pretty simple.  Unfortunately, it's a bit more complicated than I let on.  I (conveniently) failed to mention that if the bound element's text contains HTML, we need to take extra care not to insert the special unicode symbol into any of the HTML tags (or else we'll end up disrupting the author's markup).</p>
	<div class = "note">
Actually, the final solution I came up with <em>doesn't</em> take care not to insert the special unicode symbol into HTML tags.  Instead, I willingly make a mess out of the markup and then write a bit of logic to clean it up later on, but I'll explain all of that as we get further into the binding's ECMAScript code.</div>
	<h3>The word wrap code</h3>
	<p>The code to make this happen isn't long, so rather than try to explain it up front, I'll first show the full code, and then provide an explanation afterwards:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="sc3"><span class="re1">&lt;?xml</span> version = <span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;bindings</span> xmlns = <span class="st0">&quot;http://www.mozilla.org/xbl&quot;</span> xmlns:html = <span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="re2">&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;binding</span> id = <span class="st0">&quot;wordwrap&quot;</span> applyauthorstyles = <span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span></p>
	<p>&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;implementation<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var elem = this;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// maintain a reference to the bound element</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;elem.addEventListener('overflow',<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;function()<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// matches any &quot;mangled&quot; HTML tag<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var exp = /<span class="sc3"><span class="re1">&lt;</span>&amp;#<span class="nu0">8203</span>;\/*<span class="br0">&#91;</span>&amp;#<span class="nu0">8203</span>;_\<span class="re0">s</span>=<span class="st0">&quot;'\w]+&gt;</span>/g;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var txt = elem.innerHTML;&nbsp; &nbsp; &nbsp;// the bound element's innerHTML<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var chars = txt.split('');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var newTxt = chars.join('<span class="sc1">&amp;#8203;</span>');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;newTxt = newTxt.replace(exp, reconstructTag);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;elem.innerHTML = newTxt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;},false);</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;function reconstructTag(_tag)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return _tag.replace(/<span class="sc1">&amp;#8203;</span>/g, '');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3">&lt;/constructor&gt;</span><br />
&nbsp; &nbsp;<span class="sc3">&lt;/implementation&gt;</span></p>
	<p><span class="sc3">&lt;/binding&gt;</span></p>
	<p><span class="sc3">&lt;/bindings&gt;</span></span></div>
	<h3>Explanation:</h3>
	<p>The first thing we do is stuff the bound element (<code>this</code>) in a variable, <code>elem</code>.  This is of course, totally optional, but it helps me (my brain is small and remembering what <code>this</code> represents eludes me quickly and frequently).</p>
	<p>Next, we add an event listener to the bound element that "listens" for the 'overflow' event (whenever text overflows its containing element).  You're probably aware the in typical Javascript, there is no such 'overflow' event.  This, along with its counterpart, 'underflow' are just two the many "extras" that you get when writing Javascript in XBL.</p>
	<p>The remainder of the code will all take place within the context of the anonymous function that executes on 'overflow'.</p>
	<p>Next, we create a regular expression that matches any "mangled" HTML tag (more on this in a bit).</p>
	<p>The next three steps are all quite straight-forward. We store the bound element's innerHTML in a variable called, <code>txt</code>.  We then call <code>.split('')</code> on that text and store it in the variable, <code>chars</code>.  Passing an empty string into the <code>.split(..)</code> function will yield an array of characters representing the string that was split.  In other words, each character in the string is now an element in the array <code>chars</code>.  Finally, we put all of those characters back together by calling <code>chars.join('&amp;#8203');</code> and stuffing the result in <code>newTxt</code>.  This inserts that special unicode symbol between each character in the array as it joins them back together.</p>
	<h3>The tricky part:</h3>
	<p>If you were paying attention, then at this point, you'd realize that any HTML that existed inside of the bound element, just got totally mangled with that last <code>.join(..)</code>. statement.  Think about it: if the bound element's innerHTML were something like this:</p>
	<div class="dean_ch" style="white-space: nowrap;">This &lt;span&gt;is a&lt;/span&gt; paragraph.</div>
	<p>Then after executing the <code>.join(..)</code> statement, the variable, <code>newTxt</code> would now be equal to:</p>
	<div class="dean_ch" style="white-space: nowrap;">&amp;amp;#8203;T&amp;amp;#8203;h&amp;amp;#8203;i&amp;amp;#8203;s&amp;amp;#8203; &amp;amp;#8203;&lt;&amp;amp;#8203;s&amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;n&amp;amp;#8203;&gt;&amp;amp;#8203;i&amp;amp;#8203;s&amp;amp;#8203; &amp;amp;#8203;a&amp;amp;#8203;&lt;&amp;amp;#8203;/&amp;amp;#8203;s&amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;n&amp;amp;#8203;&gt;&amp;amp;#8203; &amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;r&amp;amp;#8203;a&amp;amp;#8203;g&amp;amp;#8203;r&amp;amp;#8203;a&amp;amp;#8203;p&amp;amp;#8203;h&amp;amp;#8203;.&amp;amp;#8203;</div>
	<p>Besides perhaps giving you a head-ache, the above HTML snippet should make you realize that the insertion of that special unicode symbol between <em>every</em> character in the string has a really detrimental effect on the &lt;span&gt; tag.</p>
	<h3>The solution:</h3>
	<div class = "note">
The <a href = "http://ecmascript.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Word-wrap for Mozilla (take 2)">follow-up</a> to this post explains a much easier method that doesn't involve mangling the HTML.  It is highly recommended that you check out that approach as well.
</div>
	<p>It turns out, that "unmangling" the HTML tags isn't too too hard (just takes some fancy regular expression work).  The regular expression, <code>exp</code> will match any HTML tag that has had the special unicode symbol inserted into it.  We can utilize this regular expression to match all occurrences of "mangled" HTML tags and (with some help from the <code>.replace(..)</code> function) replace them with "unmangled" versions of the tag.</p>
	<p>In order to do this though, we need to make of use a callback function when we invoke the <code>.replace(..)</code> function.  When you pass a function reference as the second parameter into a <code>.replace(..)</code> call (as in: <code>myString.replace(regex, myFn)</code>) Javascript will automatically pass the matched string into the callback function for you!</p>
	<p>This is an extremely powerful concept.  We can now take all "mangled" HTML tag matches and send them through the <code>reconstructTag(..)</code> function.  The <code>reconstructTag(..)</code> function simply returns a copy of the string sent into it, but with all occurrences of that special unicode symbol stripped out (thus returning our "mangled" HTML tags to proper form).</p>
	<p>With all of these concepts working together, we end up with a string that looks perfectly unaltered to the end user, but which wraps nicely when it would otherwise overflow its container.</p>
	<p>See for yourself on my demo page: <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap/">Word Wrap Binding Demo</a>.</p>
	<p>And, to see a slightly more complex example, take a look at my implementation of an ellipsis for Mozilla using XBL: <a href = "http://ecmascript.stchur.com/blogcode/mozilla_ellipsis/">Mozilla Ellipsis</a>.</p>
	<h3>Final thoughts:</h3>
	<p>Mozilla Bindings offer tremendous power to the developer.  You can do virtually <em>anything</em> with them; the sky is the limit really.  In this blog post, we just looked at one example: how to make long, unbroken strings wrap when they would otherwise overflow their container.  But we also saw how you can take this further (see the ellipsis demo link above).</p>
	<h3>Important Warning / Disclaimer!</h3>
	<p>It should be noted that I have absolutely <em>no idea</em> what kind of effect inserting the special unicode symbol (needed to make this technique work) might have on accessibility.  It's an important question.  Is that character going to be read aloud by screen readers (what in the world would it say)?  Will search engines see it and have no idea what your text represents, thereby hurting your search engine ranking?  My fear is that the effect of inserting this character into your string might not be good.  But of course, without any real testing, I can't say for sure.</p>
	<p>My recommendation would be to use this concept with caution and only when absolutely necessary.  A little common sense will go along way towards ensuring you're not bloating your page will a lot of "fancy-just-for-the-heck-of-it" code.</p>
	<p>So there ya go!  Word wrap in Mozilla.  Happy Binding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Retrieving Elements by Class Name</title>
		<link>http://blog.stchur.com/2006/11/29/retrieving-elements-by-class-name/</link>
		<comments>http://blog.stchur.com/2006/11/29/retrieving-elements-by-class-name/#comments</comments>
		<pubDate>Wed, 29 Nov 2006 10:34:56 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2006/11/29/retrieving-elements-by-class-name/</guid>
		<description><![CDATA[	Everyone is already familiar with document.getElementById(..). Sometimes though, you don&#039;t want to (or can&#039;t) retrieve an element by its id.  What would be nice was if there was some way to &#034;query&#034; for all elements of a certain CSS class name and then return them all in an array.  Well there is no [...]]]></description>
			<content:encoded><![CDATA[	<p>Everyone is already familiar with <code>document.getElementById(..)</code>. Sometimes though, you don&#039;t want to (or can&#039;t) retrieve an element by its id.  What would be nice was if there was some way to &#034;query&#034; for all elements of a certain CSS class name and then return them all in an array.  Well there is no such function, but there&#039;s not reason we can&#039;t write one!</p>
	<p>Read on to learn more.</p>
	<p><span id="more-22"></span></p>
	<p>I&#039;m going to call my function <code>getElementsByClassName(..)</code>.  In order to write this function, we&#039;ll need to leverage another, native ECMAScript function: <code>.getElementsByTagName(..)</code>.  I trust everyone is already familiar with how that function works.  If not, there are plenty of resources on the web that can help you &#8212; I&#039;m not going to get into that here.</p>
	<p>The <code>getElementsByClassName(..)</code> function will take three parameters:</p>
	<ol>
	<li>_className: (required) A regular expression (or a string) used to match the desired class name(s).</li>
	<li>_startElem: (optional) The element at which you wish to begin the search; default = &#039;document&#039;.</li>
	<li>_filterTag: (optional) The tag name you wish to limit searches to; default = &#039;*&#039;.</li>
	</ol>
	<p>The decision to use a regular expression instead of just a simple string might not be obvious; let me explain.</p>
	<p>Since DOM elements can have multiple classes specified (simply separate them by a space), a direct string-to-.className comparison would not be very flexible.  Suppose, for example, I want to retrieve all elements that have the className: <code>'animal'</code> and <code>'dog'</code>.  You might think would be as simple as passing in the string <code>'animal dog'</code>, but that may not work.  The element&#039;s <code>.className</code> property could very well be <code>'animal poodle dog'</code>, in which case that string comparison would fail, but the element does indeed have the classes <code>'animal'</code> and <code>'dog'</code>.</p>
	<p>Clearly we need something more robust.  Enter regular expressions!</p>
	<p>If our <code>getElementsByClassName(..)</code> takes a regular expression, we now have a great deal more flexibility.  We can query all elements that have classes <code>'animal'</code> and <code>'dog'</code> but not <code>'poodle'</code> (something that would be darn near impossible with a straight string comparison).</p>
	<p>Still, we don&#039;t want to force the average person to have to write a regular expression just to use this function, so we&#039;ll also allow plain old strings to be passed in, and when that happens, we&#039;ll simply generate a stock regex that works for 99% of cases.</p>
	<p>The second parameter, <code>_startElem</code>, is to increase efficiency.  There is a good chance that you don&#039;t want to query the entire document for elements with a particular class name, but that you want to confine your query to some parent element.  This optional parameter allows you to do that.  If this parameter is not specified, it will default to the entire document.</p>
	<p>The third parameter, <code>_filterTag</code>, is also to improve efficiency.  You may only be interested in querying a elements of a specific tag name.  It would be silly then to query all elements if you&#039;re only interested in say, <code>&lt;span&gt;</code> elements.  If this parameter is not specified, it will default to all elements (&#039;*&#039;).</p>
	<p>Now that we have the basic design for this function, we can go ahead and write it.</p>
	<p>Here is the full code for <code>getElementsByClassName(..)</code> with the explanation of any tricky code to follow.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">function</span> getElementsByClassName<span class="br0">&#40;</span>_className, _startElem, _filterTag<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _className === <span class="st0">&#039;string&#039;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> _className = <span class="kw2">new</span> RegExp<span class="br0">&#40;</span><span class="st0">&#039;(^| )&#039;</span> + _className + <span class="st0">&#039;( |$)&#039;</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// default to the document element if no _startElem is specified</span><br />
&nbsp; &nbsp;_startElem = _startElem || document;</p>
	<p>&nbsp; &nbsp;<span class="co1">// default to all elements if no _filterTag is specified</span><br />
&nbsp; &nbsp;_filterTag = _filterTag || <span class="st0">&#039;*&#039;</span>;</p>
	<p>&nbsp; &nbsp;<span class="kw2">var</span> arr = <span class="br0">&#91;</span><span class="br0">&#93;</span>; &nbsp; &nbsp;<span class="co1">// the array of matched elements that will be returned</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> tags; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1">// array of all tags to check for class name matches</span></p>
	<p>&nbsp; &nbsp;<span class="coMULTI">/* If the browser supports [DOMElement].all, we&#039;ll use that. &nbsp;Otherwise<br />
&nbsp; &nbsp; &nbsp; &nbsp;we&#039;ll use .getElementsByTagName(..), which is really the preferred method. */</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _startElem.<span class="me1">all</span> != <span class="st0">&#039;undefined&#039;</span> &amp;&amp; _filterTag == <span class="st0">&#039;*&#039;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;tags = _startElem.<span class="me1">all</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// the W3C way (but won&#039;t work for IE less than 6)</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;tags = _startElem.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span>_filterTag<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// loop through the tags array checking for .className matches</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> i, len = tags.<span class="me1">length</span>;<br />
&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; len; i++<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> elem = tags<span class="br0">&#91;</span>i<span class="br0">&#93;</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_className.<span class="me1">test</span><span class="br0">&#40;</span>elem.<span class="me1">className</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> arr.<span class="me1">push</span><span class="br0">&#40;</span>elem<span class="br0">&#41;</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw1">return</span> arr;<br />
<span class="br0">&#125;</span></div>
	<p>Most of this function is pretty self-explanatory, but two things require explanation.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="co1">// default to the document element if no _startElem is specified</span><br />
_startElem = _startElem || document;</p>
	<p><span class="co1">// default to all elements if no _filterTag is specified</span><br />
_filterTag = _filterTag || <span class="st0">&#039;*&#039;</span>;</div>
	<p>The above code ensures default values for <code>_startElem</code> and <code>_filterTag</code>.  It does this by leveraging the fact that, in ECMAScript, all variables are variant type, and that ECMAScript uses short-circuit evaluation.</p>
	<p>It boils down to this:  when assigning a variable using logical OR ( || ), the variable&#039;s value will be equal to the value of the first variable that evaluates to true in an if conditional.  Since this is going to be the subject of a future blog entry, I&#039;m not going to go into any additional details here.  All you need to know for now, is that if either <code>_startElem</code> or <code>_filterTag</code> is unspecified, each will receive its proper default value.</p>
	<p>The other piece of code that requires some explanation is:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _startElem.<span class="me1">all</span> != <span class="st0">&#039;undefined&#039;</span> &amp;&amp; _filterTag == <span class="st0">&#039;*&#039;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;tags = _startElem.<span class="me1">all</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw1">else</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;tags = _startElem.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span>_filterTag<span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
	<p>The really tricky part about this is that it&#039;s not obvious why we need to do it.</p>
	<p>The problem is, IE (less than 6) supports <code>.getElementsByTagName(..)</code>, but it doesn&#039;t support passing in the universal selector to that function (the value &#039;*&#039;).  Since all modern versions of IE support <code>.getElementsByTagName(..)</code>, but they don&#039;t all support the universal selector, we have something of a problems here.</p>
	<p>We can use <code>[DOMElement].all</code> in place of <code>.getElementsByTagName('*')</code>, for IE, but the fact that <code>.all</code> exists doesn&#039;t necessarily tell us we&#039;re in IE (Opera supports <code>.all</code> too).</p>
	<p>Fortunately, <code>.all</code> is sufficient for what we&#039;re trying to do, so it doesn&#039;t really matter if we&#039;re using IE5, IE6, IE7, or Opera (or even some other browser that supports <code>.all</code> that I don&#039;t even know about).</p>
	<p>So, if the browser supports <code>.all</code> we&#039;ll use that.  Otherwise, we&#039;ll use the W3C standard&#039;s <code>.getElementsByTagName('*')</code> instead.</p>
	<p>With all of that sorted out, our <code>tags</code> variable should now be an array, appropriately populated with DOM elements that the rest of the code will filter based on class name.</p>
	<p>Everything else in the function (including the filtering loop) should be fairly easy to understand.  The only thing left to do now is show a few samples of how to utilize it properly.</p>
	<div class="dean_ch" style="white-space: nowrap;">&lt;!DOCTYPE html <span class="kw2">PUBLIC</span> <span class="st0">&quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span> <span class="st0">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;</span>&gt;</p>
	<p>&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;getElementsByClassName<span class="br0">&#40;</span>..<span class="br0">&#41;</span> samples&lt;/title&gt;<br />
&lt;script type = <span class="st0">&quot;text/javascript&quot;</span>&gt;</p>
	<p><span class="coMULTI">/* include getElementsByClassName(..) function */</span></p>
	<p><span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="kw2">var</span> dogHouse = document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&#039;theHouse&#039;</span><span class="br0">&#41;</span>;</p>
	<p><span class="kw2">var</span> animals = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;animal&#039;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> animalsWithHomes = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;animal&#039;</span>, dogHouse<span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> dogs = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;dog&#039;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> poodles = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;poodle&#039;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> divDogs = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;dog&#039;</span>, <span class="kw2">null</span>, <span class="st0">&#039;div&#039;</span><span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> cats = getElementsByClassName<span class="br0">&#40;</span><span class="st0">&#039;cat&#039;</span><span class="br0">&#41;</span>;</p>
	<p><span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;Total animals: &#039;</span> + animals.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;Animals with homes: &#039;</span> + animalsWithHomes.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;Total Dogs: &#039;</span> + dogs.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;Number of Poodles: &#039;</span> + poodles.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;DIV Dogs: &#039;</span> + divDogs.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&#039;Number of Cats: &#039;</span> + cats.<span class="me1">length</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
&lt;/script&gt;</p>
	<p>&lt;style type = <span class="st0">&quot;text/css&quot;</span>&gt;<br />
#theHouse, #theStreets <span class="br0">&#123;</span> border: 1px solid #<span class="nu0">000</span>; <span class="br0">&#125;</span><br />
&lt;/style&gt;<br />
&lt;/head&gt;</p>
	<p>&lt;body <span class="kw3">onload</span> = <span class="st0">&quot;init()&quot;</span>&gt;</p>
	<p>The House:<br />
&lt;div id = <span class="st0">&quot;theHouse&quot;</span>&gt;<br />
&lt;div <span class="kw2">class</span> = <span class="st0">&quot;animal dog poodle&quot;</span>&gt;Poodle <span class="nu0">1</span> <span class="br0">&#40;</span>div<span class="br0">&#41;</span>&lt;/div&gt;<br />
&lt;span <span class="kw2">class</span> = <span class="st0">&quot;animal dog chocolateLab&quot;</span>&gt;Chocolate Lab <span class="nu0">1</span> <span class="br0">&#40;</span>span<span class="br0">&#41;</span>&lt;/span&gt;<br />
&lt;div <span class="kw2">class</span> = <span class="st0">&quot;animal dog poodle&quot;</span>&gt;Poodle <span class="nu0">2</span> <span class="br0">&#40;</span>div<span class="br0">&#41;</span>&lt;/div&gt;<br />
&lt;/div&gt;</p>
	<p>&lt;br <span class="re0">/&gt;&lt;br /</span>&gt;</p>
	<p>The Streets:<br />
&lt;div id = <span class="st0">&quot;theStreets&quot;</span>&gt;<br />
&lt;div <span class="kw2">class</span> = <span class="st0">&quot;animal dog germanShepherd&quot;</span>&gt;Homeless Shepherd <span class="br0">&#40;</span>div<span class="br0">&#41;</span>&lt;/div&gt;<br />
&lt;span <span class="kw2">class</span> = <span class="st0">&quot;animal cat calico&quot;</span>&gt;Calico Cat <span class="nu0">1</span> <span class="br0">&#40;</span>span<span class="br0">&#41;</span>&lt;/span&gt;<br />
&lt;/div&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</div>
	<p>I don&#039;t think this requires much explanation.  It&#039;s basically just some samples of <code>.getElementsByClassName(..)</code> in action.</p>
	<p>One thing you&#039;ll note is that I didn&#039;t bother to use any regular expressions here.  I simply pass in strings and let our function use its stock regex for me.  I could have however, passed in a more complex regular expression if I really wanted to.</p>
	<p>If you&#039;re not too familiar with regular expressions, that&#039;s okay, but if you are, then that extra knowledge may go a long way towards helping you get the most out of the <code>.getElementsByClasName(..)</code> function.</p>
	<p>Well that wraps up this entry.  It was long I know, but it&#039;s a super-useful function and a great addition to any ECMAScript library.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2006/11/29/retrieving-elements-by-class-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting to Pixels with javascript</title>
		<link>http://blog.stchur.com/2006/09/20/converting-to-pixels-with-javascript/</link>
		<comments>http://blog.stchur.com/2006/09/20/converting-to-pixels-with-javascript/#comments</comments>
		<pubDate>Wed, 20 Sep 2006 21:58:17 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2006/09/20/converting-to-pixels-with-javascript/</guid>
		<description><![CDATA[	A few entries back, I wrote about CSS Computed Style.  In that blog entry, I discussed a cross-browser javascript function to retrieve the computed style of a DOM element on the page.
	If you need a quick refresher&#8230; javascript doesn&#039;t allow you to access arbitrary style properties of a DOM element via .style unless you&#039;ve [...]]]></description>
			<content:encoded><![CDATA[	<p>A few entries back, I wrote about <a href="http://ecmascript.stchur.com/2006/06/21/css-computed-style/">CSS Computed Style</a>.  In that blog entry, I discussed a cross-browser javascript function to retrieve the computed style of a DOM element on the page.</p>
	<p>If you need a quick refresher&#8230; javascript doesn&#039;t allow you to access arbitrary style properties of a DOM element via <code>.style</code> <em>unless you&#039;ve previously set that property using javascript OR if you&#039;ve defined the style using an inline style attribute of the DOM element.</em></p>
	<p>This is where CSS Computed Style can really come in handy.  By retrieving an element&#039;s computed style, you can retrieve style properties just as they were when you defined them in your CSS file (regardless of whether or not you&#039;ve ever set them in javascript).</p>
	<p>But there&#039;s a gotcha (isn&#039;t there always).  If you remember, IE doesn&#039;t really support computed style.  Instead, IE offers <code>.currentStyle</code> which, while similar, is most definitely NOT the same thing.</p>
	<p>Perhaps the most inconvenient shortcoming of <code>.currentStyle</code> is the fact that it fails to normalize all units to pixels, as the W3C recommends.</p>
	<p>In this blog entry, I&#039;m going to explain how to write a function that will convert these non-pixel values to pixels for you.</p>
	<p>Read on to learn more.</p>
	<p><span id="more-18"></span></p>
	<p>Writing a <code>convertToPixels(..)</code> function is actually rather tricky.  When I first set out to do this, I failed to account for the fact that many of the units we deal with in modern CSS are relative units.  For example, <code>em, ex,</code> or <code>%</code> are all units that have no meaning without context.</p>
	<p>As you&#039;ll see shortly, this has serious implications for the technique I&#039;m going to use for this function.</p>
	<h3>The basic concept:</h3>
	<p>The basic concept for this function is fairly simple.  We&#039;ll pass in a string to our function, something like &#039;5em&#039; or &#039;12pt&#039;.  We&#039;ll then create an invisible <code>&lt;div&gt;</code> element, set either its height or its border, add it to the page, and then measure it using <code>.offsetHeight</code> to get a pixel value.</p>
	<p>The full code for the function is below, with an explanation to follow:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">if</span> <span class="br0">&#40;</span>!window.<span class="me1">sstchur</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> window.<span class="me1">sstchur</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>!sstchur.<span class="me1">web</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> sstchur.<span class="me1">web</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>!sstchur.<span class="me1">web</span>.<span class="me1">xb</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> sstchur.<span class="me1">web</span>.<span class="me1">xb</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span></p>
	<p>sstchur.<span class="me1">web</span>.<span class="me1">xb</span>.<span class="me1">convertToPixels</span> = <span class="kw2">function</span><span class="br0">&#40;</span>_str, _context<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">/px$/</span>.<span class="me1">test</span><span class="br0">&#40;</span>_str<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> parseInt<span class="br0">&#40;</span>_str<span class="br0">&#41;</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; <span class="kw2">var</span> tmp = document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">&#039;div&#039;</span><span class="br0">&#41;</span>;<br />
&nbsp; tmp.<span class="me1">style</span>.<span class="me1">visbility</span> = <span class="st0">&#039;hidden&#039;</span>;<br />
&nbsp; tmp.<span class="me1">style</span>.<span class="me1">position</span> = <span class="st0">&#039;absolute&#039;</span>;<br />
&nbsp; tmp.<span class="me1">style</span>.<span class="me1">lineHeight</span> = <span class="st0">&#039;0&#039;</span>;</p>
	<p>&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">/%$/</span>.<span class="me1">test</span><span class="br0">&#40;</span>_str<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; _context = _context.<span class="me1">parentNode</span> || _context;<br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">height</span> = _str;<br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderStyle</span> = <span class="st0">&#039;solid&#039;</span>;<br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderBottomWidth</span> = <span class="st0">&#039;0&#039;</span>;<br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderTopWidth</span> = _str;<br />
&nbsp; <span class="br0">&#125;</span></p>
	<p>&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!_context<span class="br0">&#41;</span> <span class="br0">&#123;</span> _context = document.<span class="me1">body</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; _context.<span class="me1">appendChild</span><span class="br0">&#40;</span>tmp<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw2">var</span> px = tmp.<span class="me1">offsetHeight</span>;<br />
&nbsp; _context.<span class="me1">removeChild</span><span class="br0">&#40;</span>tmp<span class="br0">&#41;</span>;</p>
	<p>&nbsp; <span class="kw1">return</span> px + <span class="st0">&#039;px&#039;</span>;<br />
<span class="br0">&#125;</span>;</div>
	<p>The first thing you should notice about this function is that we first test whether or not the string that was passed into the function is already in pixels units (i.e. it ends with &#039;px&#039;).  If it does, we&#039;ll simply return that value right back (no sense &#034;converting&#034; what doesn&#039;t need conversion.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">/px$/</span>.<span class="me1">test</span><span class="br0">&#40;</span>_str<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> parseInt<span class="br0">&#40;</span>_str<span class="br0">&#41;</span>; <span class="br0">&#125;</span></div>
	<p>Next, we create a <code>&lt;div&gt;</code> div element and set a number of style properties:</p>
	<ul>
	<li><code>.style.visibility</code> to &#039;hidden&#039; so that this element never shows up on the page.</li>
	<li><code>.style.position</code> to &#039;absolute&#039; so that the element won&#039;t shift other elements around on the page.</li>
	<li><code>.style.lineHeight</code> to &#039;0&#039; because IE will add mysterious white-space to our element that will throw off our measurement if we don&#039;t.</li>
	</ul>
	<p>The next part is a little tricky.  If the units we&#039;re trying to convert have been specified as a percentage, then we need to set the <em>height</em> of our invisible <code>&lt;div&gt;</code>, and adjust the <code>_context</code> element to be <code>.parentNode</code> of the <code>_elem</code> that was passed in (% generally always means &#034;percent of the parent element&#034;).  However, if the units are anything else, then it&#039;s best to leave our element&#039;s height as 0, and set it&#039;s top border only.</p>
	<p>Why?  Well, trying to set the border of an element as a percentage isn&#039;t going to work.  You might think then, that we should just use the height technique all the time (I thought that at first).  The problem with this however, is that IE seems to think the a non-specified border is &#039;medium&#039;.  Trying to set the height of an element to &#039;medium&#039; isn&#039;t going to be very useful.</p>
	<p>The long and short of it is this:  A border can be almost anything (px, em, ex, pt, a keyword, like &#039;medium&#039; or &#039;large&#039;)  but it can&#039;t be a percentage, so if we&#039;re dealing with a percentage, it&#039;s best to set the height and leave the border alone.</p>
	<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">/%$/</span>.<span class="me1">test</span><span class="br0">&#40;</span>_str<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> tmp.<span class="me1">style</span>.<span class="me1">height</span> = _str; <span class="br0">&#125;</span></div>
	<p>Now, if the unit is <em>not</em> a percentage, then we&#039;ll use the border technique.  This means setting the element&#039;s top border to the specified value and <em>explicitly</em> setting the bottom border to 0 (we&#039;re not interested in the right or left borders so we can safely ignore them).  We also need to remember to set the border style to &#039;solid&#039; or else this technique won&#039;t work as expected.</p>
	<div class="dean_ch" style="white-space: nowrap;">
&nbsp; <span class="kw1">else</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderStyle</span> = <span class="st0">&#039;solid&#039;</span>;<br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderBottomWidth</span> = <span class="st0">&#039;0&#039;</span>;<br />
&nbsp; &nbsp; tmp.<span class="me1">style</span>.<span class="me1">borderTopWidth</span> = _str;<br />
&nbsp; <span class="br0">&#125;</span></div>
	<p>We&#039;re almost ready to measure our invisible element, but there&#039;s one thing we must do first.</p>
	<p>If the units we&#039;re trying to convert are relative units, then the equivalent pixel value <em>depends</em> upon context.  In other words, &#039;10%&#039; when specified on an element that is 200px would be 20px.  But that same &#039;10%&#039; when specified on an element that is 500px would be 50px. If we want the right value, we need to consider this context.</p>
	<p>That is why <code>convertToPixels(..)</code> takes an optional second parameter, <code>_context</code>.  If this parameter is not specified, we&#039;ll default to the <code>&lt;body&gt;</code> element, but if it <em>is</em> specified, we&#039;ll use it.</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw1">if</span> <span class="br0">&#40;</span>!_context<span class="br0">&#41;</span> <span class="br0">&#123;</span> _context = document.<span class="me1">body</span>; <span class="br0">&#125;</span></div>
	<p>The preceding line of code ensures that the <code>_context</code> variable won&#039;t be null (and thus wreak havoc on our function).</p>
	<p>Finally, we append the element to the <code>_context</code> element, measure its <code>.offsetHeight</code>, remove it from <code>_context</code> and then return the value we just measured.</p>
	<div class="dean_ch" style="white-space: nowrap;">
&nbsp; _context.<span class="me1">appendChild</span><span class="br0">&#40;</span>tmp<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw2">var</span> px = tmp.<span class="me1">offsetHeight</span>;<br />
&nbsp; _context.<span class="me1">removeChild</span><span class="br0">&#40;</span>tmp<span class="br0">&#41;</span>;</p>
	<p>&nbsp; <span class="kw1">return</span> px + <span class="st0">&#039;px&#039;</span>;</div>
	<p>Why add the <code>+ 'px'</code> to the value you ask?  Well, the major goal here is to make the cross-browser <code>getComputedStyle(..)</code> function we wrote to act more like a W3C style function when used in IE.  Since W3C browsers would return the value with &#039;px&#039; tacked on to the end, we&#039;ll go ahead and do this manually in our function so that we remain consistent.</p>
	<p>Now that our <code>convertToPixels(..)</code> function is complete, it would be good if we modified <code>getComputedStyle(..)</code> to take advantage of it.</p>
	<p>We&#039;ll do that in Part 2.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2006/09/20/converting-to-pixels-with-javascript/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>CSS Computed Style</title>
		<link>http://blog.stchur.com/2006/06/21/css-computed-style/</link>
		<comments>http://blog.stchur.com/2006/06/21/css-computed-style/#comments</comments>
		<pubDate>Wed, 21 Jun 2006 20:44:22 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2006/06/21/css-computed-style/</guid>
		<description><![CDATA[	Programmers who are new to javascript are often delighted to discover that it&#039;s remarkably easy to modify the style of some existing DOM element, like so:
	
var myDiv = document.getElementById&#40;&#039;myDiv&#039;&#41;;
myDiv.style.left = &#039;10em&#039;;
myDiv.style.backgroundColor = &#039;#369&#039;;
	The above code snippet will grab a reference to the element on the page whose id is myDiv, and modify that element&#039;s .left [...]]]></description>
			<content:encoded><![CDATA[	<p>Programmers who are new to javascript are often delighted to discover that it&#039;s remarkably easy to modify the style of some existing DOM element, like so:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> myDiv = document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&#039;myDiv&#039;</span><span class="br0">&#41;</span>;<br />
myDiv.<span class="me1">style</span>.<span class="me1">left</span> = <span class="st0">&#039;10em&#039;</span>;<br />
myDiv.<span class="me1">style</span>.<span class="me1">backgroundColor</span> = <span class="st0">&#039;#369&#039;</span>;</div>
	<p>The above code snippet will grab a reference to the element on the page whose id is <code>myDiv</code>, and modify that element&#039;s <code>.left</code> css property to &#039;10em&#039; and its <code>.backgroundColor</code> css property to &#039;#369&#039;.  Nothing earth-shattering here.</p>
	<p>Conversely, javascript programmers are often dismayed that the following <em>may</em> or <em>may not</em> work:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> myDiv = document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&#039;myDiv&#039;</span><span class="br0">&#41;</span>;<br />
myDiv.<span class="me1">style</span>.<span class="me1">top</span> = parseInt<span class="br0">&#40;</span>myDiv.<span class="me1">style</span>.<span class="me1">top</span><span class="br0">&#41;</span> + <span class="nu0">100</span> + <span class="st0">&#039;px&#039;</span>;</div>
	<p>Notice that I said <em>may</em> or <em>may not</em> work.  In what cases will it work and it what cases won&#039;t it work?  Glad you asked (because the answer is easy).  Read on to learn more.</p>
	<p><span id="more-10"></span></p>
	<p>Trying to retrieve the a css style property via javascript will only work when that style property has <em>previously been set</em> via javascript OR when that style property was defined inline by using the <code>style</code> attribute in (X)HTML.  Now this doesn&#039;t do you much good if you <em>haven&#039;t</em> first set said css property in javascript (and I certianly hope <em>no one</em> is using inline css styles), and you still want to retrieve it via javascript.</p>
	<p>Enter Computed Style.</p>
	<p>What is computed style exactly?  Well, according to IE, nothing at all.  IE (not surprisingly) doesn&#039;t support the W3C DOM standard for retrieving an element&#039;s computed style.  IE instead uses a proprietary <code>.currentStyle</code> property.  Once you&#039;re familiar with both implementations though, writing a cross-browser solution isn&#039;t too difficult.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw1">if</span> <span class="br0">&#40;</span>!window.<span class="me1">sstchur</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> window.<span class="me1">sstchur</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>!sstchur.<span class="me1">web</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> sstchur.<span class="me1">web</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span><br />
<span class="kw1">if</span> <span class="br0">&#40;</span>!sstchur.<span class="me1">web</span>.<span class="me1">xb</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> sstchur.<span class="me1">web</span>.<span class="me1">xb</span> = <span class="br0">&#123;</span><span class="br0">&#125;</span>; <span class="br0">&#125;</span></p>
	<p>sstchur.<span class="me1">web</span>.<span class="me1">xb</span>.<span class="me1">getComputedStyle</span> = <span class="kw2">function</span><span class="br0">&#40;</span>_elem, _style<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; <span class="kw2">var</span> computedStyle;<br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _elem.<span class="me1">currentStyle</span> != <span class="st0">&#039;undefined&#039;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> computedStyle = _elem.<span class="me1">currentStyle</span>; <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> computedStyle = document.<span class="me1">defaultView</span>.<span class="me1">getComputedStyle</span><span class="br0">&#40;</span>_elem, <span class="kw2">null</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; <span class="kw1">return</span> computedStyle<span class="br0">&#91;</span>_style<span class="br0">&#93;</span>;<br />
<span class="br0">&#125;</span></div>
	<p>This function isn&#039;t too hard to think about.  We start by checking for the existence of IE&#039;s proprietary <code>.currentStyle</code> property.  This violates my normal rule of always trying for W3C properties first, but since the namespace chain for <code>.currentStyle</code> is shorter, it requires less type checking (<code>document.defaultView</code> would fail in IE as would <code>document.default.getComputedStyle</code>).</p>
	<p>Once we&#039;ve determined what browser capabilities we&#039;re dealing with, we go head and assign the proper value to the variable, <code>computedStyle</code>.  At the end of the function we simply return computedStyle[_style].</p>
	<div class = "note">
	<p>I learned the following tip (and the majority of the above as well) from &#034;The Javascript Anthology&#034; by James Edwards &amp; Cameron Adams:</p>
	<p>It&#039;s important to be aware of browser inconsistencies with regards to computed style.  Where most W3C browser&#039;s will normalize all property units, IE will return them just as they were originally defined in your stylesheet.</p>
	<p>For example, retrieving the computed style of <code>width: 10em;</code> in a W3C browser will yield the equivalent value in pixels.  In IE, it will return &#039;10em&#039;.</p>
	<p>Similarly, hex color values in W3C browsers will be converted to equivalent rgb(x, x, x) values.</p>
	</div>
	<p>Being able to retrieve a css style property value as it was initially set in a stylesheet is a useful thing indeed.  A  basic understanding of computed style and the cross-browser function we developed in this blog entry should go a long way towards solving the some of the problems that were discussed at the beginning of this entry.</p>
	<p>Also, if you&#039;re interested in finding the height or the width of an item (including borders and padding), you&#039;re better served with <code>myElem.offsetHeight</code> and <code>myElem.offsetWidth</code>.  Those properties will return an integer representing the height or width of the the element (in pixels), and it&#039;s best to stick with those properties (as opposed to using the computed style) if you need height and/or width.</p>
	<p>As a final note, it&#039;s important to realize that retrieving the <code>.top</code> and <code>.left</code> style properties of some element on the page, using our cross-browser <code>getComputedStyle(..)</code> function is <em>not</em> the same as computing an element&#039;s absolute position on the page.  The former is simply returning a value that was previously set on said style property, while the latter is actually calculating an element&#039;s position (sometimes via recursion, sometimes simply by looping).  If you&#039;re wondering how to calculate an element&#039;s position on the page, well&#8230; that&#039;s another blog entry <img src='http://blog.stchur.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
	<p>But feel free to send comments about <em>this</em> blog entry!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2006/06/21/css-computed-style/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
