<?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>Webmonkey &#187; wiki</title>
    <atom:link href="http://www.webmonkey.com/tag/wiki/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Fri, 05 Apr 2013 20:20:46 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.4.2</generator>
    
    <item>
        <title>Ajax for Beginners</title>
        <link>http://www.webmonkey.com/2010/02/ajax_for_beginners/</link>
        <comments>http://www.webmonkey.com/2010/02/ajax_for_beginners/#comments</comments>
        <pubDate>Wed, 17 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=775</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --></p><p>JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, &#8220;I want my site to do that!&#8221; But it also has to do with the spiffy, spiffy name given to it by the folks at AdaptivePath, who named this asynchronized application <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" class="external text" title="http://www.adaptivepath.com/publications/essays/archives/000385.php" rel="nofollow">Ajax</a>. Maybe you&#8217;ve heard of it?

</p><p>A few high-profile Google applications in particular made a splash with Ajax: <a href="http://maps.google.com/" class="external text" title="http://maps.google.com/" rel="nofollow">Maps</a> and <a href="http://gmail.google.com/gmail" class="external text" title="http://gmail.google.com/gmail" rel="nofollow">Gmail</a> were first. It also powers some of the core functionality in the user interface of the ever-so-popular photo sharing site <a href="http://www.flickr.com" class="external text" title="http://www.flickr.com" rel="nofollow">Flickr</a>. By now, Ajax has become integral to the fabric of the web, especially in the era of real-time applications like <a href="http://www.twitter.com">Twitter</a>, <a href="http://www.google.com/buzz">Buzz</a> and <a href="http://www.google.com/wave">Wave</a> (all of which use Ajax extensively in their webapp front ends, for the record). Ajax may also lay claim to being the first JavaScript object with its own <a href="http://www.ajaxian.com/" class="external text" title="http://www.ajaxian.com/" rel="nofollow">fan website</a>. Date.com doesn&#8217;t count, although I did have a scintillating chat with a lady there once about the getTimeZoneoffset method.



</p><span id="more-775"></span><p><br />

</p>

<a name="What_is_Ajax.3F"></a><h3> <span class="mw-headline">What is Ajax?</span></h3>

<p>So what is this fancy object that everybody wants a piece of? In brief, it&#8217;s a solution to one of the big annoyances of web interfaces. Generally, the user inputs some data or makes a choice, and clicks a button that sends the data to the server. The server takes a look at the data and sends back a whole new web page, which is loaded into the browser. Reloading a page every time you want to do something is annoying, disjunctive and time-consuming for the user. XMLHttpRequest moves that browser-server interaction to behind the scenes, so the user can just keep on playing with the same page, even while elements on the page are talking to the server! Go take a look at <a href="http://www.google.com/webhp?complete=1" class="external text" title="http://www.google.com/webhp?complete=1" rel="nofollow">Google Suggest</a> if I&#8217;ve lost you &#8212; it&#8217;s a nice, eloquent example of this.

</p><p>JavaScript has always been able to sneakily trigger a server-side script without anything happening in the browser by using a few classic tricks. This one, for example:<tt>onSubmit='runascript = new Image(); runascript.src="<a href="http://www.wired.com/images/archiveyscript.php" class="external free" title="http://www.wired.com/images/archiveyscript.php" rel="nofollow">http://www.wired.com/images/archiveyscript.php</a>?" + this.value'</tt>. That sort of chicanery is good, maybe, for caching form data to a file on the server, but it doesn&#8217;t return any information to the JavaScript that calls it, so its usefulness is limited. Ajax, on the other hand, can get a full parcel of data back from the script it calls. Hence the &#8220;XML&#8221; part of the name  &#8211;  which really is just there for looks, kind of like the &#8220;Java&#8221; part of JavaScript, because the returned data can be plain text or whatever you like, if XML is overkill or just not your cup of tea.

</p><p>This opens up millions of exciting possibilities. Every form submission, every JavaScript event, and heaven knows what else, can now interact with server-side databases and processing power. Data retrieval, password authentication, image generation &#8211;  you name it, Ajax can trigger it.

</p>

<a name="Making_Your_Own"></a><h3> <span class="mw-headline">Making Your Own</span></h3>



<p>The potential of Ajax-enhanced web apps is limited only by your imagination &#8211;  and by browser support. Mozilla-based browsers can do it, and Safari, and newer versions of Explorer, and Opera 8 but not Opera 7. It&#8217;s best to incorporate a fallback way of doing things for users who aren&#8217;t as cutting edge as you&#8217;d like them to be. Also, Explorer does things somewhat differently (of course) from all the other browsers, so it&#8217;s necessary to fork the code to account for the irritating little 80-odd percent of the population who use IE.

</p><p>Let&#8217;s build a simple application that accepts input from the user, passes it to some PHP on the server that checks it against a database, and returns the result to the browser. It comes in three parts. First, we need an HTML form. This you&#8217;ve seen before:

</p><p><br />

</p>

 <pre class="brush: js">&lt;html&gt;

 &lt;head&gt;

 &lt;title&gt;Report&lt;/title&gt;

 &lt;script type='text/javascript' src='xhr.js'&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;form action="fallbackpage.php" method="post"&gt;



 &lt;p&gt;Welcome, student. Please enter your essay here:&lt;textarea name="essay" id="essay"&gt;

 &lt;/textarea&gt; &lt;input type="submit" name="submit" value="Submit" onClick="return

 grade(this.form.essay.value);"&gt;

 &lt;/p&gt;

 &lt;/form&gt;

 &lt;/body&gt;



 &lt;/html&gt;

</pre>

<p><br />

Note that, for users without support for our script (named xhr.js), the form will just submit to the fallback page at fallbackpage.php.

</p><p>Next comes the JavaScript. This is the exciting part, so we&#8217;ll take it slow.

</p>

 <pre class="brush: js"> function grade(essay) {

 </pre>

<p>First, we initialize the object. We have to do it two ways, for different browsers.

</p><p><br />

</p>

 <pre class="brush: js">    // Mozilla version

    if (window.XMLHttpRequest) {

        xhr = new XMLHttpRequest();

    }

    // IE version

    else if (window.ActiveXObject) {

        xhr = new ActiveXObject("Microsoft.XMLHTTP");

    }

 </pre>



<p>Then, we escape the user input to make it URL-safe:

</p>

 <pre class="brush: js">    essay=encodeURIComponent(essay);

 </pre>

<p>and use the <tt>open</tt> method of the object to open a connection to the PHP script:

</p>

 <pre class="brush: js">    xhr.open("POST","grade.php");

 </pre>

<p>The method requires two arguments:first, the HTTP method (GET or POST); second, the URL of the script.

</p><p>A quick HTTP header prepares the script for what it&#8217;s getting, and then the <tt>send</tt> method transmits the actual request:



</p>

 <pre class="brush: js"> xhr.setRequestHeader(

      'Content-Type',

      'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(essay); </pre>

<p>This last step isn&#8217;t necessary for GET requests, wherein all the data can be contained in the query string of the URL.

</p><p><br />

</p>

<a name="Getting_Results"></a><h3> <span class="mw-headline">Getting Results</span></h3>

<p>Now we&#8217;re ready to see if the HTTP request worked. The <tt>readyState</tt> property counts up from zero during the request, and shows 4 when the server page has loaded successfully.

</p>

 <pre class="brush: js"> xhr.onreadystatechange=function() {

      if (xhr.readyState==4) {

 </pre>



<p>If the request worked, then we can get the output of the server-side script by querying the <tt>responseText</tt> property, which contains a string. For more complex server script output, a <tt>responseXML</tt> property, which can hold a full document object of XML data, is also available.

</p>

 <pre class="brush: js">      grade = xhr.responseText;

      alert ("Nice essay. Your grade is " + grade);

    }

    return false;

 }

 </pre>

<p>Want to see all that in a pastable block? Here it is in a <a href="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/Ajax_for_Beginners_code1.html" rel="nofollow">separate file</a>.

</p><p>Finally, the third component is the PHP script, which lives on the server and waits patiently for the JavaScript to pass it some juicy data. This example uses PHP, but any language you like &#8212; Ruby, Perl, C, ASP &#8212; can do as well. The core of this example script is a natural-language function called <tt>grade_essay()</tt> that grades student essays from 1 to 100, but I will redact that part to conserve space.



</p>

 <pre class="brush: js"> &lt;?php

 function grade_essay($essay) {

      return strlen($essay);

 }

 $essay = urldecode(implode(file('php://input')));

 $grade = grade_essay($essay);

 echo $grade;

 ?&gt;



 </pre>

<p>The <tt>php://input</tt> grabs the POST data, which gets put into a string, decoded and passed to the ingenious grading algorithm. The algorithm returns a numeric grade. Lastly, we just output the grade with <tt>echo</tt>  &#8211;  ordinarily, this would display in the browser, but since the PHP script is running &#8220;behind the scenes,&#8221; the string output is simply returned to the JavaScript that called it. If you need structured data, an XML document would be output with an <tt>echo</tt> statement in just the same way, but the content-type of the output page must be set to <tt>text/xml</tt>.



</p><p>What the user sees is this:She types her essay into the text area in the browser, clicks Submit, and within instants an alert box pops up giving her a final grade on the essay. Invisibly, the essay has been sent to the server, read and evaluated by a team of PHP gnomes, and returned with a grade, without ever reloading the page. The user can modify her essay and resubmit it endlessly.

</p><p>And that&#8217;s the gist of the almost magical XMLHttpRequest object! The example is simple, but the uses of the object can be elaborately, multifariously clever. If you need further inspiration and edification, a burgeoning number of examples are dotted around the Web:

</p>

<ul><li> Ajax-powered start pages like <a href="http://www.google.com/ig" class="external text" title="http://www.google.com/ig" rel="nofollow">iGoogle</a>, <a href="http://www.pageflakes.com/" class="external text" title="http://www.pageflakes.com/" rel="nofollow">Pageflakes</a> and <a href="http://www.netvibes.com/" class="external text" title="http://www.netvibes.com/" rel="nofollow">Netvibes</a>

</li></ul>

<ul><li> Social news site <a href="http://digg.com" class="external text" title="http://digg.com" rel="nofollow">Digg</a>



</li></ul>

<ul><li> Movie rentals site <a href="http://www.netflix.com" class="external text" title="http://www.netflix.com" rel="nofollow">Netflix</a>

</li></ul>

<p><br />

But what data you send and receive with Ajax is up to you.

</p><p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/ajax_for_beginners/feed/</wfw:commentRss>
        <slash:comments>8</slash:comments>

        
    </item>
    
    <item>
        <title>Bit Depth</title>
        <link>http://www.webmonkey.com/2010/02/bit_depth/</link>
        <comments>http://www.webmonkey.com/2010/02/bit_depth/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=50</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[Multimedia]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Bit depth describes the file size of an image by orders of magnitude. When wrangling with file size versus image quality, it&#8217;s often important to minimize the bit depth of an image while maximizing the number of colors. To calculate the maximum number of colors for an image of a particular bit depth, remember that [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Bit depth describes the file size of an image by orders of magnitude.

</p><p>When wrangling with file size versus image quality, it&#8217;s often important to minimize the bit depth of an image while maximizing the number of colors. To calculate the maximum number of colors for an image of a particular bit depth, remember that the number of colors is equal to two to the power of what the bit depth is. For example, a GIF can support up to eight bits per pixel, and therefore can have as a many as 256 colors, since two to the power of eight equals 256.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/bit_depth/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Event</title>
        <link>http://www.webmonkey.com/2010/02/event/</link>
        <comments>http://www.webmonkey.com/2010/02/event/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=120</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[UI/UX]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Events are user interactions with their computer, such as a mouse click or key press. In the good ol&#8217; days, computers handled user interactions as input of batched data. The user fed a hunk of data in, the computer did something to that data, then produced the results. With the advent of interactive devices like [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Events are user interactions with their computer, such as a mouse click or key press.

</p><p>In the good ol&#8217; days, computers handled user interactions as input of batched data. The user fed a hunk of data in, the computer did something to that data, then produced the results. With the advent of interactive devices like the GUI interface, computers could display answers to computations onscreen. The input for these interactions are events caused by the user, which could be keystrokes, button clicks, or the position of the mouse pointer.

(see <a href="/special?title=Event_Handler&amp;action=edit" class="new" title="Event Handler">Event Handler</a>).

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/event/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>Loop</title>
        <link>http://www.webmonkey.com/2010/02/loop/</link>
        <comments>http://www.webmonkey.com/2010/02/loop/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=195</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[A loop is like a programming thought. Say you&#8217;re a police officer using a radar gun to catch speeding motorists. If the speed limit is 55 miles per hour, you might say to yourself: &#8220;If a car makes my radar gun display a higher value than 55, I&#8217;ll pull them over, but until then I [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>A loop is like a programming thought. Say you&#8217;re a police officer using a radar gun to catch speeding motorists. If the speed limit is 55 miles per hour, you might say to yourself: &#8220;If a car makes my radar gun display a higher value than 55, I&#8217;ll pull them over, but until then I will continue to take readings. And perhaps snack on this cruller.&#8221; In programming, the statement of this loop would be the action (firing up your motorcycle and chasing the speeder), and the expression would be the evaluation of whether or not the passing car made your radar gun read higher than 55. This is an example of a &#8220;while&#8221; loop:

</p>

<pre class="brush: js">  while (carSpeed &lt; 55) {

  carSpeed = readRadar();

  // note:readRadar() should return the latest carSpeed

}



pullEmOver();  // this will only execute once carSpeed is &gt;= 55

</pre><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/loop/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>Outline Font</title>
        <link>http://www.webmonkey.com/2010/02/outline_font/</link>
        <comments>http://www.webmonkey.com/2010/02/outline_font/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=260</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Fonts]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[An outline font supplies a geometrical description of each character so that the font can be rendered in a variety of sizes. Since they are scalable, outline fonts can make the most of an output device&#8217;s resolution. The greater the resolution of the monitor, the sharper the characters will look. Popular languages for defining outline [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p><br />

An outline font supplies a geometrical description of each character so that the <a href="/2010/02/Font" title="Reference:Font">font</a> can be rendered in a variety of sizes. Since they are scalable, outline fonts can make the most of an output device&#8217;s resolution. The greater the resolution of the monitor, the sharper the characters will look. Popular languages for defining outline fonts are PostScript and TrueType.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/outline_font/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Segmentation</title>
        <link>http://www.webmonkey.com/2010/02/segmentation/</link>
        <comments>http://www.webmonkey.com/2010/02/segmentation/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=326</guid>
        		<category><![CDATA[Glossary]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Akin to the notion &#8220;divide and conquer,&#8221; segmentation is marketingspeak for breaking your audience down into definable subcategories. For instance, Coca-Cola may segment its audience based on frequency (one can a month or five cans a day), location (Bangkok or Bangladesh), and many other criteria. On the web, segmentation is useful not just to marketers [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Akin to the notion &#8220;divide and conquer,&#8221; segmentation is marketingspeak for breaking your audience down into definable subcategories. For instance, Coca-Cola may segment its audience based on frequency (one can a month or five cans a day), location (Bangkok or Bangladesh), and many other criteria. On the web, segmentation is useful not just to marketers but to site designers as well, since the segments we track &#8211; IE vs. Mozilla, first-timer vs. repeat visitor, domestic vs. international &#8211; shape the way we develop and deploy our websites.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/segmentation/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Color Charts</title>
        <link>http://www.webmonkey.com/2010/02/color_charts/</link>
        <comments>http://www.webmonkey.com/2010/02/color_charts/#comments</comments>
        <pubDate>Mon, 15 Feb 2010 20:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=397</guid>
        		<category><![CDATA[Cheat Sheets]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[When you&#8217;re adding a color to your web page with HTML, sometimes you can just type in the name of the color. But more often than not, you&#8217;ll need to use what&#8217;s called the hex code, which is something that the browser will be able to understand. Choose a color from the list below and [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p><br />

When you&#8217;re adding a color to your web page with HTML, sometimes you can just type in the name of the color. But more often than not, you&#8217;ll need to use what&#8217;s called the hex code, which is something that the browser will be able to understand. Choose a color from the list below and look to its left to get the hex code. If we wanted our background to be red, for example, we&#8217;d type <font color="#FF0000">bgcolor=&#8221;#FF0000&#8243;</font>. <font>Try it out!</font>
<p>
</p><br />
<span id="more-397"></span>

<a name="Colors"></a><h2> <span class="mw-headline">Colors</span></h2>

<table>

<tbody><tr>

<td valign="top">



<table id="sortable_table_id_0" class="color_table sortable" cellpadding="2" cellspacing="2" width="100%">

<tbody><tr class="even">

<td bgcolor="#eceae1"> <b>Hex Code</b>

&nbsp;

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

&nbsp;

</td></tr>

<tr class="odd">

<td> #FFFFFF

</td><td bgcolor="#ffffff">

</td></tr>

<tr class="even">

<td> #FFFFCC



</td><td bgcolor="#ffffcc">

</td></tr>

<tr class="odd">

<td> #FFFF99

</td><td bgcolor="#ffff99">

</td></tr>

<tr class="even">

<td> #FFFF66

</td><td bgcolor="#ffff66">

</td></tr>

<tr class="odd">

<td> #FFFF33

</td><td bgcolor="#ffff33">

</td></tr>



<tr class="even">

<td> #FFFF00

</td><td bgcolor="#ffff00">

</td></tr>

<tr class="odd">

<td> #FFCCFF

</td><td bgcolor="#ffccff">

</td></tr>

<tr class="even">

<td> #FFCCCC

</td><td bgcolor="#ffcccc">

</td></tr>

<tr class="odd">

<td> #FFCC99



</td><td bgcolor="#ffcc99">

</td></tr>

<tr class="even">

<td> #FFCC66

</td><td bgcolor="#ffcc66">

</td></tr>

<tr class="odd">

<td> #FFCC33

</td><td bgcolor="#ffcc33">

</td></tr>

<tr class="even">

<td> #FFCC00

</td><td bgcolor="#ffcc00">

</td></tr>



<tr class="odd">

<td> #FF99FF

</td><td bgcolor="#ff99ff">

</td></tr>

<tr class="even">

<td> #FF99CC

</td><td bgcolor="#ff99cc">

</td></tr>

<tr class="odd">

<td> #FF9999

</td><td bgcolor="#ff9999">

</td></tr>

<tr class="even">

<td> #FF9966



</td><td bgcolor="#ff9966">

</td></tr>

<tr class="odd">

<td> #FF9933

</td><td bgcolor="#ff9933">

</td></tr>

<tr class="even">

<td> #FF9900

</td><td bgcolor="#ff9900">

</td></tr>

<tr class="odd">

<td> #FF66FF

</td><td bgcolor="#ff66ff">

</td></tr>



<tr class="even">

<td> #FF66CC

</td><td bgcolor="#ff66cc">

</td></tr>

<tr class="odd">

<td> #FF66CC

</td><td bgcolor="#ff66cc">

</td></tr>

<tr class="even">

<td> #FF6666

</td><td bgcolor="#ff6666">

</td></tr>

<tr class="odd">

<td> #FF6633



</td><td bgcolor="#ff6633">

</td></tr>

<tr class="even">

<td> #FF6600

</td><td bgcolor="#ff6600">

</td></tr>

<tr class="odd">

<td> #FF33FF

</td><td bgcolor="#ff33ff">

</td></tr>

<tr class="even">

<td> #FF33CC

</td><td bgcolor="#ff33cc">

</td></tr>



<tr class="odd">

<td> #FF3399

</td><td bgcolor="#ff3399">

</td></tr>

<tr class="even">

<td> #FF3399

</td><td bgcolor="#ff3399">

</td></tr>

<tr class="odd">

<td> #FF3333

</td><td bgcolor="#ff3333">

</td></tr>

<tr class="even">

<td> #FF3300



</td><td bgcolor="#ff3300">

</td></tr>

<tr class="odd">

<td> #FF00FF

</td><td bgcolor="#ff00ff">

</td></tr>

<tr class="even">

<td> #FF00CC

</td><td bgcolor="#ff00cc">

</td></tr>

<tr class="odd">

<td> #FF0099

</td><td bgcolor="#ff0099">

</td></tr>



<tr class="even">

<td> #FF0066

</td><td bgcolor="#ff0066">

</td></tr>

<tr class="odd">

<td> #FF0033

</td><td bgcolor="#ff0033">

</td></tr>

<tr class="even">

<td> #FF0000

</td><td bgcolor="#ff0000">

</td></tr>

<tr class="odd">

<td> <br />



</td></tr>

<tr class="even">

<td bgcolor="#eceae1"> <b>Hex Code</b>

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

</td></tr>

<tr class="odd">

<td> #66FFFF

</td><td bgcolor="#66ffff">

</td></tr>

<tr class="even">

<td> #66FFCC



</td><td bgcolor="#66ffcc">

</td></tr>

<tr class="odd">

<td> #66FF99

</td><td bgcolor="#66ff99">

</td></tr>

<tr class="even">

<td> #66FF66

</td><td bgcolor="#66ff66">

</td></tr>

<tr class="odd">

<td> #66FF33

</td><td bgcolor="#66ff33">

</td></tr>



<tr class="even">

<td> #66FF00

</td><td bgcolor="#66ff00">

</td></tr>

<tr class="odd">

<td> #66CCFF

</td><td bgcolor="#66ccff">

</td></tr>

<tr class="even">

<td> #66CCCC

</td><td bgcolor="#66cccc">

</td></tr>

<tr class="odd">

<td> #66CC99



</td><td bgcolor="#66cc99">

</td></tr>

<tr class="even">

<td> #66CC66

</td><td bgcolor="#66cc66">

</td></tr>

<tr class="odd">

<td> #66CC33

</td><td bgcolor="#66cc33">

</td></tr>

<tr class="even">

<td> #66CC00

</td><td bgcolor="#66cc00">

</td></tr>



<tr class="odd">

<td> #6699FF

</td><td bgcolor="#6699ff">

</td></tr>

<tr class="even">

<td> #6699CC

</td><td bgcolor="#6699cc">

</td></tr>

<tr class="odd">

<td> #669999

</td><td bgcolor="#669999">

</td></tr>

<tr class="even">

<td> #669966



</td><td bgcolor="#669966">

</td></tr>

<tr class="odd">

<td> #669933

</td><td bgcolor="#669933">

</td></tr>

<tr class="even">

<td> #669900

</td><td bgcolor="#669900">

</td></tr>

<tr class="odd">

<td> #6666FF

</td><td bgcolor="#6666ff">

</td></tr>



<tr class="even">

<td> #6666CC

</td><td bgcolor="#6666cc">

</td></tr>

<tr class="odd">

<td> #666699

</td><td bgcolor="#666699">

</td></tr>

<tr class="even">

<td> #666666

</td><td bgcolor="#666666">

</td></tr>

<tr class="odd">

<td> #666633



</td><td bgcolor="#666633">

</td></tr>

<tr class="even">

<td> #666600

</td><td bgcolor="#666600">

</td></tr>

<tr class="odd">

<td> #6633FF

</td><td bgcolor="#6633ff">

</td></tr>

<tr class="even">

<td> #6633CC

</td><td bgcolor="#6633cc">

</td></tr>



<tr class="odd">

<td> #663399

</td><td bgcolor="#663399">

</td></tr>

<tr class="even">

<td> #663366

</td><td bgcolor="#663366">

</td></tr>

<tr class="odd">

<td> #663333

</td><td bgcolor="#663333">

</td></tr>

<tr class="even">

<td> #663300



</td><td bgcolor="#663300">

</td></tr>

<tr class="odd">

<td> #6600FF

</td><td bgcolor="#6600ff">

</td></tr>

<tr class="even">

<td> #6600CC

</td><td bgcolor="#6600cc">

</td></tr>

<tr class="odd">

<td> #660099

</td><td bgcolor="#660099">

</td></tr>



<tr class="even">

<td> #660066

</td><td bgcolor="#660066">

</td></tr>

<tr class="odd">

<td> #660033

</td><td bgcolor="#660033">

</td></tr>

<tr class="even">

<td> #660000

</td><td bgcolor="#660000">

</td></tr></tbody></table>

</td><td valign="top">

<table class="color_table" cellpadding="2" cellspacing="2" width="100%">



<tbody><tr>

<td bgcolor="#eceae1"> <b>Hex Code</b>

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

</td></tr>

<tr>

<td> #CCFFFF

</td><td bgcolor="#ccffff">

</td></tr>

<tr>

<td> #CCFFCC

</td><td bgcolor="#ccffcc">



</td></tr>

<tr>

<td> #CCFF99

</td><td bgcolor="#ccff99">

</td></tr>

<tr>

<td> #CCFF66

</td><td bgcolor="#ccff66">

</td></tr>

<tr>

<td> #CCFF33

</td><td bgcolor="#ccff33">

</td></tr>

<tr>



<td> #CCFF00

</td><td bgcolor="#ccff00">

</td></tr>

<tr>

<td> #CCCCFF

</td><td bgcolor="#ccccff">

</td></tr>

<tr>

<td> #CCCCCC

</td><td bgcolor="#cccccc">

</td></tr>

<tr>

<td> #CCCC99



</td><td bgcolor="#cccc99">

</td></tr>

<tr>

<td> #CCCC66

</td><td bgcolor="#cccc66">

</td></tr>

<tr>

<td> #CCCC33

</td><td bgcolor="#cccc33">

</td></tr>

<tr>

<td> #CCCC00

</td><td bgcolor="#cccc00">

</td></tr>



<tr>

<td> #CC99FF

</td><td bgcolor="#cc99ff">

</td></tr>

<tr>

<td> #CC99CC

</td><td bgcolor="#cc99cc">

</td></tr>

<tr>

<td> #CC9999

</td><td bgcolor="#cc9999">

</td></tr>

<tr>

<td> #CC9966



</td><td bgcolor="#cc9966">

</td></tr>

<tr>

<td> #CC9933

</td><td bgcolor="#cc9933">

</td></tr>

<tr>

<td> #CC9900

</td><td bgcolor="#cc9900">

</td></tr>

<tr>

<td> #CC66FF

</td><td bgcolor="#cc66ff">

</td></tr>



<tr>

<td> #CC66CC

</td><td bgcolor="#cc66cc">

</td></tr>

<tr>

<td> #CC6699

</td><td bgcolor="#cc6699">

</td></tr>

<tr>

<td> #CC6666

</td><td bgcolor="#cc6666">

</td></tr>

<tr>

<td> #CC6633



</td><td bgcolor="#cc6633">

</td></tr>

<tr>

<td> #CC6600

</td><td bgcolor="#cc6600">

</td></tr>

<tr>

<td> #CC33FF

</td><td bgcolor="#cc33ff">

</td></tr>

<tr>

<td> #CC33CC

</td><td bgcolor="#cc33cc">

</td></tr>



<tr>

<td> #CC3399

</td><td bgcolor="#cc3399">

</td></tr>

<tr>

<td> #CC3366

</td><td bgcolor="#cc3366">

</td></tr>

<tr>

<td> #CC3333

</td><td bgcolor="#cc3333">

</td></tr>

<tr>

<td> #CC3300



</td><td bgcolor="#cc3300">

</td></tr>

<tr>

<td> #CC00FF

</td><td bgcolor="#cc00ff">

</td></tr>

<tr>

<td> #CC00CC

</td><td bgcolor="#cc00cc">

</td></tr>

<tr>

<td> #CC0099

</td><td bgcolor="#cc0099">

</td></tr>



<tr>

<td> #CC0066

</td><td bgcolor="#cc0066">

</td></tr>

<tr>

<td> #CC0033

</td><td bgcolor="#cc0033">

</td></tr>

<tr>

<td> #CC0000

</td><td bgcolor="#cc0000">

</td></tr>

<tr>

<td> <br />



</td></tr>

<tr>

<td bgcolor="#eceae1"> <b>Hex Code</b>

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

</td></tr>

<tr>

<td> #33FFFF

</td><td bgcolor="#33ffff">

</td></tr>

<tr>

<td> #33FFCC



</td><td bgcolor="#33ffcc">

</td></tr>

<tr>

<td> #33FF99

</td><td bgcolor="#33ff99">

</td></tr>

<tr>

<td> #33FF66

</td><td bgcolor="#33ff66">

</td></tr>

<tr>

<td> #33FF33

</td><td bgcolor="#33ff33">

</td></tr>



<tr>

<td> #33FF00

</td><td bgcolor="#33ff00">

</td></tr>

<tr>

<td> #33CCFF

</td><td bgcolor="#33ccff">

</td></tr>

<tr>

<td> #33CCCC

</td><td bgcolor="#33cccc">

</td></tr>

<tr>

<td> #33CC99



</td><td bgcolor="#33cc99">

</td></tr>

<tr>

<td> #33CC66

</td><td bgcolor="#33cc66">

</td></tr>

<tr>

<td> #33CC33

</td><td bgcolor="#33cc33">

</td></tr>

<tr>

<td> #33CC00

</td><td bgcolor="#33cc00">

</td></tr>



<tr>

<td> #3399FF

</td><td bgcolor="#3399ff">

</td></tr>

<tr>

<td> #3399CC

</td><td bgcolor="#3399cc">

</td></tr>

<tr>

<td> #339999

</td><td bgcolor="#339999">

</td></tr>

<tr>

<td> #339966



</td><td bgcolor="#339966">

</td></tr>

<tr>

<td> #339933

</td><td bgcolor="#339933">

</td></tr>

<tr>

<td> #339900

</td><td bgcolor="#339900">

</td></tr>

<tr>

<td> #3366FF

</td><td bgcolor="#3366ff">

</td></tr>



<tr>

<td> #3366CC

</td><td bgcolor="#3366cc">

</td></tr>

<tr>

<td> #336699

</td><td bgcolor="#336699">

</td></tr>

<tr>

<td> #336666

</td><td bgcolor="#336666">

</td></tr>

<tr>

<td> #336633



</td><td bgcolor="#336633">

</td></tr>

<tr>

<td> #336600

</td><td bgcolor="#336600">

</td></tr>

<tr>

<td> #3333FF

</td><td bgcolor="#3333ff">

</td></tr>

<tr>

<td> #3333CC

</td><td bgcolor="#3333cc">

</td></tr>



<tr>

<td> #333399

</td><td bgcolor="#333399">

</td></tr>

<tr>

<td> #333366

</td><td bgcolor="#333366">

</td></tr>

<tr>

<td> #333333

</td><td bgcolor="#333333">

</td></tr>

<tr>

<td> #333300



</td><td bgcolor="#333300">

</td></tr>

<tr>

<td> #3300FF

</td><td bgcolor="#3300ff">

</td></tr>

<tr>

<td> #3300CC

</td><td bgcolor="#3300cc">

</td></tr>

<tr>

<td> #330099

</td><td bgcolor="#330099">

</td></tr>



<tr>

<td> #330066

</td><td bgcolor="#330066">

</td></tr>

<tr>

<td> #330033

</td><td bgcolor="#330033">

</td></tr>

<tr>

<td> #330000

</td><td bgcolor="#330000">

</td></tr></tbody></table>

</td><td valign="top">

<table class="color_table" cellpadding="2" cellspacing="2" width="100%">



<tbody><tr>

<td bgcolor="#eceae1"> <b>Hex Code</b>

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

</td></tr>

<tr>

<td> #99FFFF

</td><td bgcolor="#99ffff">

</td></tr>

<tr>

<td> #99FFCC

</td><td bgcolor="#99ffcc">



</td></tr>

<tr>

<td> #99FF99

</td><td bgcolor="#99ff99">

</td></tr>

<tr>

<td> #99FF66

</td><td bgcolor="#99ff66">

</td></tr>

<tr>

<td> #99FF33

</td><td bgcolor="#99ff33">

</td></tr>

<tr>



<td> #99FF00

</td><td bgcolor="#99ff00">

</td></tr>

<tr>

<td> #99CCFF

</td><td bgcolor="#99ccff">

</td></tr>

<tr>

<td> #99CCCC

</td><td bgcolor="#99cccc">

</td></tr>

<tr>

<td> #99CC99



</td><td bgcolor="#99cc99">

</td></tr>

<tr>

<td> #99CC66

</td><td bgcolor="#99cc66">

</td></tr>

<tr>

<td> #99CC33

</td><td bgcolor="#99cc33">

</td></tr>

<tr>

<td> #99CC00

</td><td bgcolor="#99cc00">

</td></tr>



<tr>

<td> #9999FF

</td><td bgcolor="#9999ff">

</td></tr>

<tr>

<td> #9999CC

</td><td bgcolor="#9999cc">

</td></tr>

<tr>

<td> #999999

</td><td bgcolor="#999999">

</td></tr>

<tr>

<td> #999966



</td><td bgcolor="#999966">

</td></tr>

<tr>

<td> #999933

</td><td bgcolor="#999933">

</td></tr>

<tr>

<td> #999900

</td><td bgcolor="#999900">

</td></tr>

<tr>

<td> #9966FF

</td><td bgcolor="#9966ff">

</td></tr>



<tr>

<td> #9966CC

</td><td bgcolor="#9966cc">

</td></tr>

<tr>

<td> #996699

</td><td bgcolor="#996699">

</td></tr>

<tr>

<td> #996666

</td><td bgcolor="#996666">

</td></tr>

<tr>

<td> #996633



</td><td bgcolor="#996633">

</td></tr>

<tr>

<td> #996600

</td><td bgcolor="#996600">

</td></tr>

<tr>

<td> #9933FF

</td><td bgcolor="#9933ff">

</td></tr>

<tr>

<td> #9933CC

</td><td bgcolor="#9933cc">

</td></tr>



<tr>

<td> #993399

</td><td bgcolor="#993399">

</td></tr>

<tr>

<td> #993366

</td><td bgcolor="#993366">

</td></tr>

<tr>

<td> #993333

</td><td bgcolor="#993333">

</td></tr>

<tr>

<td> #993300



</td><td bgcolor="#993300">

</td></tr>

<tr>

<td> #9900FF

</td><td bgcolor="#9900ff">

</td></tr>

<tr>

<td> #9900CC

</td><td bgcolor="#9900cc">

</td></tr>

<tr>

<td> #990099

</td><td bgcolor="#990099">

</td></tr>



<tr>

<td> #990066

</td><td bgcolor="#990066">

</td></tr>

<tr>

<td> #990033

</td><td bgcolor="#990033">

</td></tr>

<tr>

<td> #990000

</td><td bgcolor="#990000">

</td></tr>

<tr>

<td> <br />



</td></tr>

<tr>

<td bgcolor="#eceae1"> <b>Hex Code</b>

</td><td bgcolor="#eceae1" width="85"> <b>Color</b>

</td></tr>

<tr>

<td> #00FFFF

</td><td bgcolor="#00ffff">

</td></tr>

<tr>

<td> #00FFCC



</td><td bgcolor="#00ffcc">

</td></tr>

<tr>

<td> #00FF99

</td><td bgcolor="#00ff99">

</td></tr>

<tr>

<td> #00FF66

</td><td bgcolor="#00ff66">

</td></tr>

<tr>

<td> #00FF33

</td><td bgcolor="#00ff33">

</td></tr>



<tr>

<td> #00FF00

</td><td bgcolor="#00ff00">

</td></tr>

<tr>

<td> #00CCFF

</td><td bgcolor="#00ccff">DeepSkyBlue

</td></tr>

<tr>

<td> #00CCCC

</td><td bgcolor="#00cccc">

</td></tr>

<tr>

<td> #00CC99



</td><td bgcolor="#00cc99">

</td></tr>

<tr>

<td> #00CC66

</td><td bgcolor="#00cc66">

</td></tr>

<tr>

<td> #00CC33

</td><td bgcolor="#00cc33">

</td></tr>

<tr>

<td> #00CC00

</td><td bgcolor="#00cc00">

</td></tr>



<tr>

<td> #0099FF

</td><td bgcolor="#0099ff">

</td></tr>

<tr>

<td> #0099CC

</td><td bgcolor="#0099cc">

</td></tr>

<tr>

<td> #009999

</td><td bgcolor="#009999">DarkCyan

</td></tr>

<tr>

<td> #009966



</td><td bgcolor="#009966">Teal

</td></tr>

<tr>

<td> #009933

</td><td bgcolor="#009933">

</td></tr>

<tr>

<td> #009900

</td><td bgcolor="#009900">Green

</td></tr>

<tr>

<td> #0066FF

</td><td bgcolor="#0066ff">

</td></tr>



<tr>

<td> #0066CC

</td><td bgcolor="#0066cc">

</td></tr>

<tr>

<td> #006699

</td><td bgcolor="#006699">

</td></tr>

<tr>

<td> #006666

</td><td bgcolor="#006666">

</td></tr>

<tr>

<td> #006633



</td><td bgcolor="#006633">

</td></tr>

<tr>

<td> #006600

</td><td bgcolor="#006600">Dark Green

</td></tr>

<tr>

<td> #0033FF

</td><td bgcolor="#0033ff">

</td></tr>

<tr>

<td> #0033CC

</td><td bgcolor="#0033cc">

</td></tr>



<tr>

<td> #003399

</td><td bgcolor="#003399">

</td></tr>

<tr>

<td> #003366

</td><td bgcolor="#003366">

</td></tr>

<tr>

<td> #003333

</td><td bgcolor="#003333">

</td></tr>

<tr>

<td> #003300



</td><td bgcolor="#003300">

</td></tr>

<tr>

<td> #0000FF

</td><td bgcolor="#0000ff">Blue

</td></tr>

<tr>

<td> #0000CC

</td><td bgcolor="#0000cc">Med. Blue

</td></tr>

<tr>

<td> #000099

</td><td bgcolor="#000099">Dark Blue

</td></tr>



<tr>

<td> #000066

</td><td bgcolor="#000066">Navy

</td></tr>

<tr>

<td> #000033

</td><td bgcolor="#000033">

</td></tr>

<tr>

<td> #000000

</td><td style="color: white;" bgcolor="#000000">Black

</td></tr></tbody></table>

</td></tr></tbody></table><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/color_charts/feed/</wfw:commentRss>
        <slash:comments>109</slash:comments>

        
    </item>
    
    <item>
        <title>Mulders Stylesheets Tutorial &#8211; Lesson 1</title>
        <link>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_1/</link>
        <comments>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_1/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=610</guid>
        		<category><![CDATA[UI/UX]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Building Web pages with HTML is like painting a portrait with a paint roller. Only truly determined and tenacious souls can achieve the exact result they want. It&#8217;s just not the right tool for precision and flexibility. Anyone who&#8217;s used HTML for more than a week knows it isn&#8217;t a very effective tool for making [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Building Web pages with HTML is like painting a portrait with a paint roller. Only truly determined and tenacious souls can achieve the exact result they want. It&#8217;s just not the right tool for precision and flexibility.

</p><p>Anyone who&#8217;s used HTML for more than a week knows it isn&#8217;t a very effective tool for making Web pages. That&#8217;s why we sometimes resort to making large GIFs when we want just the right font or layout. That&#8217;s why we&#8217;re forced to use convoluted table tags and invisible spacer GIFs to push things around on a page.

</p><p>It&#8217;s ridiculous, really. Our code gets too complicated, our GIFs too numerous, and our final pages too bandwidth-heavy. It&#8217;s not exactly optimal Web page construction.

</p><p>But in late 1996, stylesheets quietly entered the scene. Officially called cascading stylesheets (CSS), it was an elegant cousin to HTML that promised:

</p>

<ul><li> more precise control than ever before over layout, fonts, colors, backgrounds, and other typographical effects;

</li><li> a way to update the appearance and formatting of an unlimited number of pages by changing just one document;

</li><li> compatibility across browsers and platforms; and



</li><li> less code, smaller pages, and faster downloads.

</li></ul>

<p><br />

Despite lukewarm support from many of our favorite Web browsers, CSS is starting to make good on these promises. It&#8217;s transforming the way we make Web pages and is the cornerstone of Dynamic HTML.

</p><p>We&#8217;ll spend the next five lessons taking a tour through the land of stylesheets. You&#8217;ll learn the basics of how to create and use cascading stylesheets within your Web pages as well as what&#8217;s possible with fonts, typography, colors, backgrounds, and positioning.

</p><span id="more-610"></span><p>In Lesson 1, we&#8217;ll take a quick trip through the basics of stylesheets, giving you everything you need to get started quickly. Let&#8217;s begin by asking the most important question: What can stylesheets do for me today?

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#What_Can_Stylesheets_Do_for_Me_Today.3F">What Can Stylesheets Do for Me Today?</a></li>



<li><a href="#Your_First_Stylesheet">Your First Stylesheet</a></li>

<li><a href="#Adding_Styles">Adding Styles</a></li>

<li><a href="#Classes_and_Other_Tricks">Classes and Other Tricks</a></li>

<li><a href="#When_Stylesheets_Fight_It_Out">When Stylesheets Fight It Out</a></li>

<li><a href="#The_Bad_News_About_Browsers">The Bad News About Browsers</a></li>



<li><a href="#Review_of_Lesson_1">Review of Lesson 1</a></li>

</ol>

</td></tr></tbody></table>



<a name="What_Can_Stylesheets_Do_for_Me_Today.3F"></a><h4> <span class="mw-headline">What Can Stylesheets Do for Me Today?</span></h4>

<p>So what&#8217;s so special about stylesheets? In a nutshell:

</p>

<ul><li> You can separate form and structure.

</li><li> You can control layout like never before.

</li><li> You can make smaller, faster pages.

</li><li> You can maintain or update many pages at once, faster and easier than before.

</li><li> You can be browser friendly.

</li></ul>

<p><br />

Let&#8217;s look at each benefit.

</p><p><b>You can separate form and structure.</b>

</p><p>HTML was never meant to control the form or appearance of Web pages. It&#8217;s a language that defines the <i>structure</i> and function of elements on a page. It lets the Web browser decide how those elements should actually appear.

</p><p>But we perfectionist Web designers wanted more. So we rejoiced when Netscape invented new HTML tags that let us begin to control appearance. To make body text look the way we wanted, we surrounded the <tt>&lt;p&gt;</tt> with <tt>&lt;font face#62;</tt>, <tt>&lt;i&gt;</tt>, and so on. And then we put everything inside a nested table and used invisible spacer GIFs to push it over 20 pixels to create a margin. What a mess. Our code became convoluted, and it was harder and harder to create or move content to the Web quickly.



</p><p>Cascading stylesheets enable us to get more control the right way:by separating the part that defines structure from the part that defines form. The HTML remains clean and simple, as originally intended, and the CSS code controls appearances from afar.

</p><p><b>You can control layout like never before.</b>

</p><p>Sure, <tt>&lt;font size&gt;</tt> enabled us to resize text, and table tags helped us create margins. But overall, what we could do with HTML was very limited. We couldn&#8217;t create text exactly 80 pixels tall, we couldn&#8217;t specify margins easily, we couldn&#8217;t control the space between lines or words, we couldn&#8217;t precisely position images on the screen.

</p><p>Until now. Stylesheets make all these things possible and more. And the promise of what&#8217;s to come is even more exciting. In the next four lessons, you&#8217;ll see what I mean.

</p><p><b>You can make smaller, faster pages.</b>

</p><p>Here&#8217;s more good news: Stylesheets are simple text, just like HTML. There are no graphics, no executable program, no plug-ins, no streaming, no delays. It&#8217;s as fast as straight HTML code.

</p><p>And with CSS, you can do things that you previously had to resort to GIFs for. But wait, there&#8217;s more! As I mentioned earlier, cascading stylesheets also mean fewer table tags and other HTML hacks cluttering up your code. Less code and fewer graphics translate into smaller file sizes.

</p><p><b>You can maintain or update many pages faster and easier.</b>

</p><p>Without stylesheets, if I wanted to update the font used for body text across my entire site, I&#8217;d have to manually edit each page. Even if my site were served from a database, I&#8217;d still have to update all the templates, and within each template, I&#8217;d have to change every single instance of good ol&#8217; <tt>&lt;font size&gt;</tt>.



</p><p>The whole point of stylesheets is to separate form and structure. With stylesheets, I can have all the pages on my site point to a single CSS document. If I want to change the body text, all I do is change one line in this stylesheets document, and the <i>entire</i> site instantly changes.

</p><p><b>You can be browser friendly.</b>

</p><p>Unlike some other Web technologies I could name, CSS code degrades gracefully. That is, users don&#8217;t get a glaring broken icon if they&#8217;re missing a plug-in or code gibberish if they&#8217;re using an older browser. Browsers that recognize cascading stylesheets use it. Browsers that don&#8217;t recognize CSS simply ignore it.

</p><p>Are you convinced that stylesheets are a good idea? OK, then let&#8217;s create one.

</p>

<a name="Your_First_Stylesheet"></a><h4> <span class="mw-headline">Your First Stylesheet</span></h4>

<p>It&#8217;s about time we get to the good stuff! Launch your favorite HTML editor and create a basic Web page:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;



&lt;title&gt;My First Stylesheet&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Stylesheets:The Tool of the Web Design Gods&lt;/h1&gt;

&lt;p&gt;Amaze your friends! Squash your enemies!&lt;/p&gt;

&lt;/body&gt;



&lt;/html&gt;

</pre>

<p>Very fancy. Now let&#8217;s add some stylesheets. Simply insert the following code anywhere within the <tt>&lt;HEAD&lt;/HEAD&gt;</tt> tag:

</p>

<pre class="brush: js">&lt;style type="text/css"&gt;

&lt;!--

h1 { color: green; font-size: 37px; font-family: impact }

p { text-indent: 1cm; background: yellow; font-family: courier }

--&gt;

&lt;/style&gt;

</pre>

<p>Open the page in your browser, and here&#8217;s what you&#8217;ll see:



</p>

<div style="color: green; font-size: 37px; font-family: impact; line-height: 40px;">Stylesheets:The Tool of the Web Design Gods</div>

<p><br />

</p>

<div style="background: yellow none repeat scroll 0%; text-indent: 1cm; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-family: courier;">Amaze your friends! Squash your enemies!</div>

<p><br />

Congratulations! You just created your first stylesheets-enhanced Web page.

</p><p>(If the &#8220;Amaze your friends!&#8221; line doesn&#8217;t have yellow behind it, then you&#8217;ll need to update your browser or you won&#8217;t be able to complete this tutorial. Netscape Communicator or Internet Explorer, version 4 or higher, is recommended.)

</p><p><b>Some Terminology</b>

</p><p>Let&#8217;s look at what&#8217;s going on in this newfangled code. At the core of cascading stylesheets are rules. The simplest kind of rule looks like this:

</p><p>This rule tells the Web browser that all text surrounded by <tt>&lt;h1&gt;&lt;/h1&gt;</tt> should be displayed in green.



</p><p>Each rule consists of a selector and a declaration. In the example above, <tt>h1</tt> is the selector. It&#8217;s the HTML tag that the style is being attached to. The declaration defines what the style actually is, and it also consists of two parts:the property (in this case, <tt>color</tt>) and the value (<tt>green</tt>).

</p><p>Any HTML tag can be used as a selector. Thus, you can attach stylesheet information to any kind of element, from normal <tt>&lt;p&gt;</tt> text to <tt>&lt;code&gt;</tt> and <tt>&lt;table&gt;</tt> content. You can even use some cascading stylesheet properties on graphics by applying them to <tt>&lt;img&gt;</tt>.



</p><p>And as you can see from our first stylesheets example, you can also group rules together. Earlier, we set three different declarations all at once for <tt>&lt;p&gt;</tt>.

</p><p>Similarly, you can group selectors:

</p><p>This rule specifies that all text within <tt>&lt;h1&gt;</tt>, <tt>&lt;p&gt;</tt>, and <tt>&lt;blockquote&gt;</tt> tags will display in the Arial font.

</p><p><b>Inheritance</b>

</p><p>Stylesheets rules are inherited from &#8220;parent&#8221; to &#8220;child.&#8221; Let&#8217;s look at an example:

<pre class="brush: js">
b { color: blue }
</pre>

</p><p>This rule tells the browser that all text within <tt>&lt;b&gt;</tt> should be blue. But what does the browser do in the following situation?</p>

<pre class="brush: js">
&lt;b&gt;All my web pages will use cascading stylesheets within &lt;i>four&lt;/i> weeks.&lt;/b&gt;
</pre>

</p><p>There&#8217;s no rule set for the <tt>&lt;i&gt;</tt> tag. But since here it occurs within the <tt>&lt;b&gt;</tt>, it inherits the latter&#8217;s declarations. So, the child displays in blue, just like its parent:

</p><p><b><font color="blue">All my web pages will use cascading stylesheets within <i>four</i> weeks.</font></b>

</p><p>OK, now we know how basic stylesheets rules work. We&#8217;ve also seen one way to add stylesheets to web pages, but there are other methods. Let&#8217;s take a look.</p>


<a name="Adding_Styles"></a><h4> <span class="mw-headline">Adding Styles</span></h4>

<p>There are actually four methods you can use to add styles to your page, each with its own benefits:

</p>

<ul><li> Embed a stylesheet within the HTML document.

</li><li> Link to an external stylesheet from the HTML document.

</li><li> Import an external stylesheet into the HTML document.

</li><li> Add styles inline in the HTML document.

</li></ul>

<p><br />

<b>Embedding a Stylesheet</b>



</p><p>This is the method we used on the previous page. All the stylesheets information lives at the top of the HTML document, separated from the <tt>&lt;body&gt;</tt> of the HTML code. Here&#8217;s a refresher of what the code looks like:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;title&gt;My First Stylesheet&lt;/title&gt;

&lt;style type="text/css"&gt;

&lt;!--

h1 { color:green; font-family:impact }

p { background:yellow; font-family:courier }

--&gt;



&lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Stylesheets:The Tool of the Web Design Gods&lt;/h1&gt;

&lt;p&gt;Amaze your friends! Squash your enemies!&lt;/p&gt;

&lt;/body&gt;

&lt;/html&gt;



</pre>

<p>When stylesheets rules are embedded, browsers honor them for the length of the HTML page. When you want to add stylesheets one page at a time, this is the way to go.

</p><p>You probably noticed two curiosities in this code:the <tt>type="text/css"</tt> attribute and the comment tags. <tt>type="text/css"</tt> specifies the MIME type so browsers that don&#8217;t support CSS can ignore stylesheet code altogether. Use it.

</p><p>The comment tags (<tt>&lt;!--&gt;</tt> and <tt>&lt;--&gt;</tt>) are even more important. Some older Web browsers (such as IE 2.0 for Mac) won&#8217;t recognize stylesheets code in spite of the <tt>type="text/css"</tt> attribute and will display the stylesheets code itself! This is not a good thing. Use comments, and this snafu will never happen.



</p><p><b>Linking to a Stylesheet</b>

</p><p>Here&#8217;s where stylesheets start to get powerful. Instead of embedding stylesheets code one page at a time, you can point multiple HTML documents to one central stylesheets document. This external file will set the rules for all of your Web pages. If you change a detail such as the font size in the stylesheets file, all of your pages will instantly reflect that change. If you maintain a large site, this feature is heaven.

</p><p>Here&#8217;s how it works:Create your Web page normally but instead of the <tt>&lt;style&gt;</tt> tag, use the <tt>&lt;link&gt;</tt> tag within the <tt>&lt;head&gt;</tt>, like so:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;



&lt;title&gt;My First Stylesheet&lt;/title&gt;

&lt;link rel="stylesheet" href="mystyles.css" type="text/css"&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Stylesheets:The Tool of the Web Design Gods&lt;/h1&gt;

&lt;p&gt;Amaze your friends! Squash your enemies!&lt;/p&gt;



&lt;/body&gt;

&lt;/html&gt;

</pre>

<p>(With a linked stylesheet, you don&#8217;t have to use comment tags.)

</p><p>Now create a separate text file called <tt>mystyles.css</tt> (you can name it anything you want). All it contains is this:

</p>

<pre class="brush: js">h1 { color:green; font-family:impact }

p { background:yellow; font-family:courier }

</pre>

<p>Upload this CSS file to your server the same way you would an HTML file. When you view the page in your favorite browser, you&#8217;ll see that the browser has followed the <tt>&lt;link&gt;</tt> tag and honored all of its stylesheets rules in the HTML page. You can link to the same stylesheets file from an unlimited number of HTML documents, and you can use relative or absolute URLs with the <tt>href</tt> attribute.



</p><p><b>Importing a Stylesheet</b>

</p><p>Importing an external stylesheet works similarly to linking. The difference is that you can&#8217;t combine the linking method with other methods, whereas you can combine importing with other methods. Let&#8217;s look at an example:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;title&gt;My First Stylesheet&lt;/title&gt;

&lt;style type="text/css"&gt;

&lt;!--

@import url("company.css");

h1 { color:orange; font-family:impact }

--&gt;

&lt;/style&gt;



&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Stylesheets:The Tool of the Web Design Gods&lt;/h1&gt;

&lt;p&gt;Amaze your friends! Squash your enemies!&lt;/p&gt;

&lt;/body&gt;

&lt;/html&gt;

</pre>



<p>Let&#8217;s say that the <tt>company.css</tt> file looks like this:

</p>

<pre class="brush: js">h1 { color:green; font-family:times }

p { background:yellow; font-family:courier }

</pre>

<p>In this example, the browser first imports the <tt>company.css</tt> rules (the <tt>@import</tt> line must always be first) and then adds the embedded rules to it to get a collection of rules for the entire page.

</p><p>Notice, however, that <tt>h1</tt> has a rule both in the external stylesheets file <i>and</i> in the embedded styles. What does the browser do in the face of this conflict? The embedded rules win out, and the text displays as orange Impact:



</p>

<div style="color: orange; font-size: 37px; font-family: times; line-height: 40px;">Stylesheets:The Tool of the Web Design Gods</div>

<p><br />

</p>

<div style="background: yellow none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-family: courier;">Amaze your friends! Squash your enemies!</div>

<p><br />

The flexibility of importing stylesheets is wondrous. You can import as many stylesheets files as you want and override them with embedded styles as desired.

</p><p>Unfortunately, Web browsers have been slower to support this method of adding stylesheets to Web pages. Only IE 4 and 5 support importing, so I recommend avoiding it for the time being.

</p><p><b>Adding Styles Inline</b>

</p><p>Finally, you can also add styles inline, which means inserting stylesheets rules right in the middle of all your HTML. It might look like this:

</p>

<pre class="brush: js">&lt;html&gt;

&lt;head&gt;



&lt;title&gt;My First Stylesheet&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1 style="color:orange; font-family:impact"&gt;Stylesheets:

The Tool of the Web Design Gods&lt;/H1&gt;

&lt;p style="background:yellow; font-family:courier"&gt;Amaze your

friends! Squash your enemies!&lt;/p&gt;

&lt;/body&gt;



&lt;/html&gt;

</pre>

<p>In this scenario, you wouldn&#8217;t need any stylesheets code at all at the top of your HTML document. The inline <tt>style</tt> attribute would give the browser all the information it needs.

</p><p>The big downside here is that you have to add the inline style code every single time you want to use it. The next <tt>&lt;h1&gt;</tt> text after this one would revert back to the default browser display unless you add another <tt>style</tt> attribute.

</p><p>Inline styles are considerably less powerful than embedded, linked, and imported styles, but you might find some use for them. For example, if all your paragraphs are styled with a linked stylesheet but you want to override the style of one paragraph, you can use inline style to do so.

</p><p>Remember, you can use more than one of these methods at a time. In fact, the power of stylesheets lies in combining the ways that styles are added to pages.

</p><p><br />



</p>

<a name="Classes_and_Other_Tricks"></a><h4> <span class="mw-headline">Classes and Other Tricks</span></h4>

<p>We&#8217;ve covered all the basics of CSS syntax. Now let&#8217;s go over a few more tricks and shortcuts that you&#8217;ll be glad to know about.

</p><p><b>Classes</b>

</p><p>We said before that any HTML tag can serve as a selector and have stylesheets declarations attached to it. But what if you want something more complex than that? What if, for example, you wanted body text to be green for the first paragraph, purple for the second paragraph, and gray for the third?

</p><p>That&#8217;s where classes come in. You could create three different classes of <tt>P</tt>, each one with a different stylesheet declaration. The rules (either embedded in the HTML document or in an external stylesheets file) would look like this:

</p>

<pre class="brush: js">P.first { color:green }

P.second { color:purple }

P.third { color:gray }

</pre>

<p>And your HTML code would look like this:

</p>

<pre class="brush: js">&lt;P CLASS="first"&gt;The first paragraph, with a class name of "first."&lt;/P&gt;



&lt;P CLASS="second"&gt;The second paragraph, with a class name of "second."&lt;/P&gt;

&lt;P CLASS="third"&gt;The third paragraph, with a class name of "third."&lt;/P&gt;

</pre>

<p>You can name classes anything you want, but make sure to use a period before the class name in the stylesheets rule.

</p><p>You can also create classes that aren&#8217;t attached to any HTML tag at all:

</p>

<pre class="brush: js">.first { color:green }

</pre>

<p>This approach is more flexible, because now we can use <tt>CLASS="first"</tt> with any HTML tag in the <tt>&lt;BODY&gt;</tt> of the page, and the text will be displayed in green.



</p><p><b>Contextual Selectors</b>

</p><p>Let&#8217;s say you want all bold text to be red but only if that bold text occurs in regular <tt>&lt;P&gt;</tt> body text. It&#8217;s not possible, right? Wrong. With stylesheets, even your wildest dreams can come true (OK, maybe I&#8217;m exaggerating slightly). Contextual selectors are selectors that demand that a certain situation be true in order for their declarations to be carried out.

</p>

<pre class="brush: js">P B { color:red }



&lt;H1&gt;&lt;B&gt;Emma Thompson&lt;/B&gt;, Actress&lt;/H1&gt;

&lt;P&gt;Dramatic actor, inspired writer, down-to-earth comedienne.

Is there &lt;B&gt;nothing&lt;/B&gt; she can't do?&lt;/P&gt;



</pre>

<p>The stylesheets rule tells the browser to make all bold text red <i>only</i> if it appears within <tt>&lt;P&gt;</tt> text. Thus, when the above HTML code is displayed by the browser, the bold text in the first line isn&#8217;t red, but the bold text in the second line is.

</p><p><b>Comments</b>

</p><p>Even with the clean code that&#8217;s created with stylesheets, commenting your work is a good idea. Fortunately, comments are possible within stylesheets code and can be used on any line, like so:

</p>

<pre class="brush: js">P.first { color:green } /* green for the first paragraph of every page */

H1 { text-indent:10px; font-family:verdana }

IMG { margin-top:100px } /* give all images a top margin */

</pre>

<a name="When_Stylesheets_Fight_It_Out"></a><h4> <span class="mw-headline">When Stylesheets Fight It Out</span></h4>



<p>The scene is set for battle. Let&#8217;s say there are three different stylesheets rules at work and all of them use <tt>P</tt> as the selector. An imported stylesheet tells the browser to display <tt>&lt;P&gt;</tt> text in red. An embedded stylesheet tells the browser to use blue. And an inline stylesheet tells the browser to use yellow.

</p><p>What&#8217;s a poor web browser to do?

</p><p>Thankfully, browsers that support stylesheets have a built-in cascading order of rules that instructs them what to do in these kinds of situations. Ultimately, some kinds of stylesheets rules are more important than others. According to the official specification of cascading stylesheets, here is the order of importance:

</p>

<ol><li> <b>Inline styles</b>

</li><li> <b>Embedded styles</b>

</li><li> <b>Linked styles</b>



</li><li> <b>Imported styles</b>

</li><li> <b>Default browser styles</b>

</li></ol>

<p><br />

So inline styles override embedded styles, which override linked styles, and so on.

</p><p>It&#8217;s nice and elegant, right? Not so fast. Unfortunately, Netscape and Microsoft have been slightly less than perfect in implementing this order in their browsers. If I apply styles to the same selector using all these methods, then the browsers get it right and treat inline styles as most important, embedded styles as next-most important, and so on.

</p><p>But if my styles are applied to different selectors and inheritance is involved, all hell breaks loose. For example, both browsers give more importance to linked styles than embedded styles. For now, your best bet is to stick with one method of adding styles to Web pages, especially when you&#8217;re sure that stylesheet rules will conflict.

</p><p>But even if this cascading order worked perfectly, we would still have a problem. What happens when multiple rules of the same kind conflict? What happens, for example, if one embedded rule declares <tt>&lt;P&gt;</tt> text green and another embedded rule declares it red?

</p><p>Thanks to the wise sages who wrote the stylesheets specification, there&#8217;s an order for solving these conflicts too. It&#8217;s complicated, but here&#8217;s an oversimplified guide to what browsers check for:

</p><p>1. <b>Use the one stylesheets rule that&#8217;s specifically declared.</b>



Example:

<tt>BODY { color:green }

P { color:red }</tt>

<tt>&lt;P&gt;</tt> text is specifically declared red by one rule, but it also inherits the green value from the <tt>&lt;BODY&gt;</tt> rule. (If you give <tt>&lt;BODY&gt;</tt> a declaration, everything on the entire page inherits it.) In this situation, the specific rule outweighs the inherited value, so red wins out.

</p><p>2. <b>Use the one stylesheets rule that&#8217;s inherited.</b> If step number one doesn&#8217;t result in a winner (i.e., if there&#8217;s no rule that&#8217;s specifically declared or if there are multiple rules that are specifically declared), the browser moves on to this step. The browser looks for an inherited rule and uses one if it finds one. If it finds none or if there are multiple inherited rules, the browser moves on to step number three:

</p><p>3. <b>Use the stylesheets rules in the order they appear in the code.</b>



Example:

<tt>

P { color:green }

P { color:red }

</tt>

When all else fails, the browser resorts to using the order in which the rules appear. In the above example, <tt>&lt;P&gt;</tt> text would display in red because it&#8217;s the last rule given.

</p><p>Note: The official cascading stylesheets specification goes into a lot more detail about this cascading order, including other concepts of importance and specificity, but since those are not well supported by the major browsers, I won&#8217;t bother to go into them here.

</p><p>One final question: What happens when stylesheets rules collide with HTML tags? Take a look at this example:

</p>

<pre class="brush: js">I { font-family:impact }



&lt;P&gt;I think &lt;I&gt;&lt;FONT FACE="Times"&gt;East of Eden&lt;/FONT&gt;&lt;/I&gt;



is Steinbeck's best novel.&lt;/P&gt;

</pre>

<p>The stylesheets rule tells the browser to use Impact, but the familiar HTML <tt>&lt;FONT FACE&gt;</tt> tag demands Times. It&#8217;s an obvious conflict.

</p><p>According to the official stylesheets specification, stylesheets should win out. Only if there are no applicable CSS rules should the browser use the HTML tag instead.

</p><p>Unfortunately, the major browsers aren&#8217;t built this way. Netscape Communicator and Internet Explorer both treat HTML tags as more important than stylesheets rules if the HTML is closer to the affected text. Sigh.

</p><p>As you can see, there are all sorts of problems with the browsers&#8217; support of stylesheets. Let&#8217;s get the bad news over with.

</p>

<a name="The_Bad_News_About_Browsers"></a><h4> <span class="mw-headline">The Bad News About Browsers</span></h4>

<p>I&#8217;ll make this short and bittersweet: Cascading stylesheets are great, web browsers are not so great.

</p><p>Internet Explorer 3.0 was the first browser to try to support stylesheets, and its attempt was valiant, particularly because at that point the official specification had yet to be solidified.



</p><p>You&#8217;d think that by the time IE 4 and Communicator 4 came out, stylesheets support would be rock-solid in both of them. Well, it&#8217;s not. It looks like the development teams at Microsoft and Netscape each had their own interpretations of some of the CSS properties, and other properties weren&#8217;t supported at all.

</p><p>The result? Browsers have essentially forked stylesheet standards, with Firefox, Opera and the Webkit browsers (Chrome, Safari) all offering very similar levels of support with Internet Explorer offering a sub-standard and &#8220;just different&#8221; level of support.

</p><p>Using stylesheets today can feel like walking in a mine field once you start taking IE into consideration. Some things work in IE, but some don&#8217;t. And even when things seem to work fine across most browsers, you&#8217;ll find they appear differently depending upon the operating system.

</p><p>As we visit the various properties of cascading stylesheets in the next four lessons, I&#8217;ll try to briefly mention which browsers support what. But for the details, you&#8217;ll have to test as you go. When using stylesheets code, it&#8217;s essential to test your end product on multiple browsers and multiple platforms. This is the only way to avoid unpleasant surprises.

</p><p>In the meantime, make yourself heard! Let Microsoft, Mozilla, Google and Apple know that solid support of cascading stylesheets is essential if standardized design control is ever to be achieved.

</p><p>That about wraps it up for Lesson 1. Let&#8217;s review.

</p>

<a name="Review_of_Lesson_1"></a><h4> <span class="mw-headline">Review of Lesson 1</span></h4>

<p>In this first lesson, we discovered the magic of stylesheets and the basics of their use.

</p><p>Why use cascading stylesheets? Because they provide unsurpassed control over the layout of Web pages. They&#8217;re also the most efficient way to maintain and update a large site, and they make for smaller pages that download faster.

</p><p>CSS works through individual stylesheets rules that consist of selectors and declarations. These rules can be embedded in an HTML document, linked to or from an HTML document, imported to an HTML document, or added inline within an HTML document. Each method of adding CSS to Web pages has its own benefits.

</p><p>What&#8217;s next? In the next four lessons, we dive into most of the individual stylesheets properties that give CSS its power. You&#8217;ve seen a few examples in this lesson. Starting with Lesson 2, we&#8217;ll explore each in more detail. Here&#8217;s a quick map of where we&#8217;re going:

</p>

<ul><li> Lesson 2: Fonts



</li><li> Lesson 3: Typography and Layout

</li><li> Lesson 4: Colors and Backgrounds

</li><li> Lesson 5: Positioning

</li></ul>

<p><br />

Get thee to <a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_2" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 2"> Lesson 2!</a> <span id="title_name_el" class="wm_hidden_meta_class" title="Mulder's Stylesheets Tutorial" style="visibility: hidden;"> <span id="page_path_el" class="wm_hidden_meta_class" title="/webmonkey/stylesheets/tutorials/tutorial1.html" style="visibility: hidden;"> <span id="author_el" class="wm_hidden_meta_class" title="mulder" style="visibility: hidden;"> <span id="creation_date_el" class="wm_hidden_meta_class" title="1999-09-16T24:00:00Z" style="visibility: hidden;"> </span></span></span></span>



</p>

<div id="series">

<div class="series_hdr">From the series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Mulders_Stylesheets_Tutorial" title="Tutorial:Mulders Stylesheets Tutorial">Tutorial:Mulders Stylesheets Tutorial</a><br />

<strong class="selflink">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 1</strong><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_2" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 2">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 2</a><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_3" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 3">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 3</a><br />

<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_4" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 4">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 4</a><br />



<a href="/2010/02/Mulders_Stylesheets_Tutorial_-_Lesson_5" title="Tutorial:Mulders Stylesheets Tutorial - Lesson 5">Tutorial:Mulders Stylesheets Tutorial &#8211; Lesson 5</a><br />

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/mulders_stylesheets_tutorial_-_lesson_1/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Build a Website With Flash and MySQL &#8211; Lesson 2</title>
        <link>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/</link>
        <comments>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=684</guid>
        		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[In Build a Website With Flash and MySQL &#8211; Lesson 1, we successfully created a MySQL database, filled it with blog entries, and learned how to query it. Now we&#8217;re going to move on to the fun stuff:creating a Flash container to display our blog entries as we pull them out of the database. I&#8217;m [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>In <a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_1" title="Tutorial:Build a Website With Flash and MySQL - Lesson 1"> Build a Website With Flash and MySQL &#8211; Lesson 1</a>, we successfully created a MySQL database, filled it with blog entries, and learned how to query it. Now we&#8217;re going to move on to the fun stuff:creating a Flash container to display our blog entries as we pull them out of the database. I&#8217;m going to help you build something along the lines of what you&#8217;ll encounter at my own Flash blog site, <a href="http://www.luxagraf.com/" class="external text" title="http://www.luxagraf.com/" rel="nofollow">Luxagraf</a>.

</p><p>Fire up Flash and create a new document. The first thing we need is a nice big text field to display our entries. You could create a text field in ActionScript if you like, using the createTextField() method. I don&#8217;t know about you, but my stomach for code is still full from yesterday, so I&#8217;ve just drawn a text field using the cursor tool and given it an instance name of entries_txt. In the Properties Inspector, set the text to be dynamic, multi-line, and HTML formatted. For safety&#8217;s sake, select the character option and click &#8220;embed all characters.&#8221; Flash has some issues with dynamic textfields that don&#8217;t have embedded characters, especially if you put your text <a href="http://www.macromedia.com/support/flash/ts/documents/maskprintembed.htm" class="external text" title="http://www.macromedia.com/support/flash/ts/documents/maskprintembed.htm" rel="nofollow">under a mask</a>.<span id="more-684"></span>

</p><p>I&#8217;ve also attached a scrollbar to the text field and given it an instance name of sb.

</p><p><img src="http://www.wired.com/wired/webmonkey/stuff/Flash_MySQL_shot1.jpg" alt="Flash_MySQL_shot1.jpg">

</p><p>My design is minimalist, but you can load up your movie with cool graphics, nifty background animation, menus, and more. And you can rest assured that while Flash is retrieving your data, your design will keep your user otherwise enthralled until the data loads. You might even include a loading progress bar if you want to give modem users some feedback so they know that something is happening. Creating a progress bar for external data is a little more complex than one for an external .swf, but it&#8217;s not too bad. Colin Moock, author of <i>ActionScript:The Definitive Guide</i>, has a sample <a href="http://www.moock.org/asdg/codedepot/" class="external text" title="http://www.moock.org/asdg/codedepot/" rel="nofollow">available</a>.



</p><p>To show our list of archived entries, we&#8217;ll need a second, smaller text field, which I&#8217;ve named archive_txt. I&#8217;ve attached another scrollbar to the archive text field and given it instance name sb2. Set the archive text field up the same way:dynamic, multiline and HTML. You don&#8217;t need to embed the font again since it can use the characters from the first text field.

</p><p>That&#8217;s it for the graphics. Now let&#8217;s get back to code!

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Linking_Flash_to_the_Database">Linking Flash to the Database</a></li>

<li><a href="#Loading_Up_on_Content">Loading Up on Content</a></li>



<li><a href="#Publishing_the_Finished_Product">Publishing the Finished Product</a></li>

<li><a href="#Allow_Me_to_Extrapolate">Allow Me to Extrapolate</a></li>



</ol>

</td></tr></tbody></table>



<a name="Linking_Flash_to_the_Database"></a><h4> <span class="mw-headline">Linking Flash to the Database</span></h4>

<p>Create a new layer on top of the last one and name it &#8220;actions&#8221; or something similar. Now open up the Actions panel (F9) and paste in the following code. It should display correctly below, but if your browser refuses to wrap text properly, use the <a href="http://www.wired.com/wired/webmonkey/stuff/flashcode3.txt" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/flashcode3.txt" rel="nofollow">plain text</a> or <a href="http://www.wired.com/wired/webmonkey/stuff/flashcode1.html" class="external text" title="http://www.wired.com/wired/webmonkey/stuff/flashcode1.html" rel="nofollow">HTML</a> version of the raw code.



</p>

<pre class="brush: js">//function to load external data using the loadVars() object

//l=name of loadVars object

//n=name of text field

//t=trigger to decide whether to show all entries or just one.

//e= entry number to display (number)

//f=file to load from (string)

function lv(l, n, t, e, f) {

	sb.setSize(null, 200);

	sb2.setSize(null, 50);

	//create a new loadVars object if one doesn't already exist

	//if it does, use it

	if (l == undefined) {

		l = new LoadVars();

		l.onLoad = function() {

			var i;

			//clear out any text that might already be there

			n.htmlText = "";

			//to show a single entry at a time we use the

			//following code

			if (t == undefined) {

				n.htmlText += "&lt;b&gt;"+this["title"+e]+"  -

				"+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";

				n.htmlText += this["entry"+e];

			} else {

				//cycle through and show all entries

				for (i=0; i&lt;this.n; i++) {

					n.htmlText += "&lt;u&gt;

					&lt;a href='asfunction:_root.loadArc,

					"+this["id"+i]+"'&gt;"+this["title"+i]+"  -

					"+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

				}

			}

			sb.update();

			sb2.update();

		};

	}

	l.load(f);

}



</pre>

<p>What we have here is a reasonably generic function that you can use to load external data in any Flash movie provided you know how it works and how to modify it. I&#8217;ll walk you through it line by line and hopefully you can see where you might have to change things to suit your needs.

</p><p>First off, let&#8217;s define our single letter variables in a little more detail. First we have &#8220;l&#8221;, which will become a new instance of the loadVars() object. The object needs to have an instance name so we&#8217;ll give it one when we call the function. Next we have &#8220;n&#8221; which will be the name of the text field. If you&#8217;re following along with my example, we&#8217;re going to use the instance name of the text fields we created earlier (entries_txt and archive_txt). By making this a variable that&#8217;s passed to the function, we can create as many textboxes as we want and we don&#8217;t have to rework our main loadVars function. &#8220;t&#8221; is for trigger (like the horse, but smaller). This variable may be unnecessary for your needs, but I&#8217;ve put it in there so that I can use the same function to load both the main text and archives. For the main textfield, I&#8217;ll pass a value of undefined because I only want to show the latest entry. For the archive textfield, we can pass any value other than undefined. In my own work I tend to pass the string &#8220;cycle&#8221; so I know what it is I&#8217;m doing without looking back at the actual function, but you could pass it the string &#8220;webmonkey rocks&#8221; and it would do the same thing.

</p><p>The next variable is &#8220;e,&#8221; which we won&#8217;t be using initially, but which will help us when we get to the archive section by allowing us to select entries by number. Last we have &#8220;f&#8221;, which is short for file, as in the .php file we&#8217;re calling. In the last section, use whatever name you used when you saved your .php file. I chose blog.php.

</p><p>It&#8217;s worth asking why I didn&#8217;t use more descriptive variable names in the function. Well, that&#8217;s partially due to laziness, but it&#8217;s also because using single letters seems to make things happen a bit faster.

</p>

<a name="Loading_Up_on_Content"></a><h4> <span class="mw-headline">Loading Up on Content</span></h4>

<p>Okay, now that we&#8217;ve spelled out our variables, we&#8217;ll move on to the function and its inner workings. To load our database information into Flash we&#8217;re going to be using the loadVars() object. As with most Flash objects, the first step is to create a new instance of the object. In this function we&#8217;ve started with an if statement.

</p><p><br />

</p>

<pre class="brush: js"> if (l == undefined) {



 		l = new LoadVars();

</pre>

<p><br />

The if statement checks to see whether we have a loadVars object by the name of &#8220;l&#8221; and, if not, it creates one. Now, since &#8220;l&#8221; will be defined in our function call, we can create loadVars objects left and right if we want to. On the other side of the coin, if we already have a loadVars object by the name we&#8217;ll call, we don&#8217;t have to waste time creating a new one. The next thing we need to do is define the onLoad method of our loadVars() object. Flash needs to know what to do with the information it&#8217;s about to get. So we define the function to process our data. Here&#8217;s the section of the code from page two that we&#8217;re dealing with:



</p>

<pre class="brush: js">l.onLoad = function() {

			var i;

			n.htmlText = "";

			//to show a single entry at a time we use the

			//following code

			if (t == undefined) {

					n.htmlText += "&lt;b&gt;"+this["title"+e]+"

					-  "+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";

					n.htmlText += this["entry"+e];

			} else {

				//cycle through and show all entries

				for (i=0; i" +this["title"+i]+"

					-  "+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

				}

			}

</pre>

<p>The first thing in our function is a variable i. I should point out here that, just as we used $i in our PHP code, we&#8217;ll call this variable i as well. Using i for incremented variables is just a programming convention. If there is a good reason for it, I&#8217;m not aware of it. You can ignore convention and use whatever you like, just don&#8217;t use any of the letters we&#8217;ve already assigned. The key thing to note is the use of var to define the variable. In Flash, var creates a local variable; that is, the variable i is only defined in this function. Outside this function you can use i again and it won&#8217;t mess things up. Local variables, as this practice is called, use up less memory since they get used and wiped away immediately afterward. Next we empty out our textfield:

</p>

<pre class="brush: js">n.htmlText = "";

</pre>



<p>Now we&#8217;re going to set up two possible ways of handling our data using our &#8220;t&#8221; variable as a selector. The code reads &#8220;if the variable t is undefined then do the first chunk of code, else do the second chunk of code.&#8221; The first chunk of code is just formatting for the information that was passed from MySQL. Our variable n, which will be the name of our text field, gets its htmlText property defined.

</p>

<pre class="brush: js"> n.htmlText += "&lt;b&gt;"+this["title"+e]+"  -  "+this["date"+e]+"&lt;/b&gt;&lt;br&gt;&lt;br&gt;";



 n.htmlText += this["entry"+e];

</pre>

<p>Here we&#8217;re concatenating a string again like we did in PHP, except in Flash we concatenate strings with the + operator. The first element is an HTML bold tag to highlight the title. The title itself comes from the array we defined in PHP this["title"+e]. &#8220;This&#8221; refers to the function we&#8217;re in, which is the onLoad handler, meaning anything with the &#8220;this&#8221; designation uses the PHP passed data. So, this.["title"+e] refers to the title column in our MySQL table plus our variable e. We could have just said this.["title"+0], but then we wouldn&#8217;t be able to use this function in our archives section. Next we have a dash to separate the title and date. Then, we join the rest of the string which is the same code, but this time we use the &#8220;date&#8221; element of our PHP array. Lastly, we close the bold tag and add some <br /> tags to put a little space between the title and the entry itself. The entry itself is written on a separate line so it will be displayed below the date and title. Once again we use an element of the PHP array, this time the &#8220;entry&#8221; element, which contains the main text.

</p><p>But what about our other case? Can we display a list of past entries listed by title and date without text? Of course, but first let&#8217;s look at how our function will get to this point. If we define the variable t, the if statement we just wrote evaluates to false so Flash jumps to the else clause. The else clause then tells Flash to execute a loop so all of our entries will be displayed at once. Remember for loops? Well this one should look familiar from the PHP section. It&#8217;s essentially the same loop with one subtle difference:the second condition, iThe way we&#8217;re handling the data in the archives textbox is a little different, too. We&#8217;ve set our text to underline using the HTML tag &lt;u&gt; and wrapped everything in an HTML link (note that this should all be on one line with no hard returns).



</p>

<pre class="brush: js"> n.htmlText += "&lt;u&gt;&lt;a href='asfunction:_root.loadArc,"+this["id"+i]+"'&gt;"



 +this["title"+i]+"  -  "+this["date"+i]+"&lt;/a&gt;&lt;/u&gt;&lt;br&gt;";

</pre>

<p>Our href tag might look a little strange to veteran HTML coders. Flash has a little-known feature that allows you to call a function from within an HTML tag. The syntax is asfunction:location/nameOfFunction,variable. The limiting thing is that you can pass only one variable using this method. The quickest way around that problem is to pass a variable as long string and then break it apart in your function, but that won&#8217;t be an issue for us since we have only one variable to pass.

</p><p>The last line our onLoad function uses the variable &#8220;s&#8221; to update our scrollbar. The lines after our onLoad function call the .load method of the loadVars object and pass the name of our .php file. This tells our loadVars object to go ahead and read the .php file. It might seem backwards to define the onLoad handler before calling the load function, but <i>you must define the onload handler first</i>.

</p>

<a name="Publishing_the_Finished_Product"></a><h4> <span class="mw-headline">Publishing the Finished Product</span></h4>



<p>Alright! We&#8217;re so close, I can taste it. Now that we&#8217;ve written our main function, let&#8217;s handle that asfunction we&#8217;re calling to, but haven&#8217;t yet defined.

</p><p>Copy this code into your Flash movie:

</p>

<pre class="brush: js"> function loadArc(passed) {



 	arcNum = passed-1;



 	lv(blog_lv, entries_txt, undefined, arcNum, "blog.php");



 }

</pre>

<p>All this function does is take the entry number passed from our lv function, subtract 1, and then call the lv function again with the new number. Why subtract one? Remember that our PHP loop starts counting at zero, but our MySQL auto increment starts at one. This means we&#8217;re always one number behind. Simple solution to the problem:subtract one.

</p><p>More copy and paste:

</p>

<pre class="brush: js"> //for the large entry textfield



 lv(blog_lv, entries_txt, undefined, 0, "blog.php");



 //for the archives text field



 lv(archive_lv, archive_txt, "cycle", null, "blog.php");

</pre>

<p>These lines call the function lv with all of our variables defined. When this code gets executed Flash will jump up and read our lv() function and then look for our PHP file which will query our database, extract and format our information and send it back to Flash where it will be displayed. I know it sounds like an incredibly long and complex process, but it will actually happen in fractions of a second and your user won&#8217;t have to sit idly waiting for the entire page to redraw itself.

</p><p>OK, publish the movie and upload it to your site. You&#8217;re done! Now, when a user comes to the site and loads the Flash piece, they&#8217;ll see the latest entry in the big text box and a list of past entries in the smaller one. Try clicking on the links in the archive list. You should see the Flash movie bring up past entries in the larger text box.

</p><p>You can see a working version of this very system over at my own blog site, <a href="http://www.luxagraf.com" class="external text" title="http://www.luxagraf.com" rel="nofollow">Luxagraf</a>. While you&#8217;re poking around, click on the &#8220;Browse Archives&#8221; tab at the bottom of the Flash window and you&#8217;ll see my second textbox full of archived entries show up.



</p><p>We did it! Primitive though it may be, we&#8217;ve created a Flash-based blog and learned a few things about Flash and database integration. Now let&#8217;s take a look at some places we can expand our code and make it more useful to a wider range of applications.

</p>

<a name="Allow_Me_to_Extrapolate"></a><h4> <span class="mw-headline">Allow Me to Extrapolate</span></h4>

<p>My main goal with this tutorial was to give you, the designer/programmer (which you can now truthfully call yourself!) a starting point from which to extrapolate and expand. You&#8217;ve made it this far, and for that you should be proud, but you probably have some questions. With this in mind, I wanted to address a few things.

</p><p>First off, we only scratched the surface of MySQL and PHP. To start thinking in more general terms, I suggest visiting the developer&#8217;s sites for the two technologies. Perhaps you should also join some mailing lists and see what others are doing with MySQl and PHP. Since there is no way to sit back and anticipate what a particular project may require, it&#8217;s a good idea to look around and see how other people are using these tools.

</p><p>Some examples that spring to mind for PHP/MySQL projects are a discussion board, or perhaps a backend application that lets your client update content without having to access MySQL directly. Once you have a better idea of what you can do with a database and have polished up your PHP knowledge, you will start to see some holes in our example. For instance, what if your want your PHP query to be dynamic? Suppose you want to return a query based on user input (i.e. some sort of search criteria defined by the user)? It&#8217;s not hard to do that at all. From the Flash end, you simply need to use the sendAndLoad() method of the LoadVars() class rather than the simple load() method (look it up in the <a href="http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/" class="external text" title="http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/" rel="nofollow">ActionScript Dictionary</a>) and then write your PHP query string with a POST variable. PHP and Flash are both very flexible tools, and you&#8217;ll find that the functionality you can achieve by using them is close to unlimited.

</p><p>The final concern I wanted to address is Macromedia&#8217;s release of Flash MX 2004. Aside from the fact that software manufacturers seem intent on coming up with ever more confusing product names and pricing schemes, the more pertinent question is &#8220;Does our example still work?&#8221;

</p><p>The short answer is yes. Judging from my own experience with Flash MX 2004 Professional and the Flash Player 7, the behaviors associated with loadVars() remain the same. There is, however, a new set of data components in Flash MX 2004. I have not explored these new tools in great depth, but it&#8217;s very possible they may simplify the code necessary to access external data sources. In my readings, the new components seem to be geared toward moving data between component sets. However, there is a fair price to be paid. Just dragging the new dataGrid component onto the Flash stage is going to bump your file size up by 58Kb. In comparison, the code we&#8217;ve written is only as large as the scrollbars you use. It&#8217;s also worth noting that none of these components can query MySQL directly &#8211; several rather expensive server technologies are supported, but not the free, open source solution.

</p><p>This raises yet another issue:By no means is Flash limited to PHP and MySQL interaction. Everything we&#8217;ve done can be done with ASP or other proprietary software so long as you know how to get the returned data into a URL encoded string. Then there is XML data which is also not hard to feed into Flash&#8230;

</p><p>Hopefully this tutorial can serve as a kind of gateway, providing an entrance into the world of dynamic content for Flash movies. How much of it you use is always going to depend on your own projects and needs. If nothing else, you have left the five percent nation of non-weblog creators and joined the thronging masses. Now take this project and see if you can adapt it to your own creative needs.

</p><p>



</p>



<div id="series">

<div class="series_hdr">From the series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Build_a_Website_With_Flash_and_MySQL_-_Lesson_1" title="Tutorial:Build a Website With Flash and MySQL - Lesson 1"> Build a Website With Flash and MySQL &#8211; Lesson 1</a><br />

<strong class="selflink"> Build a Website With Flash and MySQL &#8211; Lesson 2</strong>

</p>



</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_a_website_with_flash_and_mysql_-_lesson_2/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>Build an Ajax Dropdown Menu</title>
        <link>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/</link>
        <comments>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=754</guid>
        		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[If you hang out with designers and developers at all, then you&#8217;ve probably heard the term &#8220;Ajax&#8221; by now. It&#8217;s the official buzzword of Web 2.0. But it&#8217;s also an extremely useful web development technique. In the course of this tutorial, we&#8217;re going to look at what Ajax can do. Then we&#8217;ll use a JavaScript [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>If you hang out with designers and developers at all, then you&#8217;ve probably heard the term &#8220;Ajax&#8221; by now. It&#8217;s the official buzzword of Web 2.0. But it&#8217;s also an extremely useful web development technique.

</p><p>In the course of this tutorial, we&#8217;re going to look at what Ajax can do. Then we&#8217;ll use a JavaScript class to simplify your first steps toward the ultimate in speedy user interactivity.

</p><p>First, what is Ajax? It stands for <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29" class="external text" title="http://en.wikipedia.org/wiki/Ajax_%28programming%29" rel="nofollow">Asynchronous JavaScript And XML</a>. In simple speak, Ajax allows us to use JavaScript to grab an XML file (or any other text) without reloading the whole web page.

</p><p>Ajax has been used for a lot of things, but it is most impressive when many small updates are needed in a short period. Think streaming stock quotes or draggable maps.

</p><span id="more-754"></span><p>In our example, we&#8217;ll use a pair of dropdown menu boxes (SELECT tags in HTML). A selection in the first box affects our list of choices in the second box. It&#8217;s not exactly cutting edge (Thau did <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> something similar</a> using JavaScript), but it&#8217;s a proof of concept.



</p><p>Before we get started, here&#8217;s the stuff you&#8217;ll want in your toolbag:

</p><p>1. A love of extremely <a href="/2010/02/Make_an_HTML_Document" title="Tutorial:Make an HTML Document"> basic HTML</a>.

</p><p>2. Willingness to consult <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> Thau&#8217;s Javascript Tutorial</a> if you get confused.

</p><p>3. &#8220;<a href="http://adamv.com/dev/javascript/http_request" class="external text" title="http://adamv.com/dev/javascript/http_request" rel="nofollow">Http</a>&#8220;, a caching XmlHttpRequest wrapper, which you can download to immediately make your life simpler. Plus, if you get into advanced Ajax programming, you may like the caching that is built into this Javascript class.

</p><p>But that&#8217;s the future. Let&#8217;s talk about now, alright? Ajax on three. One, two, three&#8230; Ajax!

</p><p>Before we do any JavaScript Ajax voodoo, let&#8217;s setup our HTML.

</p><p><br />

</p>



<pre class="brush: js">&lt;html&gt;

&lt;head&gt;

&lt;!--

	Javascript Ajax voodoo will go here

--&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;form name="frmSelect"&gt;

&lt;p&gt;

&lt;select name="country" onChange="handleOnChange(this);"&gt;

&lt;option&gt;Select country&lt;/option&gt;



&lt;option&gt;France&lt;/option&gt;

&lt;option&gt;Germany&lt;/option&gt;

&lt;option&gt;Spain&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;&lt;p&gt;



&lt;select name="prez"&gt;

&lt;option&gt;Select head of government&lt;/option&gt;

&lt;/select&gt;

&lt;/p&gt;

&lt;/form&gt;

&lt;/body&gt;

&lt;/html&gt;

</pre>



<p>Here we have created an HTML form containing two dropdown menus. The dropdowns use the SELECT tag, which can contain several options.

</p><p>The first dropdown has four options: Select country, France, Germany, and Spain. Notice the onChange part of this dropdown:

</p><p><code>onChange="handleOnChange(this);" </code>

</p><p>This will become important later.

</p><p>The second dropdown has only one option: Select head of government.

</p><p>What we want to accomplish with our Ajax call is to get the three most recent heads of government for each country and load them into the second dropdown whenever the user changes the first dropdown.

</p><p>Sounds simple enough, but how are you on recent European presidents and chancellors? One great thing about Ajax is that we can grab content only when we need it. So, we&#8217;ll connect ourselves to some sort of feed that will give us the head of government for a particular country when we need it.

</p><p>For the purpose of this example, our feed will be plain text files stored in the same directory as our web page. So, copy the following lines to their own text files.

</p><p>France.txt:

</p><p><code>Valéry Giscard d'Estaing|François Mitterrand|Jacques Chirac</code>

</p><p>Germany.txt:

</p><p><code>|Helmut Kohl|Gerhard Schröder|Angela Merke</code>

</p><p>Spain.txt:

</p><p><code>|Felipe González Márquez|José María Aznar López|José Luis Rodríguez Zapatero</code>



</p><p>Notice how the lines contain names separated by vertical lines? Those lines are called &#8220;pipes,&#8221; and the pipe symbol has its own keystroke on your keyboard. Just hold Shift and look for the backslash (). So, the plan of attack is that whenever Germany is selected (for example), we&#8217;ll make an Ajax call to retrieve Germany.txt, get rid of those pipes, and put the names in the second dropdown box.

</p><p>Now that we&#8217;re ready for the Ajax voodoo, let&#8217;s get to the nitty gritty on the next page.

</p>

<a name="Packin.27_boxes"></a><h4> <span class="mw-headline">Packin&#8217; boxes</span></h4>

<p>If you haven&#8217;t downloaded request.js, the Ajax wrapper Javascript class, <a href="http://adamv.com/dev/javascript/http_request" class="external text" title="http://adamv.com/dev/javascript/http_request" rel="nofollow">grab it now</a> and put it in the same directory as the web page with the two dropdowns.

</p><p>Now, find this line in your document:

</p><p><code>&lt;!-- Javascript Ajax voodoo will go here --&gt; </code>

</p><p>And replace it with these lines:

</p><p><br />

</p>



<pre class="brush: js">&lt;script src="request.js"&gt;&lt;/script&gt;

&lt;script&gt;

function handleOnChange(dd1)

{

  var idx = dd1.selectedIndex;

  var val = dd1[idx].text;

  var par = document.forms["frmSelect"];

  var parelmts = par.elements;

  var prezsel = parelmts["prez"];

  var country = val;

  if (country&nbsp;!= "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

  }

}

function fillPrez(xmlreply, prezelmt)

{

  if (xmlreply.status == Http.Status.OK)

  {

   var prezresponse = xmlreply.responseText;

   var prezar = prezresponse.split("|");

   prezelmt.length = 1;

   prezelmt.length = prezar.length;

   for (o=1; o &lt; prezar.length; o++)

   {

     prezelmt[o].text = prezar[o];

   }

  }

  else

  {

   alert("Cannot handle the Ajax call.");

  }

}

&lt;/script&gt;

</pre>

<p>Now that&#8217;s a big chunk of code.

</p><p>This line reads in the Ajax wrapper class that does the heavy lifting:

</p>

<pre class="brush: js">&lt;script src="http://www.wired.com/images/archiveequest.js"&gt;&lt;/script&gt;</pre>



<p>The <code>handleOnChange</code> function is called whenever the first dropdown is changed. Remember how I said that onChange stuff would be important?

</p><p>Lastly, the <code>fillPrez</code> function takes the output from the Ajax call and puts the names into the second dropdown.

</p><p>Let&#8217;s look through it a little closer.

</p><p>This sequence of Javascript looks through the first dropdown, finds which one is selected, and returns the country name into a variable named, appropriately, country:

</p>

<pre class="brush: js">var idx = dd1.selectedIndex;

var val = dd1[idx].text;

var par = document.forms["frmSelect"];

var parelmts = par.elements;

var prezsel = parelmts["prez"];

var country = val;

</pre>

<p>Then, if an actual country is selected, an Ajax call is made for the name of the country with .txt at the end. We supply our other function, <code>fillPrez</code>, to be the &#8220;callback&#8221; function. Whatever comes out of our Ajax call, we want it to go to <code>fillPrez</code>.



</p><p><br />

</p>

<pre class="brush: js">if (country&nbsp;!= "Select country")

  {

   var directory = ""+document.location;

   directory = directory.substr(0, directory.lastIndexOf('/'));



   Http.get({

		url: "./" +  country + ".txt",

		callback: fillPrez,

		cache: Http.Cache.Get

	}, [prezsel]);

}

</pre>

<p><br />

</p><p>We also pass along our second dropdown box, so that <code>fillPrez</code> will know which dropdown to fill.

</p><p>The first thing that happens in <code>fillPrez</code> is that we make sure that our Ajax call actually found the list of heads of government:

</p>

<pre class="brush: js">if (xmlreply.status == Http.Status.OK)</pre>



<p>If it didn&#8217;t, we let the user know there&#8217;s an error:

</p>

<pre class="brush: js">alert("Cannot handle the Ajax call.");</pre>

<p>If we&#8217;re good to go, then we grab the list of names and split it apart on those pipes:

</p><p><br />

</p>

<pre class="brush: js">var prezresponse = xmlreply.responseText;

var prezar = prezresponse.split("|");

</pre>

<p>We clear out the second dropdown, except for the first option (&#8220;Select head of government&#8221;):

</p><p><br />

</p>

<pre class="brush: js">prezelmt.length = 1;</pre>

<p><br />

Then we add each of the names into the dropdown:

</p><p><br />



</p>

<pre class="brush: js">prezelmt.length = prezar.length;

    for (o=1; o &lt; prezar.length; o++)

    {

      prezelmt[o].text = prezar[o];

}

</pre>

<p>You have now successfully created an Ajax call. Your Javascript code made a connection to your server, grabbed a text file, split apart the names in the file, and plopped the resulting data right into your dropdown box.

</p><p>See it in action and download the code <a href="http://duvinci.com/projects/ajax/dropdowns/" class="external text" title="http://duvinci.com/projects/ajax/dropdowns/" rel="nofollow">at my website</a>.

</p><p>There are a number of ways you could expand this code. A few examples:

</p><p>1. When someone chooses a head of government, you could redirect the user to the politician&#8217;s web page.

</p><p>2. You could show information about the head of government and their time in office. Extra points for using Ajax to grab the selected politician&#8217;s bio.

</p><p>3. You could also give up on the heads of government idea and instead fill the second dropdown with cities, states or provinces. Or maybe you could show fast food chain locations.

</p><p>You get the idea. There are a plethora of possibilities.

</p><p>Now, if you aren&#8217;t impressed since <a href="/2010/02/JavaScript_Tutorial" title="Tutorial:JavaScript Tutorial"> Thau did this in 1998</a> and he didn&#8217;t need no Ajax, remember this is a proof of concept. Rather than a text file, consider setting up a more dynamic feed using <a href="/2010/02/PHP_and_MySQL_Tutorial" title="Tutorial:PHP and MySQL Tutorial"> PHP and MySQL</a>.



</p><p>And if you really want to get more into the back end of providing data to Ajax calls, consider Paul&#8217;s article <a href="/2010/02/Building_With_Ajax_and_Rails" title="Tutorial:Building With Ajax and Rails"> Ajax It&#8217;s Good For What Rails You</a>.

</p><p><br />

</p><p><br />

<i>Did you love this article? Did you hate it? Think you can do better? Send us your <a href="mailto:webmonkey@wired.com?subject=nittygritty" class="external text" title="mailto:webmonkey@wired.com?subject=nittygritty" rel="nofollow">Feedback</a>. Feedback submitted here will be considered for publication on Webmonkey or Wired News, so if you don&#8217;t want us to print your comments, please say so in your email.</i>

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_an_ajax_dropdown_menu/feed/</wfw:commentRss>
        <slash:comments>6</slash:comments>

        
    </item>
    </channel>
</rss>