Wiktionary
sowiktionary
https://so.wiktionary.org/wiki/Bogga_Hore
MediaWiki 1.46.0-wmf.23
case-sensitive
Media
Special
Talk
User
User talk
Wiktionary
Wiktionary talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
TimedText
TimedText talk
Module
Module talk
Event
Event talk
User:Moncur/04
2
2075
39269
5827
2026-04-13T06:03:43Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39269
wikitext
text/x-wiki
=4. Working with the Document Object Model (DOM)=
== Understanding the Document Object Model (DOM) ==
One advantage that JavaScript has over basic HTML is that scripts can manipulate the web document and its contents. Your script can load a new page into the browser, work with parts of the browser window and document, open new windows, and even modify text within the page dynamically.
To work with the browser and documents, JavaScript uses a hierarchy of parent and child objects called the Document Object Model (DOM). These objects are organized into a tree-like structure, and represent all of the content and components of a web document.
; By the Way: The DOM is not part of the JavaScript language, rather, it's an API (application programming interface) built in to the browser. While the DOM is most often used with JavaScript, it can also be used by other languages, such as VBScript and Java.
The objects in the DOM have properties, variables that describe the web page or document, and methods, functions that enable you to work with parts of the web page.
When you refer to an object, you use the parent object name followed by the child object name or names, separated by periods. For example, JavaScript stores objects to represent images in a document as children of the document object. The following refers to the <code>image9 </code>object, a child of the <code>document </code>object, which is a child of the <code>window </code>object:
<pre>
window.document.image9</pre>
The window object is the parent object for all of the objects we will be looking at in this hour. Figure 4.1 shows this section of the DOM object hierarchy and a variety of its objects.
; By the Way: This diagram only includes the basic browser objects that will be covered in this hour. These are actually a small part of the DOM, which you'll learn more about in Part III, "Learning More About the DOM."
=== History of the DOM ===
Starting with the introduction of JavaScript 1.0 in Netscape 2.0, browsers have included objects that represent parts of a web document and other browser features. However, there was never a true standard. While both Netscape and Microsoft Internet Explorer included many of the same objects, there was no guarantee that the same objects would work the same way in both browsers, let alone in less common browsers.
The bad news is that there are still differences between the browsers, but here's the good news. Since the release of Netscape 3.0 and Internet Explorer 4.0, all of the basic objects (those covered in this hour) are supported in much the same way in both browsers. With more recent browser releases, a much more advanced DOM is supported.
=== DOM Levels ===
The W3C (World Wide Web Consortium) developed the DOM level 1 recommendation. This is a standard that defines not only basic objects, but an entire set of objects that encompass all parts of an HTML document. A level 2 DOM standard has also been released, and level 3 is under development.
Netscape 4 and Internet Explorer 4 supported their own DOMs that allowed more control over documents, but weren't standardized. Fortunately, starting with Internet Explorer 5 and Netscape 6, both support the W3C DOM, so you can support both browsers with simple, standards-compliant code. All of today's current browsers support the W3C DOM.
The basic object hierarchy described in this hour is informally referred to as DOM level 0, and the objects are included in the DOM level 1 standard. You'll learn how to use the W3C DOM to work with any part of a web document later in this book.
; Did you Know?: The W3C DOM allows you to modify a web page in real time after it has loaded. You'll learn how to do this in Part III.
== Using <code>window</code> Objects ==
At the top of the browser object hierarchy is the window object, which represents a browser window. You've already used at least one method of the window object: the <code>window.alert()</code> method, or simply <code>alert()</code>, displays a message in an alert box.
There can be several window objects at a time, each representing an open browser window. Frames are also represented by window objects. You'll learn more about windows and frames in Hour 10, "Using Windows and Frames."
; By the Way: Layers, which enable you to include, modify, and position dynamic content within a web document, are also similar to window objects. These are explained in Hour 13, "Using the W3C DOM."
== Working with Web Documents ==
The document object represents a web document, or page. Web documents are displayed within browser windows, so it shouldn't surprise you to learn that the document object is a child of the window object.
Because the window object always represents the current window (the one containing the script), you can use window.document to refer to the current document. You can also simply refer to document, which automatically refers to the current window.
; By the Way: You've already used the document.write method to display text within a web document. The examples in earlier hours only used a single window and document, so it was unnecessary to use window.document.writebut this longer syntax would have worked equally well.
If multiple windows or frames are in use, there might be several window objects, each with its own document object. To use one of these document objects, you use the name of the window and the name of the document.
In the following sections, you will look at some of the properties and methods of the document object that will be useful in your scripting.
=== Getting Information About the Document ===
Several properties of the document object include information about the current document in general:
* <code>document.URL</code> specifies the document's URL. This is a simple text field. You can't change this property. If you need to send the user to a different location, use the window.location object, described later in this hour.
* <code>document.title</code> lists the title of the current page, defined by the HTML <code><title></code> tag.
* <code>document.referrer</code> is the URL of the page the user was viewing prior to the current pageusually, the page with a link to the current page.
* <code>document.lastModified</code> is the date the document was last modified. This date is sent from the server along with the page.
* <code>document.bgColor</code> and <code>document.fgColor</code> are the background and foreground (text) colors for the document, corresponding to the <code>BGCOLOR</code> and <code>TEXT </code>attributes of the <code><body></code> tag.
* <code>document.linkColor</code>, <code>document.alinkColor</code>, and <code>document.vlinkColor </code>are the colors for links within the document. These correspond to the <code>LINK</code>, <code>ALINK</code>, and <code>VLINK </code>attributes of the <code><body></code> tag.
* <code>document.cookie</code> enables you to read or set a cookie for the document. See http://www.jsworkshop.com/cookies.html for information about cookies.
As an example of a document property, Listing 4.1 shows a short HTML document that displays its last modified date using JavaScript.
; Listing 4.1. Displaying the Last Modified Date
<pre>
<html><head><title>Test Document</title></head>
<body>
<p>This page was last modified on:
<script language="JavaScript" type="text/javascript">
document.write(document.lastModified);
</script>
</p>
</body>
</html></pre>
This can tell the user when the page was last changed. If you use JavaScript, you don't have to remember to update the date each time you modify the page. (You could also use the script to always print the current date instead of the last modified date, but that would be cheating.)
; By the Way: You might find that the <code>document.lastModified</code> property doesn't work on your web pages, or returns the wrong value. The date is received from the web server, and some servers do not maintain modification dates correctly.
=== Writing Text in a Document ===
The simplest document object methods are also the ones you will use most often. In fact, you've used one of them already. The document.write method prints text as part of the HTML page in a document window. This statement is used whenever you need to include output in a web page.
An alternative statement, <code>document.writeln</code>, also prints text, but it also includes a <code>newline (\n)</code> character at the end. This is handy when you want your text to be the last thing on the line.
; Watch Out!: Bear in mind that the newline character is displayed as a space by the browser, except inside a <code><nowiki><pre></nowiki></code> container. You will need to use the <code><nowiki><br></nowiki></code> tag if you want an actual line break.
You can use these methods only within the body of the web page, so they will be executed when the page loads. You can't use these methods to add to a page that has already loaded without reloading it.
; By the Way: You can also directly modify the text of a web page on newer browsers using the features of the new DOM. You'll learn these techniques in Hour 14.
The <code>document.write</code> method can be used within a <code><script></code> tag in the body of an <code>HTML</code> document. You can also use it in a function, provided you include a call to the function within the body of the document.
=== Using Links and Anchors ===
Another child of the document object is the link object. Actually, there can be multiple link objects in a document. Each one includes information about a link to another location or an anchor.
; Did you Know?: Anchors are named places in an HTML document that can be jumped to directly. You define them with a tag like this: <code><a name="part2"></code>. You can then link to them: <code><a href="#part2"></code>.
You can access link objects with the links array. Each member of the array is one of the link objects in the current page. A property of the array, <code>document.links.length</code>, indicates the number of links in the page.
Each link object (or member of the links array) has a list of properties defining the URL. The href property contains the entire URL, and other properties define portions of it. These are the same properties as the location object, defined later in this hour.
You can refer to a property by indicating the link number and property name. For example, the following statement assigns the entire URL of the first link to the variable link1:
<pre>link1 = links[0].href;</pre>
The anchor objects are also children of the document object. Each anchor object represents an anchor in the current documenta particular location that can be jumped to directly.
Like links, you can access anchors with an array: anchors. Each element of this array is an anchor object. The <code>document.anchors.length</code> property gives you the number of elements in the anchors array.
== Accessing Browser History ==
The <code>history</code> object is another child (property) of the <code>window</code> object. This object holds information about the URLs that have been visited before and after the current one, and it includes methods to go to previous or next locations.
The <code>history</code> object has one property you can access:
* <code>history.length</code> keeps track of the length of the history listin other words, the number of different locations that the user has visited.
; By the Way: The <code>history</code> object has <code>current</code>, <code>previous</code>, and <code>next</code> properties that store URLs of documents in the history list. However, for security and privacy reasons, these objects are not normally accessible in today's browsers.
The <code>history</code> object has three methods you can use to move through the history list:
* <code>history.go()</code> opens a URL from the history list. To use this method, specify a positive or negative number in parentheses. For example, <code>history.go(-2)</code> is equivalent to pressing the Back button twice.
* <code>history.back()</code> loads the previous URL in the history listequivalent to pressing the Back button.
* <code>history.forward()</code> loads the next URL in the history list, if available. This is equivalent to pressing the Forward button.
You'll use these methods in the Try It Yourself section at the end of this hour.
== Working with the <code>location</code> Object ==
A third child of the <code>window</code> object is the <code>location</code> object. This object stores information about the current URL stored in the window. For example, the following statement loads a URL into the current window:
<pre>window.location.href="http: //www.starlingtech.com";</pre>
The <code>HRef</code> property used in this statement contains the entire URL of the window's current location. You can also access portions of the URL with various properties of the <code>location</code> object. To explain these properties, consider the following URL:
<pre>http: //www.jsworkshop.com:80/test.cgi?lines=1#anchor</pre>
The following properties represent parts of the URL:
* <code>location.protocol</code> is the protocol part of the URL (<code>http:</code> in the example).
* <code>location.hostname</code> is the host name of the URL (<code>[http: //www.jsworkshop.com/ www.jsworkshop.com]</code> in the example).
* <code>location.port</code> is the port number of the URL (<code>80</code> in the example).
* <code>location.pathname</code> is the filename part of the URL (<code>test.cgi</code> in the example).
* <code>location.search</code> is the query portion of the URL, if any (<code>lines=1</code> in the example). Queries are used mostly by CGI scripts.
* <code>location.hash</code> is the anchor name used in the URL, if any (<code>#anchor</code> in the example).
The <code>link</code> object, introduced earlier this hour, also includes this list of properties for accessing portions of the URL.
; By the Way: Although the <code>location.href</code> property usually contains the same URL as the <code>document.URL</code> property described earlier in this hour, you can't change the <code>document.URL</code> property. Always use <code>location.href</code> to load a new page.
The <code>location</code> object has two methods:
* <code>location.reload()</code> reloads the current document. This is the same as the Reload button on the browser's toolbar. If you optionally include the <code>true</code> parameter, it will ignore the browser's cache and force a reload whether the document has changed or not.
* <code>location.replace()</code> replaces the current location with a new one. This is similar to setting the <code>location</code> object's properties yourself. The difference is that the <code>replace</code> method does not affect the browser's history. In other words, the Back button can't be used to go to the previous location. This is useful for splash screens or temporary pages that it would be useless to return to.
; Try It Yourself : Creating Back and Forward Buttons
You can use the <code>back</code> and <code>forward</code> methods of the <code>history</code> object to add your own Back and Forward buttons to a web document. The browser already has Back and Forward buttons, of course, but it's occasionally useful to include your own links that serve the same purpose.
You will now create a script that displays Back and Forward buttons and use these methods to navigate the browser. Here's the code that will create the Back button:
<pre><input type="button" onClick="history.back();" value="<-- Back">
</pre>
The <code><input></code> tag defines a button labeled Back. The <code>onClick</code> event handler uses the <code>history.back()</code> method to go to the previous page in history. The code for the Forward button is similar:
<pre>
<input type="button" onClick="history.forward();" value="Forward -->">
</pre>
With these out of the way, you just need to build the rest of the HTML document.
Listing 4.2 shows the complete HTML document, and Figure 4.2 shows a browser's display of the document. After you load this document into a browser, visit other URLs and make sure the Back and Forward buttons work.
; Listing 4.2. A Web Page That Uses JavaScript to Include Back and Forward Buttons
<pre>
<html>
<head><title>Back and Forward Buttons</title>
</head>
<body>
<h1> Back and Forward Buttons</h1>
<p>This page allows you to go back or forward to pages in the history list.
These should be equivalent to the back and forward arrow buttons in the
browser's toolbar.</p>
<p>
<input type="button" onClick="history.back();" value="<-- Back">
<input type="button" onClick="history.forward();" value="Forward" ->">
</p>
</body>
</html>
</pre>
== Summary ==
In this hour, you've learned about the Document Object Model (DOM), JavaScript's hierarchy of web page objects. You've learned how you can use the document object to work with documents, and used the history and location objects to control the current URL displayed in the browser.
You should now have a basic understanding of the DOM and some of its objectsyou'll learn about more of the objects throughout this book.
Congratulations! You've reached the end of Part I of this book. In Part II, you'll get back to learning the JavaScript language, starting with Hour 5, "Using Variables, Strings, and Arrays."
=== Q&A ===
Q1:
I can use history and document instead of window.history and window.document. Can I leave out the window object in other cases?
A1:
Yes. For example, you can use alert instead of window.alert to display a message. The window object contains the current script, so it's treated as a default object. However, be warned that you shouldn't omit the window object's name when you're using frames, layers, or multiple windows, or in an event handler.
Q2:
I used the document.lastModified method to display a modification date for my page, but it displays a date in 1970, or a date that I know is incorrect. What's wrong?
A2:
This function depends on the server sending the last modified date of the document to the browser. Some web servers don't do this properly, or require specific file attributes in order for this to work.
Q3:
Can I change history entries, or prevent the user from using the Back and Forward buttons?
A3:
You can't change the history entries. You can't prevent the use of the Back and Forward buttons, but you can use the location.replace() method to load a series of pages that don't appear in the history. There are a few tricks for preventing the Back button from working properly, but I don't recommend themthat's the sort of thing that gives JavaScript a bad name.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
1.
Which of the following objects can be used to load a new URL into the browser window?
document.url
window.location
window.url
2.
Which object contains the alert() method?
window
document
location
3.
Which of the following DOM levels describes the objects described in this hour?
DOM level 0
DOM level 1
DOM level 2
=== Quiz Answers ===
1.
b. The window.location object can be used to send the browser to a new URL.
2.
a. The window object contains the alert() method.
3.
a. The objects described in this hour fall under the informal DOM level 0 specification.
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
* Modify the Back and Forward example in Listing 4.2 to include a Reload button along with the Back and Forward buttons. (This button would trigger the location.reload() method.)
* Modify the Back and Forward example to display the current number of history entries.
-->
qfkicd9m26ispydh6qc7d71wyi1y0aw
User:Moncur/02
2
2076
39267
7060
2026-04-13T06:03:43Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39267
wikitext
text/x-wiki
= 2 Creating Simple Scripts =
== Tools for Scripting ==
Unlike many programming languages, you won't need any special software to create JavaScript scripts. In fact, you probably already have everything you need.
=== Text Editors ===
The first tool you'll need to work with JavaScript is a text editor. JavaScript scripts are stored in simple text files, usually as part of HTML documents. Any editor that can store ASCII text files will work.
You can choose from a wide range of editors, from simple text editors to word processors. If you don't have a favorite editor already, a simple editor is most likely included with your computer. For Windows computers, the Notepad accessory will work just fine.
; Watch Out:If you use a word processor to create JavaScript programs, be sure you save the files as ASCII text rather than as word processing documents. Otherwise, the browser might not recognize them.
A variety of dedicated HTML editors is also available and will work with JavaScript. In fact, many include features specifically for JavaScript, for example, color-coding the various JavaScript statements to indicate their purposes, or even creating simple scripts automatically.
For Windows computers, here are a few recommended editors:
* '''HomeSite''' An excellent HTML editor that includes JavaScript support. HomeSite is included as part of Adobe Dreamweaver and is also available separately.
* '''Microsoft FrontPage 2003''' Microsoft's visual HTML editor. The Script Builder component enables you to easily create simple scripts.
* '''TextPad''' A powerful text editor that includes a number of features missing from Notepad. TextPad's view of a JavaScript document is shown in Figure 2.1.
The following editors are available for both Windows and Macintosh:
* '''Adobe Dreamweaver''' A visually oriented editor that works with HTML, JavaScript, and Macromedia's Flash plug-in.
* '''Adobe GoLive''' A visual and HTML editor that also includes features for designing and organizing the structure of large sites.
Additionally for the Macintosh, BBEdit, TextWrangler, and Alpha are good HTML editors that you can use to create web pages and scripts.
; By the Way: Appendix B, "Tools for JavaScript Developers," includes web addresses to download these and other HTML and JavaScript editors.
=== Browsers ===
You'll need two other things to work with JavaScript: a web browser and a computer to run it on. Because this book covers new features introduced up to JavaScript 1.5 and the latest W3C DOM, I recommend that you use the latest version of Mozilla Firefox or Microsoft Internet Explorer. See the Mozilla (http:// www.mozilla.com) or Microsoft (http:// www.microsoft.com) website to download a copy.
At a minimum, you should have Firefox 1.0, Netscape 7.0, or Internet Explorer 6.0 or later. Although Netscape 4.x and Internet Explorer 4 will run many of the scripts in this book, they don't support a lot of the latest features you'll learn about.
You can choose whichever browser you like for your web browsing, but for developing JavaScript you should have more than one browser, at a minimum, Firefox and Internet Explorer. This will allow you to test your scripts in the common browsers users will employ on your site.
; By the Way:If you plan on making your scripts available over the Internet, you'll also need a web server, or access to one. However, you can use most of the JavaScript examples in this book directly from your computer's hard disk.
== Displaying Time with JavaScript ==
One common and easy use for JavaScript is to display dates and times. Because JavaScript runs on the browser, the times it displays will be in the user's current time zone. However, you can also use JavaScript to calculate "universal" (UTC) time.
; By the Way:UTC stands for Universal Time (Coordinated), and is the atomic time standard based on the old GMT (Greenwich Mean Time) standard. This is the time at the Prime Meridian, which runs through Greenwich, London, England.
As a basic introduction to JavaScript, you will now create a simple script that displays the current time and the UTC time within a web page.
=== Beginning the Script ===
Your script, like most JavaScript programs, begins with the HTML <script> tag. As you learned in Hour 1, you use the <script> and </script> tags to enclose a script within the HTML document.
; Watch Out: Remember to include only valid JavaScript statements between the starting and ending <script> tags. If the browser finds anything but valid JavaScript statements within the <script> tags, it will display a JavaScript error message.
To begin creating the script, open your favorite text editor and type the beginning and ending <script> tags as shown.
<script LANGUAGE="JavaScript" type="text/javascript">
</script>
Because this script does not use any of the new features of JavaScript 1.1 or later, you won't need to specify a version number in the <script> tag. This script should work with all browsers going back to Netscape 2.0 or Internet Explorer 3.0.
=== Adding JavaScript Statements ===
Your script now needs to determine the local and UTC times, and then display them to the browser. Fortunately, all of the hard parts, such as converting between date formats, are built in to the JavaScript interpreter.
=== Storing Data in Variables ===
To begin the script, you will use a variable to store the current date. You will learn more about variables in Hour 5, "Using Variables, Strings, and Arrays." A variable is a container that can hold a value, a number, some text, or in this case, a date.
To start writing the script, add the following line after the first <script> tag. Be sure to use the same combination of capital and lowercase letters in your version because JavaScript commands and variable names are case sensitive.
now = new Date();
This statement creates a variable called now and stores the current date and time in it. This statement and the others you will use in this script use JavaScript's built-in Date object, which enables you to conveniently handle dates and times. You'll learn more about working with dates in Hour 8, "Using Built-in Functions and Libraries."
; By the Way:Notice the semicolon at the end of the previous statement. This tells the browser that it has reached the end of a statement. Semicolons are optional, but using them helps you avoid some common errors. We'll use them throughout this book for clarity.
=== Calculating the Results ===
Internally, JavaScript stores dates as the number of milliseconds since January 1, 1970. Fortunately, JavaScript includes a number of functions to convert dates and times in various ways, so you don't have to figure out how to convert milliseconds to day, date, and time.
To continue your script, add the following two statements before the final </script> tag:
localtime = now.toString();
utctime = now.toUTCString();
These statements create two new variables: <sup>localtime</sup>, containing the current time and date in a nice readable format, and <sup>utctime</sup>, containing the UTC equivalent.
=== By the Way ===
The <sup>localtime</sup> and <sup>utctime</sup> variables store a piece of text, such as January 1, 2001 12:00 PM. In programming parlance, a piece of text is called a <sup>string</sup>. You will learn more about strings in Hour 5.
== Creating Output ==
You now have two variables, <code>localtime </code> and <code>utctime</code>, which contain the results we want from our script. Of course, these variables don't do us much good unless we can see them. JavaScript includes a number of ways to display information, and one of the simplest is the <code>document.write</code> statement.
The <code>document.write</code> statement displays a text string, a number, or anything else you throw at it. Because your JavaScript program will be used within a web page, the output will be displayed as part of the page. To display the result, add these statements before the final <sub></script></sub> tag:
<pre>
document.write("<b>Local time:</b> " + localtime + "<br>");
document.write("<b>UTC time:</b> " + utctime);
</pre>
These statements tell the browser to add some text to the web page containing your script. The output will include some brief strings introducing the results, and the contents of the <code>localtime </code> and <code>utctime</code> variables.
Notice the HTML tags, such as <nowiki><b></nowiki> , within the quotation marks, because JavaScript's output appears within a web page, it needs to be formatted using HTML. The <nowiki><br></nowiki> tag in the first line ensures that the two times will be displayed on separate lines.
; By the Way:Notice the <code>plus signs (+)</code> used between the text and variables in the previous statements. In this case, it tells the browser to combine the values into one string of text. If you use the plus sign between two numbers, they are added together.
== Adding the Script to a Web Page ==
You should now have a complete script that calculates a result and displays it. Your listing should match Listing 2.1.
; Listing 2.1. The Complete Date and Time Script
<pre>
<script language="JavaScript" type="text/javascript">
now = new Date();
localtime = now.toString();
utctime = now.toUTCString();
document.write("<b>Local time:</b> " + localtime + "<BR>");
document.write("<b>UTC time:</b> " + utctime);
</script></pre>
To use your script, you'll need to add it to an HTML document. In its most basic form, the HTML document should include opening and closing <code><html> tags, <head> tags, and <body></code> tags.
If you add these tags to the document containing your script along with a descriptive heading, you should end up with something like Listing 2.2.
; Listing 2.2. The Date and Time Script in an HTML Document
<pre><html>
<head><title>Displaying Times and Dates</title></head>
<body>
<h1>Current Date and Time</h1>
<p>
<script language="JavaScript" type="text/javascript">
now = new Date();
localtime = now.toString();
utctime = now.toUTCString();
document.write("<b>Local time:</b> " + localtime + "<BR>");
document.write("<b>UTC time:</b> " + utctime);
</script>
</p>
</body>
</html></pre>
Now that you have a complete HTML document, save it with the .htm or .html extension.
; By the Way:Notepad and other Windows text editors might try to be helpful and add the .txt extension to your script. Be sure your saved file has the correct extension.
== Testing the Script ==
To test your script, you simply need to load the HTML document you created in a web browser. Start Netscape or Internet Explorer and select Open from the File menu. Click the Choose File or Browse button, and then find your HTML file. After you've selected it, click the Open button to view the page.
If you typed the script correctly, your browser should display the result of the script, as shown in Figure 2.2. (Of course, your result won't be the same as mine, but it should be the same as the setting of your computer's clock.)
A note about Internet Explorer 6.0 and above: Depending on your security settings, the script might not execute, and a yellow highlighted bar on the top of the browser might display a security warning. In this case, click the yellow bar and select Allow Blocked Content to allow your script to run. (This happens because the default security settings allow JavaScript in online documents, but not in local files.)
; Did you Know?:You can download the HTML document for this hour from this book's website. If the version you type doesn't work, try downloading the online version.
=== Modifying the Script ===
Although the current script does indeed display the current date and time, its display isn't nearly as attractive as the clock on your wall or desk. To remedy that, you can use some additional JavaScript features and a bit of HTML to display a large clock.
To display a large clock, we need the hours, minutes, and seconds in separate variables. Once again, JavaScript has built-in functions to do most of the work:
<pre>
hours = now.getHours();
mins = now.getMinutes();
secs = now.getSeconds();</pre>
These statements load the hours, mins, and secs variables with the components of the time using JavaScript's built-in date functions.
After the hours, minutes, and seconds are in separate variables, you can create document.write statements to display them:
<pre>
document.write("<h1>");
document.write(hours + ":" + mins + ":" + secs);
document.write("</h1>");
</pre>
<nowiki>The first statement displays an HTML <h1> header tag to display the clock in a large typeface. The second statement displays the hours, mins, and secs variables, separated by colons, and the third adds the closing </h1> tag.</nowiki>
You can add the preceding statements to the original date and time script to add the large clock display. Listing 2.3 shows the complete modified version of the script.
<pre>
<html>
<head><title>Displaying Times and Dates</title></head>
<body>
<h1>Current Date and Time</h1>
<p>
<script language="JavaScript">
now = new Date();
localtime = now.toString();
utctime = now.toUTCString();
document.write("<b>Local time:</b> " + localtime + "<BR>");
document.write("<b>UTC time:</b> " + utctime);
hours = now.getHours();
mins = now.getMinutes();
secs = now.getSeconds();
document.write("<h1>");
document.write(hours + ":" + mins + ":" + secs);
document.write("</h1>");
</script>
</p>
</body>
</html>
</pre>
Now that you have modified the script, save the HTML file and open the modified file in your browser. If you left the browser running, you can simply use the Reload button to load the new version of the script. Try it and verify that the same time is displayed in both the upper portion of the window and the new large clock.
; By the Way:The time formatting produced by this script isn't perfect: Hours after noon are in 24-hour time, and there are no leading zeroes, so 12:04 is displayed as 12:4. See Hour 8, "Using Built-in Functions and Libraries," for solutions to these issues.
=== Dealing with JavaScript Errors ===
As you develop more complex JavaScript applications, you're going to run into errors from time to time. JavaScript errors are usually caused by mistyped JavaScript statements.
To see an example of a JavaScript error message, modify the statement you added in the previous section. We'll use a common error: omitting one of the parentheses. Change the last <code>document.write</code> statement in Listing 2.3 to read
<pre>
document.write("</h1>";</pre>
Save your HTML document again and load the document into the browser. Depending on the browser version you're using, one of two things will happen: Either an error message will be displayed, or the script will simply fail to execute.
If an error message is displayed, you're halfway to fixing the problem by adding the missing parenthesis. If no error was displayed, you should configure your browser to display error messages so that you can diagnose future problems:
In Netscape or Firefox, type <code>javascript:</code> into the browser's Location field to display the JavaScript Console. In Firefox, you can also select Tools, JavaScript Console from the menu. The console is shown in Figure 2.4, displaying the error message you created in this example.
In Internet Explorer, select Tools, Internet Options. On the Advanced page, uncheck the Disable Script Debugging box and check the Display a Notification About Every Script Error box. (If this is disabled, a yellow icon in the status bar will still notify you of errors.)
; By the Way:Notice the field at the top of the JavaScript Console. This enables you to type a JavaScript statement, which will be executed immediately. This is a handy way to test JavaScript's features.
The error we get in this case is missing ) after argument list (Firefox) or Expected ')' (Internet Explorer), which turns out to be exactly the problem. Be warned, however, that error messages aren't always this enlightening.
While Internet Explorer displays error dialog boxes for each error, Firefox's JavaScript Console displays a single list of errors and allows you to test commands. For this reason, you might find it useful to install Firefox for debugging and testing JavaScript, even if Internet Explorer is your primary browser.
; Did you Know?:As you develop larger JavaScript applications, finding and fixing errors becomes more important. You'll learn more about dealing with JavaScript errors in Hour 16, "Debugging JavaScript Applications."
=== Try It Yourself Using a Separate JavaScript File ===
Although simple scripts like this one can be embedded in an HTML file, as in the previous example, it's good practice to separate the HTML and JavaScript by using a separate JavaScript file. This has a few advantages:
Browsers with JavaScript disabled, or older browsers that don't support it, will ignore the script.
When multiple pages on your site use the same script, the browser only has to load the JavaScript file once, and use a cached copy on other pages.
It's easier to maintain the HTML and JavaScript code when they're separated, especially if different people are working on the design and the scripting.
We'll also be using separate JavaScript files for most of the examples in this book, so you should be familiar with this technique.
To use a separate JavaScript file with the date and time example, you will need two files. A quick way to create them is to save the combined HTML/JavaScript file in Listing 2.3 to two files, and then edit them.
The first file, datetime.html, will be the HTML file. Remove everything between the <script> tags, and add the src="datetime.js" attribute to the opening <script> tag. The resulting file is shown in Listing 2.4.
; Listing 2.4. HTML File for the Date and Time Script (datetime.html)
<pre>
<html>
<head><title>Displaying Times and Dates</title></head>
<body>
<h1>Current Date and Time</h1>
<p>
<script language="JavaScript" type="text/javascript" src="datetime.js">
</script>
</p>
</body>
</html>
</pre>
The second file, datetime.js, will contain only JavaScript commandsthe same ones you removed from the HTML file. This file should not include <script> tags, or any HTML tags. The JavaScript file is shown in Listing 2.5.
; Listing 2.5. The Date and Time Script (datetime.js)
<pre>
now = new Date();
localtime = now.toString();
utctime = now.toUTCString();
document.write("<b>Local time:</b> " + localtime + "<BR>");
document.write("<b>UTC time:</b> " + utctime);
hours = now.getHours();
mins = now.getMinutes();
secs = now.getSeconds();
document.write("<h1>");
document.write(hours + ":" + mins + ":" + secs);
document.write("</h1>");</pre>
; By the Way:If Internet Explorer displays a warning message in a yellow bar at the top of the browser window instead of executing your script, simply click the bar and select Allow Blocked Content.
As you create larger scripts, you'll find it far less confusing to keep the HTML and JavaScript in separate files. The next hour discusses this and other best practices for JavaScript.
== Summary ==
During this hour, you wrote a simple JavaScript program and tested it using a browser. You learned about the tools you need to work with JavaScript, basically, an editor and a browser. You also learned how to modify and test scripts, and what happens when a JavaScript program runs into an error. Finally, you learned how to use scripts in separate JavaScript files.
In the process of writing this script, you have used some of JavaScript's basic features: <code>variables</code>, the <code>document.write</code> <code>statement</code>, and <code>functions </code>for working with dates and times.
Now that you've learned a bit of JavaScript syntax, you're ready to learn more of the details. You'll do that in Hour 3, "Getting Started with JavaScript Programming."
=== Q&A ===
Q1:
Why do I need more than one browser to test scripts? Won't JavaScript behave the same way on both browsers?
A1:
Although JavaScript is standardized, the browsers don't interpret it in exactly the same way. Your script might have minor flaws that have no effect in one browser but cause an error in another. Also, as you move on to more advanced features of JavaScript, you'll need to deal with browsers in different ways, as described in Hour 15, "Unobtrusive Scripting," and you'll need to test each one.
Q2:
When I try to run my script, the browser displays the actual script in the browser window instead of executing it. What did I do wrong?
A2:
This is most likely caused by one of three errors. First, you might be missing the beginning or ending <code><script> </code> tags. Check them, and verify that the first reads <code><script LANGUAGE="JavaScript" type="text/javascript"></code>. Second, your file might have been saved with a .txt extension, causing the browser to treat it as a text file. Rename it to <code>.htm or .html</code> to fix the problem. Third, make sure your browser supports JavaScript, and that it is not disabled in the <code>Preferences</code> dialog.
Q3:
Why are the <code><nowiki><b></nowiki></code> and <code><nowiki><br></nowiki></code> tags allowed in the statements to print the time? I thought <code>HTML tags</code> weren't allowed within the <code><script></code> tags.
A3:
Because this particular tag is inside quotation marks, it's considered a valid part of the script. The script's output, including any <code>HTML tags</code>, is interpreted and displayed by the browser. You can use other HTML tags within quotation marks to add formatting, such as the <code><nowiki><h1></nowiki></code> tags we added for the large clock display.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
1.
What software do you use to create and edit JavaScript programs?
A browser
A text editor
A pencil and a piece of paper
2.
What are variables used for in JavaScript programs?
Storing numbers, dates, or other values
Varying randomly
Causing high school algebra flashbacks
3.
What should appear at the very end of a JavaScript script embedded in an HTML file?
The <code><tt><script LANGUAGE="JavaScript"></code></tt> tag
The <code><tt></script></code></tt> tag
The END statement
=== Quiz Answers ===
1.
b. Any text editor can be used to create scripts. You can also use a word processor if you're careful to save the document as a text file with the .html or .htm extension.
2.
a. Variables are used to store numbers, dates, or other values.
3.
b. Your script should end with the <code></script></code> tag.
=== Exercises ===
To further your knowledge of <code>JavaScript</code>, perform the following exercises:
Add a millisecond field to the large clock. You can use the <code><tt>getMilliseconds</code> function</tt>, which works just like <code>getSeconds</code> but returns milliseconds.
Modify the script to display the time, including milliseconds, twice. Notice whether any time passes between the two time displays when you load the page.
-->
06dtbxkdifsg404e3toto9aeuct3epo
User:Moncur/03
2
2077
39268
5826
2026-04-13T06:03:43Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39268
wikitext
text/x-wiki
=3. Getting Started with JavaScript Programming=
== Basic Concepts ==
There are a few basic concepts and terms you'll run into throughout this book. In the following sections, you'll learn about the basic building blocks of JavaScript.
=== Statements ===
Statements are the basic units of a JavaScript program. A <code>statement </code> is a section of code that performs a ''single action''. For example, the following three statements are from the date and time example in Hour 2, "Creating Simple Scripts":
<pre>
hours = now.getHours();
mins = now.getMinutes();
secs = now.getSeconds();</pre>
Although a statement is typically a single line of JavaScript, this is not a rule, it's possible to break a statement across multiple lines, or to include more than one statement in a single line.
A <code>semicolon </code> marks the end of a statement. You can also omit the semicolon if you start a new line after the statement. If you combine statements into a single line, you must use semicolons to separate them.
=== Combining Tasks with Functions ===
In the basic scripts you've examined so far, you've seen some JavaScript statements that have a section in parentheses, like this:
<code>document.write("Testing.");</code>
This is an example of a <code>function</code>. Functions provide a simple way to handle a task, such as adding <code>output </code>to a web page. JavaScript includes a wide variety of <code>built-in functions</code>, which you will learn about throughout this book. A <code>statement </code>that uses a function, as in the preceding example, is referred to as a <code>function call</code>.
Functions take <code>parameters </code>(the expression inside the <code>parentheses</code>) to tell them what to do. Additionally, a function can return a value to a waiting <code>variable</code>. For example, the following function call prompts the user for a response and stores it in the <code>text </code>variable:
<code>text = prompt("Enter some text.")</code>
You can also create your own functions. This is useful for two main reasons: First, you can separate logical portions of your script to make it easier to understand. Second, and more importantly, you can use the function several times or with different data to avoid repeating script statements.
; By the Way : You will learn how to define, call, and return values from your own functions in Hour 6, "Using Functions and Objects."
=== Variables ===
In Hour 2, you learned that variables are containers that can store a number, a string of text, or another value. For example, the following statement creates a variable called <code>fred </code>and assigns it the value 27:
<code>var fred = 27;</code>
JavaScript variables can contain numbers, text strings, and other values. You'll learn more about them in Hour 5, "Using Variables, Strings, and Arrays."
=== Understanding Objects ===
JavaScript also supports <code>objects</code>. Like variables, objects can store data, but they can store two or more pieces of data at once.
The items of data stored in an object are called the properties of the object. For example, you could use objects to store information about people such as in an address book. The properties of each person object might include a name, an address, and a telephone number.
JavaScript uses <code>periods </code>to separate object names and property names. For example, for a person object called Bob, the properties might include <code>Bob.address</code> and <code>Bob.phone</code>.
Objects can also include <code>methods</code>. These are functions that work with the object's data. For example, our person object for the address book might include a display() method to display the person's information. In JavaScript terminology, the statement Bob.display() would display Bob's details.
; By the Way : The <code>document.write</code> function we discussed earlier this hour is actually the write method of the document object. You will learn more about this object in Hour 4, "Working with the Document Object Model (DOM)."
Don't worry if this sounds confusing, you'll be exploring objects in much more detail later in this book. For now, you just need to know the basics. JavaScript supports three kinds of objects:
* ''Built-in objects'' are built in to the JavaScript language. You've already encountered one of these, <code>Date</code>, in Hour 2. Other built-in objects include <code>Array </code>and <code>String</code>, which you'll explore in Hour 5, and <code>Math</code>, which is explained in Hour 8, "Using Built-in Functions and Libraries."
* ''DOM (Document Object Model)'' objects represent various components of the browser and the current HTML document. For example, the <code>alert()</code> function you used earlier in this hour is actually a method of the <code>window </code>object. You'll explore these in more detail in Hour 4.
* ''Custom objects'' are objects you create yourself. For example, you could create a <code>person </code>object, as in the examples in this section. You'll learn to use custom objects in Hour 6.
=== Conditionals ===
Although <code>event handlers</code> notify your script when something happens, you might want to check certain conditions yourself. For example, did the user enter a valid email address?
JavaScript supports <code>conditional statements</code>, which enable you to answer questions like this. A typical conditional uses the <code>if</code> statement, as in this example:
<code>if (count==1) alert("The countdown has reached 1.");</code>
This compares the variable count with the constant 1, and displays an alert message to the user if they are the same. You will use conditional statements like this in most of your scripts.
; By the Way : You'll learn more about conditionals in Hour 7, "Controlling Flow with Conditions and Loops."
=== Loops ===
Another useful feature of JavaScript, and most other programming languages, is the capability to create <code>loops</code>, or groups of statements that repeat a certain number of times. For example, these statements display the same alert 10 times, greatly annoying the user:
<pre>for (i=1; i<=10; i++) {
Alert("Yes, it's yet another alert!");
}</pre>
The for statement is one of several statements JavaScript uses for loops. This is the sort of thing computers are supposed to be good at: performing repetitive tasks. You will use loops in many of your scripts, in much more useful ways than this example.
; By the Way: Loops are covered in detail in Hour 7.
=== Event Handlers ===
As mentioned in Hour 1, "Understanding JavaScript," not all scripts are located within <code><script></code> tags. You can also use scripts as event handlers. Although this might sound like a complex programming term, it actually means exactly what it says: <code>Event handlers are scripts that handle events</code>.
In real life, an event is something that happens to you. For example, the things you write on your calendar are events: "Dentist appointment" or "Fred's birthday." You also encounter <code>unscheduled events</code> in your life: for example, a traffic ticket, an <code>IRS audit</code>, or an unexpected visit from relatives.
Whether events are scheduled or unscheduled, you probably have normal ways of handling them. Your event handlers might include things such as <code>When </code>Fred's birthday arrives, send him a present or <code>When </code>relatives visit unexpectedly, turn out the lights and pretend nobody is home.
Event handlers in JavaScript are similar: They tell the browser what to do when a certain event occurs. The events JavaScript deals with aren't as exciting as the ones you deal with, they include such events as <code>When </code>the mouse button clicks and <code>When </code>this page is finished loading. Nevertheless, they're a very useful part of JavaScript.
Many JavaScript events (such as mouse clicks) are caused by the user. Rather than doing things in a set order, your script can <code>respond </code>to the user's actions. Other events don't involve the user directly, for example, an event is triggered when an HTML document <code>finishes loading</code>.
Each event handler is associated with a particular <code>browser object</code>, and you can specify the event handler in the tag that defines the object. For example, <code>images </code>and <code>text links</code> have an event, <code>onMouseOver</code>, that happens when the mouse pointer moves over the object. Here is a typical HTML image tag with an event handler:
<pre>
<img src="button.gif" onMouseOver="highlight();""></pre>
You specify the event handler as an <code>attribute </code>to the HTML tag and include the JavaScript statement to handle the event within the quotation marks. This is an ideal use for functions because function names are short and to the point and can refer to a whole series of statements.
See the Try It Yourself section at the end of this hour for a complete example of an event handler within an HTML document.
; By the Way: You can also define event handlers within JavaScript without using HTML attributes. You'll learn this technique, and more about event handlers, in Hour 9, "Responding to Events."
=== Which Script Runs First? ===
You can actually have several scripts within a web document: one or more sets of <code><script></code> tags, external JavaScript files, and any number of event handlers. With all of these scripts, you might wonder how the browser knows which to execute first. Fortunately, this is done in a logical fashion:
Sets of <code><script></code> tags within the <code><head></code> section of an HTML document are handled <code>first</code>, whether they include embedded code or refer to a JavaScript file. Because these scripts <code>cannot create output in the web page</code>, it's a good place to <code>define </code>functions for use later.
Sets of <code><script></code> tags within the <code><body></code> section of the HTML document are executed after those in the <code><head></code> section, while the web page loads and displays. If there is more than one script in the body, they are executed in order.
Event handlers are executed when their events happen. For example, the <code>onLoad</code> event handler is executed when the body of a web page loads. Because the <code><head></code> section is loaded before any events, you can <code>define functions</code> there and use them in event handlers.
== JavaScript Syntax Rules ==
JavaScript is a simple language, but you do need to be careful to use its syntax, the rules that define how you use the language correctly. The rest of this book covers many aspects of JavaScript syntax, but there are a few basic rules you should understand to avoid errors.
=== Case Sensitivity ===
Almost everything in JavaScript is case sensitive: you cannot use lowercase and capital letters interchangeably. Here are a few general rules:
* <code>JavaScript keywords</code>, such as <code>for </code>and <code>if</code>, are always lowercase.
* <code>Built-in objects</code> such as <code>Math </code>and <code>Date </code>are capitalized.
* <code>DOM object names</code> are usually lowercase, but their methods are often a combination of capitals and lowercase. Usually capitals are used for all but the first word, as in <code>toLowerCase </code>and <code>getElementById</code>.
When in doubt, follow the exact case used in this book or another JavaScript reference. If you use the wrong case, the browser will usually display an error message.
=== Variable, Object, and Function Names ===
When you define your own <code>variables, objects, or functions</code>, you can choose their names. Names can include uppercase letters, lowercase letters, numbers, and the <code>underscore </code>(_) character. Names must begin with a letter or underscore.
You can choose whether to use capitals or lowercase in your <code>variable </code>names, but remember that JavaScript is case sensitive: score, Score, and SCORE would be considered three different variables. Be sure to use the same name each time you refer to a variable.
=== Reserved Words ===
One more rule for variable names: they must not be reserved words. These include the words that make up the JavaScript language, such as if and for, DOM object names such as window and document, and built-in object names such as Math and Date. A complete list of reserved words is included in Appendix D, "JavaScript Quick Reference."
=== Spacing ===
Blank space (known as whitespace by programmers) is ignored by JavaScript. You can include spaces and tabs within a line, or blank lines, without causing an error. Blank space often makes the script more readable.
== Using Comments ==
JavaScript comments enable you to include documentation within your script. This will be useful if someone else tries to understand the script, or even if you try to understand it after a long break. To include comments in a JavaScript program, begin a line with <code>two slashes</code>, as in this example:
<pre>//this is a comment.</pre>
You can also begin a comment with two slashes in the middle of a line, which is useful for documenting a script. In this case, everything on the line after the slashes is treated as a comment and ignored by the browser. For example,
<pre>a = a + 1; // add one to the value of a</pre>
JavaScript also supports <code>C-style comments</code>, which begin with <code>/*</code> and end with <code>*/</code>. These comments can extend across more than one line, as the following example demonstrates:
<pre>/*This script includes a variety
of features, including this comment. */</pre>
Because JavaScript statements within a comment are ignored, C-style comments are often used for commenting out sections of code. If you have some lines of JavaScript that you want to temporarily take out of the picture while you debug a script, you can add /* at the beginning of the section and */ at the end.
; By the Way: Because these comments are part of JavaScript syntax, they are only valid inside <code><script></code> tags or within an external JavaScript file.
== Best Practices for JavaScript ==
You should now be familiar with the basic rules for writing valid JavaScript. Along with following the rules, it's also a good idea to follow<code> best practices</code>. The following practices may not be required, but you'll save yourself and others some headaches if you follow them.
; Use comments liberally: These make your code easier for others to understand, and also easier for you to understand when you edit them later. They are also useful for marking the major divisions of a script.
; Use a semicolon at the end of each statement, :and only use one statement per line This will make your scripts easier to debug.
; Use separate JavaScript files whenever possible : This separates JavaScript from HTML and makes debugging easier, and also encourages you to write modular scripts that can be reused.
; Avoid being browser-specific: As you learn more about JavaScript, you'll learn some features that only work in one browser. Avoid them unless absolutely necessary, and always test your code in more than one browser.
; Keep JavaScript optional: Don't use JavaScript to perform an essential function on your sitefor example, the primary navigation links. Whenever possible, users without JavaScript should be able to use your site, although it may not be quite as attractive or convenient. This strategy is known as progressive enhancement.
There are many more best practices involving more advanced aspects of JavaScript. These are covered in detail in Hour 15, "Unobtrusive Scripting."
=== Try It Yourself Using an Event Handler ===
To conclude this hour, here's a simple example of an event handler. This will demonstrate how you <code>set up an event</code>, which you'll use throughout this book, and how JavaScript works without<code> <script> </code>tags. Listing 3.1 shows an HTML document that includes a simple event handler.
; Listing 3.1. An HTML Document with a Simple Event Handler:
<pre>
<html>
<head>
<title>Event Handler Example</title>
</head>
<body>
<h1>Event Handler Example</h1>
<p>
<a href="http://www.jsworkshop.com/" onClick="alert('Aha! An Event!');">Click this link</a>
to test an event handler.
</p>
</body>
</html></pre>
The event handler is defined with the following <code>onClick </code>attribute within the<code> <a></code> tag that defines a link:
<pre>onClick="alert('Aha! An Event!");"</pre>
This event handler uses the built-in <code>alert()</code> function to display a message when you click on the link. In more complex scripts, you will usually define your own function to act as an event handler. Figure 3.1 shows this example in action.
You'll use other event handlers similar to this in the next hour, and events will be covered in more detail in Hour 9.
; Did you Know?: Notice that after you click the OK button on the alert, the browser follows the link defined in the <code><a></code> tag. Your event handler could also stop the browser from following the link, as described in Hour 9.
== Summary ==
During this hour, you've been introduced to several components of JavaScript programming and syntax: functions, objects, event handlers, conditions, and loops. You also learned how to use JavaScript comments to make your script easier to read, and looked at a simple example of an event handler.
In the next hour, you'll look at the Document Object Model (DOM) and learn how you can use the objects within the DOM to work with web pages and interact with users.
=== Q&A ===
Q1:
I've heard the term object-oriented applied to languages such as C++ and Java. If JavaScript supports objects, is it an object-oriented language?
A1:
Yes, although it might not fit some people's strict definitions. JavaScript objects do not support all of the features that languages such as C++ and Java support, although the latest versions of JavaScript have added more object-oriented features.
Q2:
Having several scripts that execute at different times seems confusing. Why would I want to use event handlers?
A2:
Event handlers are the ideal way (and in JavaScript, the only way) to handle gadgets within the web page, such as buttons, check boxes, and text fields. It's actually more convenient to handle them this way. Rather than writing a script that sits and waits for a button to be pushed, you can simply create an event handler and let the browser do the waiting for you.
Q3:
Some examples in other books suggest enclosing scripts in HTML comments (<nowiki><!--</nowiki> and <nowiki>--></nowiki>) to hide the script from older browsers. Is this necessary?
A3:
This technique was only necessary for supporting very old browsers, such as Netscape 2.0. I no longer recommend this because all modern browsers handle JavaScript correctly. If you are still concerned about non-JavaScript browsers, the best way to hide your script is to use an external JavaScript file, as described in Hour 2.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
1.
A script that executes when the user clicks the mouse button is an example of what?
An object
An event handler
An impossibility
2.
Which of the following are capabilities of functions in JavaScript?
Accept parameters
Return a value
Both of the above
3.
Which of the following is executed first by a browser?
A script in the <head> section
A script in the <body> section
An event handler for a button
=== Quiz Answers ===
1.
b. A script that executes when the user clicks the mouse button is an event handler.
2.
c. Functions can accept both parameters and return values.
3.
a. Scripts defined in the <head> section of an HTML document are executed first by the browser.
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
Examine the Date and Time script you created in Hour 2 and find any examples of functions and objects being used.
Add JavaScript comments to the Date and Time script to make it more clear what each line does. Verify that the script still runs properly.
-->
th2918ahx1debk123vwujgq4p11y3dp
User:Moncur/01
2
2078
39266
5819
2026-04-13T06:03:42Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39266
wikitext
text/x-wiki
=1 Understanding JavaScript=
The World Wide Web (WWW) began as a text-only medium, the first browsers didn't even support images within web pages. Although it's still not quite ready to give television a run for its money, the Web has come a long way since then.
Today's websites can include a wealth of features: graphics, sounds, animation, video, and occasionally useful content. Web scripting languages, such as JavaScript, are one of the easiest ways to spice up a web page and to interact with users in new ways.
The first hour of this book introduces the concept of web scripting and the JavaScript language. It also describes how JavaScript fits in with other web languages.
== Learning Web Scripting Basics ==
In the world of science fiction movies (and many other movies that have no excuse), computers are often seen obeying commands in English. Although this might indeed happen in the near future, computers currently find it easier to understand languages such as BASIC, C, and Java.
If you know how to use HTML (Hypertext Markup Language) to create a web document, you've already worked with one computer language. You use HTML tags to describe how you want your document formatted, and the browser obeys your commands and shows the formatted document to the user.
Because HTML is a simple text markup language, it can't respond to the user, make decisions, or automate repetitive tasks. Interactive tasks such as these require a more sophisticated language: a programming language, or a scripting language.
Although many programming languages are complex, scripting languages are generally simple. They have a simple syntax, can perform tasks with a minimum of commands, and are easy to learn. Web scripting languages enable you to combine scripting with HTML to create interactive web pages.
=== Scripts and Programs ===
A movie or a play follows a script, a list of actions (or lines) for the actors to perform. A web script provides the same type of instructions for the web browser. A script in JavaScript can range from a single line to a full-scale application. (In either case, JavaScript scripts usually run within a browser.)
; By the Way
: Is JavaScript a scripting language or a programming language? It depends on who you ask. We'll refer to scripting throughout this book, but feel free to include JavaScript programming on your résumé after you've finished this book.
Some programming languages must be compiled, or translated, into machine code before they can be executed. JavaScript, on the other hand, is an interpreted language: The browser executes each line of script as it comes to it.
There is one main advantage to interpreted languages: Writing or changing a script is very simple. Changing a JavaScript script is as easy as changing a typical HTML document, and the change is enacted as soon as you reload the document in the browser.
; By the Way
: Interpreted languages have their disadvantages. They can't execute really quickly, so they're not ideally suited for complicated work, such as graphics. Also, they require the interpreter (in JavaScript's case, usually a browser) in order to work.
=== Introducing JavaScript ===
JavaScript was developed by Netscape Communications Corporation, the maker of the Netscape web browser. JavaScript was the first web scripting language to be supported by browsers, and it is still by far the most popular.
; By the Way
: A bit of history: JavaScript was originally called LiveScript and was first introduced in Netscape Navigator 2.0 in 1995. It was soon renamed JavaScript to indicate a marketing relationship with Sun's Java language.
JavaScript is almost as easy to learn as HTML, and it can be included directly in HTML documents. Here are a few of the things you can do with JavaScript:
* Display messages to the user as part of a web page, in the browser's status line, or in alert boxes
* Validate the contents of a form and make calculations (for example, an order form can automatically display a running total as you enter item quantities)
* Animate images or create images that change when you move the mouse over them
* Create ad banners that interact with the user, rather than simply displaying a graphic
* Detect the browser in use or its features and perform advanced functions only on browsers that support them
* Detect installed plug-ins and notify the user if a plug-in is required
* Modify all or part of a web page without requiring the user to reload it
* Display or interact with data retrieved from a remote server
You can do all this and more with JavaScript, including creating entire applications. We'll explore the uses of JavaScript throughout this book.
== How JavaScript Fits into a Web Page ==
As you hopefully already know, HTML is the language you use to create web documents. To refresh your memory, ''Listing 1.1'' shows a short but sadly typical web document.
; Listing 1.1. A Simple HTML Document
<pre>
<html>
<head>
<title>Our Home Page</title>
</head>
<body>
<h1>The American Eggplant Society</h1>
<p>Welcome to our Web page. Unfortunately,
it's still under construction.</p>
</body>
</html>
</pre>
This document consists of a header within the <head> tags and the body of the page within the <body> tags. To add JavaScript to a page, you'll use a similar tag: <script>.
The <code><script></code> tag tells the browser to start treating the text as a script, and the closing </script> tag tells the browser to return to HTML mode. In most cases, you can't use JavaScript statements in an HTML document except within <script> tags. The exception is event handlers, described later in this hour.
JavaScript and HTML
Using the <script> tag, you can add a short script (in this case, just one line) to a web document, as shown in Listing 1.2.
; Did you Know?:If you want to try this example in a browser but don't want to type it, the HTML document is available on this book's website (as are all of the other listings).
; Listing 1.2. A Simple HTML Document with a Simple Script
<pre>
<html>
<head>
<title>Our Home Page</title>
</head>
<body>
<h1>The American Eggplant Society</h1>
<p>Welcome to our Web page. Unfortunately,
it's still under construction.
We last worked on it on this date:
<script language="JavaScript" type="text/javascript">
document.write(document.lastModified);
</script>
</p>
</body>
</html>
</pre>
JavaScript's document.write statement, which you'll learn more about later, sends output as part of the web document. In this case, it displays the modification date of the document.
; By the Way
: Notice that the <script> tag in Listing 1.2 includes the parameter type="text/javascript". This specifies the scripting language to the browser. You can also specify a JavaScript version, as you'll learn later in this hour.
In this example, we placed the script within the body of the HTML document. There are actually four different places where you might use scripts:
* In the body of the page In this case, the script's output is displayed as part of the HTML document when the browser loads the page.
* In the header of the page between the <head> tags Scripts in the header don't immediately affect the HTML document, but can be referred to by other scripts. The header is often used for functionsgroups of JavaScript statements that can be used as a single unit. You will learn more about functions in Hour 3, "Getting Started with JavaScript Programming."
* Within an HTML tag, such as <body> or <form> This is called an event handler and enables the script to work with HTML elements. When using JavaScript in event handlers, you don't need to use the <script> tag. You'll learn more about event handlers in Hour 3.
* In a separate file entirely JavaScript supports the use of files with the .js extension containing scripts; these can be included by specifying a file in the <script> tag.
; Using Separate JavaScript Files
When you create more complicated scripts, you'll quickly find your HTML documents become large and confusing. To avoid this, you can use one or more external JavaScript files. These are files with the .js extension that contain JavaScript statements.
External scripts are supported by all modern browsers. To use an external script, you specify its filename in the <script> tag:
<script language="JavaScript" type="text/javascript" src="filename.js">
</script>
Because you'll be placing the JavaScript statements in a separate file, you don't need anything between the opening and closing <script> tags, in fact, anything between them will be ignored by the browser.
You can create the .js file using a text editor. It should contain one or more JavaScript commands, and only JavaScriptdon't include <script> tags, other HTML tags, or HTML comments. Save the .js file in the same directory as the HTML documents that refer to it. See the Try It Yourself section of Hour 2 for an example of separate HTML and script files.
; Did you Know? : External JavaScript files have a distinct advantage: You can link to the same .js file from two or more HTML documents. Because the browser stores this file in its cache, this can reduce the time it takes your web pages to display.
=== Events ===
Many of the useful things you can do with JavaScript involve interacting with the user, and that means responding to events, for example, a link or a button being clicked. You can define event handlers within HTML tags to tell the browser how to respond to an event. For example, Listing 1.3 defines a button that displays a message when clicked.
; Listing 1.3. A Simple Event Handler
<pre>
<html>
<head>
<title>Event Test</title>
</head>
<body>
<h1>Event Test</h1>
<button onclick="alert('You clicked the button.')">
</body>
</html>
</pre>
In Hour 9, "Responding to Events," you'll learn more about JavaScript's event model and creating simple and complex event handlers.
; By the Way: You can also use an external script to define event handlers. This is a good practice because it lets you keep all of your JavaScript in one place, rather than scattered across the HTML document. See Hour 9 for details.
== Browsers and JavaScript ==
Like HTML, JavaScript requires a web browser to be displayed, and different browsers may display it differently. Unlike HTML, the results of a browser incompatibility with JavaScript are more drastic: Rather than simply displaying your text incorrectly, the script may not execute at all, may display an error message, or may even crash the browser.
We'll take a quick look at the way different browsers and different versions of the same browser treat JavaScript in the following sections.
=== The DOM (Document Object Model) ===
Let's start with one reason you shouldn't have to think too much about different browsers. Almost everything you do with JavaScript involves working with the Document Object Model (DOM), a standardized set of objects that represent a web document.
The DOM includes objects that enable you to work with all aspects of the current document. For example, you can read the value the user types in a form field, or the filename of the current page.
The DOM is defined by the W3C (World Wide Web Consortium) and the latest browsers support DOM levels 1 and 2, which enable you to control all parts of a web page with JavaScript.
; Did you Know?: Early versions of the DOM only allowed JavaScript to manipulate certain parts of a page, such as form elements and links. The new DOM enables you to work with every element defined in HTML.
=== Internet Explorer ===
Microsoft's Internet Explorer (IE) browser was a latecomer to the Internet, but has now become the most popular browser. The latest versions of IE support most of JavaScript 1.5 and the W3C DOM.
At this writing, IE 6.0 is the latest released version, and IE 7.0 is in beta. Although most of the examples in this book will work in IE 5.0 and later, I recommend testing your scripts with the latest browsers.
=== Netscape and Firefox ===
Netscape, which for a time made the Web's most popular browser, established the Mozilla Foundation to maintain an open-source version of the browser. This led to the Mozilla browser and more recently, Firefox, a streamlined browser based on the Mozilla engine.
Firefox has recently begun to challenge Microsoft's browser dominance, with an estimated 10% of web users. That might not sound like many, but ignoring Firefox means ignoring at least 10% of your audience, and on many sites the percentage is much higher.
Firefox is available for Windows, Macintosh, and Linux platforms and is free, open-source software. You can download Firefox from the Mozilla website at http: //www.mozilla.org/ .
At this writing, the current version of Firefox is 1.5. Most of the scripts in this book will work with Firefox 1.0 or later, as well as versions 6 and 7 of the Netscape browser.
; By the Way: Netscape 4.0 and Internet Explorer 4.0 supported incompatible versions of Dynamic HTML (DHTML)an attempt to overcome the limits of the current DOM. The new W3C DOM eliminates the need for these proprietary models, and you can now write standard code that will work on most modern browsers.
=== Other Browsers ===
Although Internet Explorer and Firefox are the most popular browsers, there are many other browsers. Here are two less-common browsers you'll probably hear about:
* Safari, Apple's browser, is included with MacOS and is the default browser on most Macintosh computers.
* Opera, from Opera Software, is an alternative browser notable for its support of many platforms, including mobile phones. The latest version of Opera, 8.0, supports the W3C DOM and JavaScript 1.5, and should work with most scripts in this book.
; Did you Know?:There are many other browsers out there, but you don't need to know all of them to create working scripts, as long as you follow the standards, your scripts will work on browsers that support JavaScript almost every time. This book will focus on teaching standards-based scripting that will work in all modern browsers.
=== Versions of JavaScript ===
The JavaScript language has evolved since its original release in Netscape 2.0. There have been several versions of JavaScript:
* JavaScript 1.0, the original version, is supported by Netscape 2.0 and Internet Explorer 3.0.
* JavaScript 1.1 is supported by Netscape 3.0 and mostly supported by Internet Explorer 4.0.
* JavaScript 1.2 is supported by Netscape 4.0 and partially supported by Internet Explorer 4.0.
* JavaScript 1.3 is supported by Netscape 4.5 and Internet Explorer 5.0 and 6.0.
* JavaScript 1.5 is partially supported by Internet Explorer 6.0, and supported by Netscape 6.0 and Firefox 1.0.
* JavaScript 1.6 is currently supported by Firefox 1.5.
Each of these versions is an improvement over the previous version and includes a number of new features. With rare exception, browsers that support the new version will also support scripts written for earlier versions.
The European Computer Manufacturing Association (ECMA) has finalized the ECMA-262 specification for ECMAScript, a standardized version of JavaScript. JavaScript 1.3 follows the ECMA-262 standard, and JavaScript 1.5 follows ECMA-262 revision 3.
; By the Way : Another language you might hear of is JScript. This is how Microsoft refers to its implementation of JavaScript, which is generally compatible with the standard version.
The Mozilla Foundation, the open-source offshoot of Netscape that develops the Firefox browser, is also working with ECMA on JavaScript 2.0, a future version that will correspond with the fourth edition of the ECMAScript standard. JavaScript 2.0 will improve upon earlier versions with a more modular approach, better object support, and features to make JavaScript useful as a general-purpose scripting language as well as a web language.
== Specifying JavaScript Versions ==
As mentioned earlier in this hour, you can specify a version of JavaScript in the <script> tag. For example, this tag specifies JavaScript version 1.3:
<script language="JavaScript1.3" type="text/javascript">
There are two ways of specifying the JavaScript language in the <script> tag. The old method uses the language attribute, and the new method recommended by the HTML 4.0 specification uses the type attribute. To maintain compatibility with older browsers, you can use both attributes.
When you specify a version number in the language attribute, this allows your script to execute only if the browser supports the version you specified or a later version.
When the <script> tag doesn't specify a version number, all browsers that support JavaScript will run the script. Because most of the JavaScript language has remained the same since version 1.0, you will rarely need to worry about JavaScript versions.
; Did you Know?:In most cases, you shouldn't specify a JavaScript version at all. This allows your script to run on all of the browsers that support JavaScript. You should only specify a particular version when your script uses features unique to a specific version.
=== JavaScript Beyond the Browser ===
Although JavaScript programs traditionally run within a web browser, and web-based JavaScript is the focus of this book, JavaScript is becoming increasingly popular in other applications. Here are a few examples:
* Adobe Dreamweaver and Flash, used for web applications and multimedia, can be extended with JavaScript.
* Several server-side versions of JavaScript are available. These run within a web server rather than a browser.
* Microsoft's Windows Scripting Host (WSH) supports JScript, Microsoft's implementation of JavaScript, as a general-purpose scripting language for Windows. Unfortunately, the most popular applications developed for WSH so far have been email viruses.
* Microsoft's Common Language Runtime (CLR), part of the .NET framework, supports JavaScript.
Along with these examples, many of the changes in the upcoming JavaScript 2.0 are designed to make it more suitable as a general-purpose scripting language.
== Exploring JavaScript's Capabilities ==
If you've spent any time browsing the Web, you've undoubtedly seen lots of examples of JavaScript in action. Here are some brief descriptions of typical applications for JavaScript, all of which you'll explore further, later in this book.
=== Improving Navigation ===
Some of the most common uses of JavaScript are in navigation systems for websites. You can use JavaScript to create a navigation tool, for example, a drop-down menu to select the next page to read, or a submenu that pops up when you hover over a navigation link.
When it's done right, this kind of JavaScript interactivity can make a site easier to use, while remaining usable for browsers that don't support JavaScript.
=== Validating Forms ===
Form validation is another common use of JavaScript. A simple script can read values the user types into a form and make sure they're in the right format, such as with ZIP Codes or phone numbers. This allows users to notice common errors and fix them without waiting for a response from the web server. You'll learn how to write form validation scripts in Hour 11, "Getting Data with Forms."
=== Special Effects ===
One of the earliest and most annoying uses of JavaScript was to create attention-getting special effectsfor example, scrolling a message in the browser's status line or flashing the background color of a page.
These techniques have fortunately fallen out of style, but thanks to the W3C DOM and the latest browsers, some more impressive effects are possible with JavaScript, for example, creating objects that can be dragged and dropped on a page, or creating fading transitions between images in a slideshow.
=== Remote Scripting (AJAX) ===
For a long time, the biggest limitation of JavaScript was that there was no way for it to communicate with a web server. For example, you could use it to verify that a phone number had the right number of digits, but not to look up the user's location in a database based on the number.
Now that some of JavaScript's advanced features are supported by most browsers, this is no longer the case. Your scripts can get data from a server without loading a page, or send data back to be saved. These features are collectively known as AJAX (Asynchronous JavaScript And XML), or remote scripting. You'll learn how to develop AJAX scripts in Hour 17, "AJAX: Remote Scripting."
You've seen AJAX in action if you've used Google's Gmail mail application, or recent versions of Yahoo! Mail or Microsoft Hotmail. All of these use remote scripting to present you with a responsive user interface that works with a server in the background.
== Alternatives to JavaScript ==
JavaScript is not the only language used on the Web, and in some cases, it may not be the right tool for the job. Other languages, such as Java, can do some things better than JavaScript. In the following sections, we'll look at a few other commonly used web languages and their advantages.
=== Java ===
Java is a programming language developed by Sun Microsystems that can be used to create applets, or programs that execute within a web page.
Java is a compiled language, but the compiler produces code for a virtual machine rather than a real computer. The virtual machine is a set of rules for bytecodes and their meanings, with capabilities that fit well into the scope of a web browser.
The virtual machine code is then interpreted by a web browser. This allows the same Java applet to execute the same way on PCs, Macintoshes, and UNIX machines, and on different browsers.
; By the Way: Java is also a densely populated island in Indonesia and a slang term for coffee. This has resulted in a widespread invasion of coffee-related terms in computer literature.
At this point, we need to make one thing clear: Java is a fine language, but you won't be learning it in this book. Although their names and some of their commands are similar, JavaScript and Java are entirely different languages.
=== ActiveX ===
ActiveX is a specification developed by Microsoft that enables ordinary Windows programs to be run within a web page. ActiveX programs can be written in languages such as Visual C++ and Visual Basic, and they are compiled before being placed on the web server.
ActiveX applications, called controls, are downloaded and executed by the web browser, like Java applets. Unlike Java applets, controls can be installed permanently when they are downloaded, eliminating the need to download them again.
ActiveX's main advantage is that it can do just about anything. This can also be a disadvantage: Several enterprising programmers have already used ActiveX to bring exciting new capabilities to web pages, such as "the web page that turns off your computer" and "the web page that formats your disk drive."
Fortunately, ActiveX includes a signature feature that identifies the source of the control and prevents controls from being modified. Although this won't prevent a control from damaging your system, you can specify which sources of controls you trust.
ActiveX has two main disadvantages: First, it isn't as easy to program as a scripting language or Java. Second, ActiveX is proprietary, it works only in Microsoft Internet Explorer, and only under Windows platforms.
=== VBScript ===
VBScript, sometimes known as Visual Basic Scripting Edition, is Microsoft's answer to JavaScript. Just as JavaScript's syntax is loosely based on Java, VBScript's syntax is loosely based on Microsoft Visual Basic, a popular programming language for Windows machines.
Like JavaScript, VBScript is a simple scripting language, and you can include VBScript statements within an HTML document. VBScript can work with the DOM in the same way as JavaScript. To begin a VBScript script, you use the <script LANGUAGE="VBScript"> tag.
VBScript can do many of the same things as JavaScript, and it even looks similar in some cases. It has two main advantages:
* For those who already know Visual Basic, it may be easier to learn than JavaScript.
* It is closely integrated with ActiveX, Microsoft's standard for web-embedded applications.
VBScript's main disadvantage is that it is supported only by Microsoft Internet Explorer. JavaScript, on the other hand, is supported by Netscape, Internet Explorer, and several other browsers. JavaScript is a much more popular language, and you can see it in use all over the Web.
=== CGI and Server-Side Scripting ===
CGI (Common Gateway Interface) is not really a language, but a specification that enables programs to run on web servers. CGI programs can be written in any number of languages, including Perl, C, and Visual Basic.
Along with traditional CGI, scripting languages such as Microsoft's Active Server Pages, Java Server Pages, Cold Fusion, and PHP are often used on web servers. A server-side implementation of JavaScript is also available.
Server-side programs are heavily used on the Web. Almost every time you type information into a form and press a button to send it to a website, the data is processed by a server-side application.
The main difference between JavaScript and server-side languages is that JavaScript applications execute on the client (the web browser) and server-side applications execute on the web server. The main disadvantage of this approach is that, because the data must be sent to the web server and back, response time might be slow.
On the other hand, CGI can do things JavaScript can't do. In particular, it can read and write files on the server and interact with other server components, such as databases. Although a client-side JavaScript program can read information from a form and then manipulate it, it can't store the data on the web server.
JavaScript is often used in conjunction with server-side languages. In its simplest form, this means JavaScript handles client-side chores such as form validation, whereas a server-side language receives data and stores it in a database. Using AJAX, this interaction can be instantaneous and does not even require loading a new page.
; Did you Know?: CGI and server-side programming are outside the focus of this book. You can learn more about these technologies with other Sams books, including Teach Yourself CGI Programming in 24 Hours, Teach Yourself Perl in 24 Hours, and Teach Yourself PHP in 24 Hours. See Appendix A, "Other JavaScript Resources," for more sources of information.
== Summary ==
During this hour, you've learned what web scripting is and what JavaScript is. You've also learned how to insert a script into an HTML document or refer to an external JavaScript file, what sorts of things JavaScript can do, and how JavaScript differs from other web languages.
If you're waiting for some real JavaScript code, look no further. The next hour, "Creating Simple Scripts," guides you through the process of creating several working JavaScript examples. You'll also learn about the tools you'll need to work with JavaScript.
=== Q&A ===
Q1:
Do I need to test my JavaScript on more than one browser?
A1:
In an ideal world, any script you write that follows the standards for JavaScript will work in all browsers, and 90% of the time that's true in the real world. But browsers do have their quirks, and you should test your scripts on Internet Explorer and Firefox at a minimum.
Q2:
If I plan to learn Java or CGI anyway, will I have any use for JavaScript?
A2:
Certainly. JavaScript is the ideal tool for many applications, such as form validation. Although Java and CGI have their uses, they can't do all that JavaScript can do.
Q3:
Are there browsers out there that don't support JavaScript?
A3:
Yes. A few niche browsers, such as text-based browsers and tools for blind users, have partial JavaScript support or no support. Mobile phone browsers often support little or no JavaScript. Finally, many users of Internet Explorer or Firefox have JavaScript support turned off, and some corporate firewalls and ad-blocking software block JavaScript. Hour 2 describes how to account for browsers that don't support JavaScript.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
# Why do JavaScript and Java have similar names?
## JavaScript is a stripped-down version of Java.
## Netscape's marketing department wanted them to sound related.
## They both originated on the island of Java.
# When a user views a page containing a JavaScript program, which machine actually executes the script?
## The user's machine running a web browser
## The web server
## A central machine deep within Netscape's corporate offices
# Which of the following languages is supported by both Microsoft Internet Explorer and Netscape?
## VBScript
## ActiveX
## JavaScript
=== Quiz Answers ===
1. b. Although some of the syntax is similar, JavaScript got its Java-based name mostly because of a marketing relationship.
2. a. JavaScript programs execute on the web browser. (There is actually a server-side version of JavaScript, but that's another story.)
3. c. JavaScript is supported by both Netscape and Internet Explorer, although the implementations are not identical.
=== Exercises ===
If you want to learn a bit about JavaScript or check out the latest developments before you proceed with the next hour, perform these activities:
* Visit this book's website to check for news about JavaScript and updates to the scripts in this book.
* View some of the examples on this book's website to see JavaScript in action.
-->
fl9ygi9ukfmh4ryoobvtoligfnlbtg2
User:Moncur/08
2
2079
39273
5818
2026-04-13T06:03:45Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39273
wikitext
text/x-wiki
<!---->
=8. Using Built-in Functions and Libraries=
== Using the <code>Math</code> Object ==
The <code>Math</code> object is a built-in JavaScript object that includes math constants and functions. You don't need to create a <code>Math</code> object; it exists automatically in any JavaScript program. The <code>Math</code> object's properties represent mathematical constants, and its methods are mathematical functions.
=== Rounding and Truncating ===
Three of the most useful methods of the <code>Math</code> object enable you to round decimal values up and down:
* <code>Math.ceil()</code> rounds a number up to the next integer.
* <code>Math.floor()</code> rounds a number down to the next integer.
* <code>Math.round()</code> rounds a number to the nearest integer.
All of these take the number to be rounded as their single parameter. You might notice one thing missing: the capability to round to a decimal place, such as for dollar amounts. Fortunately, you can easily simulate this. Here is a simple function that rounds numbers to two decimal places:
<pre>function round(num) {
return Math.round(num * 100) / 100;
}
</pre>
This function multiplies the value by 100 to move the decimal, and then rounds the number to the nearest integer. Finally, the value is divided by 100 to restore the decimal to its original position.
=== Generating Random Numbers ===
One of the most commonly used methods of the <code>Math</code> object is the <code>Math.random()</code> method, which generates a random number. This method doesn't require any parameters. The number it returns is a random decimal number between zero and one.
You'll usually want a random number between one and a value. You can do this with a general-purpose random number function. The following is a function that generates random numbers between one and the parameter you send it:
<pre>function rand(num) {
return Math.floor(Math.random() * num) + 1;
}
</pre>
This function multiplies a random number by the value specified in the <code>num</code> parameter, and then converts it to an integer between one and the number by using the <code>Math.floor()</code> method.
=== Other <code>Math</code> Functions===
The <code>Math</code> object includes many functions beyond those you've looked at here. For example, <code>Math.sin()</code> and <code>Math.cos()</code> calculate sines and cosines. The <code>Math</code> object also includes properties for various mathematical constants, such as <code>Math.PI</code>. See [Appendix D], "JavaScript Quick Reference," for a complete list of <code>math</code> functions and constants.
== Working with <code>Math</code> Functions ==
The <code>Math.random()</code> method generates a random number between <code>0</code> and <code>1</code>. However, it's very difficult for a computer to generate a truly random number. (It's also hard for a human being to do so—that's why dice were invented.)
Today's computers do reasonably well at generating random numbers, but just how good is JavaScript's <code>Math.random</code> function? One way to test it is to generate many random numbers and calculate the average of all of them.
In theory, the average should be somewhere near <code>.5</code>, halfway between <code>0</code> and <code>1</code>. The more random values you generate, the closer the average should get to this middle ground.
As an example of the use of the <code>Math</code> object's methods, you can create a script that tests JavaScript's random number function. To do this, you'll generate 5,000 random numbers and calculate their average.
; Did you Know?:Rather than typing it in, you can download and try this hour's example at this book's website.
In case you skipped [Hour 7], "Controlling Flow with Conditions and Loops," and are getting out your calculator, don't worry—you'll use a loop to generate the random numbers. You'll be surprised how fast JavaScript can do this.
To begin your script, you will initialize a variable called <code>total</code>. This variable will store a running total of all of the random values, so it's important that it starts at <code>0</code>:
<pre>total = 0;</pre>
Next, begin a loop that will execute 5,000 times. Use a <code>for</code> loop because you want it to execute a fixed number of times:
<pre>for (i=1; i<=5000; i++) {</pre>
Within the loop, you will need to create a random number and add its value to <code>total</code>. Here are the statements that do this and continue with the next iteration of the loop:
<pre>
num = Math.random();
total += num;
}
</pre>
Depending on the speed of your computer, it might take a few seconds to generate those 5,000 random numbers. Just to be sure something is happening, the script will display a status message after each 1,000 numbers:
<pre>if (i % 1000 == 0)
document.write("Generated " + i + " numbers...<br>");
</pre>
; By the Way?:The <code>%</code> symbol in the previous code is the modulo operator, which gives you the remainder after dividing one number by another. Here it is used to find even multiples of 1,000.
The final part of your script will calculate the average by dividing <code>total</code> by 5,000. Your script can also round the average to three decimal places, using the trick you learned earlier in this hour:
<pre>average = total / 5000;
average = Math.round(average * 1000) / 1000;
document.write("<H2>Average of 5000 numbers: " + average + "</H2>");
</pre>
To test this script and see just how random those numbers are, combine the complete script with an HTML document and <code><script></code> tags. [Listing 8.1] shows the complete random number testing script.
; Listing 8.1. A Script to Test JavaScript's Random Number Function
<pre><html>
<head>
<title>Math Example</title>
</head>
<body>
<h1>Math Example</h1>
<p>How random are JavaScript's random numbers?
Let's generate 5000 of them and find out.</p>
<script language="JavaScript" type="text/javascript">
total = 0;
for (i=1; i<=5000; i++) {
num = Math.random();
total += num;
if (i % 1000 == 0)
document.write("Generated " + i + " numbers...<br>");
}
average = total / 5000;
average = Math.round(average * 1000) / 1000;
document.write("<H2>Average of 5000 numbers: " + average + "</H2>");
</script>
</body>
</html>
</pre>
To test the script, load the HTML document into a browser. After a short delay, you should see a result. If it's close to <code>.5</code>, the numbers are reasonably random. My result was <code>.502</code>, as shown in [Figure 8.1].
; By the Way?:The average you've used here is called an arithmetic mean. This type of average isn't a perfect way to test randomness. Actually, all it tests is the distribution of the numbers above and below <code>.5</code>. For example, if the numbers turned out to be 2,500 <code>.4</code>s and 2,500 <code>.6</code>s, the average would be a perfect <code>.5</code>—but they wouldn't be very random numbers. (Thankfully, JavaScript's random numbers don't have this problem.)
== Using the <code>with</code> Keyword ==
The <code>with</code> keyword is one you haven't seen before. You can use it to make JavaScript programming easier—or at least easier to type.
The <code>with</code> keyword specifies an object, and it is followed by a block of statements enclosed in braces. For each statement in the block, any properties you mention without specifying an object are assumed to be for that object.
As an example, suppose you have a string called <code>lastname</code>. You can use <code>with</code> to perform string operations on it without specifying the name of the string every time:
<pre>with (lastname) {
window.alert("length of last name: " + length);
capname = toUpperCase();
}
</pre>
In this example, the <code>length</code> property and the <code>toUpperCase</code> method refer to the <code>lastname</code> string, although it is only specified once with the <code>with</code> keyword.
Obviously, the <code>with</code> keyword only saves a bit of typing in situations like this. However, you might find it more useful when you're dealing with a DOM object throughout a large procedure, or when you are using a built-in object, such as the <code>Math</code> object, repeatedly.
== Working with Dates ==
The <code>Date</code> object is a built-in JavaScript object that enables you to conveniently work with dates and times. You can create a <code>Date</code> object anytime you need to store a date, and use the <code>Date</code> object's methods to work with the date.
You encountered one example of a <code>Date</code> object in [Hour 2], "Creating Simple Scripts," with the time/date script. The <code>Date</code> object has no properties. To set or obtain values from a <code>Date</code> object, you must use the methods described in the next section.
; By the Way?:JavaScript dates are stored as the number of milliseconds since midnight, January 1, 1970. This date is called the epoch. Dates before 1970 weren't allowed in early versions, but are now represented by negative numbers.
=== Creating a <code>Date</code> Object ===
You can create a <code>Date</code> object using the <code>new</code> keyword. You can also optionally specify the date to store in the object when you create it. You can use any of the following formats:
<pre>birthday = new Date();
birthday = new Date("June 20, 2003 08:00:00");
birthday = new Date(6, 20, 2003);
birthday = new Date(6, 20, 2003, 8, 0, 0);
</pre>
You can choose any of these formats, depending on which values you wish to set. If you use no parameters, as in the first example, the current date is stored in the object. You can then set the values using the <code>set</code> methods, described in the next section.
=== Setting <code>Date</code> Values ===
A variety of <code>set</code> methods enable you to set components of a <code>Date</code> object to values:
* <code>setDate()</code> sets the day of the month.
* <code>setMonth()</code> sets the month. JavaScript numbers the months from 0 to 11, starting with January (<code>0</code>).
* <code>setFullYear()</code> sets the year.
* <code>setTime()</code> sets the time (and the date) by specifying the number of milliseconds since January 1, 1970.
* <code>setHours()</code>, <code>setMinutes()</code>, and <code>setSeconds()</code> set the time.
As an example, the following statement sets the year of a <code>Date</code> object called <code>holiday</code> to 2003:
<pre>holiday.setFullYear(2003);</pre>
=== Reading <code>Date</code> Values ===
You can use the <code>get</code> methods to get values from a <code>Date</code> object. This is the only way to obtain these values, because they are not available as properties. Here are the available <code>get</code> methods for dates:
* <code>getdate()</code> gets the day of the month.
* <code>getMonth()</code> gets the month.
* <code>getFullYear()</code> gets the year.
* <code>getTime()</code> gets the time (and the date) as the number of milliseconds since January 1, 1970.
* <code>getHours()</code>, <code>getMinutes()</code>, <code>getSeconds()</code>, and <code>getMilliseconds()</code> get the components of the time.
; By the Way?:Along with <code>setFullYear</code> and <code>getFullYear</code>, which require four-digit years, JavaScript includes <code>setYear</code> and <code>getYear</code> methods, which use two-digit year values. You should always use the four-digit version to avoid Year 2000 issues.
=== Working with Time Zones ===
Finally, a few functions are available to help your <code>Date</code> objects work with local time values and time zones:
* <code>getTimeZoneOffset()</code> gives you the local time zone's offset from UTC (Coordinated Universal Time, based on the old Greenwich Mean Time standard). In this case, local refers to the location of the browser. (Of course, this only works if the user has set his or her system clock accurately.)
* <code>toUTCString()</code> converts the <code>date</code> object's time value to text, using UTC. This method was introduced in JavaScript 1.2 to replace the <code>toGMTString</code> method, which still works but should be avoided.
* <code>toLocalString()</code> converts the <code>date</code> object's time value to text, using local time.
Along with these basic functions, JavaScript 1.2 and later include UTC versions of several of the functions described previously. These are identical to the regular commands, but work with UTC instead of local time:
* <code>getUTCDate()</code> gets the day of the month in UTC time.
* <code>getUTCDay()</code> gets the day of the week in UTC time.
* <code>getUTCFullYear()</code> gets the four-digit year in UTC time.
* <code>getUTCMonth()</code> returns the month of the year in UTC time.
* <code>getUTCHours()</code>, <code>getUTCMinutes()</code>, <code>getUTCSeconds()</code>, and <code>getUTCMilliseconds()</code> return the components of the time in UTC.
* <code>setUTCDate()</code>, <code>setUTCFullYear()</code>, <code>setUTCMonth()</code>, <code>setUTCHours()</code>, <code>setUTCMinutes()</code>, <code>setUTCSeconds()</code>, and <code>setUTCMilliseconds()</code> set the time in UTC.
=== Converting Between Date Formats ===
Two special methods of the <code>Date</code> object allow you to convert between date formats. Instead of using these methods with a <code>Date</code> object you created, you use them with the built-in object <code>Date</code> itself. These include the following:
* <code>Date.parse()</code> converts a date string, such as <code>June 20, 1996</code>, to a <code>Date</code> object (number of milliseconds since 1/1/1970).
* <code>Date.UTC()</code> does the opposite. It converts a <code>Date</code> object value (number of milliseconds) to a UTC (GMT) time.
== Using Third-Party Libraries ==
When you use JavaScript's built-in <code>Math</code> and <code>Date</code> functions, JavaScript does most of the work—you don't have to figure out how to convert dates between formats or calculate a cosine. Third-party libraries are not included with JavaScript, but they serve a similar purpose—enabling you to do complicated things with only a small amount of code.
Using one of these libraries is usually as simple as copying one or more files to your site and including a <code><script></code> tag in your document to load the library. Several popular JavaScript libraries are discussed in the following sections.
; Did you Know?:JavaScript libraries are a relatively new phenomenon, and new libraries are appearing regularly. See this book's website for an updated list of libraries.
=== Prototype ===
Prototype, created by Sam Stephenson, is a JavaScript library that simplifies tasks such as working with DOM objects, dealing with data in forms, and remote scripting (AJAX). By including a single <code>prototype.js</code> file in your document, you have access to many improvements to basic JavaScript.
For example, you've used the <code>document.getElementById</code> method to obtain the DOM object for an element within a web page. Prototype includes an improved version of this in the <code>$()</code> function. Not only is it easier to type, but it is also more sophisticated than the built-in function and supports multiple objects.
Adding Prototype to your pages requires only one file, <code>prototype.js</code>, and one <code><script></code> tag:
<pre><script type="text/javascript" src="prototype.js"> </script></pre>
; By the Way?:
Prototype is free, open-source software. You can download it from its official website at [http://prototype.conio.net/ http://prototype.conio.net]. Prototype is also built into the Ruby on Rails framework for the server-side language Ruby—see [http://www.rubyonrails.com/ http://www.rubyonrails.com/] for more information.
=== Script.aculo.us ===
By the end of this book, you'll learn to do some impressive things with JavaScript—for example, animating an object within a page. The code for a task like this is complex, but you can also include effects in your pages using a prebuilt library. This enables you to use impressive effects with only a few lines of code.
Script.aculo.us by Thomas Fuchs is one such library. It includes functions to simplify drag-and-drop tasks, such as rearranging lists of items. It also includes a number of Combination Effects, which enable you to use highlighting and animated transitions within your pages. For example, a new section of the page can be briefly highlighted in yellow to get the user's attention, or a portion of the page can fade out or slide off the screen.
After you've included the appropriate files, using effects is as easy as using any of JavaScript's built-in methods. For example, the following statements use Script.aculo.us to fade out an element of the page with the <code>id</code> value <code>test</code>:
<pre>obj = document.getElementById("test");
new Effect.Fade(obj);
</pre>
Script.aculo.us is built on the Prototype framework described in the previous section, and includes all of the functions of Prototype, so you could also simplify this further by using the <code>$</code> function:
<pre>new Effect.Fade($("test"));</pre>
; Did you Know?:You will create a script that demonstrates several Script.aculo.us effects in the Try It Yourself section later this hour.
=== AJAX Frameworks ===
AJAX (Asynchronous JavaScript and XML), also known as remote scripting, enables JavaScript to communicate with a program running on the web server. This enables JavaScript to do things that were traditionally not possible, such as dynamically loading information from a database or storing data on a server without refreshing a page.
Unfortunately, AJAX requires some complex scripting, particularly because the methods you use to communicate with the server vary depending on the browser in use. Fortunately, many libraries have been created to fill the need for a simple way to use AJAX.
The Prototype library, described previously, includes AJAX features. There are also many dedicated AJAX libraries. One of the most popular is SAJAX (Simple AJAX), an open-source toolkit that makes it easy to use AJAX to communicate with PHP, Perl, and other languages from JavaScript. Visit the SAJAX website for details at [http://www.modernmethod.com/sajax http://www.modernmethod.com/sajax].
; By the Way?:See [Hour 17], "AJAX: Remote Scripting," for examples of remote scripting, with and without using third-party libraries.
== Other Libraries ==
There are many more JavaScript libraries out there, and more are appearing all of the time as JavaScript is taken more seriously as an application language. Here are some more libraries you might want to explore:
* Dojo ([http://www.dojotoolkit.org/ http://www.dojotoolkit.org/]) is an open-source toolkit that adds power to JavaScript to simplify building applications and user interfaces. It adds features ranging from extra string and math functions to animation and AJAX.
* The Yahoo! UI Library ([http://developer.yahoo.net/yui/ http://developer.yahoo.net/yui/]) was developed by Yahoo! and made available to everyone under an open-source license. It includes features for animation, DOM features, event management, and easy-to-use user interface elements such as calendars and sliders.
* MochiKit ([http://mochikit.com/ http://mochikit.com/]) is a lightweight library that adds features for working with the DOM, CSS colors, string formatting, and AJAX. It also supports a nice logging mechanism for debugging your scripts.
== Try It Yourself ==
=== Adding Effects with a Library ===
To see how simple it is to use an external library, you will now create an example script that includes the Script.aculo.us library and use event handlers to demonstrate several of the available effects.
; Watch Out!: This example was created using version 1.5.1 of the Script.aculo.us library. It should work with later versions, but the library might have changed since this was written. If you have trouble, you might need to use this specific version.
=== Downloading the Library ===
To use the library, you will need to download it and copy the files you need to the same folder where you will store your script. You can download the library from the Script.aculo.us website at [http://script.aculo.us/downloads http://script.aculo.us/downloads].
The download is available as a Zip file. Inside the Zip file you will find a folder called <code>scriptaculous-js-x.x.x</code>. You will need the following files from the folders under this folder:
* <code>prototype.js</code> (the Prototype library) from the <code>lib</code> folder
* <code>effects.js</code> (the effects functions) from the <code>src</code> folder
Copy both of these files to a folder on your computer, and be sure to create your demonstration script in the same folder.
; By the Way?:The Script.aculo.us download includes many other files, and you can include the entire library if you intend to use all of its features. For this example, you only need the two files described here.
=== Including the Files ===
To add the library to your HTML document, simply use <code><script></code> tags to include the two JavaScript files you copied from the download:
<pre><script type="text/javascript" src="prototype.js"> </script>
<script type="text/javascript" src="effects.js"> </script>
</pre>
If you include these statements as the first things in the <code><head></code> section of your document, the library functions will be available to other scripts or event handlers anywhere in the page.
=== Using Effects ===
After you have included the library, you simply need to include a bit of JavaScript to trigger the effects. We will use a section of the page wrapped in a <code></code> tag with the <code>id</code> value <code>test</code> to demonstrate the effects. Each effect is triggered by a simple event handler on a button. For example, this code defines the Fade Out button:
<pre><input type="button" value="Fade Out" onClick="new Effect.Fade($('test'))">
</pre>
This uses the <code>$</code> function built into Prototype to obtain the object for the element with the <code>id</code> value <code>test</code>, and then passes it to the <code>Effect.Fade()</code> function built into Script.aculo.us.
; Did you Know?:This example will demonstrate six effects: <code>Fade</code>, <code>Appear</code>, <code>SlideUp</code>, <code>SlideDown</code>, <code>Highlight</code>, and <code>Shake</code>. There are more than 16 effects in the library, plus methods for supporting Drag and Drop and other features. See [http://script.aculo.us/ http://script.aculo.us] for details.
=== Building the Script ===
After you have included the libraries, you can combine them with event handlers and some example text to create a complete demonstration of Script.aculo.us effects. The complete HTML document for this example is shown in [Listing 8.2].
; Listing 8.2. The Complete Library Effects Example
<pre><html>
<head>
<title>Testing script.aculo.us effects</title>
<script type="text/javascript" src="prototype.js"> </script>
<script type="text/javascript" src="effects.js"> </script>
</head>
<body">
<h1>Testing script.aculo.us Effects</h1>
<form name="form1">
<input type="button" value="Fade Out" onClick="new Effect.Fade($('test'))">
<input type="button" value="Fade In" onClick="new Effect.Appear($('test'))">
<input type="button" value="Slide Up" onClick="new Effect.SlideUp($('test'))">
<input type="button" value="Slide Down" onClick="new Effect.SlideDown($('test'))">
<input type="button" value="Highlight" onClick="new Effect.Highlight($('test'))">
<input type="button" value="Shake" onClick="new Effect.Shake($('test'))">
</form>
<div id="test" style="background-color:#CCC; margin:20px; padding:10px;">
<h2>Testing Effects</h2>
<hr>
<p>This section of the document is within a <div> element
with the <b>id</b> value <b>test</b>. The event handlers on the
buttons above send this object to the
<a href="http://script.aculo.us/">script.aculo.us</a> library
to perform effects. Click the buttons to see the effects.
</p>
</body>
</html>
</pre>
This document starts with two <code><script></code> tags to include the library's files. The effects are triggered by the event handlers defined for each of the six buttons. The <code></code> section at the end defines the <code>test</code> element that will be used to demonstrate the effects.
To try this example, make sure the <code>prototype.js</code> and <code>effects.js</code> files from Script.aculo.us are stored in the same folder as your script, and then load the HTML file into a browser. The display should look like [Figure 8.2], and you can use the six buttons at the top of the page to trigger effects.
== Summary ==
In this hour, you learned some specifics about the <code>Math</code> and <code>Date</code> objects built into JavaScript, and learned more than you ever wanted to know about random numbers. You also learned how third-party libraries can simplify your scripting, and you used a library to create special effects in a web page.
You've reached the end of Part II, which covered some basic building blocks of JavaScript programs. In Part III, you'll learn more about the Document Object Model, which contains objects that refer to various parts of the browser window and HTML document. This begins in [Hour 9], "Responding to Events."
=== Q&A ===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q1:'''
| The random numbers are generated so quickly I can't be sure it's happening at all. Is there a way to slow this process down?
|-
| align="right" | ''' A1: '''
| Yes. If you add one or more form fields to the example and use them to display the data as it is generated, you'll see a much slower result. It will still be done within a couple of seconds on a fast computer, though.
|-
| align="right" | '''Q2:'''
| Can I use more than one third-party library in the same script?
|-
| align="right" | ''' A2: '''
| Yes, in theory: If the libraries are well written and designed not to interfere with each other, there should be no problem combining them. In practice, this will depend on the libraries you need and how they were written.
|-
| align="right" | '''Q3:'''
| Can I build my own library to simplify scripting?
|-
| align="right" | ''' A3: '''
| Yes, as you deal with more complicated scripts, you'll find yourself using the same functions over and over. You can combine them into a library for your own use. This is as simple as creating a <code>.js</code> file.
|}
=== Quiz Questions ===
Test your knowledge of JavaScript libraries and built-in functions by answering the following questions.
'''1.''' Which of the following objects cannot be used with the <code>new</code> keyword?
# <code>Date</code>
# <code>Math</code>
# <code>String</code>
'''2.''' How does JavaScript store dates in a <code>Date</code> object?
# The number of milliseconds since January 1, 1970
# The number of days since January 1, 1900
# The number of seconds since Netscape's public stock offering
'''3.''' What is the range of random numbers generated by the <code>Math.random</code> function?
# Between <code>1</code> and <code>100</code>
# Between <code>1</code> and the number of milliseconds since January 1, 1970
# Between <code>0</code> and <code>1</code>
=== Quiz Answers ===
{| cellspacing="16" cellpadding="0" border="0"
| align="right" | '''1.'''
| b. The <code>Math</code> object is static; you can't create a <code>Math</code> object.
|-
| align="right" | '''2.'''
| a. Dates are stored as the number of milliseconds since January 1, 1970.
|-
| align="right" | '''3.'''
| c. JavaScript's random numbers are between <code>0</code> and <code>1</code>.
|}
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
* Modify the random number script in [Listing 8.1] to run three times, calculating a total of 15,000 random numbers, and display separate totals for each set of 5,000. (You'll need to use another <code>for</code> loop that encloses most of the script.)
* Visit the Script.aculo.us page at [http://script.aculo.us/ http://script.aculo.us/] to find the complete list of effects. Modify [Listing 8.2] to add buttons for one or more additional effects.
cxfuaeezhi6wjtakpt22j4y7po5jiqb
User:Moncur/07
2
2080
39272
5830
2026-04-13T06:03:45Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39272
wikitext
text/x-wiki
=7. Controlling Flow with Conditions and Loops=
== The <code>if</code> Statement ==
One of the most important features of a computer language is the capability to test and compare values. This allows your scripts to behave differently based on the values of variables, or based on input from the user.
The <code>if</code> statement is the main conditional statement in JavaScript. This statement means much the same in JavaScript as it does in English—for example, here is a typical conditional statement in English:
:If the phone rings, answer it.
This statement consists of two parts: a condition (If the phone rings) and an action (answer it). The <code>if</code> statement in JavaScript works much the same way. Here is an example of a basic <code>if</code> statement:
<pre>if (a == 1) window.alert("Found a 1!");</pre>
This statement includes a condition (if <code>a</code> equals <code>1</code>) and an action (display a message). This statement checks the variable <code>a</code> and, if it has a value of <code>1</code>, displays an alert message. Otherwise, it does nothing.
If you use an <code>if</code> statement like the preceding example, you can use a single statement as the action. You can also use multiple statements for the action by enclosing them in braces (<code>{}</code>), as shown here:
<pre>if (a == 1) {
window.alert("Found a 1!");
a = 0;
}</pre>
This block of statements checks the variable <code>a</code> once again. If it finds a value of <code>1</code>, it displays a message and sets <code>a</code> back to <code>0</code>.
=== Conditional Operators ===
The action part of an <code>if</code> statement can include any of the JavaScript statements you've already learned (and any others, for that matter), but the condition part of the statement uses its own syntax. This is called a conditional expression.
A conditional expression usually includes two values to be compared (in the preceding example, the values were <code>a</code> and <code>1</code>). These values can be variables, constants, or even expressions in themselves.
; By the Way: Either side of the conditional expression can be a variable, a constant, or an expression. You can compare a variable and a value, or compare two variables. (You can compare two constants, but there's usually no reason to.)
Between the two values to be compared is a conditional operator. This operator tells JavaScript how to compare the two values. For instance, the <code>==</code> operator is used to test whether the two values are equal. A variety of conditional operators is available:
* <code>==</code> Is equal to
* <code>!=</code> Is not equal to
* <code><</code> Is less than
* <code>></code> Is greater than
* <code>>=</code> Is greater than or equal to
* <code><=</code> Is less than or equal to
; By the Way: Be sure not to confuse the equality operator (<code>==</code>) with the assignment operator (<code>=</code>), even though they both might be read as "equals." Remember to use <code>=</code> when assigning a value to a variable, and <code>==</code> when comparing values. Confusing these two is one of the most common mistakes in JavaScript programming.
=== Combining Conditions with Logical Operators ===
Often, you'll want to check a variable for more than one possible value, or check more than one variable at once. JavaScript includes logical operators, also known as Boolean operators, for this purpose. For example, the following two statements check different conditions and use the same action:
<pre>if (phone == "") window.alert("error!");
if (email == "") window.alert("error!");</pre>
Using a logical operator, you can combine them into a single statement:
<pre>if (phone == "" || email == "") window.alert("Something's Missing!");</pre>
This statement uses the logical Or operator (<code>||</code>) to combine the conditions. Translated to English, this would be, "If the phone number is blank or the email address is blank, display an error message."
An additional logical operator is the And operator, <code>&&</code>. Consider this statement:
<pre>if (phone == "" && email == "") window.alert("Both are Missing!");</pre>
This statement uses <code>&&</code> (And) instead of <code>||</code> (Or), so the error message will only be displayed if both the email address and phone number variables are blank. (In this particular case, Or is a better choice.)
; Did you Know?: If the JavaScript interpreter discovers the answer to a conditional expression before reaching the end, it does not evaluate the rest of the condition. For example, if the first of two conditions separated by the <code>&&</code> operator is false, the second is not evaluated. You can take advantage of this to improve the speed of your scripts.
The third logical operator is the exclamation mark (<code>!</code>), which means Not. It can be used to invert an expression—in other words, a true expression would become false, and a false one would become true. For example, here's a statement that uses the Not operator:
<pre>if (!($phone == "")) alert("phone is OK");</pre>
In this statement, the <code>!</code> (Not) operator inverts the condition, so the action of the <code>if</code> statement is executed only if the phone number variable is not blank. The extra parentheses are necessary because all JavaScript conditions must be in parentheses. You could also use the <code>!=</code> (Not equal) operator to simplify this statement:
<pre>if ($phone != "") alert("phone is OK");</pre>
As with the previous statement, this alerts you if the phone number field is not blank.
; Did you Know?: The logical operators are powerful, but it's easy to accidentally create an impossible condition with them. For example, the condition <code>(a < 10 && a > 20)</code> might look correct at first glance. However, if you read it out loud, you get "If <code>a</code> is less than <code>10</code> and <code>a</code> is greater than <code>20</code>"an impossibility in our universe. In this case, Or (<code>||</code>) should have been used.
=== The <code>else</code> Keyword ===
An additional feature of the <code>if</code> statement is the <code>else</code> keyword. Much like its English equivalent, <code>else</code> tells the JavaScript interpreter what to do if the condition isn't true. The following is a simple example of the <code>else</code> keyword in action:
<pre>if (a == 1) {
alert("Found a 1!");
a = 0;
}
else {
alert("Incorrect value: " + a);
}</pre>
This is a modified version of the previous example. This displays a message and resets the variable <code>a</code> if the condition is met. If the condition is not met (if <code>a</code> is not <code>1</code>), a different message is displayed.
; By the Way: Like the <code>if</code> statement, <code>else</code> can be followed either by a single action statement or by a number of statements enclosed in braces.
== Using Shorthand Conditional Expressions ==
In addition to the <code>if</code> statement, JavaScript provides a shorthand type of conditional expression that you can use to make quick decisions. This uses a peculiar syntax that is also found in other languages, such as C. A conditional expression looks like this:
<pre>variable = (condition) ? (true action) : (false action);</pre>
This assigns one of two values to the variable: one if the condition is true, and another if it is false. Here is an example of a conditional expression:
<pre>value = (a == 1) ? 1 : 0;</pre>
This statement might look confusing, but it is equivalent to the following <code>if</code> statement:
<pre>if (a == 1)
value = 1;
else
value = 0;</pre>
In other words, the value after the question mark (<code>?</code>) will be used if the condition is true, and the value after the colon (<code>:</code>) will be used if the condition is false. The colon represents the <code>else</code> portion of this statement and, like the <code>else</code> portion of the <code>if</code> statement, is optional.
These shorthand expressions can be used anywhere JavaScript expects a value. They provide an easy way to make simple decisions about values. As an example, here's an easy way to display a grammatically correct message about a variable:
<pre>document.write("Found " + counter + ((counter == 1) ? " word." : " words."));</pre>
This will print the message <code>Found 1 word</code> if the <code>counter</code> variable has a value of <code>1</code>, and <code>Found 2 words</code> if its value is <code>2</code> or greater. This is one of the most common uses for a conditional expression.
== Testing Multiple Conditions with <code>if</code> and <code>else</code> ==
You can now create an example script using <code>if</code> and <code>else</code>. In [Hour 2], "Creating Simple Scripts," you created a script that displays the current date and time. This example will use conditions to display a greeting that depends on the time: "Good morning," "Good Afternoon," "Good Evening," or "Good Day". To accomplish this, you can use a combination of several <code>if</code> statements:
<pre>if (hours < 10) document.write("Good morning.");
else if (hours >= 14 && hours <= 17) document.write("Good afternoon.");
else if (hours > 17) document.write("Good evening.");
else document.write("Good day.");</pre>
The first statement checks the <code>hours</code> variable for a value less than 10—in other words, it checks whether the current time is before 10:00 a.m. If so, it displays the greeting "Good morning."
The second statement checks whether the time is between 2:00 p.m. and 5:00 p.m. and, if so, displays "Good afternoon." This statement uses <code>else if</code> to indicate that this condition will only be tested if the previous one failed—if it's morning, there's no need to check whether it's afternoon. Similarly, the third statement checks for times after 5:00 p.m. and displays "Good evening."
The final statement uses a simple <code>else</code>, meaning it will be executed if none of the previous conditions matched. This covers the times between 10:00 a.m. and 2:00 p.m. (neglected by the other statements) and displays "Good day."
=== The HTML File ===
To try this example in a browser, you'll need an HTML file. We will keep the JavaScript code separate, so [Listing 7.1] is the complete HTML file. Save it as <code>timegreet.html</code> but don't load it into the browser until you've prepared the JavaScript file in the next section.
; Listing 7.1. The HTML File for the Time and Greeting Example
<pre><html>
<head><title>if statement example</title></head>
<body>
<h1>Current Date and Time</h1>
<p>
<script language="JavaScript" type="text/javascript" src="timegreet.js">
</script>
</p>
</body>
</html>
</pre>
=== The JavaScript File ===
[Listing 7.2] shows the complete JavaScript file for the time greeting example. This uses the built-in <code>Date</code> object functions to find the current date and store it in <code>hours</code>, <code>mins</code>, and <code>secs</code> variables. Next, <code>document.write</code> statements display the current time, and the <code>if</code> and <code>else</code> statements introduced earlier display an appropriate greeting.
; Listing 7.2. A Script to Display the Current Time and a Greeting
<pre>// Get the current date
now = new Date();
// Split into hours, minutes, seconds
hours = now.getHours();
mins = now.getMinutes();
secs = now.getSeconds();
// Display the time
document.write("<h2>");
document.write(hours + ":" + mins + ":" + secs);
document.write("</h2>");
// Display a greeting
document.write("<p>");
if (hours < 10) document.write("Good morning.");
else if (hours >= 14 && hours <= 17) document.write("Good afternoon.");
else if (hours > 17) document.write("Good evening.");
else document.write("Good day.");
document.write("</p>");
</pre>
To try this example, save this file as <code>timegreet.js</code> (or download it from this book's website) and then load the <code>timegreet.html</code> file into your browser. [Figure 7.1] shows the results of this script.
== Using Multiple Conditions with <code>switch</code> ==
In the previous example, you used several <code>if</code> statements in a row to test for different conditions. Here is another example of this technique:
<pre>if (button=="next") window.location="next.html";
else if (button=="previous") window.location="prev.html";
else if (button=="home") window.location="home.html";
else if (button=="back") window.location="menu.html";</pre>
Although this is a compact way of doing things, this method can get messy if each <code>if</code> statement has its own block of code with several statements. As an alternative, JavaScript includes the <code>switch</code> statement, which enables you to combine several tests of the same variable or expression into a single block of statements. The following shows the same example converted to use <code>switch</code>:
<pre>switch(button) {
case "next":
window.location="next.html";
break;
case "previous":
window.location="prev.html";
break;
case "home":
window.location="home.html";
break;
case "back":
window.location="menu.html";
break;
default:
window.alert("Wrong button.");
}</pre>
The <code>switch</code> statement has several components:
* The initial <code>switch</code> statement. This statement includes the value to test (in this case, <code>button</code>) in parentheses.
* Braces (<code>{</code> and <code>}</code>) enclose the contents of the <code>switch</code> statement, similar to a function or an <code>if</code> statement.
* One or more <code>case</code> statements. Each of these statements specifies a value to compare with the value specified in the <code>switch</code> statement. If the values match, the statements after the <code>case</code> statement are executed. Otherwise, the next case is tried.
* The <code>break</code> statement is used to end each case. This skips to the end of the <code>switch</code>. If <code>break</code> is not included, statements in multiple cases might be executed whether they match or not.
* Optionally, the <code>default</code> case can be included and followed by one or more statements that are executed if none of the other cases were matched.
; By the Way: You can use multiple statements after each <code>case</code> statement within the <code>switch</code> structure. You don't need to enclose them in braces. If the case matches, the JavaScript interpreter executes statements until it encounters a <code>break</code> or the next <code>case</code>.
== Using <code>for</code> Loops ==
Loops are useful any time you need a section of code to execute more than once. The <code>for</code> keyword is the first tool to consider for creating loops. A <code>for</code> loop typically uses a variable (called a counter or an index) to keep track of how many times the loop has executed, and it stops when the counter reaches a certain number. A basic <code>for</code> statement looks like this:
<pre>for (var = 1; var < 10; var++) {</pre>
There are three parameters to the <code>for</code> loop, separated by semicolons:
* The first parameter (<code>var = 1</code> in the example) specifies a variable and assigns an initial value to it. This is called the initial expression because it sets up the initial state for the loop.
* The second parameter (<code>var < 10</code> in the example) is a condition that must remain true to keep the loop running. This is called the condition of the loop.
* The third parameter (<code>var++</code> in the example) is a statement that executes with each iteration of the loop. This is called the increment expression because it is typically used to increment the counter. The increment expression executes at the end of each loop iteration.
After the three parameters are specified, a left brace (<code>{</code>) is used to signal the beginning of a block. A right brace (<code>}</code>) is used at the end of the block. All the statements between the braces will be executed with each iteration of the loop.
The parameters for a <code>for</code> loop may sound a bit confusing, but once you're used to it, you'll use <code>for</code> loops frequently. Here is a simple example of this type of loop:
<pre>for (i=0; i<10; i++) {
document.write("This is line " + i + "<br>");
}</pre>
These statements define a loop that uses the variable <code>i</code>, initializes it with the value of zero, and loops as long as the value of <code>i</code> is less than 10. The increment expression, <code>i++</code>, adds one to the value of <code>i</code> with each iteration of the loop. Because this happens at the end of the loop, the output will list the numbers zero through nine.
When a loop includes only a single statement between the braces, as in this example, you can omit the braces if you want. The following statement defines the same loop without braces:
<pre>for (i=0; i<10; i++)
document.write("This is line " + i + "<br>");</pre>
; Did you Know?: It's a good style convention to use braces with all loops whether they contain one statement or many. This makes it easy to add statements to the loop later without causing syntax errors.
The loop in this example contains a <code>document.write</code> statement that will be repeatedly executed. To see just what this loop does, you can add it to a <code><script></code> section of an HTML document as shown in [Listing 7.3].
; Listing 7.3. A Loop Using the <code>for</code> Keyword
<pre><html>
<head>
<title>Using a for Loop</title>
</head>
<body>
<h1>"for" Loop Example</h1>
<p>The following is the output of the
<b>for</b> loop:</p>
<script language="JavaScript" type="text/javascript">
for (i=1;i<10;i++) {
document.write("This is line " + i + "<br>");
}
</script>
</body>
</html>
</pre>
This example displays a message with the loop's counter during each iteration. The output of [Listing 7.3] is shown in [Figure 7.2].
Notice that the loop was only executed nine times. This is because the conditional is <code>i<10</code>. When the counter (<code>i</code>) is incremented to <code>10</code>, the expression is no longer true. If you need the loop to count to <code>10</code>, you can change the conditional; either <code>i<=10</code> or <code>i<11</code> will work fine.
; By the Way: You might notice that the variable name <code>i</code> is often used as the counter in loops. This is a programming tradition that began with an ancient language called Forth. There's no need for you to follow this tradition, but it is a good idea to use one consistent variable for counters. (To learn more about Forth, see the Forth Interest Group's website at [http://www.forth.org/ www.forth.org].)
The structure of the <code>for</code> loop in JavaScript is based on Java, which in turn is based on C. Although it is traditionally used to count from one number to another, you can use just about any statement for the initialization, condition, and increment. However, there's usually a better way to do other types of loops with the <code>while</code> keyword, described in the next section.
== Using <code>while</code> Loops ==
Another keyword for loops in JavaScript is <code>while</code>. Unlike <code>for</code> loops, <code>while</code> loops don't necessarily use a variable to count. Instead, they execute as long as a condition is true. In fact, if the condition starts out as false, the statements won't execute at all.
The <code>while</code> statement includes the condition in parentheses, and it is followed by a block of statements within braces, just like a <code>for</code> loop. Here is a simple <code>while</code> loop:
<pre>while (total < 10) {
n++;
total += values[n];
}</pre>
This loop uses a counter, <code>n</code>, to iterate through the <code>values</code> array. Rather than stopping at a certain count, however, it stops when the total of the values reaches <code>10</code>.
You might have noticed that you could have done the same thing with a <code>for</code> loop:
<pre>for (n=0;total < 10; n++) {
total += values[n];
}</pre>
As a matter of fact, the <code>for</code> loop is nothing more than a special kind of <code>while</code> loop that handles an initialization and an increment for you. You can generally use <code>while</code> for any loop. However, it's best to choose whichever type of loop makes the most sense for the job, or that takes the least amount of typing.
== Using <code>do…while</code> Loops ==
JavaScript 1.2 introduced a third type of loop: the <code>do…while</code> loop. This type of loop is similar to an ordinary <code>while</code> loop, with one difference: The condition is tested at the end of the loop rather than the beginning. Here is a typical <code>do…while</code> loop:
<pre>do {
n++;
total += values[n];
}
while (total < 10);</pre>
As you've probably noticed, this is basically an upside-down version of the previous <code>while</code> example. There is one difference: With the <code>do</code> loop, the condition is tested at the end of the loop. This means that the statements in the loop will always be executed at least once, even if the condition is never true.
; By the Way: As with the <code>for</code> and <code>while</code> loops, the <code>do</code> loop can include a single statement without braces, or a number of statements enclosed in braces.
== Working with Loops ==
Although you can use simple <code>for</code> and <code>while</code> loops for straightforward tasks, there are some considerations you should make when using more complicated loops. In the next sections, we'll look at infinite loops and the <code>break</code> and <code>continue</code> statements, which give you more control over your loops.
=== Creating an Infinite Loop ===
The <code>for</code> and <code>while</code> loops give you quite a bit of control over the loop. In some cases, this can cause problems if you're not careful. For example, look at the following loop code:
<pre>while (i < 10) {
n++;
values[n] = 0;
}</pre>
There's a mistake in this example. The condition of the <code>while</code> loop refers to the <code>i</code> variable, but that variable doesn't actually change during the loop. This creates an infinite loop. The loop will continue executing until the user stops it, or until it generates an error of some kind.
Infinite loops can't always be stopped by the user, except by quitting the browser—and some loops can even prevent the browser from quitting, or cause a crash.
Obviously, infinite loops are something to avoid. They can also be difficult to spot because JavaScript won't give you an error that actually tells you there is an infinite loop. Thus, each time you create a loop in a script, you should be careful to make sure there's a way out.
; By the Way: Depending on the browser version in use, an infinite loop might even make the browser stop responding to the user. Be sure you provide an escape route from infinite loops, and save your script before you test it just in case.
Occasionally, you might want to create an infinite loop deliberately. This might include situations when you want your program to execute until the user stops it, or if you are providing an escape route with the <code>break</code> statement, which is introduced in the next section. Here's an easy way to create an infinite loop:
<pre>while (true) {</pre>
Because the value <code>true</code> is the conditional, this loop will always find its condition to be true.
=== Escaping from a Loop ===
There is one way out of an infinite loop. You can use the <code>break</code> statement during a loop to exit it immediately and continue with the first statement after the loop. Here is a simple example of the use of <code>break</code>:
<pre>while (true) {
n++;
if (values[n] == 1) break;
}</pre>
Although the <code>while</code> statement is set up as an infinite loop, the <code>if</code> statement checks the corresponding value of an array. If it finds a value of <code>1</code>, it exits the loop.
When the JavaScript interpreter encounters a <code>break</code> statement, it skips the rest of the loop and continues the script with the first statement after the right brace at the loop's end. You can use the <code>break</code> statement in any type of loop, whether infinite or not. This provides an easy way to exit if an error occurs, or if another condition is met.
=== Continuing a Loop ===
One more statement is available to help you control the execution of statements in a loop. The <code>continue</code> statement skips the rest of the loop but, unlike <code>break</code>, it continues with the next iteration of the loop. Here is a simple example:
<pre>for (i=1; i<21; i++) {
if (score[i]==0) continue;
document.write("Student number ",i, " Score: ", score[i], "\n");
}</pre>
This script uses a <code>for</code> loop to print out scores for 20 students, stored in the <code>score</code> array. The <code>if</code> statement is used to check for scores with a value of <code>0</code>. The script assumes that a score of <code>0</code> means that the student didn't take the test, so it continues the loop without printing that score.
== Looping Through Object Properties ==
A third type of loop is available in JavaScript. The <code>for…in</code> loop is not as flexible as an ordinary <code>for</code> or <code>while</code> loop. Instead, it is specifically designed to perform an operation on each property of an object.
For example, the <code>navigator</code> object contains properties that describe the user's browser, as you'll learn in [Hour 15], "Unobtrusive Scripting." You can use <code>for…in</code> to display this object's properties:
<pre>for (i in navigator) {
document.write("property: " + i);
document.write(" value: " + navigator[i] + "<br>");
}</pre>
Like an ordinary <code>for</code> loop, this type of loop uses an index variable (<code>i</code> in the example). For each iteration of the loop, the variable is set to the next property of the object. This makes it easy when you need to check or modify each of an object's properties.
=== Try It Yourself: Working with Arrays and Loops ===
To apply your knowledge of loops, you will now create a script that deals with arrays using loops. As you progress through this script, try to imagine how difficult it would be without JavaScript's looping features.
This simple script will prompt the user for a series of names. After all of the names have been entered, it will display the list of names in a numbered list. To begin the script, initialize some variables:
<pre>names = new Array();
i = 0;</pre>
The <code>names</code> array will store the names the user enters. You don't know how many names will be entered, so you don't need to specify a dimension for the array. The <code>i</code> variable will be used as a counter in the loops.
Next, use the <code>prompt</code> statement to prompt the user for a series of names. Use a loop to repeat the prompt for each name. You want the user to enter at least one name, so a <code>do</code> loop is ideal:
<pre>do {
next = prompt("Enter the Next Name", "");
if (next > " ") names[i] = next;
i = i + 1;
}
while (next > " ");</pre>
;Did you Know?: If you're interested in making your scripts as short as possible, remember that you could use the increment (<code>++</code>) operator to combine the <code>i = i + 1</code> statement with the previous statement: <code>names[i++]=1</code>.
This loop prompts for a string called <code>next</code>. If a name was entered and isn't blank, it's stored as the next entry in the <code>names</code> array. The <code>i</code> counter is then incremented. The loop repeats until the user doesn't enter a name or clicks Cancel in the prompt dialog.
Next, your script can display the number of names that was entered:
<pre>document.write("<h2>" + (names.length) + " names entered.</h2>");</pre>
This statement displays the <code>length</code> property of the <code>names</code> array, surrounded by level 2 heading tags for emphasis.
Next, the script should display all the names in the order they were entered. Because the names are in an array, the <code>for…in</code> loop is a good choice:
<pre>document.write("<ol>");
for (i in names) {
document.write("<li>" + names[i] + "<br>");
}
document.write("</ol>");</pre>
Here you have a <code>for…in</code> loop that loops through the <code>names</code> array, assigning the counter <code>i</code> to each index in turn. The script then prints the name with a <code><nowiki><li></nowiki></code> tag as an item in an ordered list. Before and after the loop, the script prints beginning and ending <code><nowiki><ol></nowiki></code> tags.
You now have everything you need for a working script. [Listing 7.4] shows the HTML file for this example, and [Listing 7.5] shows the JavaScript file.
; Listing 7.4. A Script to Prompt for Names and Display Them (HTML)
<pre><html>
<head>
<title>Loops Example</title>
</head>
<body>
<h1>Loop Example</h1>
<p>Enter a series of names. I will then
display them in a nifty numbered list.</p>
<script language="JavaScript" type="text/javascript" src="loops.js">
</script>
</body>
</html>
</pre>
; Listing 7.5. A Script to Prompt for Names and Display Them (JavaScript)
<pre>// create the array
names = new Array();
i = 0;
// loop and prompt for names
do {
next = window.prompt("Enter the Next Name", "");
if (next > " ") names[i] = next;
i = i + 1;
} while (next > " ");
document.write("<h2>" + (names.length) + " names entered.</h2>");
// display all of the names
document.write("<ol>");
for (i in names) {
document.write("<li>" + names[i] + "<br>");
}
document.write("</ol>");
</pre>
To try this example, save the JavaScript file as <code>loops.js</code> and then load the HTML document into a browser. You'll be prompted for one name at a time. Enter several names, and then click Cancel to indicate that you're finished. [Figure 7.3] shows what the final results should look like in a browser.
== Summary ==
In this hour, you've learned two ways to control the flow of your scripts. First, you learned how to use the <code>if</code> statement to evaluate conditional expressions and react to them. You also learned a shorthand form of conditional expression using the <code>?</code> operator, and the <code>switch</code> statement for working with multiple conditions.
You also learned about JavaScript's looping capabilities using <code>for</code>, <code>while</code>, and other loops, and how to control loops further using the <code>break</code> and <code>continue</code> statements. Lastly, you looked at the <code>for…in</code> loop for working with each property of an object.
In the next hour, you'll look at JavaScript's built-in functions, another essential tool for creating your own scripts. You'll also learn about third-party libraries that enable you to create complex effects with simple scripts.
=== Q&A ===
;Q1:What happens if I compare two items of different data types (for example, a number and a string) in a conditional expression?
;A1:The JavaScript interpreter does its best to make the values a common format and compare them. In this case, it would convert them both to strings before comparing. In JavaScript 1.3 and later, you can use the special equality operator <code>===</code> to compare two values and their types—using this operator, the expression will be true only if the expressions have the same value and the same data type.
;Q2:Why would I use switch if using <code>if </code>and <code>else </code>is just as simple?
;A2:Either one works, so it's your choice. Personally, I find switch statements confusing and prefer to use if. Your choice might also depend on what other programming languages you're familiar with because some support switch and others don't.
;Q3:Why don't I get a friendly error message if I accidentally use <code>=</code> instead of <code>==</code>?
;A3:In some cases, this will result in an error. However, the incorrect version often appears to be a correct statement. For example, in the statement<code> if (a=1)</code>, the variable a will be assigned the value 1. The <code>if</code> statement is considered true, and the value of a is lost.
;Q4:It seems like I could use a <code>for</code> loop to replace any of the other loop methods (<code>while</code>, <code>do</code>, and so on). Why so many choices?
;A4:You're right. In most cases, a <code>for</code> loop will work, and you can do all your loops that way if you want. For that matter, you can use <code>while</code> to replace a <code>for</code> loop. You can use whichever looping method makes the most sense for your application.
=== Quiz Questions ===
Test your knowledge of JavaScript conditions and loops by answering the following questions.
;1.:Which of the following operators means "is not equal to" in JavaScript?
#<code>!</code>
#<code>!=</code>
#<code><></code>
;2.:
What does the <code>switch </code>statement do?
#Tests a variable for a number of different values
#Turns a variable on or off
#Makes ordinary if statements longer and more confusing
;3.:Which type of JavaScript loop checks the condition at the end of the loop?
#<code>for</code>
#<code>while</code>
#<code>do…while</code>
;4.:Within a loop, what does the <code>break </code>statement do?
#Crashes the browser
#Starts the loop over
#Escapes the loop entirely
;5.:The statement <code>while (3==3)</code> is an example of
#A typographical error
#An infinite loop
#An illegal JavaScript statement
=== Quiz Answers ===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| b. The <code>!=</code> operator means is not equal to.
|-
| align="right" | '''2.'''
| a. The <code>switch</code> statement can test the same variable or expression for a number of different values.
|-
| align="right" | '''3.'''
| c. The <code>do…while</code> loop uses a condition at the end of the loop.
|-
| align="right" | '''4.'''
| c. The <code>break</code> statement escapes the loop.
|-
| align="right" | '''5.'''
| b. Because the condition <code>(3==3)</code> will always be true, this statement creates an infinite loop.
|}
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
* Modify [Listing 7.4] to sort the names in alphabetical order before displaying them. You can use the <code>sort</code> method of the <code>Array</code> object, described in [Hour 5], "Using Variables, Strings, and Arrays."
* Modify [Listing 7.4] to prompt for exactly 10 names. What happens if you click the Cancel button instead of entering a name?
mfix34u9w57z205e7xllfo6epkpvt6i
User:Moncur/06
2
2081
39271
5829
2026-04-13T06:03:44Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39271
wikitext
text/x-wiki
=6. Using Functions and Objects=
== Using Functions ==
The scripts you've seen so far are simple lists of instructions. The browser begins with the first statement after the <code><script></code> tag and follows each instruction in order until it reaches the closing <code></script></code> tag (or encounters an error).
Although this is a straightforward approach for short scripts, it can be confusing to read a longer script written in this fashion. To make it easier for you to organize your scripts, JavaScript supports functions, which you learned about in [Hour 3], "Getting Started with JavaScript Programming." In this section, you will learn how to define and use functions.
=== Defining a Function ===
Functions are groups of JavaScript statements that can be treated as a single unit. To use a function, you must first define it. Here is a simple example of a function definition:
<pre>function Greet() {
alert("Greetings.");
}
</pre>
This defines a function that displays an alert message to the user. This begins with the <code>function</code> keyword. The function's name is <code>Greet</code>. Notice the parentheses after the function's name. As you'll learn next, the space between them is not always empty.
The first and last lines of the function definition include braces (<code>{</code> and <code>}</code>). You use these to enclose all of the statements in the function. The browser uses the braces to determine where the function begins and ends.
Between the braces, this particular function contains a single line. This uses the built-in <code>alert()</code> function, which displays an alert message. The message will contain the text "Greetings."
; By the Way: Function names are case sensitive. If you define a function such as <code>Greet()</code> with a capital letter, be sure you use the identical name when you call the function.
Now, about those parentheses. The current <code>Greet()</code> function always does the same thing: Each time you use it, it displays the same message. Although this avoids a bit of typing, it doesn't really provide much of an advantage.
To make your function more flexible, you can add parameters, also known as arguments. These are variables that are received by the function each time it is called. For example, you can add a parameter called <code>who</code> that tells the function the name of the person to greet. Here is the modified <code>Greet()</code> function:
<pre>function Greet(who) {
alert("Greetings, " + who);
}
</pre>
Of course, to use this function, you should include it in an HTML document. Traditionally, the best place for a function definition is within the <code><head></code> section of the document. Because the statements in the <code><head></code> section are executed first, this ensures that the function is defined before it is used.
[Listing 6.1] shows the <code>Greet()</code> function embedded in the header section of an HTML document.
; Listing 6.1. The <code>Greet()</code> Function in an HTML Document
<pre><html>
<head>
<title>Functions</title>
<script language="JavaScript" type="text/javascript">
function Greet(who) {
alert("Greetings, " + who);
}
</script>
</head>
<body>
This is the body of the page.
</body>
</html>
</pre>
; By the Way: As usual, you can download the listings for this hour or view them online at this book's website.
=== Calling the Function ===
You have now defined a function and placed it in an HTML document. However, if you load [Listing 6.1] into a browser, you'll notice that it does absolutely nothing. This is because the function is defined—ready to be used—but we haven't used it yet.
Making use of a function is referred to as calling the function. To call a function, use the function's name as a statement in a script. You will need to include the parentheses and the values for the function's parameters. For example, here's a statement that calls the <code>Greet</code> function:
<pre>Greet("Fred");
</pre>
This tells the JavaScript interpreter to transfer control to the first statement in the <code>Greet</code> function. It also passes the parameter <code>"Fred"</code> to the function. This value will be assigned to the <code>who</code> variable inside the function.
; By the Way: Functions can have more than one parameter. To define a function with multiple parameters, list a variable name for each parameter, separated by commas. To call the function, specify values for each parameter separated by commas.
[Listing 6.2] shows a complete HTML document that includes the function definition and a second script in the body of the page that actually calls the function. To demonstrate the usefulness of functions, we'll call it twice to greet two different people.
; Listing 6.2. The Complete Function Example
<pre><html>
<head>
<title>Functions</title>
<script language="JavaScript" type="text/javascript">
function Greet(who) {
alert("Greetings, " + who);
}
</script>
</head>
<body>
<h1>Function Example</h1>
<p>Prepare to be greeted twice.</p>
<script language="JavaScript" type="text/javascript">
Greet("Fred");
Greet("Ethel");
</script>
</body>
</html>
</pre>
This listing includes a second set of <code><script></code> tags in the body of the page. The second script includes two function calls to the <code>Greet</code> function, each with a different name.
Now that you have a script that actually does something, try loading it into a browser. You should see something like [Figure 6.1], which shows the Greeting script running in Firefox.
; By the Way: Notice that the second alert message isn't displayed until you press the OK button on the first alert. This is because JavaScript processing is halted while alerts are displayed.
=== Returning a Value ===
The function you just created displays a message to the user, but functions can also return a value to the script that called them. This allows you to use functions to calculate values. As an example, you can create a function that averages four numbers.
Your function should begin with the <code>function</code> keyword, the function's name, and the parameters it accepts. We will use the variable names a, b, c, and d for the four numbers to average. Here is the first line of the function:
<pre>function Average(a,b,c,d) {
</pre>
; By the Way:I've also included the opening brace (<code>{</code>) on the first line of the function. This is a common style, but you can also place the brace on the next line, or on a line by itself.
Next, the function needs to calculate the average of the four parameters. You can calculate this by adding them, and then dividing by the number of parameters (in this case, 4). Thus, here is the next line of the function:
<pre>result = (a + b + c + d) / 4;
</pre>
This statement creates a variable called <code>result</code> and calculates the result by adding the four numbers, and then dividing by 4. (The parentheses are necessary to tell JavaScript to perform the addition before the division.)
To send this result back to the script that called the function, you use the <code>return</code> keyword. Here is the last part of the function:
<pre>return result;
}
</pre>
[Listing 6.3] shows the complete <code>Average()</code> function in an HTML document. This HTML document also includes a small script in the <code><body></code> section that calls the <code>Average()</code> function and displays the result.
; Listing 6.3. The <code>Average()</code> Function in an HTML Document
<pre><html>
<head>
<title>Function Example</title>
<script language="JavaScript" type="text/javascript">
function Average(a,b,c,d) {
result = (a + b + c + d) / 4;
return result;
}
</script>
</head>
<body>
<p>The following is the result of the function call.</p>
<script LANGUAGE="JavaScript" type="text/javascript">
score = Average(3,4,5,6);
document.write("The average is: " + score);
</script>
</body>
</html>
</pre>
You can use a variable with the function call, as shown in this listing. This statement averages the numbers 3, 4, 5, and 6 and stores the result in a variable called <code>score</code>:
<pre>score = Average(3,4,5,6);
</pre>
; Did you Know?: You can also use the function call directly in an expression. For example, you could use the <code>alert</code> statement to display the result of the function: <code>alert(Average(1,2,3,4))</code>.
== Introducing Objects ==
In the previous hour, you learned how to use variables to represent different kinds of data in JavaScript. JavaScript also supports objects, a more complex kind of variable that can store multiple data items and functions.
Although a variable can have only one value at a time, an object can contain multiple values, as well as functions for working with the values. This allows you to group related data items and the functions that deal with them into a single object.
In this hour, you'll learn how to define and use your own objects. You've already worked with some objects:
* DOM objects Allow your scripts to interact with web pages. You learned about these in [Hour 4], "Working with the Document Object Model (DOM)."
* Built-in objects Include strings and arrays, which you learned about in [Hour 5], "Using Variables, Strings, and Arrays."
The syntax for working with all three types of objects—DOM objects, built-in objects, and custom objects—is the same, so even if you don't end up creating your own objects, you should have a good understanding of JavaScript's object terminology and syntax.
=== Creating Objects ===
When you created an array in the previous hour, you used the following JavaScript statement:
<pre>scores = new Array(4);
</pre>
The <code>new</code> keyword tells the JavaScript interpreter to use a function—in this case, the built-in <code>Array</code> function—to create an object. You'll create a function for a custom object later in this hour.
=== Object Properties and Values ===
Each object has one or more properties—essentially, variables that will be stored within the object. For example, in [Hour 4], you learned that the <code>location.href</code> property gives you the URL of the current document. The <code>href</code> property is one of the properties of the <code>location</code> object in the DOM.
You've also used the <code>length</code> property of <code>String</code> objects, as in the following example from the previous hour:
<pre>test = "This is a test."
document.write(test.length);
</pre>
Like variables, each object property has a value. To read a property's value, you simply include the object name and property name, separated by a period, in any expression, as in <code>test.length</code> previously. You can change a property's value using the <code>=</code> operator, just like a variable. The following example sends the browser to a new URL by changing the <code>location.href</code> property:
<pre>location.href="http://www.jsworkshop.com/";
</pre>
; By the Way: An object can also be a property of another object. This is referred to as a child object.
=== Understanding Methods ===
Along with properties, each object can have one or more methods. These are functions that work with the object's data. For example, the following JavaScript statement reloads the current document, as you learned in [Hour 4]:
<pre>location.reload();
</pre>
When you use <code>reload()</code>, you're using a method of the <code>location</code> object. Like normal functions, methods can accept arguments in parentheses, and can return values.
== Using Objects to Simplify Scripting ==
Although JavaScript's variables and arrays are versatile ways to store data, sometimes you need a more complicated structure. For example, suppose you are creating a script to work with a business card database that contains names, addresses, and phone numbers for a variety of people.
If you were using regular variables, you would need several separate variables for each person in the database: a name variable, an address variable, and so on. This would be very confusing.
Arrays would improve things slightly. You could have a names array, an addresses array, and a phone number array. Each person in the database would have an entry in each array. This would be more convenient, but still not perfect.
With objects, you can make the variables that store the database as logical as business cards. Each person is represented by a <code>Card</code> object, which has properties for name, address, and phone number. You can even add methods to the object to display or work with the information.
In the following sections, you'll use JavaScript to actually create the <code>Card</code> object and its properties and methods. Later in this hour, you'll use the <code>Card</code> object in a script to display information for several members of the database.
=== Defining an Object ===
The first step in creating an object is to name it and its properties. We've already decided to call the object a <code>Card</code> object. Each object will have the following properties:
* <code>name</code>
* <code>address</code>
* <code>workphone</code>
* <code>homephone</code>
The first step in using this object in a JavaScript program is to create a function to make new <code>Card</code> objects. This function is called the constructor for an object. Here is the constructor function for the <code>Card</code> object:
<pre>function Card(name,address,work,home) {
this.name = name;
this.address = address;
this.workphone = work;
this.homephone = home;
}
</pre>
The constructor is a simple function that accepts parameters to initialize a new object and assigns them to the corresponding properties. This function accepts several parameters from the statement that calls the function, and then assigns them as properties of an object. Because the function is called <code>Card</code>, the object is the <code>Card</code> object.
Notice the <code>this</code> keyword. You'll use it anytime you create an object definition. Use <code>this</code> to refer to the current object—the one that is being created by the function.
=== Defining an Object Method===
Next, you will create a method to work with the <code>Card</code> object. Because all <code>Card</code> objects will have the same properties, it might be handy to have a function that prints out the properties in a neat format. Let's call this function <code>PrintCard()</code>.
Your <code>PrintCard()</code> function will be used as a method for <code>Card</code> objects, so you don't need to ask for parameters. Instead, you can use the <code>this</code> keyword again to refer to the current object's properties. Here is a function definition for the <code>PrintCard()</code> function:
<pre>function PrintCard() {
line1 = "Name: "+ this.name + "<br>\n";
line2 = "Address: " + this.address + "<br>\n";
line3 = "Work Phone: " + this.workphone + "<br>\n";
line4 = "Home Phone: " + this.homephone + "<hr>\n";
document.write(line1, line2, line3, line4);
}
</pre>
This function simply reads the properties from the current object (<code>this</code>), prints each one with a caption, and skips to a new line.
You now have a function that prints a card, but it isn't officially a method of the <code>Card</code> object. The last thing you need to do is make <code>PrintCard()</code> part of the function definition for <code>Card</code> objects. Here is the modified function definition:
<pre>function Card(name,address,work,home) {
this.name = name;
this.address = address;
this.workphone = work;
this.homephone = home;
this.PrintCard = PrintCard;
}
</pre>
The added statement looks just like another property definition, but it refers to the <code>PrintCard()</code> function. This will work so long as the PrintCard() function is defined with its own function definition. Methods are essentially properties that define a function rather than a simple value.
; Did you Know?: The previous example uses lowercase names such as <code>workphone</code> for properties, and an uppercase name (<code>PrintCard</code>) for the method. You can use any case for property and method names, but this is one way to make it clear that <code>PrintCard</code> is a method rather than an ordinary property.
=== Creating an Object Instance ===
Now let's use the object definition and method you just created. To use an object definition, you create a new object. This is done with the <code>new</code> keyword. This is the same keyword you've already used to create <code>Date</code> and <code>Array</code> objects.
The following statement creates a new <code>Card</code> object called <code>tom</code>:
<pre>tom = new Card("Tom Jones", "123 Elm Street", "555-1234", "555-9876");
</pre>
As you can see, creating an object is easy. All you do is call the <code>Card()</code> function (the object definition) and give it the required attributes, in the same order as the definition.
After this statement executes, a new object is created to hold Tom's information. This is called an instance of the <code>Card</code> object. Just as there can be several string variables in a program, there can be several instances of an object you define.
Rather than specify all the information for a card with the <code>new</code> keyword, you can assign them after the fact. For example, the following script creates an empty <code>Card</code> object called <code>holmes</code>, and then assigns its properties:
<pre>holmes = new Card();
holmes.name = "Sherlock Holmes";
holmes.address = "221B Baker Street";
holmes.workphone = "555-2345";
holmes.homephone = "555-3456";
</pre>
After you've created an instance of the <code>Card</code> object using either of these methods, you can use the <code>PrintCard()</code> method to display its information. For example, this statement displays the properties of the <code>tom</code> card:
<pre>tom.PrintCard();
</pre>
== Extending Built-in Objects ==
JavaScript includes a feature that enables you to extend the definitions of built-in objects. For example, if you think the <code>String</code> object doesn't quite fit your needs, you can extend it, adding a new property or method. This might be very useful if you were creating a large script that used many strings.
You can add both properties and methods to an existing object by using the <code>prototype</code> keyword. (A prototype is another name for an object's definition, or constructor function.) The <code>prototype</code> keyword enables you to change the definition of an object outside its constructor function.
As an example, let's add a method to the <code>String</code> object definition. You will create a method called <code>heading</code>, which converts a string into an HTML heading. The following statement defines a string called <code>title</code>:
<pre>title = "Fred's Home Page";
</pre>
This statement would output the contents of the <code>title</code> string as an HTML level 1 heading:
<pre>document.write(title.heading(1));
</pre>
[Listing 6.4] adds a <code>heading</code> method to the <code>String</code> object definition that will display the string as a heading, and then displays three headings using the method.
; Listing 6.4. Adding a Method to the <code>String</code> Object
<pre>
<html>
<head>
<title>Test of heading method</title>
</head>
<body>
<script LANGUAGE="JavaScript" type="text/javascript">
function addhead (level) {
html = "H" + level;
text = this.toString();
start = "<" + html + ">";
stop = "</" + html + ">";
return start + text + stop;
}
String.prototype.heading = addhead;
document.write ("This is a heading 1".heading(1));
document.write ("This is a heading 2".heading(2));
document.write ("This is a heading 3".heading(3));
</script>
</body>
</html>
</pre>
First, you define the <code>addhead()</code> function, which will serve as the new string method. It accepts a number to specify the heading level. The <code>start</code> and <code>stop</code> variables are used to store the HTML "begin header" and "end header" tags, such as <code><nowiki><h1></nowiki></code> and <code><nowiki></h1></nowiki></code>.
After the function is defined, use the <code>prototype</code> keyword to add it as a method of the <code>String</code> object. You can then use this method on any <code>String</code> object or, in fact, any JavaScript string. This is demonstrated by the last three statements, which display quoted text strings as level 1, 2, and 3 headers.
=== Try It Yourself Storing Data in Objects ===
Now you've created a new object to store business cards and a method to print them out. As a final demonstration of objects, properties, functions, and methods, you will now use this object in a web page to display data for several cards.
Your script will need to include the function definition for <code>PrintCard()</code>, along with the function definition for the <code>Card</code> object. You will then create three cards and print them out in the body of the document. We will use separate HTML and JavaScript files for this example. [Listing 6.5] shows the complete script.
; Listing 6.5. An Example Script That Uses the <code>Card</code> Object
<pre>
// define the functions
function PrintCard() {
line1 = "<b>Name: </b>" + this.name + "<br>\n";
line2 = "<b>Address: </b>" + this.address + "<br>\n";
line3 = "<b>Work Phone: </b>" + this.workphone + "<br>\n";
line4 = "<b>Home Phone: </b>" + this.homephone + "<hr>\n";
document.write(line1, line2, line3, line4);
}
function Card(name,address,work,home) {
this.name = name;
this.address = address;
this.workphone = work;
this.homephone = home;
this.PrintCard = PrintCard;
}
// Create the objects
sue = new Card("Sue Suthers", "123 Elm Street", "555-1234", "555-9876");
phred = new Card("Phred Madsen", "233 Oak Lane", "555-2222", "555-4444");
henry = new Card("Henry Tillman", "233 Walnut Circle", "555-1299", "555-1344");
// And print them
sue.PrintCard();
phred.PrintCard();
henry.PrintCard();
</pre>
Notice that the <code>PrintCard()</code> function has been modified slightly to make things look good with the captions in boldface. To use this script, save it as <code>cardtest.js</code>. Next, you'll need to include the script in a simple HTML document. [Listing 6.6] shows the HTML document for this example.
; Listing 6.6.: The HTML File for the <code>Card</code> Object Example
<pre><html>
<head>
<title>JavaScript Business Cards</title>
</head>
<body>
<h1>JavaScript Business Card Test</h1>
<p>Script begins here.</p><hr>
<script language="JavaScript" type="text/javascript" src="cardtest.js">
</script>
<p>End of script.</p>
</body>
</html>
</pre>
To test the script, save the HTML document in the same directory as the <code>cardtest.js</code> file you created earlier, and then load the HTML document into a browser. The browser's display of this example is shown in [Figure 6.2].
; By the Way: This example isn't a very sophisticated database because you have to include the data for each person in the script. However, an object like this could be used to store a database record retrieved from a database server with thousands of records.
== Summary ==
In this hour, you've looked at two important features of JavaScript. First, you learned how to use functions to group JavaScript statements, and how to call functions and use the values they return.
You also learned about JavaScript's object-oriented features—defining objects with constructor functions, creating object instances, and working with properties, property values, and methods.
In the next hour, you'll look at two more features you'll use in almost every script—conditions to let your scripts evaluate data, and loops to repeat sections of code.
=== Q&A ===
; Q1:Many objects in JavaScript, such as DOM objects, include parent and child objects. Can I include child objects in my custom object definitions?
; A1:Yes. Just create a constructor function for the child object, and then add a property to the parent object that corresponds to it. For example, if you created a Nicknames object to store several nicknames for a person in the card file example, you could add it as a child object in the Card object's constructor: <code>this.nick = new Nicknames();</code>.
; Q2:Can I create an array of custom objects?
; A2:Yes. First, create the object definition as usual and define an array with the required number of elements. Then assign a new object to each array element (for example, <code>cardarray[1] = new Card();</code>). You can use a loop, described in the next hour, to assign objects to an entire array at once.
; Q3:Can I modify all properties of objects?
; A3:With custom objects, yes—but this varies with built-in objects and DOM objects. For example, you can use the length property to find the length of a string, but it is a read-only property and cannot be modified.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
1. What JavaScript keyword is used to create an instance of an object?
# object
# new
# instance
2. What is the meaning of the <code>this</code> keyword in JavaScript?
# The current object.
# The current script.
# It has no meaning.
3. What does the <code>prototype</code> keyword allow you to do in a script?
# Change the syntax of JavaScript commands.
# Modify the definitions of built-in objects.
# Modify the user's browser so only your scripts will work.
=== Quiz Answers ===
1. b. The <code>new</code> keyword creates an object instance.
2. a. The <code>this</code> keyword refers to the current object.
3. b. The <code>prototype</code> keyword allows you to modify the definitions of built-in objects.
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
* Modify the <code>Greet()</code> function to accept two parameters, <code>who1</code> and <code>who2</code>, and to include both names in a single greeting dialog. Modify [Listing 6.2] to use a single function call to the new function.
* Modify the definition of the <code>Card</code> object to include a property called <code>email</code> for the person's email address. Modify the <code>PrintCard()</code> function in [Listing 6.5] to include this property.
2y033ilivzkczx0pp7fbjg2hs59kmam
User:Moncur/05
2
2082
39270
5828
2026-04-13T06:03:44Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39270
wikitext
text/x-wiki
=5. Using Variables, Strings, and Arrays=
== Using Variables ==
Unless you skipped the first few hours of this book, you've already used a few variables. You probably can also figure out how to use a few more without any help. Nevertheless, there are some aspects of variables you haven't learned yet. We will now look at some of the details.
=== Choosing Variable Names ===
Variables are named containers that can store data (for example, a number, a text string, or an object). As you learned earlier in this book, each variable has a name. There are specific rules you must follow when choosing a variable name:
* Variable names can include letters of the alphabet, both upper- and lowercase. They can also include the digits 09 and the underscore (_) character.
* Variable names cannot include spaces or any other punctuation characters.
* The first character of the variable name must be either a letter or an underscore.
* Variable names are case sensitive: <code>totalnum</code>, <code>Totalnum</code>, and <code>TotalNum</code> are separate variable names.
* There is no official limit on the length of variable names, but they must fit within one line.
Using these rules, the following are examples of valid variable names:
<pre>
total_number_of_fish
LastInvoiceNumber
temp1
a
_var39</pre>
; By the Way: You can choose to use either friendly, easy-to-read names or completely cryptic ones. Do yourself a favor: use longer, friendly names whenever possible. Although you might remember the difference between <code>a</code>, <code>b</code>, <code>x</code>, and <code>x1</code> right now, you might not after a good night's sleep.
=== Using Local and Global Variables ===
Some computer languages require you to declare a variable before you use it. JavaScript includes the <code>var</code> keyword, which can be used to declare a variable. You can omit <code>var</code> in many cases; the variable is still declared the first time you assign a value to it.
To understand where to declare a variable, you will need to understand the concept of scope. A variable's scope is the area of the script in which that variable can be used. There are two types of variables:
* Global variables have the entire script (and other scripts in the same HTML document) as their scope. They can be used anywhere, even within functions.
* Local variables have a single function as their scope. They can be used only within the function they are created in.
To create a global variable, you declare it in the main script, outside any functions. You can use the <code>var</code> keyword to declare the variable, as in this example:
<pre>var students = 25;</pre>
This statement declares a variable called <code>students</code> and assigns it a value of 25. If this statement is used outside functions, it creates a global variable. The <code>var</code> keyword is optional in this case, so this statement is equivalent to the previous one:
<pre>students = 25;</pre>
Before you get in the habit of omitting the <code>var</code> keyword, be sure you understand exactly when it's required. It's actually a good idea to always use the <code>var</code> keyword - you'll avoid errors and make your script easier to read, and it won't usually cause any trouble.
; By the Way: For the most part, the variables you've used in earlier hours of this book have been global.
A local variable belongs to a particular function. Any variable you declare with the <code>var</code> keyword in a function is a local variable. Additionally, the variables in the function's parameter list are always local variables.
To create a local variable within a function, you must use the <code>var</code> keyword. This forces JavaScript to create a local variable, even if there is a global variable with the same name.
You should now understand the difference between local and global variables. If you're still a bit confused, don't worry—if you use the <code>var</code> keyword every time, you'll usually end up with the right type of variable.
=== Assigning Values to Variables ===
As you learned in [Hour 2], "Creating a Simple Script," you can use the equal sign to assign a value to a variable. For example, this statement assigns the value 40 to the variable <code>lines</code>:
<pre>lines = 40;</pre>
You can use any expression to the right of the equal sign, including other variables. You have used this syntax earlier to add one to a variable:
<pre>lines = lines + 1;</pre>
Because incrementing or decrementing variables is quite common, JavaScript includes two types of shorthand for this syntax. The first is the <code>+=</code> operator, which enables you to create the following shorter version of the preceding example:
<pre>lines += 1;</pre>
Similarly, you can subtract a number from a variable using the <code>-=</code> operator:
<pre>lines -= 1;</pre>
If you still think that's too much to type, JavaScript also includes the increment and decrement operators, <code>++</code> and <code>--</code>. This statement adds one to the value of <code>lines</code>:
<pre>lines++;</pre>
Similarly, this statement subtracts one from the value of <code>lines</code>:
<pre>lines--;</pre>
You can alternately use the <code>++</code> or <code>--</code> operators before a variable name, as in <code>++lines</code>. However, these are not identical. The difference is when the increment or decrement happens:
* If the operator is after the variable name, the increment or decrement happens after the current expression is evaluated.
* If the operator is before the variable name, the increment or decrement happens before the current expression is evaluated.
This difference is only an issue when you use the variable in an expression and increment or decrement it in the same statement. As an example, suppose you have assigned the <code>lines</code> variable the value 40. The following two statements have different effects:
<pre>alert(lines++);
alert(++lines);</pre>
The first statement displays an alert with the value 40, and then increments <code>lines</code> to 41. The second statement first increments <code>lines</code> to 41, then displays an alert with the value 41.
; By the Way: These operators are strictly for your convenience. If it makes more sense to you to stick to <code>lines = lines + 1</code>, do it—your script won't suffer.
== Understanding Expressions and Operators ==
An expression is a combination of variables and values that the JavaScript interpreter can evaluate to a single value. The characters that are used to combine these values, such as <code>+</code> and <code>/</code>, are called operators.
; Did you Know?: Along with variables and constant values, you can also use calls to functions that return results within an expression.
=== Using JavaScript Operators ===
You've already used some operators, such as the <code>+</code> sign (addition) and the increment and decrement operators. Table 5.1 lists some of the most important operators you can use in JavaScript expressions.
{| cellspacing="0" cellpadding="5"
| + '''Table 5.1. Common JavaScript Operators'''
|-
! Operator
! Description
! Example
|-
| <code>+</code>
| Concatenate (combine) strings
| <code>message="this is" + "a test";</code>
|-
| <code>+</code>
| Add
| <code>result = 5 + 7;</code>
|-
| <code>-</code>
| Subtract
| <code>score = score - 1;</code>
|-
| <code>*</code>
| Multiply
| <code>total = quantity * price;</code>
|-
| <code>/</code>
| Divide
| <code>average = sum / 4;</code>
|-
| <code>%</code>
| Modulo (remainder)
| <code>remainder = sum % 4;</code>
|-
| <code>++</code>
| Increment
| <code>TRies++;</code>
|-
| <code>--</code>
| Decrement
| <code>total--;</code>
|}
Along with these, there are also many other operators used in conditional statements—you'll learn about these in [Hour 7], "Controlling Flow with Conditions and Loops."
=== Operator Precedence ===
When you use more than one operator in an expression, JavaScript uses rules of operator precedence to decide how to calculate the value. [Table 5.1] lists the operators from lowest to highest precedence, and operators with highest precedence are evaluated first. For example, consider this statement:
<pre>result = 4 + 5 * 3;</pre>
If you try to calculate this result, there are two ways to do it. You could multiply <code>5 * 3</code> first and then add <code>4</code> (result: <code>19</code>) or add <code>4 + 5</code> first and then multiply by <code>3</code> (result: <code>27</code>). JavaScript solves this dilemma by following the precedence rules: Because multiplication has a higher precedence than addition, it first multiplies <code>5 * 3</code> and then adds <code>4</code>, producing a result of <code>19</code>.
; By the Way: If you're familiar with any other programming languages, you'll find that the operators and precedence in JavaScript work, for the most part, the same way as those in C, C++, and Java.
Sometimes operator precedence doesn't produce the result you want. For example, consider this statement:
<pre>result = a + b + c + d / 4;</pre>
This is an attempt to average four numbers by adding them all together and then dividing by four. However, because JavaScript gives division a higher precedence than addition, it will divide the <code>d</code> variable by <code>4</code> before adding the other numbers, producing an incorrect result.
You can control precedence by using parentheses. Here's the working statement to calculate an average:
<pre>result = (a + b + c + d) / 4;</pre>
The parentheses ensure that the four variables are added first, and then the sum is divided by four.
; Did you Know?: If you're unsure about operator precedence, you can use parentheses to make sure things work the way you expect and to make your script more readable.
== Data Types in JavaScript ==
In some computer languages, you have to specify the type of data a variable will store: for example, a number or a string. In JavaScript, you don't need to specify a data type in most cases. However, you should know the types of data JavaScript can deal with.
These are the basic JavaScript data types:
* Numbers, such as <code>3</code>, <code>25</code>, or <code>1.4142138</code>. JavaScript supports both integers and floating-point numbers.
* Boolean, or logical values. These can have one of two values: <code>true</code> or <code>false</code>. These are useful for indicating whether a certain condition is true.
; By the Way: You'll learn more about Boolean values, and about using conditions in JavaScript, in [Hour 7].
* Strings, such as <code>"I am a jelly doughnut"</code>. These consist of one or more characters of text. (Strictly speaking, these are <code>String</code> objects, which you'll learn about later in this hour.)
* The null value, represented by the keyword <code>null</code>. This is the value of an undefined variable. For example, the statement <code>document.write(fig)</code> will result in this value (and an error message) if the variable <code>fig</code> has not been previously used or defined.
Although JavaScript keeps track of the data type currently stored in each variable, it doesn't restrict you from changing types midstream. For example, suppose you declared a variable by assigning it a value:
<pre>total = 31;</pre>
This statement declares a variable called <code>total</code> and assigns it the value of 31. This is a numeric variable. Now suppose you changed the value of <code>total</code>:
<pre>total = "albatross";</pre>
This assigns a string value to <code>total</code>, replacing the numeric value. JavaScript will not display an error when this statement executes; it's perfectly valid, although it's probably not a very useful total.
; By the Way: Although this feature of JavaScript is convenient and powerful, it can also make it easy to make a mistake. For example, if the <code>total</code> variable was later used in a mathematical calculation, the result would be invalid—but JavaScript does not warn you that you've made this mistake.
== Converting Between Data Types ==
JavaScript handles conversions between data types for you whenever it can. For example, you've already used statements like this:
<pre>document.write("The total is " + total);
</pre>
This statement prints out a message such as <code>"The total is 40"</code>. Because the <code>document.write</code> function works with strings, the JavaScript interpreter automatically converts any nonstrings in the expression (in this case, the value of <code>total</code>) to strings before performing the function.
This works equally well with floating-point and Boolean values. However, there are some situations where it won't work. For example, the following statement will work fine if the value of <code>total</code> is 40:
<pre>average = total / 3;
</pre>
However, the <code>total</code> variable could also contain a string; in this case, the preceding statement would result in an error.
In some situations, you might end up with a string containing a number, and need to convert it to a regular numeric variable. JavaScript includes two functions for this purpose:
* <code>parseInt()</code>Converts a string to an integer number.
* <code>parseFloat()</code>Converts a string to a floating-point number.
Both of these functions will read a number from the beginning of the string and return a numeric version. For example, these statements convert the string <code>"30 angry polar bears"</code> to a number:
<pre>stringvar = "30 angry polar bears";
numvar = parseInt(stringvar);
</pre>
After these statements execute, the <code>numvar</code> variable contains the number 30. The nonnumeric portion of the string is ignored.
; By the Way: These functions look for a number of the appropriate type at the beginning of the string. If a valid number is not found, the function will return the special value <code>NaN</code>, meaning not a number.
== Using <code>String</code> Objects ==
You've already used several strings during the first few hours of this book. Strings store a group of text characters, and are named similarly to other variables. As a simple example, this statement assigns the string <code>This is a test</code> to a string variable called <code>test</code>:
<pre>test = "This is a test";
</pre>
=== Creating a <code>String</code> Object ===
JavaScript stores strings as <code>String</code> objects. You usually don't need to worry about this, but it will explain some of the techniques for working with strings, which use methods (built-in functions) of the <code>String</code> object.
There are two ways to create a new <code>String</code> object. The first is the one you've already used, whereas the second uses object-oriented syntax. The following two statements create the same string:
<pre>test = "This is a test";
test = new String("This is a test");
</pre>
The second statement uses the <code>new</code> keyword, which you use to create objects. This tells the browser to create a new <code>String</code> object containing the text <code>This is a test</code>, and assigns it to the variable <code>test</code>.
; By the Way: Although you can create a string using object-oriented syntax, the standard JavaScript syntax is simpler, and there is no difference in the strings created by these two methods.
=== Assigning a Value ===
You can assign a value to a string in the same way as any other variable. Both of the examples in the previous section assigned an initial value to the string. You can also assign a value after the string has already been created. For example, the following statement replaces the contents of the <code>test</code> variable with a new string:
<pre>test = "This is only a test.";
</pre>
You can also use the concatenation operator (<code>+</code>) to combine the values of two strings. [Listing 5.1] shows a simple example of assigning and combining the values of strings.
; Listing 5.1. Assigning Values to Strings and Combining Them
<pre>
<html>
<head>
<title>String Test</title>
</head>
<body>
<h1>String Test</h1>
<script language="JavaScript" type="text/javascript">;
test1 = "This is a test. ";
test2 = "This is only a test.";
both = test1 + test2;
alert(both);
</script>
</body>
</html>
</pre>
This script assigns values to two string variables, <code>test1</code> and <code>test2</code>, and then displays an alert with their combined value. If you load this HTML document in a browser, your output should resemble [Figure 5.1].
In addition to using the <code>+</code> operator to concatenate two strings, you can use the <code>+=</code> operator to add text to a string. For example, this statement adds a period to the current contents of the string <code>sentence:</code>
<pre>sentence += ".";
</pre>
; By the Way: The plus sign (<code>+</code>) is also used to add numbers in JavaScript. The browser knows whether to use addition or concatenation based on the types of data you use with the plus sign. If you use it between a number and a string, the number is converted to a string and concatenated.
=== Calculating the String's Length ===
From time to time, you might find it useful to know how many characters a string variable contains. You can do this with the <code>length</code> property of <code>String</code> objects, which you can use with any string. To use this property, type the string's name followed by <code>.length</code>.
For example, <code>test.length</code> refers to the length of the <code>test</code> string. Here is an example of this property:
<pre>test = "This is a test.";
document.write(test.length);
</pre>
The first statement assigns the string <code>This is a test</code> to the <code>test</code> variable. The second statement displays the length of the string—in this case, 15 characters. The <code>length</code> property is a read-only property, so you cannot assign a value to it to change a string's length.
; By the Way: Remember that although <code>test</code> refers to a string variable, the value of <code>test.length</code> is a number and can be used in any numeric expression.
=== Converting the String's Case ===
Two methods of the <code>String</code> object enable you to convert the contents of a string to all uppercase or all lowercase:
* <code>toUpperCase()</code>Converts all characters in the string to uppercase.
* <code>toLowerCase()</code>Converts all characters in the string to lowercase.
For example, the following statement displays the value of the <code>test</code> string variable in lowercase:
<pre>document.write(test.toLowerCase());
</pre>
Assuming that this variable contained the text <code>This Is A Test</code>, the result would be the following string:
<pre>this is a test
</pre>
Note that the statement doesn't change the value of the <code>text</code> variable. These methods return the upper- or lowercase version of the string, but they don't change the string itself. If you want to change the string's value, you can use a statement like this:
<pre>test = test.toLowerCase();
</pre>
; By the Way: Note that the syntax for these methods is similar to the <code>length</code> property introduced earlier. The difference is that methods always use parentheses, whereas properties don't. The <code>toUpperCase</code> and <code>toLowerCase</code> methods do not take any parameters, but you still need to use the parentheses.
== Working with Substrings ==
So far, you've worked with entire strings. JavaScript also enables you to work with substrings, or portions of a string. You can use the <code>substring</code> method to retrieve a portion of a string, or the <code>charAt</code> method to get a single character. These are explained in the following sections.
=== Using Part of a String ===
The <code>substring</code> method returns a string consisting of a portion of the original string between two index values, which you must specify in parentheses. For example, the following statement displays the fourth through sixth characters of the <code>text</code> string:
<pre>document.write(text.substring(3,6));
</pre>
At this point, you're probably wondering where the <code>3</code> and the <code>6</code> come from. There are three things you need to understand about the index parameters:
* Indexing starts with <code>0</code> for the first character of the string, so the fourth character is actually index <code>3</code>.
* The second index is noninclusive. A second index of <code>6</code> includes up to index <code>5</code> (the sixth character).
* You can specify the two indexes in either order. The smaller one will be assumed to be the first index. In the previous example, <code>(6,3)</code> would have produced the same result. Of course, there is rarely a reason to use the reverse order.
As another example, suppose you defined a string called <code>alpha</code> to hold the alphabet:
<pre>alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
</pre>
The following are examples of the <code>substring()</code> method using this string:
* <code>alpha.substring(0,4)</code> returns <code>ABCD</code>.
* <code>alpha.substring(10,12)</code> returns <code>KL</code>.
* <code>alpha.substring(12,10)</code> also returns <code>KL</code>. Because it's smaller, <code>10</code> is used as the first index.
* <code>alpha.substring(6,7)</code> returns <code>G</code>.
* <code>alpha.substring(24,26)</code> returns <code>YZ</code>.
* <code>alpha.substring(0,26)</code> returns the entire alphabet.
* <code>alpha.substring(6,6)</code> returns the <code>null</code> value, an empty string. This is true whenever the two index values are the same.
=== Getting a Single Character ===
The <code>charAt</code> method is a simple way to grab a single character from a string. You specify the character's index, or position, in parentheses. The indexes begin at 0 for the first character. Here are a few examples using the <code>alpha</code> string:
* <code>alpha.charAt(0)</code> returns <code>A</code>.
* <code>alpha.charAt(12)</code> returns <code>M</code>.
* <code>alpha.charAt(25)</code> returns <code>Z</code>.
* <code>alpha.charAt(27)</code> returns an empty string because there is no character at that position.
=== Finding a Substring ===
Another use for substrings is to find a string within another string. One way to do this is with the <code>indexOf</code> method. To use this method, add <code>indexOf</code> to the string you want to search, and specify the string to search for in the parentheses. This example searches for "this" in the <code>test</code> string:
<pre>loc = test.indexOf("this");
</pre>
; By the Way: As with most JavaScript methods and property names, <code>indexOf</code> is case sensitive. Make sure you type it exactly as shown here when you use it in scripts.
The value returned in the <code>loc</code> variable is an index into the string, similar to the first index in the <code>substring</code> method. The first character of the string is index <code>0</code>.
You can specify an optional second parameter to indicate the index value to begin the search. For example, this statement searches for the word <code>fish</code> in the <code>temp</code> string, starting with the 20th character:
<pre>location = temp.indexOf("fish",19);
</pre>
; By the Way: One use for the second parameter is to search for multiple occurrences of a string. After finding the first occurrence, you search starting with that location for the second one, and so on.
A second method, <code>lastIndexOf()</code>, works the same way, but finds the last occurrence of the string. It searches the string backwards, starting with the last character. For example, this statement finds the last occurrence of <code>Fred</code> in the <code>names</code> string:
<pre>location = names.lastIndexOf("Fred");
</pre>
As with <code>indexOf()</code>, you can specify a location to search from as the second parameter. In this case, the string will be searched backward starting at that location.
== Using Numeric Arrays ==
An array is a numbered group of data items that you can treat as a single unit. For example, you might use an array called <code>scores</code> to store several scores for a game. Arrays can contain strings, numbers, objects, or other types of data. Each item in an array is called an element of the array.
=== Creating a Numeric Array ===
Unlike most other types of JavaScript variables, you typically need to declare an array before you use it. The following example creates an array with four elements:
<pre>scores = new Array(4);
</pre>
To assign a value to the array, you use an index in brackets. Indexes begin with <code>0</code>, so the elements of the array in this example would be numbered <code>0</code> to <code>3</code>. These statements assign values to the four elements of the array:
<pre>scores[0] = 39;
scores[1] = 40;
scores[2] = 100;
scores[3] = 49;
</pre>
You can also declare an array and specify values for elements at the same time. This statement creates the same <code>scores</code> array in a single line:
<pre>scores = new Array(39,40,100,49);
</pre>
In JavaScript 1.2 and later, you can also use a shorthand syntax to declare an array and specify its contents. The following statement is an alternative way to create the <code>scores</code> array:
<pre>scores = [39,40,100,49];
</pre>
; Did you Know?: Remember to use parentheses when declaring an array with the <code>new</code> keyword, as in <code>a=new Array(3,4,5)</code>, and use brackets when declaring an array without <code>new</code>, as in <code>a=[3,4,5]</code>. Otherwise, you'll run into JavaScript errors.
=== Understanding Array Length ===
Like strings, arrays have a <code>length</code> property. This tells you the number of elements in the array. If you specified the length when creating the array, this value becomes the <code>length</code> property's value. For example, these statements would print the number <code>30</code>:
<pre>scores = new Array(30);
document.write(scores.length);
</pre>
You can declare an array without a specific length, and change the length later by assigning values to elements or changing the <code>length</code> property. For example, these statements create a new array and assign values to two of its elements:
<pre>test = new Array();
test[0]=21;
test[5]=22;
</pre>
In this example, because the largest index number assigned so far is <code>5</code>, the array has a <code>length</code> property of <code>6</code>—remember, elements are numbered starting at 0.
=== Accessing Array Elements ===
You can read the contents of an array using the same notation you used when assigning values. For example, the following statements would display the values of the first three elements of the <code>scores</code> array:
<pre>scoredisp = "Scores: " + scores[0] + "," + scores[1] + "," + scores[2];
document.write(scoredisp);
</pre>
; Did you Know?: Looking at this example, you might imagine it would be inconvenient to display all the elements of a large array. This is an ideal job for loops, which enable you to perform the same statements several times with different values. You'll learn all about loops in [Hour 7].
== Using String Arrays ==
So far, you've used arrays of numbers. JavaScript also allows you to use string arrays, or arrays of strings. This is a powerful feature that enables you to work with a large number of strings at the same time.
=== Creating a String Array ===
You declare a string array in the same way as a numeric array—in fact, JavaScript does not make a distinction between them:
<pre>names = new Array(30);</pre>
You can then assign string values to the array elements:
<pre>names[0] = "Henry J. Tillman";
names[1] = "Sherlock Holmes";</pre>
As with numeric arrays, you can also specify a string array's contents when you create it. Either of the following statements would create the same string array as the preceding example:
<pre>names = new Array("Henry J. Tillman", "Sherlock Holmes");
names = ["Henry J. Tillman", "Sherlock Holmes"];</pre>
You can use string array elements anywhere you would use a string. You can even use the string methods introduced earlier. For example, the following statement prints the first five characters of the first element of the <code>names</code> array, resulting in <code>Henry</code>:
<pre>document.write(names[0].substring(0,5));</pre>
=== Splitting a String ===
JavaScript includes a string method called <code>split</code>, which splits a string into its component parts. To use this method, specify the string to split and a character to divide the parts:
<pre>test = "John Q. Public";
parts = test.split(" ");</pre>
In this example, the <code>test</code> string contains the name <code>John Q. Public</code>. The <code>split</code> method in the second statement splits the <code>name</code> string at each space, resulting in three strings. These are stored in a string array called <code>parts</code>. After the example statements execute, the elements of <code>parts</code> contain the following:
* <code>parts[0] = "John"</code>
* <code>parts[1] = "Q."</code>
* <code>parts[2] = "Public"</code>
JavaScript also includes an array method, <code>join</code>, which performs the opposite function. This statement reassembles the <code>parts</code> array into a string:
<pre>fullname = parts.join(" ");</pre>
The value in the parentheses specifies a character to separate the parts of the array. In this case, a space is used, resulting in the final string <code>John Q. Public</code>. If you do not specify a character, commas are used.
=== Sorting a String Array ===
JavaScript also includes a <code>sort</code> method for arrays, which returns an alphabetically sorted version of the array. For example, the following statements initialize an array of four names and sort it:
<pre>names[0] = "Public, John Q.";
names[1] = "Tillman, Henry J.";
names[2] = "Bush, George W.";
names[3] = "Mouse, Mickey";
sortednames = names.sort();</pre>
The last statement sorts the <code>names</code> array and stores the result in a new array, <code>sortednames</code>.
== Sorting a Numeric Array ==
Because the <code>sort</code> method sorts alphabetically, it won't work with a numeric array—at least not the way you'd expect. If an array contains the numbers 4, 10, 30, and 200, for example, it would sort them as 10, 200, 30, 4—not even close. Fortunately, there's a solution: You can specify a function in the <code>sort</code> method's parameters, and that function will be used to compare the numbers. The following code sorts a numeric array correctly:
<pre>function numcompare(a,b) {
return a-b;
}
nums = new Array(30, 10, 200, 4);
sortednums = nums.sort(numcompare);</pre>
This example defines a simple function, <code>numcompare</code>, which subtracts the two numbers. After you specify this function in the <code>sort</code> method, the array is sorted in the correct numeric order: 4, 10, 30, 200.
; By the Way: JavaScript expects the comparison function to return a negative number if <code>a</code> belongs before <code>b</code>, 0 if they are the same, or a positive number if <code>a</code> belongs after <code>b</code>. This is why <code>a-b</code> is all you need for the function to sort numerically.
; Try It Yourself : Sorting and Displaying Names
To gain more experience working with JavaScript's string and array features, you can create a script that enables the user to enter a list of names, and displays the list in sorted form.
Because this will be a larger script, you will create separate HTML and JavaScript files, as described in [Hour 3], "Getting Started with JavaScript Programming." First, the <code>sort.html</code> file will contain the HTML structure and form fields for the script to work with. [Listing 5.2] shows the HTML document.
; Listing 5.2. The HTML Document for the Sorting Example
<pre>
<html>
<head>
<title>Array Sorting Example</title>
<script type="text/javascript" language="javascript" src="sort.js">
</script>
</head>
<body>
<h1>Sorting String Arrays</h1>
<p>Enter two or more names in the field below,
and the sorted list of names will appear in the
text area.</p>
<form name="theform">
Name:
<input type="text" name="newname" size="20">
<input type="button" name="addname" value="Add" onclick="SortNames();">
<br>
<h2>Sorted Names</h2>
<textarea cols="60" rows="10" name="sorted">
The sorted names will appear here.
</textarea>
</form>
</body>
</html>
</pre>
Because the script will be in a separate document, the <code><script></code> tag in the header of this document uses the <code>src</code> attribute to include a JavaScript file called <code>sort.js</code>. You will create this file next.
This document defines a form named <code>theform</code>, a text field named <code>newname</code>, an <code>addname</code> button, and a textarea named <code>sorted</code>. Your script will use these form fields as its user interface. [Listing 5.3] shows the JavaScript file.
; Listing 5.3. The JavaScript File for the Sorting Example
<pre>// initialize the counter and the array
var numnames=0;
var names = new Array();
function SortNames() {
// Get the name from the text field
thename=document.theform.newname.value;
// Add the name to the array
names[numnames]=thename;
// Increment the counter
numnames++;
// Sort the array
names.sort();
document.theform.sorted.value=names.join("\n");
}</pre>
The script begins by defining two variables with the <code>var</code> keyword: <code>numnames</code> will be a counter that increments as each name is added, and the <code>names</code> array will store the names.
When you type a name into the text field and click the button, the <code>onclick</code> event handler calls the <code>SortNames</code> function. This function stores the text field value in a variable, <code>thename</code>, and then adds the name to the <code>names</code> array using <code>numnames</code> as the index. It then increments <code>numnames</code> to prepare for the next name.
The final section of the script sorts the names and displays them. First, the <code>sort()</code> method is used to sort the <code>names</code> array. Next, the <code>join()</code> method is used to combine the names, separating them with line breaks, and display them in the textarea.
To test the script, save it as <code>sort.js</code>, and then load the <code>sort.html</code> file you created previously into a browser. You can then add some names and test the script. [Figure 5.2] shows the result after sorting several names.
== Summary ==
During this hour, you've focused on variables and how JavaScript handles them. You've learned how to name variables, how to declare them, and the differences between local and global variables. You also explored the data types supported by JavaScript and how to convert between them.
You also learned about JavaScript's more complex variables, strings and arrays, and looked at the features that enable you to perform operations on them, such as converting strings to uppercase or sorting arrays.
In the next hour, you'll continue your JavaScript education by learning more about two additional key features: functions and objects.
=== Q&A ===
; Q1: What is the importance of the var keyword? Should I always use it to declare variables?
; A1: You only need to use var to define a local variable in a function. However, if you're unsure at all, it's always safe to use var. Using it consistently will help you keep your scripts organized and error free.
; Q2: Is there any reason I would want to use the var keyword to create a local variable with the same name as a global one?
; A2: Not on purpose. The main reason to use var is to avoid conflicts with global variables you might not know about. For example, you might add a global variable in the future, or you might add another script to the page that uses a similar variable name. This is more of an issue with large, complex scripts.
; Q3: What good are Boolean variables?
; A3: Often in scripts you'll need a variable to indicate whether something has happenedfor example, whether a phone number the user has entered is in the right format. Boolean variables are ideal for this; they're also useful in working with conditions, as you'll see in Hour 7.
; Q4: Can I store other types of data in an array? For example, can I have an array of dates?
; A4: Absolutely. JavaScript allows you to store any data type in an array.
; Q5: What about two-dimensional arrays?
; A5: These are arrays with two indexes (such as columns and rows). JavaScript does not directly support this type of array, but you can use objects to achieve the same effect. You will learn more about objects in the next hour.
=== Quiz Questions ===
Test your knowledge of JavaScript by answering the following questions:
1. Which of the following is not a valid JavaScript variable name?
# 2names
# first_and_last_names
# FirstAndLast
2. If the statement var fig=2 appears in a function, which type of variable does it declare?
# A global variable
# A local variable
# A constant variable
3. If the string test contains the value The eagle has landed., what would be the value of test.length?
# 4
# 21
# The
4. Using the same example string, which of these statements would return the word eagle?
# test.substring(4,9)
# test.substring(5,9)
# test.substring("eagle")
5. What will be the result of the JavaScript expression 31 + "angry polar bears"?
# An error message
# 32
# "31 angry polar bears"
=== Quiz Answers ===
1. a. 2names is an invalid JavaScript variable name because it begins with a number. The others are valid, although they're probably not ideal choices for names.
2. b. Because the variable is declared in a function, it is a local variable. The var keyword ensures that a local variable is created.
3. b. The length of the string is 21 characters.
4. a. The correct statement is test.substring(4,9). Remember that the indexes start with 0, and that the second index is noninclusive.
5. c. JavaScript converts the whole expression to the string "31 angry polar bears". (No offense to polar bears, who are seldom angry and rarely seen in groups this large.)
=== Exercises ===
To further explore JavaScript variables, strings, and arrays, you can perform the following exercises:
* Modify the sorting example in [Listing 5.3] to convert the names to all upper-case before sorting and displaying them.
* Modify [Listing 5.3] to display a numbered list of names in the textarea.
rnpzpm7k1lw0wyepsj84xj9aboecqcz
User:Moncur/09
2
2084
39274
5963
2026-04-13T06:03:46Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39274
wikitext
text/x-wiki
= 9. Responding to Events =
== Understanding Event Handlers ==
As you learned in [Hour 3], "Getting Started with JavaScript Programming," JavaScript programs don't have to execute in order. You also learned they can detect events and react to them. Events are things that happen to the browser—the user clicking a button, the mouse pointer moving, or a web page or image loading from the server.
A wide variety of events enable your scripts to respond to the mouse, the keyboard, and other circumstances. Events are the key method JavaScript uses to make web documents interactive.
The script that you use to detect and respond to an event is called an event handler. Event handlers are among the most powerful features of JavaScript. Luckily, they're also among the easiest features to learn and use—often, a useful event handler requires only a single statement.
=== Objects and Events ===
As you learned in [Hour 4], "Working with the Document Object Model (DOM)," JavaScript uses a set of objects to store information about the various parts of a web page—buttons, links, images, windows, and so on. An event can often happen in more than one place (for example, the user could click any one of the links on the page), so each event is associated with an object.
Each event has a name. For example, the <code>onMouseOver</code> event occurs when the mouse pointer moves over an object on the page. When the pointer moves over a particular link, the <code>onMouseOver</code> event is sent to that link's event handler, if it has one.
; By the Way: Notice the strange capitalization on the <code>onMouseOver</code> keyword. This is the standard notation for event handlers. The <code>on</code> is always lowercase, and each word in the event name is capitalized.
=== Creating an Event Handler ===
You don't need the <code><script></code> tag to define an event handler. Instead, you can add an event handler attribute to an individual HTML tag. For example, here is a link that includes an <code>onMouseOver</code> event handler:
<pre><a href="http://www.jsworkshop.com/" onMouseOver="window.alert('You moved over the link.');">
Click here</a>
</pre>
Note that this is all one <code><a></code> tag, although it's split into multiple lines. This specifies a statement to be used as the <code>onMouseOver</code> event handler for the link. This statement displays an alert message when the mouse moves over the link.
; By the Way: The previous example uses single quotation marks to surround the text. This is necessary in an event handler because double quotation marks are used to surround the event handler itself. (You can also use single quotation marks to surround the event handler and double quotes within the script statements.)
You can use JavaScript statements like the previous one in an event handler, but if you need more than one statement, it's a good idea to use a function instead. Just define the function in the header of the document, and then call the function as the event handler like this:
<pre><a href="#bottom" onMouseOver="DoIt();">Move the mouse over this link.</a>
</pre>
This example calls a function called <code>DoIt()</code> when the user moves the mouse over the link. Using a function is convenient because you can use longer, more readable JavaScript routines as event handlers. You'll use a longer function to handle events in the "Try It Yourself: Adding Link Descriptions to a Web Page" section of this hour.
; Did you Know?: For simple event handlers, you can use two statements if you separate them with a semicolon. However, in most cases it's easier to use a function to perform the statements.
=== Defining Event Handlers with JavaScript ===
Rather than specifying an event handler in an HTML document, you can use JavaScript to assign a function as an event handler. This allows you to set event handlers conditionally, turn them on and off, and change the function that handles an event dynamically.
; Did you Know?: Setting up event handlers this way is also a good practice in general: It allows you to use an external JavaScript file to define the function and set up the event, keeping the JavaScript code completely separate from the HTML file.
To define an event handler in this way, you first define a function, and then assign the function as an event handler. Event handlers are stored as properties of the <code>document</code> object or another object that can receive an event. For example, these statements define a function called <code>mousealert()</code>, and then assign it as the <code>onMouseDown</code> event handler for the document:
<pre>function mousealert() {
alert ("You clicked the mouse!");
}
document.onmousedown = mousealert;
</pre>
You can use this technique to set up an event handler for any HTML element, but an additional step is required: You must first find the object corresponding to the element. To do this, use the <code>document.getElementById()</code> function. First, define an element in the HTML document and specify an <code>id</code> attribute:
<pre><a href="http://www.google.com/" id="link1">
</pre>
Next, in the JavaScript code, find the object and apply the event handler:
<pre>obj = document.getElementById("link1");
obj.onclick = MyFunction;
</pre>
You can do this for any object as long as you've defined it with a unique <code>id</code> attribute in the HTML file. Using this technique, you can easily assign the same function to handle events for multiple objects without adding clutter to your HTML code. See the "Try It Yourself" section in this hour for an example of this technique.
=== Supporting Multiple Event Handlers ===
What if you want more than one thing to happen when you click on an element? For example, suppose you want two functions called <code>update</code> and <code>display</code> to both execute when a button is clicked. You can't assign two functions to the <code>onclick</code> property. One solution is to define a function that calls both functions:
<pre>function UpdateDisplay() {
update();
display();
}
</pre>
This isn't always the ideal way to do things. For example, if you're using two third-party scripts and both of them want to add an <code>onLoad</code> event to the page, there should be a way to add both. The W3C DOM standard defines a function, <code>addEventListener</code>, for this purpose. This function defines a listener for a particular event and object, and you can add as many listener functions as you need.
Unfortunately, <code>addEventListener</code> is not supported by Internet Explorer (as of versions 6 and 7), so you have to use a different function, <code>attachEvent</code>, in that browser. See [Hour 15], "Unobtrusive Scripting," for a function that combines these two for a cross-browser event-adding script.
=== Using the <code>event</code> Object ===
When an event occurs, you might need to know more about the event—for example, for a keyboard event, you need to know which key was pressed. The DOM includes an <code>event</code> object that provides this information.
To use the <code>event</code> object, you can pass it on to your event handler function. For example, this statement defines an <code>onKeyPress</code> event that passes the <code>event</code> object to a function:
<pre><body onKeyPress="getkey(event);">
</pre>
You can then define your function to accept the event as a parameter:
<pre>function getkey(e) {
...
}
</pre>
In Mozilla-based browsers (Firefox and Netscape), an <code>event</code> object is automatically passed to the event handler function, so this will work even if you use JavaScript rather than HTML to define an event handler. In Internet Explorer, the most recent event is stored in the <code>window.event</code> object. The previous HTML example passes this object to the event handler function. If you define the event handler with JavaScript, this is not possible, so you need to use some code to find the correct object:
<pre>Function getkey(e) {
if (!e) e=window.event;
...
}
</pre>
This checks whether the <code>e</code> variable is already defined. If not, it gets the <code>window.event</code> object and stores it in <code>e</code>. This ensures that you have a valid <code>event</code> object in any browser.
Unfortunately, while both Internet Explorer and Mozilla-based browsers support <code>event</code> objects, they support different properties. One property that is the same in both browsers is <code>event.type</code>, the type of event. This is simply the name of the event, such as <code>mouseover</code> for an <code>onMouseOver</code> event, and <code>keypress</code> for an <code>onKeyPress</code> event. The following sections list some additional useful properties for each browser.
=== Internet Explorer <code>event</code> Properties ===
The following are some of the commonly used properties of the <code>event</code> object for Internet Explorer 4.0 and later:
* <code>event.button</code> The mouse button that was pressed. This value is <code>1</code> for the left button and usually <code>2</code> for the right button.
* <code>event.clientX</code> The x-coordinate (column, in pixels) where the event occurred.
* <code>event.clientY</code> The y-coordinate (row, in pixels) where the event occurred.
* <code>event.altkey</code> A flag that indicates whether the Alt key was pressed during the event.
* <code>event.ctrlkey</code> Indicates whether the Ctrl key was pressed.
* <code>event.shiftkey</code> Indicates whether the Shift key was pressed.
* <code>event.keyCode</code> The key code (in Unicode) for the key that was pressed.
* <code>event.srcElement</code> The object where the element occurred.
; By the Way: See the Try it Yourself section of this hour for an example that uses the <code>srcElement</code> property and Mozilla's <code>target</code> property for a cross-browser method of determining the object for an event.
=== Netscape and Firefox <code>event</code> Properties ===
The following are some of the commonly used properties of the <code>event</code> object for Netscape 4.0 and later:
* <code>event.modifiers</code> Indicates which modifier keys (Shift, Ctrl, Alt, and so on) were held down during the event. This value is an integer that combines binary values representing the different keys.
* <code>event.pageX</code> The x-coordinate of the event within the web page.
* <code>event.pageY</code> The y-coordinate of the event within the web page.
* <code>event.which</code> The keycode for keyboard events (in Unicode), or the button that was pressed for mouse events (It's best to use the cross-browser <code>button</code> property instead.)
* <code>event.button</code> The mouse button that was pressed. This works just like Internet Explorer except that the left button's value is <code>0</code> and the right button's value is <code>2</code>.
* <code>event.target</code> The object where the element occurred.
; By the Way: The <code>event.pageX</code> and <code>event.pageY</code> properties are based on the top-left corner of the element where the event occurred, not always the exact position of the mouse pointer.
== Using Mouse Events ==
The DOM includes a number of event handlers for detecting mouse actions. Your script can detect the movement of the mouse pointer and when a button is clicked, released, or both.
=== Over and Out ===
You've already seen the first and most common event handler, <code>onMouseOver</code>. This handler is called when the mouse pointer moves over a link or other object.
The <code>onMouseOut</code> handler is the opposite—it is called when the mouse pointer moves out of the object's border. Unless something strange happens, this always happens sometime after the <code>onMouseOver</code> event is called.
This handler is particularly useful if your script has made a change when the pointer moved over the object—for example, displaying a message in the status line or changing an image. You can use an <code>onMouseOut</code> handler to undo the action when the pointer moves away.
You'll use both <code>onMouseOver</code> and <code>onMouseOut</code> handlers in the "Try it Yourself: Adding Link Descriptions to a Web Page" section at the end of this hour.
; By the Way: One of the most common uses for the <code>onMouseOver</code> and <code>onMouseOut</code> event handlers is to create rollovers—images that change when the mouse moves over them. You'll learn how to create these in [Hour 19], "Using Graphics and Animation."
=== Using the <code>onMouseMove</code> Event ===
The <code>onMouseMove</code> event occurs any time the mouse pointer moves. As you might imagine, this happens quite often—the event can trigger hundreds of times as the mouse pointer moves across a page.
Because of the large number of generated events, browsers don't support the <code>onMouseMove</code> event by default. To enable it for a page, you need to use event capturing. This is similar to the dynamic events technique you learned earlier in this hour, but requires an extra step for some older browsers.
The basic syntax to support this event, for both browsers, is to set a function as the <code>onMouseMove</code> handler for the document or another object. For example, this statement sets the <code>onMouseMove</code> handler for the document to a function called <code>MoveHere</code>, which must be defined in the same page:
<pre>document.onMouseMove=MoveHere;
</pre>
Additionally, older versions of Netscape require that you specifically enable the event using the <code>document.captureEvents</code> method:
<pre>document.captureEvents(Event.MOUSEMOVE);
</pre>
=== Ups and Downs (and Clicks) ===
You can also use events to detect when the mouse button is clicked. The basic event handler for this is <code>onClick</code>. This event handler is called when the mouse button is clicked while positioned over the appropriate object.
; By the Way: The object in this case can be a link. It can also be a form element. You'll learn more about forms in [Hour 11], "Getting Data with Forms."
For example, you can use the following event handler to display an alert when a link is clicked:
<pre><a href="http://www.jsworkshop.com/" onClick="alert('You are about to leave this site.');">Click Here</a>
</pre>
In this case, the <code>onClick</code> event handler runs before the linked page is loaded into the browser. This is useful for making links conditional or displaying a disclaimer before launching the linked page.
If your <code>onClick</code> event handler returns the <code>false</code> value, the link will not be followed. For example, the following is a link that displays a confirmation dialog. If you click Cancel, the link is not followed; if you click OK, the new page is loaded:
<pre><a href="http://www.jsworkshop.com/" onClick="return(window.confirm('Are you sure?'));">
Click Here</a>
</pre>
This example uses the <code>return</code> statement to enclose the event handler. This ensures that the <code>false</code> value that is returned when the user clicks Cancel is returned from the event handler, which prevents the link from being followed.
The <code>onDblClick</code> event handler is similar, but is only used if the user double-clicks on an object. Because links usually require only a single click, you could use this to make a link do two different things depending on the number of clicks. (Needless to say, this could be confusing.) You can also detect double-clicks on images and other objects.
To give you even more control of what happens when the mouse button is pressed, two more events are included:
* <code>onMouseDown</code> is used when the user presses the mouse button.
* <code>onMouseUp</code> is used when the user releases the mouse button.
These two events are the two halves of a mouse click. If you want to detect an entire click, use <code>onClick</code>. Use <code>onMouseUp</code> and <code>onMouseDown</code> to detect just one or the other.
To detect which mouse button is pressed, you can use the <code>button</code> property of the <code>event</code> object. This property is assigned the value <code>0</code> or <code>1</code> for the left button, and <code>2</code> for the right button. This property is assigned for <code>onClick</code>, <code>onDblClick</code>, <code>onMouseUp</code>, and <code>onMouseDown</code> events.
; Watch Out!: Browsers don't normally detect <code>onClick</code> or <code>onDblClick</code> events for the right mouse button. If you want to detect the right button, <code>onMouseDown</code> is the most reliable way.
As an example of these event handlers, you can create a script that displays information about mouse button events and determines which button is pressed. [Listing 9.1] shows the mouse event script.
; Listing 9.1. The JavaScript file for the mouse click example.
<pre>function mousestatus(e) {
if (!e) e = window.event;
btn = e.button;
whichone = (btn < 2) ? "Left" : "Right";
message=e.type + " : "+ whichone + "\n";
document.form1.info.value += message;
}
obj=document.getElementById("testlink");
obj.onmousedown = mousestatus;
obj.onmouseup = mousestatus;
obj.onclick = mousestatus;
obj.ondblclick = mousestatus;
</pre>
This script includes a function, <code>mousestatus()</code>, that detects mouse events. This function uses the <code>button</code> property of the <code>event</code> object to determine which button was pressed. It also uses the <code>type</code> property to display the type of event, since the function will be used to handle multiple event types.
After the function, the script finds the object for a link with the <code>id</code> attribute <code>testlink</code> and assigns its <code>onmousedown</code>, <code>onmouseup</code>, <code>onclick</code>, and <code>ondblclick</code> events to the <code>mousestatus</code> function.
Save this script as <code>click.js</code>. Next, you will need an HTML document to work with the script, shown in [Listing 9.2].
;Listing 9.2. The HTML file for the mouse click example.
<pre><html>
<head>
<title>Mouse click test</title>
</head>
<body>
<h1>Mouse Click Test</h1>
<p>Click the mouse on the test link below. A message below
will indicate which button was clicked.</p>
<h2><a href="#" id="testlink">Test Link</a></h2>
<form name="form1">
<textarea rows="10" cols="70" name="info"></textarea>
</form>
<script language="javascript" type="text/javascript" src="click.js">
</script>
</body>
</html>
</pre>
This file defines a test link with the <code>id</code> property <code>testlink</code>, which is used in the script to assign event handlers. It also defines a form and a textarea used by the script to display the events. To test this document, save it in the same folder as the JavaScript file you created previously and load the HTML document into a browser. The results are shown in [Figure 9.1].
;By the Way: Notice that a single click of the left mouse button triggers three events: <code>onMouseDown</code>, <code>onMouseUp</code>, and then <code>onClick</code>.
== Using Keyboard Events ==
JavaScript can also detect keyboard actions. The main event handler for this purpose is <code>onKeyPress</code>, which occurs when a key is pressed and released, or held down. As with mouse buttons, you can detect the down and up parts of the keypress with the <code>onKeyDown</code> and <code>onKeyUp</code> event handlers.
Of course, you might find it useful to know which key the user pressed. You can find this out with the <code>event</code> object, which is sent to your event handler when the event occurs. In Netscape and Firefox, the <code>event.which</code> property stores the ASCII character code for the key that was pressed. In Internet Explorer, <code>event.keyCode</code> serves the same purpose.
; By the Way: ASCII (American Standard Code for Information Interchange) is the standard numeric code used by most computers to represent characters. It assigns the numbers 0—128 to various characters—for example, the capital letters A through Z are ASCII values 65 to 90.
=== Displaying Typed Characters ===
If you'd rather deal with actual characters than key codes, you can use the <code>fromCharCode</code> string method to convert them. This method converts a numeric ASCII code to its corresponding string character. For example, the following statement converts the <code>event.which</code> property to a character and stores it in the <code>key</code> variable:
<pre>Key = String.fromCharCode(event.which);
</pre>
Because different browsers have different ways of returning the key code, displaying keys browser independently is a bit harder. However, you can create a script that displays keys for either browser. The following function will display each key as it is typed:
<pre>function DisplayKey(e) {
// which key was pressed?
if (e.keyCode) keycode=e.keyCode;
else keycode=e.which;
character=String.fromCharCode(keycode);
// find the object for the destination paragraph
k = document.getElementById("keys");
// add the character to the paragraph
k.innerHTML += character;
}
</pre>
The <code>DisplayKey()</code> function receives the <code>event</code> object from the event handler and stores it in the variable <code>e</code>. It checks whether the <code>e.keyCode</code> property exists, and stores it in the <code>keycode</code> variable if present. Otherwise, it assumes the browser is Netscape or Firefox and assigns <code>keycode</code> to the <code>e.which</code> property.
The remaining lines of the function convert the key code to a character and add it to the paragraph in the document with the <code>id</code> attribute <code>keys</code>. [Listing 9.3] shows a complete example using this function.
; By the Way: The final lines in the <code>DisplayKey()</code> function use the <code>getElementById()</code> function and the <code>innerHTML</code> attribute to display the keys you type within a paragraph on the page. This technique is explained in [Hour 13], "Using the W3C DOM."
; Listing 9.3. Displaying Typed Characters
<pre><html>
<head>
<title>Displaying Keypresses</title>
<script language="javascript" type="text/javascript">
function DisplayKey(e) {
// which key was pressed?
if (e.keyCode) keycode=e.keyCode;
else keycode=e.which;
character=String.fromCharCode(keycode);
// find the object for the destination paragraph
k = document.getElementById("keys");
// add the character to the paragraph
k.innerHTML += character;
}
</script>
</head>
<body onKeyPress="DisplayKey(event);">
<h1>Displaying Typed Characters</h1>
<p>This document includes a simple script that displays the keys
you type in the paragraph below. Type a few keys and try it. </p>
<p id="keys">
</p>
</body>
</html>
</pre>
When you load this example into either Netscape or Internet Explorer, you can type and see the characters you've typed appear in a paragraph of the document. [Figure 9.2] shows this example in action in Firefox.
== Using the <code>onLoad</code> and <code>onUnload</code> Events ==
Another event you'll use frequently is <code>onLoad</code>. This event occurs when the current page (including all of its images) finishes loading from the server.
The <code>onLoad</code> event is related to the <code>window</code> object, and to define it you use an event handler in the <code><body></code> tag. For example, the following is a <code><body></code> tag that uses a simple event handler to display an alert when the page finishes loading:
<pre><body onLoad="alert('Loading complete.');">
</pre>
; Watch Out!: Because the <code>onLoad</code> event occurs after the HTML document has finished loading and displaying, you cannot use the <code>document.write</code> or <code>document.open</code> statements within an <code>onLoad</code> event handler. This would overwrite the current document.
In JavaScript 1.1 and later, images can also have an <code>onLoad</code> event handler. When you define an <code>onLoad</code> event handler for an <code><img></code> tag, it is triggered as soon as the specified image has completely loaded.
To set an <code>onLoad</code> event using JavaScript, you assign a function to the <code>onload</code> property of the <code>window</code> object:
<pre>window.onload = MyFunction;
</pre>
You can also specify an <code>onUnload</code> event for the <code><body></code> tag. This event will be triggered whenever the browser unloads the current document—this occurs when another page is loaded or when the browser window is closed.
=== Try It Yourself — Adding Link Descriptions to a Web Page ===
One of the most common uses for an event handler is to display descriptions of links when the user moves the mouse over them. For example, moving the mouse over the Order Form link might display a message such as "Order a product or check an order's status".
Link descriptions like these are typically displayed with the <code>onMouseOver</code> event handler. You will now create a script that displays messages in this manner and clears the message using the <code>onMouseOut</code> event handler. You'll use functions to simplify the process.
; By the Way: This example uses the <code>innerHTML</code> property to display the descriptions within a heading on the page. See [Hour 13] for a complete description of this property.
This will also be an example of defining event handlers entirely with JavaScript. The HTML document, shown in [Listing 9.4], does not include any <code><script></code> tags or event handlers—the only thing it requires is some <code>id</code> attributes on the objects we will be using in the script.
;Listing 9.4. The HTML Document for the Descriptive Links Example
<pre><html>
<head>
<title>Descriptive Links</title>
</head>
<body>
<h1>Descriptive Links</h1>
<p>Move the mouse pointer over one of
these links to view a description:</p>
<ul>
<li><a href="order.html" id="order">Order Form</a>
<li><a href="email.html" id="email">Email</a>
<li><a href="complain.html" id="complain">Complaint Department</a>
</ul>
<h2 id="description"></h2>
<script language="JavaScript" type="text/javascript" src="linkdesc.js">
</script>
</body>
</html>
</pre>
This document defines three links in a bulleted list. Each <code><a></code> tag is defined with an <code>id</code> attribute for the script to use to attach an event handler. The <code><nowiki><h2></nowiki></code> tag with the <code>id</code> value <code>description</code>, currently blank, will be used to display a description of each link.
; By the Way: Notice that the <code><script></code> tag is below the content of the HTML document. It would not work at the top of the document because the objects the script uses are not yet defined. You can also deal with this issue by using an <code>onLoad</code> event handler instead of a simple script to set up the event handlers.
The script will begin with a function to serve as the <code>onMouseOver</code> event handler for the links:
<pre>function hover(e) {
if (!e) var e = window.event;
// which link was the mouse over?
whichlink = (e.target) ? e.target.id : e.srcElement.id;
// choose the appropriate description
if (whichlink=="order") desc = "Order a product";
else if (whichlink=="email") desc = "Send us a message";
else if (whichlink=="complain") desc = "Insult us, our
products, or our families";
// display the description in the H2
d = document.getElementById("description");
d.innerHTML = desc;
}
</pre>
The <code>hover</code> function uses the <code>target</code> or <code>srcElement</code> properties to find the target object for the link, and then finds its <code>id</code> attribute. Three <code>if</code> statements evaluate the <code>id</code> and choose an appropriate description. Finally, the script uses the <code>getElementById()</code> method to find the <code><nowiki><h2></nowiki></code> tag that will display the descriptions, and displays the description using the <code>innerHTML</code> property.
; Did you Know?: The conditional statement on the third line of the <code>hover</code> function checks whether the <code>target</code> property exists, and if not, it uses the <code>srcElement</code> property. This is called feature sensing—detecting whether the browser supports a feature—and is explained further in [Hour 15], "Unobtrusive Scripting."
One more function will be required. The <code>cleardesc()</code> function will serve as the <code>onMouseOut</code> event handler and clear the description when the mouse is no longer over one of the links.
<pre>function cleardesc() {
d = document.getElementById("description");
d.innerHTML = "";
}
</pre>
Now that the functions are defined, you need to set them as the event handlers for the links. Each link requires the following three lines of code:
<pre>orderlink = document.getElementById("order");
orderlink.onmouseover=hover;
orderlink.onmouseout=cleardesc;
</pre>
After using <code>getElementById()</code> to find the object with the <code>id</code> attribute <code>"order"</code>, this sets up the <code>hover()</code> and <code>cleardesc()</code> functions as its <code>onMouseOver</code> and <code>onMouseOut</code> event handlers. This will need to be repeated for the other two links. Putting all of this together, the complete JavaScript file for this example is shown in [Listing 9.5].
; Listing 9.5. The JavaScript File for the Link Descriptions Example
<pre>function cleardesc() {
d = document.getElementById("description");
d.innerHTML = "";
}
function hover(e) {
if (!e) var e = window.event;
// which link was the mouse over?
whichlink = (e.target) ? e.target.id : e.srcElement.id;
// choose the appropriate description
if (whichlink=="order") desc = "Order a product";
else if (whichlink=="email") desc = "Send us a message";
else if (whichlink=="complain") desc = "Insult us, our
products, or our
families";
// display the description in the H2
d = document.getElementById("description");
d.innerHTML = desc;
}
// Set up the event handlers
orderlink = document.getElementById("order");
orderlink.onmouseover=hover;
orderlink.onmouseout=cleardesc;
emaillink = document.getElementById("email");
emaillink.onmouseover=hover;
emaillink.onmouseout=cleardesc;
complainlink = document.getElementById("complain");
complainlink.onmouseover=hover;
complainlink.onmouseout=cleardesc;
</pre>
To test the script, store it as <code>linkdesc.js</code> in the same folder as the HTML document, and load the HTML file into a browser; this script should work on any JavaScript-capable browser. Internet Explorer's display of the example is shown in [Figure 9.3].
; Did you Know?: As usual, you can download the listings for this hour from this book's website.
== Summary ==
In this hour, you've learned to use events to detect mouse actions, keyboard actions, and other events, such as the loading of the page. You can use event handlers to perform a simple JavaScript statement when an event occurs, or to call a more complicated function.
JavaScript includes a variety of other events. Many of these are related to forms, which you'll learn more about in [Hour 11]. Another useful event is <code>onError</code>, which you can use to prevent error messages from displaying. This event is described in [Hour 16], "Debugging JavaScript Applications."
In the next hour, you'll continue learning about the objects in the DOM. Specifically, [Hour 10], "Using Windows and Frames," looks at the objects associated with windows, frames, and layers, and how they work with JavaScript.
=== Q&A ===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q1:'''
| I noticed that the <code><img></code> tag in HTML can't have <code>onMouseOver</code> or <code>onClick</code> event handlers in some browsers. How can my scripts respond when the mouse moves over an image?
|-
| align="right" | ''' A1: '''
| The easiest way to do this is to make the image a link by surrounding it with an <code><a></code> tag. You can include the <code>BORDER=0</code> attribute to prevent the blue link border from being displayed around the image.
|-
| align="right" | '''Q2:'''
| My image rollovers using <code>onMouseOver</code> work perfectly in Internet Explorer, but not in Netscape. Why?
|-
| align="right" | ''' A2: '''
| Re-read the previous answer, and check whether you've used an <code>onMouseOver</code> event for an <code><img></code> tag. This is supported by Internet Explorer and Netscape 6, but not by earlier versions of Netscape.
|-
| align="right" | '''Q3:'''
| What happens if I define both <code>onKeyDown</code> and <code>onKeyPress</code> event handlers? Will they both be called when a key is pressed?
|-
| align="right" | ''' A3: '''
| The <code>onKeyDown</code> event handler is called first. If it returns <code>TRue</code>, the <code>onKeyPress</code> event is called. Otherwise, no keypress event is generated.
|-
| align="right" | '''Q4:'''
| When I use the <code>onLoad event</code>, my event handler sometimes executes before the page is done loading, or before some of the graphics. Is there a better way?
|-
| align="right" | ''' A4: '''
| This is a bug in some older browsers. One solution is to add a slight delay to your script using the <code>setTimeout</code> method. You'll learn how to use this method in [Hour 10].
|}
=== Quiz Questions ===
Test your knowledge of JavaScript events by answering the following questions.
{| cellspacing="16" cellpadding="0" border="0"
|-
| valign="top" | '''1.'''
| Which of the following is the correct event handler to detect a mouse click on a link?
# onMouseUp
# onLink
# onClick
|-
| valign="top" | '''2.'''
| When does the <code>onLoad</code> event handler for the <code><body></code> tag execute?
# When an image is finished loading
# When the entire page is finished loading
# When the user attempts to load another page
|-
| valign="top" | '''3.'''
| Which of the following <code>event</code> object properties indicates which key was pressed for an <code>onKeyPress</code> event in Internet Explorer?
# event.which
# event.keyCode
# event.onKeyPress
|}
=== Quiz Answers ===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| c. The event handler for a mouse click is <code>onClick</code>
|-
| align="right" | '''2.'''
| b. The <code><body></code> tag's <code>onLoad</code> handler executes when the page and all its images are finished loading.
|-
| align="right" | '''3.'''
| b. In Internet Explorer, the <code>event.keyCode</code> property stores the character code for each keypress.
|}
=== Exercises ===
To gain more experience using event handlers in JavaScript, try the following exercises:
* Add one or more additional links to the document in [Listing 9.4]. Add event handlers to the script in [Listing 9.5] to display a unique description for each link.
* Modify [Listing 9.5] to display a default welcome message whenever a description isn't being displayed. (Hint: You'll need to include a statement to display the welcome message when the page loads. You'll also need to change the <code>cleardesc</code> function to restore the welcome message.)
fo4awo14e2f13leazechz01p7slf783
User:Moncur/10
2
2085
39275
5974
2026-04-13T06:03:46Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39275
wikitext
text/x-wiki
=10. Using Windows and Frames=
== Controlling Windows with Objects ==
In [Hour 4], "Working with the Document Object Model (DOM)," you learned that you can use DOM objects to represent various parts of the browser window and the current HTML document. You also learned that the <code>history</code>, <code>document</code>, and <code>location</code> objects are all children of the <code>window</code> object.
In this hour, you'll take a closer look at the <code>window</code> object itself. As you've probably guessed by now, this means you'll be dealing with browser windows. A variation of the <code>window</code> object also enables you to work with frames, as you'll see later in this hour.
The <code>window</code> object always refers to the current window (the one containing the script). The <code>self</code> keyword is also a synonym for the current window. As you'll learn in the next sections, you can have more than one window on the screen at the same time, and can refer to them with different names.
=== Properties of the <code>window</code> Object ===
Although there is normally a single <code>window</code> object, there might be more than one if you are using pop-up windows or frames. As you learned in [Hour 4], the <code>document</code>, <code>history</code>, and <code>location</code> objects are properties (or children) of the <code>window</code> object. In addition to these, each <code>window</code> object has the following properties:
* <code>window.closed</code> Indicates whether the window has been closed. This only makes sense when working with multiple windows because the current window contains the script and cannot be closed without ending the script.
* <code>window.defaultstatus</code> and <code>window.status</code> The default message for the status line, and a temporary message to display on the status line. Some recent browsers disable status line changes by default, so you might not be able to use these.
* <code>window.frames[]</code> An array of objects for frames, if the window contains them.
* <code>window.name</code> The name specified for a frame, or for a window opened by a script.
* <code>window.opener</code> In a window opened by a script, this is a reference to the window containing the script that opened it.
* <code>window.parent</code> For a frame, a reference to the parent window containing the frame.
* <code>window.screen</code> A child object that stores information about the screen the window is in—its resolution, color depth, and so on.
* <code>window.self</code> A synonym for the current <code>window</code> object.
* <code>window.top</code> A reference to the top-level window when frames are in use.
; By the Way: The properties of the <code>window.screen</code> object include <code>height</code>, <code>width</code>, <code>availHeight,</code> and <code>availWidth</code> (the available height and width rather than total), and <code>colorDepth</code>, which indicates the color support of the monitor: <code>8</code> for 8-bit color, <code>32</code> for 32-bit color, and so on.
=== Creating a New Window ===
One of the most convenient uses for the <code>window</code> object is to create a new window. You can do this to display a document—for example, a pop-up advertisement or the instructions for a game—without clearing the current window. You can also create windows for specific purposes, such as navigation windows.
You can create a new browser window with the <code>window.open()</code> method. A typical statement to open a new window looks like this:
<pre>WinObj=window.open("URL", "WindowName", "Feature List");
</pre>
The following are the components of the <code>window.open()</code> statement:
* The <code>WinObj</code> variable is used to store the new <code>window</code> object. You can access methods and properties of the new object by using this name.
* The first parameter of the <code>window.open()</code> method is a URL, which will be loaded into the new window. If it's left blank, no web page will be loaded. In this case, you could use JavaScript to fill the window with content.
* The second parameter specifies a window name (here, <code>WindowName</code>). This is assigned to the <code>window</code> object's <code>name</code> property and is used to refer to the window.
* The third parameter is a list of optional features, separated by commas. You can customize the new window by choosing whether to include the toolbar, status line, and other features. This enables you to create a variety of "floating" windows, which might look nothing like a typical browser window.
The features available in the third parameter of the <code>window.open()</code> method include <code>width</code> and <code>height</code>, to set the size of the window in pixels, and several features that can be set to either <code>yes</code> (1) or <code>no</code> (0): <code>toolbar</code>, <code>location</code>, <code>directories</code>, <code>status</code>, <code>menubar</code>, <code>scrollbars</code>, and <code>resizable</code>. You can list only the features you want to change from the default. This example creates a small window with no toolbar or status line:
<pre>SmallWin = window.open("","small","width=100,height=120,toolbar=0,status=0");
</pre>
=== Opening and Closing Windows ===
Of course, you can close windows as well. The <code>window.close()</code> method closes a window. Browsers don't normally allow you to close the main browser window without the user's permission; this method's main purpose is for closing windows you have created. For example, this statement closes a window called <code>updatewindow</code>:
<pre>updatewindow.close();</pre>
As another example, [Listing 10.1] shows an HTML document that enables you to open a small new window by pressing a button. You can then press another button to close the new window. The third button attempts to close the current window. Depending on your browser and its settings, this might or might not work. If it does close the window, most browsers will ask for confirmation first.
; Listing 10.1. An HTML Document That Uses JavaScript to Enable You to Create and Close Windows
<pre><html>
<head><title>Create a New Window</title>
</head>
<body>
<h1>Create a New Window</h1>
<hr>
<p>Use the buttons below to test opening and closing windows in JavaScript.</p>
<hr>
<form NAME="inform">
<input TYPE="button" VALUE="Open New Window" onClick="NewWin=window.open('','NewWin',
'toolbar=no,status=no,width=200,height=100'); ">
<p><input TYPE="button" VALUE="Close New Window" onClick="NewWin.close();" ></p>
<p><input TYPE="button" VALUE="Close Main Window" onClick="window.close();"></p>
</form>
<br><p>Have fun!</p>
<hr>
</body>
</html>
</pre>
This example uses simple event handlers to do its work, one for each of the buttons. [Figure 10.1] shows Firefox's display of this page, with the small new window on top.
== Moving and Resizing Windows ==
The DOM also enables you to move or resize windows. Although earlier browsers placed some restrictions on this, most modern browsers allow you to move and resize any window freely. You can do this using the following methods for any <code>window</code> object:
* <code>window.moveTo()</code> moves the window to a new position. The parameters specify the x (column) and y (row) position.
* <code>window.moveBy()</code> moves the window relative to its current position. The x and y parameters can be positive or negative, and are added to the current values to reach the new position.
* <code>window.resizeTo()</code> resizes the window to the width and height specified as parameters.
* <code>window.resizeBy()</code> resizes the window relative to its current size. The parameters are used to modify the current width and height.
As an example, [Listing 10.2] shows an HTML document with a simple script that enables you to resize or move the main window.
; Listing 10.2. Moving and Resizing the Current Window
<pre><html>
<head>
<title>Moving and resizing windows</title>
<script language="javascript" type="text/javascript">
function DoIt() {
if (document.form1.w.value && document.form1.h.value)
self.resizeTo(document.form1.w.value, document.form1.h.value);
if (document.form1.x.value && document.form1.y.value)
self.moveTo(document.form1.x.value, document.form1.y.value);
}
</script>
</head>
<body>
<h1>Moving and Resizing Windows</h1>
<form name="form1">
<b>Width:</b> <input type="text" name="w"><br>
<b>Height:</b> <input type="text" name="h"><br>
<b>X-position:</b> <input type="text" name="x"><br>
<b>Y-position:</b> <input type="text" name="y"><br>
<input type="button" value="Change Window" onClick="DoIt();">
</form>
</body>
</html>
</pre>
In this example, the <code>DoIt()</code> function is called as an event handler when you click the Change Window button. This function checks whether you have specified width and height values. If you have, it uses the <code>self.resizeTo()</code> method to resize the current window. Similarly, if you have specified x and y values, it uses <code>self.moveTo()</code> to move the window.
Depending on their settings, some browsers might not allow your script to resize or move the main window. In particular, Firefox can be configured to disallow it. You can enable it by selecting Tools, Options from the menu. Select the Content tab, click the Advanced button next to the Enable JavaScript option, and enable the Move or Resize Existing Windows option.
; Watch Out!: This is one of those JavaScript features you should think twice about before using. These methods are best used for resizing or moving pop-up windows your script has generated—not as a way to force the user to use your preferred window size, which most users will find very annoying. You should also be aware that browser settings may be configured to prevent resizing or moving windows, so make sure your script still works even without resizing.
== Using Timeouts ==
Sometimes the hardest thing to get a script to do is to do nothing at all—for a specific amount of time. Fortunately, JavaScript includes a built-in function to do this. The <code>window.setTimeout</code> method enables you to specify a time delay and a command that will execute after the delay passes.
; By the Way: Timeouts don't actually make the browser stop what it's doing. Although the statement you specify in the <code>setTimeout</code> method won't be executed until the delay passes, the browser will continue to do other things while it waits (for example, acting on event handlers).
You begin a timeout with a call to the <code>setTimeout()</code> method, which has two parameters. The first is a JavaScript statement, or group of statements, enclosed in quotes. The second parameter is the time to wait in milliseconds (thousandths of seconds). For example, the following statement displays an alert dialog box after 10 seconds:
<pre>ident=window.setTimeout("alert('Time's up!')",10000);
</pre>
; Watch Out!: Like event handlers, timeouts use a JavaScript statement within quotation marks. Make sure that you use a single quote (apostrophe) on each side of each string within the statement, as shown in the preceding example.
A variable (<code>ident</code> in this example) stores an identifier for the timeout. This enables you to set multiple timeouts, each with its own identifier. Before a timeout has elapsed, you can stop it with the <code>clearTimeout()</code> method, specifying the identifier of the timeout to stop:
<pre>window.clearTimeout(ident);
</pre>
=== Updating a Page with Timeouts ===
Normally, a timeout only happens once because the statement you specify in the <code>setTimeout()</code> method statement is only executed once. But often, you'll want your statement to execute over and over. For example, your script might be updating a clock or a countdown and need to execute once per second.
You can make a timeout repeat by issuing the <code>setTimeout()</code> method call again in the function called by the timeout. [Listing 10.3] shows an HTML document that demonstrates a repeating timeout.
; Listing 10.3. Using Timeouts to Update a Page Every Two Seconds
<pre><html>
<head><title>Timeout Example</title>
<script language="javascript" type="text/javascript"gt;
var counter="0;"
// call Update function in 2 seconds after first load ID="window.setTimeout("Update();",2000);"
function Update() {
counter++;
document.form1.input1. value="The counter is now at " + counter;
// set another timeout for the next count ID="window.setTimeout("Update();",2000);"
}
</script>
</head>
<body>
<h1>Timeout Example</h1>
<hr><p>
The text value below is being updated every two seconds.
Press the RESET button to restart the count, or the STOP button to stop it.
</p><hr>
<form NAME="form1">
<input TYPE="text" NAME="input1" SIZE="40"><br>
<input TYPE="button" VALUE="RESET" onClick="counter = 0;"><br>
<input TYPE="button" VALUE="STOP" onClick="window.clearTimeout(ID);">
</form>
<hr>
</body>
</html>
</pre>
This program displays a message in a text field every two seconds, including a counter that increments each time. You can use the Reset button to start the count over and the Stop button to stop the counting.
This script calls the <code>setTimeout()</code> method when the page loads, and again at each update. The <code>Update()</code> function performs the update, adding one to the counter and setting the next timeout. The Reset button sets the counter to zero, and the Stop button demonstrates the <code>clearTimeout()</code> method. [Figure 10.2] shows Internet Explorer's display of the timeout example after the counter has been running for a while.
; By the Way: This example and the next one use buttons, which are a simple example of what you can do with HTML forms and JavaScript. You'll learn much more about forms in [Hour 11], "Getting Data with Forms."
== Displaying Dialog Boxes ==
The <code>window</code> object includes three methods that are useful for displaying messages and interacting with the user. You've already used these in some of your scripts. Here's a summary:
* <code>window.alert(message)</code> displays an alert dialog box, shown in [Figure 10.3]. This dialog box simply gives the user a message.
* <code>window.confirm(message)</code> displays a confirmation dialog box. This displays a message and includes OK and Cancel buttons. This method returns <code>true</code> if OK is pressed and <code>false</code> if Cancel is pressed. A confirmation is displayed in [Figure 10.4].
* <code>window.prompt(message,default)</code> displays a message and prompts the user for input. It returns the text entered by the user. If the user does not enter anything, the default value is used.
To use the <code>confirm()</code> and <code>prompt()</code> methods, use a variable to receive the user's response. For example, this statement displays a prompt and stores the text the user enters in the <code>text variable</code>:
<pre>text = window.prompt("Enter some text","Default value");
</pre>
; Did you Know?: You can usually omit the <code>window</code> object when referring to these methods because it is the default context of a script (for example, <code>alert("text")</code>).
=== Creating a Script to Display Dialog Boxes ===
As a further illustration of these types of dialog boxes, [Listing 10.4] shows an HTML document that uses buttons and event handlers to enable you to test dialog boxes.
; Listing 10.4. An HTML Document That Uses JavaScript to Display Alerts, Confirmations, and Prompts
<pre><html>
<head><title>Alerts, Confirmations, and Prompts</title>
</head>
<body>
<h1>Alerts, Confirmations, and Prompts</h1>
<hr>
Use the buttons below to test dialogs in JavaScript.
<hr>
<form NAME="winform">
<p><input TYPE="button" VALUE="Display an Alert" onClick="window.alert('This is a test alert.'); "></p>
<p><input TYPE="button" VALUE="Display a Confirmation" onClick="window.confirm('Would you like to confirm?');"></p>
<p><input TYPE="button" VALUE="Display a Prompt" onClick="window.prompt('Enter some Text:','This is the default value');">
</p>
</form>
<br>Have fun!
<hr>
</body>
</html>
</pre>
This document displays three buttons, and each one uses an event handler to display one of the dialog boxes.
[Figure 10.5] shows the script in [Listing 10.4] in action. The prompt dialog box is currently displayed and shows the default value.
== Working with Frames ==
Browsers also support frames, which enable you to divide the browser window into multiple panes. Each frame can contain a separate URL or the output of a script.
=== Using JavaScript Objects for Frames ===
When a window contains multiple frames, each frame is represented in JavaScript by a <code>frame</code> object. This object is equivalent to a <code>window</code> object, but it is used for dealing specifically with that frame. The <code>frame</code> object's name is the same as the <code>NAME</code> attribute you give it in the <code><frame></code> tag.
Remember the <code>window</code> and <code>self</code> keywords, which refer to the current window? When you are using frames, these keywords refer to the current frame instead. Another keyword, <code>parent</code>, enables you to refer to the main window.
Each frame object in a window is a child of the <code>parent</code> window object. Suppose you define a set of frames using the following HTML:
<pre><frameset ROWS="*,*" COLS="*,*">
<frame NAME="topleft" SRC="topleft.htm">
<frame NAME="topright" SRC="topright.htm">
<frame NAME="bottomleft" SRC="botleft.htm">
<frame NAME="bottomright" SRC="botright.htm">
</frameset>
</pre>
This simply divides the window into quarters. If you have a JavaScript program in the <code>topleft.htm</code> file, it would refer to the other windows as <code>parent.topright</code>, <code>parent.bottomleft</code>, and so on. The keywords <code>window</code> and <code>self</code> would refer to the <code>topleft</code> frame.
; By the Way: If you use nested framesets, things are a bit more complicated. <code>window</code> still represents the current frame, <code>parent</code> represents the frameset containing the current frame, and <code>top</code> represents the main frameset that contains all the others.
=== The <code>frames</code> Array ===
Rather than referring to frames in a document by name, you can use the <code>frames</code> array. This array stores information about each of the frames in the document. The frames are indexed starting with zero and beginning with the first <code><frame></code> tag in the frameset document.
For example, you could refer to the frames defined in the previous example using array references:
* <code>parent.frames[0]</code> is equivalent to the <code>topleft</code> frame.
* <code>parent.frames[1]</code> is equivalent to the <code>topright</code> frame.
* <code>parent.frames[2]</code> is equivalent to the <code>bottomleft</code> frame.
* <code>parent.frames[3]</code> is equivalent to the <code>bottomright</code> frame.
You can refer to a frame using either method interchangeably, and depending on your application, you should use the most convenient method. For example, a document with 10 frames would probably be easier to use by number, but a simple two-frame document is easier to use if the frames have meaningful names.
== Try it Yourself — Using Frames with JavaScript ==
As a simple example of addressing frames using JavaScript, you will now create an HTML document that divides the window into four frames, and a document with a script for the top-left corner frame. Buttons in the top-left frame will trigger JavaScript event handlers that display text in the other frames.
To begin, you will need a frameset document. [Listing 10.5] shows a simple HTML document to divide the window into four frames.
; Listing 10.5. An HTML Document That Divides the Window into Four Frames
<pre><frameset ROWS="*,*" COLS="*,*">
<frame NAME="top_left" SRC="topleft.html">
<frame NAME="top_right" SRC="">
<frame NAME="bottom_left" SRC="">
<frame NAME="bottom_right" SRC="">
</frameset>
</pre>
The first frame defined here, <code>top_left</code>, to will contain an HTML document and a simple script. [Listing 10.6] shows the HTML and JavaScript code for the top-left frame.
; Listing 10.6. The HTML and JavaScript for the Frame Example
<pre>
<html>
<head>
<title>Frame Test</title>
<script language="javascript" type="text/javascript">
function FillFrame(framename) {
// Find the object for the frame
theframe=parent[framename];
// Open and clear the frame's document
theframe.document.open();
// Create some output
theframe.document.write("<h1>JavaScript Output</h1>");
theframe.document.write("<p>This text is in the ");
theframe.document.write(framename + " frame.</p>");
}
</script>
</head>
<body>
<h1>Frame Test</h1>
<form name="form1">
<input type="button" value="Top right" onClick="FillFrame('top_right');">
<input type="button" value="Bottom left" onClick="FillFrame('bottom_left');">
<input type="button" id="js" value="Bottom right" onClick="FillFrame('bottom_right');">
</form>
</body>
</html>
</pre>
This document defines three buttons with event handlers that call the <code>FillFrame()</code> function with a parameter for the frame name. The function finds the correct child of the <code>parent</code> window object for the specified frame, uses <code>document.open</code> to create a new document in the frame, and uses <code>document.write</code> to display text in the frame.
To try this example, save [Listing 10.6] as <code>topleft.html</code> in the same folder as the frameset document from [Listing 10.5], and load [Listing 10.5] into a browser. [Figure 10.6] shows the result of this example after all three buttons have been clicked.
== Summary ==
In this hour, you've learned how to use the <code>window</code> object to work with browser windows, and used its properties and methods to set timeouts and display dialog boxes. You've also learned how JavaScript can work with framed documents.
In the next hour, you'll move on to another unexplored area of the JavaScript object hierarchy—the <code>form</code> object. You'll learn how to use forms to create some of the most useful applications of JavaScript.
=== Q&A ===
; Q1:When a script is running in a window created by another script, how can it refer back to the original window?
;A1: JavaScript 1.1 and later include the <code>window.opener</code> property, which lets you refer to the window that opened the current window.
; Q2: I've heard about layers, which are similar to frames, but more versatile, and are supported in the latest browsers. Can I use them with JavaScript?
; A2: Yes. You'll learn how to use layers with JavaScript in [Hour 13], "Using the W3C DOM."
; Q3: How can I update two frames at once when the user clicks on a single link?
; A3: You can do this by using an event handler, as in [Listing 10.6], and including two statements to load URLs into different frames.
===Quiz Questions===
Test your knowledge of the DOM's window features by answering the following questions.
''' 1.''' Which of the following methods displays a dialog box with OK and Cancel buttons, and waits for a response?
# <code>window.alert</code>
# <code>window.confirm</code>
# <code>window.prompt</code>
'''2.''' What does the <code>window.setTimeout</code> method do?
# Executes a JavaScript statement after a delay
# Locks up the browser for the specified amount of time
# Sets the amount of time before the browser exits automatically
'''3.''' You're working with a document that contains three frames with the names <code>first</code>, <code>second</code>, and <code>third</code>. If a script in the second frame needs to refer to the first frame, what is the correct syntax?
# <code>window.first</code>
# <code>parent.first</code>
# <code>frames.first</code>
===Quiz Answers===
'''1.''' b. The <code>window.confirm</code> method displays a dialog box with OK and Cancel buttons.
''' 2.''' a. The <code>window.setTimeout</code> method executes a JavaScript statement after a delay.
''' 3.''' b. The script in the second frame would use <code>parent.first</code> to refer to the first frame.
=== Exercises ===
If you want to study the <code>window</code> object and its properties and methods further, perform these exercises:
* Return to the date/time script you created in [Hour 2], "Creating Simple Scripts." This script only displays the date and time once when the page is loaded. Using timeouts, you can modify the script to reload automatically every second or two and display a "live" clock. (Use the <code>location.reload()</code> method, described in [Hour 4].)
* Modify the examples in Listings 10.5 and 10.6 to use three horizontal frames instead of four frames in a grid. Change the buttons to make it clear which frame they will affect.
0hvh1zjr4qw74lmh57g87x5hwbliclg
User:Moncur/15
2
2090
39280
6080
2026-04-13T06:03:48Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39280
wikitext
text/x-wiki
=15. Unobtrusive Scripting=
== Scripting Best Practices ==
As you start to develop more complex scripts, it's important to know some scripting best practices. These are guidelines for using JavaScript that more experienced programmers have learned the hard way. Here are a few of the benefits of following these best practices:
* Your code will be readable and easy to maintain, whether you're turning the page over to someone else or just trying to remember what you did a year ago.
* You'll create code that follows standards, and won't be crippled by a new version of a particular browser.
* You'll create pages that work even without JavaScript.
* It will be easy to adapt code you create for one site to another site or project.
* Your users will thank you for creating a site that is easy to use, and easy to fix when things go wrong.
Whether you're writing an entire AJAX web application or simply enhancing a page with a three-line script, it's useful to know some of the concepts that are regularly considered by those who write complex scripts for a living. The following sections introduce some of these best practices.
=== Content, Presentation, and Behavior ===
When you create a web page, or especially an entire site or application, you're dealing with three key areas: content, presentation, and behavior.
* Content consists of the words that a visitor can read on your pages. You create the content as text, and mark it up with HTML to define different classes of contentheadings, paragraphs, links, and so on.
* Presentation is the appearance and layout of the words on each pagetext formatting, fonts, colors, and graphics. Although it was common in the early days of the Web to create the presentation using HTML only, you can now use Cascading Style Sheets (CSS) to define the presentation.
* Behavior is what happens when you interact with a page—items that highlight when you move over them, forms you can submit, and so on. This is where JavaScript comes in, along with server-side languages such as PHP.
It's a good idea to keep these three areas in mind, especially as you create larger sites. Ideally, you want to keep content, presentation, and behavior separated as much as possible. One good way to do this is to create an external CSS file for the presentation and an external JavaScript file for the behavior, and link them to the HTML document.
Keeping things separated like this makes it easier to maintain a large site—if you need to change the color of the headings, for example, you can make a quick edit to the CSS file without having to look through all of the HTML markup to find the right place to edit. It also makes it easy for you to reuse the same CSS and JavaScript on multiple pages of a site. Last, but not least, this will encourage you to use each language where its strengths lie, making your job easier.
=== Progressive Enhancement ===
One of the old buzzwords of web design was graceful degradation. The idea was that you could build a site that used all of the bells and whistles of the latest browsers, as long as it would "gracefully degrade" to work on older browsers. This mostly meant testing on a few older browsers and hoping it worked, and there was always the possibility of problems in browsers that didn't support the latest features.
Ironically, you might expect browsers that lack the latest features to be older, less popular ones, but some of the biggest problems are with brand-new browsers—those included with mobile phones and other new devices, all of which are primitive compared to the latest browsers running on computers.
One new approach to web design that addresses this problem is known as progressive enhancement. The idea is to keep the HTML documents as simple as possible, so they'll definitely work in even the most primitive browsers. After you've tested that and made sure the basic functionality is there, you can add features that make the site easier to use or better looking for those with new browsers.
If you add these features unobtrusively, they have little chance of preventing the site from working in its primitive HTML form. Here are some guidelines for progressive enhancement:
* Enhance the presentation by adding rules to a separate CSS file. Try to avoid using HTML markup strictly for presentation, such as <code><nowiki><b></nowiki></code> for boldface or <code><nowiki><blockquote></nowiki></code> for an indented section.
* Enhance behavior by adding scripts to an external JavaScript file.
* Add events without using inline event handlers, as described in [Hour 9], "Responding to Events," and later in this hour.
* Use feature sensing, described later this hour, to ensure that JavaScript code only executes on browsers that support the features it requires.
; By the Way: The term progressive enhancement first appeared in a presentation and article on this topic by Steve Champeon. The original article, along with many more web design articles, is available on his company's website at [http://hesketh.com/ http://hesketh.com/].
=== Adding Event Handlers ===
In [Hour 9], you learned that there is more than one way to set up an event handler. The simplest way is to add them directly to an HTML tag. For example, this <code><body></code> tag has an event handler that calls a function called <code>Startup</code>.
<pre><body onLoad="Startup();"></pre>
This method still works, but it does mean putting JavaScript code in the HTML page, which means you haven't fully separated content and behavior. To keep things entirely separate, you can set up the event handler in the JavaScript file instead, using syntax like this:
<pre>window.onload=Startup;</pre>
Right now, this is usually the best way to set up events: It keeps JavaScript out of the HTML file, and it works in all browsers since Netscape 4 and Internet Explorer 4. However, it does have one problem: You can't attach more than one event to the same element of a page. For example, you can't have two different <code>onLoad</code> event handlers that both execute when the page loads.
When you're the only one writing scripts, this is no big deal—you can combine the two into one function. But when you're trying to use two or three third-party scripts on a page, and all of them want to add an <code>onLoad</code> event handler to the body, you have a problem.
=== The W3C Event Model ===
To solve this problem and standardize event handling, the W3C created an event model as part of the DOM level 2 standard. This uses a method, <code>addEventListener()</code>, to attach a handler to any event on any element. For example, the following uses the W3C model to set up the same <code>onLoad</code> event handler as the previous examples:
<pre>window.addEventListener('load', Startup, false);</pre>
The first parameter of <code>addEventListener()</code> is the event name without the <code>on</code> prefix—<code>load</code>, <code>click</code>, <code>mouseover</code>, and so on. The second parameter specifies the function to handle the event, and the third is an advanced flag that indicates how multiple events should be handled. (<code>false</code> works for most purposes.)
Any number of functions can be attached to an event in this way. Because one event handler doesn't replace another, you use a separate function, <code>removeEventListener()</code>, which uses the same parameters:
<pre>window.removeEventListener('load', Startup, false);</pre>
The problem with the W3C model is that Internet Explorer (as of versions 6 and 7) doesn't support it. Instead, it supports a proprietary method, <code>attachEvent()</code>, which does much the same thing. Here's the <code>Startup</code> event handler defined Microsoft-style:
<pre>window.attachEvent('onload', Startup);</pre>
The <code>attachEvent()</code> method has two parameters. The first is the event, with the <code>on</code> prefix—<code>onload</code>, <code>onclick</code>, <code>onmouseover</code>, and so on. The second is the function that will handle the event. Internet Explorer also supports a <code>detachEvent()</code> method with the same parameters for removing an event handler.
=== Attaching Events the Cross-Browser Way ===
As you can see, attaching events in this new way is complex and will require different code for different browsers. In most cases, you're better off using the traditional method to attach events, and that method is used in most of this book's examples. However, if you really need to support multiple event handlers, you can use some <code>if</code> statements to use either the W3C method or Microsoft's method. For example, the following code adds the <code>ClickMe()</code> function as an event for the element with the <code>id</code> attribute <code>btn</code>:
<pre>obj = document.getElementById("btn');
if (obj.addEventListener) {
obj.addEventListener('click',ClickMe,false);
} else if (obj.attachEvent) {
obj.attachEvent('onclick',ClickMe);
} else {
obj.onclick=ClickMe;
}
</pre>
This checks for the <code>addEventListener()</code> method, and uses it if it's found. Otherwise, it checks for the <code>attachEvent()</code> method, and uses that. If neither is found, it uses the traditional method to attach the event handler. This technique is called feature sensing and is explained in detail later this hour.
Many universal functions are available to compensate for the lack of a consistent way to attach events. If you are using a third-party library, there's a good chance it includes an event function that can simplify this process for you.
; Did you Know?: The Yahoo! UI Library includes an event-handling function that can attach events in any browser, attach the same event handler to many objects at once, and other nice features. See [http://developer.yahoo.net/yui/ http://developer.yahoo.net/yui/] for details, and see [Hour 8], "Using Built-in Functions and Libraries," for information about using third-party libraries.
=== Web Standards: Avoid Being Browser Specific ===
The Web was built on standards, such as the HTML standard developed by the W3C. Now there are a lot of standards involved with JavaScriptCSS, the W3C DOM, and the ECMAScript standard that defines JavaScript's syntax.
Right now, both Microsoft and the Mozilla Project are improving their browsers' support for web standards, but there are always going to be some browser-specific, nonstandard features, and some parts of the newest standards won't be consistently supported between browsers.
Although it's perfectly fine to test your code in multiple browsers and do whatever it takes to get it working, it's a good idea to follow the standards rather than browser-specific techniques when you can. This ensures that your code will work on future browsers that improve their standards support, whereas browser-specific features might disappear in new versions.
; By the Way: One reason to make sure you follow standards is that your pages can be better interpreted by search engines, which often helps your site get search traffic. Separating content, presentation, and behavior is also good for search engines because they can focus on the HTML content of your site without having to skip over JavaScript or CSS.
=== Documenting Your Code ===
As you create more complex scripts, don't forget to include comments in your code to document what it does, especially when some of the code seems confusing or is difficult to get working. It's also a good idea to document all of the data structures and variables, and function arguments used in a larger script.
Comments are a good way to organize code, and will help you work on the script in the future. If you're doing this for a living, you'll definitely need to use comments so that others can work on your code as easily as you can.
=== Usability ===
While you're adding cool features to your site, don't forget about usability—making things as easy, logical, and convenient as possible for users of your site. Although there are many books and websites devoted to usability information, a bit of common sense goes a long way.
For example, suppose you use a drop-down list as the only way to navigate between pages of your site. This is a common use for JavaScript, and it works well, but is it usable? Try comparing it to a simple set of links across the top of a page.
* The list of links lets you see at a glance what the site contains; the drop-down list requires you to click to see the same list.
* Users expect links and can spot them quickly—a drop-down list is more likely to be part of a form than a navigation tool, and thus won't be the first thing they look for when they want to navigate your site.
* Navigating with a link takes a single click—navigating with the drop-down list takes at least two clicks.
Remember to consider the user's point of view whenever you add JavaScript to a site, and be sure you're making the site easier to use—or at least not harder to use. Also make sure the site is easy to use even without JavaScript.
=== Design Patterns ===
If you learn more about usability, you'll undoubtedly see design patterns mentioned. This is a computer science term meaning "an optimal solution to a common problem." In web development, design patterns are ways of designing and implementing part of a site that webmasters run into over and over.
For example, if you have a site that displays multiple pages of data, you'll have "Next Page" and "Previous Page" links, and perhaps numeric links for each page. This is a common design pattern—a problem many web designers have had to solve, and one with a generally agreed-upon solution. Other common web design patterns include a login form, a search engine, or a list of navigation links for a site.
Of course, you can be completely original and make a search engine, a shopping cart, or a login form that looks nothing like any other, but unless you have a way of making them even easier to use, you're better off following the pattern, and giving your users an experience that matches their expectations.
Although you can find some common design patterns just by browsing sites similar to yours and noticing how they solved particular problems, there are also sites that specialize in documenting these patterns, and they're a good place to start if you need ideas on how to make your site work.
; Did you Know?: The Yahoo! Developer Network documents a variety of design patterns used on their network of sites, many of which are implemented using JavaScript: [http://developer.yahoo.net/ypatterns/ http://developer.yahoo.net/ypatterns/].
=== Accessibility ===
One final aspect of usability to consider is accessibility—making your site as accessible as possible for all users, including the disabled. For example, blind users might use a text-reading program to read your site, which will ignore images and most scripts. More than just good manners, accessibility is mandated by law in some countries.
The subject of accessibility is complex, but you can get most of the way there by following the philosophy of progressive enhancement: Keep the HTML as simple as possible, keep JavaScript and CSS separate, and make JavaScript an enhancement rather than a requirement for using your site.
===Reading Browser Information===
In [Hour 4], "Working with the Document Object Model (DOM)," you learned about the various objects (such as <code>window</code> and <code>document</code>) that represent portions of the browser window and the current web document. JavaScript also includes an object called <code>navigator</code> that you can use to read information about the user's browser.
The <code>navigator</code> object isn't part of the DOM, so you can refer to it directly. It includes a number of properties, each of which tells you something about the browser. These include the following:
* <code>navigator.appCodeName</code> is the browser's internal code name, usually <code>Mozilla</code>.
* <code>navigator.appName</code> is the browser's name, usually <code>Netscape</code> or <code>Microsoft Internet Explorer</code>.
* <code>navigator.appVersion</code> is the version of the browser being used—for example, <code>4.0(Win95;I)</code>.
* <code>navigator.userAgent</code> is the user-agent header, a string that the browser sends to the web server when requesting a web page. It includes the entire version information—for example, <code>Mozilla/4.0(Win95;I)</code>.
* <code>navigator.language</code> is the language (such as English or Spanish) of the browser. This is stored as a code, such as "en_US" for U.S. English. This property is supported only by Netscape and Firefox.
* <code>navigator.platform</code> is the computer platform of the current browser. This is a short string, such as <code>Win16</code>, <code>Win32</code>, or <code>MacPPC</code>. You can use this to enable any platform-specific features—for example, ActiveX components.
; By the Way: As you might have guessed, the <code>navigator</code> object is named after Netscape Navigator, the browser that originally supported JavaScript. Fortunately, this object is also supported by Internet Explorer and most other recent browsers.
=== Displaying Browser Information ===
As an example of how to read the <code>navigator</code> object's properties, [Listing 15.1] shows a script that displays a list of the properties and their values for the current browser.
; Listing 15.1. A Script to Display Information About the Browser:
<pre><html>
<head>
<title>Browser Information</title>
</head>
<body>
<h1>Browser Information</h1>
<hr>
<p>
The <b>navigator</b> object contains the following information
about the browser you are using.
</p>
<ul>
<script language="JavaScript" type="text/javascript">
document.write("<li><b>Code Name:</b> " + navigator.appCodeName);
document.write("<li><b>App Name:</b> " + navigator.appName);
document.write("<li><b>App Version:</b> " + navigator.appVersion);
document.write("<li><b>User Agent:</b> " + navigator.userAgent);
document.write("<li><b>Language:</b> " + navigator.language);
document.write("<li><b>Platform:</b> " + navigator.platform);
</script>
</ul>
<hr>
</body>
</html>
</pre>
This script includes a basic HTML document. A script is used within the body of the document to display each of the properties of the <code>navigator</code> object using the <code>document.write()</code> statement.
To try this script, load it into the browser of your choice. If you have more than one browser or browser version handy, try it in each one. Firefox's display of the script is shown in [Figure 15.1].
=== Dealing with Dishonest Browsers ===
If you tried the browser information script in [Listing 15.1] using one of the latest versions of Internet Explorer, you probably got a surprise. [Figure 15.2] shows how Internet Explorer 6.0 displays the script.
There are several unexpected things about this display. First of all, the <code>navigator.language</code> property is listed as undefined. This isn't much of a surprise because this property isn't yet supported by Internet Explorer.
More important, you'll notice that the word <code>Mozilla</code> appears in the Code Name and User Agent fields. The full user agent string reads as follows:
<pre>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)</pre>
Believe it or not, Microsoft did have a good reason for this. At the height of the browser wars, about the time Netscape 3.0 and IE 3.0 came out, it was becoming common to see "Netscape only" pages. Some webmasters who used features such as frames and JavaScript set their servers to turn away browsers without <code>Mozilla</code> in their user agent string. The problem with this was that most of these features were also supported by Internet Explorer.
Microsoft solved this problem in IE 4.0 by making IE's user agent read <code>Mozilla</code>, with the word <code>compatible</code> in parentheses. This allows IE users to view those pages, but still includes enough details to tell web servers which browser is in use.
You've probably already noticed the other problem with Internet Explorer 6.0's user agent string: the portion reading <code>Mozilla/4.0</code>. Not only is IE claiming to be Netscape, but it's also masquerading as version 4.0. Why?
As it turns out, this was another effort by Microsoft to stay one step ahead of the browser wars, although this one doesn't make quite as much sense. Because poorly written scripts were checking specifically for "Mozilla/4" for dynamic HTML pages, Microsoft was concerned that its 5.0 version would fail to run these pages. Since changing it now would only create more confusion, this tradition continues with IE 6.0.
; By the Way: Microsoft isn't alone in confusing browser IDs. Netscape version 6 displays a user agent string beginning with <code>Mozilla/5</code>, and an app version of 5.0. (Netscape 5.0 was Netscape's open-source browser, code named Mozilla, which formed the foundation of Netscape 6 and Firefox.)
Although these are two interesting episodes in the annals of the browser wars, what does all this mean to you? Well, you'll need to be careful when your scripts are trying to differentiate between IE and Netscape, and between different versions. You'll need to check for specific combinations instead of merely checking the <code>navigator.</code>appVersion value. Fortunately, there's a better way to handle this, as you'll learn in the next section.
== Cross-Browser Scripting ==
If all of those details about detecting different browser versions seem confusing, here's some good news—in most cases, you can write cross-browser scripts without referring to the <code>navigator</code> object at all. This is not only easier, it's better, because browser-checking code is often confused by new browser versions, and has to be updated each time a new browser is released.
=== Feature Sensing ===
Checking browser versions is sometimes called browser sensing. The better way of dealing with multiple browsers is called feature sensing. In feature sensing, rather than checking for a specific browser, you check for a specific feature. For example, suppose your script needs to use the <code>document.getElementById()</code> function. You can begin a script with an <code>if</code> statement that checks for the existence of this function:
<pre>if (document.getElementById) {
// do stuff
}
</pre>
If the <code>getElementById</code> function exists, the block of code between the brackets will be executed. Another common way to use feature sensing is at the beginning of a function that will make use of a feature:
<pre>function changeText() {
if (!document.getElementById) return;
// the rest of the function executes if the feature is supported
}</pre>
If this looks familiar, it's because it's been used in several previous examples in this book. For example, most of the code listings in [Hour 14], "Using Advanced DOM Features," make use of feature sensing to prevent errors in browsers that don't support the W3C DOM.
You don't need to check for every feature before you use it—for example, there's not much point in verifying that the <code>window</code> object exists in most cases. You can also assume that the existence of one feature means others are supported: If <code>getElementById()</code> is supported, chances are the rest of the W3C DOM functions are supported.
Feature sensing is a very reliable method of keeping your JavaScript unobtrusive—if a browser supports the feature, it works, and if the browser doesn't, your script stays out of the way. It's also much easier than trying to keep track of hundreds of different browser versions and what they support.
; By the Way: Feature sensing is also handy when working with third-party libraries, as discussed in [Hour 8]. You can check for the existence of an object or a function belonging to the library to verify that the library file has been loaded before your script uses its features.
=== Dealing with Browser Quirks ===
So, if feature sensing is better than browser sensing, why do you still need to know about the <code>navigator</code> object? There's one situation where it still comes in handy, although if you're lucky you won't find yourself in that situation.
As you develop a complex script and test it in multiple browsers, you might run across a situation where your perfectly standard code works as it should in one browser, and fails to work in another. Assuming you've eliminated the possibility of a problem with your script, you've probably run into a browser bug, or a difference in features between browsers at the very least. Here are some tips for this situation:
* Double-check for a bug in your own code. See [Hour 16], "Debugging JavaScript Applications," for debugging tips.
* Search the Web to see if others have run into the same bug. Often you'll find that someone else has already found a workaround.
* Try a different approach to the code, and you might sidestep the bug.
* If the problem is that a feature is missing in one browser, use feature sensing to check for that feature.
* When all else fails, use the <code>navigator</code> object to detect a particular browser and substitute some code that works in that browser. This should be your last resort.
; Did you Know?: Peter-Paul Koch's QuirksMode, [http://www.quirksmode.org/ www.quirksmode.org], is a good place to start when you're looking for specific information about browser bugs.
== Supporting Non-JavaScript Browsers ==
Some visitors to your site will be using browsers that don't support JavaScript at all. These aren't just a few holdouts using ancient browsers—actually, there are more non-JavaScript browsers than you might think:
* Both Internet Explorer and Firefox include an option to turn off JavaScript, and some users do so. More often, the browser might have been set up by their ISP or employer with JavaScript turned off by default, usually in a misguided attempt to increase security.
* Some corporate firewalls and personal antivirus software block JavaScript.
* Some ad-blocking software mistakenly prevents scripts from working even if they aren't related to advertising.
* More and more mobile phones are coming with web browsers these days, and most of these support little to no JavaScript.
* Some disabled users use special-purpose browsers or text-only browsers that might not support JavaScript.
As you can see, it would be foolish to assume that all of your visitors will support JavaScript. Two techniques you can use to make sure these users can still use the site are discussed in the following sections.
; By the Way: Search engines are another "browser" that will visit your site frequently, and they usually don't pay any attention to JavaScript. If you want search engines to fully index your site, it's critical that you avoid making JavaScript a requirement to navigate the site.
===Using the <code><noscript></code> Tag===
One way to be friendly to non-JavaScript browsers is to use the <code><noscript></code> tag. Supported in most modern browsers, this tag displays a message to non-JavaScript browsers. Browsers that support JavaScript ignore the text between the <code><noscript></code> tags, whereas others display it. Here is a simple example:
<pre><noscript>
This page requires JavaScript. You can either switch to a browser
that supports JavaScript, turn your browser's script support on,
or switch to the <a href="nojs.html">Non-JavaScript</a> version of
this page.
</noscript>
</pre>
Although this works, the trouble is that <code><noscript></code> is not consistently supported by all browsers that support JavaScript. An alternative that avoids <code><noscript></code> is to send users with JavaScript support to another page. This can be accomplished with a single JavaScript statement:
<pre><script language="JavaScript" type="text/javascript">
window.location="JavaScript.html";
</script>
</pre>
This script redirects the user to a different page. If the browser doesn't support JavaScript, of course, the script won't be executed, and the rest of the page can display a warning message to explain the situation.
=== Keeping JavaScript Optional ===
Although you can detect JavaScript browsers and display a message to the rest, the best choice is to simply make your scripts unobtrusive. Use JavaScript to enhance rather than as an essential feature, keep JavaScript in separate files, assign event handlers in the JavaScript file rather than in the HTML, and browsers that don't support JavaScript will simply ignore your script.
In those rare cases where you absolutely need JavaScript—for example, an AJAX application or a JavaScript game—you can warn users that JavaScript is required. However, it's a good idea to offer an alternative JavaScript-free way to use your site, especially if it's an e-commerce or business site that your business relies on. Don't turn away customers with lazy programming.
One place you should definitely not require JavaScript is in the navigation of your site. Although you can create drop-down menus and other fancy navigation tools using JavaScript, they prevent users' non-JavaScript browsers from viewing all of your site's pages. They also prevent search engines from viewing the entire site, compromising your chances of getting search traffic.
; By the Way: Google's Gmail application ([http://mail.google.com/ mail.google.com]), one of the most well-known uses of AJAX, requires JavaScript for its elegant interface. However, Google offers a Basic HTML View that can be used without JavaScript. This allows them to support older browsers and mobile phones without compromising the user experience for those with modern browsers.
=== Avoiding Errors ===
If you've made sure JavaScript is only an enhancement to your site, rather than a requirement, those with browsers that don't support JavaScript for whatever reason will still be able to navigate your site. One last thing to worry about: It's possible for JavaScript to cause an error, or confuse these browsers into displaying your page incorrectly.
This is a particular concern with browsers that partially support JavaScript, such as mobile phone browsers. They might interpret a <code><script></code> tag and start the script, but might not support the full JavaScript language or DOM. Here are some guidelines for avoiding errors:
* Use a separate JavaScript file for all scripts. This is the best way to guarantee that the browser will ignore your script completely if it does not have JavaScript support.
* Use feature sensing whenever your script tries to use the newer DOM features, such as <code>document.getElementById()</code>.
* Test your pages with your browser's JavaScript support turned off. Make sure nothing looks strange, and make sure you can still navigate the site.
; Did you Know?: The developer's toolbars for Firefox and Internet Explorer include a convenient way to turn off JavaScript for testing. See [Hour 16] for details.
== Try It Yourself — Creating an Unobtrusive Script ==
As an example of unobtrusive scripting, you can create a script that adds functionality to a page with JavaScript without compromising its performance in older browsers. In this example, you will create a script that creates graphic check boxes as an alternative to regular check boxes.
; By the Way: Note: See [Hour 11], "Getting Data with Forms," for the basics of working with forms in JavaScript.
Let's start with the final result: [Figure 15.3] shows this example as it appears in Firefox. The first check box is an ordinary HTML one, and the second is a graphic check box managed by JavaScript.
The graphic check box is just a larger graphic that you can click on to display the checked or unchecked version of the graphic. Although this could just be a simple JavaScript simulation that acts like a check box, it's a bit more sophisticated. Take a look at the HTML for this example in [Listing 15.2].
; Listing 15.2. The HTML File for the Graphic Check box Example:
<pre><html>
<head>
<title>Graphic Checkboxes</title>
</head>
<body>
<h1>Graphic Checkbox Example</h1>
<form name="form1">
<p>
<input type="checkbox" name="check1" id="check1">
An ordinary checkbox.
</p><p>
<input type="checkbox" name="check2" id="check2">
A graphic checkbox, created with unobtrusive JavaScript.
</p>
</form>
<script language="JavaScript" type="text/javascript" src="checkbox.js">
</script>
</body>
</html>
</pre>
If you look closely at the HTML, you'll see that the two check boxes are defined in exactly the same way with the standard <code><input></code> tag. Rather than substitute for a check box, this script actually replaces the regular check box with the graphic version. The script for this example is shown in [Listing 15.3].
; Listing 15.3. The JavaScript File for the Graphic Check box Example:
<pre>function graphicBox(box) {
// be unobtrusive
if (!document.getElementById) return;
// find the object and its parent
obj = document.getElementById(box);
parentobj = obj.parentNode;
// hide the regular checkbox
obj.style.visibility = "hidden";
// create the image element and set its onclick event
img = document.createElement("IMG");
img.onclick = Toggle;
img.src = "unchecked.gif";
// save the checkbox id within the image ID
img.id = "img" + box;
// display the graphic checkbox
parentobj.insertBefore(img,obj);
}
function Toggle(e) {
if (!e) var e=window.event;
// find the image ID
img = (e.target) ? e.target : e.srcElement;
// find the checkbox by removing "img" from the image ID
checkid = img.id.substring(3);
checkbox = document.getElementById(checkid);
// "click" the checkbox
checkbox.click();
// display the right image for the clicked or unclicked state
if (checkbox.checked) file = "checked.gif";
else file="unchecked.gif";
img.src=file;
}
//replace the second checkbox with a graphic
graphicBox("check2");
</pre>
This script has three main components:
* The <code>graphicBox()</code> function converts a regular check box to a graphic one. It starts by hiding the existing check box by changing its <code>style.visibility</code> property, and then creates a new image node containing the <code>unchecked.gif</code> graphic and inserts it into the DOM next to the original check box. (These DOM features were described in the previous hour.) It gives the image an <code>id</code> attribute containing the text <code>img</code> plus the check box's <code>id</code> attribute to make it easier to find the check box later.
* The <code>Toggle()</code> function is specified by <code>graphicBox()</code> as the event handler for the new image's <code>onClick</code> event. This function removes <code>img</code> from the image's <code>id</code> attribute to find the <code>id</code> of the real check box. It executes the <code>click()</code> method on the check box, toggling its value. Finally, it changes the image to <code>unchecked.gif</code> or <code>checked.gif</code> depending on the state of the real check box.
* The last line of the script file runs the <code>graphicBox()</code> function to replace the second check box with the <code>id</code> attribute <code>check2</code>.
Using this technique has three important advantages. First, it's an unobtrusive script. The HTML has been kept simple, and browsers that don't support JavaScript will display the ordinary check box. Second, because the real check box is still on the page but hidden, it will work correctly when the form is submitted to a server-side script. Last but not least, you can use it to create any number of graphic check boxes simply by defining regular ones in the HTML file and adding a call to <code>graphicBox()</code> to transform each one.
; By the Way: See [Hour 19], "Using Graphics and Animation," for details on the image manipulation features used in this example.
To try this example, save the JavaScript file as <code>checkbox.js</code>, and be sure the HTML file is in the same folder. You'll also need two graphics the same size, <code>unchecked.gif</code> and <code>checked.gif</code>, in the same folder. You can download all of the files you need for this example from this book's website.
== Summary ==
In this hour, you've learned many guidelines for creating scripts that work in as many browsers as possible, and learned how to avoid errors and headaches when working with different browsers. Most important, you learned how you can use JavaScript while keeping your pages small, efficient, and valid with web standards.
In the next hour, you'll learn about another thing you'll run into frequently when working with more advanced scripts: bugs. [Hour 16] shows you how to avoid common JavaScript errors, and how to use debugging tools and techniques to find and fix errors when they happen.
=== Q&A ===
'''Q1:'''
Is it possible to create 100% unobtrusive JavaScript that can enhance a page without causing any trouble for anyone?
''' A1: '''
Not quite. For example, the unobtrusive script in the Try It Yourself section of this hour is close—it will work in the latest browsers, and the regular check box will display and work fine in even ancient browsers. However, it can still fail if someone with a modern browser has images turned off: The script will hide the check box because JavaScript is supported, but the image won't be there. This is a rare circumstance, but it's an example of how any feature you add can potentially cause a problem for some small percentage of your users.
''' Q2:'''
Can I detect the user's email address using the <code>navigator</code> object or another technique?
''' A2: '''
No, there is no reliable way to detect users' email addresses using JavaScript. (If there was, you would get hundreds of advertisements in your mailbox every day from companies that detected your address as you browsed their pages.) You can use a signed script to obtain the user's email address, but this requires the user's permission and only works in some versions of Netscape.
'''Q3:'''
Are there browsers besides Firefox, Netscape, and Internet Explorer that support JavaScript?
''' A3: '''
Yes. Opera is a multiplatform browser that supports JavaScript and the W3C DOM. Apple's Safari browser for Macintosh also supports JavaScript. It's always best to support all browsers if you can, and to focus on web standards rather than particular browsers.
=== Quiz Questions ===
Test your knowledge of unobtrusive scripting by answering the following questions.
''' 1.'''
Which of the following is the best place to put JavaScript code?
# Right in the HTML document
# In a separate JavaScript file
# In a CSS file
'''2.'''
Which of the following is something you can't do with JavaScript?
# Send browsers that don't support a feature to a different page
# Send users of Internet Explorer to a different page
# Send users of non-JavaScript browsers to a different page
'''3.'''
Which of the following is the best way to define an event handler that works in all modern browsers?
# <code><body onLoad="MyFunction()"></code>
# <code>window.onload=MyFunction;</code>
# <code>window.attachEvent('load',MyFunction,false);</code>
=== Quiz Answers ===
''' 1.'''
b. The best place for JavaScript is in a separate JavaScript file.
''' 2.'''
c. You can't use JavaScript to send users of non-JavaScript browsers to a different page because the script won't be executed at all.
'''3.'''
b. The code <code>window.onload=MyFunction;</code> defines an event handler in all modern browsers. This is better than using an inline event handler as in (a) because it keeps JavaScript out of the HTML document. Option (c) uses the W3C's standard method, but does not work in Internet Explorer.
=== Exercises ===
If you want to gain more experience creating cross-browser scripts, try the following exercises:
* Add several check boxes to the HTML document in [Listing 15.2], and add the corresponding function calls to the script in [15.3] to replace all of them with graphic check boxes.
* Modify the script in [Listing 15.3] to convert all check boxes with a <code>class</code> value of <code>graphic</code> into graphic check boxes. You can use <code>getElementsByTagName()</code> and then check each item for the right <code>className</code> property.
nkbwk92bdp57no1umbjqe3znpnkoe5d
User:Bartlett/01
2
2104
39211
5516
2026-04-13T06:03:13Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39211
wikitext
text/x-wiki
= Hour 1. Understanding CSS =
; What You'll Learn in This Hour:
* What style sheets are and what the term "cascading" refers to
* How the Cascading Style Sheets standard was written and what the two levels of CSS refer to
* How CSS is used with HTML and XML and when to use it
* The types of style effects you can produce with CSS and what you can't do
* How browser support for CSS affects what you can do with style sheets
Cascading Style Sheets (CSS) can open up a whole new dimension to your web designs, delivering power and flexibility beyond what's available in plain HTML.
== What Are Cascading Style Sheets? ==
Cascading Style Sheets is the name of a simple language that enables you to declare how documents are displayed by web browsers. This language is used extensively on the Web and can be applied to HTML as well as to newer XML-based languages.
Through the application of CSS, you're able to change many aspects of how a web page is displayed—the fonts, the colors, the layout, the graphics, the links, and more. Cascading Style Sheets enable content—your HTML markup, text, graphics, and multimedia—to be separated from presentation.
=== Defining Style Sheets ===
The concept of style sheets did not originate on the Web; it has been used extensively in computing for years now. The most familiar application of style sheets off the Web is the formatting styles used in word processors, such as Microsoft Word.
Microsoft Word allows you to assign parts of your file to specific styles, such as "Heading" or "Note," and then decide what sort of formatting should be applied to each style. For example, a Heading style should be larger and bold, with extra line spacing after the heading and in a specific heading font. This book, in fact, was composed in exactly that way; each part of the book, from headings to text paragraphs to tips and notes, has a specific style that I set as I composed the manuscript, and those styles eventually determined how you see the printed page today.
In the same way, Cascading Style Sheets let you, the web designer, assign specific styles to different types of HTML elements. You might want to make all your text one color, to make all your headings a specific font, and to specify that all notes should be centered in a box with a thin outline. You can do some of this in HTML by using <code></code> tags and various attributes, but that can get cumbersome and difficult to maintain. When you define your presentation styles in CSS, it becomes quick and easy to apply new styles that can affect all styles on a page or even the whole site—without editing the source HTML at all!
=== Defining Cascading ===
The term cascading in Cascading Style Sheets refers to a specific way in which browsers determine which styles to apply to a specific part of the page. This method is called "the cascade," and it's from the cascade that CSS takes its name.
When I'm designing something that I know is going to be used in a fixed medium, such as the printed page or this book, I can be pretty confident that the styles that I choose will show up exactly like I expect them to. All copies of this book will look exactly the same; the page layout won't vary from reader to reader, and the same fonts will appear in each copy. Page 57 of your copy of this book is identical to every other page 57 in existence.
When you're designing for a variable medium such as the Web, however, you don't have that certainty. The appearance of a web page (designed with CSS or not) depends on a number of factors, including the characteristics of the user's display device, his computer's color resolution, the version of the browser he's using, and even his preferred font size.
;Did you Know?: Some users might not even be using monitors at all! People with visual disabilities routinely use the Web as a primary source of information, relying on software known as screen readers, which vocalize the content of a page. You'll learn more about how CSS benefits users with disabilities in [Hour 22], "Accessibility and Print Media"; you can also read more at the International Center for Disability Resources on the Internet website at [http://www.icdri.org/ http://www.icdri.org/].
This lack of absolute control over the final presentation can be somewhat disconcerting for designers who are used to fixed mediums; how can you fine-tune your design if you don't know how it will eventually look? It's important to keep in mind that this isn't a design flaw in CSS—it's a deliberate feature. Creating designs that adapt to the user's environment and preferences widens your audience and enables more people to access your content.
The cascade is the set of principles that tells browsers how to merge together a number of presentation choices: the web developer's designs for the site, the web browser's capabilities and default settings, and the web user's preferences or requirements for display. In the cascade, items that are higher up in priority affect other properties with lower priorities, with the values "cascading" down like a waterfall. You'll learn more about this in [Hour 7], "Cascading and Inheritance," but for now it's enough to understand that in CSS, the final presentation is an active collaboration between designer, browser, and user.
== The Origin of Cascading Style Sheets ==
The Cascading Style Sheets language was created through a collaborative effort between web developers and browser programmers under the auspices of the World Wide Web Consortium (W3C for short).
The W3C is an international industry group, comprising hundreds of companies, research institutions, and web development organizations, that issues technical specifications for web languages and protocols.
W3C specifications are called recommendations because the W3C is technically not a standards-issuing organization, but in practice this is usually an issue of semantics. W3C recommendations are taken as defining a standard form of a web language, and they are used by web developers, software tool creators, browser programmers, and others as a blueprint for computer communication over the Web. Examples of W3C recommendations include Hypertext Markup Language (HTML), Extensible Markup Language (XML), Extensible Stylesheet Language (XSL), and Scalable Vector Graphics (SVG).
=== The CSS Specifications ===
The W3C recommendations issued by the Cascading Style Sheet working group are collectively the official specification for the CSS language. The CSS working group consists of a number of experts in web development, graphic design, and software programming, representing a number of companies, who all work together to establish a common styling language for the Web.
Two full recommendations have been issued for Cascading Style Sheets so far; these are called Cascading Style Sheets Level 1 (CSS1) and Cascading Style Sheets Level 2 (CSS2). An update to CSS2, CSS 2.1, has been drafted and is gaining acceptance. Work is under way currently on Cascading Style Sheets Level 3, but these are only draft proposals at the time of writing.
=== CSS Level 1 ===
The Cascading Style Sheets Level 1 (sometimes called CSS1 for short) specification was officially issued as a W3C recommendation in December 1996. The URL for this specification is [http://www.w3.org/TR/REC-CSS1 http://www.w3.org/TR/REC-CSS1].
Did you Know?
If you try to read the W3C recommendation for CSS1, you may end up confused. That's because W3C documents aren't written as a general introduction to a subject but rather as precise language definitions for software developers. Most W3C recommendations are quite opaque to most normal people, although the CSS1 specification isn't too bad compared with some. Later in this hour I'll give some tips on how to read a W3C recommendation if you need to dive into it.
CSS Level 1 defines a number of simple text formatting properties, along with properties for colors, fonts and boxes, principles of the cascade, and the linking mechanism between CSS and HTML. CSS1 may be used to create some impressive results, but it doesn't deliver the full range of function found in CSS Level 2.
=== CSS Level 2 ===
CSS Level 2 was published in May 1998 (at [http://www.w3.org/TR/REC-CSS2 http://www.w3.org/TR/REC-CSS2]) and extends the power of CSS considerably. CSS Level 2 enables the web developer to use CSS to lay out a page, replacing HTML tables; to create style sheets for specific output devices, such as printers or even Braille devices; to have fine control over which parts of the page receive styling; and to designate a wider range of effects, such as text shadows or downloadable fonts. CSS Level 2 includes and extends all properties and values defined in CSS Level 1.
=== CSS Level 2.1 ===
The W3C published a working draft in June 2005 called Cascading Style Sheets, Level 2 Revision 1 ([http://www.w3.org/TR/CSS21 http://www.w3.org/TR/CSS21]), more commonly known as CSS 2.1 This update to the CSS2 specification is not yet a formal W3C recommendation, but was written to reflect a snapshot of the current state of CSS implementation in browsers. CSS properties and values that were not widely supported by the browsers were cut from the specification, a few widely supported values were added, and various problems in the definition of the CSS language were fixed.
CSS 2.1 has been adopted as a de facto standard, if only because it gives a good approximation of the most workable features in CSS2. Generally speaking, nearly all CSS 2.1 style sheets should work properly in the newest versions of the major browsers, and most web developers are writing in CSS 2.1 (even if they haven't read the official specification). For those reasons, this book focuses on CSS 2.1 when there is a conflict between the CSS2 and CSS 2.1 languages; CSS 2.1 is the safer, saner version.
=== Other Style Languages ===
CSS isn't the only style language, but it's the primary one used on the Web. Some other style languages include Document Style Semantics and Specification Language (DSSSL) and Extensible Stylesheet Language (XSL).
DSSSL is an older and more complex styling language developed for Standard Generalized Markup Language (SGML), an ancestor of XML and the basis for HTML syntax. DSSSL is rarely used on the Web, just as other SGML technologies (besides HTML) are extremely uncommon.
XSL is a group of related languages intended for styling XML documents. XSL Transformations (XSLT) is a method to describe a transformation from one XML-based language to another. XSL Formatting Objects (XSL-FO) is one such language; an XML document can be converted to XSL-FO with XSLT. XSL-FO files contain XML formatting objects, which can be used by browsers or printing software to lay out the appearance of a document precisely, most commonly for print media.
== CSS in Web Design ==
Because the Cascading Style Sheets language was designed to be used primarily with HTML, CSS is ideally suited for use in web design. The language is simple and flexible enough to encompass all common web presentation effects, and the concepts should be familiar to anyone who has used HTML before. To use the CSS language effectively, it's important to understand how it's used, what it can do, and what it can't do.
=== How CSS Is Used ===
In CSS, the term style sheet refers to a file consisting of a number of CSS rules. A rule is the smallest unit of CSS, defining one or more style effects. Each rule identifies which parts of the web page it selects and what properties it applies to that section of the page. The web document then links to that style sheet, which means the browser downloads the style sheet and applies the rules when it displays the web page. A single CSS file can be linked to by any number of documents, so one style sheet can control the look of the entire site or a portion thereof.
CSS can be used with several different markup languages, including HTML and XML-based languages.
=== CSS and HTML ===
The Hypertext Markup Language (HTML) consists of a series of tags that mark up specific elements within a document. Each of those elements has a default presentation style, which is provided by the browser, based on the formal specification for HTML. You can apply a style sheet to an HTML page by linking to it or even by including the style sheet within the HTML file, and the presentation style for each element can be redefined.
A hypothetical style sheet can be created that states that all <code><nowiki><h1></nowiki></code> tags should be presented on a green background with white text, and all <code><nowiki><p></nowiki></code> tags should be indented 25 pixels and the text justified. This would change the appearance of any web page that links to that style sheet.
HTML pages can contain attributes and tags that set presentational styles, but their versatility and utility are limited compared with CSS. Style sheets can be used either in conjunction with HTML presentational markup, such as <code><nowiki><font></nowiki></code> or <code>color="red"</code> attributes, or can replace presentational tags and attributes entirely.
For example, CSS is used extensively to define the colors, look, and layout of this book's author's personal site ([http://kynn.com/ http://kynn.com/]). In [Figure 1.1], no style sheet has been applied to the site, and so the appearance is quite plain. No HTML attributes have been used for formatting because the site relies on Cascading Style Sheets for presentation effects. The fonts are all browser defaults and the colors are very basic. Despite the somewhat boring appearance, all information is clearly visible and the page can be used easily. All that it needs is a style sheet to make it look better.
[Figure 1.2] is the author's site as it appears in a browser that understands Cascading Style Sheets. The style sheet not only specifies more attractive fonts for the page, but it also reformats the navigation bar, lays out the page in columns, and aligns the content attractively. The overall effect of the style sheet is to enhance the appearance considerably, making the site appear more friendly, identifiable, and usable.
What does CSS look like? In [Figure 1.3] you can see an example of the CSS "source code" used to style the web page in [Figure 1.2]. As you can see, the CSS language is very different in form and syntax from HTML.
=== CSS and XML ===
Cascading Style Sheets are also designed to work with Extensible Markup Language (XML). XML languages often don't have an inherent presentation defined, and CSS files can be applied directly to XML files to add presentational styling.
;By the Way: For most of this book, I'm going to assume you're using CSS with HTML. The techniques for using CSS with XML are pretty much the same as using CSS with HTML. Specific issues related to XML are covered in Bonus Web [Hour 2], "CSS and XML," available on this book's website (described in the Introduction).
=== What CSS Can Do ===
As you see on the author's site, the application of a style sheet can drastically change the appearance of an HTML page. CSS can be used to change anything from text styling to page layout, and can be combined with JavaScript to produce dynamic presentation effects.
=== Text Formatting and Colors ===
CSS can be used to produce a number of text effects, such as
* Choosing specific fonts and font sizes
* Setting bold, italics, underlines, and text shadows
* Changing text color and background color
* Changing the colors of links or removing underlining
* Indenting or centering text
* Stretching and adjusting text size and line spacing
* Transforming sections of text to upper-, lower-, or mixed case
* Adding drop-capitals and other special effects
These are all accomplished by creating CSS rules to set properties on text.
=== Graphical Appearance and Layout ===
CSS can also be used to change the look of the entire page. CSS properties for positioning—sometimes called CSS-P—were introduced in CSS Level 2 and enable you to format a web page without using tables. Some of the things you can do with CSS to affect the graphical layout of the page include
* Setting a background graphic, controlling its location, tiling, and scrolling
* Drawing borders and outlines around sections of a page
* Setting vertical and horizontal margins on all elements, as well as vertical and horizontal padding
* Flowing text around images, or even around other text
* Positioning sections of the page in precise locations on the virtual canvas
* Redefining how HTML tables, forms, and lists are presented
* Layering page elements atop each other in a specified order
=== Dynamic Actions ===
Dynamic effects in web design are those that are interactive, changing in response to being used. CSS lets you create interactive designs that respond to the user, such as
* Mouseover effects on links
* Dynamically inserted content before or after HTML tags
* Automatic numbering of page elements
* Fully interactive designs in Dynamic HTML (DHTML) and Asynchronous JavaScript and XML (AJAX)
=== What CSS Can't Do ===
Although CSS is powerful, it does have certain limitations. The primary limitation of CSS is that it is restricted to working mainly with only what is present in the markup file. The display order can be somewhat altered, and a small amount of text content can be inserted, but to produce major changes in the source HTML (or XML), you need to use another method—such as XSL Transformations (XSLT).
Also, CSS is a younger language than HTML by about five years; this means that some of the oldest browsers don't understand styles written in CSS, or might not load a style sheet at all. CSS is also of limited use on simple text browsers, such as those written for cell phones or mobile devices.
The Cascading Style Sheets language was designed to be backwards compatible, which means older browsers don't refuse to show your web page if they aren't able to display your styles. Instead, the default HTML presentation is used, and if you've designed your CSS and HTML properly, the page content is usable even if your CSS styles aren't shown. This allows older browsers to access even advanced CSS pages.
=== When to Use CSS ===
After you start learning to create Cascading Style Sheets, you probably will never want to stop using them! You can start using CSS today, as a supplement to your presentational markup, and then gradually move toward purer CSS presentations as you learn more.
=== Reading W3C Specifications ===
You may find yourself referring to the CSS recommendations from time to time—as well as the HTML and XHTML specifications as well. As they define the language, a specification is considered the definitive source for that language. After you get the hang of reading the CSS 2.1 specification, it makes a useful reference—but there's a learning curve.
A W3C recommendation is different from most other types of technical writing. Most technical works you're familiar with, from user manuals to books like this one, are written as documentation. Documentation is a user resource, something that helps you understand how to use a program or language. Tutorials, reference works, and textbooks are all written with that goal.
Standards, including the de facto standards of W3C recommendations, are written differently. The purpose of a standards document is to be definitive. A specification explicitly defines what is contained within a given set of technology. The key to comprehending a spec is not only understanding how it is organized but also understanding the intended audience and use of the specification.
In nearly all cases, the intended audience of a W3C specification is not you. It's not web developers, even though the languages defined by these specs are written for use by web developers. As a web developer, you'll definitely be able to gain useful knowledge from the W3C's recommendations, but that's just an ancillary effect.
[Figure 1.4] is an example—this is part of the CSS 2.1 specification; specifically, the part that defines a property called <code>clip</code>. Does this make sense to you? Probably not, because it's full of technical jargon, links to other parts of the specification, and advice on whether or not any "user agents" (browsers) must support a given feature.
The real audience for W3C recommendations is the software developers who create programs that use the protocols and languages in the specs. The CSS 2.1 specification, for example, was written primarily for implementers at Microsoft, Opera, Mozilla, Apple, and other software companies producing web-related software. In other words, people who already have a basic understanding of what the language does, and how other languages work with it.
One consequence of being written for those already in the know is that the W3C specifications aren't written linearly but circularly. To make sense of what's written in section two, you need to have read not only section one, but also sections three, four, and five, plus the appendix and about a half dozen related specifications. For a definitive work, that's actually quite appropriate; you can't read a dictionary straight through, either, and all terms in a dictionary are defined with other dictionary terms. W3C recommendations are written in the same manner, so you'll probably have to read through several times—following hyperlinks instead of just proceeding linearly—to fully grasp everything.
To approach a W3C recommendation, first understand the structure of the document. Nearly all are written with the same general outline. The first part of the structure looks like a bit of legalistic fluff, but is actually quite important; it identifies when the document was written and what status it holds in the W3C's hierarchy of technical recommendations. The W3C Process is a procedure for moving a working group's documents from draft to officially approved recommendation, and there are a number of steps along the way. The status of the document is stated at the very beginning.
A short introduction usually follows, which states the purpose of the recommendation. A glossary of terms might be provided at the front, but most commonly it is at the end; read it before the main content so you'll recognize the terms, even if they don't make sense until you've read more. Also at the end you'll find a list of references; W3C documents don't usually link directly to other sources but instead link to their reference lists. These references include the links out to other materials you can find on the Web, many of which are essential to making sense of what you're reading.
The main content is in the middle, of course, and is usually divided into sensible categories, although if you start following links within a recommendation, you'll find yourself skipping randomly through the text, which can be disorienting. The best W3C recommendations have small menu bars at the top that allow you to page between sections or, more usefully, to jump directly to an alphabetized table listing all elements, attributes, or properties. The index at the back of a long recommendation also proves invaluable when navigating the structure of the W3C specification.
== Browser Support ==
Unfortunately for those of us who want to reap the full benefits of using CSS, the browser manufacturers were slow in providing support for CSS in their software. This meant that people who programmed authoring software didn't bother to produce CSS (after all, which browsers could display it?) and web developers didn't bother to learn CSS because it was a pointless exercise.
Early browsers that understood Cascading Style Sheets, such as Internet Explorer 3 and Netscape 4, had only incomplete implementations, meaning that even simple style sheets using rules defined in CSS1 might not have displayed consistently. This meant that CSS was considered unreliable for several years after the recommendations were issued.
Thankfully, the Dark Age of CSS didn't last forever, and current browsers have decent support for the CSS standards. Recent versions of Firefox, Internet Explorer, Opera, and Safari all have good implementations of the Cascading Style Sheet specifications. We're entering a new age of CSS, one where you can design safely and confidently, knowing that your style sheet won't confuse some old browser with buggy CSS implementations.
=== Workarounds for Browser Limitations ===
However, some older browsers still exist and are used by a number of web surfers, despite the poor and quirky support for CSS—most notably Internet Explorer versions 5, 5.5, and 6. Furthermore, not even the newest browsers adhere 100% to the specifications, although they come very close. In [Hour 3], "Browser Support for CSS," you'll learn more about what some of those limitations may be.
For these reasons, it may be necessary to employ workarounds or browser hacks in your CSS or HTML to ensure that your style effects come through as intended. These are described in [Hour 24], "Troubleshooting and Browser Hacks," and specific implementation problems are mentioned throughout the book when you need to know about them.
== Summary ==
Cascading Style Sheets are files that describe how to present specific effects when displaying a web page. They're so named because they follow a specific pattern, called the cascade, which determines the order in which style effects are applied. The CSS language is a web standard, defined by the World Wide Web Consortium; the current version is CSS Level 2, updated by CSS 2.1.
A style sheet consists of CSS rules that define styles to apply to specific parts of the page. Style rules can change the color, font, and other qualities of the text of a page; they can define the layout and graphical appearance; and they can add interactivity to a site.
Although Cascading Style Sheets are quite powerful and useful, care needs to be taken to apply them in ways consistent with current browser implementations. Not all browsers have good CSS support, and using CSS without understanding the support issues can lead to problems if you're not careful.
== Workshop ==
This workshop contains a Q&A section and quiz questions to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
=== Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q.'''
| Which version of CSS should I use?
|-
| align="right" | ''' A.'''
| Cascading Style Sheets Level 2 is the most current W3C recommendation; it contains all the CSS1 properties and gives more complete definitions for them, in addition to defining new properties that weren't included in CSS1. Very few browsers (if any) supported only CSS1; most of them supported either a subset of CSS1 or a set chosen from CSS1 and CSS2 properties, so the division between the two is not really meaningful when you look at browser support. Because CSS 2.1 updates CSS2 to fix some problematic definitions and remove unimplemented property values, CSS 2.1 is your best bet for current and future compatibility. However, there are still implementation problems even with CSS 2.1, and so you have to test all your style sheets on a wide variety browsers.
|-
| align="right" | '''Q.'''
| So what's so cool about CSS anyway?
|-
| align="right" | ''' A.'''
| Because Cascading Style Sheets let you encode your style effects separately from your HTML, this promotes separation of presentation and content. That means that the look of the page is independent from the information on the page, and that's cool for a number of reasons. You can create a single style sheet that styles the entire site at once. You can develop alternate style sheets for specific output devices, such as printers. You can ensure greater accessibility for people with disabilities. In addition, Cascading Style Sheets also afford a measure of control over the presentation, which simply is not available in traditional HTML web design.
|-
| align="right" | '''Q.'''
| What's the most important thing to know about Cascading Style Sheets?
|-
| align="right" | '''A.'''
| Browser support is the critical issue in CSS design. You will see this theme repeated throughout the book. Lack of browser support has seriously hindered the use of CSS, and many of the really great things you can do with style sheets continue to be limited in many browsers. Fortunately, the browser companies are working hard to improve their programs, and are getting ever closer to full, correct implementation of the CSS specifications.
|}
=== Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| What is the cascade in CSS?
|-
| align="right" | '''2.'''
| Which markup languages can be used with CSS?
|-
| align="right" | '''3.'''
| What's the current version of Cascading Style Sheets?
|}
=== Answers===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| The cascade is the set of rules that order how style preferences are combined together. The effects of higher-priority rules cascade down like a waterfall.
|-
| align="right" | '''2.'''
| CSS was designed to work with HTML as well as with any XML-based markup language.
|-
| align="right" | '''3.'''
| The current version of Cascading Style Sheets is CSS Level 2, updated by the CSS 2.1 draft.
|}
8w8un1u4dldr2ithqqv7yrclnbh0ypw
39283
39211
2026-04-13T06:05:06Z
Redmin
5511
Restoring removed markup mistakenly removed by my bot
39283
wikitext
text/x-wiki
= Hour 1. Understanding CSS =
; What You'll Learn in This Hour:
* What style sheets are and what the term "cascading" refers to
* How the Cascading Style Sheets standard was written and what the two levels of CSS refer to
* How CSS is used with HTML and XML and when to use it
* The types of style effects you can produce with CSS and what you can't do
* How browser support for CSS affects what you can do with style sheets
Cascading Style Sheets (CSS) can open up a whole new dimension to your web designs, delivering power and flexibility beyond what's available in plain HTML.
== What Are Cascading Style Sheets? ==
Cascading Style Sheets is the name of a simple language that enables you to declare how documents are displayed by web browsers. This language is used extensively on the Web and can be applied to HTML as well as to newer XML-based languages.
Through the application of CSS, you're able to change many aspects of how a web page is displayed—the fonts, the colors, the layout, the graphics, the links, and more. Cascading Style Sheets enable content—your HTML markup, text, graphics, and multimedia—to be separated from presentation.
=== Defining Style Sheets ===
The concept of style sheets did not originate on the Web; it has been used extensively in computing for years now. The most familiar application of style sheets off the Web is the formatting styles used in word processors, such as Microsoft Word.
Microsoft Word allows you to assign parts of your file to specific styles, such as "Heading" or "Note," and then decide what sort of formatting should be applied to each style. For example, a Heading style should be larger and bold, with extra line spacing after the heading and in a specific heading font. This book, in fact, was composed in exactly that way; each part of the book, from headings to text paragraphs to tips and notes, has a specific style that I set as I composed the manuscript, and those styles eventually determined how you see the printed page today.
In the same way, Cascading Style Sheets let you, the web designer, assign specific styles to different types of HTML elements. You might want to make all your text one color, to make all your headings a specific font, and to specify that all notes should be centered in a box with a thin outline. You can do some of this in HTML by using <code><font></code> tags and various attributes, but that can get cumbersome and difficult to maintain. When you define your presentation styles in CSS, it becomes quick and easy to apply new styles that can affect all styles on a page or even the whole site—without editing the source HTML at all!
=== Defining Cascading ===
The term cascading in Cascading Style Sheets refers to a specific way in which browsers determine which styles to apply to a specific part of the page. This method is called "the cascade," and it's from the cascade that CSS takes its name.
When I'm designing something that I know is going to be used in a fixed medium, such as the printed page or this book, I can be pretty confident that the styles that I choose will show up exactly like I expect them to. All copies of this book will look exactly the same; the page layout won't vary from reader to reader, and the same fonts will appear in each copy. Page 57 of your copy of this book is identical to every other page 57 in existence.
When you're designing for a variable medium such as the Web, however, you don't have that certainty. The appearance of a web page (designed with CSS or not) depends on a number of factors, including the characteristics of the user's display device, his computer's color resolution, the version of the browser he's using, and even his preferred font size.
;Did you Know?: Some users might not even be using monitors at all! People with visual disabilities routinely use the Web as a primary source of information, relying on software known as screen readers, which vocalize the content of a page. You'll learn more about how CSS benefits users with disabilities in [Hour 22], "Accessibility and Print Media"; you can also read more at the International Center for Disability Resources on the Internet website at [http://www.icdri.org/ http://www.icdri.org/].
This lack of absolute control over the final presentation can be somewhat disconcerting for designers who are used to fixed mediums; how can you fine-tune your design if you don't know how it will eventually look? It's important to keep in mind that this isn't a design flaw in CSS—it's a deliberate feature. Creating designs that adapt to the user's environment and preferences widens your audience and enables more people to access your content.
The cascade is the set of principles that tells browsers how to merge together a number of presentation choices: the web developer's designs for the site, the web browser's capabilities and default settings, and the web user's preferences or requirements for display. In the cascade, items that are higher up in priority affect other properties with lower priorities, with the values "cascading" down like a waterfall. You'll learn more about this in [Hour 7], "Cascading and Inheritance," but for now it's enough to understand that in CSS, the final presentation is an active collaboration between designer, browser, and user.
== The Origin of Cascading Style Sheets ==
The Cascading Style Sheets language was created through a collaborative effort between web developers and browser programmers under the auspices of the World Wide Web Consortium (W3C for short).
The W3C is an international industry group, comprising hundreds of companies, research institutions, and web development organizations, that issues technical specifications for web languages and protocols.
W3C specifications are called recommendations because the W3C is technically not a standards-issuing organization, but in practice this is usually an issue of semantics. W3C recommendations are taken as defining a standard form of a web language, and they are used by web developers, software tool creators, browser programmers, and others as a blueprint for computer communication over the Web. Examples of W3C recommendations include Hypertext Markup Language (HTML), Extensible Markup Language (XML), Extensible Stylesheet Language (XSL), and Scalable Vector Graphics (SVG).
=== The CSS Specifications ===
The W3C recommendations issued by the Cascading Style Sheet working group are collectively the official specification for the CSS language. The CSS working group consists of a number of experts in web development, graphic design, and software programming, representing a number of companies, who all work together to establish a common styling language for the Web.
Two full recommendations have been issued for Cascading Style Sheets so far; these are called Cascading Style Sheets Level 1 (CSS1) and Cascading Style Sheets Level 2 (CSS2). An update to CSS2, CSS 2.1, has been drafted and is gaining acceptance. Work is under way currently on Cascading Style Sheets Level 3, but these are only draft proposals at the time of writing.
=== CSS Level 1 ===
The Cascading Style Sheets Level 1 (sometimes called CSS1 for short) specification was officially issued as a W3C recommendation in December 1996. The URL for this specification is [http://www.w3.org/TR/REC-CSS1 http://www.w3.org/TR/REC-CSS1].
Did you Know?
If you try to read the W3C recommendation for CSS1, you may end up confused. That's because W3C documents aren't written as a general introduction to a subject but rather as precise language definitions for software developers. Most W3C recommendations are quite opaque to most normal people, although the CSS1 specification isn't too bad compared with some. Later in this hour I'll give some tips on how to read a W3C recommendation if you need to dive into it.
CSS Level 1 defines a number of simple text formatting properties, along with properties for colors, fonts and boxes, principles of the cascade, and the linking mechanism between CSS and HTML. CSS1 may be used to create some impressive results, but it doesn't deliver the full range of function found in CSS Level 2.
=== CSS Level 2 ===
CSS Level 2 was published in May 1998 (at [http://www.w3.org/TR/REC-CSS2 http://www.w3.org/TR/REC-CSS2]) and extends the power of CSS considerably. CSS Level 2 enables the web developer to use CSS to lay out a page, replacing HTML tables; to create style sheets for specific output devices, such as printers or even Braille devices; to have fine control over which parts of the page receive styling; and to designate a wider range of effects, such as text shadows or downloadable fonts. CSS Level 2 includes and extends all properties and values defined in CSS Level 1.
=== CSS Level 2.1 ===
The W3C published a working draft in June 2005 called Cascading Style Sheets, Level 2 Revision 1 ([http://www.w3.org/TR/CSS21 http://www.w3.org/TR/CSS21]), more commonly known as CSS 2.1 This update to the CSS2 specification is not yet a formal W3C recommendation, but was written to reflect a snapshot of the current state of CSS implementation in browsers. CSS properties and values that were not widely supported by the browsers were cut from the specification, a few widely supported values were added, and various problems in the definition of the CSS language were fixed.
CSS 2.1 has been adopted as a de facto standard, if only because it gives a good approximation of the most workable features in CSS2. Generally speaking, nearly all CSS 2.1 style sheets should work properly in the newest versions of the major browsers, and most web developers are writing in CSS 2.1 (even if they haven't read the official specification). For those reasons, this book focuses on CSS 2.1 when there is a conflict between the CSS2 and CSS 2.1 languages; CSS 2.1 is the safer, saner version.
=== Other Style Languages ===
CSS isn't the only style language, but it's the primary one used on the Web. Some other style languages include Document Style Semantics and Specification Language (DSSSL) and Extensible Stylesheet Language (XSL).
DSSSL is an older and more complex styling language developed for Standard Generalized Markup Language (SGML), an ancestor of XML and the basis for HTML syntax. DSSSL is rarely used on the Web, just as other SGML technologies (besides HTML) are extremely uncommon.
XSL is a group of related languages intended for styling XML documents. XSL Transformations (XSLT) is a method to describe a transformation from one XML-based language to another. XSL Formatting Objects (XSL-FO) is one such language; an XML document can be converted to XSL-FO with XSLT. XSL-FO files contain XML formatting objects, which can be used by browsers or printing software to lay out the appearance of a document precisely, most commonly for print media.
== CSS in Web Design ==
Because the Cascading Style Sheets language was designed to be used primarily with HTML, CSS is ideally suited for use in web design. The language is simple and flexible enough to encompass all common web presentation effects, and the concepts should be familiar to anyone who has used HTML before. To use the CSS language effectively, it's important to understand how it's used, what it can do, and what it can't do.
=== How CSS Is Used ===
In CSS, the term style sheet refers to a file consisting of a number of CSS rules. A rule is the smallest unit of CSS, defining one or more style effects. Each rule identifies which parts of the web page it selects and what properties it applies to that section of the page. The web document then links to that style sheet, which means the browser downloads the style sheet and applies the rules when it displays the web page. A single CSS file can be linked to by any number of documents, so one style sheet can control the look of the entire site or a portion thereof.
CSS can be used with several different markup languages, including HTML and XML-based languages.
=== CSS and HTML ===
The Hypertext Markup Language (HTML) consists of a series of tags that mark up specific elements within a document. Each of those elements has a default presentation style, which is provided by the browser, based on the formal specification for HTML. You can apply a style sheet to an HTML page by linking to it or even by including the style sheet within the HTML file, and the presentation style for each element can be redefined.
A hypothetical style sheet can be created that states that all <code><nowiki><h1></nowiki></code> tags should be presented on a green background with white text, and all <code><nowiki><p></nowiki></code> tags should be indented 25 pixels and the text justified. This would change the appearance of any web page that links to that style sheet.
HTML pages can contain attributes and tags that set presentational styles, but their versatility and utility are limited compared with CSS. Style sheets can be used either in conjunction with HTML presentational markup, such as <code><nowiki><font></nowiki></code> or <code>color="red"</code> attributes, or can replace presentational tags and attributes entirely.
For example, CSS is used extensively to define the colors, look, and layout of this book's author's personal site ([http://kynn.com/ http://kynn.com/]). In [Figure 1.1], no style sheet has been applied to the site, and so the appearance is quite plain. No HTML attributes have been used for formatting because the site relies on Cascading Style Sheets for presentation effects. The fonts are all browser defaults and the colors are very basic. Despite the somewhat boring appearance, all information is clearly visible and the page can be used easily. All that it needs is a style sheet to make it look better.
[Figure 1.2] is the author's site as it appears in a browser that understands Cascading Style Sheets. The style sheet not only specifies more attractive fonts for the page, but it also reformats the navigation bar, lays out the page in columns, and aligns the content attractively. The overall effect of the style sheet is to enhance the appearance considerably, making the site appear more friendly, identifiable, and usable.
What does CSS look like? In [Figure 1.3] you can see an example of the CSS "source code" used to style the web page in [Figure 1.2]. As you can see, the CSS language is very different in form and syntax from HTML.
=== CSS and XML ===
Cascading Style Sheets are also designed to work with Extensible Markup Language (XML). XML languages often don't have an inherent presentation defined, and CSS files can be applied directly to XML files to add presentational styling.
;By the Way: For most of this book, I'm going to assume you're using CSS with HTML. The techniques for using CSS with XML are pretty much the same as using CSS with HTML. Specific issues related to XML are covered in Bonus Web [Hour 2], "CSS and XML," available on this book's website (described in the Introduction).
=== What CSS Can Do ===
As you see on the author's site, the application of a style sheet can drastically change the appearance of an HTML page. CSS can be used to change anything from text styling to page layout, and can be combined with JavaScript to produce dynamic presentation effects.
=== Text Formatting and Colors ===
CSS can be used to produce a number of text effects, such as
* Choosing specific fonts and font sizes
* Setting bold, italics, underlines, and text shadows
* Changing text color and background color
* Changing the colors of links or removing underlining
* Indenting or centering text
* Stretching and adjusting text size and line spacing
* Transforming sections of text to upper-, lower-, or mixed case
* Adding drop-capitals and other special effects
These are all accomplished by creating CSS rules to set properties on text.
=== Graphical Appearance and Layout ===
CSS can also be used to change the look of the entire page. CSS properties for positioning—sometimes called CSS-P—were introduced in CSS Level 2 and enable you to format a web page without using tables. Some of the things you can do with CSS to affect the graphical layout of the page include
* Setting a background graphic, controlling its location, tiling, and scrolling
* Drawing borders and outlines around sections of a page
* Setting vertical and horizontal margins on all elements, as well as vertical and horizontal padding
* Flowing text around images, or even around other text
* Positioning sections of the page in precise locations on the virtual canvas
* Redefining how HTML tables, forms, and lists are presented
* Layering page elements atop each other in a specified order
=== Dynamic Actions ===
Dynamic effects in web design are those that are interactive, changing in response to being used. CSS lets you create interactive designs that respond to the user, such as
* Mouseover effects on links
* Dynamically inserted content before or after HTML tags
* Automatic numbering of page elements
* Fully interactive designs in Dynamic HTML (DHTML) and Asynchronous JavaScript and XML (AJAX)
=== What CSS Can't Do ===
Although CSS is powerful, it does have certain limitations. The primary limitation of CSS is that it is restricted to working mainly with only what is present in the markup file. The display order can be somewhat altered, and a small amount of text content can be inserted, but to produce major changes in the source HTML (or XML), you need to use another method—such as XSL Transformations (XSLT).
Also, CSS is a younger language than HTML by about five years; this means that some of the oldest browsers don't understand styles written in CSS, or might not load a style sheet at all. CSS is also of limited use on simple text browsers, such as those written for cell phones or mobile devices.
The Cascading Style Sheets language was designed to be backwards compatible, which means older browsers don't refuse to show your web page if they aren't able to display your styles. Instead, the default HTML presentation is used, and if you've designed your CSS and HTML properly, the page content is usable even if your CSS styles aren't shown. This allows older browsers to access even advanced CSS pages.
=== When to Use CSS ===
After you start learning to create Cascading Style Sheets, you probably will never want to stop using them! You can start using CSS today, as a supplement to your presentational markup, and then gradually move toward purer CSS presentations as you learn more.
=== Reading W3C Specifications ===
You may find yourself referring to the CSS recommendations from time to time—as well as the HTML and XHTML specifications as well. As they define the language, a specification is considered the definitive source for that language. After you get the hang of reading the CSS 2.1 specification, it makes a useful reference—but there's a learning curve.
A W3C recommendation is different from most other types of technical writing. Most technical works you're familiar with, from user manuals to books like this one, are written as documentation. Documentation is a user resource, something that helps you understand how to use a program or language. Tutorials, reference works, and textbooks are all written with that goal.
Standards, including the de facto standards of W3C recommendations, are written differently. The purpose of a standards document is to be definitive. A specification explicitly defines what is contained within a given set of technology. The key to comprehending a spec is not only understanding how it is organized but also understanding the intended audience and use of the specification.
In nearly all cases, the intended audience of a W3C specification is not you. It's not web developers, even though the languages defined by these specs are written for use by web developers. As a web developer, you'll definitely be able to gain useful knowledge from the W3C's recommendations, but that's just an ancillary effect.
[Figure 1.4] is an example—this is part of the CSS 2.1 specification; specifically, the part that defines a property called <code>clip</code>. Does this make sense to you? Probably not, because it's full of technical jargon, links to other parts of the specification, and advice on whether or not any "user agents" (browsers) must support a given feature.
The real audience for W3C recommendations is the software developers who create programs that use the protocols and languages in the specs. The CSS 2.1 specification, for example, was written primarily for implementers at Microsoft, Opera, Mozilla, Apple, and other software companies producing web-related software. In other words, people who already have a basic understanding of what the language does, and how other languages work with it.
One consequence of being written for those already in the know is that the W3C specifications aren't written linearly but circularly. To make sense of what's written in section two, you need to have read not only section one, but also sections three, four, and five, plus the appendix and about a half dozen related specifications. For a definitive work, that's actually quite appropriate; you can't read a dictionary straight through, either, and all terms in a dictionary are defined with other dictionary terms. W3C recommendations are written in the same manner, so you'll probably have to read through several times—following hyperlinks instead of just proceeding linearly—to fully grasp everything.
To approach a W3C recommendation, first understand the structure of the document. Nearly all are written with the same general outline. The first part of the structure looks like a bit of legalistic fluff, but is actually quite important; it identifies when the document was written and what status it holds in the W3C's hierarchy of technical recommendations. The W3C Process is a procedure for moving a working group's documents from draft to officially approved recommendation, and there are a number of steps along the way. The status of the document is stated at the very beginning.
A short introduction usually follows, which states the purpose of the recommendation. A glossary of terms might be provided at the front, but most commonly it is at the end; read it before the main content so you'll recognize the terms, even if they don't make sense until you've read more. Also at the end you'll find a list of references; W3C documents don't usually link directly to other sources but instead link to their reference lists. These references include the links out to other materials you can find on the Web, many of which are essential to making sense of what you're reading.
The main content is in the middle, of course, and is usually divided into sensible categories, although if you start following links within a recommendation, you'll find yourself skipping randomly through the text, which can be disorienting. The best W3C recommendations have small menu bars at the top that allow you to page between sections or, more usefully, to jump directly to an alphabetized table listing all elements, attributes, or properties. The index at the back of a long recommendation also proves invaluable when navigating the structure of the W3C specification.
== Browser Support ==
Unfortunately for those of us who want to reap the full benefits of using CSS, the browser manufacturers were slow in providing support for CSS in their software. This meant that people who programmed authoring software didn't bother to produce CSS (after all, which browsers could display it?) and web developers didn't bother to learn CSS because it was a pointless exercise.
Early browsers that understood Cascading Style Sheets, such as Internet Explorer 3 and Netscape 4, had only incomplete implementations, meaning that even simple style sheets using rules defined in CSS1 might not have displayed consistently. This meant that CSS was considered unreliable for several years after the recommendations were issued.
Thankfully, the Dark Age of CSS didn't last forever, and current browsers have decent support for the CSS standards. Recent versions of Firefox, Internet Explorer, Opera, and Safari all have good implementations of the Cascading Style Sheet specifications. We're entering a new age of CSS, one where you can design safely and confidently, knowing that your style sheet won't confuse some old browser with buggy CSS implementations.
=== Workarounds for Browser Limitations ===
However, some older browsers still exist and are used by a number of web surfers, despite the poor and quirky support for CSS—most notably Internet Explorer versions 5, 5.5, and 6. Furthermore, not even the newest browsers adhere 100% to the specifications, although they come very close. In [Hour 3], "Browser Support for CSS," you'll learn more about what some of those limitations may be.
For these reasons, it may be necessary to employ workarounds or browser hacks in your CSS or HTML to ensure that your style effects come through as intended. These are described in [Hour 24], "Troubleshooting and Browser Hacks," and specific implementation problems are mentioned throughout the book when you need to know about them.
== Summary ==
Cascading Style Sheets are files that describe how to present specific effects when displaying a web page. They're so named because they follow a specific pattern, called the cascade, which determines the order in which style effects are applied. The CSS language is a web standard, defined by the World Wide Web Consortium; the current version is CSS Level 2, updated by CSS 2.1.
A style sheet consists of CSS rules that define styles to apply to specific parts of the page. Style rules can change the color, font, and other qualities of the text of a page; they can define the layout and graphical appearance; and they can add interactivity to a site.
Although Cascading Style Sheets are quite powerful and useful, care needs to be taken to apply them in ways consistent with current browser implementations. Not all browsers have good CSS support, and using CSS without understanding the support issues can lead to problems if you're not careful.
== Workshop ==
This workshop contains a Q&A section and quiz questions to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
=== Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q.'''
| Which version of CSS should I use?
|-
| align="right" | ''' A.'''
| Cascading Style Sheets Level 2 is the most current W3C recommendation; it contains all the CSS1 properties and gives more complete definitions for them, in addition to defining new properties that weren't included in CSS1. Very few browsers (if any) supported only CSS1; most of them supported either a subset of CSS1 or a set chosen from CSS1 and CSS2 properties, so the division between the two is not really meaningful when you look at browser support. Because CSS 2.1 updates CSS2 to fix some problematic definitions and remove unimplemented property values, CSS 2.1 is your best bet for current and future compatibility. However, there are still implementation problems even with CSS 2.1, and so you have to test all your style sheets on a wide variety browsers.
|-
| align="right" | '''Q.'''
| So what's so cool about CSS anyway?
|-
| align="right" | ''' A.'''
| Because Cascading Style Sheets let you encode your style effects separately from your HTML, this promotes separation of presentation and content. That means that the look of the page is independent from the information on the page, and that's cool for a number of reasons. You can create a single style sheet that styles the entire site at once. You can develop alternate style sheets for specific output devices, such as printers. You can ensure greater accessibility for people with disabilities. In addition, Cascading Style Sheets also afford a measure of control over the presentation, which simply is not available in traditional HTML web design.
|-
| align="right" | '''Q.'''
| What's the most important thing to know about Cascading Style Sheets?
|-
| align="right" | '''A.'''
| Browser support is the critical issue in CSS design. You will see this theme repeated throughout the book. Lack of browser support has seriously hindered the use of CSS, and many of the really great things you can do with style sheets continue to be limited in many browsers. Fortunately, the browser companies are working hard to improve their programs, and are getting ever closer to full, correct implementation of the CSS specifications.
|}
=== Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| What is the cascade in CSS?
|-
| align="right" | '''2.'''
| Which markup languages can be used with CSS?
|-
| align="right" | '''3.'''
| What's the current version of Cascading Style Sheets?
|}
=== Answers===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| The cascade is the set of rules that order how style preferences are combined together. The effects of higher-priority rules cascade down like a waterfall.
|-
| align="right" | '''2.'''
| CSS was designed to work with HTML as well as with any XML-based markup language.
|-
| align="right" | '''3.'''
| The current version of Cascading Style Sheets is CSS Level 2, updated by the CSS 2.1 draft.
|}
l85o81toctomc35c3n5vd4r81tor1to
User:Bartlett/02
2
2105
39212
6254
2026-04-13T06:03:14Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39212
wikitext
text/x-wiki
= Hour 2. Getting Started with CSS =
; What You'll Learn in This Hour:
* What kinds of tools, from text editors to CSS software, you can use to write your style sheets
* How to create, name, and save a style sheet
* What the different parts of a CSS rule are and the function of each
* How and when to add comments to a style sheet
* Which simple rules you can use to create a basic style sheet
* How to apply your style sheet to a simple HTML file
* Which browsers to use to test your style sheet
== Creating a Style Sheet ==
A Cascading Style Sheet, as you learned in [Hour 1], "Understanding CSS," is simply a file made up of style rules. CSS files are ordinary text files, just as HTML files are ordinary text files. This means that you can use a wide variety of programs to create a style sheet, from simple text editors to specialized software written just for creating and maintaining style sheets. Anything that can be used to create a text file can create a style sheet.
Because Cascading Style Sheets are pretty simple to write, you don't need to use complex tools to create a basic style sheet. Many web developers will write CSS by hand, meaning that they type out the text of each rule; however, authoring tools exist that can make this task easier.
===Software Tools for CSS ===
Your editing environment is the program or set of programs that you use to create your style sheet. You'll want to choose the editing environment that works best for you, be that a text editor, a style sheet editor, or a web development tool. I use a text editor myself, and I recommend starting simple, at least until you've learned enough about the basics of CSS to understand how editing tools can help you.
===Text Editors ===
Every operating system comes with a basic text editor, and because CSS is just basic text, it's a good match for one of these programs. A text editor is a simple program that just produces plain text files, which means it can also be used to create HTML or CSS files. Unlike word processing software, text editors don't save formatting with the text; that's why they are said to produce plain text. Text editors are ubiquitous and don't get in the way of your learning about CSS, so this is probably where you want to start. You probably already know how to use one of the text editors on your computer. Some basic text editors include
* Notepad or WordPad on Microsoft Windows
* TextEdit on Macintosh
* vi, vim, or emacs on Linux or Unix
[Figure 2.1] shows a style sheet being edited in Notepad on Windows; this is the style sheet from the author's personal website, which was shown in [Hour 1]. Don't worry too much about reading and understanding the properties; the style sheet is rather complex and has a lot of properties from the middle or end of this book.
;Did you Know?: You can use a word processing program, such as Microsoft Word, to create text files, but you need to remember to save your files as plain text without any special formatting. It's probably easier to just use a text editor, although most of them lack the advanced features found in word processors, such as advanced find-and-replace and word counting. Fortunately, you'll rarely need those features when editing CSS.
===Style Sheet Editors ===
Some software has been written specifically to create CSS style sheets; these have advanced features such as color-coding of rules and properties, syntax checking, and more. These are great tools, and I highly recommend them when you're doing serious CSS development; if you're just beginning, though, they may be more than you need right now and could overwhelm you with options. After you understand the principles and language of CSS, however, a style sheet editor is invaluable. Some of the CSS editors available include
* TopStyle, for Windows; [http://www.bradsoft.com/topstyle/ http://www.bradsoft.com/topstyle/]
* Style Master, for Windows and Mac OS X; [http://www.westciv.com/style_master/ http://www.westciv.com/style_master/]
* CSSEdit, for Mac OS X; [http://www.macrabbit.com/cssedit/ http://www.macrabbit.com/cssedit/]
* JustStyle CSS Editor, for all Java-enabled computers; [http://www.ucware.com/juststyle/ http://www.ucware.com/juststyle/]
The screenshot in [Figure 2.2] shows the author's style sheet being edited in Style Master, one of the CSS editors listed here. As you can see, a style sheet editor offers a lot more in the way of development features compared to a simple text editor, but it's also more complex to use.
===HTML Editors and Web Development Software ===
Because CSS is an integral part of web design, web design packages that let you create HTML often support CSS editing. Visual editors let you set styles and create the style sheet behind the scenes, whereas those with source editing modes enable you to edit the style sheet directly. As with CSS editors, I recommend using these after you've become familiar with the basics of CSS syntax. Your favorite web editing environment may already include CSS support; some that do include
* Microsoft FrontPage, for Windows; [http://www.microsoft.com/frontpage/ http://www.microsoft.com/frontpage/]
* Macromedia Dreamweaver, for Windows and Mac OS X; [http://www.macromedia.com/software/dreamweaver/ http://www.macromedia.com/software/dreamweaver/]
* Adobe GoLive, for Windows and Macintosh; [http://www.adobe.com/products/golive/ http://www.adobe.com/products/golive/]
* CoffeeCup HTML Editor, for Windows; [http://www.coffeecup.com/editor/ http://www.coffeecup.com/editor/]
* BBEdit, for Mac OS X; [http://www.barebones.com/products/bbedit/ http://www.barebones.com/products/bbedit/]
=== Naming and Saving a Style Sheet ===
However you edit your style sheet, the basic principle will be the same: You create a text file that contains the CSS rules, and you save that as a CSS file. Your style sheet's filename shouldn't contain spaces, so that it will be easier to use on the Web.
The extension you should use is <code>.css</code>, so your files should be named something like <code>test.css</code> or <code>sitedesign.css</code>. While you're learning and practicing, you'll probably want to keep the <code>.css</code> file in the same directory as your HTML pages. After you've got the hang of CSS, you'll probably want to store your style sheets in a designated directory on your website; I usually create a <code>/styles/</code> directory for mine.
== Writing CSS Rules ==
The building blocks of any style sheet are the CSS rules that compose it. Each rule is a single statement that identifies what should be styled and how those styles should be applied. Style sheets are then composed of lists of rules, which the browser uses to determine what a page should look like (or even sound like).
===The Basic Structure of a CSS Rule ===
A CSS rule consists of two sections: the selector(s) and the declaration(s). A declaration is made up of a property and a value for that property. A simple CSS rule would therefore look something like this:
<pre>selector { property: value; }
</pre>
One important thing to note is that CSS ignores extra whitespace, just as HTML usually does. This means that as far as CSS-enabled browsers are concerned, one space is equal to twenty spaces or even five spaces, four blank lines, and four more spaces. So the rule could be written like this and still mean the same thing:
<pre>selector
{
property:
value;
}
</pre>
You should feel free to use whatever spaces and lines you need within your CSS to make it easy to read and maintain. For example, I usually indent the property and value pairs quite a bit by inserting spaces; this makes it easier for me to see at a glance where one rule ends and the next begins. By being consistent in how you use blank spaces in your style sheets, you can keep them easy to read and maintain. There is no one best way to write a style rule, and you may end up using different spacing in different situations. As long as it works for you, that's what matters.
===The Selector ===
The selector part of the rule tells which section of the document the rule covers. The simplest type of selector is a type selector that indicates a specific markup element, such as the <code><nowiki><p></nowiki></code> tag in HTML. You write a type selector by just giving the name of the element without the <code><></code> brackets, as in the following:
<pre>p { property: value; }
</pre>
Such a rule would select the styling of all <code><nowiki><p></nowiki></code> tags.
===The Declaration ===
The next part of the rule is the declaration. Declarations are enclosed in <code>{}</code> braces. Within the braces, the property name is given first, followed by a colon, and then a property value. An ending semicolon is optional but recommended for reasons that will become apparent later this hour. The entire rule is concluded by the ending brace.
===Properties ===
Properties are defined by the official CSS specifications; these are the specific style effects you can define and expect to be supported by CSS-compliant browsers. Most browsers are likely to ignore properties that aren't part of the CSS specification, although some browsers recognize nonstandard properties that are not part of the formal language specification. It's best to not rely on these proprietary extensions, but browsers that don't recognize them simply overlook them. In [Hour 3], "Browser Support for CSS," you'll learn more about how browsers handle or don't handle CSS.
===Values ===
The value of the declaration follows the property name, after the colon, and defines exactly how that property should be set. The range of values for each property is also defined in the CSS specifications. For example, the property named <code>color</code> can take values that consist of color names or codes, as in the following:
<pre>p { color: blue; }
</pre>
This rule declares that the content of all paragraph tags should have their <code>color</code> properties set to the value <code>blue</code>. So all <code><nowiki><p></nowiki></code> text would turn blue.
;By the Way: What happens if you don't set the <code>color?</code> Well, you can probably guess from your work with HTML that a default will be chosen—one set by the browser or the user's preferences. The color might also be set by the text attribute on the <code><body></code> tag, or on a <code></code> tag. CSS adds additional ways to determine the color, including writing a rule with the <code><body></code> tag as the selector, which would then apply to all <code><nowiki><p></nowiki></code> tags within the <code><body></code>—that is to say, it would apply to all paragraphs on the page.
The specific process CSS uses to determine the color of the text or of any other property settings is called the cascade. You'll learn more about how the cascade works in [Hour 7], "Cascading and Inheritance."
===Combining CSS Rules ===
You can combine two CSS rules that share the same selector by listing their declarations within the curly braces. The ending semicolon is no longer optional between two rules combined this way; it's a necessary separator between the two declarations. For ease of editing and combining, I suggest always including the semicolon even if your braces contain only one declaration.
Here's an example of two CSS rules with the same selector:
<pre>p { color: blue; }
p { font-size: large; }
</pre>
These rules can be combined into one rule like the following:
<pre>p { color: blue; font-size: large; }
</pre>
I could have also written the rule like this:
<pre>p
{
color: blue;
font-size: large;
}
</pre>
That particular style of spacing makes it a little easier to cut and paste entire lines while writing or testing the CSS. The browsers don't care about the whitespace—it's there to help you organize your style sheet in whatever manner works best for you.
You can also combine rules if they have the same declarations and different selectors. You combine selectors by putting them in a list, separated by commas. For example, the following rules have the same declarations:
<pre>p { color: blue; }
address { color: blue; }
</pre>
You can write them as one rule, as follows:
<pre>p, address { color: blue; }
</pre>
This rule says, "The content of <code><nowiki><p></nowiki></code> tags and of <code><address></code> tags should be colored as blue text."
You can use multiple selectors together with multiple declarations; that is perfectly legal and very common. You can also write additional rules to further style those selectors together or separately. Here's what that might look like:
<pre>p, address
{
color: blue;
font-size: large;
}
p
{
font-family: Arial;
}
</pre>
===CSS Comments ===
Like many other languages, including HTML, CSS allows you to embed comments in the source code. A comment is a special bit of code that you embed in your CSS that is completely ignored by the browser. Comments serve as a way of adding to the source notes that are meant for the author of the style sheet or someone maintaining it. The user doesn't ever see comments, and they won't affect the style of the page; they are significant only when reading or editing the style sheet itself.
Comments can be used to describe what your style sheet is doing at a particular point, or perhaps why it's doing it, so that when you come back to the style sheet later, you can recall why you wrote it that particular way. Comments are also useful for hiding sections of code that you feel you don't need any more or that you want browsers to ignore; this is known as commenting out your code. Comments can also be used to identify the author and the creation date of the style sheet and to provide a copyright notice.
Comments in CSS begin with the characters <code>/*</code> and end with the characters <code>*/</code>. Anything between the start of the comment and the end is ignored. Here's an example of a comment:
<pre>/* Let's turn all the paragraph text blue */
p { color: blue; }
</pre>
Your comments can appear anywhere you like, even inside a rule:
<pre>p
{
color: /* make it less blue */ purple;
font-size: large;
}
</pre>
You can comment out parts of a declaration if you decide you don't want that particular part of the style rule to be applied, but you don't want to delete it. This is useful for testing various options when developing your style sheet. For example, this comments out the <code>font-size</code> declaration:
<pre>p
{
color: /* make it less blue */ purple;
/* font-size: large; */
}
</pre>
However, you can't nest comments, meaning that if you try to enclose one comment within another, both comments end at the first <code>*/</code>. For example, imagine that you want to comment out the color purple instead; if the comment markers are in the wrong place, as in the following, it doesn't work:
<pre>p
{
/* color: /* make it less blue */ purple; */
font-size: large;
}
</pre>
In this case, the comment ends after <code>blue</code>, not at the end of the declaration. This leaves the word <code>purple</code> floating there outside the comment. CSS browsers will probably ignore it because a <code>purple</code> by itself doesn't have any particular meaning in CSS, but that's just lucky this time. You need to be careful when placing your comments so that you don't accidentally try to nest them.
===Simple CSS Properties for Text Formatting ===
As you've probably surmised from the previous examples, there are CSS properties that can be used to set the text color, the size of the font, and the family of the font—<code>color, font-size</code>, and <code>font-family</code>, respectively. These are some of the simplest and yet most useful CSS properties; collectively, they perform the same function as the HTML <code><nowiki><font></nowiki></code> tag. Another very useful property is <code>background-color</code>, which sets the color of the background.
===The <code>color</code> Property ===
The <code>color</code> property is used to set the foreground color of the element, which is the property controlling the color of the text. For example,
<pre>h1 { color: lime; }
h2 { color: red; }
</pre>
This makes all <code><nowiki><h1></nowiki></code> elements a bright, lime-green color and makes all <code><nowiki><h1></nowiki></code> elements red. As with HTML, you can use one of 17 standard color names, or you can give an RGB value, such as <code>#FF0000</code>. The color names and their corresponding RGB values are shown in [Table 2.1].
{| cellspacing="0" cellpadding="5"|+ Table 2.1. Color Names in CSS
|-
| Color Name
| RGB Value
|-
| <code>aqua</code>
| <code>#00FFFF</code>
|-
| <code>black</code>
| <code>#000000</code>
|-
| <code>blue</code>
| <code>#0000FF</code>
|-
| <code>fuchsia</code>
| <code>#FF00FF</code>
|-
| <code>gray</code>
| <code>#808080</code>
|-
| <code>green</code>
| <code>#008000</code>
|-
| <code>lime</code>
| <code>#00FF00</code>
|-
| <code>maroon</code>
| <code>#800000</code>
|-
| <code>navy</code>
| <code>#000080</code>
|-
| <code>olive</code>
| <code>#808000</code>
|-
| <code>orange</code>
| <code>#ffA500</code>
|-
| <code>purple</code>
| <code>#800080</code>
|-
| <code>red</code>
| <code>#FF0000</code>
|-
| <code>silver</code>
| <code>#C0C0C0</code>
|-
| <code>teal</code>
| <code>#008080</code>
|-
| <code>white</code>
| <code>#FFFFFF</code>
|-
| <code>yellow</code>
| <code>#FFFF00</code>
|}
=== The <code>background-color</code> Property ===
You can use the <code>background-color</code> property to set the background color. The values are the same as for the <code>color</code> property—color names or RGB values. To set the background color for the whole page, use the <code><body></code> tag in your selector; you can set backgrounds on any other elements as well. For example,
<pre>body { background: silver; }
h1 { background: #FFFF00; }
</pre>
;Watch Out!: When you set the background color, make sure you've also set a foreground color that is visible against it! Otherwise your text may be very hard to read.
===The <code>font-size</code> Property ===
The <code>font-size</code> property enables you to specify the size of the text that's displayed to the user. One of the easier ways to specify font sizes is to give a value relative to the user's default text size; this respects the user's preferences as set in the browser.
The default text size has a value of <code>normal</code>; larger sizes go up in increments of about 20% to values of large, <code>x-large</code>, and <code>xx-large</code>. Smaller sizes decrease by 20% to <code>small, x-small</code>, and <code>xx-small</code>. You can also use the relative values <code>larger</code> and <code>smaller</code> to indicate one step up or down the scale from the current size. Here are some examples:
<pre>dl { font-size: large; }
caption { font-size: small; }
em { font-size: larger; }
</pre>
===The <code>font-family</code> Property ===
You can use the <code>font-family</code> property to set the font face of the text. So why is it called <code>font-family</code> and not <code>font-face</code>? When you designate a font, you're really designating a whole family of related variants within the same font family. So when choosing Arial font, you're actually choosing the Arial family of fonts, each one slightly different in size.
CSS also uses generic font families. The generic font families are <code>sans-serif, serif, monospace, cursive</code>, and <code>fantasy</code>. These aren't names of specific fonts, but rather a broad class that can be used as defaults if the browser doesn't know what a font name represents. If you choose a font that isn't installed on the user's machine, the browser uses just the normal font, so make sure you designate a generic font family as well as a specific one. You indicate the generic font by listing it after the specific font, separated by a comma.
Common web fonts and their generic families are shown on [Table 2.2].
{| cellspacing="0" cellpadding="5"|+ Table 2.2. Common Font Families
|-
| Font
| Generic Font Family
|-
| <code>Arial</code>
| <code>sans-serif</code>
|-
| <code>Times New Roman</code>
| <code>serif</code>
|-
| <code>Courier New</code>
| <code>monospace</code>
|-
| <code>Verdana</code>
| <code>sans-serif</code>
|}
If the name of the font family has more than one word, enclose it in quotes. Here are some examples of CSS rules that use <code>font-family</code>:
<pre>body { font-family: Arial, sans-serif; }
h1 { font-family: "Courier New", monospace; }
h2 { font-family: "Times New Roman", serif; }
</pre>
You'll learn more about font families and font sizes in [Hour 9], "Fonts and Font Families."
===A Simple Style Sheet ===
Using just the simple properties and values you've learned so far this hour, you already can create a basic style sheet; an example of a complete style sheet is shown in [Listing 2.1].
; Listing 2.1. A Basic Style Sheet with Color, Size, and Font Declarations
<pre>/* basic-2.1.css */
body { font-family: Arial;
color: black;
background-color: white; }
/* I think Verdana looks nice for headlines */
h1, h2, h3, h4, h5, h6
{ font-family: Verdana, sans-serif; }
/* This makes the largest heading have a background */
h1 { background-color: silver; }
/* This puts the even numbered headings in gray */
h2, h4, h6
{ color: gray; }
table { background-color: white; }
th { background-color: black;
color: white;
font-size: smaller; }
td { background-color: gray;
font-size: smaller; }
address { font-family: "Courier New", monospace;
font-size: larger; }
</pre>
You can find a copy of this style sheet on the book's website.
== Linking a Style Sheet to an HTML Page ==
A style sheet by itself doesn't really do anything except sit there on your hard drive or web server. If you try to load it in your browser, it displays as just plain text. To actually use the CSS rules, you need to have a file with markup, such as an HTML page, and you need to add an HTML tag to link the CSS file to the web page.
=== A Simple HTML Page for Styling ===
[Listing 2.2] shows the structure of a basic HTML page like one you might find on the Web; it has headlines, paragraphs, horizontal rules, and even a table on the side. You can download a copy of this file from the book's website—because that's easier than typing in the whole thing.
;Listing 2.2. A Simple HTML File that Needs Styling
<pre><!-- authorbio-2.2.html -->
<html>
<head>
<title>Kynn.com</title>
</head>
<body>
<h1>Kynn.com</h1>
<table align="right" width="25%">
<tr><th><h3>New Stuff</h3></th></tr>
<tr><td>
<ul>
<li>Pictures of <a href="http://www.desertmuseum.org/">
The Arizona-Sonora Desert Museum</a> from
<a href="/gallery/2006/02/desertmuseum/">February
2006</a></li>
<li>The <a href="/projects/heritage-tour/">Black
Heritage Tour of Tucson, Arizona</a></li>
</ul>
</td></tr>
</table>
<h2>Kynn Bartlett's Web Site</h2>
<p>Welcome to my site!</p>
<h3>Biography</h3>
<p>Kynn Bartlett has been using the Internet since
1986, and has been a Web developer since 1994.
Self-taught in HTML, CSS, XML, and many other Web
technologies, he passes this knowledge along to others
through authoring books, teaching online classes, and
giving seminars and presentations. His specialty is
Web accessibility: Making Web sites that can be used
by people with disabilities.</p>
<p>Kynn was a key board member in building the HTML Writers
Guild, a non-profit educational association of Web
developers from around the world, and helped create the
Guild's online education program. He also served as the
Guild's representative on several World Wide Web
Consortium working groups.</p>
<p>From 1995 to 2005, Kynn was the co-owner and Chief
Technologist of Idyll Mountain Internet, in Fullerton,
California. Currently, he lives in Tucson, Arizona, where
he writes books and does digital photography in addition
to Web consulting.</p>
<hr>
<address>
<a href="mailto:kynn@css24.com">kynn@css24.com</a>
</address>
</body>
</html>
</pre>
As shown in the screenshot in [Figure 2.3], web browsers display this simply, without any CSS styles. It's not ugly, but it's not very interesting to look at, either.
===Linked Style Sheets in HTML ===
To apply the style sheet to the HTML page, you need to tell the browser which style sheet to use. You do this by using the <code><link></code> element of HTML, and in this case the <code>basic-2.1.css</code> file from [Listing 2.1].
The <code><link></code> tag can appear only within the <code><head></code> section of the HTML page. To link the style sheet, I open the HTML file and add the following line (shown in bold):
<pre><head>
<title>Kynn.com</title>
<link type="text/css" rel="stylesheet" href="basic-2.1.css">
</head>
</pre>
You can see the effect of applying the style sheet in [Figure 2.4]; compare this with [Figure 2.3] to see the difference CSS can make in the appearance of the page.
== Viewing Your Style Sheet ==
After you've created a style sheet, you'll want to take a look at it to ensure that it works. Uneven browser support for CSS means that it's important to check how it appears in various browsers, as well as to make sure you got the syntax correct.
To view the style sheet, simply view the HTML file that links to your CSS file. Don't try viewing the CSS file directly; it just looks like source code in many browsers. The way to know whether it worked is to look at the HTML page that's being styled.
===Recommended Browsers ===
You'll want to verify your style sheet in at least the major browsers because they represent the greatest number of users who may access your page. You'll also want to test in browsers that have good support for the CSS standard. Browsers can vary between operating systems; Internet Explorer on Microsoft Windows handles CSS quite differently from Internet Explorer on a Macintosh.
Naturally, it's difficult for one person to have access to every different browser combination available, but the more you're able to use, the better your results will be. I recommend a standard testing suite consisting of three or four of the following browsers:
* Internet Explorer (6.0 or higher for Windows)
* Safari (1.3 or higher for Mac OS X)
* Firefox (1.5 or higher for Windows, Mac OS X, or Linux)
* Opera (8.5 or higher for Windows, Mac OS X, or Linux)
* Lynx (2.8 or higher; Windows, Macintosh, or Linux)
These browsers represent a good cross-section for testing, and are generally widely available on most popular operating systems. In [Hour 3] you'll learn more about these browsers and how to install them on your computer.
===Try it Yourself: Creating Your First Style Sheet ===
Learning by doing is the key to understanding Cascading Style Sheets, and building your own style sheet is the first step in the process. Follow these instructions to create and test your own CSS:
{| border="0"
|-
| '''1. '''
| Select an HTML page to style. This could be one you've created before, a brand new one, or perhaps the <code>authorbio-2.2.html</code> file used earlier this hour.<br /><br />
|-
| '''2. '''
| Create a new CSS file, using the text editor of your choice. Using the style properties you learned this hour, add style rules to apply to your HTML page. Change the color of the text, the background color, the font sizes, and the text font. Save this file with a <code>.css</code> extension.<br /><br />
|-
| '''3. '''
| Use the <code><link></code> tag in your HTML to associate the style sheet with the HTML page. Be sure the HTML and CSS files are in the same directory, or else the browser might not be able to find the CSS file. (You can use full URL paths if you want, but for now, it's easiest to have HTML and CSS in the same location.)<br /><br />
|-
| '''4. '''
| Open your page in your primary web browser and view the results of your work. You may want to go back and tweak the CSS to see what effect additional styles have; go right ahead, and then reload the page!<br /><br />
|-
| '''5. '''
| If you have any of the other recommended browsers, try the page with those. You probably won't see much difference because the CSS properties introduced in this hour are relatively safe and reasonably well supported.<br /><br />
|}
== Summary ==
In this hour, you learned about using text editors and specialized software to create and edit style sheets, which are just ordinary text files of CSS rules. You learned the general structure of a CSS rule and its component parts, including the selector, the declaration, the property name, and the property value. You learned how and why to include comments in your CSS files. You got to see a few simple styles change an HTML page, setting the text color, size, and font, and you learned how the HTML <code><link></code> tag associates a style sheet with a web page. Finally, you learned how to display your page in your browser and see your CSS in action.
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q.'''
| I'm not sure what the "RGB" values used for colors are. Can you explain?
|-
| align="right" | '''A.'''
| Sure! RGB triples are one of the most common ways to specify color on the Web, in both HTML and CSS. RGB stands for Red-Green-Blue and is a standard way to specify a color as a composite of three values: the amount of red, the amount of green, and the amount of blue. In HTML and CSS these are written in hexadecimal numbers (base 16), which start with 0, go up to 9, and then continue on to A, B, C, D, E, and F. If you don't know how to use RGB hexadecimal values, you can use the <code>rgb()</code> function to specify colors, like this:
<code>h1 { color: rgb(100%, 50%, 25%); }<br /></code><br />
|-
| align="right" | ''' Q.'''
| Can I set the <code>font-size</code> to a specific value, such as 12 point?
|-
| align="right" | ''' A.'''
| Yes, you can; 12 point is written as <code>12pt</code> (no space). This is what's known as an absolute font size, though, and it can cause problems for users who need to adjust their preferences to account for visual impairments. For now I recommend sticking with the relative values given earlier in this hour, like <code>larger</code> and <code>x-small</code>, but if you want you can read ahead to [ch09.html#ch09 Hour 9] for more about font size units.
|}
=== Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| What kind of software is needed to create a CSS file?
|-
| align="right" | ''' 2.'''
| What is the name of the part of a CSS rule that goes within the curly braces?
# The selector
# The declaration
# The property name
# The property value
|-
| align="right" | '''3.'''
| You want to make all your HTML headings (<code><nowiki><h1></nowiki></code>, and so on) blue and in Arial font. What CSS rule(s) do you write?
|}
=== Answers===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| Because CSS files are just ordinary text files, anything that can create or edit text files can make a style sheet. This includes text editors, style sheet editors, web development tools, and word processors. The important thing is to save the files as plain text, usually with a <code>.css</code> file extension suffix.
|-
| align="right" | '''2.'''
| The declaration, which consists of the one or more pairs of property names and values, is the part of the CSS rule between curly braces.
|-
| align="right" | ''' 3.'''
| Here's the easiest way to make headings blue and Arial:
<pre>
h1, h2, h3, h4, h5, h6
{
color: blue;
font-family: Arial;
}
</pre>
You could also write this as several rules—as many as 12—but this combined form is the easiest way to do it.
|}
=== Exercise ===
You now know how to make the easiest types of style sheets—those that can be applied to HTML pages to change the colors, background colors, and fonts of HTML tags on the page. Test your new skills by creating several web pages that use the same style sheet. You will soon notice you're running into some limitations—you have to style all elements the same way. In [Hour 4], "Using CSS with HTML," you'll learn how to expand your repertoire of selectors.
p1kcycdok9tijfu4eb9heyq7d1s82c2
39284
39212
2026-04-13T06:14:26Z
Redmin
5511
Restoring markup mistakenly removed by my bot
39284
wikitext
text/x-wiki
= Hour 2. Getting Started with CSS =
; What You'll Learn in This Hour:
* What kinds of tools, from text editors to CSS software, you can use to write your style sheets
* How to create, name, and save a style sheet
* What the different parts of a CSS rule are and the function of each
* How and when to add comments to a style sheet
* Which simple rules you can use to create a basic style sheet
* How to apply your style sheet to a simple HTML file
* Which browsers to use to test your style sheet
== Creating a Style Sheet ==
A Cascading Style Sheet, as you learned in [Hour 1], "Understanding CSS," is simply a file made up of style rules. CSS files are ordinary text files, just as HTML files are ordinary text files. This means that you can use a wide variety of programs to create a style sheet, from simple text editors to specialized software written just for creating and maintaining style sheets. Anything that can be used to create a text file can create a style sheet.
Because Cascading Style Sheets are pretty simple to write, you don't need to use complex tools to create a basic style sheet. Many web developers will write CSS by hand, meaning that they type out the text of each rule; however, authoring tools exist that can make this task easier.
===Software Tools for CSS ===
Your editing environment is the program or set of programs that you use to create your style sheet. You'll want to choose the editing environment that works best for you, be that a text editor, a style sheet editor, or a web development tool. I use a text editor myself, and I recommend starting simple, at least until you've learned enough about the basics of CSS to understand how editing tools can help you.
===Text Editors ===
Every operating system comes with a basic text editor, and because CSS is just basic text, it's a good match for one of these programs. A text editor is a simple program that just produces plain text files, which means it can also be used to create HTML or CSS files. Unlike word processing software, text editors don't save formatting with the text; that's why they are said to produce plain text. Text editors are ubiquitous and don't get in the way of your learning about CSS, so this is probably where you want to start. You probably already know how to use one of the text editors on your computer. Some basic text editors include
* Notepad or WordPad on Microsoft Windows
* TextEdit on Macintosh
* vi, vim, or emacs on Linux or Unix
[Figure 2.1] shows a style sheet being edited in Notepad on Windows; this is the style sheet from the author's personal website, which was shown in [Hour 1]. Don't worry too much about reading and understanding the properties; the style sheet is rather complex and has a lot of properties from the middle or end of this book.
;Did you Know?: You can use a word processing program, such as Microsoft Word, to create text files, but you need to remember to save your files as plain text without any special formatting. It's probably easier to just use a text editor, although most of them lack the advanced features found in word processors, such as advanced find-and-replace and word counting. Fortunately, you'll rarely need those features when editing CSS.
===Style Sheet Editors ===
Some software has been written specifically to create CSS style sheets; these have advanced features such as color-coding of rules and properties, syntax checking, and more. These are great tools, and I highly recommend them when you're doing serious CSS development; if you're just beginning, though, they may be more than you need right now and could overwhelm you with options. After you understand the principles and language of CSS, however, a style sheet editor is invaluable. Some of the CSS editors available include
* TopStyle, for Windows; [http://www.bradsoft.com/topstyle/ http://www.bradsoft.com/topstyle/]
* Style Master, for Windows and Mac OS X; [http://www.westciv.com/style_master/ http://www.westciv.com/style_master/]
* CSSEdit, for Mac OS X; [http://www.macrabbit.com/cssedit/ http://www.macrabbit.com/cssedit/]
* JustStyle CSS Editor, for all Java-enabled computers; [http://www.ucware.com/juststyle/ http://www.ucware.com/juststyle/]
The screenshot in [Figure 2.2] shows the author's style sheet being edited in Style Master, one of the CSS editors listed here. As you can see, a style sheet editor offers a lot more in the way of development features compared to a simple text editor, but it's also more complex to use.
===HTML Editors and Web Development Software ===
Because CSS is an integral part of web design, web design packages that let you create HTML often support CSS editing. Visual editors let you set styles and create the style sheet behind the scenes, whereas those with source editing modes enable you to edit the style sheet directly. As with CSS editors, I recommend using these after you've become familiar with the basics of CSS syntax. Your favorite web editing environment may already include CSS support; some that do include
* Microsoft FrontPage, for Windows; [http://www.microsoft.com/frontpage/ http://www.microsoft.com/frontpage/]
* Macromedia Dreamweaver, for Windows and Mac OS X; [http://www.macromedia.com/software/dreamweaver/ http://www.macromedia.com/software/dreamweaver/]
* Adobe GoLive, for Windows and Macintosh; [http://www.adobe.com/products/golive/ http://www.adobe.com/products/golive/]
* CoffeeCup HTML Editor, for Windows; [http://www.coffeecup.com/editor/ http://www.coffeecup.com/editor/]
* BBEdit, for Mac OS X; [http://www.barebones.com/products/bbedit/ http://www.barebones.com/products/bbedit/]
=== Naming and Saving a Style Sheet ===
However you edit your style sheet, the basic principle will be the same: You create a text file that contains the CSS rules, and you save that as a CSS file. Your style sheet's filename shouldn't contain spaces, so that it will be easier to use on the Web.
The extension you should use is <code>.css</code>, so your files should be named something like <code>test.css</code> or <code>sitedesign.css</code>. While you're learning and practicing, you'll probably want to keep the <code>.css</code> file in the same directory as your HTML pages. After you've got the hang of CSS, you'll probably want to store your style sheets in a designated directory on your website; I usually create a <code>/styles/</code> directory for mine.
== Writing CSS Rules ==
The building blocks of any style sheet are the CSS rules that compose it. Each rule is a single statement that identifies what should be styled and how those styles should be applied. Style sheets are then composed of lists of rules, which the browser uses to determine what a page should look like (or even sound like).
===The Basic Structure of a CSS Rule ===
A CSS rule consists of two sections: the selector(s) and the declaration(s). A declaration is made up of a property and a value for that property. A simple CSS rule would therefore look something like this:
<pre>selector { property: value; }
</pre>
One important thing to note is that CSS ignores extra whitespace, just as HTML usually does. This means that as far as CSS-enabled browsers are concerned, one space is equal to twenty spaces or even five spaces, four blank lines, and four more spaces. So the rule could be written like this and still mean the same thing:
<pre>selector
{
property:
value;
}
</pre>
You should feel free to use whatever spaces and lines you need within your CSS to make it easy to read and maintain. For example, I usually indent the property and value pairs quite a bit by inserting spaces; this makes it easier for me to see at a glance where one rule ends and the next begins. By being consistent in how you use blank spaces in your style sheets, you can keep them easy to read and maintain. There is no one best way to write a style rule, and you may end up using different spacing in different situations. As long as it works for you, that's what matters.
===The Selector ===
The selector part of the rule tells which section of the document the rule covers. The simplest type of selector is a type selector that indicates a specific markup element, such as the <code><nowiki><p></nowiki></code> tag in HTML. You write a type selector by just giving the name of the element without the <code><></code> brackets, as in the following:
<pre>p { property: value; }
</pre>
Such a rule would select the styling of all <code><nowiki><p></nowiki></code> tags.
===The Declaration ===
The next part of the rule is the declaration. Declarations are enclosed in <code>{}</code> braces. Within the braces, the property name is given first, followed by a colon, and then a property value. An ending semicolon is optional but recommended for reasons that will become apparent later this hour. The entire rule is concluded by the ending brace.
===Properties ===
Properties are defined by the official CSS specifications; these are the specific style effects you can define and expect to be supported by CSS-compliant browsers. Most browsers are likely to ignore properties that aren't part of the CSS specification, although some browsers recognize nonstandard properties that are not part of the formal language specification. It's best to not rely on these proprietary extensions, but browsers that don't recognize them simply overlook them. In [Hour 3], "Browser Support for CSS," you'll learn more about how browsers handle or don't handle CSS.
===Values ===
The value of the declaration follows the property name, after the colon, and defines exactly how that property should be set. The range of values for each property is also defined in the CSS specifications. For example, the property named <code>color</code> can take values that consist of color names or codes, as in the following:
<pre>p { color: blue; }
</pre>
This rule declares that the content of all paragraph tags should have their <code>color</code> properties set to the value <code>blue</code>. So all <code><nowiki><p></nowiki></code> text would turn blue.
;By the Way: What happens if you don't set the <code>color?</code> Well, you can probably guess from your work with HTML that a default will be chosen—one set by the browser or the user's preferences. The color might also be set by the text attribute on the <code><body></code> tag, or on a <code><font></code> tag. CSS adds additional ways to determine the color, including writing a rule with the <code><body></code> tag as the selector, which would then apply to all <code><nowiki><p></nowiki></code> tags within the <code><body></code>—that is to say, it would apply to all paragraphs on the page.
The specific process CSS uses to determine the color of the text or of any other property settings is called the cascade. You'll learn more about how the cascade works in [Hour 7], "Cascading and Inheritance."
===Combining CSS Rules ===
You can combine two CSS rules that share the same selector by listing their declarations within the curly braces. The ending semicolon is no longer optional between two rules combined this way; it's a necessary separator between the two declarations. For ease of editing and combining, I suggest always including the semicolon even if your braces contain only one declaration.
Here's an example of two CSS rules with the same selector:
<pre>p { color: blue; }
p { font-size: large; }
</pre>
These rules can be combined into one rule like the following:
<pre>p { color: blue; font-size: large; }
</pre>
I could have also written the rule like this:
<pre>p
{
color: blue;
font-size: large;
}
</pre>
That particular style of spacing makes it a little easier to cut and paste entire lines while writing or testing the CSS. The browsers don't care about the whitespace—it's there to help you organize your style sheet in whatever manner works best for you.
You can also combine rules if they have the same declarations and different selectors. You combine selectors by putting them in a list, separated by commas. For example, the following rules have the same declarations:
<pre>p { color: blue; }
address { color: blue; }
</pre>
You can write them as one rule, as follows:
<pre>p, address { color: blue; }
</pre>
This rule says, "The content of <code><nowiki><p></nowiki></code> tags and of <code><address></code> tags should be colored as blue text."
You can use multiple selectors together with multiple declarations; that is perfectly legal and very common. You can also write additional rules to further style those selectors together or separately. Here's what that might look like:
<pre>p, address
{
color: blue;
font-size: large;
}
p
{
font-family: Arial;
}
</pre>
===CSS Comments ===
Like many other languages, including HTML, CSS allows you to embed comments in the source code. A comment is a special bit of code that you embed in your CSS that is completely ignored by the browser. Comments serve as a way of adding to the source notes that are meant for the author of the style sheet or someone maintaining it. The user doesn't ever see comments, and they won't affect the style of the page; they are significant only when reading or editing the style sheet itself.
Comments can be used to describe what your style sheet is doing at a particular point, or perhaps why it's doing it, so that when you come back to the style sheet later, you can recall why you wrote it that particular way. Comments are also useful for hiding sections of code that you feel you don't need any more or that you want browsers to ignore; this is known as commenting out your code. Comments can also be used to identify the author and the creation date of the style sheet and to provide a copyright notice.
Comments in CSS begin with the characters <code>/*</code> and end with the characters <code>*/</code>. Anything between the start of the comment and the end is ignored. Here's an example of a comment:
<pre>/* Let's turn all the paragraph text blue */
p { color: blue; }
</pre>
Your comments can appear anywhere you like, even inside a rule:
<pre>p
{
color: /* make it less blue */ purple;
font-size: large;
}
</pre>
You can comment out parts of a declaration if you decide you don't want that particular part of the style rule to be applied, but you don't want to delete it. This is useful for testing various options when developing your style sheet. For example, this comments out the <code>font-size</code> declaration:
<pre>p
{
color: /* make it less blue */ purple;
/* font-size: large; */
}
</pre>
However, you can't nest comments, meaning that if you try to enclose one comment within another, both comments end at the first <code>*/</code>. For example, imagine that you want to comment out the color purple instead; if the comment markers are in the wrong place, as in the following, it doesn't work:
<pre>p
{
/* color: /* make it less blue */ purple; */
font-size: large;
}
</pre>
In this case, the comment ends after <code>blue</code>, not at the end of the declaration. This leaves the word <code>purple</code> floating there outside the comment. CSS browsers will probably ignore it because a <code>purple</code> by itself doesn't have any particular meaning in CSS, but that's just lucky this time. You need to be careful when placing your comments so that you don't accidentally try to nest them.
===Simple CSS Properties for Text Formatting ===
As you've probably surmised from the previous examples, there are CSS properties that can be used to set the text color, the size of the font, and the family of the font—<code>color, font-size</code>, and <code>font-family</code>, respectively. These are some of the simplest and yet most useful CSS properties; collectively, they perform the same function as the HTML <code><nowiki><font></nowiki></code> tag. Another very useful property is <code>background-color</code>, which sets the color of the background.
===The <code>color</code> Property ===
The <code>color</code> property is used to set the foreground color of the element, which is the property controlling the color of the text. For example,
<pre>h1 { color: lime; }
h2 { color: red; }
</pre>
This makes all <code><nowiki><h1></nowiki></code> elements a bright, lime-green color and makes all <code><nowiki><h1></nowiki></code> elements red. As with HTML, you can use one of 17 standard color names, or you can give an RGB value, such as <code>#FF0000</code>. The color names and their corresponding RGB values are shown in [Table 2.1].
{| cellspacing="0" cellpadding="5"|+ Table 2.1. Color Names in CSS
|-
| Color Name
| RGB Value
|-
| <code>aqua</code>
| <code>#00FFFF</code>
|-
| <code>black</code>
| <code>#000000</code>
|-
| <code>blue</code>
| <code>#0000FF</code>
|-
| <code>fuchsia</code>
| <code>#FF00FF</code>
|-
| <code>gray</code>
| <code>#808080</code>
|-
| <code>green</code>
| <code>#008000</code>
|-
| <code>lime</code>
| <code>#00FF00</code>
|-
| <code>maroon</code>
| <code>#800000</code>
|-
| <code>navy</code>
| <code>#000080</code>
|-
| <code>olive</code>
| <code>#808000</code>
|-
| <code>orange</code>
| <code>#ffA500</code>
|-
| <code>purple</code>
| <code>#800080</code>
|-
| <code>red</code>
| <code>#FF0000</code>
|-
| <code>silver</code>
| <code>#C0C0C0</code>
|-
| <code>teal</code>
| <code>#008080</code>
|-
| <code>white</code>
| <code>#FFFFFF</code>
|-
| <code>yellow</code>
| <code>#FFFF00</code>
|}
=== The <code>background-color</code> Property ===
You can use the <code>background-color</code> property to set the background color. The values are the same as for the <code>color</code> property—color names or RGB values. To set the background color for the whole page, use the <code><body></code> tag in your selector; you can set backgrounds on any other elements as well. For example,
<pre>body { background: silver; }
h1 { background: #FFFF00; }
</pre>
;Watch Out!: When you set the background color, make sure you've also set a foreground color that is visible against it! Otherwise your text may be very hard to read.
===The <code>font-size</code> Property ===
The <code>font-size</code> property enables you to specify the size of the text that's displayed to the user. One of the easier ways to specify font sizes is to give a value relative to the user's default text size; this respects the user's preferences as set in the browser.
The default text size has a value of <code>normal</code>; larger sizes go up in increments of about 20% to values of large, <code>x-large</code>, and <code>xx-large</code>. Smaller sizes decrease by 20% to <code>small, x-small</code>, and <code>xx-small</code>. You can also use the relative values <code>larger</code> and <code>smaller</code> to indicate one step up or down the scale from the current size. Here are some examples:
<pre>dl { font-size: large; }
caption { font-size: small; }
em { font-size: larger; }
</pre>
===The <code>font-family</code> Property ===
You can use the <code>font-family</code> property to set the font face of the text. So why is it called <code>font-family</code> and not <code>font-face</code>? When you designate a font, you're really designating a whole family of related variants within the same font family. So when choosing Arial font, you're actually choosing the Arial family of fonts, each one slightly different in size.
CSS also uses generic font families. The generic font families are <code>sans-serif, serif, monospace, cursive</code>, and <code>fantasy</code>. These aren't names of specific fonts, but rather a broad class that can be used as defaults if the browser doesn't know what a font name represents. If you choose a font that isn't installed on the user's machine, the browser uses just the normal font, so make sure you designate a generic font family as well as a specific one. You indicate the generic font by listing it after the specific font, separated by a comma.
Common web fonts and their generic families are shown on [Table 2.2].
{| cellspacing="0" cellpadding="5"|+ Table 2.2. Common Font Families
|-
| Font
| Generic Font Family
|-
| <code>Arial</code>
| <code>sans-serif</code>
|-
| <code>Times New Roman</code>
| <code>serif</code>
|-
| <code>Courier New</code>
| <code>monospace</code>
|-
| <code>Verdana</code>
| <code>sans-serif</code>
|}
If the name of the font family has more than one word, enclose it in quotes. Here are some examples of CSS rules that use <code>font-family</code>:
<pre>body { font-family: Arial, sans-serif; }
h1 { font-family: "Courier New", monospace; }
h2 { font-family: "Times New Roman", serif; }
</pre>
You'll learn more about font families and font sizes in [Hour 9], "Fonts and Font Families."
===A Simple Style Sheet ===
Using just the simple properties and values you've learned so far this hour, you already can create a basic style sheet; an example of a complete style sheet is shown in [Listing 2.1].
; Listing 2.1. A Basic Style Sheet with Color, Size, and Font Declarations
<pre>/* basic-2.1.css */
body { font-family: Arial;
color: black;
background-color: white; }
/* I think Verdana looks nice for headlines */
h1, h2, h3, h4, h5, h6
{ font-family: Verdana, sans-serif; }
/* This makes the largest heading have a background */
h1 { background-color: silver; }
/* This puts the even numbered headings in gray */
h2, h4, h6
{ color: gray; }
table { background-color: white; }
th { background-color: black;
color: white;
font-size: smaller; }
td { background-color: gray;
font-size: smaller; }
address { font-family: "Courier New", monospace;
font-size: larger; }
</pre>
You can find a copy of this style sheet on the book's website.
== Linking a Style Sheet to an HTML Page ==
A style sheet by itself doesn't really do anything except sit there on your hard drive or web server. If you try to load it in your browser, it displays as just plain text. To actually use the CSS rules, you need to have a file with markup, such as an HTML page, and you need to add an HTML tag to link the CSS file to the web page.
=== A Simple HTML Page for Styling ===
[Listing 2.2] shows the structure of a basic HTML page like one you might find on the Web; it has headlines, paragraphs, horizontal rules, and even a table on the side. You can download a copy of this file from the book's website—because that's easier than typing in the whole thing.
;Listing 2.2. A Simple HTML File that Needs Styling
<pre><!-- authorbio-2.2.html -->
<html>
<head>
<title>Kynn.com</title>
</head>
<body>
<h1>Kynn.com</h1>
<table align="right" width="25%">
<tr><th><h3>New Stuff</h3></th></tr>
<tr><td>
<ul>
<li>Pictures of <a href="http://www.desertmuseum.org/">
The Arizona-Sonora Desert Museum</a> from
<a href="/gallery/2006/02/desertmuseum/">February
2006</a></li>
<li>The <a href="/projects/heritage-tour/">Black
Heritage Tour of Tucson, Arizona</a></li>
</ul>
</td></tr>
</table>
<h2>Kynn Bartlett's Web Site</h2>
<p>Welcome to my site!</p>
<h3>Biography</h3>
<p>Kynn Bartlett has been using the Internet since
1986, and has been a Web developer since 1994.
Self-taught in HTML, CSS, XML, and many other Web
technologies, he passes this knowledge along to others
through authoring books, teaching online classes, and
giving seminars and presentations. His specialty is
Web accessibility: Making Web sites that can be used
by people with disabilities.</p>
<p>Kynn was a key board member in building the HTML Writers
Guild, a non-profit educational association of Web
developers from around the world, and helped create the
Guild's online education program. He also served as the
Guild's representative on several World Wide Web
Consortium working groups.</p>
<p>From 1995 to 2005, Kynn was the co-owner and Chief
Technologist of Idyll Mountain Internet, in Fullerton,
California. Currently, he lives in Tucson, Arizona, where
he writes books and does digital photography in addition
to Web consulting.</p>
<hr>
<address>
<a href="mailto:kynn@css24.com">kynn@css24.com</a>
</address>
</body>
</html>
</pre>
As shown in the screenshot in [Figure 2.3], web browsers display this simply, without any CSS styles. It's not ugly, but it's not very interesting to look at, either.
===Linked Style Sheets in HTML ===
To apply the style sheet to the HTML page, you need to tell the browser which style sheet to use. You do this by using the <code><link></code> element of HTML, and in this case the <code>basic-2.1.css</code> file from [Listing 2.1].
The <code><link></code> tag can appear only within the <code><head></code> section of the HTML page. To link the style sheet, I open the HTML file and add the following line (shown in bold):
<pre><head>
<title>Kynn.com</title>
<link type="text/css" rel="stylesheet" href="basic-2.1.css">
</head>
</pre>
You can see the effect of applying the style sheet in [Figure 2.4]; compare this with [Figure 2.3] to see the difference CSS can make in the appearance of the page.
== Viewing Your Style Sheet ==
After you've created a style sheet, you'll want to take a look at it to ensure that it works. Uneven browser support for CSS means that it's important to check how it appears in various browsers, as well as to make sure you got the syntax correct.
To view the style sheet, simply view the HTML file that links to your CSS file. Don't try viewing the CSS file directly; it just looks like source code in many browsers. The way to know whether it worked is to look at the HTML page that's being styled.
===Recommended Browsers ===
You'll want to verify your style sheet in at least the major browsers because they represent the greatest number of users who may access your page. You'll also want to test in browsers that have good support for the CSS standard. Browsers can vary between operating systems; Internet Explorer on Microsoft Windows handles CSS quite differently from Internet Explorer on a Macintosh.
Naturally, it's difficult for one person to have access to every different browser combination available, but the more you're able to use, the better your results will be. I recommend a standard testing suite consisting of three or four of the following browsers:
* Internet Explorer (6.0 or higher for Windows)
* Safari (1.3 or higher for Mac OS X)
* Firefox (1.5 or higher for Windows, Mac OS X, or Linux)
* Opera (8.5 or higher for Windows, Mac OS X, or Linux)
* Lynx (2.8 or higher; Windows, Macintosh, or Linux)
These browsers represent a good cross-section for testing, and are generally widely available on most popular operating systems. In [Hour 3] you'll learn more about these browsers and how to install them on your computer.
===Try it Yourself: Creating Your First Style Sheet ===
Learning by doing is the key to understanding Cascading Style Sheets, and building your own style sheet is the first step in the process. Follow these instructions to create and test your own CSS:
{| border="0"
|-
| '''1. '''
| Select an HTML page to style. This could be one you've created before, a brand new one, or perhaps the <code>authorbio-2.2.html</code> file used earlier this hour.<br /><br />
|-
| '''2. '''
| Create a new CSS file, using the text editor of your choice. Using the style properties you learned this hour, add style rules to apply to your HTML page. Change the color of the text, the background color, the font sizes, and the text font. Save this file with a <code>.css</code> extension.<br /><br />
|-
| '''3. '''
| Use the <code><link></code> tag in your HTML to associate the style sheet with the HTML page. Be sure the HTML and CSS files are in the same directory, or else the browser might not be able to find the CSS file. (You can use full URL paths if you want, but for now, it's easiest to have HTML and CSS in the same location.)<br /><br />
|-
| '''4. '''
| Open your page in your primary web browser and view the results of your work. You may want to go back and tweak the CSS to see what effect additional styles have; go right ahead, and then reload the page!<br /><br />
|-
| '''5. '''
| If you have any of the other recommended browsers, try the page with those. You probably won't see much difference because the CSS properties introduced in this hour are relatively safe and reasonably well supported.<br /><br />
|}
== Summary ==
In this hour, you learned about using text editors and specialized software to create and edit style sheets, which are just ordinary text files of CSS rules. You learned the general structure of a CSS rule and its component parts, including the selector, the declaration, the property name, and the property value. You learned how and why to include comments in your CSS files. You got to see a few simple styles change an HTML page, setting the text color, size, and font, and you learned how the HTML <code><link></code> tag associates a style sheet with a web page. Finally, you learned how to display your page in your browser and see your CSS in action.
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q.'''
| I'm not sure what the "RGB" values used for colors are. Can you explain?
|-
| align="right" | '''A.'''
| Sure! RGB triples are one of the most common ways to specify color on the Web, in both HTML and CSS. RGB stands for Red-Green-Blue and is a standard way to specify a color as a composite of three values: the amount of red, the amount of green, and the amount of blue. In HTML and CSS these are written in hexadecimal numbers (base 16), which start with 0, go up to 9, and then continue on to A, B, C, D, E, and F. If you don't know how to use RGB hexadecimal values, you can use the <code>rgb()</code> function to specify colors, like this:
<code>h1 { color: rgb(100%, 50%, 25%); }<br /></code><br />
|-
| align="right" | ''' Q.'''
| Can I set the <code>font-size</code> to a specific value, such as 12 point?
|-
| align="right" | ''' A.'''
| Yes, you can; 12 point is written as <code>12pt</code> (no space). This is what's known as an absolute font size, though, and it can cause problems for users who need to adjust their preferences to account for visual impairments. For now I recommend sticking with the relative values given earlier in this hour, like <code>larger</code> and <code>x-small</code>, but if you want you can read ahead to [ch09.html#ch09 Hour 9] for more about font size units.
|}
=== Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| What kind of software is needed to create a CSS file?
|-
| align="right" | ''' 2.'''
| What is the name of the part of a CSS rule that goes within the curly braces?
# The selector
# The declaration
# The property name
# The property value
|-
| align="right" | '''3.'''
| You want to make all your HTML headings (<code><nowiki><h1></nowiki></code>, and so on) blue and in Arial font. What CSS rule(s) do you write?
|}
=== Answers===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| Because CSS files are just ordinary text files, anything that can create or edit text files can make a style sheet. This includes text editors, style sheet editors, web development tools, and word processors. The important thing is to save the files as plain text, usually with a <code>.css</code> file extension suffix.
|-
| align="right" | '''2.'''
| The declaration, which consists of the one or more pairs of property names and values, is the part of the CSS rule between curly braces.
|-
| align="right" | ''' 3.'''
| Here's the easiest way to make headings blue and Arial:
<pre>
h1, h2, h3, h4, h5, h6
{
color: blue;
font-family: Arial;
}
</pre>
You could also write this as several rules—as many as 12—but this combined form is the easiest way to do it.
|}
=== Exercise ===
You now know how to make the easiest types of style sheets—those that can be applied to HTML pages to change the colors, background colors, and fonts of HTML tags on the page. Test your new skills by creating several web pages that use the same style sheet. You will soon notice you're running into some limitations—you have to style all elements the same way. In [Hour 4], "Using CSS with HTML," you'll learn how to expand your repertoire of selectors.
23k3caz2eobjw75bfp1mqeukbi4gt5k
User:Bartlett/03
2
2106
39213
7134
2026-04-13T06:03:15Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39213
wikitext
text/x-wiki
= Hour 3. Browser Support for CSS =
;What You'll Learn in This Hour:
* How web browsers fail to support CSS correctly
* The consequences of browser failure
* What the Acid2 test is and what it measures
* What a layout engine is and how it affects your web page
* How current browsers implement Cascading Style Sheets
* How screen readers work with browsers to speak web pages to blind users
CSS rules are always interpreted by web browsers, just as the HTML pages those rules style are interpreted. The HTML and CSS standards give specifics on how browsers should display those rules—but they're not always followed. To design pages with CSS, you not only need to know the standards, as presented in the CSS specification, but also understand how browsers' quirks and flaws will affect your web design results.
== Modern Browsers and CSS ==
From the perspective of a CSS designer, the most important part of the web browser is not the menu bar, the tabbed window interface, or even the security and privacy features. The true heart of a web browser is its layout engine.
The layout engine is the part of the browser program that reads an HTML page and applies the browser's default style rules, the user's personal style sheet (if any), and the style sheets associated with the page being displayed. The colors, fonts, page layout, and other properties controlled by HTML and CSS are all applied by the layout engine, which presents the page content to the user.
This is also where you find browser bugs and quirks that affect CSS usage. The layout engine is the primary determinant of whether a browser is broken, quirky, or compliant.
In modern web browsers, the layout engine is modular and can be used by other applications. For example, the layout engine used in Firefox is known by the code-name Gecko. (All layout engines have code-names which are, essentially, arbitrarily chosen and don't really mean anything in particular.) Gecko is an open-source layout engine—meaning that the code used to create the program is available on the Web for anyone to readand it has been used in other programs, such as the browsers Camino, K-Meleon, and Epiphany, as well as the email program Thunderbird. From a CSS designer's perspective, these browsers are all effectively the same as Firefox; they display CSS in the same way, and share any quirks and bugs found in Gecko.
The rest of this hour is a snapshot of the major browsers in the first part of 2006 (and some minor browsers), grouped by layout engine. Older versions of these browsers are listed as well, with advice on how these browsers will affect your web design practices.
===Internet Explorer ===
Microsoft's Internet Explorer 6 is currently the most popular web browser; recent browser statistics show that more people use IE than all other browsers combined.
On the other hand, Internet Explorer is probably the least favorite current browser among designers who use CSS extensively. There are a number of bugs and other problems in Internet Explorer, which force it into the category of "quirky browsers." You're going to need to make special provisions for Internet Explorer if you use more complex CSS, such as advanced selectors or CSS for layout.
Did you Know?
You can download Internet Explorer 6 from [http://www.microsoft.com/windows/ie/ http://www.microsoft.com/windows/ie/]. It's available on the Windows platform only; see later this hour for details on the now-defunct Internet Explorer for Mac.
The layout engine used in Internet Explorer is code-named Trident. As the part of the web browser responsible for the display of web content, including HTML tags and CSS rules, Trident is also the source of the bugs and quirks in IE. These include problems calculating the dimensions of sized content (the "box model bug"), lack of support for advanced CSS selectors, and a number of display quirks ranging in importance from trivial to serious. You can get a list of CSS bugs from the website Position Is Everything ([http://www.positioniseverything.net/ http://www.positioniseverything.net/]).
By the Way
At the time of this book's writing, a preview version of Internet Explorer 7 is available for testing. Some, but not all, known CSS bugs in Internet Explorer 6 are being fixed in the new version. Because of the unstable nature of pre-release software, this book doesn't cover any Internet Explorer 7 CSS quirks or bugs.
===Internet Explorer Shells ===
An Internet Explorer shell is a browser which uses the Trident layout engine from Internet Explorer but provides its own user interface frameworkthe buttons, bars and menus that drive the program. This means that the look of the browser may not resemble Internet Explorer at all, but under the hood, it displays websites just as Internet Explorer would. Early IE shells were created for corporate branding purposes, but recent browsers based on Trident have focused on providing a better browsing experience for the user.
Maxthon from MySoft ([http://www.maxthon.com/ http://www.maxthon.com/]) is an example of such a shell. It adds features from other browsers such as tabbed browsing and ad blocking, while using the Trident layout engine for HTML and CSS display. This means that Maxthon inherits all of Internet Explorer 6's CSS quirks and bugs.
Fortunately, you don't need to do anything else to support users of Internet Explorer shells than you're already doing for IE 6 itself. Maxthon users don't need special attention beyond any browser hacks you might put in place anyway.
Other examples of Internet Explorer shells include America Online's AOL Explorer ([http://downloads.channel.aol.com/browser http://downloads.channel.aol.com/browser]) and Avant Browser ([http://www.avantbrowser.com/ http://www.avantbrowser.com/]).
===Older Versions of Internet Explorer ===
Internet Explorer 3 was the first major browser to implement cascading style sheetsor rather, it was the first to attempt to do so. By all measures it failed horribly in the attempt, producing nightmares for many early adopter web designers who tried to use CSS. Internet Explorer 4 was almost as bad, but things started slowly getting better in IE 5 and 5.5.
The early, buggy versions of Internet Explorer are all but gone from the Web, but you may still have to deal with Internet Explorer 5 and 5.5. These versions had decent CSS support but a number of serious problems related to page layout. In [ch24.html#ch24 Hour 24], you'll learn several ways to selectively hide or target CSS rules for those versions of Internet Explorer.
===Firefox ===
One of the earliest graphical browsers was called Netscape. Netscape was the top dog of browsers until Microsoft threw its market dominance around and knocked Netscape out of the competition. The Netscape browser eventually became part of the open source movement, in a project code-named Mozilla.
Mozilla Firefox is an open-source browser developed by the Mozilla Foundation and is available on a wide variety of platforms, including Microsoft Windows, Mac OS X, and Linux and other Unix-like operating systems. The most recent version, as this book is being written, is Firefox 1.5. Firefox provides standard features found on most browsers such as tabbed browsing, pop-up blocking, and good support for user style sheets.
Did you Know?
You can download Firefox for a wide variety of platforms from [http://www.mozilla.com/firefox/ http://www.mozilla.com/firefox/].
Firefox has very good overall CSS 2.1 support, which is one reason why it's used for the screenshots in this book. (The other reason is that it's one of the few current browsers available on all major operating systems, meaning it's very likely that anyone who picks up this book will be able to run Firefox.) There are a few quirks and bugs in Firefox, but in general you won't make big changes to your CSS or HTML to support Firefox users.
By the Way
At the time of this book's writing, a preview version of Firefox 2 is available for testing. Because of the unstable nature of pre-release software, this book doesn't cover any Firefox 2 CSS quirks or bugs.
===Other Gecko-Based Browsers ===
The layout engine used in Firefox is called Gecko, and it has been incorporated into a number of other browsers, some of them open source, and others that are closed but use the layout engine. Because Gecko provides a solid base for CSS implementation, you don't have any extra worries from Gecko-based browsersno more than those you have for Firefox bugs.
Netscape Browser version 8.1 ([http://browser.netscape.com/ns8/ http://browser.netscape.com/ns8/], Windows only) is an example of a browser that is Gecko-basedit is proprietary software developed by Netscape Communications (part of America Online), the current owners of the "Netscape" trade name. The user interface shell is closed source, but it uses the Gecko engine. Interestingly, it also can use Internet Explorer's Trident layout engine as well on certain pages.
Making the Gecko family tree even more complicated is the Mozilla browser ([http://www.mozilla.org/products/mozilla1.x/ http://www.mozilla.org/products/mozilla1.x/]), part of the Mozilla Application Suite, which is different from Mozilla Firefox and is currently at version 1.7. Mozilla-thebrowser is now giving way to the open-source project codenamed SeaMonkey, which released version 1.0 ([http://www.mozilla.org/projects/seamonkey/ http://www.mozilla.org/projects/seamonkey/]) in January 2006.
The Gecko layout engine is also used on several projects that give a "native" user interface environment, rather than Firefox's more generic, cross-platform user interface. Camino ([http://www.caminobrowser.org/ http://www.caminobrowser.org/]) is an open-source browser for Mac OS X that feels more like a native Macintosh application, with the Gecko engine doing the HTML and CSS display. K-Meleon ([http://kmeleon.sourceforge.net/ http://kmeleon.sourceforge.net/]) does the same for the Microsoft Windows operating system, and Epiphany ([http://www.gnome.org/projects/epiphany/ http://www.gnome.org/projects/epiphany/]) is the native Linux and Unix-like browser with a Gecko layout engine foundation.
Other examples of Gecko-based browsers include Flock ([http://flock.com/ http://flock.com/]) and Galeon ([http://galeon.sourceforge.net/ http://galeon.sourceforge.net/]).
===Older Versions of Netscape ===
Ancient versions of Netscapesometimes also called Netscape Navigator and Netscape Communicator, depending on the corporate policy of any given timehad no CSS support; Netscape 3 wouldn't recognize CSS rules or related attributes and elements. This actually made it a good test case for web developers who wanted to see how their sites would work without style sheets. These days, however, nobody uses Netscape 3 or earlier versions.
Netscape 4 was released in June 1997 and had notoriously bad CSS support. Version 4.02 contained a bug that would cause the entire browser to crash upon reading certain perfectly valid CSS rules. Later versions of Netscape in the 4.x series gradually improved their support for CSS, but even by the release of Netscape 4.8, it was still a very buggy browser that required major work-arounds to do complex CSS layouts.
Fortunately for web developers, Netscape 4 is all but dead. These days it is used by so few people that there's really little point in using the classic work-arounds and browser hacks for Netscape 4. Unless you are very conscientious, or somehow dealing with a group of primitive users who run Netscape 4 on stone computers, you won't have to make changes to your CSS or HTML to deal with Netscape 4.
Netscape 5 actually wasn't released; the browser developers skipped the numbering to "catch up" to Internet Explorer 6. Netscape 6 was the first Mozilla release, using the new Gecko engine developed by open source developers. The Gecko support for CSS started out strong and has gotten stronger since. In general, there are very few times in which you'll need to use browser hacks to deal with bugs in Netscape 6.2 or later.
Did you Know?
The Netscape website has an incomplete archive of old versions of Netscape for testing. As of early 2006, this appears to be unavailable, but you can find archived versions of Netscape browsers at [http://browsers.evolt.org/ http://browsers.evolt.org/].
===Opera ===
The Opera browser was developed by Opera Software of Oslo, Norway, and runs on Microsoft Windows, Mac OS X, and Linux and Unix-like operating systems. The current version is Opera 8.5, and it uses a layout engine named Presto. Presto has good support for CSS, which isn't that surprising considering that Håkon Wium Lie, one of the creators of the CSS specification, is a long-time Opera employee. Opera is also very customizable, and has good support for user-defined style sheets and user configuration options.
Did you Know?
You can download Opera for a wide variety of platforms from [http://www.opera.com/ http://www.opera.com/].
In general, there are very few situations in which you will need to provide special code for Opera only. Opera's CSS 2.1 support is generally quite solid and it does CSS-based layout without major problems.
By the Way
At the time of this book's writing, a preview version of Opera 9 is available for testing. The new version of Opera promises even better support for CSS; in late March, 2006, the Web Standards Project announced that Opera 9 passed the Acid2 test. Because of the unstable nature of pre-release software, this book doesn't cover any Opera 9 CSS quirks or bugs.
Early versions of Opera quickly gained a reputation for excellent CSS supportrelative to the existing browsers in the market. The 5.0 and 6.0 versions have seen Opera drop back into the middle of the pack for CSS support; there are some serious CSS limitations and bugs in Opera versions before Opera 7.
Fortunately, Opera users tend to be well informed about new browser releases and transition relatively quickly to newer, less buggy versions. For this reason, the older versions of Opera are not a serious problem at this time and rarely need any special attention.
===Safari ===
Safari is Apple Computer's web browser for the Mac OS X operating system. The layout engine in Safari is called WebCore and is based on the KHTML layout engine from Konqueror (which you'll learn about in just a moment). There are two current versions of SafariSafari 2 runs on Mac OS X version 10.4, and Safari 1.3 is for Mac OS X version 10.3. The layout engine is almost the same between the two versions, so for CSS purposes they're effectively the same browser.
Safari supports nearly all of CSS 2.1, including advanced selectors and CSS-based layout. You won't have many problems from Safari when you write standard CSS. In April 2005, it was reported that Safari 2 had successfully passed the Acid2 test.
Older versions of Safari had numerous CSS bugs, but Apple's software developers have been diligently rooting them out. The Safari browser is included with the Mac OS X operating system, and is automatically updated by Apple's software update program. This means very few users will have-out-of date versions of Safari; you won't have to worry about older, buggy versions.
Did you Know?
Apple's website for Safari is [http://www.apple.com/safari/ http://www.apple.com/safari/], and you can also install the most recent version through Software Update.
===Konqueror ===
Konqueror is an open-source browser developed as part of the K Desktop Environment (KDE) by volunteers for Linux, BSD, and other Unix-like operating systems. In addition to being a web browser, it also functions as a file manager and file viewer.
Konqueror uses a layout engine called KHTML, which was incorporated into Apple's WebCore layout engine. Konqueror also can operate in a mode where it uses Mozilla's Gecko layout engine.
In general, Konqueror's support for CSS is good, thanks in part to the contributions of Apple's WebCore developers back into the KHTML project, and in part because of the efforts of KDE's volunteers. In June 2005, Konqueror passed the Acid2 test from the Web Standards Project. Because of this high level of CSS support and Konqueror's small user base, you likely will never have to pay any special attention to Konqueror.
Did you Know?
You can download Konqueror from the KDE website at [http://konqueror.kde.org/ http://konqueror.kde.org/].
===WebCore ===
WebCore is the name of Apple's KHTML-derived layout engine for Mac OS X, which has been incorporated into other applications that need HTML rendering functions. Such applications have no more and no fewer problems than does Safari when it comes to CSS display; whatever you do for Safari will benefit these browsers as well.
The OmniWeb browser is one of the older small browsers still around, originally written in 1995 for the NeXTSTEP platform. Created by the Omni Group, OmniWeb first used its own proprietary layout engine, but in 2003 switched to using Apple's WebCore.
Did you Know?
OmniWeb is available for Mac OS X from [http://www.omnigroup.com/applications/omniweb/ http://www.omnigroup.com/applications/omniweb/].
===Other Browsers ===
In addition to the major browsers listed here, there are a number of smaller, less frequently used browsers you should be aware of. A huge list of many browsers can be found at the Evolt browser archive, [http://browsers.evolt.org/ http://browsers.evolt.org/]. It's also important for you to understand screen readers, a type of assistive technology employed by users who are blind.
===Lynx ===
Lynx is an old classic browser, which is most commonly used at a shell window or command prompt. Versions of Lynx can run on any system, although it is most commonly used on Unix-like operating systems, such as Linux or Mac OS X.
Lynx doesn't display images. It doesn't display colors. It doesn't do tables. It's the prototypical text-only browserand it definitely doesn't do CSS. This actually makes it ideal for testing your CSS-based designs to ensure that the underlying page can be used even if the style sheets are not understood.
[ch.htm#ch03fig03 Figure 3.3] is an example of how Lynx displays the author's websiteby ignoring the style sheet. You can compare this with [ch01lev1sec3.html#ch01fig02 Figure 1.2] in [ch01.html#ch01 Hour 1], which shows the same site in Firefox.
<div style="text-align: center;"> Figure 3.3. Lynx displays the author's personal website. [images/03fig03_alt.jpg [View full size image]][[Image:03fig03.jpg|500px]] </div>
Did you Know?
The download site for Lynx is [http://lynx.isc.org/ http://lynx.isc.org/], and the browser runs on many operating systems.
Many people use Lynx because it provides a faster and simpler interface to the Web, without the extra download time of a graphical browser. Other examples of similar text-based browsers include Links ([http://links.sourceforge.net/ http://links.sourceforge.net/]) and w3m ([http://w3m.sourceforge.net/ http://w3m.sourceforge.net/]).
===iCab ===
iCab is a web browser created by Alexander Clauss of Germany, and is available for both Mac OS X and for earlier versions of Mac OS, making it the primary browser for Macintosh users who have not upgraded beyond Mac OS 9. The CSS support in iCab is good, and in June 2005 it was reported that iCab was the second browser to pass the Acid2 test. This high level of CSS support plus the small user base of iCab mean that you are not likely to need to make special considerations for iCab.
Did you Know?
You can download iCab for Mac OS X (or earlier versions of Mac OS) from [http://www.icab.de/ http://www.icab.de/].
===Internet Explorer for Macintosh ===
Even though they both originated at Microsoft around the same time, Internet Explorer for Windows and Internet Explorer for Macintosh are literally different pieces of software that confusingly share the same name. Internet Explorer for Mac was bundled with new Apple computers for years, and for a while was the best browser for Macs. In fact, it was probably the best browser for any operating system in 2000.
Internet Explorer for Mac was developed separately from the Windows version, and had a number of features that its Windows counterpart didn't have. From a CSS perspective, the most important of these was the layout engine, code-named Tasman, which provided superior (but quirky) CSS support, especially when compared with Trident, the equivalent in Internet Explorer on Windows.
You'd have to worry about providing support for Internet Explorer for Mac, except for one thing: It's officially dead. The last version for Mac OS X was 5.2.3, and 5.1.7 for Mac OS 8 and 9both released in June 2003. Microsoft no longer has programmers working on it, Apple no longer bundles it with new computers, and as of January 2006 you can't even download it from Microsoft's site. They tell you to use Safari instead.
That's kind of a shame, really, but it makes your job easier as a web developervery few people are using Internet Explorer for Mac, and so you probably won't need to use the Mac IE workarounds from [ch24.html#ch24 Hour 24].
===Screen Readers ===
A screen reader is a specialized piece of software that works between the operating system and applications to read out a program's output to a user who is blind or visually impaired. This allows someone to access and use your website even if she is unable to see it.
The term "screen reader" is descriptive; most screen readers literally read only whatever they see on the screen. A screen reader needs to work with a browser to access the Web. The most common screen readers, such as JAWS or WindowEyes, are available only for Microsoft Windows, and work primarily with Internet Explorer.
This means that someone using a screen reader not only has to deal with the quirks of the screen reader and possible inaccessible web design techniques in the HTML, but also the CSS quirks of the browser. [ch24.html#ch24 Hour 24] has advice on how to make specific sections of your site available only to users with screen readers.
By the Way
You'll learn more about access by people with disabilities in [ch22.html#ch22 Hour 22], "Accessibility and Print Media."
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Test Drive a New Browser
The more browsers you use for testing, the better you'll be able to understand how your CSS works with those browsers. To get some hands-on experience with new browsers, follow these directions:
{| border="0"
|-
|
| >
|-
| '''1. '''
| Choose one or more browsers from earlier in this hour that will work on your operating system. If you've already used them all, download an older version or an alternate browser from the Evolt browser archive.
|-
| '''2. '''
| Install the browser and fire it up for surfing the Web.
|-
| '''3. '''
| Visit several websites that use CSS, including the site for this book, and the Web Standards Project, home of the Acid 2 test ([http://www.webstandards.org/action/acid2 http://www.webstandards.org/action/acid2]).
|-
| '''4. '''
| How does your experience using these browsers differ from your experience using your normal browser-of-choice? Note whether the CSS support is better or worse, and rank the browser you're using as "ancient," "broken," "quirky," or "compliant."
|}
|}
==Summary ==
Browser support is the key issue to understanding how to use Cascading Style Sheets effectively. Older browsers ignore CSS, compliant browsers support CSS, and other browsers provide either broken or quirky support for the standards. Knowing how to deal with the different types of browsers makes your style sheets more effective across a variety of platforms and browser versions.
The layout engine is the most important part of the browser, from a CSS perspective, as it determines how a web page is displayedand thus how web designers deal with that browser. The Acid2 test was developed as one benchmark to measure a browser's conformance with CSS.
Internet Explorer (for Windows) is an example of a quirky browserone that requires special attention from the web designer. Firefox, Opera, Safari, and related browsers are generally compliant with the web standards. Web designers need to be aware of these browsers and others when using CSS.
== Workshop ==
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | ''' Q.'''
| Which browsers should I use?
|-
| align="right" | ''' A.'''
| For your own personal use, you're free to use any you prefer! I like Safari and Firefox, myself. For testing purposes, as described in [ch02.html#ch02 Hour 2], "Getting Started with CSS," a good minimal set of browsers consists of Internet Explorer, Lynx, Firefox, Opera, and/or Safari. If you have access to additional platforms, you'll want to get appropriate browsers for those. In short, testing on as many browsers and platforms as possible will always be to your advantage.
|-
| align="right" | ''' Q.'''
| Are there more browsers out there than just those you've listed? What about older versions?
|-
| align="right" | ''' A.'''
| It turns out there are dozens and dozens of browsers that run on a wide variety of operating systems and configurations. You can find these alternate browsers, as well as older versions of more popular browsers, at the Evolt browser archive at [http://browsers.evolt.org/ http://browsers.evolt.org/].
|-
| align="right" | ''' Q.'''
| What do I look for when testing a web page with a browser?
|-
| align="right" | '''A.'''
| Well, the most obvious thing to check for is simple access to information. Are you able to read what's on the screen and get at the content of the HTML? Next, check for functionality. You may find that some browsers make it impossible to follow links or submit forms if your style sheet is not understood. Finally, check for aesthetics: Does the page look as you want it to look, or a reasonable approximation? If so, you're in luck; if not, you may want to change your style sheet by adding or removing properties. The workarounds in subsequent hours of this book can help you figure out how to make effects work in specific browsers.
|-
| align="right" | ''' Q.'''
| I don't have access to every browser ever created, and I certainly don't have multiple computers with a variety of operating systems. What can I do, short of spending a fortune on new hardware?
|-
| align="right" | ''' A.'''
| For starters, you can join any number of web forums or mailing lists that support web developers. Experienced designers are usually more than happy to help out new folks learning CSS. Another resource is BrowserCam ([http://www.browsercam.com/ http://www.browsercam.com/]) which, for a fee, offers screenshots and even remote access on a wide variety of computer and browser combinations.
|}
===Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | ''' 1.'''
| What will an older browser do if it encounters Cascading Style Sheets? Is this a good thing or a bad thing?
|-
| >
| >
|-
| align="right" | ''' 2.'''
| Which browsers are the closest to being fully compliant with the CSS specifications?
|-
| align="right" | ''' 3.'''
| Why is it important to test in Internet Explorer 6?
|}
===Answers===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1.'''
| An older browserone written before the CSS recommendation was issuedwon't understand anything about Cascading Style Sheets. This is not great, but it's not bad either because CSS is designed so that if you design your style sheets correctly, your web pages will still function even with CSS unavailable. The presentation may look dull or even awful, but your message will still shine through.
|-
| align="right" | '''2.'''
| The best browsers for CSS support currently are Firefox 1.5 (and derivatives), Opera 8.5, and Safari. Internet Explorer 7 and Opera 9 are very promising, but were not yet officially released as of the time this book was written.
|-
| align="right" | '''3.'''
| It's important to test your designs in Internet Explorer 6 because it's still used by a sizable number of web surfers, and because it contains serious problems that can render your designs unusable because of quirks and bugs.
|}
===Exercise ===
This would be an excellent time to assemble your test suite of browsers. Using the information provided in this chapter, assemble your own set of programs that you'll use to check your designs. A variety of browsersancient, broken, quirky, and compliantis a good approach. Will you include minor browsers in your test suite? How will you deal with programs that don't run on your primary computer? If you use Microsoft Windows, you can't easily test on Safari. Write down your testing decisions and procedures.
c8rltyinnwpfzj3d86x0u8j7o3qlovg
User:Bartlett/04
2
2107
39214
5492
2026-04-13T06:03:15Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39214
wikitext
text/x-wiki
= Hour 4. Using CSS with HTML =
; What You'll Learn in This Hour:
* What the different types of HTML are and how to use them with Cascading Style Sheets
* The three ways to link CSS to styles and when to use each
* How to create an external style sheet for your entire website
* How to embed style sheets directly in your HTML
* How to create CSS rules based on the HTML attributes of <code>class</code> and <code>id</code>
In previous hours, you've used Cascading Style Sheets to style your HTML pages by linking in an external CSS file. The true power of CSS and HTML really shines through only when you understand both of these complementary languages, how they relate to each other, and how they can be used effectively.
HTML and CSS blend together well not by coincidence but by design; they literally were made for each other. Using that designed synergy is the key to creating effective presentations on your websites.
|}
./ ADD NAME=CH04LEV1SEC1.HTML
== Types of HTML ==
To fully understand how HTML and CSS work together, it's important to know what we're talking about when we talk about HTML. Hypertext Markup Language is defined by formal recommendations issued by the World Wide Web Consortium (W3C), just as the Cascading Style Sheets language is.
HTML 4.01
The most recent version of HTML is HTML 4.01. HTML 4.01 is an updated version of HTML 4.0, which itself was an improvement over HTML 3.2 and 2.0. (There was no official version numbered 1.0; the first version of HTML was a quickly changing adhoc language put together primarily by World Wide Web creator Tim Berners-Lee. When efforts began to standardize HTML, numbering started with 2.0.)
HTML 4.01 comes in three "flavors"Strict, Transitional, and Frameset. The type of HTML used on your page is indicated by the <code>DOCTYPE</code> statement you place as the first line of the page. Each flavor has a set of tags and attributes that are allowed and disallowed; they're like a variant of spoken human languages, in a way.
What's the difference between the three? HTML Strict relies entirely on CSS for presentational styling; HTML Transitional includes some HTML attributes and elements for presentation effects; and HTML Frameset is used to create frames.
Strict
HTML 4.01 Strict is a version of HTML that removes nearly all the presentational markupthe <code><span style="text-align: center;"></code> tags, the <code>color</code> and <code>link</code> attributes on <code><body></code>, the <code>border</code> attribute, and other old standbys that have been used for years to make pages more visually appealing. So what's a web developer to do if she doesn't want boring pages?
The answer should be clear to anyone reading this book: Use Cascading Style Sheets! The Strict variety relies heavily on CSS for presentation; that's why it's considered strict.
To declare your page as using HTML Strict, put the following at the very top of your HTML file as the first line:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
</pre></div>
You'll want to use HTML Strict if you're designing primarily for newer browsers or if you don't mind giving unstyled pages to older browsers that ignore CSS.
<div>Did you Know?
Several recent browsers have a special compatibility mode for HTML and CSS where they adhere more closely to the published standards. Firefox and Internet Explorer turn on this mode when they encounter a valid <code>DOCTYPE</code> for HTML Strict and for a few other <code>DOCTYPE</code> declarations; other pages are shown in a "quirky" mode for backward compatibility with older browsers. For more information, see the following URLs:
* [http://www.mozilla.org/docs/web-developer/quirks/ http://www.mozilla.org/docs/web-developer/quirks/]
* [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp]</div>
Transitional
HTML 4.01 Transitional adds back in those presentation markup tags and attributes, although some, such as the <code></code> tag, are considered deprecated. What's deprecated mean? That's W3C-talk that means "This is still within the formal specification, but you really should not use it, and it won't be in future versions of this language." Not all presentation markup in HTML 4.01 is deprecated, and you can freely use those nondeprecated elements and attributes as part of HTML 4.01 Transitional.
Transitional HTML is so named because at the time the HTML 4.0 specification was released, few browsers had particularly good CSS support, which meant Strict wasn't really usable on most websites, unless you wanted plain gray or white backgrounds, black text, and default fonts.
Transitional is intended as a temporary measure until browsers catch up. So far, the browsers have been slow in catching up; Transitional HTML is therefore what I suggest for most web development. If you are concerned about delivering your design to the majority of browsers out there, you should use HTML Transitional.
<div>By the Way
You can use CSS and Transitional HTML together, and in fact that's highly recommended; CSS rules are followed if the browser understands CSS, and if not, it looks at the HTML attributes or elements instead. This enables you to have "fall-back" presentations in the HTML markup for older or limited browsers that don't support CSS.</div>
This is the DOCTYPE statement for HTML 4.01 Transitional; it should be the very first line of your document:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
</pre></div>
Frameset
The Frameset variety of HTML 4.01 is intended for use only in creating frameset pagesthose that use the <code><frameset></code> element, along with <code><frame></code> and <code><noframes></code>, to lay out different windows within the page. It's otherwise identical to Transitional HTML; you need to use this only on the page that establishes the frames, not on the frames contained within that set (unless they define other <code><frameset></code> elements, of course).
You'll want to use HTML Frameset whenever you're creating a frame presentation and at no other time otherwise.
The DOCTYPE for HTML 4.01 Frameset is
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
</pre></div>
XHTML
XHTML 1.0 is a version of HTML 4.01 written as XML, which means it follows the very specific rules and structure imposed on XML documents. The tags are all the same as in HTML, but how you write them may be different. For example, all XHTML tags are lowercase, and all attribute values have to be quoted. XHTML 1.0 comes in the same three varieties: Strict, Transitional, and Frameset. The next version, XHTML 1.1, is available only in a Strict flavor and thus relies entirely on CSS for presentation.
Using CSS with XHTML is pretty much the same as using CSS with HTML. Because XHTML represents a move forward to an XML-based web, you may end up migrating from HTML to XHTML sometime in the future. For this reason, I recommend writing all your CSS rules so that element names are written in lowercase letters. It doesn't matter in HTML, but it will in XHTML, and making this a habit will save you time now if you choose to use XHTML in the future: You won't need to rewrite all your style sheets.
Validating HTML
Validating your HTML means that you run your page through an HTML validator, which is a program to analyze HTML code and ensure that the code you write is in compliance with the HTML specification. In this way, an HTML validator is like a spellchecker or grammar checker for HTML.
By validating your HTML, you can catch errors in your code, such as misspelled attributes (like <code>aling</code> or <code>scr</code>) or closing tags you've accidentally left out. Validation also improves your compatibility with browsers: Valid HTML code is closer to what browsersespecially newer onesare expecting. You can validate against your chosen variety of HTML (Strict, Transitional, or Frameset) to ensure that you're using only tags and attributes that are within that subset of the language.
From the standpoint of troubleshooting your style sheet, it's much easier to catch CSS errors if you know you don't have many HTML errors. I've spent many hours chasing down what I thought were mistakes in my CSS when really I'd just written an HTML attribute or element incorrectly.
I recommend always making sure your HTML is valid. Valid code conforms to the appropriate HTML Document Type Definition, which is a formal specification of HTML syntax. You use the DOCTYPE statement as the first line of your HTML file to indicate the correct version of HTML.
To check your HTML, you can use one of the validation services listed here:
* W3C's HTML Validator ([http://validator.w3.org/ http://validator.w3.org])
* Web Design Group's HTML Validator ([http://www.htmlhelp.com/tools/validator http://www.htmlhelp.com/tools/validator])
<div>Did you Know?
If a validator locates a problem with your HTML files, you can correct them by hand, in an HTML editor, or by using the HTML Tidy program created by Dave Raggett of the W3C. You can download HTML Tidy for free for various operating systems from [http://www.w3.org/People/Raggett/tidy/ http://www.w3.org/People/Raggett/tidy/]. It's well worth the time.</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Validate a Web Page
The process of checking your HTML is so important to creating good CSS that you should take the time out now to get familiar with it:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Choose a validator from the list just given and go to that site.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Enter the URL of a web page you've worked on, or upload the file directly from your computer.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Make sure your web page contains a <code>DOCTYPE</code> statement as the first line, preferably Transitional (if you use HTML attributes for appearance) or Strict (if you use pure CSS).<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Check the validation results. You may have tags that aren't closed, obsolete elements or attributes, or plain, ordinary typos. What would it take to fix your page?<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Make those changes and revalidate until your page passes. Congratsyou're writing valid HTML.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>For fun, validate other websites, including major destinations on the Internet such as search engines or news portals. How serious are they about valid HTML?<br /><br /></div>
|}
|}
<div>By the Way
The code examples given in this book don't include the DOCTYPE statement, so technically they aren't valid. This was done deliberately to conserve space as well as attention; a complex DOCTYPE at the beginning of an HTML example can distract from whatever point I'm trying to make by providing the HTML code. However, I do ensure the code is otherwise valid, and I ask for your forgiveness for lack of DOCTYPE. Do as I say, not as I do, in this specific case.</div>
./ ADD NAME=CH04LEV1SEC2.HTML
== Style Sheets in HTML ==
The Cascading Style Sheets language was specifically designed to work with HTML to build web pages. CSS rules can appear within linked style sheets, embedded style sheets, or inline style attributes.
The CSS rules that you will write for each method are generally the same, but the way your HTML and your CSS work together depends on the method you used. So far, you've worked with linked external style sheets, as that's the most useful way of dealing with Cascading Style Sheets and offers the most flexibility.
<div>By the Way
Examples in this book, unless stated otherwise, generally assume you're using a linked style sheet, and complete listings are shown as external CSS files. CSS rules (and declarations, for inline styles) are written the same regardless of how they're applied to HTML, so you'll get the same styling effects if you use linked, embedded, or inline style rules.</div>
Linked Style Sheets
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," you learned about how to create external style sheets and link them with the <code><link></code> element in HTML. Linking style sheets in this manner gives you the greatest portability and ease of maintenance when designing your styles for your website.
Many sites use one or more global style sheets that are linked from every page on the site. Using a global style sheet lets you make changes to one file that will affect the appearance of every page on your site. With a simple change, you can switch the colors, fonts, sizes, and more across your whole website.
External style sheets let you separate your content fully from your styles, which means it's easy to replace those styles with something else. For example, you could easily change the appearance of a site by replacing the old style sheet with a new set of rules under the same name.
You can also link in specific style sheets for specific uses, such as one style sheet per company division, as well as a global style sheet for the whole company, on a corporate website. You can link style sheets for specific types of output devices as well, using styles written just for those types of devices. For example, you could create a style sheet specifically for handheld wireless devices, screen readers, or printers. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," you'll learn more about designing for alternate output devices.
As seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], you can create linked style sheets by using the HTML <code><link></code> element in the <code><head></code> section of the page. A number of attributes can be used with the <code><link></code> element, but for our purposes only the following options are important:
<div><pre><link rel="relationship" href="URL" type="content-type" media="media-type">
</pre></div>
The <code><link></code> tag is actually an all-purpose linking element; it doesn't just define style sheets but also can be used to create any link between the entire document and some other URL location. To use it to identify a linked document as a style sheet, you need to specify what the relationship is. Other types of relationships include <code>contents</code> (specifying the location of a table of contents), <code>alternate</code> (an alternate version of the page for specific types of output devices or languages), and <code>glossary</code> (for a glossary of terms). To indicate a style sheet, however, you need only <code>rel="stylesheet"</code>.
The <code>href</code> attribute indicates the location of the style sheet and is a normal web URL. The location can be relative or absolute; without a directory path, it's assumed to be within the same directory, but you can use any URL path (and machine name), as with any other link in HTML.
Your style sheet even can reside on a different web server than your HTML file; in fact, this is a good way to quickly and easily add style to a web page. However, this isn't a license to merely steal someone else's work, any more than viewing the HTML source is an invitation to swipe source code. Use an offsite style sheet only if the site operator has explicitly given permission for it to be used in such a manner. Keep in mind that many web hosting services charge for bandwidth usage, so you may be costing someone money each time you use that style sheet without permission. Also remember that because you don't control the style sheet, it could affect the look of your web page if it's changed or removed.
<div>Did you Know?
The World Wide Web Consortium offers a number of style sheets for public use at [http://www.w3.org/StyleSheets/Core/ http://www.w3.org/StyleSheets/Core/]. You can use these to test styles on your pages by applying them as linked style sheets.</div>
The <code>content-type</code> attribute of the <code><link></code> tag indicates the styling language of the linked style sheet. For Cascading Style SheetsLevels 1, 2, and 2.1this should be <code>text/css</code>. This is also the MIME type that your server should return when serving up CSS files. All modern web servers recognize the file <code>extension.css</code> as being a CSS file and send an appropriate MIME type. If you name your file something ending in <code>.css</code>, the server sends it as <code>text/css</code>. If you think your server doesn't do this properly for some reason, you should consult your web server administrator or the documentation for your server software. Also, if you write a server-side script to create a CSS document in, for example, Perl, ASP, or PHP, you should make sure you set the content-type HTTP header line to <code>text/css</code>.
The <code>media</code> attribute tells the browser with which types of media or output device categories the style sheet should be used. A browser applies different style sheets depending on the mediafor example, one style sheet for printing and another for onscreen display. Style sheets for other media are ignored, and those rules aren't applied.
For the most part, we are concerned with the media-type <code>screen</code>, which means visual, onscreen display. Because <code>screen</code> is assumed to be the default, you don't need to specify this unless you're linking a style sheet for another type of output device. Other media types include <code>printer</code> (for printed documents), <code>braille</code> (for tactile Braille devices), <code>aural</code> (for speech synthesizers), and <code>all</code>, which covers all media types. You can list more than one media type by separating them with commas, such as <code>screen, printer</code>.
<div>By the Way
You'll learn more about the media types <code>printer, braille</code>, and <code>aural</code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22].</div>
Embedded Style Sheets
Another way to apply CSS to HTML is by embedding the CSS directly within the HTML file with the <code><style></code> tag. Your CSS rules are then part of the same file as the HTML, which makes editing easier, at least at first. An embedded style sheet also is useful for rules that apply only to a specific page and don't need to be used by other parts of the site, which helps keep the size of your global style sheet relatively small. For example, if you have a rule that applies only to the front page of the site, you don't need that in a site-wide style sheet that is accessed by every page, even those that don't use the rule.
On the other hand, it's also harder to maintain and update a site only with embedded style sheets; you have to edit every single page when you want to make a change in the appearance of the site.
For this reason, I prefer linking instead of embedding CSS, but in many situations it's easier or more appropriate to use an embedded style sheet. For example, when testing CSS rules or developing a style sheet, it may be easiest to use an embedded style sheet and then convert it to an external style sheet for production use.
<div>Did you Know?
How do you convert an embedded style sheet to an external one? Simple: You just cut the content of the <code><style></code> tag and paste it into a new file with a name ending in <code>.css</code>. Here's the tricky part: If there are any URL references (such as background images) in your CSS, you need to make sure that they apply relative to the new style sheet and not the original document. To convert an external style sheet to an embedded one, just paste it into a <code><style></code> element and check the URLs again.</div>
To embed a style sheet, use the <code><style></code> tag, which can be used only within the <code><head></code> of a web page:
<div><pre><style type="text/css" media="media-type">
... CSS rules go here ...
</style>
</pre></div>
The <code>type</code> attribute is required. Theoretically, this is because a different style language could be used with HTML, although in practice only CSS is ever used. The media attribute is optional; the default is <code>screen</code>. As with the <code><link></code> element, you can set multiple media types by listing them with comma separators.
You can have more than one <code><style></code> element within the <code><head></code> section of the page if you like; for example, you could have one for <code>screen</code> and one for <code>printer</code>. (You could have two for <code>printer</code>, if you want, but it usually makes more sense to combine them together in a single <code><style></code> tag.)
Hiding CSS Code from Older Browsers
Browsers shouldn't ever reveal the contents of a <code><style></code> tag. Even if a browser doesn't support CSS, it shouldn't display the rules to the user. However, some very ancient browsers were written before CSS was created, and because these browsers don't know what the <code><style></code> tag is, they just display it as HTML text, which is just a mess. The best way to avoid this is by wrapping your CSS rules within HTML comments:
<div><pre><style type="text/css" media="screen">
<!--
... CSS rules go here ...
-->
</style>
</pre></div>
The older browsers interpret this as just a normal comment, whereas the modern browsers understand the CSS. As nearly every browser used these days understands the <code><style></code> tag, it's not particularly necessary, but it doesn't hurt anything to do it, either. The examples in this book don't include comments.
Inline Style Attributes
You set inline styles on HTML tags by using the <code>style</code> attribute. Such a style applies to that particular element, or possibly to that element's children, if the rule's properties can be inherited.
<div>By the Way
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], "Cascading and Inheritance," you'll learn more about how HTML tags inherit CSS properties from other tags.</div>
The <code>style</code> attribute can be set on nearly any HTML tag that is displayed by a browser. The attribute contains the declaration of a CSS rule but not a selector; the tag itself (and its content) serves as the selector.
Here's an example of using inline styles to set some CSS properties:
<div><pre><table style="font-family: Arial; font-size: large">
<tr>
<th style="color: blue">
Writer's Name
</th>
<th style="color: green">
Primary Genre
</th>
</tr>
<tr><td>Kynn</td><td>Technical (Web Design)</td></tr>
<tr><td>Nick</td><td>Fiction (Horror)</td></tr>
<tr style="color: red">
<td>R. Francis</td>
<td>Non-Fiction (Podcasting)</td>
</tr>
</table>
</pre></div>
As you can see, the selector is unnecessary; the style is applied to the tag on which the <code>style</code> attribute is set. Also, there are no ending semicolons on the rules. Within <code>style</code> attributes, the ending semicolon is optional. I usually write it myself because it makes it easier to add additional rules if I need them.
Style attributes are most useful for single-point changes, such as changing the color of an announcement to make it stand out, like this:
<div><pre><h1 style="color: red;">
Just Added: New book signing at City Lights on Feb. 5.
</h1>
</pre></div>
As you're building a web page, it may seem easier to use inline styles rather than to create a separate style sheet; you won't have to go back to the <code><style></code> section or an external style sheet, but can just type the declaration directly into an attribute. However, in the long run it's harder to maintain inline styles because they'll be scattered throughout your HTML source.
Ultimately, the use of inline styles reduces the separation of content from presentation because it mixes the two together within the same markup. It makes more sense to use HTML for structure and content and CSS for presentation; in this regard, inline CSS is just a single step up from HTML presentation attributes.
In general, you should avoid using inline styles unless you have a very specific use in mind. If you have to style more than one part of your page the same way, it's better to use an embedded or external style sheet and define a class instead.
<div>Did you Know?
It's perfectly valid to use all three methods for using CSS rules within one documentfor example, an external style sheet for the entire site applied with a <code><link></code> tag; an embedded style sheet inside a <code><style></code> tag for rules specific to that web page; and inline styles set on individual elements with the <code>style</code> attribute.</div>
./ ADD NAME=CH04LEV1SEC3.HTML
== Classes and IDs ==
In addition to setting styles based on HTML elements, CSS allows for rules based on two optional attributes in HTML: <code>class</code> and <code>id</code>. Each of these can serve as the selector part of a CSS rule and can be set on any visible HTML tag.
<div>By the Way
For even more selectors you can use with HTML and CSS, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors," and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors."</div>
The <code><div></code> and <code><span></code> elements really come into their own with the <code>class</code> and <code>id</code> selectors. Through the use of <code>class</code> and <code>id</code> attributes, <code><div></code> or <code><span></code> tags can be made to have nearly any effect and presentation, which is often good but sometimes bad. When using <code>class</code> and <code>id</code> markers, you shouldn't neglect other markup tags that might be better suited for the task at hand. For example, you might decide to create an <code>emphatic</code> class for emphasizing portions of your text, and then use a CSS rule to make it bold. It's better to instead just use the <code><strong></code> tag in HTML and apply CSS to style it as you want<code><strong></code> already has a meaning in HTML (which is "emphasized text"). Use <code><div></code> or <code><span></code> only if there are no appropriate HTML tags you can style or restyle.
The <code>class</code> Attribute in HTML
The <code>class</code> attribute is used to define a related group of HTML elements on a page. They might have the same function or role, but in a CSS context, it means they have the same style rules applied to them. (The <code>class</code> attribute could be used for more than just styling, but in practice it's rarely used for any other purpose.)
The elements within a class can be of any type; one might be a <code><p></code>, another a <code><span></code>, and a third an <code><img></code>. That's perfectly fine; they will have the same style rules applied to them, but the fact that each one has a default presentation (defined by the browser or the HTML specifications) means those styles will be applied relative to the way they're normally rendered.
To create a class, you simply have to give it a name. A class name may be nearly anything, but has to be one word; in practice, it's best to stick to letters and numbers. Avoid using underlines, periods, and other non-alphanumeric characters when naming your classes.
You can name a class anything you like; it's basically just an arbitrary word used to group these items together. A descriptive name is good, especially one that describes function instead of presentation. For example, <code>class="detail"</code> makes more sense than <code>class="bluetext"</code>; if I can't come up with a good descriptive name, I'll use something arbitrary instead, such as the names of planets or the seven dwarves. Class names are not inherently case sensitive, but you should try to use the same case of characters when writing your HTML and your CSS rules.
After you've chosen a name for your class, you just have to assign HTML elements to that class by setting the class attribute on each. A given HTML element can be part of one or more classes if they are separated with spaces. Here are some examples:
<div><pre><div class="p1">
<h2 class="q2">Meeting Times</h2>
<p class="r3">
We will be meeting every other Wednesday, at
<span class="q2 j4">7:30 p.m.</span>
</p>
</div>
</pre></div>
In this example, the <code><div></code> is part of the <code>p1</code> class. The <code><h2></code> and the <code><span></code> are both part of the <code>q2</code> class. The <code><p></code> is part of the <code>"r3"</code> class, and the <code><span></code> is also part of the <code>j4</code> class.
Class Selectors in CSS
After you've defined a class in your HTML, you can use it as a class selector in CSS. Class selectors are indicated by a period (<code>.</code>) before the name of the class, like this:
<div><pre>.q2 { color: blue; }
.r3 { font-family: Arial; }
</pre></div>
You can combine an element selector with a class selector; the result selects only those members of the class that are of that particular element. (Or, it selects only those elements that are members of that particular classsame thing.) Just put the name of the element directly in front of the period and then the class name. For example:
<div><pre>span.q2 { font-size: large; }
p.r3 { color: green; }
</pre></div>
The first refers to all <code><span></code> elements with <code>class="q2"</code>; the latter to all <code><p></code> elements in the <code>r3</code> class. You can combine together several classes within a rule to select only elements that have those classes listed (separated by spaces, as described before) by separating them with periods, as shown here:
<div><pre>.q2.j4 { font-family: Arial; }
</pre></div>
This rule would select the <code><span></code>, which is part of both class <code>q2</code> and class <code>j4</code>.
A complete example of using class selectors is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex01 Listings 4.1] and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex02 4.2], and the result of displaying in a browser is presented in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04fig01 Figure 4.1].
Listing 4.1. HTML Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><html><br /><!-- This is class-4.1.html --><br /><head><br /><title><br />Class Selectors in Action<br /></title><br /><link type="text/css" rel="stylesheet" href="5-3.css"><br /></head><br /><body><br /><h1 class="mercury"><br />Welcome!<br /></h1><br /><div class="mars"><br /><p class="saturn"><br />This is a short page to tell you about our writers<br />group. We meet in the bookstore every other Wednesday;<br />our meetings are at <span class="mercury">7:30 p.m.<br />sharp.</span><br /></p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Listing 4.2. CSS Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* This is class-4.2.css */<br />.mercury { color: white; background-color: black; }<br />.mars { font-family: Arial; }<br />.saturn { color: black; }<br />h1.mercury { font-family: Verdana; color: silver; }<br /></pre></div><br />
|}
Figure 4.1. Firefox displays the style rules defined with class selectors.
[[Image:04fig01.jpg|300px]]
The <code>id</code> Attribute in HTML
The HTML attribute <code>id</code> is similar to the <code>class</code> attributeit can be set on nearly any tag and can be used as a CSS selectorbut is much more restricted. Only one tag on a page can have a given <code>id</code>; it must be unique within the page and is used to identify just that element. An id attribute's value has to begin with a letter and can be followed by letters, numbers, periods (<code>.</code>), underlines (<code>_</code>), hyphens (<code>-</code>) or colons (<code>:</code>); however, if you're using it as a selector in CSS, it's safest to stick to just letters and numbers. Case matters, so be consistent in the case of your <code>id</code> attributes. Here's an example:
<div><pre><a href="next.html" id="next">The next page</a>
</pre></div>
<code>id</code> Selectors in CSS
An <code>id</code> selector is indicated by a # (the hash, also called the pound sign) before the value of the <code>id</code>. For example:
<div><pre>#next { font-size: large; }
</pre></div>
Why would you want to use <code>id</code> selectors and not class selectors? Good question. A class selector is more flexible; it can do anything an <code>id</code> selector can do and more. If you want to reuse the style, you can do it with a class selector by adding new elements to the class, but you can't do that with <code>id</code> selectors because an <code>id</code> value must be unique in a document, and only one element on the page can have that value.
An <code>id</code> selector is useful if you know that you have to identify one unique item within a pagefor example, the Next link, or maybe a common navigation or layout element that appears on each page. In general, <code>id</code> selectors are less useful than class selectors when you use CSS with HTML. When using CSS with XML, however, <code>id</code> attributes play a larger role because XML uses <code>id</code> attributes more than HTML does.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Using CSS with HTML
To apply what you've learned this hour, why not create an HTML page, create an external CSS file and link it to the HTML file, and add embedded and inline styles? This will make you familiar with the ways HTML and CSS are used together in web design.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create a basic HTML document with headers, paragraphs, <code><div></code> and <code><span></code> tags, and other markup. Be sure to set some <code>class</code> and <code>id</code> attributes on your tags. Save this HTML file.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Create a CSS file with rules based on element selectors, <code>class</code> selectors, and <code>id</code> selectors. Save this CSS file.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Use <code><link></code> to apply the CSS style sheet to the HTML file. View the results in an HTML browser that supports CSS.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Add more styles directly into the HTML file by creating a <code><style></code> element in the <code><head></code>; view the results.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Create some inline styles using the <code>style</code> attribute, and check your creation in a browser.<br /><br /></div>
|}
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourwith external style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
|}
./ ADD NAME=CH04LEV1SEC4.HTML
== Summary ==
In this hour, you learned about the three flavors of HTML 4.01 and how CSS is used in each, and you learned about the benefits of validating your HTML code. You learned about three tools for applying Cascading Style Sheets to HTML pages: external style sheets that use the <code><link></code> tag, embedded style sheets defined inside a <code><style></code> tag, or specific styles set with the <code>style</code> attribute. You learned how to set <code>class</code> and <code>id</code> attributes in HTML and how to create rules using <code>class</code> and <code>id</code> attributes as selectors.
./ ADD NAME=CH04LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1a1 Q.]'''
| Will there be such a thing as HTML 5?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1 A.]'''
| No, and yes, and kind of. The W3C has stopped work on developing HTML and is concentrating on XHTML instead. The next version of HTML will be XHTML 2.0, and in addition to being composed of distinct modules, it will have new elements and attributes that don't currently exist in HTML. You can track the progress of XHTML 2's development at [http://www.w3.org/Markup/ http://www.w3.org/Markup/].
In addition, a group called the Web Hypertext Application Technology Working Group (WhatWG), a group of browser developers and other interested parties, is working on what they call Web Applications 1.0an extension to XHTML 1.0, which is informally referred to as "HTML 5." Whether these efforts will bear fruit as a replacement for HTML 4.01 is unclear; you can follow the WhatWG's progress at [http://www.whatwg.org/ http://www.whatwg.org].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2a2 Q.]'''
| Can you use selectors with inline styles? For example, <code><div style=".dot { color: black; }"></code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2 A.]'''
| No; a style attribute contains only the declaration part of a CSS rule, not the selector portion. The selector is the content of the element itself.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3a3 Q.]'''
| You said I could use style attributes, embedded style sheets, and linked style sheets on the same HTML page. What happens if they have different values for the same property?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3 A.]'''
| When two or more rules conflict, the method of resolving the conflict is known as the cascade. You'll learn more about this in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], but the general principle is that the more specific rule usually wins.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1a1 1.]'''
| What HTML tag is used to insert an embedded style sheet? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2a2 2.]'''
| What HTML tag is used to associate an external style sheet with an HTML tag? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3a3 3.]'''
| What is the default value for the <code>media</code> attribute?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4a4 4.]'''
| What is the difference between a class selector and an <code>id</code> selector? When would you use each?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5a5 5.]'''
| What are the three "flavors" of HTML, and which one relies on CSS for nearly all presentation styling?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6a6 6.]'''
| What does HTML validation check for?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1 1.]'''
| The <code><style></code> tag is used to embed a style sheet in an HTML file. The main attributes are <code>type</code>, which should be <code>text/css</code>, and an optional <code>media</code> attribute.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2 2.]'''
| The <code><link></code> tag can be set in the <code><head></code> of an HTML file to link to an external style sheet. The primary attributes used with CSS are <code>type, media, rel="stylesheet"</code>, and <code>href</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3 3.]'''
| The default value of the <code>media</code> attribute is <code>screen</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4 4.]'''
| An <code>id</code> selector applies to only one element within each document, whereas a <code>class</code> selector can be used to select any element within that class. You'd use <code>class</code> when you needed to select multiple elements, and <code>id</code> if you wanted to select only a single, unique element.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5 5.]'''
| The three types of HTML 4.01 are Strict, Transitional, and Frameset. HTML Strict has almost no presentational markup and depends on CSS to provide styling instructions.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6 6.]'''
| HTML validation checks your HTML code against the formal specification and DTD for the HTML language.
|}
Exercise
Create your own web page and use what you've learned so far to style your page. Choose your type of HTML, set a <code>DOCTYPE</code>, and validate the page. Use <code><link></code> and <code><style></code> tags to set up your style sheet, and add inline rules with the <code>style</code> attribute.
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourexternal style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
./ ADD NAME=CH05.HTML</span>
7etimgenggdxnwi3ft04ie610q2nuo6
39285
39214
2026-04-13T06:28:20Z
Redmin
5511
Restoring markup mistakenly removed by my bot
39285
wikitext
text/x-wiki
= Hour 4. Using CSS with HTML =
; What You'll Learn in This Hour:
* What the different types of HTML are and how to use them with Cascading Style Sheets
* The three ways to link CSS to styles and when to use each
* How to create an external style sheet for your entire website
* How to embed style sheets directly in your HTML
* How to create CSS rules based on the HTML attributes of <code>class</code> and <code>id</code>
In previous hours, you've used Cascading Style Sheets to style your HTML pages by linking in an external CSS file. The true power of CSS and HTML really shines through only when you understand both of these complementary languages, how they relate to each other, and how they can be used effectively.
HTML and CSS blend together well not by coincidence but by design; they literally were made for each other. Using that designed synergy is the key to creating effective presentations on your websites.
|}
./ ADD NAME=CH04LEV1SEC1.HTML
== Types of HTML ==
To fully understand how HTML and CSS work together, it's important to know what we're talking about when we talk about HTML. Hypertext Markup Language is defined by formal recommendations issued by the World Wide Web Consortium (W3C), just as the Cascading Style Sheets language is.
HTML 4.01
The most recent version of HTML is HTML 4.01. HTML 4.01 is an updated version of HTML 4.0, which itself was an improvement over HTML 3.2 and 2.0. (There was no official version numbered 1.0; the first version of HTML was a quickly changing adhoc language put together primarily by World Wide Web creator Tim Berners-Lee. When efforts began to standardize HTML, numbering started with 2.0.)
HTML 4.01 comes in three "flavors"Strict, Transitional, and Frameset. The type of HTML used on your page is indicated by the <code>DOCTYPE</code> statement you place as the first line of the page. Each flavor has a set of tags and attributes that are allowed and disallowed; they're like a variant of spoken human languages, in a way.
What's the difference between the three? HTML Strict relies entirely on CSS for presentational styling; HTML Transitional includes some HTML attributes and elements for presentation effects; and HTML Frameset is used to create frames.
Strict
HTML 4.01 Strict is a version of HTML that removes nearly all the presentational markupthe <code><span style="text-align: center;"></code> tags, the <code>color</code> and <code>link</code> attributes on <code><body></code>, the <code>border</code> attribute, and other old standbys that have been used for years to make pages more visually appealing. So what's a web developer to do if she doesn't want boring pages?
The answer should be clear to anyone reading this book: Use Cascading Style Sheets! The Strict variety relies heavily on CSS for presentation; that's why it's considered strict.
To declare your page as using HTML Strict, put the following at the very top of your HTML file as the first line:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
</pre></div>
You'll want to use HTML Strict if you're designing primarily for newer browsers or if you don't mind giving unstyled pages to older browsers that ignore CSS.
<div>Did you Know?
Several recent browsers have a special compatibility mode for HTML and CSS where they adhere more closely to the published standards. Firefox and Internet Explorer turn on this mode when they encounter a valid <code>DOCTYPE</code> for HTML Strict and for a few other <code>DOCTYPE</code> declarations; other pages are shown in a "quirky" mode for backward compatibility with older browsers. For more information, see the following URLs:
* [http://www.mozilla.org/docs/web-developer/quirks/ http://www.mozilla.org/docs/web-developer/quirks/]
* [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp]</div>
Transitional
HTML 4.01 Transitional adds back in those presentation markup tags and attributes, although some, such as the <code><font></code> tag, are considered deprecated. What's deprecated mean? That's W3C-talk that means "This is still within the formal specification, but you really should not use it, and it won't be in future versions of this language." Not all presentation markup in HTML 4.01 is deprecated, and you can freely use those nondeprecated elements and attributes as part of HTML 4.01 Transitional.
Transitional HTML is so named because at the time the HTML 4.0 specification was released, few browsers had particularly good CSS support, which meant Strict wasn't really usable on most websites, unless you wanted plain gray or white backgrounds, black text, and default fonts.
Transitional is intended as a temporary measure until browsers catch up. So far, the browsers have been slow in catching up; Transitional HTML is therefore what I suggest for most web development. If you are concerned about delivering your design to the majority of browsers out there, you should use HTML Transitional.
<div>By the Way
You can use CSS and Transitional HTML together, and in fact that's highly recommended; CSS rules are followed if the browser understands CSS, and if not, it looks at the HTML attributes or elements instead. This enables you to have "fall-back" presentations in the HTML markup for older or limited browsers that don't support CSS.</div>
This is the DOCTYPE statement for HTML 4.01 Transitional; it should be the very first line of your document:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
</pre></div>
Frameset
The Frameset variety of HTML 4.01 is intended for use only in creating frameset pagesthose that use the <code><frameset></code> element, along with <code><frame></code> and <code><noframes></code>, to lay out different windows within the page. It's otherwise identical to Transitional HTML; you need to use this only on the page that establishes the frames, not on the frames contained within that set (unless they define other <code><frameset></code> elements, of course).
You'll want to use HTML Frameset whenever you're creating a frame presentation and at no other time otherwise.
The DOCTYPE for HTML 4.01 Frameset is
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
</pre></div>
XHTML
XHTML 1.0 is a version of HTML 4.01 written as XML, which means it follows the very specific rules and structure imposed on XML documents. The tags are all the same as in HTML, but how you write them may be different. For example, all XHTML tags are lowercase, and all attribute values have to be quoted. XHTML 1.0 comes in the same three varieties: Strict, Transitional, and Frameset. The next version, XHTML 1.1, is available only in a Strict flavor and thus relies entirely on CSS for presentation.
Using CSS with XHTML is pretty much the same as using CSS with HTML. Because XHTML represents a move forward to an XML-based web, you may end up migrating from HTML to XHTML sometime in the future. For this reason, I recommend writing all your CSS rules so that element names are written in lowercase letters. It doesn't matter in HTML, but it will in XHTML, and making this a habit will save you time now if you choose to use XHTML in the future: You won't need to rewrite all your style sheets.
Validating HTML
Validating your HTML means that you run your page through an HTML validator, which is a program to analyze HTML code and ensure that the code you write is in compliance with the HTML specification. In this way, an HTML validator is like a spellchecker or grammar checker for HTML.
By validating your HTML, you can catch errors in your code, such as misspelled attributes (like <code>aling</code> or <code>scr</code>) or closing tags you've accidentally left out. Validation also improves your compatibility with browsers: Valid HTML code is closer to what browsersespecially newer onesare expecting. You can validate against your chosen variety of HTML (Strict, Transitional, or Frameset) to ensure that you're using only tags and attributes that are within that subset of the language.
From the standpoint of troubleshooting your style sheet, it's much easier to catch CSS errors if you know you don't have many HTML errors. I've spent many hours chasing down what I thought were mistakes in my CSS when really I'd just written an HTML attribute or element incorrectly.
I recommend always making sure your HTML is valid. Valid code conforms to the appropriate HTML Document Type Definition, which is a formal specification of HTML syntax. You use the DOCTYPE statement as the first line of your HTML file to indicate the correct version of HTML.
To check your HTML, you can use one of the validation services listed here:
* W3C's HTML Validator ([http://validator.w3.org/ http://validator.w3.org])
* Web Design Group's HTML Validator ([http://www.htmlhelp.com/tools/validator http://www.htmlhelp.com/tools/validator])
<div>Did you Know?
If a validator locates a problem with your HTML files, you can correct them by hand, in an HTML editor, or by using the HTML Tidy program created by Dave Raggett of the W3C. You can download HTML Tidy for free for various operating systems from [http://www.w3.org/People/Raggett/tidy/ http://www.w3.org/People/Raggett/tidy/]. It's well worth the time.</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Validate a Web Page
The process of checking your HTML is so important to creating good CSS that you should take the time out now to get familiar with it:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Choose a validator from the list just given and go to that site.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Enter the URL of a web page you've worked on, or upload the file directly from your computer.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Make sure your web page contains a <code>DOCTYPE</code> statement as the first line, preferably Transitional (if you use HTML attributes for appearance) or Strict (if you use pure CSS).<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Check the validation results. You may have tags that aren't closed, obsolete elements or attributes, or plain, ordinary typos. What would it take to fix your page?<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Make those changes and revalidate until your page passes. Congratsyou're writing valid HTML.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>For fun, validate other websites, including major destinations on the Internet such as search engines or news portals. How serious are they about valid HTML?<br /><br /></div>
|}
|}
<div>By the Way
The code examples given in this book don't include the DOCTYPE statement, so technically they aren't valid. This was done deliberately to conserve space as well as attention; a complex DOCTYPE at the beginning of an HTML example can distract from whatever point I'm trying to make by providing the HTML code. However, I do ensure the code is otherwise valid, and I ask for your forgiveness for lack of DOCTYPE. Do as I say, not as I do, in this specific case.</div>
./ ADD NAME=CH04LEV1SEC2.HTML
== Style Sheets in HTML ==
The Cascading Style Sheets language was specifically designed to work with HTML to build web pages. CSS rules can appear within linked style sheets, embedded style sheets, or inline style attributes.
The CSS rules that you will write for each method are generally the same, but the way your HTML and your CSS work together depends on the method you used. So far, you've worked with linked external style sheets, as that's the most useful way of dealing with Cascading Style Sheets and offers the most flexibility.
<div>By the Way
Examples in this book, unless stated otherwise, generally assume you're using a linked style sheet, and complete listings are shown as external CSS files. CSS rules (and declarations, for inline styles) are written the same regardless of how they're applied to HTML, so you'll get the same styling effects if you use linked, embedded, or inline style rules.</div>
Linked Style Sheets
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," you learned about how to create external style sheets and link them with the <code><link></code> element in HTML. Linking style sheets in this manner gives you the greatest portability and ease of maintenance when designing your styles for your website.
Many sites use one or more global style sheets that are linked from every page on the site. Using a global style sheet lets you make changes to one file that will affect the appearance of every page on your site. With a simple change, you can switch the colors, fonts, sizes, and more across your whole website.
External style sheets let you separate your content fully from your styles, which means it's easy to replace those styles with something else. For example, you could easily change the appearance of a site by replacing the old style sheet with a new set of rules under the same name.
You can also link in specific style sheets for specific uses, such as one style sheet per company division, as well as a global style sheet for the whole company, on a corporate website. You can link style sheets for specific types of output devices as well, using styles written just for those types of devices. For example, you could create a style sheet specifically for handheld wireless devices, screen readers, or printers. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," you'll learn more about designing for alternate output devices.
As seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], you can create linked style sheets by using the HTML <code><link></code> element in the <code><head></code> section of the page. A number of attributes can be used with the <code><link></code> element, but for our purposes only the following options are important:
<div><pre><link rel="relationship" href="URL" type="content-type" media="media-type">
</pre></div>
The <code><link></code> tag is actually an all-purpose linking element; it doesn't just define style sheets but also can be used to create any link between the entire document and some other URL location. To use it to identify a linked document as a style sheet, you need to specify what the relationship is. Other types of relationships include <code>contents</code> (specifying the location of a table of contents), <code>alternate</code> (an alternate version of the page for specific types of output devices or languages), and <code>glossary</code> (for a glossary of terms). To indicate a style sheet, however, you need only <code>rel="stylesheet"</code>.
The <code>href</code> attribute indicates the location of the style sheet and is a normal web URL. The location can be relative or absolute; without a directory path, it's assumed to be within the same directory, but you can use any URL path (and machine name), as with any other link in HTML.
Your style sheet even can reside on a different web server than your HTML file; in fact, this is a good way to quickly and easily add style to a web page. However, this isn't a license to merely steal someone else's work, any more than viewing the HTML source is an invitation to swipe source code. Use an offsite style sheet only if the site operator has explicitly given permission for it to be used in such a manner. Keep in mind that many web hosting services charge for bandwidth usage, so you may be costing someone money each time you use that style sheet without permission. Also remember that because you don't control the style sheet, it could affect the look of your web page if it's changed or removed.
<div>Did you Know?
The World Wide Web Consortium offers a number of style sheets for public use at [http://www.w3.org/StyleSheets/Core/ http://www.w3.org/StyleSheets/Core/]. You can use these to test styles on your pages by applying them as linked style sheets.</div>
The <code>content-type</code> attribute of the <code><link></code> tag indicates the styling language of the linked style sheet. For Cascading Style SheetsLevels 1, 2, and 2.1this should be <code>text/css</code>. This is also the MIME type that your server should return when serving up CSS files. All modern web servers recognize the file <code>extension.css</code> as being a CSS file and send an appropriate MIME type. If you name your file something ending in <code>.css</code>, the server sends it as <code>text/css</code>. If you think your server doesn't do this properly for some reason, you should consult your web server administrator or the documentation for your server software. Also, if you write a server-side script to create a CSS document in, for example, Perl, ASP, or PHP, you should make sure you set the content-type HTTP header line to <code>text/css</code>.
The <code>media</code> attribute tells the browser with which types of media or output device categories the style sheet should be used. A browser applies different style sheets depending on the mediafor example, one style sheet for printing and another for onscreen display. Style sheets for other media are ignored, and those rules aren't applied.
For the most part, we are concerned with the media-type <code>screen</code>, which means visual, onscreen display. Because <code>screen</code> is assumed to be the default, you don't need to specify this unless you're linking a style sheet for another type of output device. Other media types include <code>printer</code> (for printed documents), <code>braille</code> (for tactile Braille devices), <code>aural</code> (for speech synthesizers), and <code>all</code>, which covers all media types. You can list more than one media type by separating them with commas, such as <code>screen, printer</code>.
<div>By the Way
You'll learn more about the media types <code>printer, braille</code>, and <code>aural</code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22].</div>
Embedded Style Sheets
Another way to apply CSS to HTML is by embedding the CSS directly within the HTML file with the <code><style></code> tag. Your CSS rules are then part of the same file as the HTML, which makes editing easier, at least at first. An embedded style sheet also is useful for rules that apply only to a specific page and don't need to be used by other parts of the site, which helps keep the size of your global style sheet relatively small. For example, if you have a rule that applies only to the front page of the site, you don't need that in a site-wide style sheet that is accessed by every page, even those that don't use the rule.
On the other hand, it's also harder to maintain and update a site only with embedded style sheets; you have to edit every single page when you want to make a change in the appearance of the site.
For this reason, I prefer linking instead of embedding CSS, but in many situations it's easier or more appropriate to use an embedded style sheet. For example, when testing CSS rules or developing a style sheet, it may be easiest to use an embedded style sheet and then convert it to an external style sheet for production use.
<div>Did you Know?
How do you convert an embedded style sheet to an external one? Simple: You just cut the content of the <code><style></code> tag and paste it into a new file with a name ending in <code>.css</code>. Here's the tricky part: If there are any URL references (such as background images) in your CSS, you need to make sure that they apply relative to the new style sheet and not the original document. To convert an external style sheet to an embedded one, just paste it into a <code><style></code> element and check the URLs again.</div>
To embed a style sheet, use the <code><style></code> tag, which can be used only within the <code><head></code> of a web page:
<div><pre><style type="text/css" media="media-type">
... CSS rules go here ...
</style>
</pre></div>
The <code>type</code> attribute is required. Theoretically, this is because a different style language could be used with HTML, although in practice only CSS is ever used. The media attribute is optional; the default is <code>screen</code>. As with the <code><link></code> element, you can set multiple media types by listing them with comma separators.
You can have more than one <code><style></code> element within the <code><head></code> section of the page if you like; for example, you could have one for <code>screen</code> and one for <code>printer</code>. (You could have two for <code>printer</code>, if you want, but it usually makes more sense to combine them together in a single <code><style></code> tag.)
Hiding CSS Code from Older Browsers
Browsers shouldn't ever reveal the contents of a <code><style></code> tag. Even if a browser doesn't support CSS, it shouldn't display the rules to the user. However, some very ancient browsers were written before CSS was created, and because these browsers don't know what the <code><style></code> tag is, they just display it as HTML text, which is just a mess. The best way to avoid this is by wrapping your CSS rules within HTML comments:
<div><pre><style type="text/css" media="screen">
<!--
... CSS rules go here ...
-->
</style>
</pre></div>
The older browsers interpret this as just a normal comment, whereas the modern browsers understand the CSS. As nearly every browser used these days understands the <code><style></code> tag, it's not particularly necessary, but it doesn't hurt anything to do it, either. The examples in this book don't include comments.
Inline Style Attributes
You set inline styles on HTML tags by using the <code>style</code> attribute. Such a style applies to that particular element, or possibly to that element's children, if the rule's properties can be inherited.
<div>By the Way
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], "Cascading and Inheritance," you'll learn more about how HTML tags inherit CSS properties from other tags.</div>
The <code>style</code> attribute can be set on nearly any HTML tag that is displayed by a browser. The attribute contains the declaration of a CSS rule but not a selector; the tag itself (and its content) serves as the selector.
Here's an example of using inline styles to set some CSS properties:
<div><pre><table style="font-family: Arial; font-size: large">
<tr>
<th style="color: blue">
Writer's Name
</th>
<th style="color: green">
Primary Genre
</th>
</tr>
<tr><td>Kynn</td><td>Technical (Web Design)</td></tr>
<tr><td>Nick</td><td>Fiction (Horror)</td></tr>
<tr style="color: red">
<td>R. Francis</td>
<td>Non-Fiction (Podcasting)</td>
</tr>
</table>
</pre></div>
As you can see, the selector is unnecessary; the style is applied to the tag on which the <code>style</code> attribute is set. Also, there are no ending semicolons on the rules. Within <code>style</code> attributes, the ending semicolon is optional. I usually write it myself because it makes it easier to add additional rules if I need them.
Style attributes are most useful for single-point changes, such as changing the color of an announcement to make it stand out, like this:
<div><pre><h1 style="color: red;">
Just Added: New book signing at City Lights on Feb. 5.
</h1>
</pre></div>
As you're building a web page, it may seem easier to use inline styles rather than to create a separate style sheet; you won't have to go back to the <code><style></code> section or an external style sheet, but can just type the declaration directly into an attribute. However, in the long run it's harder to maintain inline styles because they'll be scattered throughout your HTML source.
Ultimately, the use of inline styles reduces the separation of content from presentation because it mixes the two together within the same markup. It makes more sense to use HTML for structure and content and CSS for presentation; in this regard, inline CSS is just a single step up from HTML presentation attributes.
In general, you should avoid using inline styles unless you have a very specific use in mind. If you have to style more than one part of your page the same way, it's better to use an embedded or external style sheet and define a class instead.
<div>Did you Know?
It's perfectly valid to use all three methods for using CSS rules within one documentfor example, an external style sheet for the entire site applied with a <code><link></code> tag; an embedded style sheet inside a <code><style></code> tag for rules specific to that web page; and inline styles set on individual elements with the <code>style</code> attribute.</div>
./ ADD NAME=CH04LEV1SEC3.HTML
== Classes and IDs ==
In addition to setting styles based on HTML elements, CSS allows for rules based on two optional attributes in HTML: <code>class</code> and <code>id</code>. Each of these can serve as the selector part of a CSS rule and can be set on any visible HTML tag.
<div>By the Way
For even more selectors you can use with HTML and CSS, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors," and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors."</div>
The <code><div></code> and <code><span></code> elements really come into their own with the <code>class</code> and <code>id</code> selectors. Through the use of <code>class</code> and <code>id</code> attributes, <code><div></code> or <code><span></code> tags can be made to have nearly any effect and presentation, which is often good but sometimes bad. When using <code>class</code> and <code>id</code> markers, you shouldn't neglect other markup tags that might be better suited for the task at hand. For example, you might decide to create an <code>emphatic</code> class for emphasizing portions of your text, and then use a CSS rule to make it bold. It's better to instead just use the <code><strong></code> tag in HTML and apply CSS to style it as you want<code><strong></code> already has a meaning in HTML (which is "emphasized text"). Use <code><div></code> or <code><span></code> only if there are no appropriate HTML tags you can style or restyle.
The <code>class</code> Attribute in HTML
The <code>class</code> attribute is used to define a related group of HTML elements on a page. They might have the same function or role, but in a CSS context, it means they have the same style rules applied to them. (The <code>class</code> attribute could be used for more than just styling, but in practice it's rarely used for any other purpose.)
The elements within a class can be of any type; one might be a <code><p></code>, another a <code><span></code>, and a third an <code><img></code>. That's perfectly fine; they will have the same style rules applied to them, but the fact that each one has a default presentation (defined by the browser or the HTML specifications) means those styles will be applied relative to the way they're normally rendered.
To create a class, you simply have to give it a name. A class name may be nearly anything, but has to be one word; in practice, it's best to stick to letters and numbers. Avoid using underlines, periods, and other non-alphanumeric characters when naming your classes.
You can name a class anything you like; it's basically just an arbitrary word used to group these items together. A descriptive name is good, especially one that describes function instead of presentation. For example, <code>class="detail"</code> makes more sense than <code>class="bluetext"</code>; if I can't come up with a good descriptive name, I'll use something arbitrary instead, such as the names of planets or the seven dwarves. Class names are not inherently case sensitive, but you should try to use the same case of characters when writing your HTML and your CSS rules.
After you've chosen a name for your class, you just have to assign HTML elements to that class by setting the class attribute on each. A given HTML element can be part of one or more classes if they are separated with spaces. Here are some examples:
<div><pre><div class="p1">
<h2 class="q2">Meeting Times</h2>
<p class="r3">
We will be meeting every other Wednesday, at
<span class="q2 j4">7:30 p.m.</span>
</p>
</div>
</pre></div>
In this example, the <code><div></code> is part of the <code>p1</code> class. The <code><h2></code> and the <code><span></code> are both part of the <code>q2</code> class. The <code><p></code> is part of the <code>"r3"</code> class, and the <code><span></code> is also part of the <code>j4</code> class.
Class Selectors in CSS
After you've defined a class in your HTML, you can use it as a class selector in CSS. Class selectors are indicated by a period (<code>.</code>) before the name of the class, like this:
<div><pre>.q2 { color: blue; }
.r3 { font-family: Arial; }
</pre></div>
You can combine an element selector with a class selector; the result selects only those members of the class that are of that particular element. (Or, it selects only those elements that are members of that particular classsame thing.) Just put the name of the element directly in front of the period and then the class name. For example:
<div><pre>span.q2 { font-size: large; }
p.r3 { color: green; }
</pre></div>
The first refers to all <code><span></code> elements with <code>class="q2"</code>; the latter to all <code><p></code> elements in the <code>r3</code> class. You can combine together several classes within a rule to select only elements that have those classes listed (separated by spaces, as described before) by separating them with periods, as shown here:
<div><pre>.q2.j4 { font-family: Arial; }
</pre></div>
This rule would select the <code><span></code>, which is part of both class <code>q2</code> and class <code>j4</code>.
A complete example of using class selectors is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex01 Listings 4.1] and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex02 4.2], and the result of displaying in a browser is presented in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04fig01 Figure 4.1].
Listing 4.1. HTML Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><html><br /><!-- This is class-4.1.html --><br /><head><br /><title><br />Class Selectors in Action<br /></title><br /><link type="text/css" rel="stylesheet" href="5-3.css"><br /></head><br /><body><br /><h1 class="mercury"><br />Welcome!<br /></h1><br /><div class="mars"><br /><p class="saturn"><br />This is a short page to tell you about our writers<br />group. We meet in the bookstore every other Wednesday;<br />our meetings are at <span class="mercury">7:30 p.m.<br />sharp.</span><br /></p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Listing 4.2. CSS Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* This is class-4.2.css */<br />.mercury { color: white; background-color: black; }<br />.mars { font-family: Arial; }<br />.saturn { color: black; }<br />h1.mercury { font-family: Verdana; color: silver; }<br /></pre></div><br />
|}
Figure 4.1. Firefox displays the style rules defined with class selectors.
[[Image:04fig01.jpg|300px]]
The <code>id</code> Attribute in HTML
The HTML attribute <code>id</code> is similar to the <code>class</code> attributeit can be set on nearly any tag and can be used as a CSS selectorbut is much more restricted. Only one tag on a page can have a given <code>id</code>; it must be unique within the page and is used to identify just that element. An id attribute's value has to begin with a letter and can be followed by letters, numbers, periods (<code>.</code>), underlines (<code>_</code>), hyphens (<code>-</code>) or colons (<code>:</code>); however, if you're using it as a selector in CSS, it's safest to stick to just letters and numbers. Case matters, so be consistent in the case of your <code>id</code> attributes. Here's an example:
<div><pre><a href="next.html" id="next">The next page</a>
</pre></div>
<code>id</code> Selectors in CSS
An <code>id</code> selector is indicated by a # (the hash, also called the pound sign) before the value of the <code>id</code>. For example:
<div><pre>#next { font-size: large; }
</pre></div>
Why would you want to use <code>id</code> selectors and not class selectors? Good question. A class selector is more flexible; it can do anything an <code>id</code> selector can do and more. If you want to reuse the style, you can do it with a class selector by adding new elements to the class, but you can't do that with <code>id</code> selectors because an <code>id</code> value must be unique in a document, and only one element on the page can have that value.
An <code>id</code> selector is useful if you know that you have to identify one unique item within a pagefor example, the Next link, or maybe a common navigation or layout element that appears on each page. In general, <code>id</code> selectors are less useful than class selectors when you use CSS with HTML. When using CSS with XML, however, <code>id</code> attributes play a larger role because XML uses <code>id</code> attributes more than HTML does.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Using CSS with HTML
To apply what you've learned this hour, why not create an HTML page, create an external CSS file and link it to the HTML file, and add embedded and inline styles? This will make you familiar with the ways HTML and CSS are used together in web design.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create a basic HTML document with headers, paragraphs, <code><div></code> and <code><span></code> tags, and other markup. Be sure to set some <code>class</code> and <code>id</code> attributes on your tags. Save this HTML file.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Create a CSS file with rules based on element selectors, <code>class</code> selectors, and <code>id</code> selectors. Save this CSS file.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Use <code><link></code> to apply the CSS style sheet to the HTML file. View the results in an HTML browser that supports CSS.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Add more styles directly into the HTML file by creating a <code><style></code> element in the <code><head></code>; view the results.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Create some inline styles using the <code>style</code> attribute, and check your creation in a browser.<br /><br /></div>
|}
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourwith external style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
|}
./ ADD NAME=CH04LEV1SEC4.HTML
== Summary ==
In this hour, you learned about the three flavors of HTML 4.01 and how CSS is used in each, and you learned about the benefits of validating your HTML code. You learned about three tools for applying Cascading Style Sheets to HTML pages: external style sheets that use the <code><link></code> tag, embedded style sheets defined inside a <code><style></code> tag, or specific styles set with the <code>style</code> attribute. You learned how to set <code>class</code> and <code>id</code> attributes in HTML and how to create rules using <code>class</code> and <code>id</code> attributes as selectors.
./ ADD NAME=CH04LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1a1 Q.]'''
| Will there be such a thing as HTML 5?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1 A.]'''
| No, and yes, and kind of. The W3C has stopped work on developing HTML and is concentrating on XHTML instead. The next version of HTML will be XHTML 2.0, and in addition to being composed of distinct modules, it will have new elements and attributes that don't currently exist in HTML. You can track the progress of XHTML 2's development at [http://www.w3.org/Markup/ http://www.w3.org/Markup/].
In addition, a group called the Web Hypertext Application Technology Working Group (WhatWG), a group of browser developers and other interested parties, is working on what they call Web Applications 1.0an extension to XHTML 1.0, which is informally referred to as "HTML 5." Whether these efforts will bear fruit as a replacement for HTML 4.01 is unclear; you can follow the WhatWG's progress at [http://www.whatwg.org/ http://www.whatwg.org].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2a2 Q.]'''
| Can you use selectors with inline styles? For example, <code><div style=".dot { color: black; }"></code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2 A.]'''
| No; a style attribute contains only the declaration part of a CSS rule, not the selector portion. The selector is the content of the element itself.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3a3 Q.]'''
| You said I could use style attributes, embedded style sheets, and linked style sheets on the same HTML page. What happens if they have different values for the same property?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3 A.]'''
| When two or more rules conflict, the method of resolving the conflict is known as the cascade. You'll learn more about this in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], but the general principle is that the more specific rule usually wins.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1a1 1.]'''
| What HTML tag is used to insert an embedded style sheet? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2a2 2.]'''
| What HTML tag is used to associate an external style sheet with an HTML tag? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3a3 3.]'''
| What is the default value for the <code>media</code> attribute?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4a4 4.]'''
| What is the difference between a class selector and an <code>id</code> selector? When would you use each?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5a5 5.]'''
| What are the three "flavors" of HTML, and which one relies on CSS for nearly all presentation styling?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6a6 6.]'''
| What does HTML validation check for?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1 1.]'''
| The <code><style></code> tag is used to embed a style sheet in an HTML file. The main attributes are <code>type</code>, which should be <code>text/css</code>, and an optional <code>media</code> attribute.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2 2.]'''
| The <code><link></code> tag can be set in the <code><head></code> of an HTML file to link to an external style sheet. The primary attributes used with CSS are <code>type, media, rel="stylesheet"</code>, and <code>href</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3 3.]'''
| The default value of the <code>media</code> attribute is <code>screen</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4 4.]'''
| An <code>id</code> selector applies to only one element within each document, whereas a <code>class</code> selector can be used to select any element within that class. You'd use <code>class</code> when you needed to select multiple elements, and <code>id</code> if you wanted to select only a single, unique element.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5 5.]'''
| The three types of HTML 4.01 are Strict, Transitional, and Frameset. HTML Strict has almost no presentational markup and depends on CSS to provide styling instructions.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6 6.]'''
| HTML validation checks your HTML code against the formal specification and DTD for the HTML language.
|}
Exercise
Create your own web page and use what you've learned so far to style your page. Choose your type of HTML, set a <code>DOCTYPE</code>, and validate the page. Use <code><link></code> and <code><style></code> tags to set up your style sheet, and add inline rules with the <code>style</code> attribute.
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourexternal style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
./ ADD NAME=CH05.HTML</span>
2oszifxovjj06qg51jc1kfaozmqi9pi
39286
39285
2026-04-13T06:28:39Z
Redmin
5511
39286
wikitext
text/x-wiki
= Hour 4. Using CSS with HTML =
; What You'll Learn in This Hour:
* What the different types of HTML are and how to use them with Cascading Style Sheets
* The three ways to link CSS to styles and when to use each
* How to create an external style sheet for your entire website
* How to embed style sheets directly in your HTML
* How to create CSS rules based on the HTML attributes of <code>class</code> and <code>id</code>
In previous hours, you've used Cascading Style Sheets to style your HTML pages by linking in an external CSS file. The true power of CSS and HTML really shines through only when you understand both of these complementary languages, how they relate to each other, and how they can be used effectively.
HTML and CSS blend together well not by coincidence but by design; they literally were made for each other. Using that designed synergy is the key to creating effective presentations on your websites.
|}
./ ADD NAME=CH04LEV1SEC1.HTML
== Types of HTML ==
To fully understand how HTML and CSS work together, it's important to know what we're talking about when we talk about HTML. Hypertext Markup Language is defined by formal recommendations issued by the World Wide Web Consortium (W3C), just as the Cascading Style Sheets language is.
HTML 4.01
The most recent version of HTML is HTML 4.01. HTML 4.01 is an updated version of HTML 4.0, which itself was an improvement over HTML 3.2 and 2.0. (There was no official version numbered 1.0; the first version of HTML was a quickly changing adhoc language put together primarily by World Wide Web creator Tim Berners-Lee. When efforts began to standardize HTML, numbering started with 2.0.)
HTML 4.01 comes in three "flavors"Strict, Transitional, and Frameset. The type of HTML used on your page is indicated by the <code>DOCTYPE</code> statement you place as the first line of the page. Each flavor has a set of tags and attributes that are allowed and disallowed; they're like a variant of spoken human languages, in a way.
What's the difference between the three? HTML Strict relies entirely on CSS for presentational styling; HTML Transitional includes some HTML attributes and elements for presentation effects; and HTML Frameset is used to create frames.
Strict
HTML 4.01 Strict is a version of HTML that removes nearly all the presentational markupthe <code><span style="text-align: center;"></code> tags, the <code>color</code> and <code>link</code> attributes on <code><body></code>, the <code>border</code> attribute, and other old standbys that have been used for years to make pages more visually appealing. So what's a web developer to do if she doesn't want boring pages?
The answer should be clear to anyone reading this book: Use Cascading Style Sheets! The Strict variety relies heavily on CSS for presentation; that's why it's considered strict.
To declare your page as using HTML Strict, put the following at the very top of your HTML file as the first line:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
</pre></div>
You'll want to use HTML Strict if you're designing primarily for newer browsers or if you don't mind giving unstyled pages to older browsers that ignore CSS.
<div>Did you Know?
Several recent browsers have a special compatibility mode for HTML and CSS where they adhere more closely to the published standards. Firefox and Internet Explorer turn on this mode when they encounter a valid <code>DOCTYPE</code> for HTML Strict and for a few other <code>DOCTYPE</code> declarations; other pages are shown in a "quirky" mode for backward compatibility with older browsers. For more information, see the following URLs:
* [http://www.mozilla.org/docs/web-developer/quirks/ http://www.mozilla.org/docs/web-developer/quirks/]
* [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp]</div>
Transitional
HTML 4.01 Transitional adds back in those presentation markup tags and attributes, although some, such as the <code><font></code> tag, are considered deprecated. What's deprecated mean? That's W3C-talk that means "This is still within the formal specification, but you really should not use it, and it won't be in future versions of this language." Not all presentation markup in HTML 4.01 is deprecated, and you can freely use those nondeprecated elements and attributes as part of HTML 4.01 Transitional.
Transitional HTML is so named because at the time the HTML 4.0 specification was released, few browsers had particularly good CSS support, which meant Strict wasn't really usable on most websites, unless you wanted plain gray or white backgrounds, black text, and default fonts.
Transitional is intended as a temporary measure until browsers catch up. So far, the browsers have been slow in catching up; Transitional HTML is therefore what I suggest for most web development. If you are concerned about delivering your design to the majority of browsers out there, you should use HTML Transitional.
<div>By the Way
You can use CSS and Transitional HTML together, and in fact that's highly recommended; CSS rules are followed if the browser understands CSS, and if not, it looks at the HTML attributes or elements instead. This enables you to have "fall-back" presentations in the HTML markup for older or limited browsers that don't support CSS.</div>
This is the DOCTYPE statement for HTML 4.01 Transitional; it should be the very first line of your document:
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
</pre></div>
Frameset
The Frameset variety of HTML 4.01 is intended for use only in creating frameset pagesthose that use the <code><frameset></code> element, along with <code><frame></code> and <code><noframes></code>, to lay out different windows within the page. It's otherwise identical to Transitional HTML; you need to use this only on the page that establishes the frames, not on the frames contained within that set (unless they define other <code><frameset></code> elements, of course).
You'll want to use HTML Frameset whenever you're creating a frame presentation and at no other time otherwise.
The DOCTYPE for HTML 4.01 Frameset is
<div><pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
</pre></div>
XHTML
XHTML 1.0 is a version of HTML 4.01 written as XML, which means it follows the very specific rules and structure imposed on XML documents. The tags are all the same as in HTML, but how you write them may be different. For example, all XHTML tags are lowercase, and all attribute values have to be quoted. XHTML 1.0 comes in the same three varieties: Strict, Transitional, and Frameset. The next version, XHTML 1.1, is available only in a Strict flavor and thus relies entirely on CSS for presentation.
Using CSS with XHTML is pretty much the same as using CSS with HTML. Because XHTML represents a move forward to an XML-based web, you may end up migrating from HTML to XHTML sometime in the future. For this reason, I recommend writing all your CSS rules so that element names are written in lowercase letters. It doesn't matter in HTML, but it will in XHTML, and making this a habit will save you time now if you choose to use XHTML in the future: You won't need to rewrite all your style sheets.
Validating HTML
Validating your HTML means that you run your page through an HTML validator, which is a program to analyze HTML code and ensure that the code you write is in compliance with the HTML specification. In this way, an HTML validator is like a spellchecker or grammar checker for HTML.
By validating your HTML, you can catch errors in your code, such as misspelled attributes (like <code>aling</code> or <code>scr</code>) or closing tags you've accidentally left out. Validation also improves your compatibility with browsers: Valid HTML code is closer to what browsersespecially newer onesare expecting. You can validate against your chosen variety of HTML (Strict, Transitional, or Frameset) to ensure that you're using only tags and attributes that are within that subset of the language.
From the standpoint of troubleshooting your style sheet, it's much easier to catch CSS errors if you know you don't have many HTML errors. I've spent many hours chasing down what I thought were mistakes in my CSS when really I'd just written an HTML attribute or element incorrectly.
I recommend always making sure your HTML is valid. Valid code conforms to the appropriate HTML Document Type Definition, which is a formal specification of HTML syntax. You use the DOCTYPE statement as the first line of your HTML file to indicate the correct version of HTML.
To check your HTML, you can use one of the validation services listed here:
* W3C's HTML Validator ([http://validator.w3.org/ http://validator.w3.org])
* Web Design Group's HTML Validator ([http://www.htmlhelp.com/tools/validator http://www.htmlhelp.com/tools/validator])
<div>Did you Know?
If a validator locates a problem with your HTML files, you can correct them by hand, in an HTML editor, or by using the HTML Tidy program created by Dave Raggett of the W3C. You can download HTML Tidy for free for various operating systems from [http://www.w3.org/People/Raggett/tidy/ http://www.w3.org/People/Raggett/tidy/]. It's well worth the time.</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Validate a Web Page
The process of checking your HTML is so important to creating good CSS that you should take the time out now to get familiar with it:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Choose a validator from the list just given and go to that site.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Enter the URL of a web page you've worked on, or upload the file directly from your computer.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Make sure your web page contains a <code>DOCTYPE</code> statement as the first line, preferably Transitional (if you use HTML attributes for appearance) or Strict (if you use pure CSS).<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Check the validation results. You may have tags that aren't closed, obsolete elements or attributes, or plain, ordinary typos. What would it take to fix your page?<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Make those changes and revalidate until your page passes. Congratsyou're writing valid HTML.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>For fun, validate other websites, including major destinations on the Internet such as search engines or news portals. How serious are they about valid HTML?<br /><br /></div>
|}
|}
<div>By the Way
The code examples given in this book don't include the DOCTYPE statement, so technically they aren't valid. This was done deliberately to conserve space as well as attention; a complex DOCTYPE at the beginning of an HTML example can distract from whatever point I'm trying to make by providing the HTML code. However, I do ensure the code is otherwise valid, and I ask for your forgiveness for lack of DOCTYPE. Do as I say, not as I do, in this specific case.</div>
./ ADD NAME=CH04LEV1SEC2.HTML
== Style Sheets in HTML ==
The Cascading Style Sheets language was specifically designed to work with HTML to build web pages. CSS rules can appear within linked style sheets, embedded style sheets, or inline style attributes.
The CSS rules that you will write for each method are generally the same, but the way your HTML and your CSS work together depends on the method you used. So far, you've worked with linked external style sheets, as that's the most useful way of dealing with Cascading Style Sheets and offers the most flexibility.
<div>By the Way
Examples in this book, unless stated otherwise, generally assume you're using a linked style sheet, and complete listings are shown as external CSS files. CSS rules (and declarations, for inline styles) are written the same regardless of how they're applied to HTML, so you'll get the same styling effects if you use linked, embedded, or inline style rules.</div>
Linked Style Sheets
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," you learned about how to create external style sheets and link them with the <code><link></code> element in HTML. Linking style sheets in this manner gives you the greatest portability and ease of maintenance when designing your styles for your website.
Many sites use one or more global style sheets that are linked from every page on the site. Using a global style sheet lets you make changes to one file that will affect the appearance of every page on your site. With a simple change, you can switch the colors, fonts, sizes, and more across your whole website.
External style sheets let you separate your content fully from your styles, which means it's easy to replace those styles with something else. For example, you could easily change the appearance of a site by replacing the old style sheet with a new set of rules under the same name.
You can also link in specific style sheets for specific uses, such as one style sheet per company division, as well as a global style sheet for the whole company, on a corporate website. You can link style sheets for specific types of output devices as well, using styles written just for those types of devices. For example, you could create a style sheet specifically for handheld wireless devices, screen readers, or printers. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," you'll learn more about designing for alternate output devices.
As seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], you can create linked style sheets by using the HTML <code><link></code> element in the <code><head></code> section of the page. A number of attributes can be used with the <code><link></code> element, but for our purposes only the following options are important:
<div><pre><link rel="relationship" href="URL" type="content-type" media="media-type">
</pre></div>
The <code><link></code> tag is actually an all-purpose linking element; it doesn't just define style sheets but also can be used to create any link between the entire document and some other URL location. To use it to identify a linked document as a style sheet, you need to specify what the relationship is. Other types of relationships include <code>contents</code> (specifying the location of a table of contents), <code>alternate</code> (an alternate version of the page for specific types of output devices or languages), and <code>glossary</code> (for a glossary of terms). To indicate a style sheet, however, you need only <code>rel="stylesheet"</code>.
The <code>href</code> attribute indicates the location of the style sheet and is a normal web URL. The location can be relative or absolute; without a directory path, it's assumed to be within the same directory, but you can use any URL path (and machine name), as with any other link in HTML.
Your style sheet even can reside on a different web server than your HTML file; in fact, this is a good way to quickly and easily add style to a web page. However, this isn't a license to merely steal someone else's work, any more than viewing the HTML source is an invitation to swipe source code. Use an offsite style sheet only if the site operator has explicitly given permission for it to be used in such a manner. Keep in mind that many web hosting services charge for bandwidth usage, so you may be costing someone money each time you use that style sheet without permission. Also remember that because you don't control the style sheet, it could affect the look of your web page if it's changed or removed.
<div>Did you Know?
The World Wide Web Consortium offers a number of style sheets for public use at [http://www.w3.org/StyleSheets/Core/ http://www.w3.org/StyleSheets/Core/]. You can use these to test styles on your pages by applying them as linked style sheets.</div>
The <code>content-type</code> attribute of the <code><link></code> tag indicates the styling language of the linked style sheet. For Cascading Style SheetsLevels 1, 2, and 2.1this should be <code>text/css</code>. This is also the MIME type that your server should return when serving up CSS files. All modern web servers recognize the file <code>extension.css</code> as being a CSS file and send an appropriate MIME type. If you name your file something ending in <code>.css</code>, the server sends it as <code>text/css</code>. If you think your server doesn't do this properly for some reason, you should consult your web server administrator or the documentation for your server software. Also, if you write a server-side script to create a CSS document in, for example, Perl, ASP, or PHP, you should make sure you set the content-type HTTP header line to <code>text/css</code>.
The <code>media</code> attribute tells the browser with which types of media or output device categories the style sheet should be used. A browser applies different style sheets depending on the mediafor example, one style sheet for printing and another for onscreen display. Style sheets for other media are ignored, and those rules aren't applied.
For the most part, we are concerned with the media-type <code>screen</code>, which means visual, onscreen display. Because <code>screen</code> is assumed to be the default, you don't need to specify this unless you're linking a style sheet for another type of output device. Other media types include <code>printer</code> (for printed documents), <code>braille</code> (for tactile Braille devices), <code>aural</code> (for speech synthesizers), and <code>all</code>, which covers all media types. You can list more than one media type by separating them with commas, such as <code>screen, printer</code>.
<div>By the Way
You'll learn more about the media types <code>printer, braille</code>, and <code>aural</code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22].</div>
Embedded Style Sheets
Another way to apply CSS to HTML is by embedding the CSS directly within the HTML file with the <code><style></code> tag. Your CSS rules are then part of the same file as the HTML, which makes editing easier, at least at first. An embedded style sheet also is useful for rules that apply only to a specific page and don't need to be used by other parts of the site, which helps keep the size of your global style sheet relatively small. For example, if you have a rule that applies only to the front page of the site, you don't need that in a site-wide style sheet that is accessed by every page, even those that don't use the rule.
On the other hand, it's also harder to maintain and update a site only with embedded style sheets; you have to edit every single page when you want to make a change in the appearance of the site.
For this reason, I prefer linking instead of embedding CSS, but in many situations it's easier or more appropriate to use an embedded style sheet. For example, when testing CSS rules or developing a style sheet, it may be easiest to use an embedded style sheet and then convert it to an external style sheet for production use.
<div>Did you Know?
How do you convert an embedded style sheet to an external one? Simple: You just cut the content of the <code><style></code> tag and paste it into a new file with a name ending in <code>.css</code>. Here's the tricky part: If there are any URL references (such as background images) in your CSS, you need to make sure that they apply relative to the new style sheet and not the original document. To convert an external style sheet to an embedded one, just paste it into a <code><style></code> element and check the URLs again.</div>
To embed a style sheet, use the <code><style></code> tag, which can be used only within the <code><head></code> of a web page:
<div><pre><style type="text/css" media="media-type">
... CSS rules go here ...
</style>
</pre></div>
The <code>type</code> attribute is required. Theoretically, this is because a different style language could be used with HTML, although in practice only CSS is ever used. The media attribute is optional; the default is <code>screen</code>. As with the <code><link></code> element, you can set multiple media types by listing them with comma separators.
You can have more than one <code><style></code> element within the <code><head></code> section of the page if you like; for example, you could have one for <code>screen</code> and one for <code>printer</code>. (You could have two for <code>printer</code>, if you want, but it usually makes more sense to combine them together in a single <code><style></code> tag.)
Hiding CSS Code from Older Browsers
Browsers shouldn't ever reveal the contents of a <code><style></code> tag. Even if a browser doesn't support CSS, it shouldn't display the rules to the user. However, some very ancient browsers were written before CSS was created, and because these browsers don't know what the <code><style></code> tag is, they just display it as HTML text, which is just a mess. The best way to avoid this is by wrapping your CSS rules within HTML comments:
<div><pre><style type="text/css" media="screen">
<!--
... CSS rules go here ...
-->
</style>
</pre></div>
The older browsers interpret this as just a normal comment, whereas the modern browsers understand the CSS. As nearly every browser used these days understands the <code><style></code> tag, it's not particularly necessary, but it doesn't hurt anything to do it, either. The examples in this book don't include comments.
Inline Style Attributes
You set inline styles on HTML tags by using the <code>style</code> attribute. Such a style applies to that particular element, or possibly to that element's children, if the rule's properties can be inherited.
<div>By the Way
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], "Cascading and Inheritance," you'll learn more about how HTML tags inherit CSS properties from other tags.</div>
The <code>style</code> attribute can be set on nearly any HTML tag that is displayed by a browser. The attribute contains the declaration of a CSS rule but not a selector; the tag itself (and its content) serves as the selector.
Here's an example of using inline styles to set some CSS properties:
<div><pre><table style="font-family: Arial; font-size: large">
<tr>
<th style="color: blue">
Writer's Name
</th>
<th style="color: green">
Primary Genre
</th>
</tr>
<tr><td>Kynn</td><td>Technical (Web Design)</td></tr>
<tr><td>Nick</td><td>Fiction (Horror)</td></tr>
<tr style="color: red">
<td>R. Francis</td>
<td>Non-Fiction (Podcasting)</td>
</tr>
</table>
</pre></div>
As you can see, the selector is unnecessary; the style is applied to the tag on which the <code>style</code> attribute is set. Also, there are no ending semicolons on the rules. Within <code>style</code> attributes, the ending semicolon is optional. I usually write it myself because it makes it easier to add additional rules if I need them.
Style attributes are most useful for single-point changes, such as changing the color of an announcement to make it stand out, like this:
<div><pre><h1 style="color: red;">
Just Added: New book signing at City Lights on Feb. 5.
</h1>
</pre></div>
As you're building a web page, it may seem easier to use inline styles rather than to create a separate style sheet; you won't have to go back to the <code><style></code> section or an external style sheet, but can just type the declaration directly into an attribute. However, in the long run it's harder to maintain inline styles because they'll be scattered throughout your HTML source.
Ultimately, the use of inline styles reduces the separation of content from presentation because it mixes the two together within the same markup. It makes more sense to use HTML for structure and content and CSS for presentation; in this regard, inline CSS is just a single step up from HTML presentation attributes.
In general, you should avoid using inline styles unless you have a very specific use in mind. If you have to style more than one part of your page the same way, it's better to use an embedded or external style sheet and define a class instead.
<div>Did you Know?
It's perfectly valid to use all three methods for using CSS rules within one documentfor example, an external style sheet for the entire site applied with a <code><link></code> tag; an embedded style sheet inside a <code><style></code> tag for rules specific to that web page; and inline styles set on individual elements with the <code>style</code> attribute.</div>
./ ADD NAME=CH04LEV1SEC3.HTML
== Classes and IDs ==
In addition to setting styles based on HTML elements, CSS allows for rules based on two optional attributes in HTML: <code>class</code> and <code>id</code>. Each of these can serve as the selector part of a CSS rule and can be set on any visible HTML tag.
<div>By the Way
For even more selectors you can use with HTML and CSS, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors," and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors."</div>
The <code><div></code> and <code><span></code> elements really come into their own with the <code>class</code> and <code>id</code> selectors. Through the use of <code>class</code> and <code>id</code> attributes, <code><div></code> or <code><span></code> tags can be made to have nearly any effect and presentation, which is often good but sometimes bad. When using <code>class</code> and <code>id</code> markers, you shouldn't neglect other markup tags that might be better suited for the task at hand. For example, you might decide to create an <code>emphatic</code> class for emphasizing portions of your text, and then use a CSS rule to make it bold. It's better to instead just use the <code><strong></code> tag in HTML and apply CSS to style it as you want<code><strong></code> already has a meaning in HTML (which is "emphasized text"). Use <code><div></code> or <code><span></code> only if there are no appropriate HTML tags you can style or restyle.
The <code>class</code> Attribute in HTML
The <code>class</code> attribute is used to define a related group of HTML elements on a page. They might have the same function or role, but in a CSS context, it means they have the same style rules applied to them. (The <code>class</code> attribute could be used for more than just styling, but in practice it's rarely used for any other purpose.)
The elements within a class can be of any type; one might be a <code><p></code>, another a <code><span></code>, and a third an <code><img></code>. That's perfectly fine; they will have the same style rules applied to them, but the fact that each one has a default presentation (defined by the browser or the HTML specifications) means those styles will be applied relative to the way they're normally rendered.
To create a class, you simply have to give it a name. A class name may be nearly anything, but has to be one word; in practice, it's best to stick to letters and numbers. Avoid using underlines, periods, and other non-alphanumeric characters when naming your classes.
You can name a class anything you like; it's basically just an arbitrary word used to group these items together. A descriptive name is good, especially one that describes function instead of presentation. For example, <code>class="detail"</code> makes more sense than <code>class="bluetext"</code>; if I can't come up with a good descriptive name, I'll use something arbitrary instead, such as the names of planets or the seven dwarves. Class names are not inherently case sensitive, but you should try to use the same case of characters when writing your HTML and your CSS rules.
After you've chosen a name for your class, you just have to assign HTML elements to that class by setting the class attribute on each. A given HTML element can be part of one or more classes if they are separated with spaces. Here are some examples:
<div><pre><div class="p1">
<h2 class="q2">Meeting Times</h2>
<p class="r3">
We will be meeting every other Wednesday, at
<span class="q2 j4">7:30 p.m.</span>
</p>
</div>
</pre></div>
In this example, the <code><div></code> is part of the <code>p1</code> class. The <code><h2></code> and the <code><span></code> are both part of the <code>q2</code> class. The <code><p></code> is part of the <code>"r3"</code> class, and the <code><span></code> is also part of the <code>j4</code> class.
Class Selectors in CSS
After you've defined a class in your HTML, you can use it as a class selector in CSS. Class selectors are indicated by a period (<code>.</code>) before the name of the class, like this:
<div><pre>.q2 { color: blue; }
.r3 { font-family: Arial; }
</pre></div>
You can combine an element selector with a class selector; the result selects only those members of the class that are of that particular element. (Or, it selects only those elements that are members of that particular classsame thing.) Just put the name of the element directly in front of the period and then the class name. For example:
<div><pre>span.q2 { font-size: large; }
p.r3 { color: green; }
</pre></div>
The first refers to all <code><span></code> elements with <code>class="q2"</code>; the latter to all <code><p></code> elements in the <code>r3</code> class. You can combine together several classes within a rule to select only elements that have those classes listed (separated by spaces, as described before) by separating them with periods, as shown here:
<div><pre>.q2.j4 { font-family: Arial; }
</pre></div>
This rule would select the <code><span></code>, which is part of both class <code>q2</code> and class <code>j4</code>.
A complete example of using class selectors is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex01 Listings 4.1] and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04ex02 4.2], and the result of displaying in a browser is presented in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04fig01 Figure 4.1].
Listing 4.1. HTML Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><html><br /><!-- This is class-4.1.html --><br /><head><br /><title><br />Class Selectors in Action<br /></title><br /><link type="text/css" rel="stylesheet" href="5-3.css"><br /></head><br /><body><br /><h1 class="mercury"><br />Welcome!<br /></h1><br /><div class="mars"><br /><p class="saturn"><br />This is a short page to tell you about our writers<br />group. We meet in the bookstore every other Wednesday;<br />our meetings are at <span class="mercury">7:30 p.m.<br />sharp.</span><br /></p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Listing 4.2. CSS Code Illustrating Class Selectors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* This is class-4.2.css */<br />.mercury { color: white; background-color: black; }<br />.mars { font-family: Arial; }<br />.saturn { color: black; }<br />h1.mercury { font-family: Verdana; color: silver; }<br /></pre></div><br />
|}
Figure 4.1. Firefox displays the style rules defined with class selectors.
[[Image:04fig01.jpg|300px]]
The <code>id</code> Attribute in HTML
The HTML attribute <code>id</code> is similar to the <code>class</code> attributeit can be set on nearly any tag and can be used as a CSS selectorbut is much more restricted. Only one tag on a page can have a given <code>id</code>; it must be unique within the page and is used to identify just that element. An id attribute's value has to begin with a letter and can be followed by letters, numbers, periods (<code>.</code>), underlines (<code>_</code>), hyphens (<code>-</code>) or colons (<code>:</code>); however, if you're using it as a selector in CSS, it's safest to stick to just letters and numbers. Case matters, so be consistent in the case of your <code>id</code> attributes. Here's an example:
<div><pre><a href="next.html" id="next">The next page</a>
</pre></div>
<code>id</code> Selectors in CSS
An <code>id</code> selector is indicated by a # (the hash, also called the pound sign) before the value of the <code>id</code>. For example:
<div><pre>#next { font-size: large; }
</pre></div>
Why would you want to use <code>id</code> selectors and not class selectors? Good question. A class selector is more flexible; it can do anything an <code>id</code> selector can do and more. If you want to reuse the style, you can do it with a class selector by adding new elements to the class, but you can't do that with <code>id</code> selectors because an <code>id</code> value must be unique in a document, and only one element on the page can have that value.
An <code>id</code> selector is useful if you know that you have to identify one unique item within a pagefor example, the Next link, or maybe a common navigation or layout element that appears on each page. In general, <code>id</code> selectors are less useful than class selectors when you use CSS with HTML. When using CSS with XML, however, <code>id</code> attributes play a larger role because XML uses <code>id</code> attributes more than HTML does.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Using CSS with HTML
To apply what you've learned this hour, why not create an HTML page, create an external CSS file and link it to the HTML file, and add embedded and inline styles? This will make you familiar with the ways HTML and CSS are used together in web design.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create a basic HTML document with headers, paragraphs, <code><div></code> and <code><span></code> tags, and other markup. Be sure to set some <code>class</code> and <code>id</code> attributes on your tags. Save this HTML file.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Create a CSS file with rules based on element selectors, <code>class</code> selectors, and <code>id</code> selectors. Save this CSS file.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Use <code><link></code> to apply the CSS style sheet to the HTML file. View the results in an HTML browser that supports CSS.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Add more styles directly into the HTML file by creating a <code><style></code> element in the <code><head></code>; view the results.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Create some inline styles using the <code>style</code> attribute, and check your creation in a browser.<br /><br /></div>
|}
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourwith external style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
|}
./ ADD NAME=CH04LEV1SEC4.HTML
== Summary ==
In this hour, you learned about the three flavors of HTML 4.01 and how CSS is used in each, and you learned about the benefits of validating your HTML code. You learned about three tools for applying Cascading Style Sheets to HTML pages: external style sheets that use the <code><link></code> tag, embedded style sheets defined inside a <code><style></code> tag, or specific styles set with the <code>style</code> attribute. You learned how to set <code>class</code> and <code>id</code> attributes in HTML and how to create rules using <code>class</code> and <code>id</code> attributes as selectors.
./ ADD NAME=CH04LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1a1 Q.]'''
| Will there be such a thing as HTML 5?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q1 A.]'''
| No, and yes, and kind of. The W3C has stopped work on developing HTML and is concentrating on XHTML instead. The next version of HTML will be XHTML 2.0, and in addition to being composed of distinct modules, it will have new elements and attributes that don't currently exist in HTML. You can track the progress of XHTML 2's development at [http://www.w3.org/Markup/ http://www.w3.org/Markup/].
In addition, a group called the Web Hypertext Application Technology Working Group (WhatWG), a group of browser developers and other interested parties, is working on what they call Web Applications 1.0an extension to XHTML 1.0, which is informally referred to as "HTML 5." Whether these efforts will bear fruit as a replacement for HTML 4.01 is unclear; you can follow the WhatWG's progress at [http://www.whatwg.org/ http://www.whatwg.org].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2a2 Q.]'''
| Can you use selectors with inline styles? For example, <code><div style=".dot { color: black; }"></code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q2 A.]'''
| No; a style attribute contains only the declaration part of a CSS rule, not the selector portion. The selector is the content of the element itself.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3a3 Q.]'''
| You said I could use style attributes, embedded style sheets, and linked style sheets on the same HTML page. What happens if they have different values for the same property?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa1q3 A.]'''
| When two or more rules conflict, the method of resolving the conflict is known as the cascade. You'll learn more about this in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], but the general principle is that the more specific rule usually wins.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1a1 1.]'''
| What HTML tag is used to insert an embedded style sheet? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2a2 2.]'''
| What HTML tag is used to associate an external style sheet with an HTML tag? What are the primary attributes of that tag?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3a3 3.]'''
| What is the default value for the <code>media</code> attribute?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4a4 4.]'''
| What is the difference between a class selector and an <code>id</code> selector? When would you use each?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5a5 5.]'''
| What are the three "flavors" of HTML, and which one relies on CSS for nearly all presentation styling?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6a6 6.]'''
| What does HTML validation check for?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q1 1.]'''
| The <code><style></code> tag is used to embed a style sheet in an HTML file. The main attributes are <code>type</code>, which should be <code>text/css</code>, and an optional <code>media</code> attribute.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q2 2.]'''
| The <code><link></code> tag can be set in the <code><head></code> of an HTML file to link to an external style sheet. The primary attributes used with CSS are <code>type, media, rel="stylesheet"</code>, and <code>href</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q3 3.]'''
| The default value of the <code>media</code> attribute is <code>screen</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q4 4.]'''
| An <code>id</code> selector applies to only one element within each document, whereas a <code>class</code> selector can be used to select any element within that class. You'd use <code>class</code> when you needed to select multiple elements, and <code>id</code> if you wanted to select only a single, unique element.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q5 5.]'''
| The three types of HTML 4.01 are Strict, Transitional, and Frameset. HTML Strict has almost no presentational markup and depends on CSS to provide styling instructions.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch04qa2q6 6.]'''
| HTML validation checks your HTML code against the formal specification and DTD for the HTML language.
|}
Exercise
Create your own web page and use what you've learned so far to style your page. Choose your type of HTML, set a <code>DOCTYPE</code>, and validate the page. Use <code><link></code> and <code><style></code> tags to set up your style sheet, and add inline rules with the <code>style</code> attribute.
You'll have successfully completed the activity if you're able to use CSS with your HTML in each of the ways discussed this hourexternal style sheets, embedded style sheets, and inline <code>style</code> attributesand if you can utilize <code>class</code> and <code>id</code> attributes as selectors in your CSS rules.
./ ADD NAME=CH05.HTML
9lu1gc5cbt38e4c6fswibijq55xpvtf
User:Bartlett/05
2
2108
39215
5493
2026-04-13T06:03:16Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39215
wikitext
text/x-wiki
= Hour 5. Selectors =
;What You'll Learn in This Hour:
* More about simple selectors you've already been using
* How to use <code>class</code> and <code>id</code> selectors
* What the universal selector is and when to use it
* What pseudo-classes and pseudo-elements are and how they can be used
* How to specify styles that affect hypertext links
As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," selectors are the part of the CSS rule that identifies the target of the styling. Putting the power of selectors to use is vital for getting the most out of CSS.
|}
./ ADD NAME=CH05LEV1SEC1.HTML
== Simple Selectors ==
You've seen the simplest type of selectors already: type selectors, <code>class</code> selectors, and <code>id</code> selectors. In this hour, you'll look at how you can use them more effectively.
So far you have learned how to create CSS rules using simple selectors: type selectors based on the HTML tag, and <code>class</code> or <code>id</code> selectors based on attributes in the HTML.
A type selector is simply the name of an HTML tag minus the <code><></code> angle brackets. For example:
<div><pre>h1 { color: blue; }
</pre></div>
This selects all <code><h1></code> tags and specifies that they're the color <code>blue</code>. Type selectors are the easiest to use because they're so straightforward, but they're also very limited. What if you want only some of the <code><h1></code> tags to be <code>blue</code> and others to be <code>green?</code> That's when you'd use <code>class</code> and <code>id</code> selectors.
<div>Did you Know?
Although I said type selectors had to be HTML tags, I must admit that's only half true. They actually have to be any sort of legitimate element for the language you're styling; this is how you can use CSS with XML, for example. And in fact, you don't have to have the actual tag present! HTML (but not XML or XHTML) lets you leave out certain tag declarations entirely, such as the <code><body></code> element. These are implied tags. The opening and closing tags are implied. If you have a rule based on <code>body</code>, such as <code>'body { font-family: Arial; }'</code>, a CSS-compliant browser will still apply your font to the implied <code><body></code> even though no tags are present.</div>
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4], "Using CSS with HTML," you learned how you can set <code>class</code> and <code>id</code> selectors in your rules based on HTML attributes of <code>class</code> and <code>id</code>, such as
<div><pre>#here { font-size: large; }
.there { color: green; }
</pre></div>
An <code>id</code> selector uniquely identifies part of a page, whereas a <code>class</code> selector allows you to identify specific tags as being part of a certain set you've defined.
Using <code>class</code> and <code>id</code> Selectors
You can combine <code>class</code> selectors or <code>id</code> selectors with <code><div></code> tags to designate specific sections of a page that should receive special styling. For example, consider the HTML page shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex01 Listing 5.1], which has a <code>class</code> or <code>id</code> attribute set on each <code><div></code> tag.
Listing 5.1. HTML Sections Set via <code><div></code> and <code>class</code>
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- imgtip-5.1.html --><br /><html><br /><head><br /><title>Image Accessibility</title><br /><link type="text/css" rel="stylesheet"<br />href="tips-5.2.css"><br /></head><br /><body><br /><div id="breadcrumb"><br /><a href="http://kynn.com">Kynn.com</a> ·<br /><a href="http://kynn.com/writing/">Writing</a> ·<br /><a href="http://kynn.com/writing/tips">Tips</a> ·<br />Images<br /></div><br /><div id="header"><br /><h1>Image Accessibility</h1><br /><h2>Making your graphics accessible</h2><br /></div><br /><div class="tips"><br /><p> Here are some helpful tips on making your graphical<br />content accessible to users who can't see images: </p><br /><ul><br /><li>Always include an <code>alt</code> attribute on your<br /><code><img></code> tag.</li><br /><li>The <code>alt</code> attribute should contain a short<br />replacement for the graphic, in text. If the image<br />itself has text, list that in <code>alt</code>.</li><br /><li>If the image is purely decorative and doesn't convey<br />any additional information, use <code>alt=""</code>.</li><br /><li>If there is more information in the graphic than you<br />can convey in a short <code>alt</code> attribute, such<br />as the information in a graph or chart, then use<br />the <code>longdesc</code> attribute to give the URL of<br />a page that describes the graphic in text.</li><br /></ul><br /></div><br /><div id="footer"><br /><address> Copyright © 2006 by Kynn Bartlett </address><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
As you can see, I linked in an external style sheet, <code>tips-5.2.css</code>, using a <code><link></code> tag. That style sheet defines a style for each section of the page; the sections are <code>breadcrumb, header, tips</code>, and <code>footer</code>. The style sheet is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex02 Listing 5.2].
Listing 5.2. Sectional Styles Using Classes and IDs
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* tips-5.2.css */<br />body<br />{ color: black;<br />background-color: white; }<br />#breadcrumb<br />{ font-family: Verdana, sans-serif;<br />color: black;<br />background-color: silver; }<br />#header<br />{ color: white;<br />background-color: maroon;<br />font-family: "Courier New", monospace; }<br />.tips<br />{ color: white;<br />background-color: gray;<br />font-family: Arial, sans-serif; }<br />#footer<br />{ color: silver;<br />background-color: black;<br />font-family: "Times New Roman", serif; }<br /></pre></div><br />
|}
The effect of applying these styles is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig01 Figure 5.1]. You'll notice that I've used background colors to make some of the <code><div></code> sections visible; in practice, this can be a somewhat unattractive effect; some of my examples are written simply to illustrate a principle rather than to be aesthetically appealing, especially in the limited black, white, and gray shades available in this book. Each section gets its own font, background color, and foreground color.
<div style="text-align: center;"> Figure 5.1. Firefox displays sectional styles set by <code><div></code>, <code>class</code> and <code>id</code>. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/05fig01_alt.jpg [View full size image]]</div>[[Image:05fig01.jpg|500px]] </div>
<div>Did you Know?
In this example, <code>id</code> selectors were used for the breadcrumb trail, the header, and the footer, and a <code>class</code> selector for the tips. Why?
Simple: You can (and probably should) use <code>id</code> whenever you can be sure that the <code>id</code> will be unique on a page. A page may contain multiple tips, but just one bread-crumb trail, one header, and one footer. The style sheet could still be written with <code>class</code>; it doesn't really hurt anything to use <code>class</code> instead of <code>id</code>, but style sheets are simpler and more specific if they use <code>id</code>.</div>
The Universal Selector
In addition to type, <code>class</code>, and <code>id</code> selectors, CSS also defines a universal selector. The universal selector applies to all tags and content within a page and is represented by an asterisk (<code>*</code>). Here's an example of a universal selector rule:
<div><pre>* { color: blue; }
</pre></div>
If you're writing a rule that uses the universal selector and there's something else to that rule, such as a <code>class</code> or <code>id</code> selector, you can leave out the asterisk. In fact, the general way of writing class selectors is just a special case of the universal selector with the asterisk omitted. The following two declarations are identical:
<div><pre>*.there { color: green; }
.there { color: green; }
</pre></div>
You may wonder why there's a need for a universal selector; as you've seen before, you can affect the style of an entire page by using a selector of the <code><body></code> tag. It's important to understand that the universal selector sets the style on all elements and doesn't just set an inherited default. What do I mean? Consider the following style sheet:
<div><pre>* { color: green; }
h1 { color: blue; }
</pre></div>
Let's assume you'll link that to an HTML file that includes this:
<div><pre><h1>This is <em>very</em> important</h1>
</pre></div>
What color will the word "very" be? It will be green and in the middle of a blue headline because the universal rule says everything has the color green explicitly set, just as if there were a rule for every possible element, reading
<div><pre>element { color: green; }
</pre></div>
In practice, you'd probably want the color of the <code><em></code> to inherit from the <code><h1></code>'s style, so you need to be very careful about when and where you use a universal selector. You would have gotten a very different result if you did the following:
<div><pre>body { color: green; }
h1 { color: blue; }
</pre></div>
This would also make the default text green and the <code><h1></code> heading blue, but the embedded <code><em></code> would inherit the color from the <code><h1></code>. You'll learn more about inheritance in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], "Cascading and Inheritance."
./ ADD NAME=CH05LEV1SEC2.HTML
== Combining Simple Selectors==
To get the most utility out of your CSS rules, you'll want to write combined rules. You've already learned a little about grouping selectors together; now you'll see how you can use descendant selectors as well.
Grouping Selectors
As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], you can combine rules by listing the selectors together, separating them by commas. You can combine any sort of selectors in this way, such as in the following rule:
<div><pre>/* Anything that is sorta heading-like is in Arial;
only even headings are maroon and the rest are green */
h1, h2, h3, h4, h5, h6, dt, .heading, .standout, #headline
{ font-family: Arial; }
h1, h3, h5, dt, .heading, .standout, #headline
{ font-color: maroon; }
h2, h4, h6
{ font-color: green; }
</pre></div>
Alternately, you could have written the same set of rules in another way by grouping them differently:
<div><pre>/* Anything that is sorta heading-like is in Arial;
only even headings are maroon, and the rest are green */
h1, h3, h5, dt, .heading, .standout, #headline
{ font-family: Arial;
font-color: maroon; }
h2, h4, h6
{ font-family: Arial;
font-color: green; }
</pre></div>
Writing it the first way makes it easier to change the font family if you need to; the declaration <code>font-family: Arial;</code> appears in only one place in your document. The way you group your rules can improve the ease with which you can modify them. Note, though, that there's a drawback to this approach, as well; to change how one type of selector is rendered (say, anything in the <code>standout</code> class), you need to edit several rules. There are no hard-and-fast guidelines, therefore, about how you can group your rules in modules; as you gain experience with CSS, you'll form your own methods for style rules grouping.
Descendant Selectors
One of the most useful ways to group selectors together is to use a descendant selector. A descendant, in HTML and XML, is an element that's completely contained within another element's content. As an example, the <code><h2></code> is a descendant of the <code><div></code>, and the <code><cite></code> of the <code><h1></code>, in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex03 Listing 5.3]. The <code><cite></code> is also a descendant of the <code><div></code>, as it's contained by both the <code><div></code> and the <code><h1></code>, and they are all descendants of the <code><body></code> element.
Listing 5.3. Descendants in HTML
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- babe-5.3.html --><br /><html><br /><head><br /><title>Babe: Best Movie EVER</title><br /><style type="text/css"><br />/* add style rules here */<br /></style><br /></head><br /><body><br /><div class="header"><br /><h1>Movie Review: <cite>Babe</cite></h1><br /><p>A Mini-Review by Joe H. Moviefan</p><br /></div><br /><div class="opinion"><br /><h2>The Best Movie <em>EVER</em></h2><br /><p>The movie <cite>Babe</cite> was the best family<br />movie ever produced! This great movie featured<br />talking animals, a cantankerous old man, and<br />subtle-yet-Oscar-winning special effects -- who<br />could ask for more? The clever writing and<br />humorous touches make this all-ages movie great<br />for children while still very enjoyable by<br />adults. What a great movie!</p><br /></div><br /><div class="footer"><br /><p>What did you think? Mail me at<br /><a href="mailto:joe@example.com">Joe H.<br />Moviefan.com!</a></p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Descendant selectors define rules based on where a given tag appears within the page by combining together simple selectors, separated by spaces. For example, here's a rule to change the color of all <code><cite></code> tags contained within paragraphs:
<div><pre>p cite { color: white; background-color: black; }
</pre></div>
You'll notice that I listed the outside tag first and then the inside. If you did it the other way around, you wouldn't match anything because no cite tags contain paragraph tags.
If this rule is added to the <code><style></code> element of the HTML page from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex03 Listing 5.3], the effect shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig02 Figure 5.2] is produced. Notice that the <code><cite></code> within the <code><h1></code> is not styled by this rule, only the <code><cite></code> inside the <code><p></code> element.
<div style="text-align: center;"> Figure 5.2. Firefox displays the second <code><cite></code> with the chosen style.
[[Image:05fig02.jpg|500px]]
</div>
It's important to keep in mind that a descendant selector means any descendant, not just an immediate child. A descendant could be an element inside an element inside an element. This enables you to make rules that apply to any descendant element, no matter how deeply it's nested.
You can combine section styles (set via <code>class</code> and <code><div></code>) with element-based type selectors, as well; for example, the following code changes the font face and colors of <code><p></code> tags within the <code>header</code> section, but leaves the rest of the header aloneas well as the other paragraph tags that aren't contained by something with the <code>.header</code> class:
<div><pre>.header p { font-family: Verdana, sans-serif;
color: white; background-color: black; }
</pre></div>
The effects of this rule are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig03 Figure 5.3].
<div style="text-align: center;"> Figure 5.3. Changing the header paragraph font style.
[[Image:05fig03.jpg|500px]]
</div>
A more complete style sheet that demonstrates how to set a number of different combined selectors is listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex04 Listing 5.4]. To use this with my movie review page, I'll add the following to the <code><head></code> of the page:
<div><pre><link type="text/css" rel="stylesheet" href="babe-5.4.css">
</pre></div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig04 Figure 5.4] shows how [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex03 Listing 5.3] looks with this style sheet applied.
<div style="text-align: center;"> Figure 5.4. Displaying various selectors with separate styles. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/05fig04_alt.jpg [View full size image]]</div>[[Image:05fig04.jpg|500px]] </div>
Listing 5.4. A Variety of Selectors in a Single Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* babe-5.4.css: Style sheet for Babe review */<br />body<br />{ font-family: Arial, sans-serif;<br />color: black;<br />background-color: white; }<br />.header h1<br />{ font-family: "Courier New", monospace;<br />color: silver;<br />background-color: black; }<br />.header cite<br />{ font-family: Verdana, sans-serif;<br />background-color: silver;<br />color: black; }<br />.header p<br />{ font-family: Arial, monospace;<br />color: black;<br />font-size: x-large; }<br />.opinion h2<br />{ color: white;<br />background-color: navy;<br />font-family: Arial, sans-serif; }<br />em<br />{ font-size: larger; }<br />p cite<br />{ color: white;<br />background-color: black; }<br />.footer<br />{ font-family: "Times New Roman", serif;<br />font-size: small;<br />color: white;<br />background-color: gray; }<br />.footer a<br />{ color: white;<br />background-color: black; }<br /></pre></div><br />
|}
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Experimenting with Simple Selectors
Why not try out these selectors yourself? You can use the example HTML files from this chapter.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Download either the accessibility tip in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05lev1sec1.html#ch05ex01 Listing 5.1] or the movie review in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex03 Listing 5.3] from the book's website.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Open the HTML file in a browser and view it without styles.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Create a style sheet. Add your own style rules based on the <code>class</code> and <code>id</code> attributes set in the HTML. Choose your own text colors, backgrounds, font sizes, and other properties.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Link your style sheet to the HTML file with the <code><link></code> element and view it in a browser. Are they styled the way you wanted? If not, try again until you're satisfied.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Add to the HTML filesrewrite the text, add more paragraphs, create new <code>class</code> and <code>id</code> attributes. Write new CSS rules based on these! Or even better, write your own pages from scratch and use your own content for testing out combined selectors.<br /><br /></div>
|}
|}
./ ADD NAME=CH05LEV1SEC3.HTML
== Pseudo-Classes and Pseudo-Elements ==
In addition to type selectors, <code>id</code> selectors, and <code>class</code> selectors, CSS also allows pseudo-class and pseudo-element selectors.
A pseudo-class selector is a selector based on a set of predefined qualities that an HTML element can possess. These qualities function in practice similar to a <code>class</code> attribute on the element, so in CSS terms, they are called pseudo-classes. No actual <code>class</code> attributes exist in the markup that corresponds to these pseudo-classes; instead, they represent some aspect of the element to which they're applied, or even the state of the browser's user interface relative to that element.
A pseudo-element selector identifies a virtual element, one that doesn't exist in the markup but can be deduced by the browser and used to apply a style. As with pseudo-classes, there is no markup that corresponds to the pseudo-element.
Simple Pseudo-Classes
The pseudo-classes in CSS are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05table01 Table 5.1]. The <code>:active, :focus</code>, and <code>:hover</code> pseudo-classes are covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch12.html#ch12 Hour 12], "Styling Links."
{| cellspacing="0" cellpadding="5"|+ Table 5.1. CSS Pseudo-Classes
|-
| Pseudo-class
| Selects
|-
| <code>:active</code>
| Elements that have been activated (such as active links)
|-
| <code>:first-child</code>
| The first child of an element
|-
| <code>:focus</code>
| Elements that have focus (such as form fields receiving input)
|-
| <code>:hover</code>
| Elements that are pointed at (such as by a mouse)
|-
| <code>:lang()</code>
| Styles for a specific language
|-
| <code>:link</code>
| Unfollowed links
|-
| <code>:visited</code>
| Previously visited links
|}
Pseudo-classes can stand alone in a style rule, as classes can, but most commonly they're used with elements as a type selector, as follows:
<div><pre>:link { color: red; }
a:link { color: red; }
</pre></div>
Both these rules are valid; the former applies to any element that happens to be a link, whereas the latter rule covers only <code><a></code> tags. In practice, these are the same things in HTML: Only the <code><a></code> elements are links, and so the rules mean the same thing.
You can combine pseudo-classes with real classes or even other pseudo-classes by putting them together with no spaces between, just the <code>.</code> and <code>:</code> indicators. For example, here's HTML with <code>class</code> attributes set on links:
<div><pre><a href="search.html" class="nav">
Search the Site
</a>
...
<a href="http://www.idyllmtn.com/" class="offsite">
Idyll Mountain Internet
</a>
</pre></div>
Here are rules to work with each of those links; note that the order of the <code>class</code> and the pseudo-class doesn't matter:
<div><pre>a:link.nav { color: cyan; }
a.offsite:link { color: green; }
</pre></div>
The <code>:link</code> and <code>:visited</code> Pseudo-Classes
In HTML, you can use attributes on the <code><body></code> tag to determine the colors of links:
<div><pre><body link="red" visited="gray">
</pre></div>
CSS gives the same functionality through pseudo-classes, and by combining pseudo-class selectors with <code>class</code> or <code>id</code> selectors, you can put different link colors on different parts of the page as you'll see later in this hour.
The <code>:link</code> pseudo-class is the equivalent of the <code><body></code> attribute link in HTML: It defines a style for links that have yet to be followed. You usually set these on the <code><a></code> tag because <code><a></code> is the only visible linking element in HTML. Here's an example CSS rule using <code>:link:</code>
<div><pre>a:link { color: red; }
</pre></div>
Visited links are those that the user has already been to; the browser keeps track of a list of visited URLs and colors them differently. The <code>:visited</code> pseudo-class is used to write rules applying to those types of links, as follows:
<div><pre>a:visited { color: gray; }
</pre></div>
The <code>:link</code> and <code>:visited</code> pseudo-selectors are mutually exclusive; a given link is either one or the other at any given time and can't be both at once. However, you can write a rule that applies to both, such as
<div><pre>a:link,
a:visited { color: blue; }
</pre></div>
<div>Watch Out!
Note that changing the <code>:link</code> and <code>:visited</code> colors to the same value can cause problems for users! Most users expect links to change to some coloranything other than the original, although usually from blue to purpleafter they have been visited. Unless you've got a good reason for it, you'll probably want to supply different <code>:link</code> and <code>:visited</code> colors.</div>
Unlike HTML, which lets you change only the colors of the links, CSS allows you to apply nearly any style to unvisited or visited links by using the <code>:link</code> and <code>:visited</code> pseudo-selectors. For example:
<div><pre>a:link { color: black;
background-color: lime;
font-family: Arial, sans-serif; }
a:visited { color: gray;
background-color: yellow;
font-family: "Times New Roman", serif; }
</pre></div>
This puts your unvisited links in black text on a lime green background and puts the visited links in gray on a yellow background. Unvisited links are in Arial font, and visited links are in Times New Roman. Now, apart from an illustrative example, you never want to write rules like these; it doesn't make sense, for example, for the font face to change when you've clicked on a link and some of my color choices are just plain ugly. Background colors on links do help them stand out from rest of the page, though, and that's not such a bad thing. You'll learn more about the theory behind link styles in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch12.html#ch12 Hour 12].
To color links differently on different sections of the page, combine <code>:link</code> and <code>:visited</code> pseudo-selectors with section classes in a descendant selector, like this:
<div><pre>#breadcrumb { background-color: black; color: white; }
#breadcrumb a:link { color: cyan; font-size: large; }
#breadcrumb a:visited { font-size: small; color: fuchsia; }
</pre></div>
This creates a black breadcrumb trail with unvisited links in large cyan letters (bright blue) and visited links in smaller, fuchsia (bright purple). If you add these styles to the style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05lev1sec1.html#ch05ex02 Listing 5.2], the accessibility tip page from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05lev1sec1.html#ch05ex01 Listing 5.1] will look like the page shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig05 Figure 5.5].
<div style="text-align: center;"> Figure 5.5. Pseudo-class selectors coloring links on a page. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/05fig05_alt.jpg [View full size image]]</div>[[Image:05fig05.jpg|500px]] </div>
The <code>:first-child</code> Pseudo-Class
The <code>:first-child</code> pseudo-class is used to select an element that's the first child of another element. The first child is the first tag within some other element; if the first child matches the base type of the selectorthe part before the <code>:first-child</code> pseudo-classthen the rule applies to that element.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex05 Listing 5.5] shows the start of a short story. The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex06 Listing 5.6] sets the first paragraph of the story to be larger than the rest, as well as gives it a silver background. The results are displayed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig06 Figure 5.6].
Listing 5.5. A Few Paragraphs in HTML
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- story-5.5.html --><br /><html><br /><head><br /><title>Fortune of Reversal</title><br /><link type="text/css" rel="stylesheet"<br />href="story-5.7.css"><br /></head><br /><body><br /><h1 id="storytitle">Fortune of Reversal</h1><br /><div class="storybody"><br /><p>They dined on heaping platters of Szechuan chicken, of<br />spicy beef, of shrimp and vegetables in some exotic dish<br />without a name. Bits of food were passed from chopsticks<br />to chopsticks, violating all known laws of Chinese<br />cuisine etiquette. The tea flowed hot and fast that night,<br />until the meal finally concluded itself.</p><br /><p>"Thank you for dining here tonight," said the badgeless,<br />anonymous waitress. She placed a small tray containing the<br />check and two wrapped fortune cookies on the edge of the<br />table, and hefted the empty plates one by one, forming a<br />stack on the crook of her elbow.</p><br /><p>"Absolutely delicious," declared Oliver as he pulled a card<br />from his wallet and flicked it onto the bill. He picked up<br />the two cookies, an afterthought. "Fortune cookie, my<br />love?" he asked Amanda.</p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Listing 5.6. A Style Sheet Using <code>:first-child</code> Pseudo-Class Selector
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* story-5.6.css */<br /><br />#storytitle<br />{ font-family: Verdana; }<br /><br />.storybody p<br />{ font-family: Arial; }<br /><br />.storybody p:first-child<br />{ font-size: x-large;<br />background-color: silver; }<br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 5.6. Firefox uses the <code>:first-child</code> selector to style the first paragraph.
[[Image:05fig06.jpg|500px]]
</div>
<div>Watch Out!
Internet Explorer for Windows does not support the <code>:first-child</code> pseudo-element; rules with such selectors are ignored. For maximum compatibility, set a <code>class</code> attribute manually on your first child elements, such as <code>class="firstone"</code>, and then include that <code>class</code> as an additional selector in your rule. For example:
<div><pre>.storybody p:first-child, .storybody p.firstone
{ font-size: large; }
</pre></div>
Of course, by doing so you've made the first half of the selector redundantthe other browsers understand the class-based workaround! So you may want to drop the use of <code>:first-child</code> entirely if you're going to add this workaround.</div>
The <code>:lang()</code> Pseudo-Class
On the Web, languages are indicated by a two-letter code, sometimes followed by a dash and an additional country code for regional versions of a language. Some of these languages are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05table02 Table 5.2]; for a complete list, see the book's website.
{| cellspacing="0" cellpadding="5"|+ Table 5.2. Several Language Codes
|-
| Code
| Language
|-
| <code>de</code>
| German
|-
| <code>en</code>
| English
|-
| <code>en-ca</code>
| Canadian English
|-
| <code>en-uk</code>
| British English
|-
| <code>en-us</code>
| American English
|-
| <code>fr</code>
| French
|-
| <code>jp</code>
| Japanese
|-
| <code>ru</code>
| Russian
|}
The choice of language can dictate a number of factors, including the direction of the text, the fonts used, or even the dictionary for pronunciation used by a screen reader. The CSS language doesn't allow you to set the language, which must be done in the HTML or in an HTTP header, but it does let you create rules or style sheets that apply to only certain languages.
To set the language within an HTML document, you simply have to use the <code>lang</code> attribute on the <code><html></code> tag. Sections of a second language embedded within the document can be indicated with the <code>lang</code> attribute on a <code><span></code> or any other appropriate HTML element, such as <code><blockquote></code> or <code><div></code>.
The CSS specification defines a special pseudo-class, <code>:lang()</code>, for indicating rules that should be applied only to elements that match a certain language. Such a rule is written like the following:
<div><pre>:lang(en-uk) { background-color: #CCCCFF; }
</pre></div>
This would display anything written in British English with a light blue background color. How does the browser know which parts of the text are written in British English? It needs to be set in the HTML, as in the following:
<div><pre><p>He cried out in a bad Monty Python imitation,
<span lang="en-uk">He's pinin' for the fjords!</span>
</p>
</pre></div>
By itself, <code>:lang()</code> is not particularly useful, but when combined with other CSS rules and properties, it can be quite powerful.
Pseudo-Elements in CSS
Cascading Style Sheets defines four pseudo-elementsvirtual elements created from their content in the document in relationship to a base element. These are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05table03 Table 5.3]. The pseudo-elements <code>:before</code> and <code>:after</code> are used to insert generated content and are discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch23.html#ch23 Hour 23], "User Interface and Generated Content."
{| cellspacing="0" cellpadding="5"|+ Table 5.3. The Pseudo-Elements of CSS
|-
| Pseudo-Element
| Selects
|-
| <code>:before</code>
| Inserts something before an element
|-
| <code>:after</code>
| Inserts something after an element
|-
| <code>:first-letter</code>
| The first letter of a block element
|-
| <code>:first-line</code>
| The first line of a block element
|}
The pseudo-elements <code>:first-line</code> and <code>:first-letter</code> select portions of another element, and these portions operate as if they were separate inline elements; however, only certain properties can be applied to these pseudo-elements, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05table04 Table 5.4].
{| cellspacing="0" cellpadding="5"|+ Table 5.4. Recognized Properties for <code>:first-line</code> and <code>:first-letter</code> Selectors
|-
| valign="bottom" | Property or Category
| valign="bottom" | <code>:first-line</code>
| valign="bottom" | <code>:first-letter</code>
| valign="bottom" | Hour Covered
|-
| Background properties
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch11.html#ch11 Hour 11]
|-
| Border properties
|
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16]
|-
| Color properties
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| Font properties
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch09.html#ch09 Hour 9]
|-
| Margin properties
|
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16]
|-
| Padding properties
|
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16]
|-
| <code>clear</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15]
|-
| <code>float</code>
|
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15]
|-
| <code>letter-spacing</code>
| yes
|
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| <code>line-height</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| <code>text-decoration</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| <code>text-shadow</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| <code>text-TRansform</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|-
| <code>vertical-align</code>
| yes
| yes
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15]
|-
| <code>word-spacing</code>
| yes
|
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10]
|}
The <code>:first-line</code> Pseudo-Element
The <code>:first-line</code> pseudo-element is a virtual element used to identify the first line of an element for adding specific styles that apply to only the first line. For example, you might want to put the first line of a news story in larger print to make it stand out. Such a rule would look like this:
<div><pre>p:first-line { font-size: large; }
</pre></div>
A <code>:first-line</code> pseudo-element creates a fictional tag set that is similar to a <code><span></code> or another inline element but whose content is determined when the page is rendered. As much as will fit on one line is included in the fictional tag. This will vary depending on the size of the user's browser window, the font size, and other factors, so there's no way to calculate it beforehand. This means that there aren't any viable workarounds for browsers that don't support <code>:first-line</code> because there's no way to know what will fit on one line. Fortunately, the current versions of modern browsers support <code>:first-line</code>.
The <code>:first-letter</code> Pseudo-Element
A <code>:first-letter</code> selector also references one of those imaginary, generated elements that doesn't appear in the source code but can be referenced by CSS rules. In this case, the imaginary tag is one surrounding the first letter of the element. The most common use for this is creating an initial capital letter that's larger than surrounding text.
Here's an example of a style sheet that uses both <code>:first-letter</code> and <code>:first-line:</code>
<div><pre>/* story-5.7.css */
#storytitle
{ font-family: Verdana, sans-serif; }
.storybody p
{ font-family: Arial, sans-serif; }
.storybody p:first-line
{ background-color: silver; }
.storybody p:first-letter
{ font-size: xx-large;
color: white;
background-color: black;
font-family: Verdana, sans-serif; }
</pre></div>
The result of applying this style sheet to the story sample from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex05 Listing 5.5] can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig07 Figure 5.7].
<div style="text-align: center;"> Figure 5.7. A large initial capital letter styled by a <code>:first-letter</code> rule. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/05fig07_alt.jpg [View full size image]]</div>[[Image:05fig07.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Using <code>:first-letter</code> with <code>:first-child</code>
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05fig07 Figure 5.7], each paragraph begins with a large capital letter, white on a black background. In many situations, however, only the first paragraph should have such a large initial capital letter. Make it so by doing the following:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Download both the HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex05 Listing 5.5] and the style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05ex06 Listing 5.6] from the book's website.<br /><br /></div>
|-
| >
| >
|-
| <div>'''2. '''</div>
| <div>Edit the <code>.storybody p:first-letter</code> rule so that it looks like this:<br /><br /><div><pre>.storybody p:first-child:first-letter<br />{ font-size: xx-large;<br />color: white;<br />background-color: black;<br />font-family: Verdana, sans-serif; }<br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Open this in your browser. How does it look? If you aren't using Internet Explorer for Windows, you should see that only the first paragraph has a large initial capital letter.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>How can you fix this to work in Internet Explorer? Recall the warning and work-around earlier this chapter.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Edit your HTML and CSS file to add a class and a style rule that will make your initial capital letter Internet Explorer-proof.<br /><br /></div>
|}
|}
./ ADD NAME=CH05LEV1SEC4.HTML
== Summary ==
The selector is the part of the CSS rule that designates the recipient of the styles defined in the style declaration. Type selectors can be used to style specific types of HTML elements, and <code>class</code> and <code>id</code> selectors choose them according to attribute values. The universal selector sets a style on all elements.
You create a descendant selector by combining two or more simple selectors together to show the hierarchy of the elements on the page. Using this technique, you can apply different styles to different sections of the page.
Pseudo-element and pseudo-class selectors let you select parts of the page that aren't otherwise distinguished in the HTML. Rules with <code>:link</code> and <code>:visited</code> pseudo-class selectors can be used to style hypertext links. The <code>:lang()</code> pseudo-class can add styles to text in specific languages. The <code>:first-child</code>, <code>:first-letter</code>, and <code>:first-line</code> selectors are used for text formatting.
./ ADD NAME=CH05LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa1q1a1 Q.]'''
| Are there other selectors that aren't covered here?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa1q1 A.]'''
| Yes, and you'll learn about them in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors." Some of these are not well supported by the browsers, however.
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa1q2a2 Q.]'''
| Can I string together as many selectors as I like?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa1q2 A.]'''
| Certainly. You aren't limited to just two items in a descendant selector, for example. You could write a rule with a selector like the following, if you wanted:
<div><pre>body div #content p.special a:visited { color: green; }<br /></pre></div><br />
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q1a1 1.]'''
| Which of the following selectors means "select any <code><em></code> tag that's both part of the class <code>old</code> and within a <code><p></code> tag?"
<div># <div><code>em.old p</code></div>
# <div><code>em.old, p</code></div>
# <div><code>p.old em</code></div>
# <div><code>p em.old</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q2a2 2.]'''
| What rules would you write to make all visited links red and all unvisited links lime, and to make both kinds of links display in Arial font?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q3a3 3.]'''
| Which pseudo-element or pseudo-class can't be duplicated by using a <code><span></code> tag with an appropriate class set, and why?
<div># <div><code>:first-child</code></div>
# <div><code>:first-line</code></div>
# <div><code>:first-letter</code></div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q1 1.]'''
| The correct answer is (d), <code>p em.old</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q2 2.]'''
| Here is one set of CSS rules to make unvisited links lime and visited links red, both in Arial font:
<div><pre>a:link { color: red; font-family: Arial, sans-serif; }<br />a:visited { color: lime; font-family: Arial, sans-serif; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch05qa2q3 3.]'''
| The <code>:first-line</code> cannot be duplicated by the <code><span></code> tag because the author of the web page doesn't know where the first line will end when displayed on the user's browser.
|}
Exercise
In this hour, you saw several HTML pages and associated style sheets that used selectors to style the page. To further explore selectors, you can create additional style rules by selecting specific elements and styling them appropriately.
./ ADD NAME=CH06.HTML
huys7j78tcfg6ethjba1c2etj18v43l
User:Bartlett/06
2
2109
39216
5494
2026-04-13T06:03:16Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39216
wikitext
text/x-wiki
= Hour 6. The CSS Box Model =
; What You'll Learn in This Hour:
* How web content is displayed visually in CSS as boxes
* What categories of display elements are used and how you can affect an element's display type
* How CSS browsers interpret and display web pages
* How to set margins, borders, and padding on a box
This hour explores the core of Cascading Style Sheetsthe part of the specification that defines how parts of a web page are displayed: as stacks of boxes. The visual presentation of CSS is defined as a series of boxes based on the structure of the original document.
|}
./ ADD NAME=CH06LEV1SEC1.HTML
== Displaying Content in CSS ==
The content of a web page is the information encoded within the HTML page, found between the opening and closing tags of the HTML markup. These tags define the structure of the content, a framework that gives meaning to the content. For example, consider the following HTML:
<div><pre><p>This is the <strong>tricky part</strong>,
so pay attention!</p>
</pre></div>
The content in this example is simply the sentence <code>This is the tricky part, so pay attention!</code> The tags embedded within (and surrounding) the content create the structure, which gives meaning to the content. Any browser that understands HTML knows that the whole thing is a paragraph (identified by the <code><p></code> tag) and that the phrase <code>TRicky part</code> is strongly emphasized.
The presentation of the content, however, is not defined by the HTML; instead, it's determined by CSS rules. The browser has default rules for <code><p></code> and <code><strong></code> tags, which say that a <code><p></code> is shown visually as a paragraph on lines of its own, with leading and trailing space, and that the <code><strong></code> is shown as bold text within that paragraph.
Both the <code><p></code> and <code><strong></code> tags are shown as display boxes, which is how CSS browsers deal with HTML elements. Each HTML element corresponds to a display box, although not all elements are shown on the screen. A display box is a rectangular shape on the screen that can contain text content, images, form controls, or other display boxes.
The exact method by which HTML elements are shown as CSS display boxes is called the visual formatting method. The visual formatting method tells browsers how they should show HTML content on the screen.
Types of Elements
In the visual formatting model, markup elements are classified into two basic typesblock and inline. The type of element determines how CSS browsers will display instances of that element.
The initial type of each HTML element is set by the HTML specification. For example, <code><p></code> tags are block elements, and <code><em></code> tags are inline elements. The full list is given in the HTML 4.01 Recommendation; each tag has an indication as to what type it is. You can change the type of a specific element with CSS, although often you won't need to.
Certain CSS properties can be set only on block or inline elements; for example, the <code>text-indent</code> property (which you'll learn about in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment") applies only to block elements.
Block
A block element is one that is intended to be displayed as a distinct block of content, starting and ending with a new line. Besides the <code><p></code> tag, other block elements in HTML include <code><div></code>, <code><blockquote></code>, <code><table></code>, <code><br></code>, <code><ol></code>, and the <code><h1></code> to <code><h6></code> tags.
Block elements are listed one after each other, vertically down the page. They are as wide as they can be, which means that unless they're constrained in some way (by other block elements, by CSS properties, or by HTML markup), they'll stretch across the whole page.
<div>Did you Know?
One thing you'll notice when you start using CSS is that your headers (<code><h1></code> and friends) go all the way across the screen. Set the <code>background-color</code> property on an <code><h1></code> and you'll see how big it really is.</div>
Inline
An inline element doesn't begin and end lines; instead, it is contained within the flow of the text. Examples of inline tags include <code><em></code>, <code><span></code>, <code><b></code>, <code><img></code>, <code><input></code>, and <code><a></code>.
Inline elements flow one after another in a line, with no line breaks, horizontally across the page until the end of the available space is used up; then they just continue where they left off on the next line down.
The <code>display</code> Property
You can change the type of an element by using the <code>display</code> property. This property can take several values; the ones we're primarily concerned with in this hour are <code>block</code> and <code>inline</code>. There's another important value for <code>display</code> that's called none; something that has the <code>display</code> property set to <code>none</code> does not display at all, nor is anything inside of it displayed.
Setting the <code>display</code> property to <code>block</code> or <code>inline</code> changes the type of that element to the specified type. For example, imagine that you want to make a navigation menu, and you want all your <code><a></code> elements within that menu to appear as block elements. The HTML code may look like this:
<div><pre><div class="nav">
<a href="friends.html">My Friends</a>
<a href="cat.html">My Cat</a>
<a href="friendscats.html">My Friends' Cats</a>
<a href="catsfriends.html">My Cat's Friends</a>
</div>
</pre></div>
The <code><a></code> element is an inline element according to the HTML 4.01 specification, so by default browsers display these links as a row all on the same line, or maybe wrapping around to the next line down if there is no more room. To display these <code><a></code> tags as block tags, use this rule:
<div><pre>.nav a { display: block; }
</pre></div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig01 Figure 6.1] shows the effect of applying this rule; the first set of links is identical to the second, except that the previous rule and a silver background have been applied to it. The background illustrates that the block element goes all the way across the browser window and doesn't stop at the end of the text within it. Also, the links are clickable even on the far right side of the screen, not just on the blue underlined words.
<div style="text-align: center;"> Figure 6.1. Before and after redefining the <code><a></code> links as block. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/06fig01_alt.jpg [View full size image]]</div>[[Image:06fig01.jpg|500px]] </div>
./ ADD NAME=CH06LEV1SEC2.HTML
== Understanding the Box Model ==
Within the visual formatting model, all elements generate specific types of boxes. The method for displaying these boxes is called the box model, and understanding the box model is crucial for understanding how Cascading Style Sheets will display web pages.
The box model is defined in terms of elements, documents, trees, and of course, boxes. Many of us are not used to thinking about web pages in terms of these elements unless we've done a lot with XML or SGML. So you first need to understand the assumptions that CSS makes about web documents.
<div>By the Way
In formal W3C specifications, you rarely see terms such as web page; instead everything talks about documents. Likewise, you don't see much about tags and browsers, but instead elements and user agents. Although it may seem that this is just semantic snobbishnessand to some degree it is!there are actually some valid reasons for drawing these distinctions when speaking formally. In this book, I try to avoid writing text like you'd see in a W3C Recommendation; if you want one of those, you can find it on the W3C site at [http://www.w3.org/ http://www.w3.org/]. However, terminology counts for this discussion, and my apologies if I sound formal.</div>
Documents as Trees
Did you know that every web page is actually a tree of tags and content? If you didn't, that's okay; these types of trees are the same kind of data structures used in computer science, and most web developers aren't necessarily computer scientists.
A tree is a way of representing information in a hierarchy of elements. Think of it as somewhat similar to a family tree in genealogyone that starts at a certain ancestor and goes down from there. Your great-grandmother may be at the top; her children (including your grandmother) in the second level down; your mother, her siblings, and her cousins in the third level down; and you and the other members of your generation in the fourth level.
In the same way, an HTML document can be thought of as a tree with the <code><html></code> element as the top. In this context, the <code><html></code> element is known as the root element.
The <code><html></code> element has two children: the <code><head></code> and the <code><body></code>. These are shown lower on the treethe next levels down. The <code><head></code> has children too; <code><title></code> is one in every document, and <code><link></code> may be there to call in an external style sheet. The <code><body></code> element contains the content of the page; this could be anything from <code><h1></code> and <code><table></code> to <code><div></code> or <code><hr></code>. Some of those may have their own children, and some may not.
Each part of a tree is called a node. A node is either an element (possibly with children) or some text. Text nodes can't have children; they're just text.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06ex01 Listing 6.1] shows a very simple web page, and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig02 Figure 6.2] shows a representation of a tree based on that page.
Listing 6.1. The First Two Lines of a Poem About Trees
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><html><br /><head><br /><title>Trees</title><br /></head><br /><body><br /><h1>Trees, by <i>Joyce Kilmer</i></h1><br /><p><br />I think that I shall never see<br /><br><br />A poem as lovely as a tree.<br /></p><br /></body><br /></html><br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 6.2. Our poem represented as a tree.
[[Image:06fig02.jpg|500px]]
</div>
Documents as Boxes
After an HTML document has been defined as a data tree, it can then be visually interpreted as a series of boxes. This is probably an easier way for web developers to think of a page, but it's important to reach that understanding by first visualizing a tree because that's how a CSS browser considers the page.
You can think of these boxes as containers that hold other boxes or that hold text values. Each box in the CSS box model is held within another box, except for the box corresponding to the root node in the tree. The outer box is called the containing box. A block-containing box can hold other block boxes or inline boxes; an inline-containing box can hold only inline boxes.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig03 Figure 6.3], you can see the tree poem expressed as a series of nested boxes. You'll notice that some of these boxes don't have labels; a box exists, but no HTML tag! Those boxes are known as anonymous boxes. Anonymous boxes result whenever a tag contains mixed contentboth text and some HTML tags. The text parts become anonymous boxes. An anonymous box is styled the same as its containing box.
<div style="text-align: center;"> Figure 6.3. The tree poem as nested boxes.
[[Image:06fig03.jpg|500px]]
</div>
Also notice that the <code><br></code> tag is an empty tag; it doesn't contain any content, but it still generates a box. The <code><head></code> box appears in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig03 Figure 6.3], but in HTML the <code><head></code> tag is defined as <code>display: none;;</code> this is why you never see the content of the <code><head></code> tag.
./ ADD NAME=CH06LEV1SEC3.HTML
== Box Display Properties ==
After a browser has established that a box exists by building a tree as shown earlier and then by filling in the box model; it displays that box, either according to its own internal rules for displaying HTML or according to the style properties on that box.
In a way, all the CSS properties are box-display properties: They control how a box is displayed. However, three properties define the edges of that box: the <code>margin</code>, the <code>border</code>, and the <code>padding</code>.
The relationship between <code>margin, border, padding</code>, and the content itself is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig04 Figure 6.4]. In this example, the border color has been set to <code>gray</code> and the <code>background-color</code> to <code>silver</code>.
<div style="text-align: center;"> Figure 6.4. The <code>margin, border, padding</code>, and content of a box.
[[Image:06fig04.jpg|500px]]
</div>
<div>By the Way
You'll learn more about the <code>margin, border</code>, and <code>padding</code> properties in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes;" the current hour is a general introduction to the box model, and we'll get into more detail about other property values later in the book.</div>
The <code>margin</code> Property
The margin is an invisible property that surrounds all CSS boxes; it dictates how far that box is from other boxes. The margin is the outermost property of the box and defines the far edge of the box. Nearly all of the visible HTML elements have margins, although for many the default margin is 0 pixels.
Values for <code>margin</code> can be expressed in a variety of units; the most common values are pixels or ems. A pixel is the width of a single dot on the screen; pixel values are written as a number followed by <code>px</code>, such as <code>4px</code> or <code>12px</code>. An em is unit of measure that refers to the size of the current font; if the font is 12 pixels, an em is a unit of measure equal to 12 pixels. You write ems by putting the word <code>em</code> after a number, such as <code>3em</code> or <code>0.5em</code>.
Pixels are absolute units; they do not scale with the user's preferences. Ems are relative units; relative units are calculated based on the current font. Other units you can use include points (<code>pt</code>), centimeters (<code>cm</code>), inches (<code>in</code>), and percentages.
To set a margin of 1 em around a specific box, such as an <code><h1></code>, you'd write a CSS rule like this:
<div><pre>h1 { margin: 1em; }
</pre></div>
Margins are always transparent, meaning that whatever background color is set on the containing box shines through.
There's one more thing you need to know about margins, and that's collapsing margins. The vertical marginsthose above and below the elementdo something called collapsing, which means that only the largest value of the margins between two elements is used. Margins collapse only on block elements and only in a vertical direction, not horizontally.
<div>Did you Know?
One way to think of the collapse of margins is to imagine two motor homes parked next to each other. The owner of the motor home to the north says to the other, "Don't park within six feet of me." The owner of the southern motor home says, "Don't park within three feet of me." How close together can you park the motor homes, assuming you want to get them as close as you can? Obviously, you would park six feet away; that distance fits both requirements. That's what a <code>margin</code> value is like; you take the largest value of the two and use that as the vertical distance between two elements.</div>
The <code>border</code> Property
The <code>border</code> property is used to draw a border around a box. All boxes have borders, even if the size of the border is 0 pixels or ems, which is the default for HTML elements.
Each border has three qualities associated with it, which can all be set with the <code>border</code> property: the size of the border, the style of the border, and the color of the border. A border declaration reads like this:
<div><pre>selector { border: size style color; }
</pre></div>
The size of the border is measured the same way as the margin; pixels or ems are the most common units. Border styles include <code>solid, dashed</code>, and <code>dotted;</code> you'll use more border styles in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16]. The color of a border can be any CSS color name or RGB triplet.
So, to set a solid navy blue border that is 1/4 of the current font size around an <code><h1></code>, you would write a rule like this:
<div><pre>h1 { border: 0.25em solid navy; }
</pre></div>
And here's a dashed three-pixel purple border around paragraphs:
<div><pre>p { border: 3px dashed #660099; }
</pre></div>
You can set borders (and margins and padding) around inline elements as well as block elements. This sets a thin black border around <code><i></code> tags:
<div><pre>i { border: 1px solid black; }
</pre></div>
The <code>padding</code> Property
The space surrounding the content is the padding; this could be thought of as whitespace because there's nothing in it (no content or border), but keep in mind that it doesn't have to be white. The padding is always the same background color as the content itself, which means it is the color of the <code>background-color</code> set on the box.
Padding is measured in the same way as margins or borders; here's a three-pixel padding around <code><i></code> and a padding of 0.5 em around <code><h1></code>:
<div><pre>i { padding: 3px; }
h1 { padding: 0.5em; }
</pre></div>
Want to see the result of all the examples discussed so far? [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06fig05 Figure 6.5] shows what happens if you apply all the CSS rules named, including <code>margin, border</code>, and <code>padding</code>, to the poem from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06lev1sec2.html#ch06ex01 Listing 6.1]. I added a <code><style></code> section in the <code><head></code> and included these rules as an embedded style sheet.
<div style="text-align: center;"> Figure 6.5. Applying various box styles to the tree poem, as shown in Firefox. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/06fig05_alt.jpg [View full size image]]</div>[[Image:06fig05.jpg|500px]] </div>
./ ADD NAME=CH06LEV1SEC4.HTML
== Summary ==
The visual formatting model of CSS describes how pages should be displayed. An HTML (or XML) element can be block or inline, and the <code>display</code> property can change how an element is displayed.
The box model views web pages as nested boxes based on a tree view of a web document. Web pages are displayed as CSS properties set on those boxes.
The <code>margin, border</code>, and <code>padding</code> properties define the outer edge of the box. Margins are transparent and surround the box, separating it from other boxes; vertical borders collapse to the largest value. Borders are in specified colors and styles and are within the box's margin. Padding is inside the border and is the same background color as the content.
./ ADD NAME=CH06LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q1a1 Q.]'''
| What kind of element is a table cell? Is that block or inline?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q1 A.]'''
| It's neither inline nor block. The display value for a table cell (<code><td></code>) is special; it's <code>table-cell</code>. An element that has been set <code>display: table-cell</code> is displayed like a table cell (of course). This is a special type of block element, although there are some limitations; a <code>table-cell</code> element can't have a <code>margin</code>, for example. You'll learn more about tables and CSS in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17], "Styling Tables."
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q2a2 Q.]'''
| What is an em, anyway? Is it related to the size of a capital M?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q2 A.]'''
| Not really, although that's where it gets the name from, historically. In CSS, an em is defined as a measure equal to the size of the font; it is a square that is as tall as the font size and as wide as it is tall. It's not related to letter M officially because some fontsnon-English fontsdon't have the letter M, and CSS needs to be able to function with all fonts around the world.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q3a3 Q.]'''
| Okay, then what's a pixel? And a point? And how do percentages work?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa1q3 A.]'''
| A pixel is basically one dot on a screen; if you've got 800x600 resolution displaying on your monitor, it is showing you 800 pixels across and 600 pixels down. A point is 1/72 of an inch in CSS. Percentages are based on the width of the containing block. You'll learn more about CSS's units of measurement in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch09.html#ch09 Hour 9], "Fonts and Font Families," and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16].
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q1a1 1.]'''
| Is the <code><hr></code> element block or inline? How can you tell?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q2a2 2.]'''
| What is the correct order of the box model, from outside to inside?
<div># <div><code>border, margin, padding, content</code></div>
# <div><code>padding, border, margin, content</code></div>
# <div><code>margin, border, padding, content</code></div>
# <div><code>margin, padding, border, content</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q3a3 3.]'''
| Consider the following style rules:
<div><pre>body { background-color: red;<br />color: white; }<br />h1 { color: black;<br />padding: 1.5em;<br />border: 5px solid green;<br />background-color: yellow;<br />margin: 0.5em; }<br /></pre></div><br />
What is the color of the <code>margin</code> around an <code><h1></code>? What is the color of the <code>padding</code>?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q1 1.]'''
| Because horizontal rules are on separate lines and don't occur inline, <code><hr></code> must be block. You can check by looking it up in the HTML 4.01 specification on the W3C's website, [http://www.w3.org/ http://www.w3.org/].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q2 2.]'''
| (c). The outermost part of the box is the <code>margin</code>, then the <code>border</code>, and then the <code>padding</code> around the content.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch06qa2q3 3.]'''
| The color of the <code>margin</code> would be the <code>background-color</code> of the containing box; assuming the <code><body></code> contains the <code><h1></code>, the color would be red. The <code>background-color</code> of the <code><h1></code> determines the color of the <code>padding</code>, so the padding color is yellow.
|}
Exercise
Reading about margins and padding is one thing, but actually using them is how you'll learn to master them. Create a web page with some blocks to style<code><div></code> or <code><p></code> work well for this, as do the <code><h1></code> through <code><h6></code> headingsand set various values of margin and padding on each.
Make sure that you know the difference between the margin and padding by setting the padding around a block to 1 em, then the margin. Add in a border and you'll be able to see even more clearly that padding is within the border line and margin is without.
./ ADD NAME=CH07.HTML
01b4grh4f4xzl2h8f9xjvh01iu04lsc
User:Bartlett/07
2
2110
39217
5496
2026-04-13T06:03:17Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39217
wikitext
text/x-wiki
=Hour 7. Cascading and Inheritance =
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* What the secret formula behind the cascade really is
* Which CSS rules have the highest weight, and how those relate to HTML attributes
* How you can override the order of the cascade when writing CSS rules
* How the user can supply her own style sheet to express her preferences for display, and how those are balanced with the author's desires
* How to include one style sheet's rules within another style sheet, and which set of rules takes priority
* Which property values are inherited, which are calculated, and what that means for your CSS designs
The cascade is one of the key concepts of Cascading Style Sheetsso important, in fact, that the language was named after it. The cascade defines how you combine rules, including rules from different sourcessome provided by the web developer, some by the browser, and some from the user. When these are combined, values for properties on individual HTML tags are calculated. Some of these take their values directly from the CSS rules, whereas others are derived from other properties.
|}
./ ADD NAME=CH07LEV1SEC1.HTML
== How the Cascade Works ==
The cascade is the set of directions that determine what rules apply to a given element on the page. Without a method for determining priority of conflicting rules, it would be impossible to figure out which styles should be used. Take, for example, the style sheet shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07ex01 Listing 7.1]different rules with a number of different selectors.
Listing 7.1. A Colorful Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* colors-7.1.css */<br /><br />body { background-color: white;<br />color: black; }<br /><br />h1 { background-color: blue;<br />color: red; }<br /><br />em { background-color: green;<br />color: black; }<br /><br />#serious { color: purple; }<br /><br />.yahoo { color: black;<br />background-color: yellow; }<br /><br />#serious { color: maroon; }<br /><br />h1 em { color: lime; }<br /></pre></div><br />
|}
Now you'll look at a page that uses the style sheet and also has its own embedded CSS rules within a <code><style></code> element in the <code><head></code>. Such a page is listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07ex02 Listing 7.2].
Listing 7.2. An HTML Page with Tips on Color Use
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- tips-7.2.html --><br /><html><br /><head><br /><title>Accessibility of Color</title><br /><link type="text/css" rel="stylesheet" href="colors-7.1.css"><br /><style type="text/css"><br />.yahoo { background-color: silver;<br />color: white; }<br />h1 { background-color: yellow; }<br /></style><br /></head><br /><body><br /><h2>Accessibility Tip:</h2><br /><h1>Don't<br /><em class="yahoo" id="serious"<br />style="background-color: white;">Rely</em><br />on Color Alone</h1><br /><p> Some Web users may be unable to see color -- they may<br />be blind (and use a screenreader program); they may<br />be color-blind and unable to easily distinguish colors;<br />or they could be using an access device, such as a cell<br />phone, which does not display color. For this reason,<br />the W3C's Web Accessibility Initiative recommends that<br />you not <em>rely</em> upon color as the <em>only</em><br />way of conveying information.</p><br /><p style="color: navy;">This doesn't mean<br /><em class="yahoo" style="color: red;">"don't use color"</em><br />-- on the contrary,<br />color is very useful to those who can see it, and will<br />help make your page understandable. What it does mean<br />is that color (and other presentational effects) should<br />not be the only way you make something special. For<br />example, rather than use a <span> and a color<br />style to make something stand out, use the <strong><br />tag (which you can also style) so browsers that<br />can't use the visual CSS color rule can at least know<br />to emphasize that section -- perhaps by increasing the<br />volume when reading the text out loud, for example.</p><br /></body><br /></html><br /></pre></div><br />
|}
Now concentrate on the second word in the headline, "Rely." This word is within an <code><em></code> element, which is part of an <code><h1></code>. It has a class of yahoo and an id of <code>serious</code>. What color will the text be, and what color background will it have? You have several choices from several sources; by using the cascade, you can figure out what a browser will do with your example.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07table01 Table 7.1], I've listed the various sources from which the browser might find the background and foreground color for the word "Rely."
{| cellspacing="0" cellpadding="5"|+ Table 7.1. CSS Rules Applying to the Word "Rely"
|-
| Color
| Background
| Selector
| Source
|-
| <code>black</code>
| <code>white</code>
| <code>body</code>
| Linked style sheet
|-
| <code>red</code>
| <code>blue</code>
| <code>H1</code>
| Linked style sheet
|-
| <code>black</code>
| <code>green</code>
| <code>em</code>
| Linked style sheet
|-
| <code>purple</code>
|
| <code>#serious</code>
| Linked style sheet
|-
| <code>black</code>
| <code>yellow</code>
| <code>.yahoo</code>
| Linked style sheet
|-
| <code>marooon</code>
|
| <code>#serious</code>
| Linked style sheet
|-
| <code>lime</code>
|
| <code>h1 em</code>
| Linked style sheet
|-
| <code>white</code>
| <code>silver</code>
| <code>.yahoo</code>
| Embedded style sheet
|-
|
| <code>yellow</code>
| <code>H1</code>
| Embedded style sheet
|-
|
| <code>white</code>
| (implied)
| Inline style element
|}
Order of the Cascade
To be able to figure out which properties get applied to the <code><em></code> tag in your example, you need to think like a web browser. The first thing you need to do is to realize that many of your rules are combined rules. For example, take this rule:
<div><pre>.yahoo { color: black;
background-color: yellow; }
</pre></div>
The rule is actually two different rules, which happen to share a common selector, as follows:
<div><pre>.yahoo { color: black; }
.yahoo { background-color: yellow; }
</pre></div>
This is important because each declaration (property name and value) could be overridden separately. A rule that changes the color might not change the background color at all, so the <code>.yahoo</code> background-color rule would continue to stay in effect even if the <code>.yahoo</code> color rule is superceded.
So you need to consider only those rules that are in conflictin other words, those that designate different values for the same property name, such as those rules that affect the color property. When trying to analyze which rule takes priority, always break up rules in individual units as just shown.
How do you calculate which rule is applied? First, you sort these rules by their origin. In the cascade, the origin means one of the following: the author of the page, the user, or the browser. Author rules have priority over user rules, which have priority over the browser's default rules for how to display HTML elements. In this case, all of these rules have the same origin; they come from the author of the page.
Next you order the rules based on the selector and how specific it is. This specificity is calculated as follows:
<div># <div>An inline style attribute is the most specific type of rule. If there is an inline style rule for a specific CSS property, that rule "wins."</div>
# <div>An <code>id</code> selector is the second most specific. If there is more than one <code>id</code> in the rule, the rule with greatest number of <code>id</code> selectors wins.</div>
# <div>If there aren't any <code>id</code> selectors, or if there's the same number, count the number of classes or pseudo-classes in the rule. The rule with the most classes or pseudo-classes has the higher priority.</div>
# <div>If there's the same number of classes (or no classes), compare the number of elementsthe greater number of elements, the higher the specificity.</div>
# <div>If the number of <code>id</code> values, classes, and elements are all the same, whichever was declared most recently has the highest priority. If two rules have the same selector and are in disagreement on the value of a specific CSS property, the one listed second is more specific.</div></div>
If you ever encounter a tie, then move on to the next rule. For example, if you have a complex rule that has three id selectors, three <code>class</code> selectors, and two element selectors, and another with three <code>id</code> selectors, three <code>class</code> selectors, and one element selector, you have a tie for the <code>id</code> selectors, and a tie for the <code>class</code> selectors, so to resolve the cascade you need to move on to the number of elements to break the tie.
Applying these rules to your <code><em></code> text, you must consider the <code>color</code> property separately from the <code>background-color</code> property. The most specific rules that set the <code>color</code> property are the two rules with an id selectorthe <code>#serious</code> rules. Of these, the second one takes priority, which means the text color will be maroon.
To figure out the <code>background-color</code>, you just have to determine the most specific rule as well. In this case, the most specific rule is the inline style attribute, so the background will be white.
Calculating the colors of the <code><h1></code> is also a useful illustration; you have two competing <code><h1></code> selectors: one in the linked style sheet and one in the embedded style sheet. Which one triumphs? The one declared most recently; because your <code><style></code> comes after your <code><link></code>, the background-color will be yellow. If the order of the <code><link></code> and <code><style></code> elements were reversed, the background would be blue.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Pretend to Be a Web Browser
Here's your chance to show how good you are at imitating a web browser. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07ex01 Listing 7.1], there's a section in the second paragraph that reads "don't use color."
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Construct a table like [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07table01 Table 7.1]. List the selector, the source, the color, and the background color of each rule that applies to that section of text.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>For each rule, identify whether it comes from a <code>style</code> attribute, an <code>id</code> selector, a <code>class</code> (or pseudo-class) selector, an element selector, or a combination of these.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Rank each selector according to the specificity, as described this hour.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>What color will the text be? Test it in your web browser to check your answer.<br /><br /></div>
|}
|}
Cascading and HTML Attributes
In addition to setting <code>style, class</code>, and <code>id</code> attributes, HTML also has presentational attributes that let you affect how the page looks. Examples include <code>align, color, face, link, vlink, bgcolor</code>, and <code>background</code>.
When these attributes conflict with a CSS rule, the HTML attribute is considered to be the least specific declaration possible. In other words, the HTML attribute always is overridden by a CSS rule. However, in many cases you may want to set an HTML presentation attribute in case CSS is disabled or not understood by an older browser. Keep in mind that HTML presentational attributes are ignored only if there is a corresponding CSS rule; if there's no rule setting the color of an item, for example, the HTML value is used.
<div>Did you Know?
Remember, you generally can't use HTML presentation attributes with CSS if you are using the Strict variety of HTML. Use HTML 4.01 Transitional (or XHTML 1.0 Transitional) if you need to use HTML attributes along with your CSS styles.</div>
Using <code>!important</code> in Rules
When necessary, an author of a style sheet can designate one rule as explicitly more important than others. To do this, the author adds <code>!important</code> after the specific property name and value declaration, like this:
<div><pre>em { color: blue !important; }
</pre></div>
This overrides the normal order of the cascade by inserting a new requirement: Important rules come before rules that have not been designated as important. An <code>!important</code> rule, even one that is not very specific, always takes priority over a non-<code>!important</code> rule even if the latter is extremely specific.
The use of <code>!important</code> also changes one other part of the cascade: <code>!important</code> rules that originate with the user take priority over the author's rules. Normally, the author's rules have higher priority than the user's rules, but this allows users with special needs to define their own style sheets and designate their needs for access as more important than the author's desire for a certain style.
<div>Watch Out!
Those of you who have done programming in a language such as C++ or Perl may find this particular part of CSS perplexing. In most programming languages, an exclamation point (!) means "not," so <code>!important</code> looks like it means "not important," which is the exact opposite of the true meaning. Don't be surprised if it takes a while to get used to reading <code>!important</code> as "very important."</div>
./ ADD NAME=CH07LEV1SEC2.HTML
== User-Defined Style Sheets ==
A user-defined style sheet is one created by the user and stored on that person's local computer. The browser automatically loads this file and applies it to web pages that are viewed.
The purpose of a user-defined style sheet is to let the web surfer's preferences influence how he views the web. This is especially useful for certain specific groups of users, including those users with visual disabilities. For example, if you need a high-contrast display, your user style sheet could be set with a default black background, white text, and large font sizes.
In theory, user style sheets are quite beneficial; in practice, though, they require each web user to know how to write CSS to see the web the way she would like to see it! This is a rather high learning threshold for users who simply want to surf the web comfortably; you're learning CSS now because you want to design websites, not because you simply want to access information. Despite this, user style sheets are still incredibly functional for those who know how to use them, or for those who can download and install user style sheets written by others.
A user style sheet can have any kind of CSS rules that could normally be included in a style sheet, and the syntax is exactly the same; it's just another external style sheet, after all. However, there are certain types of rules that make less sense in a user style sheet, and several normal cautions can be relaxed.
In a user style sheet, you don't want to use any selectors that presume specific attribute values will be set, such as <code>class</code> or <code>id</code>, because you won't know what's in the HTML of each page.
Normally when creating a style sheet, you don't want to use absolute values in your font sizes, such as <code>9px</code> or <code>2cm</code>, because these don't take the user's preferences into account. A user with poor vision would have problems seeing a 9-pixel font size if you put this on a style sheet for the web. But because you know the exact properties of the final output medium when writing a user-defined style sheet for yourself, it's perfectly fine to use those values in your own user-defined style sheet.
Finally, you should declare these as <code>!important</code> to give them highest priority because, after all, it doesn't make sense to set your own preferences if the designer's style sheet can just overrule them.
An example of a user-defined style sheet is given in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07ex03 Listing 7.3]. This style sheet is designed specifically for a user who needs large print and high contrast (white-on-black).
Listing 7.3. A Sample User-Defined Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* user-7.3.css */<br />* { color: white !important;<br />background-color: white !important;<br />font-family: Verdana, sans-serif !important; }<br />body { font-size: 24pt !important; }<br />a:link { color: cyan !important; }<br />a:visited { color: violet !important; }<br /></pre></div><br />
|}
After you've created a user-defined style sheet and saved it on your hard drive (somewhere you can remember its location), you need to tell your browser to use it. How you do that depends on which browser you're using. In Internet Explorer, this is a preference under Accessibility. If you're using Firefox, you need to add your rules to the <code>user.css</code> file. In Opera, this is a preference under Document that lets you select a user-defined style sheet. It's an Advanced preference in Safari.
./ ADD NAME=CH07LEV1SEC3.HTML
== Importing CSS ==
To make style sheets that are more modular, you may want to import another style sheet. Importing, in this context, means that all the rules in the imported style sheet are included in the style sheet that is doing the importing. In this way, importing is like linking an external style sheet.
You can import another style sheet from an embedded style sheet, from a linked style sheet, or from a user style sheet. An imported style sheet can even import additional style sheets.
How do imported style sheets affect the cascade order? You might think that rules are included at the point where the importation is declared, but this actually isn't the case. Any imported style sheets are treated as if their rules had been declared before any of the rules in the importing style sheet.
You can think of the imported style sheet as being more distant, which means it is lower priority if there is a conflict. All other things being equal (same number of id attributes, classes, and elements), the importing style sheet's rules are considered more recently declared, even if the rule happens before the importation.
<div>By the Way
If you're designing a large website, and some CSS rules apply to the whole site, whereas others should be used only with certain sections of the site, you may want to write one site-wide style sheet and then import it into the style sheets you write for each part of the site.</div>
The <code>@import</code> Rule
To import a file, you write as a complete rule (with no property declarations or curly braces) an <code>@import</code> statement that looks like this:
<div><pre>@import url("filename.css");
</pre></div>
An alternate way to write the same rule is to leave out the <code>url()</code> function because everything you will <code>@import</code> will be a URL. So you can also write the rule like this:
<div><pre>@import "filename.css";
</pre></div>
You can also give <code>@import</code> an extra parameter, which is a list of media types. Like the media attribute on the <code><link></code> attribute, the style sheet loads only if the media type is correct for the browser being used. For example:
<div><pre>@import "screenorprint.css" screen, print;
@import "allmedia.css" all;
</pre></div>
Here's an example of <code>@import</code> in action. First, the importing style sheet:
<div><pre>h1 { color: red; }
h1, h2, h3, h4, h5, h6
{ font-family: sans-serif; }
@import "sitewide.css";
h2 { color: blue; }
</pre></div>
And here's the imported style sheet:
<div><pre>/* sitewide.css */
h1, h2, h3, h4, h5, h6
{ color: green; }
body { background-color: silver; }
</pre></div>
What color is an <code><h1></code>, <code><h2></code>, or <code><h3></code> on a page using the importing style sheet? The <code><h1></code> would be red and the <code><h2></code> would be blue because all the imported rules are considered to come before the original style sheet's rules. The <code><h3></code> would be green because that's the only rule setting its color.
<div>Did you Know?
The old, nearly extinct Netscape 4 browser didn't understand the <code>@import</code> rule; it simply wouldn't import other style sheets. This flaw actually got put to good use by web developers, to hide other rules that Netscape 4 couldn't understand. (It was a browser with lots of CSS problems.) All rules that were "Netscape 4 safe" could be put in the main CSS file, and then an additional style sheet could be <code>@imported</code> that contained style rules that would break in Netscape 4 but worked in other then-contemporary browsers.
This was the first browser filter ever developed. You'll learn more about filtering and other tricks in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."</div>
./ ADD NAME=CH07LEV1SEC4.HTML
== Inheritance ==
As you've already seen, some property values don't have to be explicitly set on each element if the value is already set on a parent element. For example, if you set a <code>font-family</code> property on the <code><body></code>, all other elements on the page will also have the same value unless it's changed by another rule. This is called inheritance; the page elements have inherited the property value from their parent element, <code><body></code>.
Not all properties inherit naturally; some simply don't make sense for inheritance. For example, the <code>border, margin</code>, and <code>padding</code> properties from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6], "The CSS Box Model," don't inherit. Otherwise, whenever you'd draw a box, all elements inside it would have the same type of box around them. Each property, when it's defined in the CSS specifications, is designated as either inheriting or not inheriting, by default.
Inherited Values
An inherited value is passed along in most cases as if it had been set on the element itself. Thus, if you make an <code><h1></code> blue, you're making all its children blue because they'll inherit the color. Other rulesmore specific or higher prioritycould change this, of course.
Of the properties you've learned so far, <code>font-family</code> and <code>color</code> are inherited. The <code>display, border, margin</code>, and <code>padding</code> properties are not inherited. You might think that <code>background-color</code> is inherited, but actually it's not; the default when <code>background-color</code> is unset is actually the special value <code>TRansparent</code>, which means the color "underneath" can be seen, so it's not quite the same as inheriting the value.
Calculated Values
The <code>font-size</code> property works a little differently when it comes to inheritance. That's because you don't actually inherit the declaration; you inherit the calculated value. Some values are absolute values, such as <code>12px</code>, but most will be relative values, such as <code>smaller</code> or <code>3em</code>. When a relative value is inherited, the value is first calculated before being passed on to child element.
Specifying Inheritance
If you want a property to inherit from its parent, but it doesn't actually do so by default, you can use the special value of <code>inherit</code> in a rule you write. Say that you decide any <code><div></code> in the class <code>standout</code> should have a blue border and that any paragraphs inside it should have the same border. You could write these rules:
<div><pre>div.standout { border: 1px solid blue; }
div.standout p { border: inherit; }
</pre></div>
./ ADD NAME=CH07LEV1SEC5.HTML
== Summary ==
In this hour, you learned about the cascade, user style sheets, importing style sheets, and inheritance.
The cascade first sorts rules based on source: Author style rules take priority over user style rules, which take priority over browser default styles. After that, the more specific a rule, the higher priority it's given. You can add <code>!important</code> to a rule to give it a higher priority.
User style sheets are a crucial part of the cascade that allows the user's preferences to blend with the author's desires. Users with disabilities can often benefit from specific style sheets tailored to their needs.
Not all values need to be explicitly set; values can be inherited from their parent element. Some properties inherit, and some don't; those that use relative values pass along the calculated value.
./ ADD NAME=CH07LEV1SEC6.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa1q1a1 Q.]'''
| Why is it a big deal that calculated values are inherited, instead of relative values?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa1q1 A.]'''
| Well, consider this example:
<div><pre><div class="footer"><br /><p><br />Questions? Send me email at<br /><a href="mailto:kynn@idyllmtn.com"><br />kynn@idyllmtn.com<br /></a><br /></p><br /></div><br /></pre></div><br />
If the font on the page is 20 pixels, and the style rule is <code>div.footer { font-size: smaller; }</code>, text elements within the <code><div></code> inherit the calculated value 16 pixels, which is 20% smaller than 20 pixels. The elements within the <code><div></code> do not inherit the relative value <code>smaller</code>.
What if the text elements did inherit the relative value? Well, then the <code><p></code> would have to be 20% smaller than the size of the <code><div></code> (about 12.8 pixels). The <code><a></code> would inherit smaller from its parent and would shrink to 80% of the <code><p></code>, so the email address would be 10.24 pixelsincredible shrinking text! This is why calculated values are not inherited.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa1q2a2 Q.]'''
| How did the order of the Cascade change between CSS Level One and CSS Level Two?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa1q2 A.]'''
| When CSS Level One was published, the author's <code>!important</code> styles took precedence over the user's <code>!important</code> styles. This was found to be a problem because it meant that users with special needs had no way to insist that the browser meet their needs. In the CSS Level Two recommendation, this was changed so that the user's <code>!important</code> rules beat the author's <code>!important</code> rules. Note that this is a special case exception; in most cases, the author's styles override the user's styles, assuming the user's styles are not flagged as <code>!important</code>.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa2q1a1 1.]'''
| Rank these CSS rules in order from least specific to most specific:
<div># <div><code>p { font-family: serif; }</code></div>
# <div><code><p style="font-family: fantasy;"></code></div>
# <div><code>p#mocha { font-family: monospace; }</code></div>
# <div><code>TR td p { font-family: sans-serif; }</code></div>
# <div><code>TD p.latte { font-family: cursive; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa2q2a2 2.]'''
| How would your answer to question 1 change if rule (a) were rewritten like this?
<div># <div><code>p { font-family: serif !important ; }</code></div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa2q1 1.]'''
| The least specific is (a): It has no id selectors, no classes, and only one element. Rule (d) is more specific because it has three elements instead of one. Rule (e) is more specific than (d), even though it has only two elements, because (e) has one class and (d) has none. Rule (c) is less specific than Rule (b) because <code>id</code> selectors are less specific than inline styles. Therefore, a paragraph that was affected by all these rules would be in a <code>fantasy</code> font.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch07qa2q2 2.]'''
| The addition of <code>!important</code> to rule (a) makes it more important than the others, and thus the <code>font-family</code> value would be <code>serif</code>. However, the specificity technically did not change; it is still less specific than the others, although it has higher priority. So it's a bit of a trick question; the priority would change, but because question 1 asked you about specificity, not priority, your answer should not change.
|}
Exercise
One of the best ways to become familiar with the cascade is to set up your own user style sheet. Create your own style sheet, save it on your hard drive, and tell your browser to use it as a user style sheet. You can experiment with <code>!important</code> and other aspects of the cascade by changing your user style sheet.
./ ADD NAME=CH08.HTML
evj34n2rbq90uv77tcyn8m9ehodzq9m
User:Bartlett/08
2
2111
39218
5497
2026-04-13T06:03:17Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39218
wikitext
text/x-wiki
= Hour 8. Advanced Selectors =
; What You'll Learn in This Hour:
* How to create CSS rules that select only those tags that have a specific attribute
* How to create rules based on the values of those attributes
* How to create rules that select direct children of another element and why you'd want to do that
* How to select an element that directly follows another element
|}
./ ADD NAME=CH08LEV1SEC1.HTML
== Attribute Selectors ==
An attribute selector tests for the existence, and possibly the values, of any specific HTML attributes set on an element. You'd use an attribute selector if you wanted all elements with a certain attribute to be styled a certain way. For example, <code>noshade</code> is an HTML attribute for the <code><hr></code> tag; it means that there shouldn't be any shading effects applied to the tag. If you wanted all those <code><hr></code> tags to be colored <code>silver</code>, you'd use an attribute selector based on the <code>noshade</code> attribute. The simplest form of attribute selector is simply the attribute within square brackets, as follows:
<div><pre>element[attribute] { declaration; }
</pre></div>
For example:
<div><pre>hr[noshade] { color: silver; }
</pre></div>
This rule would declare that all <code><hr></code> elements with the <code>noshade</code> attribute should be colored <code>silver</code>.
You can write an attribute selector rule so that it selects all elements with the chosen attribute by using the universal selector (<code>*</code>). For example, you could set a specific rule for all tags that have a <code>title</code> attribute to indicate which parts of the page will pop up a tooltip when you move the mouse over them, as in the following:
<div><pre>*[title] { background-color: yellow; }
</pre></div>
This marks with a <code>yellow</code> background all tags with <code>title</code> attributes. Because the universal selector is optional, you can also write the rule like this:
<div><pre>[title] { background-color: yellow; }
</pre></div>
<div>Watch Out!
Internet Explorer (up to version 5.5) does not support attribute selectors. For compatibility with older Internet Explorer versions, you can use an explicit <code>class</code> attribute and <code>class</code> selector rule. For example, to make the two attribute selector examples work in Internet Explorer 5.5, you'll need to write your HTML like this:
<div><pre><hr class="unshaded" noshade>
<a href="summer2001.html" class="hastooltip" title="What I Did for Summer Vacation">Summer 2001</a>
</pre></div>
Your CSS rules would then look like this:
<div><pre>hr[noshade], hr.unshaded { color: silver; }
*[title], .hastooltip { background-color: yellow; }
</pre></div></div>
Selecting by Attribute Value
In addition to checking for the existence of the attribute, you can also select by attribute value. There are three ways to do this:
<div><pre>element[attribute="value"] { declaration; }
element[attribute~="value"] { declaration; }
element[attribute|="value"] { declaration; }
</pre></div>
The first version designates an exact match; it selects only those elements for which the attribute has the given value. The second registers a match if the value in the rule is one of several values given in the HTML, separated by spaces. The third matches the rule's value against the HTML's value and compares the characters before hyphens. (This is to allow matching of language groups, which are written as <code>en-us, en-uk, en-au</code>, and so on. See [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors," for a listing of some common language codes.) [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08table01 Table 8.1] shows several types of selectors and attribute values and indicates whether or not each selector would match the HTML.
{| cellspacing="0" cellpadding="5"|+ Table 8.1. Testing Attribute Values
|-
| CSS Selector
| HTML Snippet
| Match?
|-
| <code>table[summary="layout"]</code>
| <code><table summary="layout"></code>
| Yes
|-
| <code>table[summary~="layout"]</code>
| <code><table summary="layout"></code>
| Yes
|-
| <code>table[summary|="layout"]</code>
| <code><table summary="layout"></code>
| Yes
|-
| <code>div[class="bar"]</code>
| <code><div class="foo bar baz"></code>
| No
|-
| <code>div[class~="bar"]</code>
| <code><div class="foo bar baz"></code>
| Yes
|-
| <code>div[class|="bar"]</code>
| <code><div class="foo bar baz"></code>
| No
|-
| <code>*[lang="en"]</code>
| <code><span lang="en"></code>
| Yes
|-
| <code>*[lang~="en"]</code>
| <code><span lang="en"></code>
| Yes
|-
| <code>*[lang|="en"]</code>
| <code><span lang="en"></code>
| Yes
|-
| <code>*[lang="en"]</code>
| <code><span lang="en-us"></code>
| No
|-
| <code>*[lang~="en"]</code>
| <code><span lang="en-us"></code>
| No
|-
| <code>*[lang|="en"]</code>
| <code><span lang="en-us"></code>
| Yes
|-
| <code>*[lang="en"]</code>
| <code><span lang="english"></code>
| No
|-
| <code>*[lang~="en"]</code>
| <code><span lang="english"></code>
| No
|-
| <code>*[lang|="en"]</code>
| <code><span lang="english"></code>
| No
|}
Let's look at an example of attribute selectors in action. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08ex01 Listing 8.1] is an HTML page consisting of a table of departure times for airline flights. I've chosen to use the <code>axis</code> attribute on table cells to group similar types of flights. <code>axis</code> is an HTML 4.01 attribute that allows for groupings of related table cells. Those flights that fly through Saint Louis have been assigned an <code>axis</code> value of <code>stlouis</code>, whereas those going through Chicago are labeled with an <code>axis</code> value of <code>ord</code>.
Listing 8.1. HTML Table Marked Up with the <code>axis</code> Attribute
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- flights-8.1.html --><br /><html><br /><head><br /><title>Flights from Los Angeles to New York</title><br /><link type="text/css" rel="stylesheet"<br />href="flights-8.2.css"><br /></head><br /><body><br /><h1>Schedule of Flights</h1><br /><h2>Los Angeles to New York</h2><br /><table><br /><tr> <th>Monday</th> <th>Tuesday</th> <th>Wednesday</th><br /><th>Thursday</th> <th>Friday</th> </tr><br /><tr> <td axis="ord">09:13 (ORD)</td><br /><td axis="ord">09:13 (ORD)</td><br /><td>10:17 (direct)</td><br /><td axis="ord">09:13 (ORD)</td><br /><td>10:17 (direct)</td> </tr><br /><tr> <td axis="stlouis">12:05 (STL)</td><br /><td axis="stlouis">12:05 (STL)</td><br /><td axis="stlouis">12:05 (STL)</td><br /><td axis="stlouis">12:05 (STL)</td><br /><td axis="stlouis">12:05 (STL)</td> </tr><br /><tr> <td axis="ord">17:15 (ORD)</td><br /><td axis="stlouis">13:44 (STL)</td><br /><td axis="ord">17:15 (ORD)</td><br /><td axis="stlouis">13:44 (STL)</td><br /><td>14:30 (direct)</td> </tr><br /><tr> <td></td><br /><td axis="ord">17:15 (ORD)</td><br /><td>19:20 (direct)</td><br /><td axis="ord">17:15 (ORD)</td><br /><td axis="ord">17:15 (ORD)</td> </tr><br /></table><br /></body><br /></html><br /></pre></div><br />
|}
The cascading style sheet for this example is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08ex02 Listing 8.2]; you'll use attribute selectors to set up rules on each flight type to show them with different background colors. This effect is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08fig01 Figure 8.1].
<div style="text-align: center;"> Figure 8.1. Using attribute selectors to make <code>axis</code> values visual. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/08fig01_alt.jpg [View full size image]]</div>[[Image:08fig01.jpg|500px]] </div>
Listing 8.2. This Style Sheet Uses Rules Based on the <code>axis</code> Attribute Selector
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* flights-8.2.css */<br /><br />body { font-family: Verdana, sans-serif; }<br /><br />td { border: 1px solid black;<br />padding: 0.25em;<br />color: black;<br />background-color: white; }<br /><br />td[axis="stlouis"]<br />{ background-color: silver;<br />color: black; }<br /><br />td[axis="ord"]<br />{ background-color: black;<br />color: white; }<br /></pre></div><br />
|}
You've been using shorthand versions of some attribute selectors for some time now; the <code>class</code> and <code>id</code> selectors are just special cases of an attribute value selector. The following pairs of rules are equivalent:
<div><pre>.apple { color: green; }
*[class~="apple"] { color: green; }
#banana { color: yellow; }
*[id="banana"] { color: yellow; }
</pre></div>
You can combine multiple attribute values together by simply adding on another attribute test. Here's an example of a rule that selects all table cells that are right-aligned and vertically aligned to the bottom:
<div><pre>td[align="right"][valign="bottom"]
{ font-size: small; }
</pre></div>
<div>Did you Know?
You can use attribute selector rules with a user style sheet to create some very simple but powerful testing tools for web development. For example, to make anchors visible, create a style sheet, set it as your user style sheet in your browser, and add the following rule:
<div><pre>a[name], [[Image:135fig01.jpg|8px]] { border: 1px dotted red; }
</pre></div>
This puts a dotted line around your anchors and anything else with the <code>id</code> attribute set. You can use this same trick to make table borders, form boundaries, field <code><label></code>s, and other block elements visible because they're outlined with a <code>border</code>. Here's a pair of rules to make it very clear which of your images don't have <code>alt</code> attributes on them:
<div><pre>img { border: 5px solid lime; }
img[alt] { border: none; }
</pre></div></div>
Family Relationships
Family-based selectors in CSS choose elements based on the relationships between the HTML tags; these relationships are named after family relationships. You've already used one of the family relationship selectors: the descendant selector, which selects elements descended from another tag. Other relationship selectors include child and adjacent sibling selectors.
Child Selectors
A child selector is a special case of descendant selectors, which were covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5]. A child selector identifies only those elements that are immediate children of another element, not any "grandchildren" or other descendants. A child selector is indicated by a greater-than symbol (>) between the parent element and the child:
<div><pre>parent > child { declaration; }
</pre></div>
For example, consider the following snippet of HTML:
<div><pre><blockquote>
<div class="opinion">
<p>I'm voting Green next year.</p>
<p>I'm wearing green, too!</p>
</div>
</blockquote>
</pre></div>
Here are some style rules, but only a few of these will be applied to the code sample:
<div><pre>blockquote p { font-size: large; }
blockquote > p { font-family: Arial, sans-serif; }
.opinion > p { font-color: green; }
</pre></div>
The first rule is used on the quote; it's a normal descendant selector, and both of the paragraphs are within a <code><blockquote></code>. The second rule is not applied; there are no <code><p></code> tags that are direct children of a <code><blockquote></code> tag; both of them are direct children of the <code><div></code>. (They're descendants of the <code><blockquote></code>, of course, but only direct children, not grandchildren, count for child selectors.) The third rule is applied to the <code><p></code> text because both paragraphs are direct children of a tag with <code>class="opinion"</code>. So the total effect will be two green paragraphs, both in the default font face.
<div>Watch Out!
Some older browsers, notably Internet Explorer 6 and earlier, don't recognize child selectors. For compatibility with these older browsers, use descendant selectors; if you're unable to get the effects you want with just descendants, use class selectors too. Here's how you would rewrite the green quote style sheet rules:
<div><pre>blockquote p { font-size: large; /* same */ }
blockquote p.childofblockquote
{ font-family: Arial, sans-serif; }
.opinion p { font-color: green; }
</pre></div>
You'll notice the additional class called <code>childofblockquote;</code> it has to be added to every <code><p></code> that is a direct child of a <code><blockquote></code>.</div>
<div>Did you Know?
Internet Explorer's lack of support for child selectors has a silver lining. Because rules with child selectors are ignored, you're able to write styles that are understood by most other modern browsers but aren't displayed by Internet Explorer. This is an example of a browser filter; you'll learn more about those in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."</div>
Adjacent Sibling Selectors
Two HTML tags are siblings if they have the same parent; they are adjacent siblings if the second occurs directly after the first in the source code. Here's some HTML to illustrate a sibling relationship:
<div><pre><ul>
<li id="greg">Greg</li>
<li id="peter">Peter</li>
<li id="bobby">Bobby</li>
<!-- id attributes are included for reference -->
</ul>
</pre></div>
The <code><li></code> elements are all siblings of each other. The <code>greg</code> and <code>peter <li></code> tags are adjacent siblings, and the <code>peter</code> and <code>bobby <li></code> tags are adjacent as well. However, the <code>greg</code> and <code>bobby</code> tags are not adjacent.
An adjacent sibling selector makes a selection based on two adjacent siblings, but it applies the declared style only to the second of the two. This is very important to remember: You are not selecting the pair; you are selecting only the final one in the list.
You write an adjacent sibling rule by listing the first sibling, a plus sign (+), and then the second sibling. A rule such as the following turns only the Peter and Bobby names blue, because they're <code>li</code> elements that directly follow another <code>li</code> element:
<div><pre>li + li { color: blue; }
</pre></div>
<div>Watch Out!
Like many other advanced selectors in CSS, the usefulness of adjacent sibling selectors has been crippled by a lack of browser support in Internet Explorer. Using the same techniques described previously in this hour, you can add a number of class attributes and selectors and approximate the behavior for those older browsers that don't support CSS Level 2 selectors. This isn't the best solution, but it's the only one that works now.</div>
Adjacent sibling selectors are useful for adding or removing margins, padding, and borders when siblings are meant to flow together visually. An example of this is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08ex03 Listing 8.3].
Listing 8.3. A Definition List with Adjacent <code><dt></code> and <code><dd></code> Elements
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- acronyms-8.3.html --><br /><html><br /><head><br /><title> Some Common Acronyms </title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br /><br />dt { font-weight: bold; }<br /><br />dt + dt, dd + dt<br />{ margin-top: 1em;<br />font-weight: bold;<br />padding-top: 1em;<br />border-top: 1px solid black; }<br />/* These rules apply to any dt that follows<br />another dt, or a dd. The only dt that<br />would not match such a rule is the first<br />one, which is a direct child of the dl. */<br /><br />dt + dd { margin-top: 0.5em; }<br />/* This applies to any dd that immediately follows<br />a dt. It doesn't apply to a dd that follows<br />another dd. */<br /><br />dd + dd { font-size: small;<br />border: 1px;<br />padding: 0.1em; }<br /><br />/* This rule selects any dd that follows another<br />dd, but not to a dd that follows a dt. */<br /><br /></style><br /></head><br /><body><br /><h1>Common Acronyms</h1><br /><br /><dl><br /><dt>CSS</dt><br /><dd>Cascading Style Sheets</dd><br /><br /><dt>HTML</dt><br /><dd>Hypertext Markup Language</dd><br /><dd>See also: <cite>XHTML</cite></dd><br /><br /><dt>WAI</dt><br /><dd>Web Accessibility Initiative</dd><br /><dd>See also: <cite>W3C</cite></dd><br /><br /><dt>WCAG</dt><br /><dd>Web Content Accessibility Guidelines</dd><br /><br /><dt>WWW</dt><br /><dd>World Wide Web</dd><br /><br /><dt>WWWC -- see <cite>W3C</cite></dt><br /><br /><dt>W3C</dt><br /><dd>World Wide Wide Consortium</dd><br /><dd>See also: <cite>WAI</cite></dd><br /><br /><dt>XHTML</dt><br /><dd>Extensible HTML</dd><br /><dd>See also: <cite>HTML</cite></dd><br /></dl><br /></body><br /></html><br /></pre></div><br />
|}
The embedded style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08ex03 Listing 8.3] uses styles based on adjacent-sibling rules applied to a definition list. In HTML, a definition list is declared by the <code><dl></code> element, which can only have <code><dt></code> (term) or <code><dd></code> (definition) elements as children; this is important for understanding why the adjacent-sibling rules work as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08fig02 Figure 8.2].
<div style="text-align: center;"> Figure 8.2. Adjacent sibling rules improve the look of a definition list. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/08fig02_alt.jpg [View full size image]]</div>[[Image:08fig02.jpg|500px]] </div>
./ ADD NAME=CH08LEV1SEC2.HTML
== Summary ==
Although unsupported by all but the newest browsers, advanced selectors add considerably to the CSS developer's toolbox. Attribute selectors allow styles to be set based on specific attribute values or even the existence of an attribute on the tag. Relationships between elements can be expressed in CSS by the child selector, which applies to direct children of a specific element, and by the adjacent sibling selector, which chooses the second of a pair of specified tags.
./ ADD NAME=CH08LEV1SEC3.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q1a1 Q.]'''
| Can I do pattern matching in attribute values? Suppose I want to select all <code><a></code> tags that are <code>mailto</code> links. Can I use <code>a[href="mailto:*"]</code> as my selector?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q1 A.]'''
| Nope. The CSS specifications don't define a way to do this type of pattern matching. Future versions of CSS based on XPath and XPointer might allow this, but for now there is no way to use pattern matching in CSS. To make your <code>mailto</code> links stand out, set a <code>class</code> attribute on them and use a <code>class</code> selector.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q2a2 Q.]'''
| If I could use either a child selector or a descendant selector, which should I use? For example, if I want to select all <code><img></code> tags within <code><a></code> links.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q2 A.]'''
| In theory, it's better to use a child selector if you know you're dealing with a direct child because it's quicker for the browser to calculate child selectors. It doesn't have to look over the full tree of the HTML document, just up one level. In practice, though, you are better off sticking with the descendant selector because of poor browser support; don't rely on a child selector alone. You can use both, if you like.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q3a3 Q.]'''
| Can I combine advanced selectors with simple selectors or other advanced selectors?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa1q3 A.]'''
| Certainly! This is a valid CSS rule:
<div><pre>.chap > th + td img[alt] { border: 2px solid green; }<br /></pre></div><br />
What would match this? Basically, anything that meets the following criteria:
* An image element
* With an <code>alt</code> attribute set (to any value)
* Where that image is a descendant of a table cell
* Assuming that table cell has a table header cell as a sibling
* Which is a direct child of an element in the <code>chap</code> class
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q1a1 1.]'''
| What does the <code>+</code> symbol indicate, in a selector?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q2a2 2.]'''
| Which selector will select the HTML element <code><h1 align="right">Welcome</h1></code>, and why?
<div># <div><code>h1[align~="right"]</code></div>
# <div><code>*[align="right"]</code></div>
# <div><code>[align|="right"]</code></div>
# <div><code>H1[align]</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q3a3 3.]'''
| You're using Opera 8.5 and you want to write a rule in your user style sheet to hide banners that are 468 pixels across and 60 pixels high. How do you write that rule?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q1 1.]'''
| The <code>+</code> symbol designates a direct sibling selector.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q2 2.]'''
| It's kind of a trick question. All of them will select the <code><h1></code>. The first will select it because <code>right</code> is one of the values listed in the attribute (it's the only value, too). The second will select it because it's exactly the value (and the selector's type is universal). The third is also a universal selector, and it will compare values before a dash; because there is no dash, it will compare just <code>right</code> with <code>right</code>. The last matches because the <code><h1></code> tag has an <code>align</code> attribute, with any value.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch08qa2q3 3.]'''
| Here's one way to zap away those annoying banners:
<div><pre>img[height="60"][width="468"] { display: none; }<br /></pre></div><br />
|}
Exercise
You'll master selectors gradually, as you work on other projects using CSS and write style sheets using these types of rules. To practice as you learn, make a "cheat sheet" to remind yourself which advanced selectors you can use, and keep that list handy as you read this book and create style sheets. Identify specific situations in which a complex rule might actually work better than simply adding <code>class</code> and <code>id</code> in HTML, which is an easy habit to fall into.
./ ADD NAME=CH09.HTML
6r3gcc184pneegxgty3lauj3knsjgxh
User:Bartlett/09
2
2112
39219
5498
2026-04-13T06:03:17Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39219
wikitext
text/x-wiki
= Hour 9. Fonts and Font Families =
; What You'll Learn in This Hour:
* Which font properties specify bold, italic, and variant fonts
* How you can set a number of font properties at once using a shorthand property
* What the generic font families are and how to use them
* Which fonts are most commonly installed on browsers
One of the most effective changes you can make to a web page when using CSS is to simply alter the browser's default font. This can add a more professional look to your website immediately, as well as make it easier for users to read and find information.
|}
./ ADD NAME=CH09LEV1SEC1.HTML
== Specifying Font Properties ==
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," you were introduced to two font properties: <code>font-size</code> and <code>font-family</code>. These enable you to specify the size and typeface of the font, respectively. In addition, a number of other properties can be used to further select fonts from within those families. These properties are <code>font-weight, font-variant, font-style, font-stretch</code>, and <code>font-size-adjust</code>.
To understand how these properties work, it's important to understand how CSS views fonts. A font in CSS is one specific instance of several properties: a specific typeface, size, weight, and other variables. So the <code>font 12pt Arial bold italic</code> is different from the <code>font 10pt Arial</code>. They are part of the same font family, of course. It's helpful to remember that when you declare a font family, you're actually selecting a group of fonts to be used. Other properties (or browser defaults) narrow down the specific font.
Font families generally include a number of variations on the base fontfor example, an italic version of the font. In some cases, you will specify a font combination that simply isn't available as a distinct variant. The browser then has to create a variant on the fly by slanting the text to produce italic effects, for example, or by using the closest available equivalent in the font family.
The effects produced by various font settings are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09table01 Table 9.1] for reference; this is because it's not always clear which property controls which effect.
{| cellspacing="0" cellpadding="5"|+ Table 9.1. Properties Affecting Font Display
|-
| Property
| Effect
|-
| <code>font-family</code>
| Selects the typeface family
|-
| <code>font-size</code>
| Sets the size of the font
|-
| <code>font-weight</code>
| Makes text bold or lighter
|-
| <code>font-variant</code>
| Creates "small caps" effect
|-
| <code>font-style</code>
| Sets italic font
|-
| <code>text-decoration</code> ([file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10])
| Underlines text
|-
| <code>color</code> ([file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10])
| Changes the color of text
|-
| <code>line-height</code> ([file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15])
| The height of the line (but not the text height)
|-
| <code>font</code>
| Sets <code>font-family, font-size, font-weight, font-variant, font-style</code>, and <code>line-height</code>
|}
The <code>font-weight</code> Property
The <code>font-weight</code> property controls how heavy a font appearsin other words, the thickness of the lines used to draw that font, relative to the size of the font. The weight of a font is measured in numbers that range from <code>100</code> to <code>900</code>, in steps of <code>100</code>. The higher the number, the bolder the font; normal text has a weight of <code>400</code> and bold text (as created by the HTML <code><b></code> tag) has a weight of <code>700</code>.
Not all font families have specific fonts at all values; in such a situation, the browser usually uses the closest match. For example, if there's no weight <code>800</code> variant for a font, the browser may substitute weight <code>700</code>.
Many browsers support only two to four <code>font-weight</code> values. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig01 Figure 9.1] shows how Safari displays each <code>font-weight</code> value of Verdana, whereas [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig02 Figure 9.2] is from Firefox. Notice that they differ on whether weight <code>600</code> should be weighted like <code>500, 700</code>, or somewhere in between. Keep this in mind; it will be important later on.
<div style="text-align: center;"> Figure 9.1. Successive <code>font-weight</code> values of Verdana font, shown in Safari. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig01_alt.jpg [View full size image]]</div>[[Image:09fig01.jpg|500px]] </div>
<div style="text-align: center;"> Figure 9.2. Successive <code>font-weight</code> values of Verdana font, shown in Firefox. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig02_alt.jpg [View full size image]]</div>[[Image:09fig02.jpg|500px]] </div>
In addition to numeric values, the <code>font-weight</code> property can take named values, as shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09table02 Table 9.2]. The <code>font-weight</code> value is inherited from the containing box if any is set. The default value is <code>normal (400)</code> for most HTML tags; some, such as <code><b></code>, <code><strong></code>, <code><h1></code> to <code><h6></code>, and <code><th></code>, default to <code>bold (700)</code>.
{| cellspacing="0" cellpadding="5"|+ Table 9.2. Values for the font-weight Property
|-
| Value
| Effect
|-
| <code>100</code> to <code>900</code>
| Lightest (<code>100</code>) to heaviest (<code>900</code>) font weight
|-
| <code>bold</code>
| Same as <code>700</code>
|-
| <code>bolder</code>
| One step (<code>+100</code>) heavier than the containing box's <code>font-weight</code>
|-
| <code>lighter</code>
| One step (<code>-100</code>) lighter than the containing box's <code>font-weight</code>
|-
| <code>normal</code>
| Same as <code>400</code>
|-
| <code>inherit</code>
| The value of the containing box's <code>font-weight</code> property
|}
If a font's weight is already at <code>900</code>, the value <code>bolder</code> won't make it any heavier; likewise, if the <code>font-weight</code> is <code>100</code>, <code>lighter</code> has no additional effect.
<div>Watch Out!
Comparing [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig01 Figure 9.1] and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig02 Figure 9.2], it's clear that browsers aren't consistent about how heavy they make in-between values such as <code>500</code> or <code>600</code>. Because <code>bolder</code> and <code>lighter</code> move up or down in steps of <code>100</code>, it's possible that a <code>bolder</code> (or <code>lighter</code>) rule may have no effect. If the default is <code>400</code>, and the browser does not render <code>500</code> as <code>700</code> but as <code>400</code>, an increase of <code>100</code> is meaningless. For this reason it's better to use either explicit numeric values (<code>400</code> or <code>700</code>) or the keyword <code>bold</code> for cross-browser consistency.</div>
The <code>font-variant</code> Property
Only one type of variant font can be set with the <code>font-variant</code> property, a variant where lowercase letters are represented with smaller versions of capital letters. The three possible values for <code>font-variant</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09table03 Table 9.3]; the default value is <code>normal</code>, and if there is a value set on the containing box, it will be inherited.
{| cellspacing="0" cellpadding="5"|+ Table 9.3. Values for the <code>font-variant</code> Property
|-
| Value
| Effect
|-
| <code>normal</code>
| Use normal lowercase letters
|-
| <code>small-caps</code>
| Use small capitals instead of lowercase letters
|-
| <code>inherit</code>
| Use the value of the containing box's <code>font-variant</code> property
|}
An example of <code>font-variant</code> is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig03 Figure 9.3]; the rule used is
<div style="text-align: center;"> Figure 9.3. Using <code>font-variant: small-caps</code>.
[[Image:09fig03.jpg|250px]]
</div>
<div><pre>#a { font-family: Optima, sans-serif;
font-variant: small-caps; }
</pre></div>
The <code>font-style</code> Property
To set something in an italic or oblique font, you can use the <code>font-style</code> property; <code>font-style</code> is not used for anything else, although the name seems deceptively general. The values for <code>font-style</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09table04 Table 9.4]. If a <code>font-style</code> property is set on the containing box, it is inherited. Otherwise, the default is usually <code>normal</code>, although some HTML properties, such as <code><i></code>, <code><em></code>, and <code><address></code>, are normally italicized by web browsers.
{| cellspacing="0" cellpadding="5"|+ Table 9.4. Values for the <code>font-style</code> Property
|-
| Value
| Effect
|-
| <code>italic</code>
| Use an italic font.
|-
| <code>normal</code>
| Use a non-oblique, non-italic font.
|-
| <code>oblique</code>
| Use an oblique or slanted font.
|-
| <code>inherit</code>
| Use the value of the containing box's <code>font-style</code> property.
|}
<div>Did you Know?
What is <code>oblique?</code> Although it's a less common term than <code>italic</code>, it's a related concept.
Most fonts we see are called Roman fonts; these are not slanted, and they correspond to the CSS value of <code>normal</code>. An italic font is created by making slanted, slightly curly alternate versions of the letters in a Roman font; each letter has been redesigned so that it's essentially a new set of characters within the same font family.
An oblique font, on the other hand, is created by just tilting the Roman font's characters at an angle. This doesn't always require font redesign and can be done automatically by a computer, but often the results are not nearly as nice looking. Many typography books explicitly discourage the use of computer-created obliques.</div>
Browsers treat <code>italic</code> and oblique property values the same because they don't really know the difference most of the time. The CSS specification allows for italic fonts to be displayed as oblique (even oblique fonts generated automatically) if a matching italic font is not available. You'll probably want to simply use italic; don't worry about the difference unless you are a professional typographer, in which case you don't need me to explain the difference between oblique and italic.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig04 Figure 9.4] shows the lack of difference between <code>oblique</code> and <code>italic</code> by current browsers; they're both rendered the same, in slanted text. This is unfortunate for typographers, but for most of us it won't be a major problem. The code used in this screenshot is
<div style="text-align: center;"> Figure 9.4. Oblique versus italic. In practice, there's no difference.
[[Image:09fig04.jpg|250px]]
</div>
<div><pre><div style="font-style: normal;">
This is normal text.
</div>
<div style="font-style: italic;">
This text is italic.
</div>
<div style="font-style: oblique;">
This text is oblique.
</div>
</pre></div>
The <code>font</code> Shorthand Property
As you've probably noticed this hour, quite a few properties define a font. Rather than typing out each property, the <code>font</code> property enables you to set these values at one time.
The <code>font</code> property is a shorthand property in CSS terminology. A shorthand value has two effects: It sets all affected properties to their default values, and it assigns designated values to the appropriate properties. The <code>font</code> property is shorthand for the <code>font-family</code>, <code>font-size</code>, <code>font-weight</code>, <code>font-variant</code>, <code>font-style</code>, and <code>line-height</code> properties. (You'll learn about <code>line-height</code> and how to use it with font in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment.") The font property doesn't let you set values for <code>font-stretch</code> or <code>font-size-adjust</code>; these need to be set in separate rules.
<div>Watch Out!
Don't overlook that first function, resetting to default values! You can easily spend hours trying to debug your style sheet if you don't remember that shorthand properties set all values, even those not shown. In addition to anything else a <code>font</code> rule does, it also is roughly equivalent to the following declarations:
<div><pre>font-family: serif; /* or the default browser font */
font-size: medium;
font-weight: normal;
font-variant: normal;
font-style: normal;
line-height: 100%;
</pre></div></div>
A font rule looks like this:
<div><pre>selector { font: style variant weight size family; }
</pre></div>
The values for <code>weight</code>, <code>size</code>, and <code>family</code> must be specified in that exact order, but other than that the values can appear in any order. Any values that aren't listed are set to their default values. Here are some examples of font shorthand rules:
<div><pre>body { font: 12pt normal "Times New Roman"; }
h1 { font: 20pt Arial italic small-caps; }
blockquote { font: bold "Courier New", sans-serif; }
</pre></div>
When using <code>font</code> it's important to keep in mind that the first function of this property is to reset values to their defaults; this means that priority order counts. For example, consider these two pairs of rules:
<div><pre>#a { font-weight: 700;
font: large Verdana, sans-serif; }
#b { font: large Verdana, sans-serif;
font-weight: 700; }
</pre></div>
In the <code>#a</code> rules, the <code>font-weight</code> gets set to <code>700</code> by the <code>font-weight</code> property, but then the <code>font</code> property resets it to the default, so the weight is back to <code>400</code>. The #b rules are in the correct order to make the text bold; first the <code>font</code> rule sets everything to default values, and then the specific rule for <code>font-weight</code> overrides the default.
<div>By the Way
The <code>font</code> property can also take values based on the user's operating system fonts; these are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch23.html#ch23 Hour 23], "User Interface and Generated Content."</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Setting Font Properties
The best way to understand how the font properties and font shorthand work is to try it yourself. Follow these steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create an HTML page with various types of text for styling. Include <code><h1></code> and <code><p></code> elements, plus other types of text such as <code><blockquote></code>.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>For each type of text, write a series of separate CSS rules, using <code>font-family</code>, <code>font-weight</code>, <code>font-style</code>, <code>font-size</code>, and <code>font-variant</code>. For example:<br /><br /><div><pre>h1 { font-family: Verdana, sans-serif;<br />font-weight: normal;<br />font-size: 200%;<br />font-style: italic;<br />font-variant: small-caps; }<br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Give different rules for your headlines and your body text. Set aside quotes with <code><blockquote></code> rules. Choose fonts and font sizes that complement the different types of text. Do your headlines have to be bold?<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Now combine your style rules together into one <code>font</code> rule, being mindful of the default values set by a shorthand property. For example, you could write<br /><br /><div><pre>h1 { font: italic small-caps 200% Verdana, sans-serif; }<br /></pre></div><br /></div>
|}
|}
./ ADD NAME=CH09LEV1SEC2.HTML
== Font Families ==
As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], the <code>font-family</code> property is used to select the family of font faces. A <code>font-family</code> rule can be written like this:
<div><pre>selector { font-family: font1, font2, font3, ...
generic; }
</pre></div>
You can give as many alternate fonts as you want; the browser looks through its own list (from the computer's operating system) and locates the closest match. After it finds one, it displays the text with that font face. For example, consider this rule:
<div><pre>h1 { font-family: "MS Sans Serif", Palatino, Helvetica,
"Bookman Old Style", "Times New Roman", Times,
Garamond, Chicago, Arial, Geneva, Verdana,
cursive; }
</pre></div>
The browser starts looking through the list of fonts, and if it finds a match, it uses that font. So on my Windows computer, it might find <code>"MS Sans Serif"</code> and display the <code><h1></code> in that font; on my Apple iBook, it won't find <code>"MS Sans Serif"</code> and will go on to the next one. If the iBook has <code>Palatino</code> (which it does), that's the font family that will be used.
<div>Watch Out!
Remember to include quotes around font names that are more than one word!</div>
The Generic Font Families
In the long rule you just saw, I included a generic font family name at the end<code>cursive</code>. In case the browser can't find any of the 11 named fonts, it will use the browser's <code>cursive</code> font. The exact value of the <code>cursive</code> font varies a lot from operating system to operating system; also, modern browsers (such as Firefox or Opera) enable the user to set specific fonts tied to the generic families. So on my Firefox browser, cursive might mean <code>"Apple Chancery"</code>, whereas on yours it may be the <code>"Lucida Handwriting"</code> font.
The five generic font families in CSS are <code>serif</code>, <code>sans-serif</code>, <code>cursive</code>, <code>fantasy</code>, and <code>monospace</code>. To show you how different browsers (on two different operating systems) will display the generic font families, I've taken some screen shots. Your browser may display these differently as well; in most browsers you can reconfigure your generic font families depending on which fonts are installed on your system.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09ex01 Listing 9.1] is a simple HTML file with embedded style attribute rules that use the generic font families.
Listing 9.1. Styling with Generic Font Families
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- generic-9.1.html --><br /><html><br /><head><br /><title>Generic Font Families</title><br /></head><br /><body><br /><h1 style="font-family: serif;">Serif Family</h1><br /><h1 style="font-family: sans-serif;">Sans-Serif Family</h1><br /><h1 style="font-family: monospace;">Monospace Family</h1><br /><h1 style="font-family: fantasy;">Fantasy Family</h1><br /><h1 style="font-family: cursive;">Cursive Family</h1><br /></body><br /></html><br /></pre></div><br />
|}
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig05 Figure 9.5], you can see the generic font families from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09ex01 Listing 9.1] as shown in Firefox, running on my iBook Macintosh laptop.
<div style="text-align: center;"> Figure 9.5. Generic font families in Firefox (Mac OS X). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig05_alt.jpg [View full size image]]</div>[[Image:09fig05.jpg|500px]] </div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig06 Figure 9.6] shows you what the generic font families look like in Firefox running on my Windows desktop computer. Notice that the <code>serif</code>, <code>sans-serif</code>, and <code>monospace</code> families are consistent with the iBook's families, but the <code>cursive</code> and <code>fantasy</code> families are very different. In fact, the <code>fantasy</code> font family seems to be unsupported in this particular browser configuration, as it uses a plain looking sans-serif font. Especially for the <code>fantasy</code> and <code>cursive</code> families, the choice of font for generic families depends a lot on which browser and operating system are used, and which fonts are installedeven when the browser versions are identical.
<div style="text-align: center;"> Figure 9.6. Generic font families in Firefox (Windows XP). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig06_alt.jpg [View full size image]]</div>[[Image:09fig06.jpg|500px]] </div>
What about Internet Explorer's generic fonts? [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig07 Figure 9.7] shows how Internet Explorer on Windows handles the fonts. In this example as well, there is no special font for the <code>fantasy</code> family; it may well be that whatever font Internet Explorer is looking for is not installed on the computer in question. You can't rely on having any given font on a user's machine, or even rely on the generic <code>fantasy</code> and <code>cursive</code> families being either fantastic or cursive. They may just be plain fonts, as these examples show.
<div style="text-align: center;"> Figure 9.7. Generic font families in Internet Explorer (Windows XP). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig07_alt.jpg [View full size image]]</div>[[Image:09fig07.jpg|500px]] </div>
As described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3], "Browser Support for CSS," Internet Explorer for Macintosh is an entirely different piece of software than Internet Explorer on Windows. This is evident in the generic font families, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig08 Figure 9.8].
<div style="text-align: center;"> Figure 9.8. Generic font families in Internet Explorer (Mac OS X). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig08_alt.jpg [View full size image]]</div>[[Image:09fig08.jpg|500px]] </div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig09 Figure 9.9] shows the generic font families as displayed by Opera 8.5 on the Macintosh. There are several things to note here: The first is that Opera isn't displaying Arial for the <code>sans-serif</code> family, as you see with the other browsers. The second is that the MS Comic Sans font, used as a <code>cursive</code> font by Internet Explorer and Firefox on Windows, appears here as a <code>fantasy</code> font!
<div style="text-align: center;"> Figure 9.9. Generic font families in Opera 8.5 (Mac OS X). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig09_alt.jpg [View full size image]]</div>[[Image:09fig09.jpg|500px]] </div>
Finally, [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig10 Figure 9.10] shows how Safari displays the font families. In short, it doesn't bother with the cursive and fantasy fonts; instead, they're shown as plain, ordinary sans-serif Arial.
<div style="text-align: center;"> Figure 9.10. Generic font families in Safari (Mac OS X). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig10_alt.jpg [View full size image]]</div>[[Image:09fig10.jpg|500px]] </div>
Generic font families are good for fallback; without them, your font face will be the single default of the browser, usually something like <code>"Times New Roman"</code>. Though as you can see, they're not very consistent. They are still better than the basic default, however, and you will want to include a generic family in each <code>font-family</code> property value (or font shorthand property value).
Serif
In font terminology, serifs are defined as the little feet or curved bits added to the ends of the straight lines that constitute a letter. These help to make the characters easier to distinguish when reading, especially when reading print. A serif font makes it much easier to distinguish among the number 1, the lowercase letter l, and the uppercase letter I, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig11 Figure 9.11].
<div style="text-align: center;"> Figure 9.11. Serif fonts make it easier to distinguish letters. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig11_alt.jpg [View full size image]]</div>[[Image:09fig11.jpg|350px]] </div>
Serif fonts are often used for normal body text in web browsers. The default test font is commonly <code>"Times New Roman"</code>, which is usually the generic <code>serif</code> family font as well. However, serif fonts tend to display poorly on the screen compared with print, especially at smaller font sizes. Many web developers will immediately change the <code>font-family</code> to a sans-serif font as the first rule of their style sheets.
Other examples of serif fonts include <code>"Bookman Old Style"</code>, <code>"Book Antiqua"</code>, <code>"Century Schoolbook"</code>, <code>Garamond</code>, <code>"Goudy Old Style"</code>, <code>Palatino</code>, and <code>Sonoma</code>. The font <code>Times</code> is similar to <code>"Times New Roman"</code>, and it's often useful to specify both of those fonts together, like this:
<div><pre>blockquote { font-family: "Times New Roman",
Times, serif; }
</pre></div>
Sans-serif
The prefix sans means "without," so a sans-serif font is one that does not have serifs. Sans-serif fonts look cleaner and more streamlined than serif fonts, and they often fit better on most web pages. (Not all web designs are the same, though, and you can many times find uses of both serif and sans-serif fonts, often within the same style sheet.) A sans-serif font is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig12 Figure 9.12].
<div style="text-align: center;"> Figure 9.12. Sans-serif fonts have a more modern look than serif fonts.
[[Image:09fig12.jpg|300px]]
</div>
The most common sans-serif font is <code>Arial</code>; its near relatives are <code>Helvetica</code> and <code>Geneva</code>. Another important font is <code>Verdana</code>, which was specifically developed for on-screen display; it is wider than <code>Arial</code> and easier to read, especially at smaller sizes. Other examples of sans-serif fonts are <code>"Century Gothic"</code>, <code>Chicago</code>, <code>Futura</code>, and <code>Tahoma</code>.
Monospace
The term monospace means that each letter is displayed in the same amount of space; columns of text line up by character, for example, so that the 15th character from the left on each line is always at the same location. This is rather like an old typewriter. (Do people still use typewriters in the 21st century?) The code samples in this book are set in a monospace font, as is any word meant to be typed, such as property values and the names of properties and selectors. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig13 Figure 9.13] is an example of the monospace generic family.
<div style="text-align: center;"> Figure 9.13. The letters of monospace fonts line up in columns.
[[Image:09fig13.jpg|300px]]
</div>
The most common <code>monospace</code> font family is <code>"Courier New"</code>, and this is the default <code>monospace</code> value on pretty much every browser. <code>Courier</code> is an older version of <code>"Courier New"</code>; you may want to list both of these to ensure a greater likelihood of a font match.
Other monospace fonts include <code>"Andale Mono"</code>, <code>VT102</code>, and <code>Mishiwaka</code>.
Fantasy
The <code>fantasy</code> generic family is even more of a grab bag than the <code>cursive</code> family; any irregular, somewhat-whimsical font falls into this category. Some are old woodcut-style ornate letters; some are bizarre squiggles; some look like animals; and some look like letters cut from newspapers for a ransom note. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig14 Figure 9.14] has an example of a font from the <code>fantasy</code> generic family.
<div style="text-align: center;"> Figure 9.14. One of many possible fantasy fonts.
[[Image:09fig14.jpg|300px]]
</div>
Because the <code>fantasy</code> generic family is so loosely defined and because browsers have interpreted this as a catchall for any strange fonts that may come along, a declaration of <code>fantasy</code> could produce text that looks like anything. For example, on my browser it may display in a comic book print font, but on yours it could appear in an old English woodcut font. Because this kind of irregularity makes it hard to design effectively, you'll probably want to avoid using this family.
Cursive
The <code>cursive</code> generic family is very variable; it refers to any font that was based on the way people handwrite text. As with <code>fantasy</code>, there are no real standards on what the default <code>cursive</code> family should be, which is why it is different from computer to computer and even from browser to browser. Examples include <code>"Script MT Bold"</code>, <code>"Apple Chancery"</code>, Swing, <code>"MS Sans Serif"</code>, and <code>"Lucida Handwriting"</code>. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09fig15 Figure 9.15], you can see one example of a cursive font.
<div style="text-align: center;"> Figure 9.15. One browser's cursive font (Firefox running on Mac OS X). <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/09fig15_alt.jpg [View full size image]]</div>[[Image:09fig15.jpg|500px]] </div>
Cursive fonts tend to be very difficult to read onscreen and probably should be avoided unless you have a very specific reason to use one, such as the writer's name after a formal letter, styled to represent a written signature.
Commonly Installed Fonts
Because there's so much variance among computers, you may not be able to know with certainty whether or not a given font will appear on a user's computer. She might indeed be using Internet Explorer 6 on Windows, but she also could have decided to delete Arial entirely! (Why someone would do this, I'm not quite sure.)
However, it's possible to devise a list of relatively safe fontsthose that are found on most operating systems and browsers. You should continue to use generic families as fallbacks, but these are relatively safe.
The common fonts are <code>"Times New Roman"</code>, <code>Times</code>, <code>Arial</code>, <code>Helvetica</code>, <code>Geneva</code>, <code>Verdana</code>, <code>"Courier New"</code>, and <code>Courier</code>. Other fonts are less reliable, such as <code>"MS Comic Sans"</code>, <code>Papyrus</code>, and <code>Optima</code>.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Font Families in Action
Let's look at what fonts you have installed on your computer which are used by your browser. Do the following:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create an HTML file with various types of text to style. You can download [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09ex01 Listing 9.1] from the book's website, or make up your own page.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Try out the generic fonts. Set a rule like this to make all the text on your page the same font family:<br /><br /><div><pre>body { font-family: sans-serif; }<br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Then try setting different fonts for the headline elements and the body text; combine them together to get the best appearance.<br /><br /><div><pre>h1, h2, h3, h4, h5, h6 { font-family: fantasy; }<br />p { font-family: cursive; }<br /></pre></div><br /></div>
|-
| <div>'''4. '''</div>
| <div>Now view the page in a different browser. How does your page change, or does it?<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Try using the common fonts such as Arial or Verdana. These are nearly ubiquitous on the Web, but what about Papyrus or Optima?<br /><br /><div><pre>h1 { font-family: Verdana, sans-serif; }<br />blockquote { font-family: Papyrus, fantasy; }<br /></pre></div><br /></div>
|}
|}
./ ADD NAME=CH09LEV1SEC3.HTML
== Summary ==
When you specify a font, you're actually selecting a font from a set maintained by the user's browser and operating system. Browsers use the various font properties, such as <code>font-weight</code>, <code>font-variant</code>, <code>font-style</code>, and <code>font-size</code>, to narrow down the fonts within a specific <code>font-family</code> and select the right one to use. All these properties can be specified with the font shorthand property.
Five generic font familiesserif, sans-serif, cursive, fantasy, and monospaceare used if the user's computer doesn't contain a font you specify. A short list of common fonts is available on all browsers. CSS describes a method for downloading fonts on demand, but unfortunately neither of the two competing methods for downloading fonts is very reliable.
./ ADD NAME=CH09LEV1SEC4.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa1q1a1 Q.]'''
| I need to have specific fonts on my page, even if the user doesn't have them on his computer. What can I do?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa1q1 A.]'''
| If you want specific fonts for headers or navigation buttons, you can create graphics containing your text, using a graphics editing program to choose the exact fonts required. The problem with text-as-graphics is that the images don't scale at all with the user's preferences, which may make it harder for some users with visual disabilities. In any case, you need to remember to set the alt attribute on the HTML <code><img></code> tag to a value equal to the text on the graphic. For more on this, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q1a1 1.]'''
| Consider the following HTML:
<div><pre><div style="font-weight: bold;"><br />That's <span style="font-weight: bolder;">heavy</a>,<br />man.<br /></div><br /></pre></div><br />
What numeric value (<code>100</code> to <code>900</code>) is the equivalent of the font weight on the word <code>heavy</code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q2a2 2.]'''
| How do you write the following properties with the <code>font</code> shorthand property?
<div><pre>.double { font-weight: 700;<br />color: navy;<br />font-family: Verdana, sans-serif;<br />font-size: x-large;<br />font-style: oblique;<br />font-variant: small-caps; }<br /></pre></div><br />
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q3a3 3.]'''
| What are the generic font families that are closest to each of these fonts?
<div># <div>Verdana</div>
# <div>Times New Roman</div>
# <div>Lucida Handwriting</div>
# <div>Helvetica</div>
# <div>Courier New</div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q1 1.]'''
| The value <code>bold</code> is inherited from the containing box, and it has a value of <code>700</code>. The <code>bolder</code> property value increases the inherited value by <code>100</code>, so the total is <code>800</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q2 2.]'''
| Here's one way to write that rule with the <code>font</code> property:
<div><pre>.double { font: oblique small-caps 700<br />x-large Verdana sans-serif;<br />color: navy; }<br /></pre></div><br />
Because <code>color</code> isn't included in the <code>font</code> shorthand property, it has to be declared separately. Note that the order of <code>weight</code>, <code>size</code>, and <code>family</code> is used; hopefully, you remembered that the order does matter for those values.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch09qa2q3 3.]'''
| The generic families for each font are
<div># <div>sans-serif</div>
# <div>serif</div>
# <div>cursive</div>
# <div>sans-serif</div>
# <div>monospace</div></div>
|}
Exercise
Explore the use of fonts in CSS with this optional project. Create a web page with a style sheet that uses a number of different fonts for headers, paragraphs, navigation, footers, tables, and anything else. Go overboard with your font choicesmake up dozens of styles, a different font for each type of contentand then start decreasing the variety of fonts you use. Discover at what point "a lot" is "too many," and discover how many fonts you really need to make a web page look right. (My preference? No more than two or three.)
./ ADD NAME=CH10.HTML
l0b9iyrq7ve0vgor4e6hvrqbeldal09
User:Bartlett/10
2
2113
39220
5499
2026-04-13T06:03:18Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39220
wikitext
text/x-wiki
= Hour 10. Text Colors and Effects =
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* Additional ways to specify the color of text
* How to use color effectively in web design
* How to add or remove underlines from your text
* How to add lines through or over your text
* Which CSS property enables you to change the case of your letters
* How to control the spaces between letters and words
* How to control line breaks and duplicate the HTML <code><pre></code> and <code><nobr></code> tags
* How to adjust the spacing between lines
Use of Cascading Style Sheets can transform a plain, boring page of text into a visual treat, without even any graphics. The CSS specifications define ways to enhance your textual content visually, from changing the colors to adding strikethrough lines. In addition, you can change the spaces between letters, words, and lines, as well as the points at which browsers wrap lines, by using simple CSS properties.
|}
./ ADD NAME=CH10LEV1SEC1.HTML
== Text Colors ==
Colors are a key part of conveying information in a visual medium. Giving distinct colors to certain types of information on a page can emphasize or de-emphasize the importance; for example, new content can be marked with a bright, vivid color, and outdated content may be presented in a more muted hue.
As you already know, using the <code>color</code> property is the primary method for setting the foreground color. You can set the background color with the <code>background-color</code> property, which is covered in detail next hour.
The foreground <code>color</code> is also used by other properties as a default color value if none is specified. For example, if a color value is omitted for the <code>border</code> property, the foreground <code>color</code> will be used.
Specifying Color Values
CSS provides two ways to define a color. The first is to use a color name, such as <code>green</code> or <code>black</code>; the second is to use a set of three RGB values, corresponding to the amount of red, green, and blue desired. RGB colors were introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," and in this hour we'll tell you other ways to specify a set of RGB values.
Color Names
Back in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], you learned about the 17 colors recognized by the CSS specifications. These color names<code>aqua</code>, <code>black</code>, <code>blue</code>, <code>fuchsia</code>, <code>gray</code>, <code>green</code>, <code>lime</code>, <code>maroon</code>, <code>navy</code>, <code>olive</code>, <code>orange</code>, <code>purple</code>, <code>red</code>, <code>silver</code>, <code>teal</code>, <code>white</code>, and <code>yellow</code>are well-supported by the browsers.
Most browsers accept other color names as well, such as <code>pink</code>, <code>cyan</code>, and <code>violet</code>. However, until a future version of CSS adds those colors to the official specification, it's probably best to avoid using such nonstandard colors. There's no guarantee that a browser will support them, so you're safer with RGB values.
Some other colors are accepted by browsers as well; those are based on the user's operating system preferences and are called system colors. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch23.html#ch23 Hour 23], "User Interface and Generated Content," you'll learn more about system colors and how to use them in your web design.
RGB Color Values
To specify a color in RGB notation, you need to know how much red, green, and blue is contained in that color. Web colors are a bit strange at first if you're not used to them; they're not at all like mixing paints as a child. For example, when you're blending paint colors, you mix red and yellow to make orange. When you're making RGB colors, you mix red and green to make yellow! If you did that with paint, you'd get some ugly, muddy gray-brown shade.
Paints (and ink, as well as most other physical objects you look at) have color because they selectively reflect light; something that actually emits light, as your monitor does, creates colors by adding together portions of colored light. It's a bit confusing, but you'll get used to it after you've worked with RGB values.
Even more confusing is the way RGB colors are written. All RGB colors are measured based on a scale from 0 to 255. They're usually counted in hexadecimal, which means a base-16 number system where the digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F. The number 32 is written as <code>20</code> (two sixteens and zero ones), and the number 111 is <code>6F</code> (six sixteens and 15 ones).
CSS offers four ways to present RGB values. The first uses straightforward hexadecimal notation, as a six-digit number:
<div><pre>body { color: #CC66FF; }
</pre></div>
This means the foreground color should have a red value of <code>CC</code> (204 out of 255, or 80%); <code>66</code> green, which is 102 (40%); and <code>FF</code> blue, or 255 (100%). What does this color look like? Kind of a light lavender. The closer you are to white (<code>#FFFFFF</code>) the more pastel the colors, and when you mix large amounts of blue and red, you get a purple effect.
You can also write this in short hex notation. This is a three-digit hexadecimal number; to convert a three-digit RGB code to a six-digit one, simply double each letter. So the same rule can be written like this:
<div><pre>body { color: #C6F; }
</pre></div>
The <code>rgb()</code> function provides two more ways to set colors, especially if you don't know hexadecimal numbers well. One of those is to provide a triplet of RGB numbers, rated from 0 to 255, separated by commas. The other is to give percentages. Here's how the lavender rule can be written:
<div><pre>body { color: rgb(204, 102, 255); }
body { color: rgb(80%, 40%, 100%); }
</pre></div>
You can use these color values when setting any color in CSS, not just the <code>color</code> property. For example, you can set a <code>background-color</code> or a <code>border</code> with any of these types of values.
<div>Did you Know?
To design effectively with color, you need a color chart, or else you have to be very willing to experiment with RGB values! I recommend getting a color chart; either a printed one you can keep by your computer or an electronic file you can refer to, or both. A great site for web color information is VisiBone, [http://www.visibone.com/ http://www.visibone.com/], which has a hex color chart arranged by hue.</div>
Using Color Effectively
When you're designing a web page and adding color by using CSS, it is always helpful to put some thought into the process. The theory and practice of employing color is a topic that could fill an entire book or several books, as not everyone seems to agree! However, here are some pointers that can help you use color more effectively in your designs; most of these are common sense, but it's amazing how many web designs don't seem to have taken these into account.
* Use colors to visually emphasize important differences among types of content. The presentation of your content should be derived from the meaning of that information. Color your navigation bar differently from your main content. Set sidebars apart visually with background colors that fit well with the rest of the page. Change the color of headings to make them more visible.
* Change colors for a reason, not on a whim. I've seen many websites where the developers appear to have discovered color just the day before and changed the color for no reason. Be able to justify your color choices.
* Bright colors draw attention; faded colors hide unimportant material. As an example, if some content is more important or changes often, give it a vibrant, bright color, such as yellow (on a dark background) or red, to make it stand out.
* Too many colors will make your page seem confusing and unprofessional; a restricted set of hues often works better. If you don't have any experience with graphic design, pick up a good book on color and design, and notice that many great designs have a limited palette.
* You don't have to change the color of everything. Black on white is not the enemy. Web users are accustomed to the default colors, and often it's easier to read text if there's high contrast, such as black on white (or white on black).
* If you're designing for a whole site, use a consistent look across your pages. Consistency helps users recognize that they're still at your site and helps establish a feeling of familiarity. If you change your site too often, regular users may be disoriented.
* If there are identifiable subsites, consider assigning each one a color scheme. Don't create a brand new design for each; it can be disorienting if each section looks like a brand new website. Instead, add color that complements the primary site design.
* Make sure your color choices look good together and contrast well. Subtle shades of difference, such as medium blue on dark blue, may not come across well and content could be lost.
* Use colors that complement any images or graphics on your page. You can derive color schemes from your graphical content, or choose graphics that fit your chosen colors. The more coordinated your colors, the better your site will look.
* Test your colors in several browsers and computers; your monitor's settings may be different than someone else's. Try testing with 256 colors instead of thousands, millions, or billions; if you can, try your site in black and white.
* Don't employ color as the only way of conveying information; visually impaired users might miss important context. It's fine to use color, but make sure that important distinctions among content are reflected in the markup as well. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," you'll learn more about designing to enable access for people with disabilities.
./ ADD NAME=CH10LEV1SEC2.HTML
== Special Text Effects ==
In addition to changing the colors of the text and the font properties from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch09.html#ch09 Hour 9], "Fonts and Font Families," Cascading Style Sheets can be used to produce text effects ranging from decorations to drop shadows. These can be used only on CSS elements that actually contain text; on anything else, they have no effect. For example, a <code>text-shadow</code> property set on an <code><img></code> tag doesn't produce a shadow under the displayed image.
The <code>text-decoration</code> Property
CSS uses the term text decoration to refer to a specific set of effects that can be applied to text: lines through, under, or around the text, and blinking text. The types of values that can be set for the <code>text-decoration</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table01 Table 10.1]. The default value for <code>text-decoration</code> is usually none, although most browsers automatically use <code>text-decoration: underline</code> for hypertext links.
{| cellspacing="0" cellpadding="5"|+ Table 10.1. Values for the <code>text-decoration</code> Property
|-
| Value
| Effect
|-
| <code>blink</code>
| The text blinks off and on.
|-
| <code>line-through</code>
| Draws a line through the middle of the text.
|-
| <code>overline</code>
| Draws a line over the top of the text.
|-
| <code>underline</code>
| Draws a line under the bottom of the text.
|-
| <code>none</code>
| None of the effects listed here.
|-
| <code>inherit</code>
| Uses the value of <code>text-decoration</code> on the containing box.
|}
<div>Watch Out!
The <code>blink</code> property value is not very popular, primarily because of serious abuse of the <code><blink></code> tag by designers when it was first introduced by Netscape. The <code><blink></code> tag is nonstandard in HTML and highly discouraged. Therefore, <code>text-decoration: blink</code> is specifically stated to be an optional part of the CSS specification; browsers don't have to support it, and in fact, most of them do not.</div>
The value of <code>text-decoration</code> technically is not inherited, although if it is set on a block element, the decoration should be applied to all text within that block.
The color of the <code>text-decoration</code>the line through, over, or under the textis the same as that of the text itself, and so can be set with the <code>color</code> property. The lines drawn are thin, and the exact thickness is up to the browser; you can't change the line thickness with CSS.
The most common value for <code>text-decoration</code> in style sheets is <code>none;</code> the property is mainly used to turn off underlines rather than add them or any other text decorations. Why is this so? Because you can use <code>text-decoration</code> to turn off the underlines on links by writing <code>a:link</code> and <code>a:visited</code> rules. Many designers find underlined links to be annoyingly ugly and much less elegant than links without underlines.
However, there are some problems with that approach: Namely, it makes it harder for the user to know what's a link and what's not. If you're going to remove one of the user's primary cues to find clickable links, you need to make sure that the links are obvious. Color typically isn't enough by itself, even though web developers like to think it should be.
If you're using inline linksthose within paragraphs of textthen you should probably leave the underlines alone. An alternative approach is to set obvious borders or background colors on your inline links.
Navigation bars are a different case; even without underlines, users can tell they're supposed to click on things that look like buttons or a list of options. Removing underlines from navigation bars is acceptable and won't cause problems.
The other side of the link-underlining coin is this: Users think that anything that is underlined is clickable. If you put <code>text-decoration: underline</code> on your <code><h2></code> tag, people will try to click it. And they'll get annoyed when it doesn't click. Therefore, you should avoid using underlines nearly all the time. If you need to call attention to something, use the <code><em></code> or <code><strong></code> tags, font effects such as <code>font-weight</code> or <code>font-style</code>, or colors. For more about styling links, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch12.html#ch12 Hour 12], "Styling Links."
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex01 Listing 10.1] is an HTML file with an embedded style sheet that demonstrates <code>text-decoration</code> in action; you can see the results displayed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig01 Figure 10.1].
Listing 10.1. Text Decorations in an Embedded Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- decorate-10.1.html --><br /><html><br /><head><br /><title>I love to decorate</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />h1 em { text-decoration: underline; }<br />.nav { border: 0.3em solid black; }<br />.nav a:link, .nav a:visited<br />{ text-decoration: none; }<br />.oops { text-decoration: line-through; }<br />.eg { border: 1px solid black;<br />margin: 2em; padding: 1em; }<br />#a { text-decoration: underline; }<br />#b { text-decoration: line-through; }<br />#c { text-decoration: overline; }<br />#d { text-decoration: blink; }<br /></style><br /></head><br /><body><br /><table class="nav" border="0" align="right"><br /><tr><th><a href="home.html">Home</a></th></tr><br /><tr><th><a href="info.html">Info</a></th></tr><br /><tr><th><a href="help.html">Help</a></th></tr><br /><tr><th><a href="news.html">News</a></th></tr><br /></table><br /><h1>I <em>love</em> to decorate!</h1><br /><p> I think that decorating<br /><span class="oops">cakes</span>HTML is lots<br />of fun. Here are some of my favorites: </p><br /><div class="eg"><br /><p id="a">Underlined text (don't you want to<br />click here?) </p><br /><p id="b">Line-through text</p><br /><p id="c">Overlined text</p><br /><p id="d"> Blinking text (this is hard to show<br />in print!) </p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 10.1. A variety of text decoration effects.
[[Image:10fig01.jpg|500px]]
</div>
The <code>text-transform</code> Property
You can change the case of text from upper- to lowercase, or vice versa, by using the <code>text-transform</code> property. Well, you're actually not changing the text itself, but rather how a CSS-enabled browser displays it. The values you can set for this property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table02 Table 10.2]; the default is none, although if a <code>text-TRansform</code> property is set on the containing box, that value will be inherited.
{| cellspacing="0" cellpadding="5"|+ Table 10.2. Values for the <code>text-transform</code> Property
|-
| Value
| Effect
|-
| <code>capitalize</code>
| Capitalizes the first letter of each word.
|-
| <code>lowercase</code>
| Changes all uppercase letters to lowercase.
|-
| <code>uppercase</code>
| Changes all lowercase letters to uppercase.
|-
| <code>none</code>
| Doesn't change anything.
|-
| <code>inherit</code>
| Uses the value on the containing box.
|}
This property is dependent upon the language and character set being used; if a language doesn't have upper- or lowercase letters, nothing is changed.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex02 Listing 10.2] is an HTML file with an embedded style sheet that contains text-transform examples.
Listing 10.2. Text Transforms in an Embedded Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- transform-10.2.html --><br /><html><br /><head><br /><title>Text Transformations</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />div.eg { margin: 1em; padding: 1em;<br />font-family: Arial, sans-serif;<br />border: 1px solid black; }<br />/*<br />#nav { text-transform: lowercase; }<br />#header h3 { text-transform: capitalize; }<br />#header h4 { text-transform: uppercase; }<br />#lion p:first-child:first-line<br />{ text-transform: uppercase; }<br />*/<br /></style><br /></head><br /><body><br /><h3>Navigation Bar:</h3><br /><div class="eg" id="nav"><br /><a href="index.html">Teach Yourself CSS</a> ·<br /><a href="about.html">About</a> ·<br /><a href="author.html">Author</a> ·<br /><a href="downloads.html">Downloads</a> ·<br /><a href="contact.html">Contact</a><br /></div><br /><h3>Subheading:</h3><br /><div class="eg" id="header"><br /><h3>george l. mountainlion</h3><br /><h4>Born February 1952<br>Died March 8, 1955</h4><br /></div><br /><h3>First Line:</h3><br /><div class="eg" id="lion"><br /><p>I freely give all signs and sounds of nature I<br />have known to those who have the grace to enjoy<br />not man-made materialism but God-made beauty.</p><br /><p>The magnificent Arizona sunsets I have watched<br />from my enclosure, I bequeath to all who see<br />not only with their eyes but with their hearts.</p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
As listed, the style sheet doesn't actually display any transformations because the style rules that use <code>text-TRansform</code> are commented out. This enables you to see the "before" view as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig02 Figure 10.2].
<div style="text-align: center;"> Figure 10.2. Example page before <code>text-TRansform</code> rules are applied. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/10fig02_alt.jpg [View full size image]]</div>[[Image:10fig02.jpg|500px]] </div>
By removing the lines containing the <code>/*</code> and <code>*/</code> markers (but not the rules between them), you can turn the transformations on, and the results are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig03 Figure 10.3]. The style examples used here are commonly found on the Webmany web designers enjoy putting navigation elements in all lowercase or uppercase text, and news sites frequently use all capital letters for sub-headlines and the first line of a story.
<div style="text-align: center;"> Figure 10.3. Example page after <code>text-transform</code> rules are applied. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/10fig03_alt.jpg [View full size image]]</div>[[Image:10fig03.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Transform Text to Uppercase and Lowercase
It's one thing to look at a pair of screenshots, but another to actually see the effects of style rules yourself. Try out <code>text-transform</code> by doing the following steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Download a copy of the HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex02 Listing 10.2] from the book's website.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>View the untransformed text in your web browser.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Edit the file to remove the comments and reload, noting the changes.<br /><br /></div>
|-
| >
| >
|-
| <div>'''4. '''</div>
| <div>Start changing the style rules. Make the headers all follow <code>text-transform: capitalize</code>. Change the navigation to uppercase.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Capitalize everything except the first letter of every <code>#lion</code> paragraph with rules that use <code>:first-letter</code> (from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors") like this:<br /><br /><div><pre>#lion { text-transform: uppercase; }<br />#lion p:first-letter { text-transform: lowercase; }<br /></pre></div><br /></div>
|-
| <div>'''6. '''</div>
| <div>Get creative! View your page in your web browser to see how text-transform works. How can you incorporate text-transform into your own site designs?<br /><br /></div>
|}
|}
./ ADD NAME=CH10LEV1SEC3.HTML
== Controlling Text Spacing ==
The display characteristics of the text can be controlled by a number of properties that affect the spaces between characters and words. These properties are less useful than many others, such as the font properties, but if you ever need to fine-tune your text display, these are the properties you will use.
The <code>letter-spacing</code> Property
All browsers use default spacing between letters; if there wasn't such a space, the letters would touch up against each other and would be nearly impossible to read. The <code>letter-spacing</code> property lets you adjust this space by increasing or decreasing the value of the default spacing. Values for <code>letter-spacing</code> are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table03 Table 10.3]; the default value is <code>normal</code>. If the letter-spacing property is set on the containing box, the value is inherited.
{| cellspacing="0" cellpadding="5"|+ Table 10.3. Values for the <code>letter-spacing</code> Property
|-
| Value
| Effect
|-
| <code>normal</code>
| Don't insert extra spacing between letters.
|-
| <code>measurement</code>
| Insert extra letter spacing.
|-
| <code>negative measurement</code>
| Reduce spacing between letters.
|-
| <code>inherit</code>
| Use the value of <code>letter-spacing</code> from the containing box.
|}
<div>Did you Know?
In typography, the space between letters is known as the kerning. Professionally typeset text often contains very subtle but important kerning effects. For example, the letters in most logos are not evenly spaced; varying the kerning can make text look a lot better. Usually this doesn't matter too much on the Web, but sometimes it is vitally important, especially to professional typesetters.</div>
The <code>text-align</code> property can also affect the <code>letter-spacing</code>; if <code>text-align</code> is set to <code>justify</code>, the browser automatically adjusts the space between letters so that the text can be justified. If the <code>letter-spacing</code> property is set to a measurement, such as <code>0.1em</code> or <code>2px</code>, the browser isn't allowed to change that space, even if it is justifying text.
The <code>word-spacing</code> Property
The <code>word-spacing</code> property is similar to the <code>letter-spacing</code> property, except, of course, that it controls the space between words. Browsers convert any whitespace (spaces, tabs, line breaks) to a single space and then display that space as a gap between words. The size of the space depends on the browser and the font; the <code>word-spacing</code> property adjusts from that initial size.
Values for <code>word-spacing</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table04 Table 10.4]. If there is a value on a containing box, that will be inherited; otherwise, the default value is <code>normal</code>. Like <code>letter-spacing</code>, if a <code>word-spacing</code> value is set, the browser is not allowed to change the spacing even when the <code>text-align</code> value is <code>justify</code>.
{| cellspacing="0" cellpadding="5"|+ Table 10.4. Values for the <code>word-spacing</code> Property
|-
| Value
| Effect
|-
| <code>normal</code>
| Don't insert extra spacing between words.
|-
| <code>measurement</code>
| Insert extra word spacing.
|-
| <code>negative measurement</code>
| Reduce spacing between words.
|-
| <code>inherit</code>
| Use the value of <code>word-spacing</code> from the containing box.
|}
Keep in mind that both <code>letter-spacing</code> and <code>word-spacing</code> add or subtract from the default browser spacing; they don't set it to that value. So if a browser normally has a space of 0.5 em between words, a <code>word-spacing</code> value of <code>0.3em</code> will make the total gap 0.8 em, not 0.3 em. Examples of letter-spacing and word-spacing rules are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex03 Listing 10.3].
Listing 10.3. Styles Affecting Letter and Word Spacing
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- spacing-10.3.html --><br /><html><br /><head><br /><title>Tips on Color Use</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />li { margin: 0.5em; }<br />h1 { letter-spacing: 0.25em;<br />word-spacing: 0.5em;<br />}<br />li#a { word-spacing: 1.5em; }<br />li#b { letter-spacing: 8px; }<br />li#c { letter-spacing: -0.1em; }<br />li#d { word-spacing: -0.3em; }<br /></style><br /></head><br /><body><br /><h1>Tips on Color Use</h1><br /><ul><br /><li id="a"><br />Use colors to visually emphasize important differences<br />among types of content. The presentation of your<br />content should be derived from the meaning of that<br />information. Color your navigation bar differently<br />from your main content. </li><br /><li id="b"><br />Change colors for a reason, not on a whim. I've seen<br />many websites where the developers appear to have<br />discovered color just the day before and changed the<br />color for no reason. Be able to justify your color<br />choices.</li><br /><li id="c"><br />Bright colors draw attention; faded colors hide<br />unimportant material. As an example, if some content<br />is more important or changes often, give it a<br />vibrant, bright color, such as yellow or red, to make<br />it stand out.</li><br /><li id="d"><br />Too many colors will make your page seem confusing<br />and unprofessional; a restricted set of hues often<br />works better. If you don't have any experience with<br />graphic design, pick up a good book on color and<br />design, and notice that many great designs have a<br />limited palette.</li><br /></ul><br /></body><br /></html><br /></pre></div><br />
|}
Each list item in this example has a different style for the word or letter spacing but the same font size, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig04 Figure 10.4].
<div style="text-align: center;"> Figure 10.4. Letter and word spacing can make a difference. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/10fig04_alt.jpg [View full size image]]</div>[[Image:10fig04.jpg|500px]] </div>
The <code>white-space</code> Property
When displaying a web page, browsers condense all whitespace in the source and consider it as if there's only one space. This is whitespace condensation. If the content exceeds the width of the box allocated to that content, the browser simply moves down to the next line and continues with the rest of the text. This is called word wrapping because the new lines occur immediately before a new word.
The <code>white-space</code> property enables you to control both the condensation of whitespace and the word wrapping by setting the values shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table05 Table 10.5]. The value of this property is inherited if it is set on a containing box; otherwise the default is <code>normal</code>.
{| cellspacing="0" cellpadding="5"|+ Table 10.5. Values for the <code>white-space</code> Property
|-
| Value
| Effect
|-
| <code>normal</code>
| Do normal word wrapping and whitespace condensing.
|-
| <code>nowrap</code>
| Condense whitespace, but don't wrap lines.
|-
| <code>pre</code>
| Don't condense whitespace, and wrap lines as in the source markup.
|-
| <code>pre-line</code>
| Don't condense whitespace, and wrap lines where there are line breaks in the source or at the end of the line.
|-
| <code>pre-wrap</code>
| Condense whitespace, and wrap lines where there are line breaks in the source or at the end of a line.
|-
| <code>inherit</code>
| Use the value of <code>white-space</code> from the containing box.
|}
A value of <code>nowrap</code> means that the text won't have automatic lines inserted, and that can lead very long lines that force the browser to display horizontal scroll bars. The <code>nowrap</code> value is similar to the old <code><nobr></code> element, which was a nonstandard
HTML tag introduced by Netscape to prevent lines from breaking in the wrong place. The <code><nobr></code> tag was never adopted as an official part of the HTML standard; if you need that same effect, use a <code>white-space:</code> nowrap rule instead.
The value <code>pre</code> produces an effect quite similar to the <code><pre></code> tag in HTML, except that <code><pre></code> also sets the font to a monospace font. The <code>white-space: pre</code> declaration doesn't change the <code>font-family</code> unless you explicitly write a rule to that effect.
<div>Watch Out!
The <code>pre-line</code> and <code>pre-wrap</code> values were introduced in the CSS 2.1 specification and aren't supported uniformly by the browsers, with the exception of Operawhich recognizes <code>pre-wrap</code> (but not <code>pre-line</code>).</div>
The HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex04 Listing 10.4] includes an embedded style sheet with <code>white-space</code> declarations.
Listing 10.4. A Demonstration of <code>white-space</code> Values
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- white-space-10.4.html --><br /><html><br /><head><br /><title>White-Space in Action</title><br /><style type="text/css"><br />h1 { font-family: Verdana, sans-serif; }<br />h2 { font-family: "Courier New", monospace; }<br />p#a { white-space: nowrap; }<br />p#b { white-space: pre;<br />font-family: Verdana, sans-serif; }<br /></style><br /></head><br /><body><br /><h1>White-Space in Action</h1><br /><h2>nowrap</h2><br /><p id="a">A value of <code>nowrap</code> means that the<br />text won't have automatic lines inserted, and that<br />can lead very long lines that force the browser<br />to display horizontal scroll bars. </p><br /><h2>pre</h2><br /><p>You can use <code>white-space: pre</code> to display<br />code samples. Unlike <code><pre></code>, the font<br />isn't automatically monospaced.<p><br /><p id="b"><html><br /><head><br /><title>Simple HTML Page</title><br /></head><br /><body><br /><h1>Simple HTML Page</h1><br /><p>This is a basic HTML web page.</p><br /></body><br /></html></p><br /></body><br /></html><br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig05 Figure 10.5] shows how this page is displayed by a web browser. Notice that the nowrap value has caused the first paragraph to scroll off the screen to the right, creating a horizontal scrollbar.
<div style="text-align: center;"> Figure 10.5. The effects of the <code>white-space</code> property. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/10fig05_alt.jpg [View full size image]]</div>[[Image:10fig05.jpg|500px]] </div>
The <code>line-height</code> Property
The line height of a line of text is determined initially by the <code>font-size</code> property's value. Usually the line height is either the same as the <code>font-size</code> or a little larger, depending on the browser's internal rules for the line height.
The <code>line-height</code> property enables you to adjust the height of the line by using a value listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10table06 Table 10.6]. The value normal means that the the browser's usual methods should be used to calculate the line height; this is the default value. Usually browsers calculate <code>line-height</code> as equal to the font size times 1 or 1.2. A font that is <code>12pt</code> tall will have a line height of <code>12pt</code> to <code>14pt</code> in most browsers.
{| cellspacing="0" cellpadding="5"|+ Table 10.6. Values for the <code>line-height</code> Property
|-
| Value
| Effect
|-
| <code>normal</code>
| Use the default line height.
|-
| <code>measurement</code>
| Set the line height to a particular value.
|-
| <code>multiplier</code>
| Set the line height based on the <code>font-size</code>.
|-
| <code>percentage</code>
| Set the line height based on the <code>font-size</code>.
|-
| <code>inherit</code>
| Use the value of <code>line-height</code> from the containing box.
|}
A multiplier is a normal number without any units, such as <code>1.5</code> or <code>3</code>, which is multiplied by the <code>font-size</code> value. A multiplier of <code>1.5</code> means the same thing as a percentage of <code>150%</code>, and is also the same as <code>1.5em</code>.
The value of <code>line-height</code> is inherited from a containing box if the property is set; in most cases, the calculated value is inherited. For example, if the <code>font-size</code> is <code>18pt</code> and the value of <code>line-height</code> is <code>200%</code>, the calculated value <code>36pt</code> will be inherited by children boxes. However, if a multiplier value such as <code>2</code> is set, that multiplier is passed on directly, and not the calculated value.
<div>Did you Know?
Because the specification allows a browser some latitude in determining the default line height, you may not get identical line spacing across all browsers. You can force a specific line height by setting the <code>line-height</code> property, thus taking the decision out of the hands of the browser's default style sheet.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex05 Listing 10.5] is a set of style rules that can be applied to the HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10ex03 Listing 10.3] to change the line height of the list items; in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10fig06 Figure 10.6], this is displayed by a browser. Setting the <code>line-height</code> to a value based on the font-size, such as <code>2</code> or <code>200%</code>, has the effect of spacing out the lines equally, assuming the <code>font-size</code> doesn't change; <code>200%</code> is double-spacing. To double-space text that contains several different font sizes, you need to use an absolute measurement, such as <code>32px</code>.
Listing 10.5. Making Space with <code>line-height</code>
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>body { font-family: Verdana, sans-serif; }<br />li { margin: 0.5em; }<br />h1 { letter-spacing: 0.25em;<br />word-spacing: 0.5em;<br />}<br />li#a { line-height: 1.2; }<br />li#b { line-height: 0.8em; }<br />li#c { line-height: 2; }<br />li#d { line-height: 200%; }<br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 10.6. Spacing out lines. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/10fig06_alt.jpg [View full size image]]</div>[[Image:10fig06.jpg|500px]] </div>
You can also set the <code>line-height</code> value as part of the <code>font</code> property, which you learned about in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch09.html#ch09 Hour 9]. When setting the font with the <code>font</code> shorthand property, include a slash after the <code>font-size</code> and indicate the desired <code>line-height</code> value. For example, to set a paragraph font that's 12-point Verdana with a line height of 200%, you'd write the following rule:
<div><pre>p { font: 12pt/200% Verdana, sans-serif; }
</pre></div>
./ ADD NAME=CH10LEV1SEC4.HTML
== Summary ==
The foreground color of text can be set with the <code>color</code> property, as you've seen in previous hours. You can set the color value in several ways, including color names, long or short hexadecimal values, and the <code>rgb()</code> function.
Color is a powerful tool for visual communication, but you also need to take care to use it effectively. Consistency and simplicity will help your websites convey information better and produce a more professional look.
Other effects you can apply to your text include decorations such as underlines and strikethroughs using the <code>text-decoration</code> property and changes of case with <code>text-TRansform</code>.
Using the <code>letter-spacing</code> and <code>word-spacing</code> properties, you can fine-tune the display of your text, increasing or decreasing the gaps between letters and words. The <code>white-space</code> property controls both the condensation of whitespace and word wrapping. The <code>line-height</code> property can be used to double-space text or otherwise control the distance between each line.
./ ADD NAME=CH10LEV1SEC5.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q1a1 Q.]'''
| I've heard someone mention "browser-safe colors" before. What is that?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q1 A.]'''
| When web browsers were first created, they couldn't handle the full range of colors available. Instead, they displayed only a limited subset of specific colors216 colors to be precise. Any other colors were displayed poorly, making some backgrounds and images look quite bad. These days, browsers can support a full range of color choices, so the browser-safe color list isn't as important, although you may want to look into it if you are supporting older hardware or software. For more information, see the VisiBone site at [http://www.visibone.com/ http://www.visibone.com/].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q2a2 Q.]'''
| I really want to use <code>text-decoration: blink</code>. Can I?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q2 A.]'''
| No.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q3a3 Q.]'''
| Are you serious?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q3 A.]'''
| Well, if you have to, you can use it. Keep in mind that blinking text is very hard to read and very distracting. Use it only if that's the only way you can get an effect; remember, though, that most browsers don't support it.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q4a4 Q.]'''
| How can I set an exact value for <code>letter-spacing</code> or <code>word-spacing</code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa1q4 A.]'''
| You can't; you can adjust it only from what the browser uses as a default. Fortunately, most browsers use sensible defaults, but there's no way to set an absolute value for letter or word spacing.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q1a1 1.]'''
| Consider the color <code>#FFFF00</code>. How do you write this color in the following ways?
<div># <div>Short hexadecimal</div>
# <div>RGB percentages</div>
# <div>RGB values</div>
# <div>Color names</div></div>
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q2a2 2.]'''
| You want to transform this text so that the first line is in uppercase, the second line is mixed case but with each letter capitalized, and the third is in lowercase. What CSS rules do you write?
<div><pre><div id="a">CSS is fun.</div><br /><div id="b">I use CSS each day.</div><br /><div id="c">Do you like it too?</div><br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q3a3 3.]'''
| The default word spacing in a hypothetical browser is 0.5 ems, and you'd like to put a full em between each word. Which of these declarations accomplishes that?
<div># <div><code>word-spacing: 0.5em;</code></div>
# <div><code>word-spacing: 1em;</code></div>
# <div><code>word-spacing: 200%;</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q4a4 4.]'''
| You want to space out each line of <code><p></code> text evenly so they are double-spaced, 16-point Arial font. How do you write this with a <code>line-height</code> rule, and how do you write it without using <code>line-height</code>?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q1 1.]'''
| Here are the alternate ways to write <code>#FFFF00</code>:
<div># <div><code>#FF0</code></div>
# <div><code>rgb(100%, 100%, 0%)</code></div>
# <div><code>rgb(255, 255, 0)</code></div>
# <div><code>yellow</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q2 2.]'''
| Here's how you transform that text:
<div><pre>#a { text-transform: uppercase; }<br />#b { text-transform: capitalize; }<br />#c { text-transform: lowercase; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q3 3.]'''
| Declaration (a) produces a total word spacing of 1 em if the browser's default is 0.5 em, but remember that you can't set the exact value. If the browser's default is 0.75 em, (a) results in a gap of 1.25 em, and (b) produces a 1.75 em gap. Percentages, such as (c), aren't valid values for <code>word-spacing</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch10qa2q4 4.]'''
| Here's one way to write the <code>line-height</code> rule:
<div><pre>p { line-height: 200%; }<br /></pre></div><br />
You could also write the same rule with a line-height value of <code>2</code>, <code>2em</code>, or even <code>32pt</code>. Without using <code>line-height</code>, you'd use the <code>font</code> property:
<div><pre>p { font: 16pt/32pt Arial, sans-serif; }<br /></pre></div><br />
|}
Exercises
To get your hands dirty with text colors and formats, try these exercises; you'll know whether you've succeeded because you'll be able to see the desired effect.
<div># <div>Make a page with headings that contrast in color with the text. What color combinations work best?</div>
# <div>See whether you can specify each color in more than one way; first try it with words, and then RGB values. Which approach is easier, and which is more flexible?</div>
# <div>Turn off underlining of links on a page. Have someone else try to use it; is it easier or harder to use? Then try overlines.</div>
# <div>Convert text to upper- or lowercase, using <code>text-TRansform</code>. In what circumstances would it be easier to simply change the text in the HTML rather than using CSS? You will discover that in some situations, <code>text-TRansform</code> is more convenient, and in others it's easier to just edit the source.</div></div> ./ ADD NAME=CH11.HTM
7u46za0qknokovt1dvpmg46xpqokdlb
User:Bartlett/11
2
2114
39221
5501
2026-04-13T06:03:19Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39221
wikitext
text/x-wiki
= Hour 11. Backgrounds and Background Colors =
; What You'll Learn in This Hour:
* More using about the <code>background-color</code> property
* How to use background and foreground colors together effectively
* How to set a background image and how to control the display of that background
* Which types of images you can use as backgrounds
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "Getting Started with CSS," you learned how to use the <code>background-color</code> property to change the appearance of HTML elements. Background colors can be used to good effect in web design to group related items together, or to highlight important parts of the page. In addition to pure colors, you can also use images as backgrounds for the whole page or for any element on the page.
|}
./ ADD NAME=CH11LEV1SEC1.HTML
== Setting Background Color ==
As you've learned already, the <code>background-color</code> property is used to set the background of an HTML element and is written like this:
<div><pre>selector { background-color: color; }
</pre></div>
This property is similar to the <code>bgcolor</code> attribute in HTML. The CSS version of background colors is a lot more useful, if just because it can be applied to anything. The <code>bgcolor</code> attribute can be set only on <code><body></code>, <code><table></code>, <code><tr></code>, <code><th></code>, and <code><td></code> tags. CSS selectors, such as <code>class</code> selectors, <code>id</code> selectors, and <code>:link</code> and <code>:visited</code> pseudo-class selectors, let you change the background colors for specific parts of the page.
The <code>background-color</code> Property
Like the foreground colors discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10], "Text Colors and Effects," a <code>background-color</code> can be specified in a number of ways: color name, RGB codes, triplets of numbers, or triplets of percentages. Here are some examples of background color declarations:
<div><pre>h1 { background-color: white; }
h2 { background-color: #FFFFFF; }
h3 { background-color: #FFF; }
h4 { background-color: rgb(255, 255, 255); }
h5 { background-color: rgb(100%, 100%, 100%); }
</pre></div>
In addition to color values, <code>background-color</code> can take two other values: <code>TRansparent</code> and <code>inherit</code>.
The <code>transparent</code> value is actually the default for all elements; <code>TRansparent</code> means that whatever background already exists will be shown. So if a <code>background-color</code> of <code>blue</code> is set on the <code><body></code>, all elements that don't have a <code>background-color</code> setting are <code>TRansparent</code> and thus are <code>blue</code>. This actually isn't the same as inheriting the value because <code>background-color</code> doesn't naturally get inherited from the containing block.
If you really need the <code>background-color</code> property to inherit, you can use the value <code>inherit</code>. In practice, <code>transparent</code> and <code>inherit</code> almost always have the same effect, although there are a few cases when you'd need to use <code>inherit</code> instead of <code>TRansparent</code>. Remember that <code>inherit</code> is the same as setting a value equal to that of the containing block's value, whereas <code>TRansparent</code> just makes the background so that it can be seen through. It is the difference between painting the ceiling blue and installing a window on the roof. If the sky is blue anyway, they'll look about the same.
Backgrounds and Foregrounds
When you're setting background and foreground colors in CSS, it's very important to make sure that your color choices will be usable by your audience. You'll need to worry about both the contrast of your color choices and the completeness of your color declarations.
Lack of contrast between your foreground and background colors can make your page difficult for a variety of users to use. Those who have poor vision will struggle to see the letters, and users of limited or black-and-white displays may be left out as well. Printed pages can also suffer from contrast problems.
When considering contrast, you also have to take the needs of users with color blindness into account; if someone can't distinguish between red and green, they may not be able to make out your green heading on a red background.
It's not just users with specific disabilities who have problems with low contrast text; many people find text or images that have poor contrast to be harder to read. High contrast between foreground and background makes your site more useable by everyone, not just users with specific needs.
<div>Did you Know?
An excellent site for color advice is Bob Stein's VisiBone website at [http://www.visibone.com/ http://www.visibone.com/]. Bob offers color charts as well as suggestions on testing your site for use by color-blind users. You can also check how users with color vision deficiencies view websites by visiting [http://www.vischeck.com/ http://www.vischeck.com/].</div>
In addition to contrast, you also have to consider completeness. By this I mean that if you specify a foreground color, you also need to specify a background color. Don't assume that all users have the same initial background and foreground colors that you do!
For example, let's say you write the following rule:
<div><pre>h1 { color: black;
font-family: Verdana, sans-serif; }
</pre></div>
Looks harmless, until you consider that the user's browser settings or style sheet may have set text to be white on a black background. Your <code><h1></code> becomes invisible black-on-black by this rule!
So if you want it to be visible, you have to set the background color explicitly whenever you set the foreground colorsomething like this:
<div><pre>h1 { color: black;
background-color: white;
font-family: Verdana, sans-serif; }
</pre></div>
./ ADD NAME=CH11LEV1SEC2.HTML
== Using Background Images ==
In addition to using solid colors as your background, you can also use images. This is similar to using the <code>background</code> attribute of HTML; the <code>background</code> attribute can be set only on the <code><body></code> tag, but CSS allows you to set a background image on any element.
A background image can be of any type understood by the browser, which means most background images are GIFs or JPEGs (a few browsers also support PNG background images). Background images are more versatile than a solid color; for example, by using an image with a gradient, you can introduce fades and blends into your backgrounds. Photographic images used as backgrounds can often have a striking affect that can't be achieved with a solid RGB color. However, complex backgrounds also have their price: It is much harder to find text colors that will contrast well with a background image.
The <code>background-image</code> property is used to set a background image on an element. The browser loads the image and then displays it behind the foreground content as specified by the CSS properties <code>background-repeat</code>, <code>background-position</code>, and <code>background-attachment</code>. TRansparent parts of the background image show the background color of the element (if any) or the background of the containing element.
In most cases, a background image tiles, which means that it repeats both horizontally and vertically across the box containing that element. A background image fills only the area inside the border (if any), which means the padding and the content itself, as defined by the box model.
<div>Did you Know?
Remember that to set a background image for the entire page, you just need to write a CSS rule for the <code><body></code> tag.</div>
A good background image intended to tile both across and down should be created so that it doesn't have visible edges and seems to flow smoothly between one tile and another. If you're going to position text over the graphic, you should also make sure that it's not too busy; you should still be able to read text after that text is placed over the background.
For the examples in this hour, I created a very simple background graphica star field. I created a 100 pixel by 100 pixel black square, made a few dots in various colors, and saved it as <code>stars.gif</code>. The background image is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig01 Figure 11.1].
<div style="text-align: center;"> Figure 11.1. A star-spangled background image, enlarged for editing. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig01_alt.jpg [View full size image]]</div>[[Image:11fig01.jpg|500px]] </div>
I also created a simple HTML page with some content, so you can see the effects of using this background image behind text; the page contains the first few lines of the U.S. national anthem, the Star Spangled Banner; apologies to my non-American readersit just seemed appropriate given the background graphic! [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex01 Listing 11.1] shows this sample HTML page, which will be used for applying styles learned this chapter. You can download the full HTML listing from the book's website.
Listing 11.1. The Sample HTML Page
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- anthem-11.1.html --><br /><html><br /><head><br /><title> The Star Spangled Banner </title><br /><style type="text/css"><br />/* insert style rules here */<br /></style><br /></head><br /><body><br /><h1>The Star Spangled Banner</h1><br /><h2>By Francis Scott Key</h2><br /><h3>HTML markup by <a href="http://kynn.com/">Kynn Bartlett</a></h3><br /><p><br />Oh say, can you see, by the dawn's early light, <br><br /><!-- rest of the lines omitted here --><br /></p><br /></body><br /></html><br /></pre></div><br />
|}
The <code>background-image</code> Property
Values for the <code>background-image</code> property are an image address URL, none, or <code>inherit</code>. URLs are indicated by the <code>url()</code> function around the address of the image. Quotes around the URL are optional and can be either single or double quotes (but they have to match); the following rules are all identical:
<div><pre>selector { background-image: url(image.gif); }
selector { background-image: url('image.gif'); }
selector { background-image: url("image.gif"); }
</pre></div>
The URL is calculated relative to wherever the rule appears, not necessarily to the web page. For example, the page URL might be [http://www.css24.com/author/index.php http://www.css24.com/author/index.php], and it links in an external style sheet located at [http://www.css24.com/styles/site.css http://www.css24.com/styles/site.css]. A value in that style sheet, such as <code>url("bg.gif")</code>, refers to something in the <code>/styles/</code> directory, not the <code>/author/</code> directory, because the <code>url()</code> style rule is located in a file in <code>/styles/</code>.
However, if the same rule were part of an embedded style sheet or an inline style attribute on the <code>index.php</code> page, it would reference something in the <code>/author/</code> directory because it's all relative to the file that contains the rule.
When you set the <code>background-image</code>, you should set the foreground colors so that they contrast with the background, just as you do when setting the <code>background-color</code>. You should also designate a <code>background-color</code> that is roughly equal to most of the <code>background-image</code> or at least one that contrasts well with the foreground color. If the <code>background-image</code> can't be loaded, the <code>background-color</code> is displayed instead. If you have a cloudy, sky-blue <code>background-image</code>, set your <code>color</code> property to <code>black</code> (because that contrasts well with the light background) and the <code>background-color</code> to something like <code>#CCCCFF</code> (light blue).
For example, here's a rule to set the <code>stars.gif</code> image as the <code>background-image</code> of the page, along with the appropriate colors:
<div><pre>body { background-image: url("stars.gif");
background-color: black;
color: white; }
a:link { color: yellow; }
a:visited { color: lime; }
</pre></div>
You'll notice I set the <code>a:link</code> and <code>a:visited</code> colors as well; otherwise, my links might not be visible against the dark background if they were left as the browser's default (blue and purple, respectively). You can see these style rules applied to the Star Spangled Banner page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig02 Figure 11.2].
<div style="text-align: center;"> Figure 11.2. Oh say, can you see the <code>stars.gif</code> background? <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig02_alt.jpg [View full size image]]</div>[[Image:11fig02.jpg|500px]] </div>
As you can see, the image was tiled across and down the page and looks like it fills up the entire page with a star field.
As noted earlier, you can set background images on any element, not just the <code><body></code>. This lets you set a background on paragraphs, <code><div></code> tags, or any other HTML tags. For example, these rules set the <code>background-image</code> on headline elements:
<div><pre>body { background-color: white;
color: black; }
h1, h2, h3 { background-image: url("stars.gif");
background-color: black;
color: white; }
h1 { padding: 0.5em; }
h2, h3 { padding: 0.25em; }
a:link { color: yellow; }
a:visited { color: lime; }
</pre></div>
I've added <code>padding</code> here to make it easier to see the effects of the background behind the text. Apply these rules and you get a different look to the page, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig03 Figure 11.3].
<div style="text-align: center;"> Figure 11.3. Background images behind <code><h1></code>, <code><h2></code>, and <code><h3></code>. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig03_alt.jpg [View full size image]]</div>[[Image:11fig03.jpg|500px]] </div>
Inline elements as well as block elements can have backgrounds; here's a set of rules that just make the star field appear behind links:
<div><pre>body { background-color: white;
color: black; }
a:link { background-image: url("stars.gif");
background-color: black;
padding: 0.5em;
color: cyan; }
a:visited { background-image: url("stars.gif");
background-color: black;
padding: 0.5em;
color: violet; }
</pre></div>
You can see these styles at work in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig04 Figure 11.4].
<div style="text-align: center;"> Figure 11.4. Inline background image. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig04_alt.jpg [View full size image]]</div>[[Image:11fig04.jpg|500px]] </div>
The <code>background-repeat</code> Property
The <code>background-repeat</code> property enables you to control whether or not the background image tiles across the screen. Values for <code>background-repeat</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11table01 Table 11.1]; the default value is <code>repeat</code>, and <code>background-repeat</code> values do not inherit from the containing block.
{| cellspacing="0" cellpadding="5"|+ Table 11.1. Values for the <code>background-repeat</code> Property
|-
| Value
| Effect
|-
| <code>repeat</code>
| Tile horizontally and vertically
|-
| <code>repeat-x</code>
| Tile only horizontally (along the X-axis)
|-
| <code>repeat-y</code>
| Tile only vertically (along the Y-axis)
|-
| <code>no-repeat</code>
| Display the image only once, with no tiling
|-
| <code>inherit</code>
| Inherit the <code>background-repeat</code> value of the containing block
|}
It's easier to demonstrate these in action rather than explain them in text, so let's look at how you use <code>background-repeat</code>. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex02 Listing 11.2] is a style sheet that sets a horizontally repeating background on the <code><body></code>, which puts a band of stars across the top of the page.
Listing 11.2. A <code>repeat-x</code> Background Image
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* stars-11.2.css */<br />body { background-color: gray;<br />background-image: url("stars.gif");<br />color: white;<br />background-repeat: repeat-x; }<br /></pre></div><br />
|}
In this example, you'll notice I set the background color to gray; this makes it easier to see where the black image starts and stops. I had to choose a color that would be dark enough to show the white text, but light enough to contrast with the black of the starfield. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig05 Figure 11.5] shows this style sheet applied to the HTML page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex01 Listing 11.1].
<div style="text-align: center;"> Figure 11.5. Horizontal tiling of the background image. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig05_alt.jpg [View full size image]]</div>[[Image:11fig05.jpg|500px]] </div>
To tile the figure vertically, you use the <code>background-repeat</code> value of <code>repeat-y</code>, as in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex03 Listing 11.3].
Listing 11.3. A repeat-y Background Image
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* stars-11.3.css */<br />body { background-color: gray;<br />background-image: url("stars.gif");<br />color: white;<br />background-repeat: repeat-y; }<br /></pre></div><br />
|}
This creates a stripe down the left side, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig06 Figure 11.6]. In the next section of this hour, you'll learn how you can use the <code>background-position</code> property to move the stripes created by <code>repeat-x</code> and <code>repeat-y</code>.
<div style="text-align: center;"> Figure 11.6. Vertical tiling of the background image. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig06_alt.jpg [View full size image]]</div>[[Image:11fig06.jpg|500px]] </div>
If you don't want the image to repeat at all, use the <code>background-repeat</code> value of <code>no-repeat</code>, as in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex04 Listing 11.4]. You use this value whenever you want a single placement of an image, such as a watermark or a very large background that shouldn't be repeated. See [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig07 Figure 11.7].
Listing 11.4. A Nonrepeating Background Image
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* stars-11.4.css */<br />body { background-color: gray;<br />background-image: url("stars.gif");<br />color: white;<br />background-repeat: no-repeat; }<br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 11.7. The background image without tiling. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig07_alt.jpg [View full size image]]</div>[[Image:11fig07.jpg|500px]] </div>
<div>Did you Know?
When an image doesn't repeat or repeats only in one direction, you can worry less about the sides of the image matching up properly when it tiles. A <code>no-repeat</code> image doesn't wrap around, so there's no need to blend the top and bottom, or the left and right, into each other smoothly.</div>
The <code>background-position</code> Property
As you can see in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig07 Figure 11.7], a background image is placed in the upper-left corner of the element box it is styling. If tiling occurs, either by default or because of the <code>background-repeat</code> property setting, the image reproduces itself to the left and right horizontally, or up and down verticallyor bothfrom that starting position.
You can change the location of the initial image by using the <code>background-position</code> property. A <code>background-position</code> value consists of two size values or percentages: one indicating the horizontal position and the second indicating the vertical. If only one value is given, it sets the horizontal position.
A size value for <code>background-position</code> is a number and a unit, such as <code>30px</code> or <code>4em</code>; this tells where the initial image's upper-left corner is to be placed.
A percentage value indicates how far over the image should be aligned; <code>50%</code> means that the center of the image (horizontally or vertically) aligns with the center of the element being styled. A pair of values, such as <code>75% 25%</code>, means the spot on the image that's 75% over from the left horizontally and 25% down from the top should be matched with the corresponding location in the element's box.
In addition to sizes and percentages, word values can be used for <code>background-position</code>; these are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11table02 Table 11.2]. Values can be combined together; <code>right center</code> means <code>100% 50%</code>, for example. However, if only one word value is given, the second value is assumed to be <code>center</code>. Word values can be listed in either order, so <code>bottom left</code> is the same as <code>left bottom</code>.
{| cellspacing="0" cellpadding="5"|+ Table 11.2. Values for the <code>background-position</code> Property
|-
| Value
| Effect
|-
| <code>size size</code>
| Place the image at the specified location
|-
| <code>percent% percent%</code>
| Place the image proportionally
|-
| <code>top</code>
| Corresponds to <code>50% 0%</code>
|-
| <code>left</code>
| Corresponds to <code>0% 50%</code>
|-
| <code>right</code>
| Corresponds to <code>100% 50%</code>
|-
| <code>bottom</code>
| Corresponds to <code>50% 100%</code>
|-
| <code>center</code>
| Corresponds to <code>50% 50%</code>
|-
| <code>top left</code>
| Corresponds to <code>0% 0%</code>
|-
| <code>top center</code>
| Same as <code>top (50% 0%)</code>
|-
| <code>top right</code>
| Corresponds to <code>100% 0%</code>
|-
| <code>left center</code>
| Same as <code>left (0% 50%)</code>
|-
| <code>center center</code>
| Same as <code>center (50% 50%)</code>
|-
| <code>right center</code>
| Same as <code>right (100% 50%)</code>
|-
| <code>bottom left</code>
| Corresponds to <code>0% 100%</code>
|-
| <code>bottom center</code>
| Same as <code>bottom (50% 100%)</code>
|-
| <code>bottom right</code>
| Corresponds to <code>100% 100%</code>
|}
<div>Did you Know?
You can use the <code>background-position</code> property to place repeating stripes across or down your page in conjunction with the <code>background-repeat</code> property. A single faint image can be used as a watermark with the <code>background-repeat</code> value of <code>no-repeat</code> and the <code>background-position</code> of <code>center center</code>.</div>
The default value of this property is <code>top left</code>, which is the same as <code>0% 0%</code>. Like <code>background-repeat</code>, this property's value is not inherited from the containing block.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex05 Listing 11.5] uses the <code>background-position</code> property to place an image that is set to tile horizontally.
Listing 11.5. A Positioned, Repeating Background Image
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* stars-11.5.css */<br />body { background-color: gray;<br />background-image: url("stars.gif");<br />color: white;<br />background-repeat: repeat-x;<br />background-position: 0% 33%; }<br /></pre></div><br />
|}
As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig08 Figure 11.8], when this style sheet is applied to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex01 Listing 11.1]'s HTML page, the effect is a stripe across the page.
<div style="text-align: center;"> Figure 11.8. Placing an image with <code>background-position</code>. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig08_alt.jpg [View full size image]]</div>[[Image:11fig08.jpg|500px]] </div>
The <code>background-attachment</code> Property
Normally, images scroll with the rest of the page; however, you can change that by using the <code>background-attachment</code> property. This property can take three values: <code>scroll, fixed</code>, or <code>inherit</code>. The default value is <code>scroll</code>, and the property's value is not inherited from the containing block unless the value is explicitly set to <code>inherit</code>.
A <code>background-attachment</code> value of <code>fixed</code> means that the image doesn't move relative to the original position of the page, even if this means it might not be displayed because the element being styled is not on the screen or is not within the region where the background image could be seen (as determined from the <code>background-repeat</code> and <code>background-attachment</code> properties). If the value of <code>background-attachment</code> is <code>fixed</code>, the location of the image is placed relative to the whole page, not to the element being styled.
You can see an example of using a <code>fixed</code> background image in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11ex06 Listing 11.6]. This is a repeating stripe across the top of the page, which won't move even when the page is scrolled up or down.
Listing 11.6. Style Sheet for a Fixed Background
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* stars-11.6.css */<br />body { background-color: gray;<br />background-image: url("stars.gif");<br />color: white;<br />background-repeat: repeat-x;<br />background-position: top left;<br />background-attachment: fixed; }<br /></pre></div><br />
|}
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig09 Figure 11.9], I've scrolled down a little with the scrollbar, but the background image remains at the top of the page where I placed it. You can test this yourself by viewing the page at the book's website; you can also download the HTML page, style sheet, and image, for local viewing.
<div style="text-align: center;"> Figure 11.9. A fixed background doesn't scroll from its original position even when you scroll the page. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/11fig09_alt.jpg [View full size image]]</div>[[Image:11fig09.jpg|500px]] </div>
<div>Watch Out!
Fixed backgrounds are supposed to be placed relative to the page even when set on boxes within the page; however, Internet Explorer positions them relative to the box of the element being styled. For this reason, it's usually best to set the style rules for watermarks or other fixed background images on the <code><body></code> tag, or another HTML element that's the same size as the whole page (such as an outermost <code><div></code>).</div>
The <code>background</code> Shorthand Property
Like the font property, <code>background</code> is a shorthand property that enables you to set several properties at once. By using <code>background</code>, you can set the <code>background-color</code>, the <code>background-image</code>, the <code>background-repeat</code>, the <code>background-position</code>, and the <code>background-attachment</code>. Simply list the values you want (in any order) as the value for <code>background</code>; any values you don't set are set to their default values.
The CSS rules used to create [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig09 Figure 11.9] can be rewritten like this:
<div><pre>body { color: white;
background: url("stars.gif") repeat-x
fixed top left gray; }
</pre></div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Create a Web Page Watermark
Let's put together everything you've learned in this chapter and create a practical example: A transparent, fixed position watermark for a web page.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create a watermark image, using a graphics program. This should be something light enough that your text can be seen over it. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11fig10 Figure 11.10] shows a rather tongue-in-cheek light blue watermark I created.<br /><br /><div style="text-align: center;"> Figure 11.10. Surely you can do better than this.
[[Image:11fig10.jpg|200px]]
</div><br /></div>
|-
| <div>'''2. '''</div>
| <div>Write a style sheet, using the image you created in step one. Set the image as a background using a rule like this:<br /><br /><div><pre>background-image: url("watermark.gif");<br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Center it on your page with this kind of style rule:<br /><br /><div><pre>background-position: center center;<br /></pre></div><br /></div>
|-
| <div>'''4. '''</div>
| <div>Make sure it doesn't repeat:<br /><br /><div><pre>background-repeat: no-repeat;<br /></pre></div><br /></div>
|-
| >
| >
|-
| <div>'''5. '''</div>
| <div>Prevent it from scrolling:<br /><br /><div><pre>background-attachment: fixed;<br /></pre></div><br /></div>
|-
| <div>'''6. '''</div>
| <div>Set the background for the rest of the page:<br /><br /><div><pre>background-color: white;<br /></pre></div><br /></div>
|-
| <div>'''7. '''</div>
| <div>Now, show off by replacing all those rules with a single <code>background</code> shorthand property rule!<br /><br /></div>
|}
|}
./ ADD NAME=CH11LEV1SEC3.HTML
== Summary ==
The background of any element can be set with the <code>background-color</code> and <code>background-image</code> properties. When using backgrounds, make sure there is contrast between the colors you're using (including image colors), and also ensure that you've set the foreground colors as well.
The tiling, position, and scrolling of the background image can be set with the <code>background-repeat</code>, <code>background-position</code>, and <code>background-attachment</code> properties. All the background properties can be set at once with the <code>background</code> shorthand property.
./ ADD NAME=CH11LEV1SEC4.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and exercises to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa1q1a1 Q.]'''
| What if I want a graphic to tile across the page horizontally and vertically, forming a "T" or "L" shape instead of filling the whole page? Can that be done?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa1q1 A.]'''
| Yes, but it's kind of tricky. Here's how you do it: Add a <code><div></code> tag just inside the <code><body></code> of your page; have it contain all the content you'd normally put in <code><body></code> and give it an <code>id</code> attribute. Then use the <code>transparent</code> value for <code>background-color</code>, like this:
<div><pre>body { background: gray url("stars.gif") repeat-x;<br />padding: 0px;<br />margin: 0px; }<br />div#mydiv { background: transparent url("stars.gif")<br />center repeat-y;<br />color: white;<br />padding: 0.5em; }<br /></pre></div><br />
This makes a T-shaped star background. The <code>padding</code> and <code>margin</code> adjustments are necessary to remove the default padding and margin the browsers put on <code><body></code> and add them back in for the <code><div></code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa1q2a2 Q.]'''
| Why doesn't the order matter for the <code>background</code> shorthand property? That seems confusing. Shouldn't they be in some specific order?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa1q2 A.]'''
| Nope. Because the properties set by the shorthand property all have completely different types of values that can be assigned to them, it's pretty easy for a browser to figure out that, for example, the value <code>green</code> must go with <code>background-color</code> and the value <code>url("stars.gif")</code> with <code>background-image</code>.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa2q1a1 1.]'''
| Which of these values for <code>background-position</code> places the background image at the middle and bottom of the styled element's display box?
<div># <div><code>bottom center</code></div>
# <div><code>center bottom</code></div>
# <div><code>bottom</code></div>
# <div><code>50% 100%</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa2q2a2 2.]'''
| You have an image named <code>skyblue.jpg</code>; it's a graphic that looks like a blue sky with a few wispy clouds. The color is closest to <code>rgb(75%, 75%, 100%)</code>. You want it to tile down the right side of the page, and the background image shouldn't scroll when the page scrolls. The rest of the page will be white; all your text will be black or other colors that contrast against the background. What CSS rule would you write, using the <code>background</code> shorthand property?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa2q1 1.]'''
| Trick question! They all do; they're all the same value.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch11qa2q2 2.]'''
| Because you want the rest of the page to be white, the RGB values of the sky don't matter that much; your black text will contrast nicely with either white or light blue. Therefore, the rule can be written like this:
<div><pre>body { background: url("skyblue.jpg") white<br />right top repeat-y fixed; }<br /></pre></div><br />
|}
Exercises
The best way to understand background colors and images is to get some hands-on practice. Create yourself a test page, an image or two, and a style sheet. Try the following exercises:
<div># <div>Position the graphic in each corner of the page.</div>
# <div>Tile the graphic along each edge of the page.</div>
# <div>Set backgrounds on inline and block elements besides just <code><body></code>. Make them scroll or tile!</div></div> ./ ADD NAME=CH12.HTML
kgqweweqzcypvbzls5jfqfa1elxqrr8
User:Bartlett/12
2
2115
39222
5500
2026-04-13T06:03:19Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39222
wikitext
text/x-wiki
= Hour 12. Styling Links =
; What You'll Learn in This Hour:
* What pseudo-selectors let you designate effects for active links, mouse hovers, and an element focus
* Which order pseudo-classes follow for link styling and inheritance
* How to create some of the most common link effects, including replacing the attributes on the <code><body></code> tag, removing underlines, and creating dynamic mouseovers
The capability to make hyperlinks is what enables the interconnectedness of the Web; HTML itself is named for the hypertext links. Cascading Style Sheets can be used to style these links beyond the default blue-underlined-text. You've already learned how to use <code>:link</code> and <code>:visited</code> pseudo-classes to create CSS rules for link presentation in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], "Selectors," and this hour expands on that knowledge and gives you additional types of selectors and style rules to use with links.
|}
./ ADD NAME=CH12LEV1SEC1.HTML
== CSS for Link Styling ==
The style rules you write to affect hypertext links are much the same as other CSS rules: You identify the elements to be styled by using a selector, and you write property declarations describing how you want the elements to appear. So why spend a whole hour on links?
One reason is that rules for hypertext links require extensive use of pseudo-selectors, whereas most other rules don't. You can't just use the element name alone and get full functionality; you need to write your rules with <code>a:link</code> and <code>a:visited</code> selectors. In this hour, you'll learn about three more pseudo-classes, as well<code>:active</code>, <code>:hover</code>, and <code>:focus</code>.
Link styles are very dependent upon the state of the user interface; what the user is doing and has done is at least as important as the content. That's not the case with most styles. You don't have to worry about your paragraph text changing state after the styles have been applied to it. Links require dynamic reapplication of the cascade and inheritance rules as the page is used.
One more reason that links are set off with their own hour is that questions about them are among those most commonly asked by people learning CSS. Underlines, mouseovers, and special effects on links are some of the coolest simple style effects you can add to a site, along with colors and fonts. Links are active styles, and the pseudo-classes used with them can add unexpected pleasant touches to a page, if done properly.
The <code>:link</code> and <code>:visited</code> Pseudo-Classes
Although you learned about <code>a:link</code> and <code>a:visited</code> selectors in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch05.html#ch05 Hour 5], we revisit them briefly here. The <code>:link</code> state and the <code>:visited</code> state are mutually exclusive, which means that either one or the other applies, but not both. Neither inherits property values from the other; if you set a style property on <code>a:link</code>, the same property isn't set on <code>a:visited</code>. You'd need to write two rules (or one rule with a combined selector).
A rule based on the <code><a></code> tag is applied to <code><a></code> links, visited or unvisited. They also are used on anchors set with the <code><a name="anchor"></code> syntax. So if you want your links to all have a yellow background, you're better off with a rule based on <code>a:link</code> and <code>a:visited</code> instead of <code>a</code> by itself, or else your anchor points will be yellow, too.
Other styles set on the box holding the <code><a></code> tag are inherited normally if those properties usually inherit. So the <code>font-family</code> and <code>font-size</code> properties, for example, are inherited from whatever element contains the link tag.
One exception is the default styling on links. Unless explicitly set by a CSS rule to something else, your links will look like whatever the browser thinks they should look like. At least, that's true when it comes to two specific properties: <code>color</code> and <code>text-decoration</code>. The accepted practice is to make unvisited links blue, visited links purple, and both kinds of links underlined. Effectively, browsers have a built-in set of style rules that look like this (although user preferences can change the specifics):
<div><pre>a:link { color: blue; }
a:visited { color: purple; }
a:link, a:visited { font-decoration: underline; }
</pre></div>
To change these default styles, you need to override these style rules explicitly with more specific ones of your own. Remember that the cascade counts pseudo-classes as classes, and it gives priority to author styles over browser default styles; that means that your <code>a:link</code> rule will win out.
The <code>:active</code> Pseudo-Class
An active link is a link that's in the process of being activated by the user in some way. How this activation occurs is dependent on the type of input and output media used. Usually this means that a mouse pointer has clicked on the link and the page is about to be replaced by a new one reached by following the link. This corresponds to the HTML attribute <code>alink</code>, which can be set on the <code><body></code> tag (although <code>alink</code> can change only the color, whereas a CSS rule can do far more). Browsers usually display this as if the following rule were in its default style sheet:
<div><pre>a:active { color: red; }
</pre></div>
The <code>:active</code> state is not mutually exclusive with <code>:link</code> or <code>:visited</code>. In fact, any link that is <code>:active</code> is undoubtedly going to be one or the other: visited or unvisited. Property values set on the <code>:link</code> or <code>:visited</code> state are inherited by the <code>:active</code> element, as appropriate for each value. For example, if you've already declared that there should be no underlines in your <code>a:link</code> and <code>a:visited</code> rules, you don't need to worry about declaring <code>text-decoration: none</code>; in the <code>a:active</code> rule if you want active links to continue to be underlined.
Cascading is also a consideration. If there's a property value conflict between an <code>a:link</code> and <code>a:active</code> rule, which one wins according to the cascade order? Well, they have the same origin (your style sheet), the same number of <code>id</code> attributes (none, presumably), the same number of classes or pseudo-classes, and the same number of elements, which means it's a tie. Therefore, the winner is whichever one is declared last, according to the source code. In practice, this means that you should put your <code>a:active</code> rule after your <code>a:link</code> and <code>a:visited</code> links.
You can combine together two or more pseudo-class selectors by simply chaining them together without spaces, like this:
<div><pre>a:link { color: blue;
background-color: white; }
a:link:active { color: white;
background-color: blue; }
a:visited { color: purple;
background-color: white; }
a:visited:active { color: white;
background-color: purple; }
</pre></div>
These rules display unvisited and visited links in <code>blue</code> or <code>purple</code> as usual, but when the link is clicked, the colors invert while the page is loading. Combined selectors let you make sure the colors are kept straight. If you didn't write a rule with two pseudo-classes, you'd have to choose either <code>blue</code> or <code>purple</code> as the color you'd use, like this:
<div><pre>a:active { color: white; background-color: purple; }
</pre></div>
The <code>:hover</code> Pseudo-Class
Hovering means that the mouse pointer has been positioned over a particular element, but the user has not necessarily clicked a button to activate it. In HTML, this state triggers a mouseover event, which can invoke JavaScript functions set on the <code>onMouseOver</code> attribute; when the mouse is no longer hovering, that's an <code>onMouseOut</code> event.
The CSS approach is to add the state of <code>:hover</code> to any other states currently on the element (such as <code>:link</code> or <code>:visited</code>) and apply an appropriate style. You can change the color, of course, but you can also change the <code>background</code> properties, <code>border</code>, <code>font-family</code>, <code>font-size</code>, or anything else you like. Some of these changes may cause the dimensions of displayed boxes to change, which can be distracting because the page has to redraw itself and shift about as someone moves the mouse, so you probably should avoid major changes such as <code>padding</code> or <code>display</code>.
Here's an example of the <code>:hover</code> rule in action. I want to make my links change <code>color</code> and <code>background-color</code> when the user moves the mouse. This points out which link will be followed if the user clicksa typical mouseover function. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex01 Listing 12.1] has an embedded style sheet in the HTML for this example.
Listing 12.1. A Simple Question that Hovers Ominously
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- game-12.1.html --><br /><html><br /><head><br /><title>Want to play a game?</title><br /><style type="text/css"><br />body {<br />background-color: black;<br />color: lime;<br />font: xx-large Verdana, sans-serif; }<br />a:link, a:visited {<br />color: lime;<br />text-decoration: none; }<br />a:hover {<br />background-color: white;<br />color: black; }<br /></style><br /></head><br /><body><br /><h1>Want to play a game?</h1><br /><h1><br /><a href="yes.html">yes</a> /<br /><a href="no.html">no</a><br /></h1><br /></body><br /></html><br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12fig01 Figure 12.1] shows what this looks like in a browser; unlike most of the screenshots in this book, I've included the mouse pointer so you can see where it is. The no option is in black-on-white text when the mouse is over it, and when the mouse is elsewhere, it turns back to lime-on-black.
<div style="text-align: center;"> Figure 12.1. How about a nice game of chess? The mouse is over "no."
[[Image:12fig01.jpg|300px]]
</div>
The CSS specifications are very vague on which HTML tags must be able to take on the <code>:hover</code> state. Can you set a rule with a selector like <code>H1:hover</code> and then change the styling on the <code><h1></code> tag whenever the mouse is moved over it? Good question. At the present time, you can't; only items that can be clicked can enter the <code>:hover</code> state in current browsers.
<div>Did you Know?
If you want to add mouseover effects to other items, you can use the HTML event attributes and JavaScript. For example, the following bit of HTML code creates an <code><h1></code> tag that changes color when the mouse moves over it:
<div><pre><h1 onmouseover="style.color = 'blue';" onmouseout="style.color = 'red';" style="color: red; background-color: white;"
>Superman</h1>
</pre></div></div>
The <code>:focus</code> Pseudo-Class
If you can type something into an HTML element, that element is said to have the focus. Focus is an indication of something that's been selected but not necessarily activated. The focus is often indicated by a light dashed line or by a colored glow around part of the page.
Being able to identify the current focus is important for keyboard access to the Web. Web surfers who aren't able to use a mouse use the tab key to move from link to link or to <code><form></code> field tags, such as <code><input></code> and <code><textarea></code>. The HTML <code>tabindex</code> attribute can affect the order of tabbing.
When an element receives the focus, it enters the <code>:focus</code> state and applicable styles are applied. In the example from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex01 Listing 12.1], the background and foreground colors don't change if someone tabs through the links; they change only if the mouse is used. Because you want to serve all your web usersnot just those with mice!you need to add the following rules to the style sheet:
<div><pre>a:focus {
background-color: white;
color: black; }
</pre></div>
<div>Did you Know?
Not all browsers support the <code>:focus</code> pseudo-class. You can use the same JavaScript techniques as already described for <code>:hover</code>, but you should use the <code>onFocus</code> attribute when the element comes into focus and the <code>onBlur</code> attribute when it loses focus.</div>
It's possible for an element to be in a state of <code>:active, :hover</code>, and <code>:focus</code> all at the same time; none of them are mutually exclusive. An <code><a></code> link is either <code>:link</code> or <code>:visited</code> as well. You should put your <code>:active, :hover</code>, and <code>:focus</code> rules after the <code>:link</code> and <code>:visited</code> rules because of the order of the cascade and inheritance.
./ ADD NAME=CH12LEV1SEC2.HTML
== Common Link-Styling Techniques ==
The rest of this hour, I'll show you how to do some of the most common tasks related to styling links. Think of this section as a small cookbook with some key recipes. Armed with these and with your growing knowledge of CSS, you can improvise on your own sites, creating your own style sheet culinary masterpieces.
Replacing HTML <code><body></code> Attributes
The <code><body></code> tag in HTML lets you set a number of attributes that affect the appearance of the entire page. Now you can replace those with CSS rules and go further than the capabilities of HTML because you can fine-tune parts of the page separately by using selectors and by having better control over backgrounds and link styles.
Here's a typical <code><body></code> tag:
<div><pre><body background="mybg.jpg" bgcolor="#FFFFCC" text="#000066" link="red" vlink="#999999" alink="#FFCC99">
</pre></div>
As you can see, this uses presentational HTML attributesthe <code>background, bgcolor, text, link, vlink</code>, and <code>alink</code> attributesto control the colors and background image on the page. This works in current browsers, but from a CSS point of view, it's a poor idea because the presentation is mixed in with the markup, and that always makes things harder, not easier. For example, if you want to change the appearance of the entire site at once, you need to go into every single HTML file and edit the attributes, but if you are using a linked style sheet, it's just a minor tweak to a single style sheet file.
So, how do you write the <code><body></code> tag with Cascading Style Sheets rules? Something like this would work:
<div><pre>body { background: #FFFFCC url("mybg.jpg");
color: #000066; }
a:link { color: red; }
a:visited { color: #999999; }
a:active { color: #FFCC99; }
</pre></div>
Removing Underlines
This seems to be one of the first questions web developers want to know: How do I turn off the underlines? If you've been reading this book straight through from beginning to end, you learned about the <code>text-decoration</code> property in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10], "Text Colors and Effects." However, in case you jumped directly to this chapter, we'll review and summarize here.
You remove underlines by using the <code>text-decoration</code> property with a value of <code>none</code>. Here's an example:
<div><pre>.navbar a:link,
.navbar a:visited
{ text-decoration: none; }
</pre></div>
<div>By the Way
Several important cautions were mentioned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10] about the effect on usability if you remove link underlines; you may want to go back and read that section if it's not fresh in your mind.</div>
Removing underlines from links can be relatively easy. The bigger question is how will you replace them? The reason that links were underlined in the first place was to make them stand out so the web user doesn't have to randomly guess what can be clicked and what can't. Here are some ideas, which can be used separately or in combination:
* Use very bright colors, set with the <code>color</code> property, to make links that much more visible. Links should stand out from the rest of the page and should be easily seen.
* Put borders around the links by using the <code>border</code> property so that the links are in boxes. Boxes can draw attention, as color does.
* Employ the <code>font-weight</code> property to make your links stand out better. Bold links likewise catch the eye; I have used <code>font-weight: bold</code> for unvisited links and <code>font-weight: normal</code> for visited links when designing styles for certain sites.
* Make all links italic (or oblique) by using <code>font-style</code>, or put them in small caps with <code>text-transform</code>. Be careful about readability, though; excessive use of this technique can make your navigation hard to use.
* Add a background color to your links with the <code>background-color</code> property. This can often give an effect similar to a highlighter pen; make sure your background stands out against both the visited and unvisited link colors.
* Utilize <code>class</code> or <code>id</code> selectors to give different styles to different kinds of links; for example, style offsite links differently from local links. Likewise, use different styles for inline links in the body of your text and for navigation links located in a sidebar.
Mouseover Effects
A mouseover effect can be as simple as swapping the colors, as you've seen earlier in this hour, or as subtle as adding the underline back on a mouseover, as follows:
<div><pre>a:link, a:visited { text-decoration: none; }
a:hover { text-decoration: underline; }
</pre></div>
You can also head for the other extreme and get pretty complex. Here's an example of making buttons with CSS and making those buttons change when the mouse rolls over them, all without using JavaScript. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex02 Listing 12.2] is the HTML file to be styled, and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex03 Listing 12.3] is the style sheet. In this example, I'm using tables for layout, but in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS," you'll learn how to lay out a page with pure CSS.
Listing 12.2. An HTML Page with a Navigation Bar
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- buttons-12.2.html --><br /><html><br /><head><br /><title>About the Local Writers Group</title><br /><link type="text/css" rel="stylesheet"<br />href="buttons-12.3.css"><br /></head><br /><body><br /><table width="100%" border="0"><br /><tr><td valign="top" align="center" width="150"><br /><div class="navbar"><br /><a href="/">Home</a><br /><a href="about.html">About Us</a><br /><a href="writers.html">Writers</a><br /><a href="links.html">Links</a><br /><a href="map.html">Map</a><br /><a href="calendar.html">Calendar</a><br /><a href="contact.html">Contact</a><br /></div><br /></td><td valign="top"><br /><h1>About Us</h1><br /><p>The Local Writers Group is an informal group of<br />writers who meet <a href="calendar.html">every other<br />Wednesday evening</a> from 7:30 to 9:00, at the<br />bookstore near the mall.</p><br /><p>If you'd like to attend, just stop by for the next<br />meeting, or <a href="contact.html">drop a note via<br />email</a> to one of our members.</p><br /></td></tr></table><br /></body><br /></html><br /></pre></div><br />
|}
Listing 12.3. Style Sheet with Mouseover Effects
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* buttons-12.3.css */<br />body { font-family: Verdana, sans-serif;<br />color: black; background-color: white; }<br />h1 { color: navy; }<br />/* link colors */<br />.nav a:link { color: yellow; }<br />.nav a:visited { color: lime; }<br />/* link buttons */<br />.nav a:link, .nav a:visited<br />{ font: bold 12pt Verdana, sans-serif;<br />padding: 0.5em; margin: 0.5em;<br />display: block; text-decoration: none;<br />background: url("button.gif") transparent 50% 50% no-repeat; }<br />/* change the button on hover and focus */<br />.nav a:hover, .nav a:focus<br />{ background-image: url("button_yellow.gif");<br />color: black; }<br />.nav a:visited:hover, .nav a:visited:focus<br />{ background-image: url("button_green.gif");<br />color: black; }<br /></pre></div><br />
|}
The three button images used are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12fig02 Figure 12.2], and the final effect can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12fig03 Figure 12.3]. When the mouse is moved over the navigation bar, the glow graphic is used. You'll notice that I used an <code>a:hover:visited</code> rule, as well, so that visited links glow lime green instead of yellow.
<div style="text-align: center;"> Figure 12.2. Background graphics for making buttons.
[[Image:12fig02.jpg|300px]]
</div>
<div style="text-align: center;"> Figure 12.3. Mouseovers in action, with the mouse over "Map." <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/12fig03_alt.jpg [View full size image]]</div>[[Image:12fig03.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Link Buttons in CSS
The technique shown here can be used to make buttons quickly and easily, without having to create each one in a graphics program. Try this:
{| border="0"
|-
| <br />
| >
|-
| <div>'''1. '''</div>
| <div>Make a default blank button in a graphics program, or download one from the Web.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Using the file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex02 Listing 12.2] or your own web page, employ styles to use the blank button in your navigation menu. Use [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12ex03 Listing 12.3] as an example.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Try changing the font size of the text links. What happens if the text is too big for a button?<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Create (or download) a button with a mouseover effect, such as a glow or outline.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Change the colors of your links text. How does it contrast with your button you've chosen? Make sure your links are readable when moused over, when visited, and when the page is newly loaded.<br /><br /></div>
|}
|}
./ ADD NAME=CH12LEV1SEC3.HTML
== Summary ==
CSS rules for styling hypertext links use the same properties as other style rules but extensively utilize pseudo-class selectors. These pseudo-class selectors track the state of various qualities<code>:link</code> and <code>:visited</code> depend on web browsing history; <code>:active, :hover</code>, and <code>:focus</code> depend on the user's interaction with the page.
Link styles can be used to replace the <code><body></code> attributes in HTML, remove links, and even create complex mouseover effects without requiring JavaScript. Armed with your growing knowledge of CSS, you can now confidently apply styles to your hypertext links.
./ ADD NAME=CH12LEV1SEC4.HTML
== Workshop ==
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa1q1a1 Q.]'''
| Now that I know CSS, I can throw away all those <code><body></code> attributes, such as <code>vlink</code> and <code>bgcolor</code>, right?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa1q1 A.]'''
| Well, probably. If you are using the Strict versions of HTML or XHTML, you have to remove them for your markup to be valid anyway. On the other hand, there are a few old browsers still out there that understand only the <code><body></code> attributes, and it probably can't hurt to include presentation markup.
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa1q2a2 Q.]'''
| What about those annoying blue borders around image links? How do I get rid of those?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa1q2 A.]'''
| How about this?
<div><pre>a:link img, a:visited img { border: 0px; }<br /></pre></div><br />
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa2q1a1 1.]'''
| Which of these rules makes the text bold when the user tabs to a link with the keyboard?
<div># <div><code>a:visited { font-weight: 700; }</code></div>
# <div><code>a:hover { font-weight: 700; }</code></div>
# <div><code>a:active { font-weight: 700; }</code></div>
# <div><code>a:focus { font-weight: 700; }</code></div>
# <div><code>a:active:hover { font-weight: 700; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa2q2a2 2.]'''
| How would you rewrite this <code><body></code> tag as CSS rules?
<div><pre><body text="white" background="stars.gif"<br />bgcolor="black" link="#00FFFF"<br />vlink="#FF00FF" alink="#FFFF00"><br /></pre></div><br />
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa2q1 1.]'''
| d. The <code>a:focus</code> selector activates whenever a link has the keyboard focus.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch12qa2q2 2.]'''
| Here's one way to rewrite the <code><body></code> attributes in CSS:
<div><pre>body { color: white;<br />background: url("stars.gif") black; }<br />a:link { color: #00FFFF; }<br />a:visited { color: #FF00FF; }<br />a:active { color: #FFFF00; }<br /></pre></div><br />
|}
Exercises
What makes for good link styles and for bad? Experimenting is the best way to figure out what works for the needs of each website. Here are some ideas you can try:
* Eliminate underlines from your inline links, but replace them with another style that makes them stand out. Which works best, in your opinionbackground colors, font weight, italics, or something else?
* Build a navigation menu that uses backgrounds, borders, and fonts instead of images. Is it easier to maintain CSS-styled text links than graphical navigation bars?
./ ADD NAME=CH13.HTML
Hour 13. Lists
6neiqn4ko42rm142dkdugoeatb85qj9
User:Bartlett/13
2
2117
39223
5517
2026-04-13T06:03:20Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39223
wikitext
text/x-wiki
./ ADD NAME=CH13.HTML
Hour 13. Lists
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* How lists are formatted in CSS
* What the different types of lists are, and how they're coded in HTML
* How other elements can be displayed as lists
* Which CSS properties change the shape and appearance of bullets
* How to set the counting methods of numbered lists
Not all information is organized into paragraphs of text. Many types of web content are actually lists of information, including navigation menus, product feature lists, glossaries, and step-by-step instructions. Because of the way information is read on the Web, the use of lists can be one of the most effective and direct methods of conveying information to an audience. Styling lists attractively can also enhance their usefulness.
|}
./ ADD NAME=CH13LEV1SEC1.HTML
List Formatting
Before I discuss how CSS browsers display lists, I need to define some terms that will be important this hour.
A list is just a set of information that has been organized into discrete pieces called list items. A list can be ordered, which means that the order in which the items are presented is important, or it can be unordered, indicating that there isn't any specific order to the items or that order isn't important. A third type of list is the definition list (also called a dictionary list); these consist of pairs of shorter terms and longer explanations.
Types of HTML Lists
Lists in HTML are usually indicated by appropriate list markup, which means they usually include a list tag such as <code><ol></code>, <code><ul></code>, or <code><dl></code>, and then list items marked up with <code><li></code> or <code><dt></code>, and <code><dd></code> for definition lists. It's also possible to create a list using nonlist tags, such as <code><div></code> or <code><a></code>, and use CSS to convert them into lists.
Within a CSS context, an element is a list item if it has the <code>display</code> property value <code>list-item</code>. When that value is set, the element is treated as an <code><li></code> tag by the browser, no matter what the tag really is. The <code>list-item</code> value designates the element as a block element, except that it also allows for a list marker. A list marker is a symbol before each list item that indicates it's a list.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex01 Listing 13.1], you can see each of the three types of HTML lists, along with a fourth "list" done without using HTML list markup.
Listing 13.1. Four Lists in HTML
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- lists-13.1.html --><br /><html><br /><head><title>List-O-Rama</title></head><br /><body><br /><table border="0" width="100%"><br /><tr><td valign="top" width="50%"><br /><h2>Ordered List: Tallest Mountains</h2><br /><ol><li>Everest</li> <li>K2</li><br /><li>Kangchenjunga</li> <li>Lhotse</li><br /><li>Makalu</li> <li>Cho Oyu</li><br /><li>Dhaulagiri</li><br /></ol</td><br /><td valign="top" width="50%"><br /><h2>Unordered List: Flavors of Soda</h2><br /><ul><li>Peach</li><br /><li>Berry:<br /><ul><li>Raspberry</li><br /><li>Blackberry</li><br /><li>Boysenberry</li><br /></ul></li><br /><li>Orange</li> <li>Kiwi</li><br /></ul></td><br /></tr><br /><tr><td valign="top" width="50%"><br /><h2>Definition List: Common Abbreviations</h2><br /><dl> <!-- definition list --><br /><dt>CSS</dt> <dd>Cascading Style Sheets</dd><br /><dt>HTML</dt> <dd>Hypertext Markup Language</dd><br /><dt>W3C</dt> <dd>World Wide Web Consortium</dd><br /></dl></td><br /><td valign="top" width="50%"><br /><h2>Non-List: Links</h2><br /><div id="nav"> <!-- not done with list markup --><br /><a href="/">Home</a><br /><a href="info/">Info</a><br /><a href="shop/">Shop</a><br /><a href="map/">Map</a><br /><a href="contact/">Contact</a><br /></div></td><br /></tr><br /></table></body></html><br /></pre></div><br />
|}
The four lists are shown in a browser in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig01 Figure 13.1]; this HTML file will be used in the examples later this hour to illustrate how CSS can be used to style lists.
<div style="text-align: center;"> Figure 13.1. Four different lists displayed by Firefox. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig01_alt.jpg [View full size image]]</div>[[Image:13fig01.jpg|500px]] </div>
Ordered (Numbered) Lists
Browsers display an ordered list by putting a number marker of some kind before the list items. Usually number markers are ordinary numbers, such as 1, 2, 3, and so on, but later in this hour you'll learn to change those to other counting methods.
Examples of ordered lists include the top ten best-seller list at a bookstore or a set of instructions for making a cake. In both cases, the specific order of the list items is significant.
Ordered lists in HTML are created by the <code><ol></code> element, which contains <code><li></code> tags for each list item.
<div>Did you Know?
Users with visual disabilities often find ordered lists easier to navigate than unordered lists because they have a better sense of context; the numbers can be used to keep track of location in a list. Using ordered lists on your page is very helpful to these users.</div>
Unordered (Bulleted) Lists
An unordered list is commonly displayed with a bullet marker. This is a symbol placed before each item of the list; it most often looks like a solid circle. During this hour you'll learn how to change the list bullet to other shapes or replace it with an image.
Unordered list examples include a list of toppings you could order on a pizza or a roster of students in a class. Even though the class roster may have an orderusually alphabetical by last namethe order probably isn't significant; it's arbitrary. For example, the list isn't ordered by the tallest or the shortest in the class. In most cases, the significance of a list's order depends on how the list is meant to be used. A list's order may not matter in one case but might in another.
To create an unordered list in HTML, you use the <code><ul></code> element, and each bullet point gets an <code><li></code> tag. Two other HTML tags create bulleted lists, <code><dir></code> and <code><menu></code>, but these are deprecated in HTML 4.01, which means that you should use the <code><ul></code> tag instead; newer browsers may not support the deprecated tags.
Definition Lists
Definition lists consist of pairs of contenta shorter term and a longer definition. The term is displayed first, and then the definition is displayed on a new line with an indented left margin. A definition list in HTML is created with the <code><dl></code> element, with several <code><dt></code> and <code><dd></code> tags inside it.
A definition list doesn't have to be a glossary. Although that's a common use, it could be anything from a listing of features in a car to a menu of desserts that describes each treat. A definition list can be used whenever you have pairs of shorter text and longer explanations or descriptions of that text.
Unlike the <code><li></code> tags in <code><ol></code> or <code><ul></code> elements, the <code><dt></code> and <code><dd></code> tags do not have the property <code>display</code> set to <code>list-item</code>. Instead, they have the <code>display</code> value of <code>block</code>, although the <code><dd></code> tag usually has an extra <code>margin-left</code> value of <code>1.33em</code>.
<div>Watch Out!
Sometimes web developers use the <code><ol></code>, <code><ul></code>, or <code><dl></code> tags to create indented texts or margins. Using structural tags, such as the list elements, for presentational effects such as margins reduces the separation of content from presentation. To create margin effects, use the CSS properties in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes," not list markup.</div>
Changing List Type with <code>display</code>
Using the CSS <code>display</code> property, you can override the default presentation of a tag and create a list from nonlist elements or change a list into a nonlist.
If you change the value of the display property, it changes only how it's presented block or inlineand in the case of the <code>list-item</code> value, it sets aside space for a marker. Changing the display property doesn't affect any other values, such as the inherent <code>margin-left</code> on <code><ol></code> or <code><dd></code>.
Examples of setting <code>display</code> properties can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex02 Listing 13.2], a style sheet to change the appearance of your HTML lists. Notice that I set <code>margin-left</code> values to remove the left margins when changing the <code>display</code> value to <code>block</code>, and I add <code>margin-left</code> when setting <code>display: list-item</code>.
Listing 13.2. Several Lists with Type Changed
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* lists-13.2.css */<br />ul li { display: inline; }<br /><br />ol { margin-left: 0px; }<br />ol li { display: block; }<br /><br />dt { display: list-item;<br />margin-left: 1em; }<br /><br />dd { display: list-item;<br />margin-left: 2em; }<br /><br />div#nav a { text-decoration: none;<br />margin-left: 2em;<br />display: list-item; }<br /></pre></div><br />
|}
The effects of this style sheet can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig02 Figure 13.2], which applies the style sheet to the HTML lists from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex01 Listing 13.1]. The Unordered List is jumbled, there are no number markers for the Ordered List, and there are new list markers before the Definition List and Non-List items. Because the type of list marker is not set, the exact marker used varies from browser to browser, depending on what the browser chooses to use for a default; your browser may show some of the lists differently than in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig02 Figure 13.2]. To ensure consistency across browsers, you should set the list item properties described later this hour whenever you change the <code>display</code> of an element to <code>list-item</code>.
<div style="text-align: center;"> Figure 13.2. Displaying alternate list formatting. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig02_alt.jpg [View full size image]]</div>[[Image:13fig02.jpg|500px]] </div>
The <code>list-style-type</code> Property
You can change the type of list marker by using the <code>list-style-type</code> property. This property is used only on elements that have the display value of <code>list-item</code>, but it can be set on any tag, and the value is inherited by children that are list items. Most commonly, it's set on the <code><ol></code> or <code><ul></code> tags that enclose the <code><li></code> list items; this way you can set different styles for each list.
The most common values for <code>list-style-type</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13table01 Table 13.1]. The default value for <code><ol></code> is <code>decimal</code>, for <code><ul></code> is <code>disc</code>, and for lists created with <code>display: list-item</code> it is <code>disc</code> as well.
{| cellspacing="0" cellpadding="5"|+ Table 13.1. Values for the <code>list-style-type</code> Property
|-
| Value
| Effect
|-
| <code>circle</code>
| A hollow circle bullet
|-
| <code>decimal</code>
| Decimal number markers (1, 2, 3, ...)
|-
| <code>decimal-leading-zero</code>
| Decimal number markers with leading zeros (01, 02, 03, ...)
|-
| <code>disc</code>
| A solid circle bullet
|-
| <code>lower-alpha</code>
| Lowercase alphanumeric markers (a, b, c, ...)
|-
| <code>lower-roman</code>
| Lowercase roman number markers (i, ii, iii, ...)
|-
| <code>none</code>
| Don't display any marker before the list
|-
| <code>square</code>
| A square bullet
|-
| <code>upper-alpha</code>
| Uppercase alphanumeric markers (A, B, C, ...)
|-
| <code>upper-roman</code>
| Uppercase roman number markers (I, II, III, ...)
|-
| <code>inherit</code>
| Use the value of <code>list-style-type</code> from the containing box
|}
There are two types of values: those that set bullet markers and those that set number markers. It is possible to set a bullet <code>list-style-type</code> for ordered lists or to set a number marker on unordered list, but generally speaking, this should be avoided. As a rule of thumb, you should use number markers only with ordered lists, and bullet markers only with unordered lists.
One list contained within another list is called a nested list. Most browsers display nested, unordered lists by changing the bullet type from <code>disc</code>, to <code>circle</code>, and then to <code>square</code>. Using <code>list-style-type</code>, you can control the marker with appropriate descendant rules. Topical outlines created using <code><ol></code> tags can be styled as well, like the following:
<div><pre>ol { list-style-type: upper-roman; }
ol ol { list-style-type: upper-alpha; }
ol ol ol { list-style-type: decimal; }
ol ol ol ol { list-style-type: lower-alpha; }
ol ol ol ol ol { list-style-type: lower-roman; }
</pre></div>
A style sheet that changes list markers is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex03 Listing 13.3].
Listing 13.3. Setting the <code>list-style-type</code> in CSS
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* lists-13.3.css */<br /><br />ol { list-style-type: upper-roman; }<br /><br />ul { list-style-type: square; }<br />ul ul { list-style-type: circle; }<br /><br />#nav a { display: list-item;<br />margin-left: 2em;<br />list-style-type: square; }<br /></pre></div><br />
|}
The results of applying this style sheet to your sample lists are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig03 Figure 13.3].
<div style="text-align: center;"> Figure 13.3. Lists with different marker types. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig03_alt.jpg [View full size image]]</div>[[Image:13fig03.jpg|500px]] </div>
<div>By the Way
Markers (bullet or number) are displayed with the same font characteristic as the list item. If you want to change a propertyfor example, the colorset the property on the list item, and then use a <code><span></code> or other inline element to change the text, as in the following:
<div><pre><ol>
<li><span class="person">Nick Mamatas</span></li>
</ol>
</pre></div>
To change the color of the list marker but not the list text, write rules like these, which put the number in red:
<div><pre>ol { color: black; }
ol li { color: red; }
ol li span.person { color: black; }
</pre></div></div>
International List Markers
You can set the list marker to count using Roman numerals, numbers, or letters, but what about languages that don't use the same alphabet? A list of additional values for the <code>list-style-type</code> property is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13table02 Table 13.2].
{| cellspacing="0" cellpadding="5"|+ Table 13.2. International Values for the <code>list-style-type</code> Property
|-
| Value
| Effect
|-
| <code>armenian</code>
| Traditional Armenian numbers
|-
| <code>cjk-ideographic</code>
| Ideographic numbers (Asian languages)
|-
| <code>georgian</code>
| Traditional Georgian numbers
|-
| <code>hebrew</code>
| Traditional Hebrew numbers
|-
| <code>hiragana</code>
| Japanese hiragana numbers
|-
| <code>hiragana-iroha</code>
| Japanese hiragana-iroha numbers
|-
| <code>katakana</code>
| Japanese katakana numbers
|-
| <code>katakana-iroha</code>
| Japanese katakana-iroha numbers
|-
| <code>lower-greek</code>
| Lowercase Greek letters
|}
The <code>:lang()</code> pseudo-selector, described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors," can be used in conjunction with these <code>list-style-type</code> values; or you could use a normal element selector, a <code>class</code> or <code>id</code> selector, or anything else that fits your markup. Here are two examples:
<div><pre>li:lang(jp) { list-style-type: hiragana; }
ul.alphabeta { list-style-type: lower-greek; }
</pre></div>
<div>Watch Out!
These are supported only for those browsers and operating systems that support these character sets and appropriate fonts. This is highly dependent upon the specific version and language support on each computer. Although you should feel free to use these with content in the appropriate language, you should also expect that browsers without support for such a given language will display these as <code>list-style-type: decimal</code>.</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Styling Your To-Do List
If you're like many people, you probably keep a list of what you need to get done. You can organize your life and practice your new CSS skills by following along:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>First, create a list in an HTML page of the items you need to complete. Use standard list markupthe <code><ol></code> tag is probably most appropriate, so that you can prioritize your list.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Add a style rule, on a linked style sheet or in a <code><style></code> section of the <code><head></code>, that sets the <code>list-style-type</code> property.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Experiment with different list types. Does your list look better with letters, numbers, or Roman numerals?<br /><br /></div>
|-
| >
| >
|-
| <div>'''4. '''</div>
| <div>Try it with a circle, disk, and square as list markers. Which is best for checking off completed items when you print out the list?<br /><br /></div>
|}
|}
The <code>list-style-image</code> Property
You aren't restricted to bullets that are circles or squares; you can actually use any image you like by using the <code>list-style-image</code> property. Naturally, you'll want to use only small images that can function as bullets for this purpose; images that are too large overwhelm the text. As an approximate rule, you should use bullets that are between 12 and 20 pixels in size.
I created a simple one-bullet image in a graphics program by first creating a 16-pixel by 16-pixel blank image, then drawing a black circle, and then adding a yellow plus sign in the middle of it; this is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig04 Figure 13.4].
<div style="text-align: center;"> Figure 13.4. Creating a simple list bullet image. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig04_alt.jpg [View full size image]]</div>[[Image:13fig04.jpg|500px]] </div>
To use this image as a bullet, I simply need to set the <code>list-style-image</code> property in a rule, as in the following:
<div><pre>selector { list-style-image: url("graphic");
</pre></div>
An example of a style sheet that uses bullet images is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex04 Listing 13.4]. Notice that I also set the <code>list-style-type</code> property to <code>circle;</code> if the image can't be loaded for any reason, the <code>circle</code> is displayed instead.
Listing 13.4. Setting a <code>list-style-image</code>
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* lists-13.4.css */<br />ol { list-style-type: upper-roman; }<br />ul { list-style-type: square;<br />list-style-image: url("yellowplus.gif"); }<br />ul ul { list-style-type: circle; }<br />/* This will inherit the list-style-image above */<br />#nav a { display: list-item;<br />margin-left: 2em;<br />list-style-type: square;<br />list-style-image: url("yellowplus.gif"); }<br /></pre></div><br />
|}
Applying this style sheet to the sample lists gives the results in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig05 Figure 13.5].
<div style="text-align: center;"> Figure 13.5. Bullet images marking lists. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig05_alt.jpg [View full size image]]</div>[[Image:13fig05.jpg|500px]] </div>
The <code>list-style-position</code> Property
When a bullet or number marker is placed, it's normally located outside the main content to the left of the list element's box. A virtual marker box is created; the box inherits the text properties of the list item, although the background is always transparent.
The browser determines the placement of this virtual marker box; as a web developer, you can't affect the exact placement of the marker. You can control one thing, though: You can move the marker box inside the list element's box, so it functions as an inline box instead. You do this by setting the <code>list-style-position</code> property.
Three values are possible for <code>list-style-position: outside</code> (the default), <code>inside</code>, and <code>inherit</code>. Any value set on a containing box is inherited, so you can set it on <code><ol></code> or <code><ul></code> selectors and it will apply to list items within them.
The effects of <code>list-style-position</code> are clarified in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13ex05 Listing 13.5]; <code>border</code> properties have been added to make the list item display boxes clear.
Listing 13.5. Setting the Position of the List Bullet or Number
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* lists-13.5.css */<br /><br />ol { list-style-type: upper-roman;<br />list-style-position: inside; }<br /><br />li { border: 1px solid black; margin: 2px; }<br />ul { list-style-type: square;<br />list-style-image: url("yellowplus.gif");<br />list-style-position: outside; }<br />ul ul { list-style-type: circle;<br />list-style-position: inside; }<br /><br />#nav a { display: list-item;<br />list-style-position: inside;<br />list-style-type: square;<br />list-style-image: url("yellowplus.gif");<br />border: 1px solid black; margin: 2px; }<br /></pre></div><br />
|}
The repositioned markers are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13fig06 Figure 13.6].
<div style="text-align: center;"> Figure 13.6. List positioning shown by outline boxes. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/13fig06_alt.jpg [View full size image]]</div>[[Image:13fig06.jpg|500px]] </div>
The <code>list-style</code> Shorthand Property
Like other shorthand properties, the <code>list-style</code> property lets you set multiple CSS properties at once. A <code>list-style</code> rule is written like the following:
<div><pre>selector { list-style: type position image; }
</pre></div>
The values for <code>type, position</code>, and <code>image</code> can appear in any order; any values that aren't specified are set to their default values. For example, to set the image to <code>yellowplus.gif</code>, the bullet type to <code>square</code>, and the position to <code>inside</code>, you can use the following rule:
<div><pre>ul li {
list-style: url("yellowplus.gif") square inside;
}
</pre></div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Further To-Do List Styling
Let's apply what you've learned to further enhance your list of items that need to be done:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>If you haven't done so already, create an HTML file with your to-do list in an ordered list (<code><ol></code>).<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>For each item, set a <code>class</code> attributeeither <code>pending</code> or <code>done</code>.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Create two separate graphics, or download them from the Web, to represent <code>pending</code> and <code>done</code>. I like a simple empty square box for <code>pending</code>, and the same box with a check mark for <code>done</code>.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Set a <code>list-style</code> rule that uses your graphics. Be sure to include default values for the marker type if the graphic isn't available, and adjust the location if you need to.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Load your HTML page in a web browser and change the style rules until you're happy. You can add additional rules that aren't related to <code>list-style</code> properties, of course: Do you want to put pending items in bold, or use a strikethrough text effect on completed items? It's your to-do liststyle it the way you'd like!<br /><br /></div>
|}
|}
./ ADD NAME=CH13LEV1SEC2.HTML
Summary
HTML defines three types of lists: ordered lists, unordered lists, and definition lists. Ordered and unordered lists contain <code>list-item</code> elements, which are a special type of <code>block</code> content.
Any HTML element with the CSS property display set to <code>list-item</code>including <code><li></code> tags, thanks to browsers' default style sheetswill generate a virtual marker box. This marker box contains a marker of some kind; ordered lists have number markers and unordered lists have bullets.
The type of marker can be set with the <code>list-style-type</code> property; a variety of number schemes and bullet types are available. Bullet images can also be used with the <code>list-style-image</code> property. The location of the marker box is set with the <code>list-style-location</code> property. All these properties can be set at once with the <code>list-style</code> shorthand property.
./ ADD NAME=CH13LEV1SEC3.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa1q1a1 Q.]'''
| How do I set styles on definition lists? You've mostly talked about <code><ol></code> and <code><ul></code>, not <code><dl></code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa1q1 A.]'''
| That's because from the CSS perspective, definition lists aren't lists at all! They're simply <code>block</code> content, not <code>list-item</code> elements. That means that you can just create style rules for <code><dl></code>, <code><dt></code>, and <code><dd></code> normally, as you would for any block elements. I personally like to do the following:
<div><pre>dt { font-weight: bold; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa1q2a2 Q.]'''
| How do I use CSS to set the starting values for ordered lists?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa1q2 A.]'''
| Unfortunately, you can't set those with CSS. To set specific number values for ordered lists, you need to use the HTML <code>start</code> attribute on the <code><ol></code> element or the <code>value</code> attribute on <code><li></code>. Both these values are deprecated in HTML 4.01, which means you can't use them in Strict HTML documents.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q1a1 1.]'''
| Which of these rules will make an ordered list count in lower-case letters?
<div># <div><code>ol { list-style-type: alphabet; }</code></div>
# <div><code>ol { list-style-type: lower-case; }</code></div>
# <div><code>ol { list-style-type: lower-letters; }</code></div>
# <div><code>ol { list-style-type: lower-alpha; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q2a2 2.]'''
| Assuming the following style rules, what color will the numbers before a list item be?
<div><pre>ol { color: green; }<br />ol li { color: blue; }<br />li { color: black; }<br />ol li span { color: red; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q3a3 3.]'''
| You want your bullet list items to be marked by a graphic, <code>bullet01.jpg</code>, which looks like a small box. You also want the graphic to be placed inside the list item's display box. How do you write this with the <code>list-style</code> shorthand property?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q1 1.]'''
| The correct answer is (d); the <code>lower-alpha</code> value orders list items with a, b, c, and so on.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q2 2.]'''
| The numbers will be the same color as the <code><li></code>; in this case, that color is <code>blue</code>. (If you think it's <code>black</code>, you're forgetting that the second rule is more specific than the first in cascade order.)
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch13qa2q3 3.]'''
| Here's one way to write such a rule:
<div><pre>ul { list-style: square inside url("bullet01.jpg"); }<br /></pre></div><br />
|}
Exercises
Some projects you can undertake to investigate list styles on your own include the following:
* Build an outline using <code><ol></code> and <code>list-style-type</code> properties. Adjust the margins and padding to suit taste.
* Design several list bullet graphics for your web pages, and add these using the <code>list-style-image</code> property. Which kinds of bullets are best at capturing the user's attention?
* Create a navigation bar on a web page, consisting of <code><a></code> links not grouped in a list. Use <code>display: list-item</code> to change the <code><a></code> links to a list, then add two types of list bulletsone for unvisited links, one for visited links.
./ ADD NAME=CH14.HTML
5depq07qikq8x2u84qxktubw0wjstse
User:Bartlett/14
2
2118
39224
5518
2026-04-13T06:03:20Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39224
wikitext
text/x-wiki
./ ADD NAME=CH14.HTML
Hour 14. Forms
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* The structure of HTML forms and how they interact with CSS rules
* How to style labels, field sets, and legends
* How to style text input fields
* How to style Submit and Reset buttons
* How to style check boxes and radio buttons
* How to style pull-down selectors and selection lists
* Which style properties are supported for HTML form elements
The HTML language provides a <code><form></code> element that can be used to gather information interactively from the user, either for submission to the web server or for processing with JavaScript. These forms can be styled with CSS rules, although variable browser support makes it an uncertain proposition. In this hour, you'll learn about which types of styles are supported for forms and which are not.
|}
./ ADD NAME=CH14LEV1SEC1.HTML
=== Styling Form Controls ===
You create a form in HTML by using the <code><form></code> element. Between the <code><form></code> and <code></form></code> tags, you put the HTML that will comprise the form. This consists of normal markup and content, plus form controls and other HTML tags used specifically for creating forms.
Form controls are the interactive portions of the form that let the user enter data for processing on the server or in the browser via JavaScript (or another browser-side language). Examples include text input boxes, check boxes, Submit buttons, and pull-down menus. Other tags that are used with forms designate labels for form elements or group them together in identified sets. Such labels are beneficial for users with disabilities who employ assistive technologies for web access, as well as make your forms easier for everyone to use.
<div>Did you Know?
If you aren't familiar with the HTML tags for forms, you can learn more by reading Sams Teach Yourself Web Publishing with HTML and CSS in One Hour a Day; ISBN: 0672328860, 5th Edition.</div>
The full list of form controls and markup for labels is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14table01 Table 14.1]. The <code><input></code> tag alone can be used to create 10 different types of form controls; the specific control created depends on the <code>type</code> attribute.
{| cellspacing="0" cellpadding="5"|+ Table 14.1. Form Controls and Label Markup
|-
| HTML Tag
| Function
|-
| <code><button></code>
| Creates a Reset, Submit, or other programmable pushbutton
|-
| <code><fieldset></code>
| Groups related form controls
|-
| <code><input type="button"></code>
| Creates a programmable push button
|-
| <code><input type="checkbox"></code>
| Creates a check box
|-
| <code><input type="file"></code>
| Selects a file from the user's computer system for uploading
|-
| <code><input type="hidden"></code>
| Creates a hidden field
|-
| <code><input type="image"></code>
| Creates a Submit button from an image
|-
| <code><input type="password"></code>
| Creates a single-line text field with obscured input
|-
| <code><input type="radio"></code>
| Creates one in a set of radio buttons
|-
| <code><input type="reset"></code>
| Creates a Reset button
|-
| <code><input type="submit"></code>
| Creates a Submit button
|-
| <code><input type="text"></code>
| Creates a single-line text field
|-
| <code><label></code>
| Provides a text label for a form control
|-
| <code><legend></code>
| Provides a text label for a <code><fieldset></code>
|-
| <code><optgroup></code>
| Groups related <code><option></code> elements together
|-
| <code><option></code>
| Designates one choice in a <code><select></code> menu
|-
| <code><select></code>
| Creates a pull-down menu or scrollable section menu
|-
| <code><textarea></code>
| Creates a multi-line text input box
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1] is an example of an HTML form that shows off a number of different form controls. This is part of a hypothetical e-commerce system that enables the user to add a note card to what she's bought from the site. As with most examples, this is a bit contrived, but the purpose is to demonstrate how styles can be applied to HTML forms.
Listing 14.1. An HTML Form
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- form-14.1.html --><br /><html><br /><head><br /><title>Include a Note Card</title><br /></head><br /><body><br /><h1>Include a Note Card</h1><br /><form method="post" action="placeholder.php"><br /><p><label><input type="checkbox" id="gift" name="gift"<br />value="1"><br />Check this box if your order is a gift</label></p><br /><p><label for="sendername">Sender's Name:</label><br /><input type="text" name="sendername"<br />value="Your Name Here"<br />size="40" id="sendername"></p><br /><fieldset id="papercolorfieldset"><br /><legend>Color of Paper:</legend><br /><label><input type="radio" name="papercolor"<br />id="papercolorblue" value="blue"><br />Blue</label><br /><label><input type="radio" name="papercolor"<br />id="papercolorpink" value="pink"><br />Pink</label><br /><label><input type="radio" name="papercolor"<br />checked="checked"<br />id="papercolorwhite" value="white"><br />White</label><br /></fieldset><br /><p><label for="inkcolor">Ink Color:</label><br /><select name="inkcolor" id="inkcolor"><br /><option selected value="black">Black</option><br /><option value="navy">Navy Blue</option><br /><option value="maroon">Maroon</option><br /><option value="green">Green</option><br /><option value="gray">Gray</option><br /><option value="red">Red</option><br /></select></p><br /><p><label for="message">Card Message:<br /></label><br /><textarea id="message" name="message" rows="4"<br />cols="40">Type your message here.</textarea></p><br /><p><label for="font">Choose a Font:</label><br /><select name="font" id="font" size="4"><br /><option selected value="TimesNewRoman"><br />Times New Roman</option><br /><option value="Optima">Optima</option><br /><option value="Verdana">Verdana</option><br /><option value="Papyrus">Papyrus</option><br /><option value="MarkerFelt">Marker Felt</option><br /><option value="Arial">Arial</option><br /><option value="CourierNew">Courier New</option><br /></select></p><br /><p><button type="button" id="backbutton"<br />name="backbutton">⇐ Go Back</button><br /><input type="submit" id="submitbutton"<br />name="submitbutton" value="Submit Form"><br /><input type="reset" id="resetbutton"<br />name="resetbutton" value="Reset Form"></p><br /></form><br /></body><br /></html><br /></pre></div><br />
|}
Without styles, this is a rather boring form, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig01 Figure 14.1]. Have no fear; it can be improved with CSS.
<div style="text-align: center;"> Figure 14.1. Firefox displays the HTML form with default styles. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig01_alt.jpg [View full size image]]</div>[[Image:14fig01.jpg|500px]] </div>
Labels, Fieldsets, and Legends
The labels for form elements are the easiest to style; they're not even form controls, just normal HTML blocks. The <code><label></code> tag, for labeling individual form controls, is an inline element and can be styled like any other inline element. The <code><fieldset></code> tag is a block element, used to group together related elements (such as a group of radio buttons), and the <code><legend></code> element serves as a label for a <code><fieldset></code>. These are shown by example in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1]. As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig01 Figure 14.1], the <code><fieldset></code> tag creates a border around the form controls it encloses, and <code><legend></code> is set as an introductory header. This styling convention isn't specified in the standards, but is ubiquitous in modern browsers.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2] is a style sheet that adds rules specifically to style the <code><label></code>, <code><fieldset></code>, and <code><legend></code> elements, as well as adding a border and font to the entire <code><form></code>.
<div>By the Way
This hour's style sheets demonstrate some style properties that you haven't learned yet, if you're reading this book in sequential order. You'll learn about <code>float</code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment"; padding, margin, and border properties in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes"; and width and height in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], "Box Sizing and Offset."</div>
Listing 14.2. A Style Sheet for Form Labels
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* labels-14.2.css */<br /><br />form { padding:0 0.5em;<br />margin: 0 0.5em;<br />border: 1px solid black;<br />font-family: Arial, sans-serif; }<br /><br />label { border: 1px dotted gray;<br />background-color: silver; }<br />label[for] { border: none; background-color: inherit;<br />float: left; width: 25%; }<br /><br />fieldset { margin-left: 25%; width: 60%; padding: 0; }<br />legend { color: white; background-color: black; }<br /></pre></div><br />
|}
<div>Watch Out!
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2], and the rest of the style sheets in this hour, use attribute value selectors, which were introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors." Internet Explorer version 6.0 (and earlier) does not support attribute value selectors; to support these styles in Internet Explorer, you need to add additional <code>class</code> or <code>id</code> selectors. The examples in this hour omit these additional selectors to make it clear which form controls are being styled. You can download the versions that work with Internet Explorer 6 from the book's website.</div>
Linking the style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2] to the HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1] produces the effect shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig02 Figure 14.2]. You can use any styles with <code><form></code>, <code><label></code>, <code><fieldset></code>, or <code><legend></code> that you can use with any normal box elements in HTML, and this is well supported by the web browsers.
<div style="text-align: center;"> Figure 14.2. Borders, margins, and backgrounds are added to form labels. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig02_alt.jpg [View full size image]]</div>[[Image:14fig02.jpg|500px]] </div>
Text Input Fields
Text boxes are created by the <code><input type="text"></code> tag or by the <code><textarea></code> tag. The <code><input type="password"></code> tag creates a text box as well; any letters typed in it are shown as asterisks but are stored by the browser as data.
You can set the font, text color, and background color on a text box. Most browsers default to a white background with black text for text boxes, with <code><input type="text"></code> displaying in a serif font, and <code><textarea></code> in monospace (as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig01 Figure 14.1]), but there are no hard and fast rules. Your CSS rules can override these browser defaults.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex03 Listing 14.3] is a style sheet with rules for text fields.
Listing 14.3. Style Rules for Text Input Fields
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* textboxes-14.3.css */<br /><br />input[type="text"]<br />{ font-size: x-large; background-color: yellow;<br />font-variant: small-caps;<br />color: maroon; width: 60%;<br />padding-left: 1em; padding-right: 1em;<br />font-family: "Courier New", monospace; }<br /><br />textarea { font-family: cursive; width: 60%;<br />color: white; background-color: navy; }<br /></pre></div><br />
|}
The style sheet also sets the <code>padding</code> and the text box <code>width</code> in one rule. In general, dimensions can be set reliably, but other box values (<code>padding, margin</code>, and <code>border</code>) are less reliable because of browser differences.
The results of applying this style sheet to the form in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1] are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig03 Figure 14.3]. The label style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2] was also applied, because it makes the form look a little more tidy.
<div style="text-align: center;"> Figure 14.3. Colors and fonts can be set on text input fields. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig03_alt.jpg [View full size image]]</div>[[Image:14fig03.jpg|500px]] </div>
Buttons
A button in an HTML form does one of three things: submits, resets, or is a programmable button called a "push" button. A Submit button, when clicked by the user, sends the form data to the server. A Reset button restores the form to its original state, with fields that are either blank or preset to a default value by the form designer. A pushbutton has no predefined action associated with it; a JavaScript action needs to be attached to make the button do anything. See Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch01.html#ch01 Hour 1], "CSS and JavaScript," for more on the JavaScript language.
A button is created by the <code><input></code> tag or the <code><button></code> tag. There are three buttons in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1], one of each type: Submit, Reset, and a programmable push button the "Go Back" button which, on a real form, could be tied to a JavaScript function. The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex04 Listing 14.4] sets CSS values on these buttons.
Listing 14.4. Rules for Styling Form Buttons
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* buttons-14.4.css */<br />input[type="submit"]<br />{ font-style: oblique;<br />background-color: navy; color: white;<br />padding-left: 2em; padding-right: 2em; }<br />input[type="reset"]<br />{ font-family: cursive; background-color: white;<br />border: 3px solid blue; color: red;<br />margin-left: 25%; width: 300px; }<br />button { border-style: inset;<br />border-color: green;<br />padding: 10px; color: green; }<br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig04 Figure 14.4] shows the style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex04 Listing 14.4] applied to the HTML form in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1], as well as the label styles from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2].
<div style="text-align: center;"> Figure 14.4. Each button has been styled separately. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig04_alt.jpg [View full size image]]</div>[[Image:14fig04.jpg|500px]] </div>
Check Boxes
A check box in HTML is created by the <code><input type="checkbox"></code> tag, and is a simple binary switch: It is either off or on, like a light switch. Browsers display check boxes as square boxes that can be clicked, and when clicked, an "X" or a check mark appears in the box.
A radio button is one of a set of form controls that share the same name attribute, created by <code><input type="radio"></code>. Only one radio button in a set can be checked at a time; selecting a new value deselects the previous setting. This is analogous to old-time analog car radios, which had push buttons that caused the tuner to jump to a new value. Browsers display radio buttons as circles with a dark dot in the selected value.
The <code><label></code> tag is used to provide a label for each type of check box. It can be either wrapped around a check box by containing the <code><input></code> tag that defines the check box, or set next to it with a <code>for</code> attribute designating which form control it labels. A set of radio buttons can be wrapped in a <code><fieldset></code> tag to group the <code><input></code> tags with an appropriate <code><legend></code> label.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex05 Listing 14.5] is a style sheet that provides some style rules for the HTML form's check boxes.
Listing 14.5. A Style Sheet That Styles Check Boxes
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* checkradio-14.5.css */<br />input[type="checkbox"]<br />{ background-color: blue;<br />color: yellow;<br />font-size: xx-large;<br />width: 50px; border-style: solid; }<br />input[type="radio"]<br />{ background-color: lime;<br />color: orange;<br />font-size: small; }<br />input[checked]<br />{ color: black; background-color: silver;<br />width: 50px; }<br /></pre></div><br />
|}
You can see the results of linking this style sheet (and the label styles from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2]) to the HTML form in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1] in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig05 Figure 14.5]. As you can see, most of the rules, such as the font-size and the color rules, have had almost no effect. The <code>width</code> rule has stretched out the check box and radio button, however. As you'll see later in this hour, Firefox is the only browser that does this; other browsers reserve more room for the check box, but leave the actual check box the same.
<div style="text-align: center;"> Figure 14.5. The effects of styling a check box are minimal, as seen in Firefox. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig05_alt.jpg [View full size image]]</div>[[Image:14fig05.jpg|500px]] </div>
Directly styling a check box or radio button is not very useful because most browsers ignore such attempts. It is better to apply styles to the labels surrounding the check boxes.
Selection Lists
You form a selection list by wrapping the <code><select></code> tag around one or more <code><option></code> tags. If no <code>size</code> property is given, the selection list will be a pull-down list; if a <code>size</code> value is given, it will be a scrollable list showing as many lines as indicated by the <code>size</code>.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex06 Listing 14.6] is a style sheet that gives a width to the two <code><select></code> tags in the example form, as well as setting various properties on the <code><option></code> elements.
Listing 14.6. Style Rules for Changing Selection List Options
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* select-14.6.css */<br />select { width: 60%; }<br />#inkcolor option { color: white; }<br />option[value="black"] { background-color: black; }<br />option[value="navy"] { background-color: navy; }<br />option[value="maroon"] { background-color: maroon; }<br />option[value="green"] { background-color: green; }<br />option[value="gray"] { background-color: gray; }<br />option[value="red"] { background-color: red; }<br />#font { border: none; background-color: silver;<br />padding: 1em 15%; height: 100px; }<br />#font option<br />{ text-align: center; border: 1px solid black;<br />margin: 3px 0; font-size: large;<br />background-color: white; }<br />option[value="TimesNewRoman"]<br />{ font-family: "Times New Roman", serif; }<br />option[value="Optima"]<br />{ font-family: Optima, sans-serif; }<br />option[value="Verdana"]<br />{ font-family: Verdana, sans-serif; }<br />option[value="Papyrus"]<br />{ font-family: Papyrus, fantasy; }<br />option[value="MarkerFelt"]<br />{ font-family: "Marker Felt", cursive; }<br />option[value="Arial"]<br />{ font-famiy: Arial, sans-serif; }<br />option[value="CourierNew"]<br />{ font-family: "Courier New", sans-serif; }<br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig06 Figure 14.6] shows [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex06 Listing 14.6] (and [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex02 Listing 14.2]) applied to the HTML form in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14ex01 Listing 14.1]. As you can see, the fonts and colors specified are used, as well as the box properties (padding, margins, borders) in the second <code><select></code> that sets the font choices.
<div style="text-align: center;"> Figure 14.6. The selection options appear in different colors and fonts. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig06_alt.jpg [View full size image]]</div>[[Image:14fig06.jpg|500px]] </div>
Although this is a very neat effect, don't get too excited about it. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig06 Figure 14.6] was created with Firefox, which is the only browser to support restyling selection lists in this manner, as you'll see later this hour. Applying styles to <code><option></code> elements is fun, but not reliable.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Styling a Simple Email Form
Create your own form to apply style rules and find out which your browsers fully support. Follow these steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create an HTML file in your text editor or web development software.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Add a form tag like this, but with your own email address:<br /><br /><div><pre><form action="mailto:kynn@example.com"><br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Create a text input field in which the user can enter her email address, a pull-down menu for choosing a subject category, and a text area for a message. Make sure you include <code><label></code> tags for the field labels as well.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Include a button for submitting the form, and don't forget to close the form with a <code></form></code> tag.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Now create a style sheet for the form. Set your default styles such as the font and colors first.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>Add styles for the text input field. Select colors and fonts that are pleasing.<br /><br /></div>
|-
| <div>'''7. '''</div>
| <div>Similarly, write style rules for the text area; add a background color and change the font if you wish.<br /><br /></div>
|-
| <div>'''8. '''</div>
| <div>Provide style rules for the pull-down menu as well. Not all browsers support these rules, so don't be too disappointed if they don't show up.<br /><br /></div>
|-
| <div>'''9. '''</div>
| <div>View the form in your web browser, with the style sheet unlinked, then link it in. How does it look to you?<br /><br /></div>
|}
|}
./ ADD NAME=CH14LEV1SEC2.HTML
=== Browser Support for Form Styles ===
As noted earlier in this hour, browsers don't reliably style form elements in the same way, making certain stylesespecially on check boxes and selection listsvery hitand-miss in actual practice. Why is this?
The CSS specifications themselves are conspicuously silent on the issue of styling form controls. Form controls are considered part of the browser's user interface (UI), not actual content for manipulation by CSS rules. The way buttons, check boxes, and pull-down lists are displayed depends on the browser's UI scheme, which is based on the operating system's user interface. For example, the figures in this chapter were primarily shot on a computer running Mac OS X. If you are using a Windows computer, the appearance, shape, and size of your Submit button will look appropriate for your system, and not like those in the book.
This means that form controls fall into a no-man's-land in the specification; it is up to the browser programmers to decide to what extent the form controls can be reshaped with CSS. Each browser company has chosen a different solution, which makes form element styling inconsistent from browser to browser.
Firefox
Firefox (and any other Gecko-based browser) supports styling for most form controls, as seen earlier in this hour, with the exception of check boxes, which are minimally styled. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig07 Figure 14.7] shows the results of applying all five style sheets in this hour to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14lev1sec1.html#ch14ex01 Listing 14.1].
<div style="text-align: center;"> Figure 14.7. Firefox displaying all form styles. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig07_alt.jpg [View full size image]]</div>[[Image:14fig07.jpg|500px]] </div>
Opera
Opera is the only browser to allow extensive styling of check boxes; the <code>color, background-color</code>, and <code>border</code> properties are applied correctly, and the check box is not stretched out. However, Opera (as of version 8.5) doesn't allow restyling of selection boxes. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig08 Figure 14.8] shows all five style sheets linked to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14lev1sec1.html#ch14ex01 Listing 14.1]. Compare this with [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig07 Figure 14.7]; the font-variant and padding properties for the text input box aren't respected. (The <code><textarea></code> box is styled correctly, though, even though you can't see it in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig08 Figure 14.8] because of the pull-down menu.)
<div style="text-align: center;"> Figure 14.8. All form style sheets, shown by Opera. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig08_alt.jpg [View full size image]]</div>[[Image:14fig08.jpg|500px]] </div>
Safari
Safari's take on the five style sheets is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig09 Figure 14.9]. Space is reserved for check boxes with <code>width</code> set, but they're not stretched as in Firefox. Note that only the button created with <code><button></code> is styled; the submit and reset button are unchanged. As with Opera, neither <code><select></code> menu is styled.
<div style="text-align: center;"> Figure 14.9. Form styles displayed by Safari. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig09_alt.jpg [View full size image]]</div>[[Image:14fig09.jpg|500px]] </div>
Internet Explorer
Internet Explorer 6 applies the fewest style rules from the five style sheets, as you can see in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig10 Figure 14.10]. Style rules are applied to the <code><textarea></code> box, but not the simple text box created by <code><input></code>. The width properties on the check boxes are ignored, and the styles for <code><select></code> menus aren't used. You can't add many styles to your forms in Internet Explorer 6.
<div style="text-align: center;"> Figure 14.10. Internet Explorer attempts to display form styles. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/14fig10_alt.jpg [View full size image]]</div>[[Image:14fig10.jpg|500px]] </div>
<div>By the Way
The screenshot in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig10 Figure 14.10] was taken after ID values were added to the HTML in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14lev1sec1.html#ch14ex01 Listing 14.1], and additional ID selectors in the five style sheets given this hour, as noted earlier.</div>
<div>Watch Out!
You can use CSS rules to produce some very extensive changes in the appearance of form controls. On browsers supporting specific form styles, you can drastically change the appearance of Submit buttons, of selection lists, and other aspects of the HTML form elements. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig10 Figure 14.10] is vivid example of this.
But just because you can do something, that doesn't mean you should do it. Your web page visitors are used to standard forms, with the Submit and Reset buttons at the bottom of the form and the text input fields displayed in a standard font. The more changes you make with CSS rules to the appearance of your form, the more likely you are to throw off your users. When styling your form elements, don't confuse your users by going against their expectations unnecessarily. Use moderation and care when styling forms, and try to avoid making your form look anything like the demonstration form in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14fig10 Figure 14.10]!</div>
./ ADD NAME=CH14LEV1SEC3.HTML
Summary
CSS rules can be written to style form elements, but the results of these rules are very browser dependent. Some browsers allow extensive restyling of form elements, whereas others are very restrictive.
Form labels can be styled easily because they are treated like any other HTML box element. Text input elements can be styled in most browsers; all modern browsers support fonts, colors, and background colors for <code><textarea></code>.
Buttons created with the <code><button></code> tag can be styled in all browsers; however, Submit and Reset buttons created with <code><input></code> are less consistent. Check box styles are ignored by most browsers, and only Firefox allows restyling of selection menu options.
./ ADD NAME=CH14LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa1q1a1 Q.]'''
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14lev1sec1.html#ch14ex05 Listing 14.5] has a style rule for a checked radio button. Does this change the style dynamically if you select another radio button?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa1q1 A.]'''
| Nope. Browsers unfortunately don't work that way with HTML forms and CSS. To get that type of dynamic effect, try using JavaScript, as described in Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch01.html#ch01 Hour 1].
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa1q2a2 Q.]'''
| What's a <code>⇐</code> anyway? You use it in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14lev1sec1.html#ch14ex01 Listing 14.1] but it shows up as a little rectangle in half the browsers.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa1q2 A.]'''
| The double left arrow symbol is represented in HTML by the <code>⇐</code> entity, and is part of HTML 4.01. A few browsers don't fully support all HTML entities, because they are naughty, naughty browsers. You can use the <code>←</code> (left arrow) entity, which is better supported, or just leave it out of your web designs.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q1a1 1.]'''
| Which of the following tags does not create a submit button?
<div># <div><code><submit value="Send it!"></code></div>
# <div><code><input type="submit" value="Sent" it!"></code></div>
# <div><code><input type="image" src="submit.gif" alt="Send it!"></code></div>
# <div><code><button type="submit">Send it!</button></code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q2a2 2.]'''
| You want to put a dotted, silver line under all form labels that enclose their associated form controls. You don't want any underlines on form labels that use <code>for</code> attributes to associate the label with the form control. How do you write this rule?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q3a3 3.]'''
| Which statements about browser support for form styling are true?
<div># <div>Only one browser lets you style selection list values separately.</div>
# <div>Internet Explorer 6 has good support for form styles.</div>
# <div>Most browsers ignore style rules relating to check boxes.</div>
# <div>Labels and legends are hard to style in CSS.</div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q1 1.]'''
| (a). There is no <code><submit></code> tag in HTML. The others all create Submit buttons.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q2 2.]'''
| Here is one way you could do this, using two rules:
<div><pre>label { border-bottom: 1px dotted silver;}<br />label[for] { border-bottom: none; }<br /></pre></div><br />
Remember that this won't work in Internet Explorer 6, which doesn't recognize attribute value selectors. All your labels will be underlined in Internet Explorer.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch14qa2q3 3.]'''
| Statements (a) and (c) are true, and statements (b) and (d) are false.
|}
Exercise
You are now able to add styles to your HTML forms. To get a better grasp on the browser support issues, create several different types of forms, and add styles to the labels, the text areas, and the form controls such as buttons and check boxes. Which styles not covered in this hour work reliably with each of these types of form elements? Build your forms in a way that the CSS enhances the usefulness for your website visitors.
./ ADD NAME=CH15.HTML
p24j4j5dnpmbyybr626hg5v94ba0jni
User:Bartlett/15
2
2119
39225
5519
2026-04-13T06:03:21Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39225
wikitext
text/x-wiki
./ ADD NAME=CH15.HTML
Hour 15. Alignment
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* How to align, justify, and center content with CSS
* How to indent paragraphs and other HTML elements
* How to make text that rises above or sinks below the rest of the text, such as subscripts or superscripts
* How to float an element on the right or left side so that subsequent content wraps around it
Control over text formatting enables you to replace many HTML tags with CSS rules. Effects that were previously available only as presentational markup attributes are part of the Cascading Style Sheets specification and can help you separate presentation from content.
|}
./ ADD NAME=CH15LEV1SEC1.HTML
=== Aligning and Indenting Text ===
The alignment of text defines the way in which the text lines up with the left or right margins. Most things you read (including this book) are left aligned; left-aligned text is generally easier to read. Centered text is often used on headlines, but it is rarely used on blocks of text because both margins are irregular and jagged, and experienced designers usually reserve right-aligned text for special text effects.
An indent is the extra space at the start of a line that lets you know you're on a new paragraph. In web design, new paragraphs are more commonly indicated by extra spacing than by indented text, although you are free to combine both if it suits your needs.
CSS properties enable you to control both the alignment and the indentation, setting them to whatever values you like on HTML block elements.
The <code>text-align</code> Property
Alignment of text inside a block property is controlled by the <code>text-align</code> property. This property has meaning only on block boxes; the content of inline boxes has no alignment, although the inline boxes themselves are aligned within the surrounding box. The block box itself is not actually positioned; only the content inside the box is aligned. To position the box itself, rather than its content, use either the margin properties you'll learn in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes," or the positioning properties you'll learn in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], "Absolute and Fixed Positioning."
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15table01 Table 15.1] shows the values you can assign to the <code>text-align</code> property; the default value is <code>left</code>. The <code>text-align</code> property is inherited, so you can use a single <code><div></code> or even a rule on the <code><body></code> to center an entire page. There's one exception; for backwards compatibility, browsers usually have a default rule that sets <code>text-align: left</code> for <code><td></code> tags and <code>text-align: center</code> for <code><th></code> tags. Keep this in mind when using tables, especially if you use them for layout.
{| cellspacing="0" cellpadding="5"|+ Table 15.1. Values for the <code>text-align</code> Property
|-
| Value
| Effect
|-
| <code>center</code>
| Center the content.
|-
| <code>justify</code>
| Justify text on both sides.
|-
| <code>left</code>
| Align content on the left.
|-
| <code>right</code>
| Align content on the right.
|-
| <code>inherit</code>
| Use the value of <code>text-align</code> from the containing box.
|}
Text that is justified is printed so that both the left and right sides line up; browsers accomplish this by adding extra spaces between words and letters. The last line of a justified paragraph is usually left aligned, if it's too short to fill an entire line by itself.
A simple HTML page with embedded style sheet that uses <code>text-align</code> is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex01 Listing 15.1]; the style rules result in the effects shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig01 Figure 15.1]. Borders have been added to the paragraph boxes to make it easier to see how the text aligns with the edges of the boxes.
Listing 15.1. CSS for Alignment
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- imgtip-15.1.html --><br /><html><br /><head><br /><title>Image Accessibility</title><br /><style type="text/css"><br />body { font-family: Arial, sans-serif; }<br />p { border: 1px solid #333333;<br />padding: 0.5em; }<br />p#a { text-align: left; }<br />p#b { text-align: justify; }<br />p#c { text-align: center; }<br />p#d { text-align: right; }<br /></style><br /></head><br /><body><br /><p id="a"><br />Always include an <code>alt</code> attribute on your<br /><code><img></code> tag.<br />The <code>alt</code> attribute should contain a short<br />replacement for the graphic, in text. If the image<br />itself has text, list that in <code>alt</code>.<br />If the image is purely decorative and doesn't convey<br />any additional information, use <code>alt=""</code>.<br />If there is more information in the graphic than you<br />can convey in a short <code>alt</code> attribute, such<br />as the information in a graph or chart, then use<br />the <code>longdesc</code> attribute to give the URL of<br />a page that describes the graphic in text.<br /></p><br /><p id="b"><br />...<br /><!-- repeat of the previous paragraph --><br /></p><br /><p id="c"><br />...<br /></p><br /><p id="d"><br />...<br /></p><br /></body><br /></html><br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 15.1. Lining up margins with CSS. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig01_alt.jpg [View full size image]]</div>[[Image:15fig01.jpg|500px]] </div>
The <code>text-indent</code> Property
Although it's most commonly used on <code><p></code> tags, the <code>text-indent</code> property can be set on any block element in HTML. (It has no effect if applied to an inline tag.) The effect produced by this property is indentation of the first line of the element, resulting from an added blank space. This blank space is treated similarly to the <code>padding</code> of the displayed box: It is inside the <code>margin</code> and <code>border</code> of the box, and it is colored with the same <code>background-color</code> as the element content.
The values for <code>text-indent</code> are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15table02 Table 15.2]; in summary, you can either give a measurement value, such as <code>3em</code> and <code>10px</code>, or a percentage value based on the size of the containing box. The default indentation is <code>0px</code>. The value of <code>text-indent</code> is inherited by all children elements, but keep in mind that it has no effect on inline elements, only block elements that inherit the value.
{| cellspacing="0" cellpadding="5"|+ Table 15.2. Values for the <code>text-indent</code> Property
|-
| Value
| Effect
|-
| <code>measurement</code>
| Sets an indent.
|-
| <code>negative measurement</code>
| Sets a hanging indent.
|-
| <code>percentage</code>
| Sets an indent based on a fraction of the containing box.
|-
| <code>inherit</code>
| Use the value of <code>text-indent</code> from the containing box.
|}
The simplest indentations are the most straightforward; here's a rule to indent all paragraphs by 3ems:
<div><pre>p { text-indent: 3em; }
</pre></div>
It gets a little trickier if you want to make a hanging indentone where the first line is not actually indented but the other lines of the text are indented. To do this, you can give a negative measurement, but it then flows off the left side of the element's box, which means it may not be visible or may overwrite other content.
The best solution is to add a <code>margin</code> to the box, which indents all the text except for that initial line, which subtracts its value from the <code>margin</code>. Here's an example, which creates a <code>2.8em</code> hanging indent:
<div><pre>p { text-indent: -2.8em;
margin-left: 3em; }
</pre></div>
<div>By the Way
This example used the <code>margin-left</code> property, which sets the <code>margin</code> for just the left side of the box. You'll learn about this and other properties that affect only one side of the box in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16].</div>
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex02 Listing 15.2] uses several different ways to set indents. Replacing the embedded style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex01 Listing 15.1] with the style sheet in this listing produces the effects shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig02 Figure 15.2]. The border on the fourth box shows how the hanging indent actually extends outside the paragraph element's display box. In practice, when using hanging indents you should avoid using borders or backgrounds on those elements; wrap them in a <code><div></code> and style instead to get the appropriate border or background effect.
Listing 15.2. Style Sheet with Several Different <code>text-indent</code> Values
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>body { font-family: Arial, sans-serif; }<br />p { border: 1px solid #333333;<br />padding: 0.5em; }<br />p#a { text-indent: 25px; }<br />p#b { text-indent: 75%; }<br />p#c { text-indent: 3em; }<br />p#d { text-indent: -3em;<br />margin-left: 3em; }<br /></pre></div><br />
|}
<div style="text-align: center;"> Figure 15.2. Various types of indentations. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig02_alt.jpg [View full size image]]</div>[[Image:15fig02.jpg|500px]] </div>
<div>Did you Know?
There is no value none for <code>text-indent; text-indent</code> only takes measurements (or <code>inherit</code>) as values. To set indentation to "none" use <code>text-indent: 0</code>.</div>
The <code>vertical-align</code> Property
The property <code>vertical-align</code> is used to adjust vertical alignment within an inline box. This can be used to make text appear higher or lower compared with the rest of the text on the line; it's most useful for creating superscripts or subscripts. Superscripts are bits of text with the baseline above the surrounding text; subscripts have baselines lower than the surrounding text.
<div>Did you Know?
Except for table cells, only inline elements use the <code>vertical-align</code> property. The use of <code>vertical-align</code> with table cells is covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17], "Styling Tables."</div>
The types of values that can be set for the <code>vertical-align</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15table03 Table 15.3]. The default value is <code>baseline</code>, and any values set on containing boxes are not inherited.
{| cellspacing="0" cellpadding="5"|+ Table 15.3. Values for the <code>vertical-align</code> Property
|-
| Value
| Effect
|-
| <code>baseline</code>
| Align with the surrounding text.
|-
| <code>bottom</code>
| Align the bottom with bottom of line.
|-
| <code>middle</code>
| Align with the middle of the surrounding text.
|-
| <code>sub</code>
| Lower to subscript level.
|-
| <code>super</code>
| Raise to superscript level.
|-
| <code>text-top</code>
| Align with the top of surrounding text.
|-
| <code>text-bottom</code>
| Align with the bottom of surrounding text.
|-
| <code>top</code>
| Align the top with top of line.
|-
| <code>measurement</code>
| Raise above surrounding text.
|-
| <code>negative measurement</code>
| Lower below surrounding text.
|-
| <code>percentage</code>
| Raise as a percentage of the <code>line-height</code>.
|-
| <code>negative percentage</code>
| Lower as a percentage of the <code>line-height</code>.
|}
Several of these values require further explanation. The <code>middle</code> value aligns the middle of the text with a height that's <code>0.5ex</code> above the baseline of the surrounding text. An <code>ex</code> is a unit of measure equal to the height of a lowercase letter, usually about half the <code>font-size</code>. Percentages are based on the value of the <code>line-height</code>, which is usually equal to the <code>font-size</code>. The <code>top</code> and <code>bottom</code> values align with the highest and lowest parts of the line, whereas <code>text-top</code> and <code>text-bottom</code> are based only on the containing box's <code>font-size</code> values.
<div>Watch Out!
Browser implementation of <code>vertical-align</code> is highly variable and is dependent upon factors such as <code>font-size, ex</code> calculation, and others. The safest values for consistency's sake are <code>sub</code>, <code>super</code>, measurements, and percentages; fortunately, the others are not particularly useful most of the time, anyway.</div>
To create superscripts or subscripts, you use the <code>vertical-align</code> property, probably in combination with <code>font-size</code>; the <code>vertical-align</code> property doesn't affect the size of text, but most subscripts or superscripts are smaller than the surrounding text. Here are some example rules:
<div><pre>.atoms { vertical-align: -0.4em;
font-size: smaller; }
.power { vertical-align: super;
font-size: smaller; }
</pre></div>
You'd use these style rules in HTML by setting <code>class</code> attributes, like this:
<div><pre>H<span class="atoms">2</span>0
x<span class="power">2</span> - 1 = 63
</pre></div>
The effects of these styles can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig03 Figure 15.3]. You could also use the HTML Transitional elements <code><sub></code> and <code><sup></code> for the same effects, but CSS affords you more control over the specific presentation details.
<div style="text-align: center;"> Figure 15.3. Superscripts and subscripts in CSS.
[[Image:15fig03.jpg|300px]]
</div>
./ ADD NAME=CH15LEV1SEC2.HTML
=== Floating Content ===
Another way to align content is to float it. Floating boxes move to one side or another according to the value of the <code>float</code> property, and any following content flows around them in a liquid fashion. The <code>clear</code> property can be used to indicate when the rest of the content should stop flowing around the floating box.
This effect should be familiar to experienced HTML developers who have used the <code>align</code> attribute on <code><img></code> or <code><table></code> tags to position floating content on either side of the page layout. The <code>clear</code> attribute on the <code><br></code> tag has been used to control when the floating should end. The CSS properties <code>float</code> and <code>clear</code> can be used on any HTML elements and therefore greatly extend the types of content that can be set to float or to stop flowing.
An example of floating content can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig04 Figure 15.4]; the pull quote is positioned on the left, and the subsequent text content wraps around it on the right side and then flows back out to the full width when the quote ends.
<div style="text-align: center;"> Figure 15.4. Floating content to the left. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig04_alt.jpg [View full size image]]</div>[[Image:15fig04.jpg|500px]] </div>
Floating content is especially useful for pictures (with or without captions), pull quotes, and sidebar text.
The <code>float</code> Property
The values for the <code>float</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15table04 Table 15.4]; the default value is <code>none</code>, meaning that the box and subsequent content are laid out according to the normal flow.
{| cellspacing="0" cellpadding="5"|+ Table 15.4. Values for the <code>float</code> Property
|-
| Value
| Effect
|-
| <code>left</code>
| The box moves to the left, and text flows around the right side.
|-
| <code>none</code>
| The box doesn't move, and text is not flowed around it.
|-
| <code>right</code>
| The box moves to the right, and text flows around the left side.
|-
| <code>inherit</code>
| Use the <code>float</code> value of the containing box.
|}
When a box is floated, it is positioned within its containing box's content section. The floating box remains within the margin, border, and padding of its containing box; it simply moves to the right or left side as appropriate. Any subsequent content is placed alongside the floating box for the length of that box.
The source for the page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig04 Figure 15.4] is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex03 Listing 15.3].
Listing 15.3. An HTML File with a Pull Quote That Will Be Floated
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- pullquote-15.3.html --><br /><html><br /><head><br /><title>Accessibility of Color</title><br /><style type="text/css"><br />h1 { font-family: Verdana, sans-serif; }<br />p { font-size: large;<br />font-family: Arial, sans-serif;<br />line-spacing: 1.25; }<br />.pullquote<br />{ float: left;<br />font-family: Verdana, sans-serif;<br />text-indent: 0;<br />border: 5px solid black;<br />padding: 0.5em;<br />margin: 0.75em;<br />background-color: silver; }<br />.pullquote p<br />{ margin: 0; padding: 0; }<br />.pullquote blockquote<br />{ font-style: italic;<br />padding: 0; margin: 0; }<br />.pullquote img { float: left; }<br /></style><br /></head><br /><body><br /><h1>Don't <em>Rely</em> on Color Alone</h1><br /><p> Some web users may be unable to see color -- they may<br />be blind (and use a screen reader program); they may<br />be color-blind and unable to easily distinguish colors;<br />or they could be using an access device, such as a cell<br />phone, which does not display color. For this reason,<br />the W3C's Web Accessibility Initiative recommends that<br />you not <em>rely</em> upon color as the <em>only</em><br />way of conveying information.</p><br /><div class="pullquote"><br /><img src="k.gif" alt=""> <!-- decorative only --><br /><p>Kynn says:</p><br /><blockquote><br /><p>"Color is very<br><br />useful to those<br><br />who can see it"</p><br /></blockquote><br /></div><br /><p> This doesn't mean "don't use color" -- on the contrary,<br />color is very useful to those who can see it, and will<br />help make your page understandable. What it does mean<br />is that color (and other presentational effects) should<br />not be the only way you make something special. For<br />example, rather than use a <span> and a color<br />style to make something stand out, use the <strong><br />tag (which you can also style) so browsers that<br />can't use the visual CSS color rule can at least know<br />to emphasize that section -- perhaps by increasing the<br />volume when reading the text out loud, for example.</p><br /></body><br /></html><br /></pre></div><br />
|}
The rule that makes the content move to the side is <code>float: left</code>. To place the pull-quote on the right side of the text, you can simply change that rule to read <code>float: right</code> instead. This is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig05 Figure 15.5].
<div style="text-align: center;"> Figure 15.5. Floating the content to the right. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig05_alt.jpg [View full size image]]</div>[[Image:15fig05.jpg|500px]] </div>
<div>Did you Know?
Other properties can be set on floated elements, of course, and some of the most useful are the <code>margin</code> properties, which can be used to affect how close subsequent content will flow. For example, <code>margin-left</code> on a right-floating element keeps the flowing text at a respectable distance. The example in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex03 Listing 15.3] also sets a background on the pull quote, as well as increases the size and adds italics.</div>
In addition to the pull quote itself, there's an additional piece of floating content in this examplethe graphic symbol within the pull-quote is also floating. This was set by the following rule in the embedded style sheet:
<div><pre>.pullquote img { float: left; }
</pre></div>
Notice that this rule moves the image within its own containing boxthe pull quote <code><div></code>and doesn't move it to the edge of the entire page.
The <code>clear</code> Property
To stop subsequent text from flowing around a floating element, you can set the <code>clear</code> property on the first element you don't want to flow. This moves that element down far enough so that it doesn't wrap around the floating box. This effectively increases the top margin of the element with the <code>clear</code> property on it by an amount calculated by the browser to provide enough space to reach past the floating box.
The values for <code>clear</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15table05 Table 15.5]; naturally, the default value is <code>none</code>. Other values specify whether the content should stop the flow around all floating boxes or only boxes on either the left or right side.
{| cellspacing="0" cellpadding="5"|+ Table 15.5. Values for the <code>clear</code> Property
|-
| Value
| Effect
|-
| <code>both</code>
| Move this box down enough so it doesn't flow around floating boxes.
|-
| <code>left</code>
| Move this box down enough so it doesn't flow around left-floating boxes.
|-
| <code>none</code>
| Don't move this box; allow it to flow normally.
|-
| <code>right</code>
| Move this box down enough so it doesn't flow around right-floating boxes.
|-
| <code>inherit</code>
| Use the <code>clear</code> value of the containing box.
|}
To use this property with the pull quote example from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex03 Listing 15.3] requires only adding a rule such as this to the embedded style sheet:
<div><pre>blockquote { clear: left; }
</pre></div>
This rule says that when a <code><blockquote></code> element is found, stop flowing the text around floated elements, and move down far enough to get past any that are present.
The <code><blockquote></code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex03 Listing 15.3] would normally flow around the floating image next to "Kynn says:", but as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig06 Figure 15.6], the <code>clear</code> rule stops the flow of text.
<div style="text-align: center;"> Figure 15.6. Clearing the float at the blockquote. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig06_alt.jpg [View full size image]]</div>[[Image:15fig06.jpg|500px]] </div>
<div>Did you Know?
Sometimes, if you float multiple boxes of content, you get a staggered effect down the page, where one box is positioned against the lower right corner of another. This happens because floated content tries to locate itself as high as possible, in addition to moving to the left or right. To avoid this problem, set a <code>clear</code> property on your floating content, like this:
<div><pre>div#sidebar { float: right; clear: right; }
</pre></div></div>
Thumbnail Galleries
A common use for the <code>float</code> property is in creating a gallery of thumbnail images that link to larger pictures, for displaying photographs or artwork on a website. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex04 Listing 15.4] is an HTML page with embedded style sheet that employs <code>float</code> in this manner.
Listing 15.4. A Simple Photo Gallery Page
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- gallery-15.4.html --><br /><html><br /><head><br /><title>Desert Museum Pictures</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />#gallery<br />{ border: 3px solid gray;<br />margin: 1em;<br />padding: 0.75em; }<br />#gallery h2 { margin: 0; }<br />#gallery div<br />{ border: 1px solid black;<br />margin: 10px;<br />padding: 10px;<br />width: 100px;<br />font-size: small;<br />float: left;<br />text-align: center; }<br />#gallery h2<br />{ clear: left; }<br />#credits { clear: both; }<br /></style><br /></head><br /><body><br /><h1>Desert Museum</h1><br /><p>Here are some pictures I took at the<br />Arizona-Sonora Desert Museum in Tucson:</p><br /><div id="gallery"><br /><h2>Mammals:</h2><br /><div><br /><a href="pics/coyote-001.jpg"><img<br />src="pics/thumb/coyote-001_thumb.jpg"<br />border="Thumbnail"></a><br><br />A Coyote<br /></div><br /><div><br /><a href="pics/coyote-002.jpg"><img<br />src="pics/thumb/coyote-002_thumb.jpg"<br />border="Thumbnail"></a><br><br />Another Coyote<br /></div><br />... <!-- more like these --><br /><h2>Birds:</h2><br />...<br /><p id="credits"><br />Pictures taken by<br /><a href="http://kynn.com/">Kynn Bartlett</a>.<br /></p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
<div>By the Way
The picture gallery here uses the <code>width</code> property, which you'll learn about in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], "Box Sizing and Offset." The <code>width</code> property forces all the images and their captions to take up the same horizontal space.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15fig07 Figure 15.7] shows the results of displaying this page in a browser. When the browser window changesbecause of different screen resolution or simply shrinking the size of the browser application's windowthe pictures continue to line up. The extra pictures just get pushed down to the next available space.
<div style="text-align: center;"> Figure 15.7. Thumbnail gallery displayed in a browser. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/15fig07_alt.jpg [View full size image]]</div>[[Image:15fig07.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Create an Image Gallery
Use CSS to display your own pictures as in this example. Follow these steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Get a number of pictures together, perhaps some you've taken on a family vacation or at a friend's birthday party. Save these all in one web directory.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Using a graphics program, create smaller versions of these pictures that are no more than 100 pixels wide. Save these in a "thumb" directory.<br /><br /></div>
|-
| >
| >
|-
| <div>'''3. '''</div>
| <div>Create an HTML page similar to that in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15ex04 Listing 15.4], which has a <code><div></code> around each picture and its caption. Each picture should be a link to the full-size version of the picture.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Write a CSS rule using <code>float</code> to line up these <code><div></code>s so that they line up across the page and continue down to the next line when they're out of room.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>View your gallery in your web browser. What other styles would you like to add to your gallery to enhance its appearance? Some font choices perhaps?<br /><br /></div>
|}
|}
./ ADD NAME=CH15LEV1SEC3.HTML
Summary
Several CSS properties allow you to adjust the appearance of text when displayed by the browsers, altering the alignment, indentation, and flow of content.
The <code>text-align</code> property specifies whether the text should be lined up on the left side, the right side, or both sides, or in the center. The <code>text-indent</code> property lets you set a paragraph indent or other indent, although hanging indents are somewhat unreliable across browsers. The <code>vertical-align</code> property lets you specify how text is aligned within an inline box and can create subscripts or superscripts.
The normal flow of the page can be affected by the <code>float</code> property, which positions a display box on either the right or left side of its containing box's content area. Subsequent text then flows around the floating box, wrapping around the outer margin. The <code>clear</code> property can be used to move content down the page until it no longer flows.
./ ADD NAME=CH15LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and exercises to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa1q1a1 Q.]'''
| The <code>text-align</code> property works only on inline content. So how do I align a block element?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa1q1 A.]'''
| You can align a block element in two ways: with margin properties and float. To place a block element on the left side of its containing block, use the <code>margin-right</code> property with a value of <code>auto</code>, and to align it on the right, use a <code>margin-left</code> value of <code>auto</code>. To center it, set both <code>margin-left</code> and <code>margin-right</code> to <code>auto</code>. You'll learn more about the right and left margins in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16].
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa2q1a1 1.]'''
| Which of these rules sets a paragraph indent equal to 300% of the <code>font-size?</code>
<div># <div><code>p { text-indent: 300%; }</code></div>
# <div><code>p { text-indent: 30px; }</code></div>
# <div><code>p { text-indent: 3em; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa2q2a2 2.]'''
| Part of your web page consists of an image followed by text; the next section begins with an <code><h3></code> tag. You want the image to be located on the left and the text to flow around it, but you don't want the next section's header to be placed next to the image. What CSS rules would you write to do this?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa2q1 1.]'''
| Rule (c) is the correct answer. <code>1em</code> equals the <code>font-size</code> measurement; if the <code>font-size</code> is <code>12pt, 3em</code> is 36 points. Percentages in <code>text-indent</code>, such as rule (a), are based on the containing block's size; so <code>text-indent: 300%</code> means to have a first line indent that is three times larger than the box holding the paragraph! A more reasonable value would be between <code>0%</code> and <code>50%</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch15qa2q2 2.]'''
| Here's an example of the type of rules you would write; in practice you'd probably use <code>class</code> or <code>id</code> selectors to make these more specific:
<div><pre>img { float: left; }<br />h3 { clear: left; }<br /></pre></div><br />
|}
Exercises
Your own experiments with the properties in this hour will help you master how to use them to style your text and float content. Try the following to expand your understanding:
* Using <code>vertical-align: super</code>, create some links that are anchors to footnotes at the bottom of the page. What makes a good-looking footnote reference? Experiment with smaller font size and adding or removing underlines.
* Try some text styles for your paragraphs, including <code>line spacing</code> (from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10], "Text Colors and Effects") coupled with <code>text-indent</code>. Printed text has often used indentation for paragraph text, whereas web browsers simply use vertical space (created by margins) between paragraphs. Test it out yourself to see how indenting paragraphs changes the feel of your page.
* The <code>float</code> property can be used to position menus on the sides of your web pages. Create some pages that use <code>float</code> to provide simple layout. You'll learn more about using <code>float</code> in layout in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS," but for now you have a useful tool for styling your pages.
./ ADD NAME=CH16.HTML
03c35ot1jpzgqt7uarcro5ieiss1daa
User:Bartlett/16
2
2120
39226
5520
2026-04-13T06:03:21Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39226
wikitext
text/x-wiki
./ ADD NAME=CH16.HTML
Hour 16. Borders and Boxes
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* What the four sides of each box are called, and how to refer to them in CSS rules
* How to use the margin shorthand property to specify margins for specific sides of a box
* Which margin values to set to center boxes horizontally
* How to set the padding on each side of a box
* Which width, color, and line styles can be used on box borders
* How to set borders for specific sides of the box
* Which properties and values enable you to hide the display of a box and its contents
Within the CSS visual formatting model, all HTML elements are displayed as either inline boxes or block boxes. Property values in CSS rules affect the way these boxes are displayed by applying the styles to the content of each box.
You learned about the box model in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6], "The CSS Box Model," and how you can use the <code>margin</code>, <code>padding</code>, and <code>border</code> properties to affect how a box is displayed. Those core properties enable you to manipulate the edges of the box itself, from the space around the content, to the border around the box, and finally to the space surrounding the content of the box.
|}
./ ADD NAME=CH16LEV1SEC1.HTML
Adjusting Boxes
As you've seen before, CSS browsers view all web pages as a series of nested boxes. Block boxes contain inline boxes or other block boxes; inline boxes contain content, usually text. Styles are applied on a box-by-box basis, using selectors that identify boxes or groups of boxes.
Each of these boxes consists of the inside of the box, which is where you can find the content or any child boxes, and the edgethe margin, border, and padding. As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6], you can adjust these by using properties known as the edge properties. You use the <code>margin</code> property to set the blank space just within the limits of the box; the border property to set a line surrounding the content, within the margin; and the <code>padding</code> property to add spacing between the content and the other edge properties.
Changing these properties lets you affect the appearance and placement of a display box so that you can better control how your content is shown to the web user.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6] when I introduced the <code>margin</code>, <code>padding</code>, and <code>border</code> properties, I didn't mention that they are actually shorthand properties, as are the <code>font</code> and <code>background</code> properties. A shorthand property is one that sets several properties at once, first resetting them to their default values (as defined by the W3C specification) and then setting individual values as given in the declaration. Each of the edge shorthand properties sets the edge characteristics of all four sides of the box.
A box in the CSS has four sides: top, bottom, left, and right. The edge properties for each side are displayed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16fig01 Figure 16.1].
<div style="text-align: center;"> Figure 16.1. The edge properties surrounding the content in the box model, on four sides.
[[Image:16fig01.jpg|479px]]
</div>
Edge properties for each side enable you either to set the margin, padding, and border separately for every side or to set several at once with a shorthand property. When using a shorthand property, you can specify between one and four values; the results of these values are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table01 Table 16.1].
{| cellspacing="0" cellpadding="5"|+ Table 16.1. Shorthand Values for Edge Properties
|-
| Shorthand Values
| Effect
|-
| <code>value</code>
| Sets all four properties to the same value
|-
| <code>value1 value2</code>
| Set the top and bottom properties to <code>value1</code> and the right and left properties to <code>value2</code>
|-
| <code>value1 value2 value3</code>
| Set the top property to <code>value1</code>, the right and left properties to <code>value2</code>, and the bottom property to <code>value3</code>
|-
| <code>value1 value2 value3 value4</code>
| Set properties in clockwise order: top, right, bottom, left
|}
Values can also be set with individual properties, such as <code>margin-left</code> or <code>padding-bottom</code>. A shorthand value always sets all appropriate values; no sides are left unset, even if less than four values are specified.
Setting the Margins
Take a look at setting the margins first. You can set all the margins to a single value with the <code>margin</code> property, like this:
<div><pre>#content p { margin: 3em; }
</pre></div>
This would put a margin space of 3 ems around any paragraphs identified by this selector. Remember that vertical margins collapse, so the nearest vertical content will be 3 ems away, unless the other content has a greater margin.
When collapsing margins, you compare the bottom margin of the first box to the top margin of the second. If both are positive, the distance is the greater of the two; if one is negative, the distance is the difference between them. If both vertical margins are negative, the distance between the boxes is the largest negative value. Negative distances mean overlapping display boxes, which is allowable in CSS, albeit often confusing.
Imagine that you want to set just the horizontal margins. Here are four ways to do that:
<div><pre>#content p { margin-left: 3em;
margin-right: 3em; }
#content p { margin: 0em 3em; }
#content p { margin: 0em 3em 0em; }
#content p { margin: 0em 3em 0em 3em; }
</pre></div>
All these rules are identical in effect; they set the right and left margins to 3 ems.
<div>Did you Know?
Nearly any displayed element box has margins that can be adjusted; the exceptions are table cells. Table cells, represented by <code><td></code> or <code><th></code> in HTML, don't have margins. See the discussion of table styling in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17], "Styling Tables," for more about this.</div>
Margin values are not inherited; unless otherwise set, a box's margin will be zero. The types of values you can set for margins are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table02 Table 16.2].
{| cellspacing="0" cellpadding="5"|+ Table 16.2. Values for the <code>margin</code> Properties
|-
| Value
| Effect
|-
| <code>measurement</code>
| Set the margin(s) to a specified size.
|-
| <code>negative measurement</code>
| Reduce the margin(s) of touching boxes by a specified size.
|-
| <code>percentage</code>
| Set the margin(s) to a percentage of the containing box's width.
|-
| <code>auto</code>
| Automatically calculate the margin(s).
|-
| <code>inherit</code>
| Use the margin value(s) of the containing box.
|}
<div>By the Way
Note that percentages are always based on the width of the containing block, even vertical margins. You'd expect them to be determined relative to the height of the containing box, but this just isn't the case in CSS.</div>
The value <code>auto</code> requires some explanation. If it is set on an inline element's margins, the value is calculated to <code>0</code>. If set on a box element's left margin or right margin, the margin is set to be all remaining space within the containing box; this will move the box with the margin to one side or another. If both the left and right margins are set to <code>auto</code>, the box will be centered within its containing box. A value of <code>auto</code> for a top or bottom margin has no effect.
<div>Did you Know?
Actually, a value of auto for any margin can mean more than what I've described here, but only when you're using CSS to position content on the screen. You'll learn more about auto margins in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], "Absolute and Fixed Positioning," in the discussion on CSS positioning.</div>
Setting the Padding
Setting values for <code>padding</code> in CSS is simpler than setting <code>margin</code> values because there are no <code>auto</code> values and no negative measurements. The only values for padding are measurements and percentages.
Percentage values for <code>padding</code>, such as <code>margin</code> percentages, are based on the containing box's width, even for the top and bottom padding properties.
Here are four different ways to set the top padding to 4 pixels, the left and right padding to 0 pixels, and the bottom padding to 8 pixels:
<div><pre>#content p { padding-top: 4px;
padding-bottom: 8px; }
#content p { padding: 4px 0px 8px; }
#content p { padding: 4px 0px 8px 0px; }
#content p { padding: 4px 0px;
padding-bottom: 8px; }
</pre></div>
Note that in the last rule, the <code>padding-bottom</code> was set twice, once as part of the <code>padding</code> shorthand rule, to <code>4px</code>, and later separately to <code>8px</code>. Because the second rule comes later (and all other priority factors are the same), the bottom padding will be 8 pixels.
Setting the Border
Borders in CSS have three distinct values associated with them: the width, or thickness of the border; the color of the border; and the style, or type of line drawn. With four sides, that means that there are actually 12 properties associated with the borders: the <code>width</code>, <code>color</code>, and <code>style</code> for <code>top</code>, <code>bottom</code>, <code>left</code>, and <code>right</code>. Each is written as <code>border-</code><code>side</code><code>-</code><code>property</code>, such as <code>border-left-style</code> or <code>border-bottom-color</code>.
The <code>border</code> shorthand property sets all 12 of these properties at once. Using the border property, you'd write a rule like this:
<div><pre>#nav div { border: solid purple 3px; }
</pre></div>
This defines the border as a solid purple line that is 3 pixels wide. This is the same as the following rule:
<div><pre>#nav div { border-top-style: solid;
border-top-color: purple;
border-top-width: 3px;
border-right-style: solid;
border-right-color: purple;
border-right-width: 3px;
border-bottom-style: solid;
border-bottom-color: purple;
border-bottom-width: 3px;
border-left-style: solid;
border-left-color: purple;
border-left-width: 3px; }
</pre></div>
Unlike <code>margin</code> and <code>width</code>, you can't set one to four different values for each side's border using the <code>border</code> shorthand property; instead, you can use one shorthand property per side, as in the following:
<div><pre>#nav div { border-left: 1em solid green;
border-right: 2em dashed blue;
border-top: 1.5em dotted red;
border-bottom: 0.5em solid purple; }
</pre></div>
Alternately, you can use other shorthand properties to set all the <code>border-width</code>, <code>border-color</code>, and <code>border-style</code> values at once. You also can set the 12 border-style properties individually or combine these approaches, using normal CSS cascading rules to resolve priorities.
Border Width
The thickness of the border is set by a <code>border-width</code> value; possible values are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table03 Table 16.3]. If no <code>border-width</code> value is specified in a shorthand property, the default is <code>medium</code>. For a border to be displayed at all, the <code>border-width</code> value for each side must be set to something, even if it's simply set to the default with a shorthand property.
{| cellspacing="0" cellpadding="5"|+ Table 16.3. Values for the <code>border-width</code> Properties
|-
| Value
| Effect
|-
| <code>medium</code>
| Sets a medium thickness border
|-
| <code>thick</code>
| Sets a thick border
|-
| <code>thin</code>
| Sets a thin border
|-
| <code>measurement</code>
| Sets a border as wide as the specified measurement
|-
| <code>inherit</code>
| Uses the inherited <code>border-width</code> value of the containing box
|}
The values <code>thin</code>, <code>medium</code>, and <code>thick</code> are relative values whose exact measurements are left up to the browser. The browser can determine the precise thickness however it likes, though within certain constraints; thin can't be thicker than <code>medium</code>, <code>thick</code> can't be thinner than <code>medium</code>, and when displaying a page, all borders of a given thickness must be the same width. One browser's interpretation of these values is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16fig02 Figure 16.2].
<div style="text-align: center;"> Figure 16.2. Each <code>border-width</code> value displayed in Firefox.
[[Image:16fig02.jpg|300px]]
</div>
The thickness of each side's border doesn't have to be the same; each can be set to a different value if you like. To set different thicknesses, you can either use multiple values with the <code>border-width</code> shorthand property, or use the <code>border-width</code> property for each side. Here are some examples:
<div><pre>#nav div { border-width: 3px 2px 3px 4px; }
#nav div { border-top-width: 3px;
border-right-width: 2px;
border-bottom-width: 3px;
border-left-width: 4px; }
#nav div { border-width: 3px 4px;
border-right: 2px; }
</pre></div>
These all set the same effect: a top border of 3 pixels, a right border of 2 pixels, a bottom border of 3 pixels, and a left border of 4 pixels.
<div>Did you Know?
Border values that are measurements based on ems are calculated based on the size of the text for that box. For example, if you have the following rules in your style sheet:
<div><pre>body { font-size: 30px; }
.sidebar { font-size: 50%; border: 0.2em; }
</pre></div>
The text within the <code>.sidebar</code> will be 50% of <code>30px</code>, or <code>15px</code>, and the border will be <code>0.2em</code> at that current size, or <code>3px</code> wide. It won't be <code>6px</code>, which is what it would be based on the size of the body text, not the <code>.sidebar</code> text. If there were no font-size rule for <code>.sidebar</code>, then the border would be <code>6px</code> wide. This also applies to margins and padding, so when you change the size of the text in a box, you may also change relative units as well, which are based on that font size.</div>
Border Color
The color of all borders can be set at once with the <code>border-color</code> shorthand property or set individually with the <code>border-top-color</code>, <code>border-right-color</code>, <code>border-bottom-color</code>, and <code>border-left-color</code> properties. If no color is specified, the default color value will be the foreground text color set by the <code>color</code> attribute.
You can specify the border color as you would any other colors in CSS: by RGB hex values, numeric values, or percentages, or by color name. Examples of setting border color are
<div><pre>#nav div { border-color: red white blue; }
#nav div { border-top-color: red;
border-right-color: white;
border-bottom-color: blue;
border-left-color: white; }
</pre></div>
Border Style
The line appearance of the border is determined by the <code>border-style</code> properties: <code>border-top-style</code>, <code>border-right-style</code>, <code>border-bottom-style</code>, and <code>border-left-style</code>. These can be set with the <code>border</code> shorthand property or with the <code>border-style</code> shorthand property that sets the style for all four of the borders.
Valid border types are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table04 Table 16.4]. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6] introduced the <code>solid</code>, <code>dashed</code>, and <code>dotted</code> values. This hour adds the three-dimensional border values <code>groove</code>, <code>ridge</code>, <code>inset</code>, and <code>outset</code>, as well as the <code>hidden</code> and <code>double</code> values.
{| cellspacing="0" cellpadding="5"|+ Table 16.4. Values for the <code>border-style</code> Properties
|-
| Value
| Effect
|-
| <code>dashed</code>
| A dashed border
|-
| <code>dotted</code>
| A dotted border
|-
| <code>double</code>
| A solid double line border
|-
| <code>groove</code>
| The border appears to be carved into the page
|-
| <code>hidden</code>
| No border displayed; borders collapsed in tables
|-
| <code>inset</code>
| The entire box appears to be carved into the page
|-
| <code>none</code>
| No border displayed
|-
| <code>outset</code>
| The entire box appears to rise up from the page
|-
| <code>ridge</code>
| The border appears to rise up from the page
|-
| <code>solid</code>
| A solid single line border
|-
| <code>inherit</code>
| Use the value of the border-style from the containing box
|}
The <code>none</code> and <code>hidden</code> values are identicalno border is displayedexcept in table styles. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17] you'll learn more about collapsing borders for table cells.
The exact rendition of each border style is left up to the browser implementation, constrained by the definitions of each style; obviously, a <code>dashed</code> border should be made up of dashed lines. Examples of each type of border are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16fig03 Figure 16.3].
<div style="text-align: center;"> Figure 16.3. Each <code>border-style</code> value displayed in Firefox.
[[Image:16fig03.jpg|500px]]
</div>
Not all browsers support all border styles; in fact, the CSS specifications explicitly allow them to opt out certain border styles. Browsers that don't display all border styles can instead choose to show them as <code>solid</code>. However, the styles listed here are currently supported by all modern browsers.
./ ADD NAME=CH16LEV1SEC2.HTML
Displaying Boxes
In addition to changing the properties of the box edge, you can also set certain boxes to not be displayed at all or to display differently. The properties controlling this are the <code>display</code> and <code>visibility</code> properties.
Why wouldn't you want a box to display? Well, in most cases you'll want them to show up; this is why they're in the page content, after all. However, you may want to hide a display box if that content is inappropriate for the type of output medium being used. For example, a navigation bar may not make sense on the printed page because you obviously can't click on paper. The <code>display</code> and <code>visibility</code> properties are also useful with JavaScript to produce Dynamic HTML effects.
<div>By the Way
You'll learn more about style sheets for printers in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media." Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch01.html#ch01 Hour 1], "CSS and JavaScript" (on the book's website), can fill you in on Dynamic HTML.</div>
The <code>display</code> Property
As you've seen before, you can use the <code>display</code> property to change a box from a block element to an inline element or vice versa; you can also use it to make something display as a list item. In general, you'll want to avoid overriding the default display rules for HTML in browsers; there are too many things that can get confused if you do this, such as the default margins on certain elements. However, setting the <code>display</code> property is very useful when you're dealing with XML, as you'll learn in Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "CSS and XML" (on the book's website).
There are going to be some times when you're going to want to use the <code>display</code> property with HTML, especially if you need to hide some content. The values you can assign to <code>display</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table05 Table 16.5].
{| cellspacing="0" cellpadding="5"|+ Table 16.5. Values for the <code>display</code> Property
|-
| Value
| Effect
|-
| <code>block</code>
| Display as a block box
|-
| <code>inline</code>
| Display as an inline box
|-
| <code>inline-block</code>
| Display inline, as an inline box, but with the box's content displayed as if it were a block box
|-
| <code>list-item</code>
| Display as a list item with list item marker
|-
| <code>none</code>
| Don't display the box or its children boxes
|-
| <code>run-in</code>
| Display as a run-in box
|-
| <code>inherit</code>
| Use the display value of the containing box
|}
In addition to the values listed here, there are several values for display that apply only to tables, such as <code>inline-table</code> or <code>table-row-group</code>; these are covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17].
The <code>inline-block</code> property was introduced in CSS Level 2.1, and is a compromise between an <code>inline</code> box and a <code>block</code> box. For purposes of placing the <code>inline-block</code> box, it is treated as an <code>inline</code> element. However, <code>inline</code> elements usually contain only other <code>inline</code> boxes; the <code>inline-block</code> element contains <code>block</code>-level boxes.
Boxes with the <code>display</code> value <code>run-in</code> are displayed as either block or inline depending on context. A <code>run-in</code> box displays as a block element unless there's another block element (which isn't positioned with CSS positioning) after it as a sibling element, in which case it will become the first inline block of that subsequent block element.
<div>Watch Out!
The <code>run-in</code> value for the <code>display</code> property isn't supported by Firefox. However, <code>run-in</code> boxes are rather complex for the actual benefit they provide; you can likely get the same effect with other properties, values, and markup, rather than try to use <code>run-in</code>.</div>
Hiding Boxes with <code>display: none</code>
The value <code>none</code> means that any selected elements aren't displayed; their boxes (and the boxes of their children) don't even appear. This value technically isn't inherited, but if you set one box to <code>display: none</code> and then try to set one of its children to <code>display: block</code> (or <code>display: inline</code>), the inner box still doesn't appear.
<div>Did you Know?
The <code>display</code> property is a handy way to include messages for users with browsers that don't support CSS, such as Lynx. For example, if you're using a specific color to mark new entries, you can add some text explanations with <code>display: none</code>. Here is an example:
<div><pre>New books are marked in red<span class="hidden">
or with the word New</span>:
<ul>
<li><span class="hidden">New:</span>
<span class="new">Teach Yourself CSS in 24 Hours</span>
</li>
</ul>
</pre></div>
You'd then write CSS rules to support those classes, like this:
<div><pre>.hidden { display: none; }
.new { color: red; }
</pre></div></div>
<div>Watch Out!
You might guess you'd be able to use the <code>display</code> trick to hide or reveal content selectively for users with visual disabilities who use screen readers, perhaps in combination with a media type. If you thought that, you wouldn't be alone (a lot of experienced web developers have assumed it would work that way), but unfortunately it's not true in practice. Screen readers take their presentation from what's displayed on the screen by a browser such as Internet Explorer, and if you hide accessibility information with a <code>display: none</code> rule, the browser won't see itand neither will the screen reader. For some interesting attempts at work-arounds, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."</div>
Styling Navigation Lists
A navigation bar on a web page is simply a list of linksa list in the normal English sense of the word list, not the HTML meaning with <code><ul></code> and <code><li></code> tags. Or is it?
Most navigation bars don't need list markers, such as bullets or numbers. Furthermore, many navigation bars are horizontal, whereas lists are vertical. So at first glance, an HTML list built with <code><ul></code> would seem inappropriate for navigation.
However, you can use the <code>display</code> property to change the way these lists are displayed. Consider the following HTML, which contains a navigation list:
<div><pre><ul id="nav">
<li><a href="/">Home</a></li>
<li><a href="/author.html">The Author</a></li>
<li><a href="/downloads.html">Downloads</a></li>
<li><a href="/contact.html">Contact</a></li>
</ul>
</pre></div>
Normally this is displayed by a browser as a list of bullet items. Using CSS, you can style this to be either a vertical navigation bar or a horizontal one.
To create a vertical navigation bar, simply use these simple style rules:
<div><pre>#nav li { display: block; }
#nav { padding: 0; margin: 0; }
</pre></div>
This changes the list items from <code>display</code> type <code>list-item</code> to <code>block</code>, and remove the padding and margins inserted by <code><ul></code> lists.
To create a horizontal navigation bar, you can do the same, but change the list items to inline blocks:
<div><pre>#nav li { display: inline; padding-right: 1em; padding-left: 1em; }
</pre></div>
Some <code>padding</code> was added to provide some extra space. Of course, you can use CSS to set background colors, borders, and any other appropriate properties you wish on the <code><ul></code> and <code><li></code> elements. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16fig04 Figure 16.4] displays the same navigation list three timesthe identical HTML, but styled to be a vertical navigation bar and a horizontal navigation bar.
<div style="text-align: center;"> Figure 16.4. A navigation list restyled to navigation bars. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/16fig04_alt.jpg [View full size image]]</div>[[Image:16fig04.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Create Graphics-Free Navigation Buttons
The border properties can be used in conjunction with color, background-color, and font properties to create "buttons" that look like graphics but are really HTML tags with styles applied. Here are some ideas you could try for practice:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Use a simple HTML list to create a menu bar. Add this to a web page as a navigation bar, using either tables for layout or CSS-based layouts (described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS").<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Add style rules to change the navigation bar to be either vertical or horizontal, as fits your page. If you have two navigation barsand many pages willthen style one as horizontal and one as vertical.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Set the font characteristics and size, the foreground and background colors, and the <code>text-decoration</code> on any links present.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Draw a border around each list item, using an <code>inset</code> or <code>outset border-style</code>. This will make your button appear to stand out (or sink into) the page.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Finally, change the border style to solid and try setting your own colors on each border to give a different three-dimensional effect. If you set the colors explicitly, you have more control over the resulting button's appearance. To make a button stand out from the page, use a light color on the top and left and a darker color on the right and bottom.<br /><br /></div>
|}
|}
The <code>visibility</code> Property
Both the <code>visibility</code> and <code>display</code> properties affect whether or not the element's display box is shown. The difference between the two is that <code>visibility</code> sets aside a place on the page for an undisplayed box, whereas <code>display</code> does not. The place where the box (and its contents) would normally be displayed is instead shown as a transparent box of the same size. The values for <code>visibility</code> are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16table06 Table 16.6].
{| cellspacing="0" cellpadding="5"|+ Table 16.6. Values for the <code>visibility</code> Property
|-
| Value
| Effect
|-
| <code>collapse</code>
| Collapse only table cells; see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17]
|-
| <code>hidden</code>
| Don't display the box, but reserve the space in the layout
|-
| <code>visible</code>
| Display the box normally
|-
| <code>inherit</code>
| Use the visibility value of the containing box
|}
The <code>visibility</code> property is most useful in dynamic HTML and JavaScript, where you can interactively change the <code>visibility</code> of a box in response to user actions. For more on this, see Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch01.html#ch01 Hour 1] on the book's website.
./ ADD NAME=CH16LEV1SEC3.HTML
Summary
Each side of a display box is named: top, right, bottom, and left. You can set the margins and padding space for each, using shorthand properties or individual properties. If you use shorthand properties and specify one value, it applies to all sides; two values assign the top/bottom and left/right; three designate top, left/right, and bottom; and four values set the properties in clockwise order.
There are also 12 properties that control the borders, and a number of shorthand properties exist to set them all in various combinations. The width, color, and line style of the borders can be set all at once, or they can be set individually for each side.
You can also control whether or not a box is displayed at all. To hide a box entirely, use the <code>display: none</code> value. If you want to reserve space for the box, but not actually show it or its content, use the <code>visibility</code> property with a value of <code>hidden</code>.
./ ADD NAME=CH16LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa1q1a1 Q.]'''
| How can I align a box with <code>margin</code> properties?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa1q1 A.]'''
| Here's how it works. First, don't use <code>text-align</code> unless you want the content of the box to be aligned. Instead, use <code>margin-left</code> and <code>margin-right</code> properties as shown here:
<div><pre>.left { margin-right: auto; } /* align left */<br />.right { margin-left: auto; } /* align right */<br />.center { margin-right: auto;<br />margin-left: auto; } /* center */<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa1q2a2 Q.]'''
| I tried setting a black border that should be <code>inset</code>, <code>groove</code>, <code>outset</code>, or <code>ridge</code>, and it showed up as <code>solid</code>! What gives?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa1q2 A.]'''
| When you set a border with those three-dimensional border types, you add the third dimension by adjusting the base color. The edges "facing the light" are colored lighter, and the edges "in shadow" are darker. The CSS specification doesn't say how to derive those colors, so browsers are free to use their own methods. If a browser decides that the light color is 20% brighter and the dark color is 20% darker, that works unless your color is less than 20% dark to begin with, like black (<code>#000000</code>)you can't actually make a darker version of <code>#000000</code>. If you want to be certain that your border colors appear properly three-dimensional, you should set the border style to <code>solid</code> and manually choose your own lighter and darker side colors, setting them individually on each side border.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q1a1 1.]'''
| These two shorthand properties set the margin and padding. What are equivalent declarations that don't use shorthand properties, and instead use properties such as <code>margin-left</code>?
<div><pre>#demo { margin: 0em 1em 1.5em;<br />padding: 5px 7px; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q2a2 2.]'''
| Likewise, these border shorthand properties can be written as 12 separate property value declarations. What are they?
<div><pre>#demo2 { border: 3px groove black;<br />border-style: dashed dotted double solid;<br />border-left: medium inset green; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q3a3 3.]'''
| A box that looks like it's depressed into the page has been styled with which border line style?
<div># <div><code>border-style: emboss;</code></div>
# <div><code>border-style: groove;</code></div>
# <div><code>border-style: inset;</code></div>
# <div><code>border-style: sunken;</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q4a4 4.]'''
| What's the difference between these two rules?
<div><pre>.hide1 { visibility: hidden; }<br />.hide2 { display: none; }<br /></pre></div><br />
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q1 1.]'''
| The equivalent declarations are
<div><pre>#demo { margin-top: 0em;<br />margin-right: 1em;<br />margin-bottom: 1.5em;<br />margin-left: 1em;<br />padding-top: 5px;<br />padding-right: 7px;<br />padding-bottom: 5px;<br />padding-left: 7px; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q2 2.]'''
| Here's how to write those rules as separate properties:
<div><pre>#demo2 { border-top-width: 3px;<br />border-top-color: black;<br />border-top-style: dashed<br />border-right-width: 3px;<br />border-right-color: black;<br />border-right-style: dotted;<br />border-bottom-width: 3px;<br />border-bottom-color: black;<br />border-bottom-style: double;<br />border-left-width: medium;<br />border-left-color: green;<br />border-left-style: inset; }<br /></pre></div><br />
Aren't shorthand properties nicer?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q3 3.]'''
| The correct answer is (c), <code>inset</code>. The <code>groove</code> value makes the line appear carved but not the box itself, and there are no such values as <code>emboss</code> or <code>sunken</code> for border styles.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch16qa2q4 4.]'''
| With the first rule, empty (transparent) space is reserved for the box, but with the second, no space is reserved and the box won't be displayed at all.
|}
Exercise
Give yourself some practice with the box properties by experimenting with the appearance of padding, margin, and borders. The <code><blockquote></code> element is a good subject for such experimentation: It is used to identify sections of text that are quoted from another source. Special margins, padding, and borders are therefore useful for identifying these.
The default styles in web browsers for <code><blockquote></code> set margins on the left and right side. Try writing rules that style these quotes differently. For example, your block quotes could have a solid, thin black line on the top and bottom (with an attractive bit of padding added), or a thick dotted line on the left side with no extra margins added. Find something you likeand don't neglect changing the font, the color, and the background color to suit your tastes.
./ ADD NAME=CH17.HTML
7oshy6ymrfe84hma8sszrxk14iw5xu9
User:Bartlett/17
2
2121
39227
5521
2026-04-13T06:03:22Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39227
wikitext
text/x-wiki
./ ADD NAME=CH17.HTML
Hour 17. Styling Tables
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* What the HTML table model is, and how it is used with CSS
* How tables are laid out on the screen
* What the layers of a table are, and how CSS rules can be used to affect cells in those layers
* How the borders, padding, and spacing of table cells can be affected by CSS
* How to use other CSS properties with table layout
Tables in HTML are a staple of web development and are used for everything from schedules and calendars to page layout. Although CSS offers the capability to replace tables for visual design of the page, it's a more common scenario to find tables and CSS styles used together for best effect.
|}
./ ADD NAME=CH17LEV1SEC1.HTML
=== Table Formatting ===
Tables are ubiquitous on the Web and constitute the primary way of formatting output visually; they were intended originally for pure data but have evolved to serve as a rudimentary page-layout sublanguage within HTML.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS," I show you how you can eliminate tables entirely from your web designs and use pure CSS for the positioning of page elements. In this hour, I'm going to assume that you are using tables either for data or layout; the properties here can be used for either. The examples given are for data tables but apply equally well to layout tables.
HTML Table Model
The way HTML browsers display tables should be familiar to anyone who has done web development work. Tables are employed not only for displaying columns of tabular data, but also for graphically laying out entire pages on the screen.
To do any serious web development, you need to know how tables are used in HTML. This same knowledge will serve you well in CSS because the CSS table model is based on the HTML table model. You have probably worked with tables before, and this explanation will be a review for you.
An HTML table is defined by the <code><table></code> element. Within the opening and closing tags of the <code><table></code> can be found a number of table rows, designated by the <code><tr></code> tag. Each row is composed of one or more table cells. A table cell can be either table data, <code><td></code>, or a table header, <code><th></code>. Table headers are generally assumed to convey some sort of information about the corresponding table data cells; at least, if the markup is used properly, this will be true.
More complex tables can be built by collecting table rows into groups, using the <code><thead></code>, <code><tbody></code>, and <code><tfoot></code> elements. Each of these tags defines a container that holds one or more table rows and identifies them as a group. The <code><thead></code> tag is used to designate table header rows; if a printed table spans more than one sheet of paper, the <code><thead></code> should be repeated on the top of each page. The <code><tfoot></code> is the complement of the table header rows; it is a group of rows that serves as a footer and should also be repeated if the table spans multiple pages. Table body sections, marked with <code><tbody></code> tags, group together related rows; a table can have one or more <code><tbody></code> sections.
An example of a data table built with table row groups can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1]; this is an HTML file that contains a weekly listing of scheduled events. In fact, it's my current schedule, as I'm writing this book; you can assume that all other time is taken up with either writing or sleeping, and often with very little of the latter!
Listing 17.1. A Simple HTML Table
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- schedule-17.1.html --><br /><html><br /><head><br /><title>Weekly Schedule</title><br /></head><br /><body><br /><table><br /><caption>My Schedule</caption><br /><thead><br /><tr><br /><th></th><br /><th>Mon</th><br /><th>Tue</th><br /><th>Wed</th><br /><th>Thu</th><br /><th>Fri</th><br /></tr><br /></thead><br /><tbody><br /><tr><br /><th>Morning</th><br /><td>Class</td><br /><td></td><br /><td>Class</td><br /><td></td><br /><td></td><br /></tr><br /><tr><br /><th>Afternoon</th><br /><td></td><br /><td>Online Gaming</td><br /><td></td><br /><td></td><br /><td></td><br /></tr><br /><tr><br /><th>Evening</th><br /><td></td><br /><td>Class</td><br /><td></td><br /><td>Game Night</td><br /><td></td><br /></tr><br /></tbody><br /></table><br /></body><br /></html><br /></html><br /></pre></div><br />
|}
This sample table also contains a <code><caption></code> tag; the caption is used to provide a label for the table. You could have specified table columns, as well, by using the <code><colgroup></code> and <code><col></code> tags, but for now, this table will serve as an effective example for your table-related style properties. Later in this hour, I'll cover columns and column groups.
A web browser displays tables with default styling based on the browser's understanding of table markup. Borders typically aren't drawn between cells or around the table; table data cells are left-justified in normal text; table header cells are center-justified and set in bold font; and captions are centered over the table. This can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig01 Figure 17.1], which shows the default styles Firefox uses to display a table.
<div style="text-align: center;"> Figure 17.1. Schedule table with default HTML styling in Firefox.
[[Image:17fig01.jpg|500px]]
</div>
CSS Table Layout
The Cascading Style Sheets model for tables is based on the HTML model; CSS was specifically built to be compatible with HTML as used on the web. Style sheets can be used in conjunction with HTML markup to style and present columns and rows of information or to lay out the whole page on the screen.
<div>Watch Out!
Just because you can do something, that doesn't mean you always should. HTML tables were not originally designed for page layout; in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20] you'll learn how you can use CSS positioning properties to create powerful and flexible layouts without using <code><table></code> tags. You may still want to use layout tables for backward compatibility with older browsers, but you should also be aware that tables, as a visual way of conveying information, may sometimes leave behind people who have vision-related disabilities. For more on users with disabilities, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media."</div>
The link between the HTML and CSS table models is the <code>display</code> property in CSS. Each table tag corresponds to a value for <code>display;</code> the default style sheet within a CSS-based browser specifies how each item should be shown to the user. The list of additional <code>display</code> values is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table01 Table 17.1].
{| cellspacing="0" cellpadding="5"|+ Table 17.1. Table-Related Values for the <code>display</code> Property
|-
| Value
| Effect
|-
| <code>inline-table</code>
| As <code><table></code>; displayed as an inline box.
|-
| <code>table</code>
| As <code><table></code>; displayed as a block box.
|-
| <code>table-caption</code>
| As <code><caption></code>; displayed before, after, or beside the table.
|-
| <code>table-cell</code>
| As <code><td></code> or <code><th></code>; an individual table cell.
|-
| <code>table-column</code>
| As <code><col></code>; not displayed but can be used for formatting.
|-
| <code>table-column-group</code>
| As <code><colgroup></code>; not displayed but can be used for formatting.
|-
| <code>table-footer-group</code>
| As <code><tfoot></code>; designates a group of footer rows.
|-
| <code>table-header-group</code>
| As <code><thead></code>; designates a group of header rows.
|-
| <code>table-row</code>
| As <code><tr></code>; a row of table cells.
|-
| <code>table-row-group</code>
| As <code><tbody></code>; designates a group of rows.
|}
Because these values are built into the browser, you won't ever actually need to change the <code>display</code> property to work with tables, but it is useful to know how CSS considers each. For example, CSS classifies <code><td></code> and <code><th></code> as the same type of <code>display</code> property.
Table cells in CSS are treated as block boxes; they can contain inline or block content and are contained by <code>table-row</code> block boxes. Table rows and groups of table rows are used primarily for grouping. Usually, styles can't be applied to them directly, although properties that are inherited can be set on rows or groups of rows and will apply to cells (<code><td></code> or <code><th></code>) within those rows.
In general, applying styles to table cells is straightforward and follows all the normal rules of cascade and inheritance; nearly any CSS properties can be set on table cells. There are a few exceptions, however, so before you go on, I'll spend some time looking at how CSS styles interact with HTML tables.
Layers and Inheritance
One key way in which tables differ from other block boxes is the introduction of table layers into the inheritance method. Each cell is considered to be a descendant of several other layers of markup, as shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table02 Table 17.2].
{| cellspacing="0" cellpadding="5"|+ Table 17.2. Table Layers, in Order from Most Specific to Most General
|-
| Layer
| Equivalent HTML
|-
| cells
| <code><td></code>, <code><th></code>
|-
| rows
| <code><tr></code>
|-
| row groups
| <code><thead></code>, <code><tbody></code>, <code><tfoot></code>
|-
| columns
| <code><col></code>
|-
| column groups
| <code><colgroup></code>
|-
| table
| <code><table></code>
|}
The most surprising thing about table layers is that they exist even if the actual tags do not! For example, all cells are part of a row group, even if there are no <code><thead></code>, <code><tbody></code>, or <code><tfoot></code> tags in the document. It is assumed that there is an unstated, invisible <code><tbody></code> surrounding all table rows that aren't already within a row group. Likewise, all cells are part of columns and column groups.
When considering the appearance of a table cell, you need to take into account the effects of these table layers. For example, the <code>background-color</code> property is normally transparent unless otherwise specified. This means that the background of the containing box of the <code><table></code> is visible. If <code>background-color</code> is set on a <code><tbody></code>, that is the cell's background color, unless the property is set on a <code><tr></code> or a table cell, which are more specific, according to the table layers model.
Automatic and Fixed Layouts
The browser usually automatically determines the dimensions of the table's box and of the box sizes of each cell within it. Browsers generally follow the same method of calculating the size, but this is not a requirement, and in fact the CSS Level 2.1 specification allows browsers to use whatever method they like to size a table and its cells. This is called an automatic layout.
However, in many cases you need more control over the dimensions of the table. At those times, you'll want to use a fixed layout, one where the width and cells of the table are specified in the CSS rules. To tell the browser you're working with a fixed layout, use the <code>table-layout</code> property. Values for <code>table-layout</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table03 Table 17.3]; the default is <code>auto</code>. This property can be set only on table elements.
{| cellspacing="0" cellpadding="5"|+ Table 17.3. Values for the <code>table-layout</code> Property
|-
| Value
| Effect
|-
| <code>auto</code>
| Let the browser determine the dimensions of the table and table cells.
|-
| <code>fixed</code>
| Explicitly designate the width of each table cell.
|-
| <code>inherit</code>
| Use the value of <code>table-layout</code> set on the containing block.
|}
After you have informed the browser that you're using a fixed layout, you then need to define the widths of each column. You do this by setting the <code>width</code> property on the table and on each table cell. The value of the <code>width</code> property can be either a measurement, such as <code>300px</code> or <code>6em</code>, or a percentage value.
<div>Did you Know?
The <code>width</code> property can be used with other block elements, as well; you'll learn more about this useful property in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], "Box Sizing and Offset."</div>
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex02 Listing 17.2] sets the <code>table-layout</code> property to <code>fixed</code> and provides width values for the table and for each table cell. A border is drawn around each cell to make the widths more apparent.
Listing 17.2. Style Sheet with Fixed Layout
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.2.css */<br />table { table-layout: fixed;<br />width: 90%; }<br />td, th { width: 15%;<br />border: 2px solid gray; }<br /></pre></div><br />
|}
Applying this style sheet to the schedule table from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1] produces the effects shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig02 Figure 17.2]. The primary advantage of a fixed layout is that it displays faster because the browser doesn't have to calculate the column widths.
<div style="text-align: center;"> Figure 17.2. Firefox displays a schedule with a fixed layout.
[[Image:17fig02.jpg|500px]]
</div>
Table Borders, Padding, and Spacing
Like other block display boxes in CSS, table cells can be surrounded by borders and can have internal padding. Unlike other block boxes, though, a table cell never has a margin on any side. Instead, table styles are used to control spacing around table cells.
The appearance of a table cell's borders is affected by several properties that determine which cells display borders and how adjacent borders interact with each other.
Displaying or Hiding Empty Cells
If you looked carefully at [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig02 Figure 17.2], you might have noticed something unusual: Only cells that contained content had borders drawn around them. This can be an effective way of presenting information in some circumstances, but in others you are going to want a border drawn around all table cells, even those that are empty. You can control the display of borders around table cells by using the <code>empty-cells</code> property.
The <code>empty-cells</code> property can be set only on table elements, and the valid values for this property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table04 Table 17.4]. The default is <code>hide</code>, which means borders aren't shown for empty cells.
{| cellspacing="0" cellpadding="5"|+ Table 17.4. Values for the <code>empty-cells</code> Property
|-
| Value
| Effect
|-
| <code>hide</code>
| Don't display borders for empty cells.
|-
| <code>show</code>
| Display appropriate borders for empty cells.
|-
| <code>inherit</code>
| Use the value of <code>empty-cells</code> set on the containing box.
|}
By setting <code>empty-cells</code> to <code>show</code>, you are telling the browser that if a cell is empty, it can go ahead and apply whatever <code>border</code> style would be used if the cell contained content. If there is no applicable border to use, the cell isn't displayed. Setting only the <code>empty-cells</code> property without the appropriate border properties (or the border <code>shorthand</code> property) is ineffective.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex03 Listing 17.3] contains rules for several styles of borders, along with an <code>empty-cells: show</code> declaration on the table.
Listing 17.3. Turning on Borders Around Empty Cells Via the <code>empty-cells</code> Property
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.3.css */<br />table { table-layout: auto; width: 90%;<br />font-size: large;<br />empty-cells: show; }<br />td, th { width: 15%; }<br />thead th { border: 0.20em dashed gray; }<br />tbody th { border: 0.25em solid black; }<br />td { border: 0.10em solid gray; }<br /></pre></div><br />
|}
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig03 Figure 17.3], you can see the results of applying this style sheet to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1]; a border surrounds every table cell, in contrast to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig02 Figure 17.2].
<div style="text-align: center;"> Figure 17.3. Empty cells become visible, as shown by Firefox.
[[Image:17fig03.jpg|500px]]
</div>
Collapsing Borders
Within CSS you can have two options for how you want table cell borders to be handled: They can either collapse or remain separate. You can choose which of these two display models to use by setting a value for <code>border-collapse</code> on your <code><table></code> element; appropriate values are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table05 Table 17.5].
{| cellspacing="0" cellpadding="5"|+ Table 17.5. Values for the <code>border-collapse</code> Property
|-
| Value
| Effect
|-
| <code>collapse</code>
| Collapse adjacent borders together.
|-
| <code>separate</code>
| Keep adjacent borders separated.
|-
| <code>inherit</code>
| Use the value of <code>border-collapse</code> set on the containing box.
|}
In the collapsed border model, two cells that are adjacent, horizontally or vertically, share a single, common border line between them. There is no space between the cells; one ends where the other begins. You'd use this to produce a clean, simple table presentation where the cells aren't separated within distinct boxes. This is a style choice you'd make based on how you envision the final look of the table.
If two adjacent cells have different border properties set on them, the border is based on the most visible <code>border</code> of the two. A wider <code>border</code> takes precedence over a narrow <code>border</code>. If two borders are the same width, the <code>border-style</code> determines which one is chosen; in order from most important to least important, a <code>border-style</code> value of <code>double</code> takes precedence over <code>solid</code>, <code>dashed</code>, <code>dotted</code>, <code>ridge</code>, <code>outset</code>, <code>groove</code>, and <code>inset</code>. If two border declarations have the same width and style and differ only in color, a rule set on a more specific layer takes precedence; a style on a table cell beats a row, row group, column, column group, or table rule. Otherwise, normal CSS cascading order is followed.
An example of collapsed borders is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex04 Listing 17.4]. This table has different border values for <code><td></code> and <code><th></code> elements in the table heading and body.
Listing 17.4. Style Sheet to Collapse Borders Between Cells
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.4.css */<br />table { table-layout: auto; width: 90%;<br />border-collapse: collapse;<br />font-size: large; empty-cells: show; }<br />td, th { width: 15%; }<br />thead th { border: 0.20em dotted gray; }<br />tbody th { border: 0.25em solid black; }<br />td { border: 0.10em solid gray; }<br /></pre></div><br />
|}
The effect of collapsing these borders can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig04 Figure 17.4].
<div style="text-align: center;"> Figure 17.4. Collapsed cell borders displayed by Firefox.
[[Image:17fig04.jpg|500px]]
</div>
Separated Borders
Table cells can also be displayed with space between them. This is known as the separated borders model and is selected by a rule on the <code><table></code> cell setting the <code>border-collapse</code> property to <code>separate</code>. You'd choose this stylistic approach if you want cells presented as a distinct box, with a background surrounding each one. For example, a table meant to look like a telephone keypad would use separated borders.
In HTML, the spacing between cells is set by the <code>cellspacing</code> attribute; in CSS the same effect is accomplished by the <code>border-spacing</code> property. The <code>border-spacing</code> property sets the distance between the outer edge of adjacent cellsin other words, the spacing between each border. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table06 Table 17.6] indicates the possible values for <code>border-spacing;</code> if one value is given, that sets both the horizontal and vertical border-spacing; if two are supplied, the first is the horizontal spacing and the second is the vertical. The space between cells displays the background of the table.
{| cellspacing="0" cellpadding="5"|+ Table 17.6. Values for the <code>border-spacing</code> Property
|-
| Value
| Effect
|-
| <code>measurement</code>
| Set the horizontal and vertical cell-spacing to the same value
|-
| <code>measurement measurement</code>
| Set the horizontal and vertical cell-spacing, respectively
|-
| <code>inherit</code>
| Use the value(s) for <code>border-spacing</code> set on the containing box.
|}
<div>Watch Out!
Current versions of Internet Explorer do not support the <code>border-spacing</code> property.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex05 Listing 17.5] is a style sheet that you can apply to the schedule from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1]; it displays the cells with a horizontal spacing of <code>0.45em</code> and a vertical spacing of 1em.
Listing 17.5. Increasing the Spacing Between Cells Using the <code>border-spacing</code> Property
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.5.css */<br />table { table-layout: auto; width: 90%;<br />border-collapse: separate;<br />font-size: large; empty-cells: show;<br />border-spacing: 0.45em 1em; }<br />td, th { width: 15%; }<br />thead th { border: 0.20em dotted gray; }<br />tbody th { border: 0.25em solid black; }<br />td { border: 0.10em solid gray; }<br /></pre></div><br />
|}
As you can see from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig05 Figure 17.5], the applied style sheet spaces out the cells appropriately in the schedule.
<div style="text-align: center;"> Figure 17.5. Firefox displays spacing between cells.
[[Image:17fig05.jpg|500px]]
</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Styling Your Weekly Calendar
To get your hands dirty with table styles, why not make your own weekly schedule?
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Create an HTML table containing your weekly schedule.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>You can break it down into the hours of each day, and then group morning, afternoon, and evening rows, using <code><tbody></code> elements.<br /><br /></div>
|-
| >
| >
|-
| <div>'''3. '''</div>
| <div>Set specific styles for the <code><th></code> and <code><thead></code> elements that are the headers for your columns and rows.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Select border styles that fit your personal preferences. Try both the separated and collapsed border models, and see which one you like best. Do you want to display borders around empty cells?<br /><br /></div>
|}
|}
Table Captions
The HTML <code><caption></code> tag gives the caption, which is a label for a table. This appears within the <code><table></code> element as the first child, and it is usually presented before the table. The display box containing the <code><caption></code> is as wide as the table itself.
The location of the caption isn't fixed; the CSS <code>caption-side</code> property can be used to place the caption on a different side of the table box. The values for <code>caption-side</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17table07 Table 17.7]. This property can be set only on <code><caption></code> elements, and the default value is <code>top</code>.
{| cellspacing="0" cellpadding="5"|+ Table 17.7. Values for the <code>caption-side</code> Property
|-
| Value
| Effect
|-
| <code>bottom</code>
| Caption appears after the table.
|-
| <code>top</code>
| Caption appears before the table.
|-
| <code>inherit</code>
| Uses the value of <code>caption-side</code> set on the containing box.
|}
<div>Watch Out!
Internet Explorer does not support the <code>caption-side</code> property. Your caption always appears before the table rows in Internet Explorer.</div>
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex06 Listing 17.6] moves the caption from the top to the bottom and sets specific font and box properties on the caption, as well. The default styling for <code><caption></code> in most browsers is the default font, centered above the table.
Listing 17.6. Style Sheet to Move the Caption to the Bottom of the Table
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.6.css */<br /><br />table { table-layout: auto; width: 90%;<br />border-collapse: separate; font-size: large;<br />border: 6px double black;<br />padding: 1em;<br />margin-bottom: 0.5em; }<br />td, th { width: 15%; }<br />thead th { border: 0.10em solid black; }<br />tbody th { border: 0.10em solid black; }<br />td { border: 0.10em solid gray; }<br /><br />caption { caption-side: bottom;<br />font-size: x-large; font-style: italic;<br />border: 6px double black; padding: 0.5em; }<br /></pre></div><br />
|}
The results of applying this style sheet to the schedule from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1] can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig06 Figure 17.6]; notice that the widths of the table and the caption are the same.
<div style="text-align: center;"> Figure 17.6. The caption displayed after the table, by Firefox.
[[Image:17fig06.jpg|500px]]
</div>
Styling Columns
As noted before, each cell in a table is part of a column in addition to being in a row. Cascading Style Sheets can be used to affect the presentation of columns, but only within certain parameters. If you need to apply a set of style rules to a specific column, such as making the third column of cells have a black background, there are two approaches. The first way to do this is to set the third cell of every row to the same <code>class</code> and then to write a <code>class</code> selector. The second is to write selectors based on columns.
To designate a column or a group of columns, you use the <code><col></code> and <code><colgroup></code> tags. These can be given <code>class</code> or <code>id</code> attributes to be used in selectors, or they can have <code>style</code> attributes for inline styles.
You'll extend your schedule markup by adding the <code><colgroup></code> and <code><col></code> tags in your example. Add the following lines to the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex01 Listing 17.1] immediately after the <code><caption></code> tag to define the columns:
<div><pre><colgroup>
<col id="time">
</colgroup>
<colgroup id="days">
<col id="mon">
<col id="tue">
<col id="wed">
<col id="thu">
<col id="fri">
</colgroup>
</pre></div>
These tags define specific identifiers for columns, which you can use in your CSS rules with id selectors. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex07 Listing 17.7] contains several examples of these types of selectors.
Listing 17.7. A Style Sheet Based on Columns
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.7.css */<br /><br />table { table-layout: auto; width: 90%;<br />empty-cells: show; font-size: large; }<br />td, th { width: 15%; }<br />tbody th { border-top: 2px solid black; }<br />tbody td { border-top: 2px solid black; }<br />caption { caption-side: top; text-align: right;<br />font-size: x-large; font-style: italic; }<br />col#mon { background-color: silver; }<br />col#tue { background-color: black;<br />color: white; /* Note: color rule is ignored! */ }<br />col#wed { background-color: violet; }<br />col#thu { background-color: yellow; }<br />col#fri { background-color: lime; }<br /></pre></div><br />
|}
Only certain types of properties are allowed in column or column group rules; other properties are ignored. The appropriate properties are <code>background</code> and related properties; <code>width</code>; <code>visibility</code>; and the border properties. The <code>visibility</code> property can take the value of <code>collapse</code> to hide an entire column; the <code>border</code> properties are respected only if the collapsing border model has been chosen with the <code>border-collapse</code> property.
<div>Watch Out!
Opera and Safari do not support the use of columns and column groups in selectors. To set styles on specific columns in these browsers, you will need to set <code>class</code> attributes on specific table cells and use appropriate <code>class-based</code> selectors.</div>
The effects of applying the style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex07 Listing 17.7] to the modified HTML page, with added column markup, can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig07 Figure 17.7]. Note that the rule setting text <code>color</code> on Tuesday is ignored because only <code>background</code>, <code>width</code>, <code>visibility</code>, and <code>border</code> can be set on columns, but the <code>background-color</code> rule was still applied. This leads to black-on-black text, which is unreadable. Be careful that you aren't hiding text like this accidentally.
<div style="text-align: center;"> Figure 17.7. The effects of applying the columnar style.
[[Image:17fig07.jpg|500px]]
</div>
./ ADD NAME=CH17LEV1SEC2.HTML
=== Applying Other Styles to Tables ===
Nearly any other styles that can be applied to block elements can be applied to tables or table cells; the primary exception is that table cells never have margin properties. To set the spaces between table cells, you would instead use a separated-borders model, as described earlier, and set the <code>border-spacing</code> property on the table. The effect is the same as setting the margin between the cells.
Horizontal Alignment
As with other block boxes, the alignment of inline elements inside a table cell can be set with the <code>text-align</code> property. Use of <code>text-align</code> can easily make tables more readable, lining up columns to the <code>left</code>, <code>right</code>, or <code>center</code> as appropriate. Because <code><th></code> cells are center-aligned and <code><td></code> cells are left-aligned, columns can look a bit disorganized; <code>text-align</code> rules can correct this. For example, if you have a table listing movie show dates, you'd want to align the columns to the right, so that the times line up.
A sample style sheet using <code>text-align</code> is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex08 Listing 17.8].
Listing 17.8. Setting the Horizontal Alignment of Table Cells
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.8.css */<br /><br />table { table-layout: auto; width: 90%;<br />border-collapse: separate; border-spacing: 0.25em;<br />empty-cells: hide; font-size: small;<br />margin-left: auto; margin-right: auto; }<br />td, th { width: 15%; }<br />th { border: 2px solid black; }<br />td { border: 2px solid gray; }<br />caption { caption-side: top; text-align: left;<br />font-size: x-large; font-style: italic; }<br /><br />tbody th { text-align: right; }<br />tbody td { text-align: center; }<br /></pre></div><br />
|}
Applying this style sheet to the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17lev1sec1.html#ch17ex01 Listing 17.1] gives the effects shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig08 Figure 17.8]. For this screenshot, I've decreased the font size so that you can see the text alignment effects easily in each cell.
<div style="text-align: center;"> Figure 17.8. Aligning cells horizontally. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/17fig08_alt.jpg [View full size image]]</div>[[Image:17fig08.jpg|500px]] </div>
Vertical Alignment
The <code>vertical-align</code> property in CSS is the equivalent of the HTML <code>valign</code> property; browsers often align table cells to the vertical middle, and this can make cell contents look clumsy if the text wraps. Most of the time you are going to want to align data cells vertically so that the first line of each row is lined up on the top. Column header cells may look better aligned along the bottom. You can use the <code>vertical-align</code> property to affect these styles.
<div>By the Way
The vertical-align property was introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment."</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17ex09 Listing 17.9] is a style sheet that aligns the content of each <code><td></code> cell with the <code>bottom</code> of that cellsee Tuesday evening for an example. It also vertically centers each <code><th></code> cell with the middle value for <code>vertical-align</code>.
Listing 17.9. Setting the Vertical Alignment of Table Cells
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* schedule-17.9.css */<br />table { table-layout: auto; width: 90%;<br />border-collapse: separate; border-spacing: 0.25em;<br />empty-cells: hide; font-size: medium;<br />margin-left: auto; margin-right: auto; }<br />td, th { width: 15%; }<br />th { border: 2px solid black; }<br />td { border: 2px solid gray; }<br />tbody th { text-align: right; }<br />tbody td { text-align: center; }<br />caption { caption-side: top; text-align: right;<br />font-size: x-large; font-style: italic; }<br />td { vertical-align: bottom; }<br />th { vertical-align: middle; }<br /></pre></div><br />
|}
The results of this style sheet, when applied to the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17lev1sec1.html#ch17ex01 Listing 17.1], are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17fig09 Figure 17.9].
<div style="text-align: center;"> Figure 17.9. Aligning cells vertically.
[[Image:17fig09.jpg|500px]]
</div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Further Styles for Your Calendar
You can add to your calendar additional styles based on what you've learned this hour.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Add <code><col></code> and <code><colgroup></code> elements to your HTML, and a <code><caption></code> to title your calendar.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Move the <code><caption></code> to before or after the calendar table, based on what you think looks best.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Set the backgrounds of each day by using column-based selectors.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Adjust the alignment, colors, and fonts of your table to suit your taste, and now you've got your own calendar!<br /><br /></div>
|}
|}
./ ADD NAME=CH17LEV1SEC3.HTML
Summary
CSS rules can be used in conjunction with HTML tables to create a pleasing presentation of columnar data or layout tables. CSS browsers conceptualize tables as a series of layers: In order from most specific to least, those are the table cells, the table rows, the groups of table rows, the table columns, the groups of table columns, and the table itself. Inheritance follows these layers, as can be seen in <code>background</code> property effects.
Nearly any CSS property can be applied to table elements, although table cells don't have margins. Borders are of special importance when dealing with tables, and CSS offers two models for displaying tables: collapsed and separated. Both are set via the <code>border-collapse</code> property.
Table cells in the collapsed border model share a common border, whereas in the separated border model, a distance defined by the <code>border-spacing</code> property separates all cells from each other. In both models, the <code>empty-cells</code> property defines whether or not borders around empty table cells are displayed.
The caption, a label for the content of the table, can be located on any side of the table and styled separately. Rules can also be set by column rather than by row or cell if you use the <code><col></code> and <code><colgroup></code> tags, although the types of properties available for column styling are limited. You can improve the appearance and usability of a table by adjusting the <code>text-align</code> and <code>vertical-align</code> properties of the cells.
./ ADD NAME=CH17LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa1q1a1 Q.]'''
| When would I ever want to change the <code>display</code> property value of a tag to a different type of table element?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa1q1 A.]'''
| When using HTML, you pretty much don't ever want to do that. The browsers all understand what the default display values for each table element are supposed to be, and they often ignore attempts to change those values. The table-related display values are intended for use with XML, which doesn't have specific tags that are shown as tables. Using the <code>display</code> property, you can make XML elements show up as tables with rows, columns, and cells.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q1a1 1.]'''
| All the following rules apply to a certain cell in a table. What color will the background of that cell be?
<div><pre>tbody { background-color: green; }<br />table { background-color: blue; }<br />tr { background-color: transparent; }<br />col { background-color: yellow; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q2a2 2.]'''
| You want to set the spacing between table cells to 10 pixels in both the horizontal and vertical directions. Which of the following CSS rules accomplishes that?
<div># <div><code>table { cell-spacing: 10px; table-layout: separate; }</code></div>
# <div><code>table { cell-spacing: 10px; border-collapse: collapse; }</code></div>
# <div><code>table { border-spacing: 10px; border-collapse: separate; }</code></div>
# <div><code>table { cell-spacing: 10px; border-collapse: separate; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q3a3 3.]'''
| How would you write a rule to make the caption appear after the table in a smaller, italic font with a thin black border around it?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q1 1.]'''
| The background color will be green. In order from most specific to least specific, the selectors are <code><tr></code>, <code><tbody></code>, <code><col></code>, and <code><table></code>. Because the background color of the table row is <code>transparent</code>, the next selector's <code>background-color</code> shows through, and that is the <code>green</code> of the <code><tbody></code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q2 2.]'''
| The correct answer is (c). There is no <code>cell-spacing</code> property; the correct name is <code>border-spacing</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch17qa2q3 3.]'''
| Here is one such rule:
<div><pre>caption { caption-side: bottom;<br />font-size: smaller;<br />font-style: italic; <br />border: thin solid black; }<br /></pre></div><br />
|}
Exercise
Tables are all around us, and not just for page layout. Any time in which you're building a grid that conveys information based on position in that grid, you're dealing with a table.
Write up some tables based on what you encounter around youa bus schedule, a campus phone and office directory, columns of weights and measures, accounting records, or whatever else strikes your fancy.
Use the HTML tags and style rules presented in this hour to create data tables. Get creativehow can you best present this tabular data in a clear, straightforward manner where the styles enhance the tables?
./ ADD NAME=CH18.HTML
okt41r4ggfdxvhq98b5scgdzzcb5lhr
User:Bartlett/18
2
2122
39228
5522
2026-04-13T06:03:22Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39228
wikitext
text/x-wiki
./ ADD NAME=CH18.HTML
Hour 18. Box Sizing and Offset
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* How browsers calculate the width and height dimensions of a display box
* Which properties can control the dimensions of a box
* What browsers will do if a box's content exceeds the dimensions of the box, and how you can control the result with CSS
* How to reposition a box from its original location, using relative positioning and the four offset properties
|}
./ ADD NAME=CH18LEV1SEC1.HTML
Sizing Content
When laying out a page, it's not always enough to specify only where content should be placed, as you can do with the <code>float</code> property (or the positioning properties, which you'll learn about in this hour and the next). To create effective layouts, you need to set the size of display boxes. In HTML, this is done with the <code>height</code> and <code>width</code> attributes; unsurprisingly, those are the names of the CSS properties that control a content box's dimensions.
To illustrate the use of the <code>width</code> and <code>height</code> attributes, I've created a sample HTML page that is used use for most of this hour. You can see this in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex01 Listing 18.1], or you can download it from the book's website.
Listing 18.1. This HTML Page Has Unsized Boxes
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- sizes-18.1.html --><br /><html><br /><head><br /><title>Tucson Valley News</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />h3 { font-style: oblique;<br />font-weight: normal; }<br />#nav { float: right; }<br />#nav ul { padding-left: 0; }<br />#nav li { display: block; }<br /><br />div { border: 1px solid black; margin: 1em; }<br /></style><br /></head><br /><body><br /><div id="banner"><br /><h1>Tucson Valley News</h1><br /></div><br /><div id="nav"><br /><h4>Tucson Valley News Quick Navigation<br />Links</h4><br /><ul><br /><li><a href="/breaking/">Breaking<br />News</a></li><br /><li><a href="/current/">Current<br />Issue</a></li><br /><li><a href="/editorial/">Editorial<br />Page</a></li><br /><li><a href="/subscribe/">Subscriptions<br /></a></li><br /></ul><br /></div><br /><div id="main"><br /><h2>Desert Museum hires webmaster</h2><br /><h3>Congrats to Liz Bartlett</h3><br /><p>The <a href="http://www.desertmuseum.org/"><br />Arizona-Sonora Desert Museum</a> has hired<br /><a href="http://www.khyri.com/">Liz<br />Bartlett</a> to be their new webmaster.</p><br /><p>Founded in 1952 by William Carr and Arthur<br />Pack, the Desert Museum is a private, nonprofit<br />organization dedicated to the conservation<br />of the Sonoran Desert.</p><br /><p>Liz Bartlett has over 11 years' experience in<br />web design, and was a founder of Idyll<br />Mountain Internet in 1995. She now lives in<br />Tucson with her husband Kynn.</p><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
The intent of the embedded style sheet within [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex01 Listing 18.1] is to create a very simple "newspaper" layout, with a headline at the top, a navigation menu at the right, and an article to the left and middle. To help you keep track of the display boxes involved, CSS rules add borders and margins to each <code><div></code>.
When a browser displays this page, it determines the layout based on the space available and how large the content is. You can see this in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig01 Figure 18.1]note how the <code><h4></code> headline in the navigation bar expands that box out to fill the available space. It's not the best design, especially because the <code><h4></code> isn't line-wrapping nicely.
<div style="text-align: center;"> Figure 18.1. The browser tries to determine the size and placement of each box, and doesn't do very well. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig01_alt.jpg [View full size image]]</div>[[Image:18fig01.jpg|500px]] </div>
The <code>width</code> and <code>height</code> Properties
To correct the problems displayed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig01 Figure 18.1], you need to use the <code>width</code> and <code>height</code> properties. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch17.html#ch17 Hour 17], "Styling Tables," briefly introduced <code>width</code>, and in this hour you'll learn to use it with all block content, as well as with its fraternal twin, <code>height</code>.
A CSS display box actually has two widths: the content width and the box width. The content width is, as you might imagine, the width of the box's content area; it is the area where the box's content exists, within the padding, the border, and the margin; this is what's set by the <code>width</code> property. The box width is the width of the entire box, including the left and right padding, the left and right border, and the left and right margin, as well as the content width. You can see this visually displayed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig02 Figure 18.2].
<div style="text-align: center;"> Figure 18.2. Content width and box width.
[[Image:18fig02.jpg|494px]]
</div>
The content height and box height are determined in the same way. The CSS properties <code>width</code> and <code>height</code> are used to control the size of the content width; the box width and box height can't be set directly. Instead, you can control the box width and height by setting appropriate padding, border, and margin values that add to the content width and height.
Values for <code>width</code> and <code>height</code> can be measurements, such as <code>3em</code> or <code>5px</code>. They can also be percentage values, such as <code>20%</code>. The percentage is based on the height or width of the parent box's content area. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex02 Listing 18.2] shows a style sheet that fixes the text wrap problem from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig01 Figure 18.1] by using <code>height</code> and <code>width</code> properties to help lay out the page.
Listing 18.2. Setting <code>height</code> and <code>width</code> Values via CSS
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>#banner { width: 80%; height: 4em; }<br />#nav { width: 20%; }<br />#nav { height: 15em; }<br />#main { width: 60%; }<br /></pre></div><br />
|}
This sets a <code>height</code> and <code>width</code> on the banner, making it at least 4ems tall, and with a width of <code>80%</code> of the available screen space. The navigation bar is <code>20%</code> wide, and the height is <code>10ems</code>. The main article space is <code>60%</code> wide.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig03 Figure 18.3], you can see the result of applying this style sheet to the HTML page of [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex01 Listing 18.1]. Because a <code>width</code> has been set on the navigation bar, the text is forced to wrap. Also, there is extra white space at the bottom of the navigation bar; the <code>height</code> has been set, and the space is reserved even if the content does not fill that space. There is no height for the <code>#main <div></code>, so the box ends when the text ends.
<div style="text-align: center;"> Figure 18.3. Boxes set to specific heights and widths. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig03_alt.jpg [View full size image]]</div>[[Image:18fig03.jpg|500px]] </div>
You should notice one more thing here. The <code>#banner</code> element is <code>80%</code> wide, and the <code>#nav</code> element is <code>20%</code> wide. You'd think they'd line up, right? But look carefully at [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig03 Figure 18.3]. If the two boxes were right on top of each other, they'd intersect. Why is that?
The <code>width</code> property sets only the content width, not the actual size taken up by the box. The true box width includes the margin (which is <code>1em</code> in this example), the border (which is <code>1px</code>) and any margins set. So the <code>#banner</code>'s content width may be <code>80%</code>, but the box width is <code>80% + 2em + 2px</code>remember to add in both the left and right sides!whereas the <code>#nav</code> element is <code>20% + 2em + 2px</code>. Together they add up to <code>100%</code> of the screen, plus <code>4em</code>, plus <code>4px</code>. Oops.
The Internet Explorer <code>width</code> Bug
Unfortunately, previous versions of Internet Explorer for both Windows and Macintosh have a bug that miscalculates content width. Internet Explorer prior to version 6 doesn't consider the content width to be just the width of the content area of a box; instead, it includes the padding and the border width, as well. This is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig04 Figure 18.4].
<div style="text-align: center;"> Figure 18.4. How Internet Explorer 5.5 (and earlier) improperly calculates widths.
[[Image:18fig04.jpg|490px]]
</div>
This leads to a problem where Internet Explorer miscalculates the size of a display box, throwing off the display of your web page. Fortunately, there is a workaround for this bug. The trick is to create two <code><div></code> elements instead of just one, thus using two boxes. The first <code><div></code> box has <code>width</code> and <code>margin</code> properties set on it. The second box is located inside the first and has <code>border</code> and <code>padding</code> properties. Boxes nested in this way display properly in Internet Explorer, as well as in properly compliant browsers, such as Firefox, Opera, and Safari.
This bug was fixed in Internet Explorer 6; however, to get correct <code>width</code> calculations, you need to use a correct <code>DOCTYPE</code> statement at the beginning of your document. If you don't use a <code>DOCTYPE</code> statement, IE 6 displays the page using a backward-compatible method identical to IE 5, which means the buggy version. For more on <code>DOCTYPE</code> switching, see [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp]. Keep in mind that some Internet Explorer users are still using Internet Explorer 5.0 or 5.5, so the type of workaround described in this hour may still be necessary on your site even if you use the correct <code>DOCTYPE</code>.
Minimum and Maximum Dimensions
Sometimes you might not want to set specific sizes for dimensions; instead, you might want more flexible designs that allow something to range in size between two values. A constraint is a value beyond which a box isn't allowed to grow or shrink; if the size is smaller than the minimum constraint, the size is that minimum, and if it's larger than the maximum constraint, the size is that maximum value.
For example, you might want a navigation bar to be as wide as 20% of the screen most of the time, but if the browser's window is only 500 pixels across, this may be too small to display your navigation links. A minimum size of <code>10em</code> would therefore be a constraint placed on the width.
The constraints for <code>width</code> are set with the <code>min-width</code> and <code>max-width</code> properties; for <code>height</code>, the values are <code>min-height</code> and <code>max-height</code>. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex03 Listing 18.3] is a style sheet that sets constraints on the boxes in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex01 Listing 18.1].
Listing 18.3. A Style Sheet to Constrain the Maximum and Minimum Sizes of Display Boxes
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* sizes-18.3.css */<br />#banner { width: 60%;<br />min-width: 500px;<br />min-height: 5em;}<br />#nav { width: 30%; min-width: 200px; }<br />#nav { max-height: 15em; }<br />#main { min-width: 300px;<br />width: 50%;<br />max-width: 600px; }<br /></pre></div><br />
|}
You can see the results of using this style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig05 Figure 18.5].
<div style="text-align: center;"> Figure 18.5. Setting box size with constraints. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig05_alt.jpg [View full size image]]</div>[[Image:18fig05.jpg|500px]] </div>
This style sheet gives the navigation menu a width of <code>30%</code>, which works decently enough unless the browser window is small. In such cases, the minimum width is set to <code>200px</code>. The <code>#banner</code> is <code>60%</code> of the space available, or a minumum of 500 pixels wide; it is also a minimum height of <code>5em</code>, although there is no extra content to fill in that space, which is just left blank. The <code>#main</code> section varies between 300 and 600 pixels, based on the width of the browser window. If the browser display space is less than 600 pixels, <code>#main</code> is <code>300px</code> (the <code>min-width</code> value); between 600 and 1200 pixels wide, <code>#main</code> is 50% of the display space; and if the browser's display area is more than 1200 pixels wide, the max-width constrains it to <code>600px</code> and no more.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig06 Figure 18.6] demonstrates what happens when the display area changesin this case, the browser window has been decreased to about two thirds of the screen, and the minimum values are being used for each window.
<div style="text-align: center;"> Figure 18.6. Shrinking the browser window brings constraints into play. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig06_alt.jpg [View full size image]]</div>[[Image:18fig06.jpg|500px]] </div>
./ ADD NAME=CH18LEV1SEC2.HTML
=== Content Overflow ===
If a display box's height hasn't been set by the <code>height</code> property, the height is calculated automatically to take up enough room for all the content. But what happens if a <code>height</code> property has been set that doesn't allow enough space for all the content? This creates a situation called overflow. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex04 Listing 18.4] is a style sheet specifically designed to create overflow.
Listing 18.4. A Style Sheet Where the Size of the Content Exceeds the Height
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* sizes-18.4.css */<br />#banner { width: 80%; height: 1.5em; }<br />#nav { width: 20%; }<br />#nav { height: 8em; }<br />#main { width: 500px; height: 450px; }<br /></pre></div><br />
|}
As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig07 Figure 18.7], the content of the columns simply spills out the bottom of the box because there's not enough room. This is the default behavior for overflow, but you can change it by using the <code>overflow</code> property.
<div style="text-align: center;"> Figure 18.7. Sometimes content just won't fit inside a box, and it overflows. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig07_alt.jpg [View full size image]]</div>[[Image:18fig07.jpg|500px]] </div>
The <code>overflow</code> Property
To change what happens when a box's content overflows, you can set the <code>overflow</code> property to one of the values shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18table01 Table 18.1]. The default value is <code>visible</code>, which has the effect shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig07 Figure 18.7].
{| cellspacing="0" cellpadding="5"|+ Table 18.1. Values for the <code>overflow</code> Property
|-
| Value
| Effect
|-
| <code>auto</code>
| The browser determines what to do with overflowing content, choosing either <code>scroll</code> or <code>visible</code>.
|-
| <code>hidden</code>
| Overflowing content is clipped and not displayed.
|-
| <code>scroll</code>
| A scrollable box is used to provide access to all content.
|-
| <code>visible</code>
| The overflowing content spills out of the box.
|-
| <code>inherit</code>
| Use the value of <code>overflow</code> set on the containing box.
|}
The <code>scroll</code> value provides scrollbars at the edges of the display box that let the user access all the content. The <code>hidden</code> value prevents that content from being displayed, so it should be used with care. A value of <code>auto</code> leaves the decision up to the browser; because this can vary from browser to browser, I advise against relying on it.
Two examples of the <code>overflow</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex05 Listing 18.5], a style sheet that sets one column to <code>scroll</code>, and the other to <code>hidden</code>.
Listing 18.5. A Style Sheet Using the <code>overflow</code> Property
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* sizes-18.5.css */<br />#banner { width: 80%; }<br />#nav { width: 20%; }<br />#nav { height: 8em;<br />overflow: scroll; }<br />#main { width: 500px; height: 300px;<br />overflow: hidden; }<br /></pre></div><br />
|}
As you can see in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig08 Figure 18.8], a scrollbar gives access to the content in the menu bar. How do you see the content in the left column? You don't. Only the content that fits in the box is visible. This is known as clipping, a term that refers to cutting away (and not displaying) all the extra content that won't fit. To prevent your content from being lost to clipping, you can avoid using <code>overflow: hidden</code> and instead set <code>overflow: scroll</code> on elements that might exceed the space you've allocated.
<div style="text-align: center;"> Figure 18.8. Overflowing content can scroll or be clipped. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/18fig08_alt.jpg [View full size image]]</div>[[Image:18fig08.jpg|500px]] </div>
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Create Scrollable Panels with CSS
One of the more controversial HTML tags has historically been <code><frame></code>, which enables you to make distinct panels for content, which can be scrolled separately from the rest of the page. The <code><frame></code> tag (and its sibling <code><iframe></code>) is considered harmful by some web development gurus because of accessibility problems and other perceived flaws. Using what you learned this hour, you can now make separately scrollable sections of your web page without using <code><frame></code> or <code><iframe></code>. Follow these steps:
{| border="0"
|-
| <br />
| >
|-
| <div>'''1. '''</div>
| <div>Make a web page with a reasonably large amount of text to readperhaps a letter, a short story, or even a style sheet listing. (If it's a style sheet, try setting the <code>white-space</code> property to <code>pre</code>, as described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10.html#ch10 Hour 10], "Text Colors and Effects.")<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Enclose the text within a <code><div></code> and give that <code><div></code> a class such as <code>scrollable</code>.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Set a <code>width</code> and <code>height</code> for the <code>.scrollable</code> class in a style sheet, and link to or embed that style sheet in the HTML page. Give it a <code>border</code> as well, so you know where the content starts to overflow.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Test the page nowyou will see something similar to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig07 Figure 18.7], with text overflowing the boundaries of the box.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Add a rule for your <code>.scrollable</code> box that sets the <code>overflow</code> property to <code>scroll</code>.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>Try it out in your browseryou should now have a scrollable text window!<br /><br /></div>
|}
|}
Relative Positioning
CSS offers several ways to position boxes on the screen. You've already learned about the <code>float</code> property in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment." You can also use the <code>position</code> property to designate a box's location on the screen.
A box that has been placed according to relative positioning has been located relative to the position in which that box would normally appear, modified by an offset. This offset is designated by the <code>top, left, right</code>, and <code>bottom</code> properties.
You declare a box to be relatively placed by setting the <code>position</code> property on it with a value of <code>relative</code>. The possible values for <code>position</code> are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18table02 Table 18.2].
{| cellspacing="0" cellpadding="5"|+ Table 18.2. Values for the <code>position</code> Property
|-
| Value
| Effect
|-
| <code>absolute</code>
| Position the box relative to the containing box.
|-
| <code>fixed</code>
| Position the box relative to the containing box, and don't move it even if the page scrolls.
|-
| <code>relative</code>
| Position the box relative to its normal position.
|-
| <code>static</code>
| Position the box where it should normally be placed.
|-
| <code>inherit</code>
| Use the <code>position</code> value of the containing box.
|}
You'll learn about the <code>position</code> values <code>absolute</code> and <code>fixed</code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], "Absolute and Fixed Positioning." The value <code>static</code> simply tells the browser to not apply any special positioning and to ignore the four offset values.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex06 Listing 18.6] is an HTML page with an embedded style sheet to relatively position one of the boxes outside of its normal position.
Listing 18.6. Relative Positioning Shown via a Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- relative-18.6.html --><br /><html><br /><head><br /><title>Three Boxes in a Row</title><br /><style type="text/css"><br />.demobox {<br />border: 3px solid black; width: 8em;<br />font-family: Verdana, sans-serif;<br />background-color: white;<br />padding: 1em; margin: 0.5em; }<br />#mars { position: relative;<br />left: 5em; top: 2em; }<br /></style><br /></head><br /><body><br /><div class="demobox" id="earth"><br />Earth</div><br /><div class="demobox" id="mars"><br />Mars</div><br /><div class="demobox" id="jupiter"><br />Jupiter</div><br /></body><br /></html><br /></pre></div><br />
|}
As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig09 Figure 18.9], the space that would normally be taken up by the box has still been set aside for it, although the box itself is now located 5 ems to the right and 2 ems down from where it would normally be.
<div style="text-align: center;"> Figure 18.9. One of the planets is out of position.
[[Image:18fig09.jpg|300px]]
</div>
The <code>top, right, bottom</code>, and <code>left</code> Properties
As shown in the previous example, the <code>top</code> and <code>left</code> properties can be used to set the distance by which a relatively positioned box is placed, with respect to the static position. The <code>bottom</code> and <code>right</code> properties also can be used to designate offsets. The types of values that can be given to these offset properties are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18table03 Table 18.3]. The default value is <code>auto</code>, which means that it is up to the browser to determine where something should be placedwhich is to say it places the box where it belongs according to normal (<code>static</code>) flow.
{| cellspacing="0" cellpadding="5"|+ Table 18.3. Values for the Offset Properties
|-
| Value
| Effect
|-
| <code>measurement</code>
| Offset the box by some amount, toward the "inside."
|-
| <code>negative-measurement</code>
| Offset the box by some amount, toward the "outside."
|-
| <code>percentage</code>
| Offset the box by a percentage, toward the "inside."
|-
| <code>negative-percentage</code>
| Offset the box by a percentage, toward the "outside."
|-
| <code>auto</code>
| Calculate the offset automatically.
|-
| <code>inherit</code>
| Use the value of the offset property from the containing box.
|}
Because positive values are toward the center point of the context box, some of these offsets can seem backward in effect from what you'd expect. For example, setting a <code>left</code> value of <code>4em</code> actually moves the box to the right; a <code>right</code> value of <code>4em</code> moves the box to the left; and a <code>top</code> value of <code>-4em</code> moves the box up, not down. You need to remember this when placing boxes. Positive values are toward the middle of the box, and negative are away from the middle.
You can also use negative values to move a box away from the center of its normal location. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex07 Listing 18.7] is a style sheet that can be used to position the planet-named boxes from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex06 Listing 18.6].
Listing 18.7. Moving Boxes with Relative Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>.demobox {<br />border: 3px solid black; width: 8em;<br />font-family: Verdana, sans-serif;<br />background-color: white;<br />padding: 1em; margin: 0.5em; }<br />#earth {<br />position: relative;<br />top: -2em; right: -5em; }<br />#mars {<br />left: 5em; top: 2em; }<br />#jupiter {<br />position: relative;<br />left: 10em; }<br /></pre></div><br />
|}
The effects of applying [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex07 Listing 18.7] to the HTML page of [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18ex06 Listing 18.6] are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18fig10 Figure 18.10]. The Earth box has been moved up and right; in fact, the top of the box is off the screen entirely. Likewise, the Jupiter box has moved far to the rightremember that the <code>left</code> value moves the box to the right when positive. A horizontal scroll bar has appeared for Jupiter; you can scroll to the right to see the whole box, even though you can't scroll up to see the Earth box.
<div style="text-align: center;"> Figure 18.10. Boxes placed with relative offsets, shown in Firefox.
[[Image:18fig10.jpg|300px]]
</div>
The Mars box didn't move this time. Why not? Because there is no <code>position</code> property for <code>#mars</code> in this style sheet, the <code>left</code> and <code>top</code> values are ignored. The default value for <code>position</code> is <code>static</code>, and unless you set <code>position: relative</code>, the box isn't offset.
./ ADD NAME=CH18LEV1SEC3.HTML
Summary
The CSS language provides a number of properties for fine-tuning your layout, giving functionality that actually exceeds that of HTML layout tables, such as scrollable display boxes.
These properties include the <code>width</code> and <code>height</code> properties for setting a box's dimensions, as well as the <code>min-width, min-height, max-width</code>, and <code>max-height</code> properties that constrain a box's dimensions.
Content that naturally exceeds the dimensions of its display box is said to have overflowed. The <code>overflow</code> property can be used to determine whether the excess content is shown, clipped, or shown with a scrollbar.
In addition to sizing boxes, you can also move them from their original positions with relative positioning. Setting the <code>position</code> property to <code>relative</code> turns on relative positioning for that box, and the four offset properties<code>top, right, bottom</code>, and <code>left</code>can be used to adjust the box's location.
./ ADD NAME=CH18LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q1a1 Q.]'''
| What's the difference between relative positioning, absolute positioning, and fixed positioning?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q1 A.]'''
| Giving a position rule to a box is the way to set all these types of positioning initially, but each is very different in practice. Relative positioning always involves moving a box from its original location, and always reserves the space for that box in the layout. Absolute and fixed positioning, which you'll learn about in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], place the box relative to a containing block, not the original position of the box, and neither of these types of positioning reserves the space where the box would normally appear.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q2a2 Q.]'''
| When would I use relative positioning instead of absolute or fixed positioning?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q2 A.]'''
| Relative positioning is useful if you need to make small changes in the location of a box, such as moving a header a little to the left or adjusting the vertical position of a box. You can also use a <code>position: relative</code> rule without any offset properties to establish a containing box for absolute positioning, as you'll learn in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19]. In fact, this is probably the most common use for the <code>relative</code> value for <code>position</code>. It's rare to create style sheets that actually use relative positioning for offsets.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q3a3 Q.]'''
| You wrote that there's a bug in Internet Explorer 5 related to box dimensions. Do I really need to worry about that in this day and age?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa1q3 A.]'''
| Yes! At least, as of early 2006, Internet Explorer versions 5 and 5.5 are still used by a decent portion of the web-navigating population. You wouldn't want one user in twenty to experience problems on your site, would you? As described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3], "Browser Support for CSS," IE 5 and 5.5 are quirky browsers, and require special considerations. The method described in this hourusing two <code><div></code>s to set box propertiesis one such approach, and using a browser filter is another. You'll learn about browser filters in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q1a1 1.]'''
| The browser's display window is 500 pixels wide. How wide will an <code><h1></code> be, assuming it's the first element of the <code><body></code> and that the following CSS rule applies to it?
<div><pre>h1 { width: 20%; min-width: 125px;<br />max-width: 200px; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q2a2 2.]'''
| Which of these rules will make scrollbars on a <code>blockquote?</code>
<div># <div><code>blockquote { height: 175px; scroll: auto; }</code></div>
# <div><code>blockquote { overflow: scroll; }</code></div>
# <div><code>blockquote { scroll: overflow; }</code></div>
# <div><code>blockquote { height: 175px; overflow: scroll; }</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q3a3 3.]'''
| Which of the following best describes relative positioning?
<div># <div>Subsequent text is flowed around the positioned box, relative to the box's new left or right location.</div>
# <div>The box is held in a location relative to where it is located, even if the page is scrolled.</div>
# <div>Relative to the box's original location, the box is offset by a certain distance.</div>
# <div>The box is placed relative to its containing box.</div></div>
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q4a4 4.]'''
| Which of these offset declarations moves a display box 20 pixels to the right?
<div># <div><code>right: 20px;</code></div>
# <div><code>left: 20px;</code></div>
# <div><code>left: -20px;</code></div>
# <div><code>right: -20px;</code></div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q1 1.]'''
| The <code><h1></code> tag will be 125 pixels wide, the minimum width. The calculated width, 100 pixels (20% of 500), is smaller than the <code>min-width</code> value, so it is increased to the value of <code>min-width</code>. Because it is not larger than the <code>max-width</code> value of <code>200px</code>, the final size is 125 pixels.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q2 2.]'''
| The correct answer is (d). There is no CSS property named <code>scroll</code>, and the <code>height</code> property is necessary or else the content doesn't overflow.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q3 3.]'''
| Choice (c) is a description of relative positioning, (a) describes floating content (from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15]), (b) describes fixed positioning, and (d) defines absolute positioning. (You'll learn about those latter two in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19].)
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch18qa2q4 4.]'''
| Both (b) and (d) shift a box to the right. Remember that positive offsets are toward the middle of the box, and negative offsets are away from it.
|}
Exercise
One of the trickier things to understand about relative positioning is that box properties offset in a funny direction. If you want to move something to the right, you set a positive <code>left</code> value, or a negative <code>right</code> value. To move something down, you set the top value. To get a grasp on the way that box offsets always point toward the middle of the box, create a web page with a relatively positioned box and then play with the various options for offset properties. This will be good practice for [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19] because offset properties are also used with the other possible values for the <code>position</code> property.
./ ADD NAME=CH19.HTML
6eq4nwz09t0zm3rol1zg0rgzvlsqnns
User:Bartlett/19
2
2123
39229
5523
2026-04-13T06:03:23Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39229
wikitext
text/x-wiki
./ ADD NAME=CH19.HTML
Hour 19. Absolute and Fixed Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* The types of positioning schemes available for placing a display box on the screen
* How to place an HTML element in relation to its containing block
* How to use CSS positioning to create a simple cartoon combining a photograph, text, and graphics
* How to control clipped content that is larger than the size allotted to a display box
* How to create rounded corners for boxes and position them with CSS
* How to designate which items should appear in front or back when content is layered over other content
* How to fix an HTML element on the screen, even if the page scrolls
|}
./ ADD NAME=CH19LEV1SEC1.HTML
Positioning Content
Whenever you include an HTML element on a page, it generates a display box, as you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch06.html#ch06 Hour 6], "The CSS Box Model." Normally, these boxes are placed one after another or within another box, based on the structure of the document and whether the box is an inline or block box. This is known as normal flow in the CSS specifications. Whenever you move an element's display box to a new location, you are disrupting the normal flow to create a new layout.
One way to disrupt the normal flow of content is by using the <code>float</code> (and <code>clear</code>) properties, which you learned about in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment." Floating content moves out of the normal order to one side or the other, and subsequent content flows around it.
Relative positioning preserves the normal content flow by reserving the appropriate amount of space for the relatively positioned element, and then moving it relative to that location.
There are two other types of positioning techniques you can use, called absolute and fixed positioning. These methods also use the <code>position</code> property and the four offset properties<code>top, right, bottom</code>, and <code>left</code>introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], "Box Sizing and Offset," but the exact meanings of these properties are different from how they're used in relative positioning.
The first way to lay out the page with CSS is to use styles that position an element relative to a specific context on the page. The <code>position</code> property is used to choose that context. Positioned content is offset from the context by a specific amount that you can set with the <code>top, right, bottom</code>, or <code>left</code> properties.
<div>By the Way
As a historical footnote, the positioning properties in CSS were originally introduced in a draft produced between the CSS Level 1 and CSS Level 2 recommendations and were called CSS-P, for CSS Positioning. CSS-P properties were partially implemented by the browsers and were formally added to the CSS language when CSS Level 2 was released.</div>
The Containing Block
To properly place a display box by using positioning styles, you must establish the context of that position. You accomplish this by using the <code>position</code> property, which defines how a box should be positioned. The values for the <code>position</code> property were listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18lev1sec2.html#ch18table02 Table 18.2] in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18]; the two we're concerned with in this hour are <code>position: absolute</code> and <code>position: fixed</code>.
When you set the <code>position</code> property to <code>absolute</code>, you are taking the element out of the normal flow of text and locating it relative to another box. This is called the containing block. The positioned element is placed relative to this containing block based on the offset properties <code>top, right, bottom</code>, and <code>left</code>.
The containing block is one of the parent boxes that contains the box being displayedbut it's not necessarily the immediate parent. The containing block is defined as the nearest ancestor to that box that has a <code>position</code> property value set on it (to something besides <code>static</code>). If none of the box's ancestors has a <code>position</code> property set, then the containing block is the display box of the <code><body></code> tag.
<div>Did you Know?
The easiest way to force a box to become a containing block for everything within itand thus change the context in which those elements are positionedis to set the <code>position</code> property of that box to <code>relative</code>. This tells the browser to reserve the space that the box would normally take up, and then move the box by the measurements given by the <code>top, right, bottom</code>, and <code>left</code> properties. If you don't set any values for the offsets, however, they default to 0and the box doesn't move. The effect of using <code>position: relative</code> without offsets is to simply create a new containing block context.</div>
./ ADD NAME=CH19LEV1SEC2.HTML
Absolute Positioning
In absolute positioning, the display box is placed in relation to the containing block, offset by a certain amount. The box is removed from the normal flow, and in fact the space normally taken up by the absolutely positioned box isn't even allocated for it. Instead, it appears somewhere else, possibly even overlaying existing content.
The containing block in absolute positioning is initially set to be the box of the <code><body></code> tag, and absolutely positioned elements are placed relative to the rest of the page. However, if an ancestor box of an element is positioned (with <code>absolute, relative</code>, or <code>fixed</code> positioning), that positioned box becomes the new containing block for absolute positioning.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex01 Listing 19.1] is a web page with embedded style sheet that sets the inner <code><div></code> to use absolute positioning, and specifies an offset of <code>4em</code> on the left and top from the outer box, which has been set to <code>position: relative</code> to make it the new containing block for its children.
Listing 19.1. A Web Page Demonstrating Absolute Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- absolute-19.1.html --><br /><html><br /><head><br /><title>Three Boxes in a Row</title><br /><style type="text/css"><br />.demobox {<br />border: 3px solid black; width: 8em;<br />font-family: Verdana, sans-serif;<br />background-color: white;<br />padding: 1em; margin: 0.5em; }<br />#mars { position: absolute;<br />right: 2em; top: 6em; }<br /></style><br /></head><br /><body><br /><div class="demobox" id="earth"><br />Earth</div><br /><div class="demobox" id="mars"><br />Mars</div><br /><div class="demobox" id="jupiter"><br />Jupiter</div><br /></body><br /></html><br /></pre></div><br />
|}
So what effect does the embedded style sheet have? [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig01 Figure 19.1] shows absolute positioning at work. The middle box, Mars, has been removed entirely from its position in the normal flow of layout; unlike relative positioning, absolute positioning does not leave the appropriate space for the positioned object in its original position.
<div style="text-align: center;"> Figure 19.1. Absolute positioning is based on the containing block.
[[Image:19fig01.jpg|300px]]
</div>
Offset Properties in Absolute Positioning
The <code>#mars</code> box in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig01 Figure 19.1] has been positioned at <code>right: 2em</code> and <code>top: 6em</code>this is not relative to the original position, but to the containing block of the <code>#mars</code> box. In this case, there are no ancestors to <code>#mars</code> that have a position property, so the containing block is the <code><body></code> element of HTML. Thus, the right side of the box is placed 2 ems in from the right side of the browser's display area, and the top side of the box is placed 6 ems down from the top.
The <code>top, right, bottom</code>, and <code>left</code> properties have different meanings when used with absolute positioning than their meanings under relative positioning. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19table01 Table 19.1] is a summary of these values and their effects; contrast this with [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18lev1sec2.html#ch18table03 Table 18.3] in the last hour.
{| cellspacing="0" cellpadding="5"|+ Table 19.1. Absolute Positioning Values for the Offset Properties
|-
| Value
| Effect
|-
| <code>measurement</code>
| Position the edge of the box toward the "inside" of the containing block
|-
| <code>negative-measurement</code>
| Position the edge of the box toward the "outside" of the containing block
|-
| <code>percentage</code>
| Position the edge of the box toward the "inside" of the containing block, as a percentage of the containing block's dimension
|-
| <code>negative-percentage</code>
| Position the edge of the box toward the "outside" of the containing block, as a percentage of the containing block's dimension
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex02 Listing 19.2] is a style sheet that can replace the embedded style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex01 Listing 19.1] with one that uses percentages. (To make it more clear where the boxes meet, the margin property has been removed.)
Listing 19.2. Percentages for Absolute Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* absolute-19.2.css */<br />.demobox {<br />border: 3px solid black; width: 8em;<br />font-family: Verdana, sans-serif;<br />background-color: white;<br />padding: 1em; }<br />#mars { position: absolute;<br />right: 50%; bottom: 50%; }<br />#earth { position: absolute;<br />left: 50%; top: 50%;}<br />#jupiter { position: absolute;<br />left: -50%; bottom: 100%; }<br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig02 Figure 19.2] is the result of applying the style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex02 Listing 19.2] to the HTML page in 19.1.
<div style="text-align: center;"> Figure 19.2. Percentages used to place boxes absolutely.
[[Image:19fig02.jpg|300px]]
</div>
Notice that the Mars and Earth boxes almost touch in the center. This is because they have values of <code>50%</code> set for their <code>right</code> and <code>left</code> values, and <code>50%</code> for their <code>top</code> and <code>bottom</code> values. However, the effects of these rules are not the same; <code>50% right</code> and <code>50% left</code> are two different positions. The <code>right</code> property lines up the right edge of the box along that halfway line, and the <code>left</code> property positions the left edge of the box at the same line.
There are three boxes in the HTML source code, but only two boxes in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig02 Figure 19.2]. Where's Jupiter? The rule of <code>-50% left</code> moved the left side of the box half a screen's width off to the left of the display window. The <code>bottom: 100%</code> rule moved the bottom of the box a full screen's height up, so it's off the top of the screen. The Jupiter box is located off to the upper left, where we can't see it.
<div>Watch Out!
It's entirely possible to position a box off the visible part of the page. For example, if you use a value of <code>-1000px</code> for <code>left</code> and <code>-800px</code> for top, the box will probably be displaced completely off the page. Such a box still "exists," but just won't be seen. In some cases, this may be exactly what you wantin [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks," you'll learn how this type of technique can be used to hide content from certain browsers, with varying degrees of success.</div>
You can also use the <code>top, right, bottom</code>, and <code>left</code> properties to place content atop existing content when you use absolute positioning. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex03 Listing 19.3] is an HTML file that contains four elements to position: a picture of a coyote, a bit of text, a graphic of a triangle, and a picture credit.
Listing 19.3. Parts of a Cartoon to Be Positioned
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- cartoon-19.3.html --><br /><html><br /><head><br /><title>Coyote Cartoon</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />a:link, a:visited { <cs>text-decoration</cs>: none;<br />color: inherit; font-weight: bold; }<br />#cartoon { padding: 16px; margin: 10px auto;<br />border: 1px solid black; }<br />#bubble { font-size: 24px;<br />text-align: center;<br />border: 1px solid black;<br />background-color: white; color: black;<br />width: 250px; padding: 2px; }<br />#credits { font-size: 14px;<br />bottom: 16px; right: 20px; }<br /></style><br /></head><br /><body><br /><div id="cartoon"><br /><img src="coyote.jpg" alt="Coyote"><br /><div id="bubble"><br />Hey! I can see my house from here!<br /></div><br /><img src="balloontail.png" id="tail" alt=""><br /><div id="credits"><br />Picture by<br /><a href="http://kynn.com/">Kynn Bartlett</a><br /></div><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
The <code>balloontail.png</code> image is a simple black and white triangle made with a transparent section. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig03 Figure 19.3] is a screen capture of the image creation process, with the transparent section shown in a gray checkerboard pattern.
<div style="text-align: center;"> Figure 19.3. Creating an image with a transparent section. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig03_alt.jpg [View full size image]]</div>[[Image:19fig03.jpg|500px]] </div>
Without any positioning properties, the cartoon appears as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig04 Figure 19.4].
<div style="text-align: center;"> Figure 19.4. Not very much of a cartoon, is it? <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig04_alt.jpg [View full size image]]</div>[[Image:19fig04.jpg|500px]] </div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex04 Listing 19.4] is a style sheet that can be embedded in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex03 Listing 19.3] (or linked from it) to position each of the elements absolutely on top of the coyote's picture and assemble the cartoon properly.
Listing 19.4. Style Sheet to Lay Out the Cartoon
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* cartoon-19.4.css */<br />#cartoon { position: relative;<br />width: 600px; }<br />/* sets the containing block */<br />#bubble { position: absolute;<br />bottom: 340px; left: 215px; }<br />#tail { position: absolute;<br />bottom: 277px; left: 240px; }<br />#credits { position: absolute;<br />bottom: 16px; right: 20px; }<br /></pre></div><br />
|}
You can see the results of this style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig05 Figure 19.5]. The box is over the coyote's head, and the triangular wedge serves to show that the coyote is "speaking." The transparent section of the triangle graphic lets the coyote image show through the transparent area.
<div style="text-align: center;"> Figure 19.5. A cartoon built with CSS. Can you do better? <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig05_alt.jpg [View full size image]]</div>[[Image:19fig05.jpg|500px]] </div>
The 1px border of the word bubble is missing where it touches the <code>balloontail.png</code> graphic. This isn't a CSS trick; the graphic is simply positioned so that it overlaps, and thus covers, the border at that point. You'll learn more about controlling overlap of layered content later this hour.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Use Absolute Positioning to Create a Cartoon
This is your chance to express the budding cartoonist within you.
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Find a photograph you like. Maybe it's one you've taken, maybe it's one of you. Create an HTML page with that picture.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Write some dialogue for the picture and add it to the HTML page. Set a <code>class</code> or <code>id</code> on the dialogue so you can position it.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Create a "tail" graphic for your word balloon, or use a simple one like the one above (available from the book's website). Add a <code>class</code> or <code>id</code> here as well.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Add a wrapper <code><div></code> around your cartoon, with a <code>class</code> or <code>id</code> property. This is important so that you can set the containing box in your CSS rules.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Write the style sheet. The first thing you'll want to do is define the containing box by setting <code>position: relative</code> on your wrapper <code><div></code>; also give it a width and a border.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>Position the dialogue, using <code>position: absolute</code> and the offset properties (<code>top, right, bottom</code>, and <code>left</code>). Reload the page in your browser as you make changes; it could take several tries to position the box right where you want it to be.<br /><br /></div>
|-
| <div>'''7. '''</div>
| <div>Put your word balloon "tail" in place. Again, this may require fine adjustments, possibly pixel-by-pixel, as you line it up just right.<br /><br /></div>
|-
| >
| >
|-
| <div>'''8. '''</div>
| <div>View the cartoon in your web browser. If it looks good, you're ready to share this with your friends, who will delight in your wonderful sense of humor and thrill to your CSS positioning skills!<br /><br /></div>
|}
|}
The <code>clip</code> Property
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], you learned how you can clip content that extends out of the display box by using the <code>overflow</code> value of hidden.
Normally, only content that extends outside the display box is clipped. However, the <code>clip</code> property enables you to define a clipping area within an absolutely positioned box that defines where the content will be clipped. The types of values that can be set for the <code>clip</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19table02 Table 19.2]. The <code>clip</code> property is used only if the box's <code>overflow</code> value is not <code>visible</code>, and if the <code>position</code> value is <code>absolute</code>.
{| cellspacing="0" cellpadding="5"|+ Table 19.2. Values for the <code>clip</code> Property
|-
| Value
| Effect
|-
| <code>auto</code>
| The clipping area is defined by the box's edges.
|-
| <code>rect(</code><code>top</code>, <code>right</code>, <code>bottom</code>, <code>left</code><code>)</code>
| The clipping area is a rectangle defined by four measurements.
|-
| <code>inherit</code>
| Use the value of <code>clip</code> set on the containing block.
|}
When using the <code>rect()</code> function to define a clipping area, you're defining a subbox relative to the display box. The values <code>top</code>, <code>right</code>, <code>bottom</code>, and <code>left</code> are measurements (which can be ems, pixels, percentages, or other types of CSS measurement) which define where the box is clippedrelative to the upper-left corner of the box.
The easiest way to think of these values is to consider them a pair of points, the first in the upper-right corner and the second in the lower-left, which define the clipping area. For example, let's say you're using clipping on a box that is 400 pixels wide and 300 across, and you have written a rule such as this:
<div><pre>#box { overflow: hidden;
clip: rect(0px, 300px, 200px, 100px);
</pre></div>
This defines a clip area where one corner is at <code>400px</code> to the right, <code>0px</code> down, and the other corner is at <code>300px</code> down, and <code>100px</code> to the right. Thus the displayed area would be from <code>100px</code> to <code>300px</code> horizontally, and <code>0px</code> to <code>200px</code> vertically.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig06 Figure 19.6] shows this rule in action, clipping text content down to size. Note that even the border is clipped; this clips the entire element box.
<div style="text-align: center;"> Figure 19.6. Clipped content, before and after.
[[Image:19fig06.jpg|500px]]
</div>
You can use clipped content with absolute positioning for some interesting effects. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex05 Listing 19.5] is an HTML page with one graphic that will be placed in each corner of the content box.
Listing 19.5. A Text Box with Corner Graphics
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- corners-19.5.html --><br /><html><br /><head><br /><title>Rounded corners</title><br /><style type="text/css"><br />/* basic formatting styles */<br />body { font-family: Optima, Geneva, serif;<br />color: white; background-color: black; }<br />.section { margin: 2em; padding: 1em 2em;<br />color: black; background-color: white; }<br />h1, h2 { text-align: center; margin: 0;<br />font-variant: small-caps; }<br />p { text-indent: 3em; text-transform: uppercase; }<br /></style><br /></head><br /><body><br /><div class="section"><br /><img src="corners.png" alt=""<br />class="corner" id="topleft"><br /><img src="corners.png" alt=""<br />class="corner" id="topright"><br /><img src="corners.png" alt=""<br />class="corner" id="bottomleft"><br /><img src="corners.png" alt=""<br />class="corner" id="bottomright"><br /><h1>George L. Mountainlion</h1><br /><h2>Born February 1952</h2><h2>Died March 8, 1955</h2><br /><p>I freely give all sights and sounds of nature I<br />have known to those who have the grace to enjoy<br />not man-made materialism but God-made beauty.</p><br /><p>The magnificent Arizona sunsets I have watched<br />from my enclosure, I bequeath to all who see not<br />only with their eyes but with their hearts.</p><br /><!-- ... --><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
The corner graphic is simply a circle on a square black background, 32 pixels by 32 pixels. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig07 Figure 19.7] shows the image being created in a simple graphics program.
<div style="text-align: center;"> Figure 19.7. Creating a graphic for rounded corners. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig07_alt.jpg [View full size image]]</div>[[Image:19fig07.jpg|500px]] </div>
Displayed without positioning and clipping properties added, the HTML page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex05 Listing 19.5] looks passable, but the corner images aren't in the corners, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig08 Figure 19.8].
<div style="text-align: center;"> Figure 19.8. Unpositioned and unclipped corners. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig08_alt.jpg [View full size image]]</div>[[Image:19fig08.jpg|500px]] </div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex06 Listing 19.6] is a style sheet that uses absolute positioning to position the graphic, and then clips off everything except the appropriate corner of the circle.
Listing 19.6. Positioning and Clipping Round Corners
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* corners-19.6.css */<br />.section { position: relative; }<br />.corner { position: absolute; }<br />#topleft { top: 0px; left: 0px;<br />overflow: hidden;<br />clip: rect(0px, 16px, 16px, 0px); }<br />#topright { top: 0px; right: 0px;<br />overflow: hidden;<br />clip: rect(0px, 32px, 16px, 16px); }<br />#bottomleft { bottom: 0px; left: 0px;<br />overflow: hidden;<br />clip: rect(16px, 16px, 32px, 0px); }<br />#bottomright { bottom: 0px; right: 0px;<br />overflow: hidden;<br />clip: rect(16px, 32px, 32px, 16px); }<br /></pre></div><br />
|}
You can see the properly positioned and clipped corner graphics in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig09 Figure 19.9].
<div style="text-align: center;"> Figure 19.9. Rounded corners, positioned and clipped. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig09_alt.jpg [View full size image]]</div>[[Image:19fig09.jpg|500px]] </div>
./ ADD NAME=CH19LEV1SEC3.HTML
=== Layered Content ===
As you've seen in the coyote cartoon example, content can be positioned into a location already occupied by something else through the use of absolute (or relative) positioning. Each of the overlapping display boxes can be thought of as existing in a third dimension, as if it were printed on a piece of clear plastic. This is commonly referred to as a layer.
<div>By the Way
Netscape 4 also used the term layer to refer to the nonstandard <code><layer></code> tag. The <code><layer></code> tag should be avoided because it is not part of the HTML specification and is not widely supported by browsers. In this book, layering refers to creating distinct, overlapping boxes with CSS and does not refer to the <code><layer></code> tag.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex07 Listing 19.7] is a simple logo designed in HTML and CSS. The intent is to create a box with "Pie Walkers of Tucson" in the foreground, and a large pi (π) symbol in the background.
Listing 19.7. Content to Be Displayed in Overlapping Layers
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- layers-19.7.html --><br /><html><br /><head><br /><title>Pie Walkers of Tucson</title><br /><style type="text/css"><br />body { font-family: Arial, sans-serif; }<br />.pwlogo { position: relative; overflow: hidden;<br />height: 175px; width: 350px;<br />border: 2px solid black;<br />margin: 10em auto; }<br />.pwlogo span { display: block; }<br />.pwlogo .pi { font: 360px bold Verdana, sans-serif;<br />position: absolute; color: silver;<br />left: 40px; top: -165px; }<br />.pwlogo .pw { font: 60px "Times New Roman", serif;<br />position: absolute;<br />font-variant: small-caps;<br />left: 10px; top: 10px; }<br />.pwlogo .of { font: 70px oblique bold Papyrus, cursive;<br />position: absolute; color: gray;<br />left: 150px; top: 30px; }<br />.pwlogo .tucson { font: 60pt bold Verdana, sans-serif;<br />position: absolute;<br />text-transform: uppercase;<br />bottom: 5px; right: 5px; }<br /></style><br /></head><br /><body><br /><div class="pwlogo"><br /><span class="pw">Pie Walkers</span><br /><span class="of">of</span><br /><span class="tucson">Tucson</span><br /><span class="pi">π</span><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig10 Figure 19.10], you can see the layered effect, as each display box is placed over another. However, there's a problem! The boxes are not in a sensible order. The pi symbol covers everything else. There are two ways to fix this: first, by changing the order of the HTML tags, and second, by using the <code>z-index</code> property.
<div style="text-align: center;"> Figure 19.10. One box is laid over another, making the logo unreadable.
[[Image:19fig10.jpg|500px]]
</div>
The <code>z-index</code> Property
Each layer is placed in the order it appears in the HTML source code, with subsequent layers placed on top of earlier ones. This order can be changed with the <code>z-index</code> property. Values for <code>z-index</code> are numbers that indicate the layering order. A lower number goes on the bottom, and a higher number goes on the top.
<div>Did you Know?
The property name <code>z-index</code> comes from basic geometry. Horizontal placement is said to be along the x-axis, vertical along the y-axis, and third-dimensional placementout of the page or the screenis along the z-axis.</div>
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex08 Listing 19.8] reassigns the layering order by using the <code>z-index</code> property. As you can see, you can skip numbers, so you don't have to assign them sequentially; all the layers are considered and then sorted so the highest are on top, even if there are gaps in the sequence.
Listing 19.8. Style Sheet to Change the Order of Layering
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* layers-19.8.css */<br />.pwlogo .pi { z-index: 1; }<br />.pwlogo .pw { z-index: 10; }<br />.pwlogo .of { z-index: 3; }<br />.pwlogo .tucson { z-index: 5; }<br /></pre></div><br />
|}
Applying this style sheet to the HTML page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex07 Listing 19.7] results in the layering order shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig11 Figure 19.11].
<div style="text-align: center;"> Figure 19.11. The layers are now in the desired order.
[[Image:19fig11.jpg|500px]]
</div>
./ ADD NAME=CH19LEV1SEC4.HTML
Fixed Positioning
In fixed positioning, a box placed on the screen doesn't move even if the rest of the page moves; it seems to float above the rest of the content without leaving its original position. This is useful if you want to create a menu bar or graphic that never leaves the page. A box placed according to fixed positioning is located in relation to the whole page, not to its containing block or its original position. Like absolute positioning (and unlike relative positioning), no space is set aside for the box in its normal flow location.
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex09 Listing 19.9] uses fixed positioning to set both a bar at the top that never goes away, and a "back to top" button that always stays fixed in the lower right corner. The full text of "The War Prayer" is omitted in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19ex09 Listing 19.9], but you can view the entirety on the book's website, to test scrolling with fixed positioning.
Listing 19.9. Using Fixed Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- fixed-19.9.html --><br /><html><br /><head><br /><title>Page with a lot of text</title><br /><style type="text/css"><br />.section { margin: 0 8em; }<br />.topbar {<br />position: fixed; top: 0; left: 0;<br />width: 100%;<br />background-color: black; color: white; }<br />.backtotop {<br />background-color: white;<br />border: 1px solid black;<br />position: fixed; bottom: 1em; right: 1em; }<br /></style><br /></head><br /><body><br /><div class="topbar"><br />You are reading:<br /><cite>The War Prayer</cite> by Mark Twain<br /></div><br /><div class="section"><br /><h1><a name="top">The War Prayer by Mark Twain</a></h1><br /><p> It was a time of great and exalting excitement.<br /><!-- ... --><br /></div><br /><div class="backtotop"><br /><a href="#top">Back to top</a><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
The effects of fixed positioning are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19fig12 Figure 19.12].
<div style="text-align: center;"> Figure 19.12. Objects fixed in position don't move when the rest of the page scrolls. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/19fig12_alt.jpg [View full size image]]</div>[[Image:19fig12.jpg|500px]] </div>
./ ADD NAME=CH19LEV1SEC5.HTML
Summary
Display boxes can be moved from their original positions in the normal flow of layout by using the <code>position</code> property. The <code>position</code> property selects among four different types of positioning schemes. Absolute positioning places the HTML element in a new location within or relative to its containing block. Fixed positioning locates the display box on a set position on the screen, even if the page scrolls.
Placement of boxes in the context of their positioning schemes is determined by the values of the offset properties: <code>left, right, top</code>, and <code>bottom</code>. These can be measurements or percentages, with a positive value moving in the direction of the center of the containing block, and a negative value moving away from it. Care needs to be taken when placing boxes so that content isn't obscured or moved off the visible part of the page entirely. Absolutely positioned content that overflows its box can be clipped with the <code>clip</code> property.
In addition to existing in two dimensions, CSS boxes occupy a third dimension, as well, that determines which boxes are layered on top of other boxes if the content overlaps. The order of layering can be set with the <code>z-index</code> property.
./ ADD NAME=CH19LEV1SEC6.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa1q1a1 Q.]'''
| My <code>clip</code> rule isn't working right, and I am following the CSS spec exactly! The clipped element doesn't appear at all. What's wrong?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa1q1 A.]'''
| The problem here is an unclear specification. You might assume that the dimensions for <code>rect()</code> are like those of <code>relative</code> offsetsthat each one specifies how to adjust the sides, with positive changes being toward the middle of the box. This is a natural assumption when you're working with positioning CSS, but it's not the case at all. Instead, a <code>rect()</code> defines a rectangle within the content box. As explained in this hour, it's easiest to think of the <code>rect()</code> values as a pair of coordinates for the upper-right and lower-left corners.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q1a1 1.]'''
| Which of the following best describes absolute positioning?
<div># <div>Subsequent text is flowed around the positioned box, relative to the box's new left or right location.</div>
# <div>The box is held in location relative to where it is located, even if the page is scrolled.</div>
# <div>Relative to the box's original location, the box is offset by a certain distance.</div>
# <div>The box is placed relative to its containing box.</div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q2a2 2.]'''
| The three <code><div></code> elements in the following snippet of HTML are placed with absolute positioning. What letter will be seen and why?
<div><pre><div style="position:" absolute; top: 0px; left: 0px;<br />background-color: white; width: 2em; z-index: 10;">K</div><br /><div style="position:" absolute; top: 0px; left: 0px;<br />background-color: white; width: 2em; z-index: 1;">L</div><br /><div style="position:" absolute; top: 0px; left: 0px;<br />background-color: white; width: 2em; z-index: 6;">B</div><br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q3a3 3.]'''
| You have an <code><img></code> tag that is 450 pixels wide and 300 pixels tall. The graphic is composed of nine images of television actors in a three by three grid, each cell 150 pixels wide by 100 pixels tall. You want to show only the face of the youngest one, in curls, in the lower left cell. How do you use <code>clip</code> to show only that portion of the image?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q1 1.]'''
| Absolute positioning is choice (c). Choice (c) is a description of relative positioning (from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18]), (a) describes floating content (from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15]), and (b) describes fixed positioning.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q2 2.]'''
| The letter K. Because they are all placed in the same location, the one that is displayed will be the <code><div></code> on the top of the stacking order. The highest <code>z-index</code> value is <code>10</code>, and so the letter K will be visible. (Technically, the other letters are visible, too; we just can't see them.)
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch19qa2q3 3.]'''
| Here is the type of rule you would write:
<div><pre>img#bunch {<br />overflow: hidden;<br />clip: rect(150, 200, 0, 300); }<br /></pre></div><br />
Did you remember that you needed to change the <code>overflow</code> value from the default of <code>visible</code> to be able to use <code>clip?</code> The values for <code>rect()</code> come from the coordinates for the upper-left corner and the lower-right corner of the portion that should be displayedthe points (150,200) and (0,300), respectively.
|}
Exercise
Placing boxes on the screen can seem arcane until you get plenty of practice with it. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS," you're going to see how to bring together what you've learned to lay out a page effectively. But you have the tools already to get started on positioning content blocks, and exercising your use of absolute and fixed positioning will help you prepare.
Begin by creating a simple HTML page with a number of different elementssome headers, a few images, <code><div></code> elements containing sections of text, some lists of linksand start placing them with absolute (or fixed) positioning. After you've got them where you want them...move them! The power of CSS-based positioning lets you move sections of your page around the screen by simply changing offset property values, thus enabling you to re-order the entire page without changing the HTML. Try it, and practice it until you've fully grasped the implications; then you'll be ready for the next hour!
./ ADD NAME=CH20.HTML
91u4sc57ok2frtexvdmtvwfwwnl3tf3
User:Bartlett/20
2
2124
39230
5524
2026-04-13T06:03:23Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39230
wikitext
text/x-wiki
./ ADD NAME=CH20.HTML
Hour 20. Page Layout in CSS
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* The different strategies for laying out a page in CSS
* Why it's a bad idea to use <code><table></code> for page layout
* The steps to replacing a table-based layout with a CSS-based structure
* How to write HTML code for CSS-based layouts
* How to use positioned content to lay out a page
* How to use floating columns to lay out a page
One of the major draws of modern CSSas supported by recent, more compliant browsersis the freedom to replace clunky HTML layout tables with structured HTML markup, styled by CSS rules. In previous hours, you've learned how to place individual portions of your web page in specific locations using absolute positioning or floating content. You can use the same types of style rules to build the visual structure of the page.
|}
./ ADD NAME=CH20LEV1SEC1.HTML
=== Laying Out the Page ===
This hour will bring together many of the techniques you've learned in previous hours for using CSS properties to lay out an entire page or even an entire website. You won't need to misuse HTML <code><table></code> elements for page layout now that you have reliable CSS techniques for layout in your repertoire.
The examples this hour use a redesigned version of the website for the Dunbar Project ([http://www.thedunbarproject.com/ http://www.thedunbarproject.com]). Dunbar School in Tucson, Arizona, was a segregated school for African-American students from 1918 until 1951, and was closed in 1978. Since then, a community group has been working to restore the school and make it into a community cultural center.
The Dunbar Project has graciously allowed the author to use their website in this book for a sample website redesign in CSS. The Dunbar Project site as it appeared in early 2006 is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig01 Figure 20.1]. It is mostly a dark teal color, and although it's not bad, it could be improved through the use of Cascading Style Sheets, as you'll see this hour.
<div style="text-align: center;"> Figure 20.1. The Dunbar Project's original website. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig01_alt.jpg [View full size image]]</div>[[Image:20fig01.jpg|500px]] </div>
The Problems with Layout Tables
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig02 Figure 20.2] shows the source view for the original version of the Dunbar Project web-site, which was not designed with CSS. Instead, multiple nested <code><table></code> tags provide the page layout, and <code><span style="text-align: center;"></code> is used extensively.
Figure 20.2. Table-based layout can be very convoluted. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig02_alt.jpg [View full size image]]</div>[[Image:20fig02.jpg|500px]]
Tables for layout are problematic for a number of reasons. HTML purists argue against tables on principle: The <code><table></code> tag is meant to identify data in rows and columns of information, and is not intended for page layout. Accessibility mavens will tell you that screen readers employed by visually impaired users struggle with table layout.
Table-based layouts are often harder to maintain than CSS-based layouts, requiring extensive rewriting of HTML tags to make simple changes. Later this hour, you'll see how a few CSS rules can easily move entire sections around without touching the HTML document at all.
CSS-based layouts make it easier to maintain your HTML pages without cluttering them up with <code><tr></code> and <code><td></code> tags, and make for simpler transitions to new layouts by just swapping in a new style sheet. Your web pages laid out with CSS will be smaller (and thus load more quickly) than table-based pages. You can write web pages with the main content first in the HTML source and the navigation and footer information after, making your page more friendly to screen readers and search engines.
Writing HTML with Structure
The first step to laying out a page is to start with well-written HTML that is divided into sections for styling. This is commonly done with <code><div></code> tags that have id attributes set on them, corresponding to the different sections of the page.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex01 Listing 20.1], you can see a redesign of the Dunbar Project home page, which uses simple markup to store the site navigation, the content, the side navigation links, and the page footer.
Listing 20.1. Using <code><div></code> Tags to Create Sections for Positioning
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- dunbar-20.1.html --><br /><html><br /><head><br /><title>The Dunbar Project</title><br /></head><br /><body><br /><div id="header"><br /><h1>The Dunbar Project</h1><br /><h2>In the Shadow of Downtown Tucson</h2><br /><div id="sitenav"><br /><ol><li><a href="index.html">Home</a></li><br /><li><a href="about/">About the Dunbar Project</a></li><br /><li><a href="gallery/">Photo Galleries</a></li><br /><li><a href="donate/">Donate</a></li><br /><li><a href="contact/">Contact</a></li></ol><br /></div> <!-- sitenav --><br /></div> <!-- header --><br /><div id="main"><br /><div id="content"><br /><h3>Welcome to The Dunbar Project Website</h3><br /><img src="DunbarTop.jpg" alt="[Dunbar School]"><br /><p>Dunbar School was completed in January 1918, for the<br />purpose of educating Tucson's African-American students.<br />The school was named after <a href="poet.html">Paul<br />Laurence Dunbar</a>, a renowned African-American poet.<br />African-American children in first through ninth grades<br />attended Dunbar until 1951, when de jure segregation was<br />eliminated from the school systems of Arizona. When<br />segregation in Arizona was eliminated, Dunbar School<br />became the non-segregated John Spring Junior High School,<br />and continued as such until 1978 when the school was<br />closed permanently.</p><br /><!-- ... more content omitted ... --><br /></div> <!-- content --><br /><div id="sidebar"><br /><h3>Dunbar Project</h3><br /><ol><li><a href="plan/">The Dunbar Site Plan</a></li><br /><li><a href="auditorium/">Dunbar Auditorium</a></li><br /><li><a href="history/">School History</a></li><br /><li><a href="proposal/">Project Proposal</a></li><br /><li><a href="donors/">Dunbar Donors</a></li><br /><li><a href="poet.html">About Paul Laurence Dunbar,<br />Poet</a></li><br /><li><a href="links/">Related Links</a></li></ol><br /><h3>Coalition Partners</h3><br /><ol><li>The Tucson Urban League</li><br /><li>The Dunbar Alumni Association</li><br /><li>The Dunbar/Spring Neighborhood Association</li><br /><li>The Juneteenth Festival Committee</li></ol><br /><h3>Individual Members</h3><br /><ol> <!-- ... list of donors omitted ... --> </ol><br /></div> <!-- sidebar --><br /><div id="footer"><br /><p id="note501c3">The Dunbar Project is a 501c(3) organization,<br />and your contributions are tax deductible.</p><br /><p id="copyright">Copyright © 2006 by the Dunbar<br />Project. Questions?<br /><a href="mailto:webmaster@thedunbarproject.com"<br />>Mail the Webmaster.</a></p><br /></div> <!-- footer --><br /></div> <!-- main --><br /></body><br /></html><br /></pre></div><br />
|}
You can download a full copy of this HTML file from the book's website; the content has been cut for space in this listing.
The structure of this page is defined by the <code><div></code> tags with id attributes. The general skeleton (with content omitted) consists of the following:
<div><pre><div id="header">
<div id="sitenav"></div>
</div> <! header >
<div id="main">
<div id="content"></div>
<div id="sidebar"></div>
<div id="footer"></div>
</div> <! main >
</pre></div>
Comments are used with the closing <code></div></code> tags as reminders about which <code><div></code> is being closed; it makes the page easier to edit later.
The page is constructed of two sections: a header and a main body. Each of these has one or more subsections. This structure provides what's needed to redesign and lay out the page.
Why this particular structure? There are actually many ways you could structure such the page, inserting <code><div></code> tags appropriately. This skeleton is simply the method chosen for this example, to get the specific styles used later on. During the web development process, you might go back to your HTML and add or remove <code><div></code> tags while styling to give more flexibility when creating page layouts.
The number of <code><div></code> tags you use will vary from layout to layout. Some web designers believe strongly in using only a minimum number of <code><div></code> tags, whereas others add them freely whenever needed. The approach for this example is down the middle between those extremes: There are enough to make it easy to illustrate how CSS-based layout works, but not so many that we're adding extraneous <code><div></code> tags just because we can.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig03 Figure 20.3] shows the new HTML page without any styles applied.
Figure 20.3. An unstyled page, ready for layout. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig03_alt.jpg [View full size image]]</div>[[Image:20fig03.jpg|500px]]
Writing a Layout Style Sheet
With an HTML page ready for styling, the next step is to write the style sheet. There are several questions to consider regarding how to lay out the page.
The first is a technical question: Will you use absolute positioning for layout, or will you use floated columns? You can get the same general layout effects from both techniques. Positioning is a little bit easier to grasp, at first, so this example uses absolute positioning. Later this hour, however, you'll learn how to lay out the same HTML page with the float property.
You need to figure out how many columns you want. There's a slight increase in complexity when you have more columns, but the specific techniques remain the same whether you're using two columns, three columns, or more. In this redesign, two columns are used to avoid making the example overly complex.
Finally, you need to determine whether you are using a fixed layout or a liquid layout. A fixed layout is one that defines a specific width for an entire page; for example, it may be always 700 pixels across, and excess space in the browser simply becomes wider margins. A liquid layout is one that grows larger (or smaller) based on the user's screen resolution and browser window size.
There are advantages and disadvantages to both fixed and liquid layouts. A fixed layout may be easier to create and easier to read on larger monitors; a liquid layout is more adaptable but could result in overly long lines, which are harder to read. In this example, the Dunbar Project site will use a liquid design with margin size based on em units.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex02 Listing 20.2] is a style sheet that starts to set up the layout choices.
Listing 20.2. A Style Sheet for Page Layout
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* dunbar-layout-20.2.css */<br /><br />body { margin: 0; padding: 0;<br />background-color: silver; }<br />#header { background-color: black; color: white; }<br />#sitenav ol { padding: 0; margin: 0;<br />display: inline; }<br />#sitenav li { display: inline; padding-left: 1em;<br />margin-left: 1em; border-left: 1px<br />solid black; }<br />#sitenav li:first-child<br />{ padding-left: 0; border-left: none;<br />margin-left: 0; }<br />#sitenav li a { color: white; }<br />#main { padding: 0 12em 2em 2em;<br />position: relative;<br />background-color: gray; }<br />#content { background-color: white; }<br />#sidebar { position: absolute; width: 10em;<br />right: 1em; top: 1em; }<br />#sidebar h3 { color: white;<br />background-color: black; }<br />#sidebar ol { margin: 0 0 1em 0;<br />background-color: white;<br />border: 2px solid black; }<br />#footer { background-color: white; }<br /></pre></div><br />
|}
This style sheet is deliberately plain and simple, with colors of black, gray, silver, and white to make it easier for you to identify the various sections of the page.
So what's happening here?
* The first rule sets the margin and padding of the <code><body></code> to <code>0</code>. This is an important first rule for layout because browsers typically add one or the other (or both) to any web page.
* The <code>#sitenav</code> rules in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex02 Listing 20.2] are used to turn the ordered list of links into a horizontal navigation bar.
* The <code>#main</code> section is set to <code>position: relative</code> to become the containing block around the <code>#content, #sidebar</code>, and <code>#footer</code> sections.
* The <code>#main</code> section is also given a large padding on the right, <code>12em</code>. This is where the <code>#sidebar</code> will be located.
* Absolute positioning is used to move the <code>#sidebar</code> into the margin, out of its place in the normal flow of content. It is positioned 1 em to the left of the right edge of its containing block (<code>#main</code>) by <code>right: 1em</code>, and 1 em down from the top edge of the containing block by <code>top: 1em</code>.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig04 Figure 20.4] shows the results of linking this style sheet to the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex01 Listing 20.1].
Figure 20.4. Positioning properties define the rough outline of the page. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig04_alt.jpg [View full size image]]</div>[[Image:20fig04.jpg|500px]]
It's still quite rough, but you can see the different sections moved into place. You should note the silver bars above and below the header. Where did they come from, and why?
The silver bars are the result of the background color set on the <code><body></code> showing through. They are formed because of the default margin properties set on the <code><h1></code> and <code><h3></code> headings used on the page. Remember that margins are outside of the border of an element's box, and the <code>background-color</code> property on a box colors only the interior content, not the margin. This applies even when you have a <code><div></code> wrapped around a heading, such as <code><h1></code>. The margin extends beyond the edge of the <code><div></code>'s background-color.
To fix this, we explicitly set the heading margins to zero on the heading tags. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex03 Listing 20.3] is a style sheet that not only does that, but also assigns colors, fonts, and other styles on the site. The teal, purple, white, and yellow colors were chosen to reflect not only the original design of the website, but also the actual colors used at the Dunbar school auditorium as well.
Listing 20.3. A Style Sheet for Colors and Fonts
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* dunbar-colors-20.3.css */<br /><br />body { font-family: Optima, sans-serif; }<br />a:link { color: #055; }<br />a:visited { color: #404; }<br />#header { text-align: center;<br />color: white; background-color: #055; }<br />#header h1, #header h2<br />{ margin: 0; }<br /><br />#header h1 { color: #FFFF00; font-size: 250%; }<br />#header h2 { font-weight: normal; font-style: italic; }<br />#sitenav { color: white; background-color: #404; }<br />#sitenav ol { font-size: 90%; text-align: center; }<br />#sitenav li { margin-left: 1em;<br />border-left: 1px solid #DD0; }<br />#sitenav li a:link, #sitenav li a:visited<br />{ color: white; text-decoration: none; }<br />#sitenav li a:hover<br />{ color: #DDDD00; }<br /><br />#main { background-color: #055; }<br /><br />#content { background-color: white; padding: 1em 5em; }<br />#content h3 { margin-top: 0; }<br />#content p { font-size: 90%; line-height: 1.4; }<br /><br />#sidebar h3 { font-size: 100%; color: white; margin: 0;<br />font-weight: normal; padding: 0.125em 0.25em;<br />background-color: #404; }<br />#sidebar ol { background-color: white; border: 2px solid #404;<br />border-top: 0; margin: 0 0 1em 0;<br />padding: 0.125em 0.25em; }<br />#sidebar li { font-size: 85%;<br />display: block; padding: 0.125em 0; }<br />#sidebar li a:link, #sidebar li a:visited<br />{ text-decoration: none; color: #055; }<br />#sidebar li a:hover { color: #404; }<br /><br />#footer { background-color: #404; color: white;<br />padding: 0.5em 5em; }<br />#footer p { margin: 0em; font-size: 85%; }<br />#footer p a:link, #footer p a:visited<br />{ color: #DDDD00; }<br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig05 Figure 20.5] shows the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex01 Listing 20.1] with both the layout style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex02 Listing 20.2] and the colors and fonts style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex03 Listing 20.3].
Figure 20.5. Fonts and colors help define the website's look. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig05_alt.jpg [View full size image]]</div>[[Image:20fig05.jpg|500px]]
As you can see, the styled page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig05 Figure 20.5] looks quite different from the unstyled version in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig03 Figure 20.3].
Re-Ordering Sections with Positioning Styles
The page in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig05 Figure 20.5] looks okay, but let's say that you got this far into the web design process and you suddenly decided that you want to have the site navigation bar located on top of the headline, rather than below it.
You could go in and change your HTML source around. This would work, but it would introduce a problem. The order of the HTML in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex01 Listing 20.1] is sensiblethe name of the site is given first, and then the navigation menu. This is how users of non-CSS browsers such as Lynx will read your page, and also how search engines and screen readers will understand it as well. Moving the title of the page after the list of links doesn't make much sense.
Instead, you can use CSS positioning properties to reformat the page without touching the HTML file. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex04 Listing 20.4] is a style sheet to do exactly that.
Listing 20.4. Moving One Section Before Another
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* dunbar-move-20.4.css */<br /><br />#header { padding: 1.25em 0 0.25em 0;<br />position: relative;<br />background-color: #404; }<br />#sitenav { position: absolute;<br />top: 0; right: 0;<br />border-bottom: 1px solid #DDDD00;<br />width: 100%;<br />background-color: #055; }<br /></pre></div><br />
|}
What's happening here?
* The <code>#header</code> section encloses the <code>#sitenav</code> in the HTML source, so by setting it to <code>position: relative</code>, it now becomes the containing block for the site navigation links.
* Padding is added to the top of the <code>#header</code> section. This is where subsequent rules will place the site navigation menu; the padding reserves the space for it.
* Absolute positioning properties align the top-right corner of the <code>#sitenav</code> section with the top-right corner of its containing block, the <code>#header</code>.
* Giving a <code>width</code> of <code>100%</code> to the <code>#sitenav</code> ensures it will reach across the full width of its containing block, which is, in this case, as wide as the browser display window.
* Finally, colors are swapped on the <code>#header</code> and the <code>#sitenav</code> to make them fit in better with the overall design in their new locations, and a yellow border is added to the bottom of the navigation links.
You can see the effects of these changes in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig06 Figure 20.6].
Figure 20.6. The navigation menu is now above the page headline. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig06_alt.jpg [View full size image]]</div>[[Image:20fig06.jpg|500px]]
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Redesign the Layout of a Page
You just learned how to move the site navigation menu around. What if you want to make further changes to the page? Try these steps to get familiar with how easy it is to change the layout with CSS:
{| border="0"
|-
| <br />
| >
|-
| <div>'''1. '''</div>
| <div>Download a copy of the Dunbar Project page for editing. You can get all the files used in this hour from the book's website. The file <code>dunbar.html</code> contains the complete HTML page, and <code>dunbar-full.css</code> has all the style rules listed in this chapter combined into a single style sheet.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Move the sidebar to the left side of the page instead of the right. To do this, you need to make space for it in the left gutter by changing the padding rule on the <code>#main</code> section to<br /><br /><div><pre>#main { padding: 0 2em 2em 12em; }<br /></pre></div><br /></div>
|-
| <div>'''3. '''</div>
| <div>Then change the positioning offset properties the <code>#sidebar</code>. You don't even have to change the rule for the top property; just replace the property name <code>right</code> with <code>left</code>.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Reload the page. You should now see the menu bar on the left side of the screen.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Next, move the <code>#footer</code> section. Even though the id of the <code><div></code> is <code>"footer"</code>, there's nothing magical about that name that means it needs to be at the bottom of the page. Place it on the right side, where the sidebar used to be located. First clear some space:<br /><br /><div><pre>#main { padding: 0 12em 2em 12em; }<br /></pre></div><br /></div>
|-
| <div>'''6. '''</div>
| <div>Then reposition the footer with these rules:<br /><br /><div><pre>#footer { position: absolute;<br />top: 1em; right: 1em;<br />width: 10em;<br />padding: 0; }<br />#footer p { padding: 0.5em; }<br /></pre></div><br /></div>
|-
| <div>'''7. '''</div>
| <div>Reload the page. The <code>#footer</code> is now no longer a footer, but a third column on the right side of the page.<br /><br /></div>
|}
|}
The Floated Columns Layout Technique
You can also lay out a web page by using the <code>float</code> property rather than positioning properties. This method is a little bit more complex, but is favored by some designers who prefer the versatility. In addition, floated columns can be written with fewer <code><div></code> tags, and in some cases deal better with side columns that are shorter than the main text.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex05 Listing 20.5] is a style sheet demonstrating how you can float entire columns on a page with CSS. This is a replacement for the <code>dunbar-layout-20.2.css</code> style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex02 Listing 20.2]. The new style sheet places the menu bar on the left instead of the right, just for variety's sakethere's nothing inherently left-biased about floated columns (or right-biased about positioning).
Listing 20.5. Float-Based Layouts in CSS
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* dunbar-float-20.5.css */<br /><br />body { margin: 0; padding: 0; }<br />#sitenav ol { padding: 0; margin: 0;<br />display: inline; }<br />#sitenav li { display: inline; padding-left: 1em;<br />margin-left: 1em; border-left: 1px<br />solid black; }<br />#sitenav li:first-child<br />{ padding-left: 0; border-left: none;<br />margin-left: 0; }<br /><br />/* This is what positions the sidebar: */<br />#main { padding: 0 2em 2em 12em; }<br />#content { float: left; }<br />#sidebar { float: left; width: 10em;<br />position: relative;<br />right: 11em; top: 1em;<br />margin-left: -100%; }<br />#sidebar ol { margin: 0 0 1em 0; }<br /></pre></div><br />
|}
What does this style sheet do?
* The first section simply duplicates the site navigation bar code from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex02 Listing 20.2], so that the entire style sheet can be replaced by this one.
* Starting at the second comment, the code for positioning the columns appears. The first rule sets the <code>#main</code> section to have a wide gutter on the left, which is where we will be placing the sidebar.
* Both the <code>#content</code> and <code>#sidebar</code> sections are set to float. This means that they line up on the left side of the <code>#main</code> section, just inside the padding.
* A width is given to the <code>#sidebar</code> of <code>10em</code>the same width as in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch10lev1sec2.html#ch10ex02 Listing 10.2]. The size was chosen because that allows 1 em of space around it, after it is placed inside the 12 em gutter set by the <code>padding</code> rule on <code>#main</code>.
* A negative margin is set on the left side of the <code>#sidebar</code>, which actually makes it overlay the <code>#content</code> section. Relative positioning is then used, via the <code>right</code> and <code>top</code> rules, to push the sidebar into the correct place in the gutter.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20fig07 Figure 20.7] shows this style sheet applied to the HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex01 Listing 20.1], along with the colors and fonts style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex03 Listing 20.3] and the style sheet from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20ex04 Listing 20.4], which relocated the site navigation menu.
Figure 20.7. The sidebar is positioned as floating content. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/20fig07_alt.jpg [View full size image]]</div>[[Image:20fig07.jpg|500px]]
./ ADD NAME=CH20LEV1SEC2.HTML
Summary
Tables have long been used in web design to lay out a web page. However, this misuse of <code><table></code> markup introduces a plethora of complications, from accessibility concerns to complexity problems. Using CSS for layout can clean up your HTML code and produce flexible designs that can be updated easily to new styles.
Laying out a page with CSS starts with adding sections to the HTML, using <code><div></code>s with ID selectors. These are then arranged in vertical columns, through the use of either positioning rules or the float property. With CSS layouts, it's not difficult to re-order and reshape the page simply by changing the style sheet.
./ ADD NAME=CH20LEV1SEC3.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q1a1 Q.]'''
| Is it ever okay to use tables for layout?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q1 A.]'''
| Never, ever, ever! Well, almost. CSS layouts generally are more efficient and versatile than <code><table></code>-based code, but if you are careful to test your layout tables in a browser such as Lynx to make sure that the site is usable without tables, you can probably get away with it. Tables aren't awful for laying out a page, and CSS can be tricky when you're dealing with grid-based designs. In general, though, you're better off using CSS whenever you can.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q2a2 Q.]'''
| Which are better measurements for layouts, pixels or percentages?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q2 A.]'''
| Some web designers, especially those from a print background or who have picky clients to please, swear by pixels. With some patience (and possibly work-arounds for browser quirks, as described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks"), you can get close to pixel-perfect designs in CSS. Other designers like percentage measurements, which scale with the size of the text window. Personally, I prefer em measurements, which are based on the user's chosen font size. There's no clear-cut advantage to any approach, however; all have their pros and cons. You can experiment with a variety of measurement types, and don't be afraid to mix and match them sensibly on your sitefor example, designating column widths in percentages but also setting pixel-based <code>min-width</code> and <code>max-width</code> values.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q3a3 Q.]'''
| Are there problems with using ems for layout?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa1q3 A.]'''
| Only if you're not careful. The biggest problems result from setting margins, padding, or positioning properties based on em values, and then changing the font size of those values. For example, you might overlook the effects of the <code>font-size</code> rule buried in these declarations:
<div><pre>#sidebar { right: 1em; top: 1em;<br />text-align: right; color: white;<br />font-family: Verdana, sans-serif;<br />font-size: 50%; }<br /></pre></div><br />
This won't actually be located 1 em in each direction from the corner of its containing block; it will be 0.5 em from the right, and 0.5 em from the top. If you are going to change the font size within a section that uses ems for dimensions or placement, set the <code>font-size</code> rules on the contents of the box, as done in this chapter's style sheets with <code>#sidebar h3 { ... }</code> and <code>#sidebar ol { ... }</code> rules. You could also add an extra <code><div></code> inside the sidebar, and set the <code>font-size</code> rule on that <code><div></code>.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q1a1 1.]'''
| Which property tells the text to start flowing normally again, after a floated column?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q2a2 2.]'''
| How do you designate the containing block for an absolutely positioned element?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q3a3 3.]'''
| What kind of rules would you write to change an ordered list of navigation links into a horizontal navigation bar?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q1 1.]'''
| The <code>clear</code> property, which was introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch15.html#ch15 Hour 15], "Alignment," can be used after floated columnsfor example, if you want a footer to reach across the entire browser window below the floated columns.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q2 2.]'''
| As explained in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], "Absolute and Fixed Positioning," you set the containing block by changing the <code>position</code> property, usually to a value of <code>relative</code> (with no offset properties designated).
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch20qa2q3 3.]'''
| [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20lev1sec1.html#ch20ex02 Listing 20.2] has an example of a style sheet with rules to do that, using the display property as described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes."
|}
Exercises
Practice the following exercises:
* What kind of layouts can you create with CSS? Choose your favorite siteseither your own or some you enjoy usingand duplicate their layout styles with CSS. Existing sites make good models for doing your own practice, but keep in mind that unless you get permission, you shouldn't simply steal someone else's code. Start with the visual appearance as you see it on the screen, and draw out boxes on paper as guidelines showing you where various columns are located. Use that as your model to write the HTML and CSS for building a similar layout.
* Try both of the techniques described in this hourusing absolutely positioned content and using floating columns. Start with one version and convert it over to the other. Find a style of page that looks right to you, and the CSS code that you feel is easiest to understand, apply, and modify consistently.
./ ADD NAME=CH21.HTML</span>
7pqddrfktvbwl8gzdhavb7c1hx4lb0h
User:Bartlett/24
2
2125
39234
5525
2026-04-13T06:03:25Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39234
wikitext
text/x-wiki
ME=CH24.HTML
Hour 24. Troubleshooting and Browser Hacks
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* How to detect errors in your style sheets or HTML code by using validators
* What browser hacks are and how they work
* How to write CSS rules that filter out specific browsers
* What conditional comments are, and how to use them with Internet Explorer
* How to reliably hide content from visual browsers while still making it available to screen readers for blind users
* Four ways to change the transparency of any element with proprietary CSS rules
* How to produce a variety of visual transformations that will appear only in Internet Explorer
* How to create rounded corners in Gecko-based browsers with proprietary CSS rules
Writing style sheets can feel like an arcane art when the style rules don't have quite the effect you want. Sometimes it will be a problem with the way you've written the rules, and other times you've just run into a browser bug or quirk. This hour teaches you how to identify your own mistakes, work around browser quirks, and use certain browser deviations from the standard to benefit rather than break your CSS-based designs.
|}
./ ADD NAME=CH24LEV1SEC1.HTML
Troubleshooting Style Sheets
When you're writing a style sheet, sometimes the results you get in your browser don't match what you were hoping for. Don't worrythis happens to everyone. To correct these problems, you can follow a strategy of eliminating syntax errors though validation, simplifying the possible sources of errors, and working around browser bugs and quirks.
HTML and CSS Validation
Everyone makes mistakes, even you and I. Mistakes in writing CSS can be benign, producing a minor effect such as putting a block of text in the wrong font, or they can be much more serious and prevent people from using your page at all.
The first step to making sure that your style sheet contains no mistakes is ensuring that your HTML isn't broken. As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4], "Using CSS with HTML," you can validate your HTML by using the World Wide Web Consortium's HTML validator at [http://validator.w3.org/ http://validator.w3.org]. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig01 Figure 24.1] shows the validator inspecting the author's website.
<div style="text-align: center;"> Figure 24.1. The W3C's HTML validator locates problems in web pages. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/24fig01_alt.jpg [View full size image]]</div>[[Image:24fig01.jpg|500px]] </div>
As you can see, the validator discovered a problemthere is an extra closing tag, </a>, that is not matched by an opening tag. This was the result of a simple HTML editing problemI changed the spot at which I wanted my link to end, but forgot to remove the original closing tag. Thanks, validator, for spotting that!
The W3C provides a free CSS validation service, as well, for checking your CSS syntax. This is located at [http://jigsaw.w3.org/css-validator/ http://jigsaw.w3.org/css-validator/].
<div>By the Way
Another CSS validator, this one from the Web Design Group, can be found at [http://www.htmlhelp.com/tools/csscheck/ http://www.htmlhelp.com/tools/csscheck/].</div>
To use the W3C CSS validator, you can specify a web page that contains CSS code, give the direct URL of a style sheet, or paste your style rules directly into a text box. The validator analyzes your CSS rules and notifies you of errors. It also gives useful warnings.
An example of CSS validation is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig02 Figure 24.2], which shows the results of validating the style sheet for the author's website. As you can see, it caught an error and gave a warning about some possible errors.
<div style="text-align: center;"> Figure 24.2. Using the W3C's CSS validator on a style sheet. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/24fig02_alt.jpg [View full size image]]</div>[[Image:24fig02.jpg|500px]] </div>
Validation is a useful strategy for a number of reasons. The biggest benefit is that it enables you to spot errors in your style sheet syntax. For example, in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig02 Figure 24.2], the CSS validator noticed a problem with the style sheet. The style sheet contained a reference to a <code>pudding</code> CSS property; this was a typo for the <code>padding</code> property.
The warnings issued by the CSS validator are quite useful for spotting accidental omissions, such as setting a foreground color without a contrasting background color. However, you have to interpret those results carefully. The CSS validator can't fully account for inheritance and transparency in your web page, and so you need to determine for yourself whether a warning is an actual problem.
A validator is like a spell-checker or grammar-checker in a word processor. It can spot potential problems and you wouldn't think of submitting a document without checking it first, but blind reliance on an automated checker without using human judgment is just as bad.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Check for Valid HTML and CSS
Get some hands-on experience with the W3C's validators by following these simple steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Choose a web page you've worked on that uses CSS.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>First, validate the HTML at [http://validator.w3.org/ http://validator.w3.org/] and take note of any problems you find.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Fix any HTML errors the validator found in your page; clean HTML is a solid foundation for CSS work.<br /><br /></div>
|-
| <div>'''4. '''</div>
| <div>Next, run the page's style sheet through the CSS validator at [http://jigsaw.w3.org/css-validator/ http://jigsaw.w3.org/css-validator/]. You'll get two types of responseserrors and warnings.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Fix any errors that appear, such as mistyped property names or poorly formed CSS rules. It's not uncommon to leave out closing curly braces or have extraneous ones, for example.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>Then go through each warning and analyze what it's trying to tell you. You may not need to change your style sheet at all, if you can check against your HTML and determine whether the warning calls for action or not.<br /><br /></div>
|-
| <div>'''7. '''</div>
| <div>Fix any warnings that are helpful, and ignore any you don't need to fix. For example, if it tells you that you need to set a background color, but it will always be inherited from an appropriate parent element, you don't need to make that change.<br /><br /></div>
|}
|}
Narrowing Your Focus
Validation won't find all your mistakes, just as a spell-checker in a word processing problem won't catch factual errors in a term paper. So just because your page is designated as syntactically valid, that doesn't mean it won't have additional problems that can affect how it appears on the screen.
After you have validated your CSS, it's time to start stripping it out. Save the original version of your HTML and CSS, and work on a copy off it. Remove sections of the CSS step by step, reloading the page in the browser each time. You can remove these rules from the page by editing them out of the source, or you can comment them out.
Your goal in this process is to identify exactly which rules are causing problems for you. Cut away any extraneous style rules that you suspect have nothing to do with your problemsbut be sure to reload after each removal, because it's possible that something that appears completely unrelated might be causing your problems! Style rules sometimes have unintended consequences.
Problems involving the cascade are particularly hard to spot at first glance because the individual rules look right, and the effects of the combination can be tricky to figure out. If you need to, review [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7], "Cascading and Inheritance," for details on how selectors are given higher specificity based on the types of selectors used. The more selectors of each type used, the more specific the rule; <code>id</code> selectors beat class (and pseudo-class) selectors, and class selectors beat element type selectors.
You should also watch for shorthand properties, such as <code>font, background, border, margin</code>, and so on. These properties not only set the values given, but also reset to the default (by the CSS specification, not by other rules on your page) any of the properties they represent. Consider this rule:
<div><pre>.sidebar { font-weight: bold; font: 12pt Verdana, sans-serif; }
</pre></div>
This certainly looks as if it would give you Verdana text, 12 points high and in bold. But it won't. Because the <code>font</code> rule listed here is a shorthand property, it is actually identical to the following:
<div><pre>font-style: normal;
font-variant: normal;
font-weight: normal;
font-size: 12pt;
line-height: normal;
font-family: Verdana, sans-serif;
</pre></div>
Because the <code>font</code> rule follows the <code>font-weight: bold;</code> rule, the weight of the font is effectively set back to <code>normal</code> from <code>bold</code>. The sidebar text would be 12 point Verdana, but it would not be bold.
Narrowing down your rules to a smaller set and checking the cascading, inheritance, and shorthand properties can identify many of these kinds of mistakes in your style sheets.
Ruling Out Browser Bugs
Now, it may be that you've made no mistakes at all in your CSS rules. As discussed throughout this book, especially in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3], "Browser Support for CSS," no browser has perfect support for the CSS standards and all have quirks and bugs ranging from minor to serious. So it's possible that a problem just isn't your fault.
To identify whether a CSS problem is the result of a browser quirk or bug, you'll first need to do some browser testing in alternate browsers. This should be part of your normal routine anyway, but you use a slightly different approach when hunting down a problem. Your goal is not to make it appear the same, but to see whether or not you can reproduce the problem on other browsers with different layout engines, including mostly compliant browsers (such as Firefox, Opera, or Safari).
Use the simplified version of the style rules you developed when narrowing down the rules to a smaller subset, and see whether you can confirm what the correct behavior should be. If two or three other browsers agree on the way your CSS code should be presented, they're probably right; however, if there's one browser that's just doing it all wrong, you most likely have stumbled onto a browser bug or quirk.
<div>By the Way
When you are trying to hunt down problems in Internet Explorer, make sure you are aware whether or not you are in "quirks mode." By default, Internet Explorer 6 is in a quirky, backwards-compatible mode that matches IE 5 and 5.5, but you can put it into a more standards-compliant mode by using a <code><!DOCTYPE></code> definition, as you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4].</div>
If you think you've found a bug, you may be rightand you may not be the only person to find it. Check on some of the very valuable websites that document browser bugs, such as Position Is Everything ([http://www.positioniseverything.net/ http://www.positioniseverything.net/]), or simply do a web search with keywords such as the name of your browser, the name of the CSS property, and "bug." You'll likely find other people who have encountered the same problems, and advice on how you can use other browser quirks to get yourself out of your difficulties.
./ ADD NAME=CH24LEV1SEC2.HTML
Browser Hacks
In a perfect world, you could sit down with this book, a copy of the CSS specification, and your computer, and write style sheets that display properly on every browser in the world. Unfortunately, as discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3], we don't live in that perfect world yet. Each browser has its own quirks and bugs, some very minor and some quite serious.
To work around these quirks and bugs, web designers have developed certain techniques for dealing with browsers that don't always behave as they should. Somewhat ironically, these techniques themselves rely on quirks and bugs themselves to get around other quirks and bugs.
A browser hack, therefore, is any technique that uses CSS rules (or sometimes HTML tags) in a quirky way to address a known problem in a browser. If a CSS rule wouldn't be included in that perfect world, but is included because, for example, Internet Explorer 5.5 has a bug, then that rule is the result of a browser hack.
A hack isn't all bad, mind you. The term "hack" has both negative and positive connotations in the English language, depending on the context in which it is used. A hack writer is a bad writer, but in computer programming, a hacker is a deft manipulator of the computer systemas opposed to a cracker, which is someone who maliciously breaks in and steals your data.
In the sense we're using it here, a browser hack is an unfortunate compromise forced upon web designers because of browser limitations. Nobody likes to use a browser hack; we'd rather live in a CSS utopia where rules work correctly. A browser hack is therefore a compromise we live with because we have to.
Browser hacks have several identifying features. First, they are targeted at specific web browsers. One browser hack might be aimed at Internet Explorer 5.5, whereas another works to correct a quirk in Opera 7. Secondly, browser hacks are almost always valid CSS, especially if they're well-written hacks. Thirdly, they exploit bugs or limitations in the targeted browser that deal with how it handles proper CSS.
Some browser hacks use selectors that are not implemented in the target browser, and thus will be ignored. For example, if you want to write a rule that won't be understood by Internet Explorer 6, an easy way to do this is to use one of the selectors from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], "Advanced Selectors," such as an attribute selector. Other browser hacks depend on bugs in the way the layout engine reads through the style sheet and parses out the CSS rules. For example, certain browsers have problems with comments stuck in the middle of property names, and these bugs can be exploited to write rules targeting those browsers.
The vast majority of browser hacks depend on at least two bugs: one in the way the rule is read by the layout engine, and one in the way the layout engine places the content on the page. The combination of these two bugs results in a hack to use the former as a fix for the latter. These double-bug browser hacks are useful only as long as each bug is unique to only that browser.
The examples in this hour use Internet Explorercurrently the most commonly used quirky browser, as described in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3]to illustrate how filtering works. You can find specific hacks for specific browsers at Position is Everything ([http://www.positioniseverything.net/ http://www.positioniseverything.net/]) and Centricle ([http://centricle.com/ref/css/filters/ http://centricle.com/ref/css/filters/]), among other sites.
Filtering Out Specific Browsers
As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], "Box Sizing and Offset," there is a bug in the way certain versions of Internet Explorer calculate the width (and height) of a box. This is called the IE box model bug. Versions of Internet Explorer prior to 6 (and IE 6 in quirks mode) miscalculate the box dimensions by including the border and padding in the width and height.
If you use CSS to set a box's <code>width</code> to 600 pixels, plus another 300 pixels of border and padding, most browsers correctly display this as 900 pixels wide. Internet Explorer makes the box 600 pixels across. If you set the <code>width</code> to 900 pixels, it displays as desired in Internet Explorer, but is suddenly 1200 pixels wide in compliant browsers. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig03 Figure 24.3] shows exactly this scenariothe <code>width</code> has been set to 600 pixels, and Internet Explorer displays it incorrectly.
<div style="text-align: center;"> Figure 24.3. This box should be 900 pixels wide, but IE miscalculates. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/24fig03_alt.jpg [View full size image]]</div>[[Image:24fig03.jpg|500px]] </div>
It would be nice if there were a way to feed separate values for <code>width</code> to Internet Explorer and to browsers that respect the standards. This desire has led to the development of browser filters. A <code>filter</code> is a kind of browser hack that targets certain browsers by writing rules that either are ignored by only those browsers, or understood by only those browsers.
You can use browser filters to address the box model bug in Internet Explorer. One way to do this is by using a rule other browsers understand, but that Internet Explorer cannot understand, and will therefore ignore.
<div>Did you Know?
As explained in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch18.html#ch18 Hour 18], there are several other ways to deal with the IE box model bug. One method is to simply never set the <code>padding</code> and <code>border</code> on any object that has the <code>width</code> set. Use nested <code><div></code>s instead of a single <code><div></code>, assign the (larger) <code>width</code> to the outer <code><div></code>, and the <code>padding</code> and <code>border</code> to the inner <code><div></code>. This makes your HTML more complex, which offends some markup purists because the extra <code><div></code> is extraneous.
Another method is to force Internet Explorer out of the default "quirks mode" and into "standards mode" by using a <code><!DOCTYPE></code> statement; this works only in Internet Explorer 6, which means you will still have to do something about IE 5.0 and 5.5. The filters in this hour can help you in that regard.</div>
The Direct Child Selector Filter
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch08.html#ch08 Hour 8], you learned that Internet Explorer (even version 6) does not understand the direct child selector, represented by a > symbol between the parent and child elements. This means that any rule written with a direct child selector will not be understood by current versions of IE. Therefore, you can write two rules: first, a rule setting the <code>width</code> to the Internet Explorer dimension, and then a second rule that updates that <code>width</code> to the "real" value, for browsers that understand direct child selectors. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1] is an example of this type of filter.
Listing 24.1. Using Child Selectors to Filter Out Internet Explorer
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- box-model-24-1.html --><br /><html><br /><head><br /><title>Box Model Woes</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />.bar { color: white; background: black;<br />text-align: center; margin: 1em 0; }<br />#six { width: 600px; } #nine { width: 900px; }<br />#box { width: 900px; /* The width for IE */<br />background-color: silver;<br />padding: 100px; border: 50px solid #555; }<br />html>body #box { width: 600px; }<br />/* The "real" width value */<br /></style><br /></head><br /><body><br /><div id="six" class="bar">600 pixels</div><br /><div id="box"><br /><p>This is a box displaying the box model<br />bug problem. Namely, we want it to have<br />a width of 600 pixels with a 100 pixel<br />padding on each side, and a 50 px border.<br />According to the W3C box model, the<br />box should be 600 + 100 + 100 + 50 + 50<br />= 900 pixels wide. According to Internet<br />Explorer, it should be 600 pixels wide.</p><br /></div><br /><div id="nine" class="bar">900 pixels</div><br /></body><br /></html><br /></pre></div><br />
|}
The results of displaying this page in Internet Explorer 6 (not in "quirks mode," because there is no <code><!DOCTYPE></code> in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1]) are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig04 Figure 24.4]. As you can see, the box is now the right size. A browser such as Firefox would also display the box at the same size because it would understand and use the real value of <code>600px</code> given in the child selector rule.
<div style="text-align: center;"> Figure 24.4. Internet Explorer uses the 900px value to produce a box of the proper dimensions. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/24fig04_alt.jpg [View full size image]]</div>[[Image:24fig04.jpg|500px]] </div>
The embedded style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1] first sets the <code>width</code> to the wrong value of <code>900px</code>, and then corrects it with the subsequent rule, which IE ignores. Another way to use a browser filter is to write a rule that is ignored by all other browsers, but understood by only the targeted browser. This is the opposite approach to the method in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1].
The Star HTML Filter
Internet Explorer, up to and including version 6, has a minor bug. IE believes that there is an invisible, unknown element that contains the <code><html></code> element. No other browser has this quirk, but if you write a rule such as the following, Internet Explorer will apply it:
<div><pre>* html p { color: blue; }
</pre></div>
Such a rule will make your paragraph tags blue, but only in IE. Any other browser would look first at the universal selector (*) and then at the <code>html</code> element selector, and conclude that there's no parent element that contains htmlso the rule won't apply to anything. Web designers call this the star HTMLfilter or star HTML hack.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex02 Listing 24.2] is a style sheet that uses this particular quirk to write a style rule just for Internet Explorer; this style sheet is a replacement for the embedded style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1].
Listing 24.2. A Style Sheet That Uses the Star HTML Filter
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>body { font-family: Verdana, sans-serif; }<br />.bar { color: white; background: black;<br />text-align: center; margin: 1em 0; }<br />#six { width: 600px; } #nine { width: 900px; }<br />#box { width: 600px; /* The correct width */<br />background-color: silver;<br />padding: 100px;<br />border: 50px solid #555; }<br />* html #box { width: 900px; }<br />/* The width for only Internet Explorer */<br /></pre></div><br />
|}
Internet Explorer displays the box correctly when this rule is used. IE actually reads both rules in this case, both the width of <code>600px</code> and the <code>width</code> of <code>900px</code>. It chooses to use the latter rule because of the specificity calculations that you learned about [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch07.html#ch07 Hour 7]. A rule with more selectors of a given type is more specific.
<div>By the Way
There isn't a screen capture of [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex02 Listing 24.2] displayed in a browser because it would look identical to [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig04 Figure 24.4], which illustrated the direct child filter. Later in this hour you will learn yet another way to fix the box model problem, and again it will look just like [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig04 Figure 24.4].</div>
So which method should you use? There are advantages and disadvantages to both. The technique in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex01 Listing 24.1] makes the assumption that any browser that understands direct child selectors will not have the Internet Explorer box model bug, and vice versa. So far this is true, but it is somewhat shaky ground. The star HTML hack in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex02 Listing 24.2] presumes that every browser that recognizes the nonsensical <code>* html</code> selector will also have a broken box model algorithm. Each hack therefore depends upon two unrelated bugs or quirks to function.
What if the next version of Internet Explorer fixes one of the bugs used in a hack but not both? For example, what if Internet Explorer 7 stopped believing in a fictional parent for <code><html></code>, but still had the box model bug in quirks mode? What if Internet Explorer suddenly understood child selectors?
In fact, it appears that exactly this situation has come trueas this book is being written, Internet Explorer 7 is available in only a preview release, but Microsoft's developers have warned that the star HTML selector won't be recognized by IE7, and direct child selectors will be understood. However, not all CSS bugs in IE6 will be fixed in IE7. Some web designers are upset by thistheir browser hacks will break in IE7.
Conditional Comments
Microsoft has recommended that web developers stop using filters that target Internet Explorer for inclusion or exclusion, such as the direct child hack or the star HTML hack. Instead, they promote the use of conditional comments.
Conditional comments are HTML markup following the general syntax of normal commentsthey begin with <code><!--</code> and end with <code>--></code>. This means that most browsers ignore anything between those markers, even if it looks like normal HTML tags.
However, Internet Explorer will look inside certain comments if they contain a conditional statement. These conditional statements enable you to embed within the comments some HTML tags that will be read only by Internet Explorer. You can even refine these conditional statements further by requiring that only IE browsers of a certain version read the HTML that is contained.
Here are several examples that illustrate the syntax for conditional comments:
<div><pre><!--[if IE]>
<p>Internet Explorer detected!</p>
<![endif]-->
<!--[if IE 6]>
<p>Congratulations (or condolences), you're using IE 6.</p>
<![endif]-->
<!--[if lte IE 5.5]>
<p>I'm sorry, you're using an earlier version of IE.</p>
<![endif]-->
</pre></div>
If you viewed this HTML code in a non-Microsoft browser, such as Firefox, you wouldn't see any of these messages, as anything between the <code><!--</code> and the <code>--></code> is ignored as a comment. But if you view this in Internet Explorer, you will see a message dependent upon your browser version.
Conditional statements can be as simple as <code>[if IE]</code> (to match all versions of Internet Explorer from 5.0 onward, when conditional comments were introduced), or more complex statements with the modifiers <code>lt</code> (less than), <code>gt</code> (greater than), <code>lte</code> (less than or equal to), or <code>gte</code> (greater than or equal to) matching against specific browser version numbers.
<div>By the Way
For more details on using conditional comments, read about them at the Microsoft Developer Network at [http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp].</div>
HTML-style comments aren't allowed inside style sheets, including embedded style sheets, so you can't use conditional comments mixed directly into your CSS rules. To use conditional comments with CSS, create one or more extra <code><style></code> or <code><link></code> elements containing style rules for Internet Explorer, and then wrap them in an appropriate conditional comment. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex03 Listing 24.3] contains an example that illustrates how to use conditional comments instead of the star HTML hack to fix box model problems.
Listing 24.3. An HTML File Containing a Conditional Comment
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- box-model-24.3.html --><br /><html><br /><head><br /><title>Box Model Woes</title><br /><style type="text/css"><br />body { font-family: Verdana, sans-serif; }<br />.bar { color: white; background: black;<br />text-align: center; margin: 1em 0; }<br />#six { width: 600px; } #nine { width: 900px; }<br />#box { width: 600px; /* the real width */<br />background-color: silver;<br />padding: 100px; border: 50px solid #555; }<br /></style><br /><!--[if lte IE 6]><br /><style type="text/css"><br />/* the width for Internet Explorer */<br />#box { width: 900px; }<br /></style><br /><![endif]--><br /></head><br /><body><br /><div id="six" class="bar">600 pixels</div><br /><div id="box"><br /><p>This is a box displaying the box model<br />bug problem. Namely, we want it to have<br />a width of 600 pixels with a 100 pixel<br />padding on each side, and a 50 px border.<br />According to the W3C box model, the<br />box should be 600 + 100 + 100 + 50 + 50<br />= 900 pixels wide. According to Internet<br />Explorer, it should be 600 pixels wide.</p><br /></div><br /><div id="nine" class="bar">900 pixels</div><br /></body><br /></html><br /></pre></div><br />
|}
The net result of this style sheet is identical to that in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex02 Listing 24.2], which used the star HTML filter. Most browsers receive only the first width rule, and Internet Explorer receives both. In this case, both rules have the same selector (#box) and thus the same specificity; therefore, the one defined later in the HTML source code is used. The result of displaying this web page is identical to that shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig04 Figure 24.4].
Hiding Content Meant for Screen Readers
When you are designing a web page, it's important for you to consider the needs of users with disabilities, as you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media." Using CSS means you're already off to a good start toward meeting those needs as a natural consequence of good web design techniques.
Sometimes there is a perceived conflict between designing a page that is accessible and designing one that is visually attractive. For example, web accessibility checklists such as the U.S. government's Section 508 requirements ([http://www.access-board.gov/sec508/guide/1194.22.htm http://www.access-board.gov/sec508/guide/1194.22.htm]) require web designers to provide links that skip over navigation lists and go directly to the main content of the page. Such a link might look like this:
<div><pre><p class="skiplink"><a href="#content">Skip Navigation</a></p>
<ul>
<!-- navigation links would be listed here -->
</ul>
<h1><a name="content">Main Content</a></h1>
</pre></div>
This provides easy access for users with screen readers, giving them a shortcut to avoid listening to long and possibly repetitive lists of links before getting to the main content of the site. However, this method also presents a problem: The text <code>Skip Navigation</code> is visible onscreen to all users and is a clickable link, but it doesn't actually seem to do anything, and the meaning of the text <code>Skip Navigation</code> is undoubtedly opaque to the average visually dependent web user. A web designer concerned with the visual appearance of the page is likely to want to hide these links.
Another example would be the ubiquitous search box. As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch14.html#ch14 Hour 14], "Forms," the <code><label></code> tag can be used to provide a text label for an HTML form element. But what about a short form like this?
<div><pre><form method="post" action="search.php">
<input type="text" id="searchtext">
<input type="submit" value="Search!">
</form>
</pre></div>
This type of form can be found around the Web, and for most users it is quite obvious what it does: You type something in the box and press the button and it searches. You know this because you can see the button labeled Search! to the right of the box. Visually impaired users, however, don't hear the search button first because web pages are read in order by screen readers. They hear an announcement of the input box, and don't know what to type because they don't hear the word "Search!"
The obvious solution is to add a <code><label></code> element telling the user it it's a search box, like this:
<div><pre><form method="post" action="search.php">
<label for="searchtext">Search:</label>
<input type="text" id="searchtext">
<input type="submit" value="Search!">
</form>
</pre></div>
This works great for screen reader users. However, to a web designer focused on the visual appearance, the label takes up extra space and unnecessarily repeats the word "Search."
The most obvious solution is to write a CSS rule to hide the display of the label text. That would be something simple such as
<div><pre>label { display: none; }
</pre></div>
This seems straightforward and simple, and many web designers using CSS seem to think this would work. A very famous "image replacement technique" using this method was promoted by the big names in CSS-based web designuntil it was discovered that it does not work. Why not?
Screen readers are a very specific type of technology; they read what is on the screen. If something is not displayed on the screenwhich is what <code>display: none</code> doesthen the screen reader doesn't read it. This is also why it doesn't work to simply add an <code>@media</code> rule; screen readers don't actually use the media type "aural" but instead read out the text as displayed visually by the browser.
A number of alternative methods for hiding material from visual browsers but still making it accessible to screen readers have been proposed over the years, many of them without being tested first in actual screen readers. Bob Easton has compiled a chart testing each of these methods in leading screen readers and makes the results available at [http://www.access-matters.com/screen-reader-test-results/ http://www.access-matters.com/screen-reader-test-results/].
From those results, it has become clear that the most reliable method to hide content while keeping it accessible to screen readers is called the off-left technique. In short, you use absolute positioning to place the hidden content way off to the left side of the screen, where it can't be seen but is still read out loud by screen readers. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex04 Listing 24.4] shows how you can use off-left placement to hide the <code>.skiplink</code> and <code><label></code> in the example HTML fragments.
Listing 24.4. A Style Sheet That Visually Hides Content but Leaves It Available for Screen Readers
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>.skiplink, label {<br />position: absolute;<br />left: -999px;<br />width: 90px; }<br /></pre></div><br />
|}
<div>By the Way
You might wonder whether it's really necessary to go to these lengths to hide accessibility-related content. In many cases, you can meet the needs of users with disabilities by simply designing your page differently. For example, perhaps your search form will start with a <code><label></code> of Search:, but the Submit button will read Go! instead. Even so, you may find situations in which you want to hide certain parts of your page but still make them readable by screen readers, and this is currently the best way to do that.</div>
./ ADD NAME=CH24LEV1SEC3.HTML
Proprietary CSS
Many web browsers can understand and apply more CSS properties than simply the ones listed in the CSS 2.1 specification. These additional CSS properties can expand your capabilities to style a page, but are usually restricted to only one or two browsers. Such properties are called proprietary CSS styles. Rather than being part of the standards agreed to by all browsers and developed by the World Wide Web Consortium (W3C), these CSS properties were created by the browser companies themselves. As such, they can be rather unreliable; browsers that don't understand these additional properties just ignore them.
Most responsible browser companies give these properties names that make it clear they are not ordinary CSS properties, but something proprietary. The most common way to do this is with a prefix on the property name identifying the browser or browser company. For example, proprietary properties recognized by Mozilla's Gecko layout engine all begin with <code>-moz-</code> (for Mozilla).
<div>Watch Out!
Proprietary CSS properties have an additional problem, in addition to being ignored by browsers that don't understand them. Any style sheet with a proprietary property uses invalid CSS, and thus will fail when tested with a validator. If validation is a priority for you, you should avoid using proprietary CSS properties.</div>
In the remainder of this hour, you'll learn about some of the proprietary extensions to the CSS language that can be used in current browsers. This isn't an extensive list; instead it's meant to make you familiar with the concept of proprietary CSS and the limitations involved as well. For more details on which specific proprietary values are supported by the browsers, see each browser's documentation website.
Opacity
One ability web designers greatly desire is to control the opacity of an objecthow opaque or transparent it is. An object that is partially opaque is partially transparentmeaning that anything placed behind it can be seen through that object. Control over the opacity of a content block is not available in CSS 2.1. You can't do it under the current standards.
However, in the proposed drafts for CSS Level 3, there is an opacity property. This property can be assigned values from <code>0.0</code> (completely transparent) to <code>1.0</code> (completely opaque), with a default value of <code>1.0</code>.
Some browser companies have implemented opacity in their browsers. However, as the CSS3 specification is still being written, it's not exactly prudent to use the draft as a reference. If the W3C's working group decided to change the definition of the <code>opacity</code> propertyfor example, to change it to a percentage scalethen web pages built with the early implementations would break.
To prevent these types of problems, the programmers working on the Gecko layout engine (used in Firefox and related browsers) chose to call this property <code>-moz-opacity</code>, and the creators of the KHTML layout engine (used in Konqueror) named it <code>-khtml-opacity</code>.
This is both responsible behavior and rather frustrating to web designers, because it means that to create an opaque content block, you need to set three properties: <code>-moz-opacity, -khtml-opacity</code>, and <code>opacity</code> itself, for those browsers such as Safari that jumped the gun and implemented the CSS3 version.
The situation is even more complex, thanks to Internet Explorer. Internet Explorer doesn't attempt to implement an opacity property a la the CSS3 standard. Instead, Internet Explorer provides what it calls the <code>filter</code> property, which lets you define IE-only transformations on any content block. One of those filters is the opacity filter, and that's what you use to get the same effect as the CSS3 <code>opacity</code> property.
<div>Watch Out!
This is an all too common situation where you have the same term with several meanings. As defined earlier in this hour, a browser filter is a hack designed to keep certain browsers from applying specific rules. But as used here, filter refers to a proprietary CSS property implemented by Microsoft. This leads to confusing ambiguitydoes "an Internet Explorer filter" refer to a browser hack to hide (or show) rules to IE, or to Internet Explorer's visual transformation <code>filter</code> property? In the rest of this hour, I will make it clear by context which sense of the word filter is being used.</div>
The syntax for the <code>filter</code> property is very different from the <code>opacity</code> (and <code>-moz-opacity</code> and <code>-khtml-opacity</code>) property: It uses percentages instead of a decimal number between 0 and 1. The four methods for setting opacity to 65% are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex05 Listing 24.5]. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig05 Figure 24.5] demonstrates how this is displayed in a web browser.
<div style="text-align: center;"> Figure 24.5. Firefox renders the content as partially transparent.
[[Image:24fig05.jpg|300px]]
</div>
Listing 24.5. Four Different Rules to Modify Opacity
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- opacity-24.5.html --><br /><html><br /><head><br /><title>Tucson Transfer Building</title><br /><style type="text/css"><br />body { margin: 0; padding: 0;<br />background-color: #6666CC;<br />background-position: top center;<br />background-repeat: none;<br />background-image: url("tucson-transfer.jpg");}<br />h1 { margin-top: 50px; margin-left: 5%;<br />width: 40%; text-align: center;<br />font-family: Optima, sans-serif;<br />background: black; color: white; }<br />#caption<br />{ width: 40%; position: absolute;<br />font-family: Optima, sans-serif;<br />top: 50px; right: 5%; padding: 0 0.5em;<br />background: white; color: black; }<br />#footer<br />{ font-size: small; margin: 1em;<br />padding: 0 0.75em;<br />border: 0.5em solid black; }<br />/* opacity rules: */<br />#caption, h1<br />{ opacity: 0.65;<br />-moz-opacity: 0.65;<br />-khtml-opacity: 0.65;<br />filter: alpha(opacity=65); }<br /></style><br /></head><br /><body><br /><h1>Tucson Transfer Building</h1><br /><div id="caption"><br /><p>The Tucson Warehouse and Transfer Company building is<br />located at the corner of 6th Street and 7th Avenue<br />in Tucson.</p><br /><p>The building is currently occupied by a number of<br />businesses, including an architectural firm and a<br />plumbing supply company.</p><br /><p>One of the early African-American pioneers of<br />Tucson, Henry Ransom, worked at the Tucson Transfer<br />Company from 1892 until his retirement in 1931.</p><br /><div id="footer"><br /><p>This page is part of the<br /><a href="http://kynn.com/projects/heritage-tour/"<br />>Tucson Black Heritage Tour</a></p><br /></div><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
Microsoft's <code>filter</code> Property
Microsoft's Internet Explorer understands a proprietary CSS property known as <code>filter;</code> the preceding section of this hour showed you how to use <code>filter</code> to change the opacity of a content box. Additional filters are supported by Internet Explorer versions 4 or later; these include those shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24table01 Table 24.1].
{| cellspacing="0" cellpadding="5"|+ Table 24.1. Types of Filters Available in Internet Explorer 4 or Later
|-
| Filter Value
| Visual Effect
|-
| <code>alpha(opacity=</code><code>percent</code><code>)</code>
| Changes the opacity
|-
| <code>blur(direction=</code><code>degrees</code>, <code>strength=</code><code>px</code><code>)</code>
| Applies a motion blur effect
|-
| <code>chroma(color=</code><code>rgb</code><code>)</code>
| Sets one color as transparent
|-
| <code>dropshadow(color=</code><code>rgb</code>, <code>offX=</code><code>px</code>, <code>offY=</code><code>px</code><code>)</code>
| Creates a shadow effect
|-
| <code>fliph</code>
| Flips along the horizontal axis
|-
| <code>flipv</code>
| Flips along the vertical axis
|-
| <code>glow(color=</code><code>rgb</code>, <code>strength=</code><code>px</code><code>)</code>
| Surrounds with a glow effect
|-
| <code>gray</code>
| Converts to 256-color grayscale
|-
| <code>invert</code>
| Displays in "negative" colors
|-
| <code>light</code>
| Shines a light source on an object
|-
| <code>mask(color=</code><code>rgb</code><code>)</code>
| Reveals transparent pixels and hides others
|-
| <code>shadow(color=</code><code>rgb</code>, <code>direction=</code><code>degrees</code>, <code>strength=</code><code>px</code><code>)</code>
| Adds a shadow effect
|-
| <code>wave(freq=</code><code>num</code>, <code>phase=</code><code>percent</code>, <code>strength=</code><code>px</code><code>)</code>
| Applies a sine wave distortion
|-
| <code>xray</code>
| Displays in stark black-and-white
|}
You use these filter values with the <code>filter</code> proprietary property, as you did earlier to change opacity. For example, to create a shadow in Internet Explorer, you can write the following CSS rule:
<div><pre>img.shadowed { filter: shadow(color=#808080, direction=135, strength=5); }
</pre></div>
This creates a shadow around any <code><img></code> that has the <code>shadowed</code> class; the shadow will be gray in color, will be offset 135° (with 0° pointing toward the top of the screen), and will extend for 5 pixels.
Internet Explorer version 5.5 and later versions support additional filters and use a more complex syntax, although they also understand the IE4 versions. As an example, to write a rule using the <code>fliph</code> and <code>glow</code> filters in Internet Explorer 4 syntax, you can write
<div><pre>h3 { filter: fliph glow(color=lime, strength=5); }
</pre></div>
The Internet Explorer 5.5 version of this rule is:
<div><pre>h3 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)
progid:DXImageTransform.Microsoft.Glow(color=lime, strength=5); }
</pre></div>
For full details on Internet Explorer filters, see the Microsoft Developer Network Site page at [http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/reference.asp http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/reference.asp], which has documentation and sample code.
Mozilla Corners
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch19.html#ch19 Hour 19], "Absolute and Fixed Positioning," you learned how to create rounded corners on boxes by using images, absolute placement, and trimming. Browsers based on the Gecko layout engine, such as Firefox, Camino, or SeaMonkey, recognize proprietary CSS properties that enable you to create these effects entirely with styles instead of images.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24table02 Table 24.2] is a listing of these properties. Each property begins with the <code>-moz-</code> prefix to indicate that these are proprietary properties. Other browsers don't recognize these properties; they are ignored silently, and the corners of selected boxes remain square.
{| cellspacing="0" cellpadding="5"|+ Table 24.2. Properties Creating Curved Corners in Gecko-Based Browsers
|-
| Property Name
| Effect
|-
| <code>-moz-border-radius</code>
| Sets the radius for all four corners.
|-
| <code>-moz-border-radius-bottomleft</code>
| Sets the radius for the bottom-left corner.
|-
| <code>-moz-border-radius-bottomright</code>
| Sets the radius for the bottom-right corner.
|-
| <code>-moz-border-radius-topleft</code>
| Sets the radius for the top-left corner.
|-
| <code>-moz-border-radius-topright</code>
| Sets the radius for the top-right corner.
|}
The <code>-moz-border-radius property</code> is similar to the border, margin, and padding properties in that you can give it one, two, or four values. If one value is given, then the border radius for each corner is set to that value. If two are given, the first value is applied to the top-left and bottom-right corners, and the second value to the top-right and bottom-left. If four values are given, they are assigned to the top-left, top-right, bottom-right, and bottom-left corners respectively.
The values for the properties in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24table02 Table 24.2] can be measurements such as <code>2em</code> or <code>12px</code>, or percentages based on the height of the box. These measurements indicate how far in from the corner, in both directions, the radius of a circle should be drawn. The edge of the box is then wrapped along that circle, and the border (if any) is drawn on that edge. If there is a background, the background ends at the newly drawn quarter-circle edge rather than continuing to fill out to the corner of the box.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24ex06 Listing 24.6] gives an example of the corner properties in use. Each box is styled with a different radius for illustrative purposes.
Listing 24.6. Boxes with Curved Corners
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- rounded-corners-24.6.html --><br /><html><br /><head><br /><title>Daily Reminder List</title><br /><style type="text/css"><br />body { margin: 0; padding: 2em;<br />font-family: Verdana, sans-serif;<br />color: black; background: white; }<br />h1 { padding: 0.5em; margin: 0;<br />border: 2px solid black;<br />background-color: silver;<br />-moz-border-radius: 0.75em; }<br />#todo { border: 3px solid gray; padding: 25px;<br />width: 40%; position: absolute;<br />left: 2em; top: 8em;<br />-moz-border-radius: 0 10%; }<br />#schedule { border: 3px solid gray;<br />width: 40%; position: absolute;<br />right: 2em; top: 8em; padding: 25px;<br />-moz-border-radius: 20px 300px 65px 0; }<br />#schedule dl { margin-left: 20%; }<br />#schedule dt { float: left; width: 20%;<br />margin-left: -20%; text-align: right;<br />font-weight: bold; font-size: small; }<br />#schedule dd.empty { background-color: silver; }<br />#schedule dd { margin: 3px 0; width: 60%;<br />height: 1.5em; padding: 2px 10px;<br />background-color: gray; color: white;<br />-moz-border-radius: 50%; }<br /></style><br /></head><br /><body><br /><h1>Daily Reminder List</h1><br /><div id="todo"><br /><h2>Things to Do</h2><br /><ul><br /><li>Feed the cat</li><br /><li>Pay bills</li><br /><li>Laundry</li><br /><li>Change the oil</li><br /><li>Call mom and dad</li><br /><li>Go shopping</li><br /></ul><br /></div><br /><div id="schedule"><br /><h2>Today's schedule</h2><br /><dl><br /><dt>9:00</dt><dd class="empty"></dd><br /><dt>10:00</dt><dd>Conference call</dd><br /><dt>11:00</dt><dd class="empty"></dd><br /><dt>12:00</dt><dd>Lunch</dd><br /><dt>1:00</dt><dd>Client Meeting</dd><br /><dt>2:00</dt><dd class="empty"></dt><br /><dt>3:00</dt><dd>Staff Party</dd><br /><dt>4:00</dt><dd class="empty"></dd><br /><dt>5:00</dt><dd class="empty"></dd><br /></dl><br /></div><br /></body><br /></html><br /></pre></div><br />
|}
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24fig06 Figure 24.6] shows how these boxes appear in a Gecko-based browser.
<div style="text-align: center;"> Figure 24.6. Firefox displays the box with rounded corners. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/24fig06_alt.jpg [View full size image]]</div>[[Image:24fig06.jpg|500px]] </div>
./ ADD NAME=CH24LEV1SEC4.HTML
Summary
To properly troubleshoot your style sheet, you need to start with valid HTML and CSS. The W3C's online validators can check for problems in your code and offer warnings about possible problems. After you have eliminated syntax errors, you should simplify your code until you spot the source of your problems.
If it turns out that you're dealing with a browser bug or quirk, you may need to use a browser hack to fix the problem. Most browser hacks rely on using one bug to fix another, including browser filters that exclude or include targeted browsers. Examples include the direct child selector hack and the star HTML hack, which can be used in rules targeting Internet Explorer quirks and bugs. You can also use Microsoft's conditional comments to provide rules that are recognized by only Internet Explorer.
Some browsers have extended the CSS they recognize beyond the specifications written by the W3C; the results are proprietary CSS properties. Examples of proprietary properties include the various versions of opacity, Internet Explorer's visual transformation filters, and Gecko's rounded corners.
./ ADD NAME=CH24LEV1SEC5.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa1q1a1 Q.]'''
| The HTML and CSS validators provide little buttons saying my code is valid. Should I use those?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa1q1 A.]'''
| It's really up to you. As a matter of aesthetics, most websites aren't designed to look good with those graphics slapped onto them; the colors, fonts, and designs of the buttons aren't guaranteed to be compatible with any random site you might create. Furthermore, the information conveyed"valid HTML!"will mean nothing to your target audience for your site, unless you are designing a website for web developers.
On my personal sites, I usually use a simple text link to the validators. Keep in mind that by putting up one of these buttons or links, you are obligating yourself to validate your HTML and CSS each and every time you make a change. It's really embarrassing to proudly proclaim your compliance with the standards, then have someone email you that the site isn't really valid CSS because you wrote <code>pudding</code> for <code>padding!</code>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa1q2a2 Q.]'''
| What should I use to filter for Internet Explorer?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa1q2 A.]'''
| Before Internet Explorer 7 came on the scene, both of the CSS-based filtering techniques given in this hour would have worked welldirect child selectors and star HTML selectors. With IE7 promising to fix both of these bugs, hacks that rely on them will no longer function for version 7 (but will still work in earlier versions). For this reason, conditional comments seem to be the safest bet.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q1a1 1.]'''
| Which of the following is not a benefit of validating your HTML and CSS?
<div># <div>You will find typographical errors in the names of CSS properties.</div>
# <div>The validator will warn you about problems with unset background colors.</div>
# <div>You will be able to use proprietary CSS properties easily.</div>
# <div>Unclosed or prematurely closed HTML tags will be brought to your attention.</div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q2a2 2.]'''
| You want to make an image appear to be 50% transparent. Which set of rules accomplishes this on the widest variety of browsers?
<div># <div><div><pre>img.fade { opacity: 50%; -khtml-opacity: 50%;<br />-moz-opacity: 50%; -ie-opacity: 50%; }<br /></pre></div></div>
# <div><div><pre>img.fade { opacity: 0.5; -khtml-opacity: 0.5;<br />-moz-opacity: 0.5; -ie-opacity: 0.5; }<br /></pre></div></div>
# <div><div><pre>img.fade { opacity: 0.5; -khtml-opacity: 0.5;<br />-moz-opacity: 0.5; filter: alpha(opacity=50); }<br /></pre></div></div>
# <div><div><pre>img.fade { opacity: 50%; -khtml-opacity: 50%;<br />-moz-opacity: 50%; filter: alpha(opacity=50); }<br /></pre></div></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q3a3 3.]'''
| You want to send a style rule to Internet Explorer only (versions 6 or lower). Can you name at least three ways to do this?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q1 1.]'''
| (c) is not a benefit of validation; if you try to validate a style sheet with proprietary CSS properties, you will get an error message.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q2 2.]'''
| The correct answer is (c). There is no property named <code>-ie-opacity</code>, and the other opacity values must be written as decimal numbers between 0 and 1, not as percentages.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch24qa2q3 3.]'''
| The three methods you learned in this hour were the direct child selector browser filter, the star HTML selector browser filter, and conditional comments.
|}
Exercise
Your ability to test browser filters depends on which browsers and operating systems you have access to. To better understand browser filtering, use the Centricle listing of filters ([http://centricle.com/ref/css/filters/ http://centricle.com/ref/css/filters/]) to discover hacks that target your specific browsers, and write rules that apply to those browsers only. Validate your code to see whether the browser filters are producing legitimate CSS. If your browsers support proprietary CSS properties, add those to your style sheet and then validate. What does the validator seem to think of your non-standard CSS?
gsin64jx5z73hwunexxggbfbzu8ob1m
User:Bartlett/21
2
2126
39231
5526
2026-04-13T06:03:24Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39231
wikitext
text/x-wiki
./ ADD NAME=CH21.HTML
Hour 21. Web Design with CSS
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* Why it's important to design for your audience and to test carefully
* How to incorporate style sheets into your web design practices
* Which questions you need to ask yourself before starting on a style sheet
* How to organize your style sheets to make them easier to use and edit
* How to create alternate style sheets that can be selected by your site visitors
The web developer's role is more than just that of a programmer or code author. In addition to understanding properties, values, selectors, and the cascade order, a CSS developer needs to be conversant in the art of design and the craft of usability.
|}
./ ADD NAME=CH21LEV1SEC1.HTML
Basic Principles of Web Design
In previous hours, you've learned the "what" of using Cascading Style Sheets. You can write your own rules, set your own fonts, choose your colors, and lay out a page.
In this hour, you'll look at the question of "when," which is what design principles are all about. It's not enough to know the method of doing something; you also need to know the right times to do it and when it's best to not do it.
Web development is a complex field, even if some of the component parts seem simple at first. Designing a website is all about balance; it's a complicated balancing act between the desires of the site operator and the needs of the audience. Even basic issues such as how much content to place on each page require finding the right balance between too much and too little. Web developers spend a lot of time making compromises, often choosing an alternative that isn't necessarily the absolute best but that works for the greatest amount of people.
Designs that reflect an understanding of the audience and put their needs first are referred to as user-centric designs. Some site designs are designer-centric, meaning that the web developer's need for artistic expression comes first; for some sites, such as a personal website, this may make sense. More common are content-centric designs, which are focused on the site information and functionality. Content-centric sites are usually more effective than designer-centric sites, but their designs sometimes fail to fully understand how their content is used in practice. An effective designer utilizes all these techniques to create web designs.
Color, Fonts, and Layout
Presentation isn't everything, but it's a whole lot of something. In an information-intensive medium such as the Webaccessed visually by most usersit's important to have an effective presentation that supports the purpose of the site. Rather than being mere window dressing, style sheets can be an integral part of a website, crucial to understanding and using the site.
Some people think that because the Web is a completely new medium, the old rules of offline design don't apply. Although the Web does introduce new challenges because of the nature of the medium, it's not so revolutionary that everything can be discarded. The disciplines of graphic design and user-interface design have a lot to teach, but few web developers learn it. For example, graphic design can tell you much about the effective use of color and whitespace, and user-interface design informs you how computer users make choices.
On the other hand, some designers make the opposite mistake of assuming they can just put the same design on the Web as on paper, and this often leads to disastrous results. "Brochure" websites gained a bad reputation early, and in most cases it was deserved, based on sites that were barely more than a scanned pamphlet posted on the Internet. The flexible nature of web design, where the user's choices can influence the final presentation as much as the author's, can prove frustrating and incomprehensible to graphic artists who are used to working in a fixed, printed medium.
As noted in previous hours, font and color rules should be used sparingly; don't go nuts simply because you can. A restrained presentation usually looks better than an overly complex one that is awash in every hue under the sun and set with dozens of fonts.
CSS rules can be used for a number of effects in combination, including simulating buttons and logos with styles. This is generally a good idea, although in some cases you'll be unable to get the exact effect you want. For example, if you need a rare font with a drop shadow, you're in trouble because the user may not have the same font on her browser, and text shadow effects are tricky in CSS. In those cases, you should use a GIF or JPEG with text to gain the desired effects.
<div>Did you Know?
Navigation menus created with CSS instead of graphics are much easier to maintain and load faster than images. If you need to add a new link, just add the HTMLno need to open a graphics program.</div>
Usability
Not all attractive web pages are created equal. Some great-looking sites are hard to use, whereas others are elegantly straightforward and a joy to use. The difference isn't found in the appearance alonealthough the visible look can affect ease of usebut instead in a somewhat nebulous quality called the usability. The usability of a website is a measure of how easy it is for people to use that site. Usability is also the name of a field of study concerned with understanding and improving how people use computers, websites, and other technologies.
<div>Did you Know?
Jakob Nielsen's website at [http://www.useit.com/ http://www.useit.com/] has good information on usability. You may also notice that his site is very plain. This is more a reflection of Jakob's personal aesthetic than of a strict usability principle. A website can (and should) employ good visual design in addition to adherence to usability; there's not a conflict between the two, and a great visual design is actually a boon to usability.</div>
Cascading Style Sheets can be used to enhance usability by producing web presentations that are simple and distinct. Your styles should reflect how the information is used, highlighting information that is most essential to the site's purpose and the user's needs while still allowing access to all the content.
For example, you can make your site's navigation system stand out by giving a distinct appearance to that part of the pagevisible enough that it can be found, but not so intrusive that the design overwhelms the rest of the content.
Many popular conventions observed on the Web are so widespread that they are second nature to use, making your site easier for visitors. As an example, placing a row of links with distinct styles on the left or top of your page lets users instantly recognize those as navigation links. Don't be afraid to reuse existing web design elements in this manner; often a site that is too creative can inadvertently become amazingly difficult to use.
Knowing Your Audience
To create user-centric designs, you need to be aware of who your audience is. In some cases, you may be in luck, as you may know everything there is to know about your users. For example, if you are working on an intranet site for your employer, and the company has standardized on Firefox, your task suddenly becomes a lot easier. You can use advanced features found only in Firefox and you don't have to worry about quirks in Internet Explorer, Opera, or other browsers.
<div>Watch Out!
However, there's a danger in taking intranet "freedom" too far. You may have to recode your entire site if there's a policy change mandating a new browser or a new version of the same browser. Some users may prefer to use familiar software, such as the Internet Explorer browser they used at their last job. Employees with disabilities might employ special assistive technologies to access the intranet. It usually saves you time and effort in the long run if you design your site to be generally accessible by everyone and not dependent upon a single browser.</div>
If you don't know exactly who your audience is, you can still make some educated guesses. Web servers dutifully record all accesses, and the information they save includes the browser type (name, version, and platform) of each person who downloads a file. These are stored in a web server log, a long listing of all connections to the server; you can then run a log analysis program, such as Analog ([http://www.analog.cx/ http://www.analog.cx/]), to collate and summarize this information. If your ISP or web host doesn't provide you with this information, ask for it; it's important data for anyone running a website.
The information you're looking for is not only the type of browser, but also which pages are being used. By looking at site usage patterns you can discern which pages are most popular and also measure the effectiveness of your navigation systems. You can also learn other useful information such as screen resolution from your browser statistics. This is useful for knowing how to design your page layouts and font sizes.
Another useful tactic for getting information on your users is to simply ask for it. Put up a survey on your site to gather responses from your current users so you can serve their needs better. In addition to gathering technical browser information, you should consider other demographics that can also affect the way you design the site. For example, generational differences among audiences can influence whether you build your site for younger or older users. Users with disabilities may have specific needs; in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22], "Accessibility and Print Media," you'll find out more about how to satisfy those needs.
Organization and Planning
Before you write one line of HTML or CSS code, you need to spend some time planning out your site and organizing the information contained on it. A carefully planned site is much easier to maintain and update than one that grows organically, out of control. Websites have a natural tendency to evolve, and this is a good thing, but planned growth is always better than accidental growth.
You may want to draw your site out on paper; you might want to create a diagram with software that creates flow charts. The exact way in which you plan your site will depend on your own preferences. Building a chart of your web content and the links between pages will help you visualize the information and group it into natural sections. The better you organize the page, the easier it will be for users to find your content.
Testing Your Website
After you've got the site up and running, it's time for testing. The first testing will be your own browser tests, using your suite of browsers. In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch03.html#ch03 Hour 3], "Browser Support for CSS," I recommended building up a standard set of browsers, ideally on different platforms if you can manage it, which represent a broad spectrum of web users. After you start using a browser with decent CSS support, such as Opera, Netscape 6, or Internet Explorer, you may not want to use older or broken browsers regularly. However, it's still important to test on those because, for whatever reason, people are still out there using them!
After you've given your pages a once-over, you're not really finished. For the same reason that writers can't edit their own work, you can't be the only one to test your web pages. A writer will often miss mistakes she's generated, because she knows how something's supposed to be written, and her mind fills in the correct version instead of what's really on the page. For the same reason, you'll want to have others test your site.
One thing you can do is to ask some fellow web developers for a critique. Because they understand the code behind the designs, they can often point out not only mistakes, but also how to fix them. If you don't know any other web developers, consider joining a local group or a mailing list.
Another way to test your site is by doing user testing, one of the core techniques employed by usability experts. In a formal usability test, you get a number of people and have them attempt to use specific site features, filming them and taking notes from behind a one-way mirror. As explained by Jakob Nielsen, a formal usability test may be overkill; a small sample of around five representative users should be enough, and you can get by without the camera and the mirror.
Here's how you do it:
<div># <div>Look over your site and choose several primary functions that users would want to accomplish. Write up several of them (five is a good number again) as tasks or questions; select a variety of functions ranging from easy to difficult. For example, to do such a test on [http://www.css24.com/ http://www.css24.com/], I might choose, "Who is the technical editor of this book?" and "Order this book from Amazon.com" as two of the questions. (On the latter task, I wouldn't require that the transaction actually be completed.)</div>
# <div>Find your test subjects. Ask them politely, and if possible, offer them compensation or a latte. As much as possible, choose representative users, but don't get obsessed about making sure they're "really" representative. For example, I wouldn't choose my mom for a test of the book's site because she's not a web developer and won't be using CSS, but I might ask my dad, who has done web design himself. If you work for a large company, find some users outside your workgroup who can spare a few minutes.</div>
# <div>Invite each user to access the website and have them attempt the list of tasks you've created. Stress to your users that you're testing the site, not them; if they get something wrong, that's great because it points out a weakness in your design. Watch the users and take notes as they move around your site. No matter how strong the temptation, don't jump in and help them; if they can't figure something out, write that down.</div>
# <div>When the test is over, thank your test subject and buy that latte. Then sit down with the results and make sure your ego is safely locked away; every site can be made better. Look at all the comments and notes you made and look for patterns across your users. If a certain function is hidden or confusing for several of them, it's likely a good candidate for redesign.</div></div>
As you can see, this kind of easy user testing isn't a formal science, but it can still produce very useful results. It's certainly better than doing no user testing at all, which is sadly the case for many websites.
./ ADD NAME=CH21LEV1SEC2.HTML
The Role of CSS in Web Design
As a web developer, skilled in HTML, Cascading Style Sheets, and possibly other web languages and technologies, you have a web development process. Even if you haven't planned it out formally, you've got a method that works for you, whether it's as simple as sitting down and designing whatever strikes your fancy or as complex as working in a multi-developer corporate development system for a large employer.
Adding CSS to your repertoire has made you an even better web developer than before; your skill set has expanded and the types of designs you can create are nearly limitless. The next step is to integrate your CSS skills into your web development process. I'm not going to tell you exactly how you'll do thatpeople have their own methodsbut I'll help you think about how you can go about using CSS in your web designs.
In a few cases you may be able to develop your style sheets completely separately from your HTML pages. More commonly you'll employ an iterative process, where you make changes to the style sheet, then changes to the HTML page, and then go back to the style sheet for a few more tweaks until you're satisfied with the results. The adaptive nature of style sheets makes it easy to create these kinds of changes, and you may find yourself continuing to perfect your styles even after you post your content on the Web.
<div>By the Way
You may not be starting with a blank slate and an uncreated website when you begin using CSS. Redesigns are very common in web development, and you may want to take advantage of a new site design to convert to a CSS-based presentation. It can sometimes be harder, but it's certainly possible to keep the same look and feel of your site when converting it to use CSS. If you're using a content management system (CMS) that automatically generates your website from a database, converting to style sheets may be a snap. CSS is very compatible, on a conceptual level, with the idea of templates as used by content management systems.</div>
As mentioned at the start of this hour, CSS design involves balancing a number of factors to arrive at the best compromise for your site and its users. Questions will arise as you work with CSS on any site, and you'll need to answer them before you go on. I've listed several of these key questions here to help you plan your site:
* Will you use Cascading Style Sheets, and if so, to what effect? You certainly aren't required to use CSS, even after reading this entire book. You can create websites that are usable, accessible, attractive, and effective without a single CSS property anywhere in evidence. However, using CSS will make your site more flexible and easier to maintain and will give you access to presentation effects you couldn't get through HTML alone.
* What "flavor" of HTML will you use? As you may recall from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4], "Using CSS with HTML," there are three varieties of HTML: Strict, Transitional, and Frameset. The Strict variety relies upon CSS for all styling effects, whereas Transitional (and Frameset) HTML can mix CSS rules with presentational markup. If you're concerned about older browsers that don't understand CSS, you may want to choose Transitional.
* Which browsers will you support? By "support," I mean investing the effort to work around the quirks of certain browsers. (By "certain browsers," I mostly mean Internet Explorer 6 and earlier.) This book has a number of workarounds, plus ways to exclude certain browsers from viewing styles. If you are designing just for CSS-enabled browsers, such as recent Firefox, Safari, or Opera versions, those workarounds become less important.
* Are you using positioning CSS for layout? It's relatively easy to use CSS for formatting text, controlling fonts, and setting colors. Using it for layout is trickier, especially with inconsistent browser support among some of the older versions. Don't assume that you must use positioning CSS; even in 2006, many sites are still using tables extensively for page layout. Using CSS for positioning is still more tricky for some developers than misusing the <code><table></code> tag.
* Will you use embedded or linked style sheets? Here, I'll give you advice: Use linked style sheets whenever you can. Many of the examples in this book use embedded style sheets, but that's mainly because it's easier to give you one listing than two.
The preceding list isn't exhaustive; you'll encounter more choices to make when designing and using CSS, but you should have learned enough by now to answer them.
Style Sheet Organization
The way you organize your style sheet can affect how easy it is for you to use and maintain your CSS, even if the effects are not evident in the presentation. This becomes even more critical if you're in a situation where someone else may have to use your styles in the future. You may work with an organization where multiple people will be working on the same site, or perhaps when you move on to another job your successor will inherit your style sheets.
To make a great style sheet, be organized and clear in what you're doing, and above all, use comments. Web developers often overlook comments in CSS, but if you have to come back later and try to figure out why you did something, they're invaluable. Comments can also be used to group related styles together into sections.
Reasonable names for <code>class</code> and <code>id</code> attributes can make your style sheet easier to read; choose names for these important selectors that reflect the functions of the elements. If you can, avoid selectors based solely on appearance characteristics, such as the <code>boldtext</code> or <code>redbox</code> classes; instead try something descriptive of why you've chosen those styles, such as <code>definition</code> or <code>sidebar</code>. That way, if you change your page styles later, you won't have to rewrite your HTML; there are few things as confusing as a rule like the following:
<div><pre>.redbox { color: blue; background-color: white; }
</pre></div>
In what way is that box red? Well, it probably was red in some prior incarnation of the style rules, but not now.
When you list your rules in your style sheet, do them in a sensible order. Generally speaking, it's best to start with the body rules first and then proceed down from there, but because the cascade order matters only in case of conflict, it's not strictly necessary to mirror the page hierarchy. What's more important is that you are able to locate the rules that apply to a given selector and to discern which styles should be applied.
An example of bad style sheet organization is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21ex01 Listing 21.1]. This is part of the style sheet from the author's personal website, but with the rules in a scrambled order. How hard is it for you to figure out what is going on here?
Listing 21.1. A Randomly Organized Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>#sidebar0 .section, #sidebar1 .section { font-size: smaller;<br />border: 0px solid lime; text-transform: lowercase;<br />margin-bottom: 1em; }<br />gnav a:link, #nav a:visited, #footer a:link, #footer<br />a:visited { text-decoration: none; color: #CCCCCC; }<br />#nav .section, #nav .shead, #nav .sitem, #nav h1 { display:<br />inline; }<br />#sidebar1 { position: absolute; right: 2em; top: 3em;<br />width: 9em; } a:link { color: #DD8800; text-decoration: none; }<br />#main { } a:hover { color: lime; }<br />#nav .shead, #nav .sitem { padding-left: 1em; padding-right:<br />1em; }<br />#nav { position: fixed; top: 0px; left: 0px; padding-top:<br />3px; padding-bottom: 3px; background-color: #333333; color:<br />white; width: 100%; text-align: center; text-transform:<br />lowercase; }<br />#nav .section { font-size: 90%; } #layout { padding: 1em; }<br />body { background-color: white; color: #333333; font-family:<br />Verdana, sans-serif; margin: 0; padding: 0; }<br />#nav h1 { font-size: 1em; background-color: #333333; color:<br />white; } a:visited { color: #CC8866; text-decoration: none; }<br />#nav { border-bottom: 1px solid lime; } #main { margin-left:<br />11.5em; margin-right: 11.5em; border: 0px solid lime;<br />margin-bottom: 1.5em; margin-top: 1.5em; }<br />#nav a:hover, #footer a:hover { color: lime; }<br />#sidebar0 { position: absolute; left: 2em; top: 3em;<br />width: 9em; text-align: right; }<br /></pre></div><br />
|}
If that was hard to follow, don't feel bad; the difficulty was intentional. CSS rules are very easily obfuscated if you're not careful. Most style sheets grow organically as piecemeal additions are made; discipline is necessary to keep the style sheet readable.
The style sheet in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21ex02 Listing 21.2] is really the same style sheet as in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21ex01 Listing 21.1]. Both are valid style sheets and both produce the same results when applied to the web page, but the second one is easier to understand. Comments make clearer what each section of the style sheet does, indentation and whitespace are used effectively, and the order is much easier to follow.
Listing 21.2. A Better-Organized Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* default styles for the page */<br />body { background-color: white;<br />color: #333333;<br />font-family: Verdana, sans-serif;<br />margin: 0;<br />padding: 0; }<br /><br />a:link { color: #DD8800; text-decoration: none; }<br />a:visited { color: #CC8866; text-decoration: none; }<br />a:hover { color: lime; }<br /><br />/* layout superstructure */<br />#layout { padding: 1em; }<br /><br />/* top navigation bar */<br />#nav { position: fixed;<br />top: 0px; left: 0px;<br />color: white; width: 100%;<br />padding-top: 3px; padding-bottom: 3px;<br />background-color: #333333;<br />text-align: center;<br />text-transform: lowercase; }<br />border-bottom: 1px solid lime; }<br />#nav .section, #nav .shead, #nav .sitem, #nav h1<br />{ display: inline; }<br />#nav .section<br />{ font-size: 90%; }<br />#nav .shead, #nav .sitem<br />{ padding-left: 1em; padding-right: 1em; }<br />#nav h1 { font-size: 1em;<br />background-color: #333333; color: white; }<br />#nav a:hover, #footer a:hover<br />{ color: lime; }<br />#nav a:link, #nav a:visited,<br />#footer a:link, #footer a:visited<br />{ text-decoration: none; color: #CCCCCC; }<br /><br />/* main content section */<br />#main { margin-left: 11.5em; margin-right: 11.5em;<br />margin-bottom: 1.5em; margin-top: 1.5em;<br />border: 0px solid lime; }<br /><br />/* two sidebars, absolutely positioned */<br />#sidebar1 { position: absolute;<br />right: 2em; top: 3em; width: 9em; }<br />#sidebar0 { position: absolute;<br />left: 2em; top: 3em; width: 9em;<br />text-align: right; }<br />#sidebar0 .section, #sidebar1 .section<br />{ font-size: smaller;<br />border: 0px solid lime;<br />text-transform: lowercase;<br />margin-bottom: 1em; }<br /></pre></div><br />
|}
Site-wide Style Sheets
The style sheet given in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21ex02 Listing 21.2] was created to be used on the entire site, not just on one page. Linking to an external style sheet is an easy way for you to apply style sheets over your entire set. You simply use the <code><link></code> tag on every page, with the <code>href</code> attribute set to the location of your site-wide style sheet.
A site-wide style sheet can be used to enforce a consistent appearance on the website, even if you have multiple web developers working on different parts of the same site. Additional styles can be added in embedded style sheets or in additional linked CSS files that are created for each department or business unit. For example, each department at a school may use the school's global style sheet for design elements common to the entire site, and individual departmental style sheets for that department's unique color, layout, and font choices.
./ ADD NAME=CH21LEV1SEC3.HTML
Alternate Style Sheets
Not all style sheets are going to appeal to everyone. Some users might prefer a smaller font, letting more fit on the screen, whereas other visitors to your site might require large print with high contrast.
The CSS specification allows you to create alternate style sheets that can be switched out by the user upon request. This allows you to create sites which offer a variety of "skins" that are selectable in browsers that support alternate style sheets.
There are actually three types of linked style sheetspersistent style sheets, preferred style sheets, and alternate style sheets. A persistent style sheet is one that can't be switched for another style sheet through use of the browser's mechanism for alternate style sheets; it is always on. The style sheets you have created so far have all been persistent.
A preferred style sheet is loaded automatically by the browser, but if an alternate style sheet is selected, the preferred sheet switches off, and the alternate style sheet is used instead. You can have multiple alternate style sheets, but only one preferred style sheet.
To designate an alternate style sheet that can be swapped out for the main style sheet, you change the attributes of the <code><link></code> property. A name must be assigned to a preferred or alternate style sheet and must be set as the <code>title</code> attribute on the link, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21table01 Table 21.1].
{| cellspacing="0" cellpadding="5"|+ Table 21.1. Attributes for <code><link></code> That Determine Style Sheet Type
|-
| Style Sheet Type
| <code>rel</code> Attribute
| <code>title</code> Attribute
|-
| Persistent
| <code>"stylesheet"</code>
| Unset
|-
| Preferred
| <code>"stylesheet"</code>
| <code>"</code><code>Name of the style sheet</code><code>"</code>
|-
| Alternate
| <code>"alternate stylesheet"</code>
| <code>"</code><code>Name of the style sheet</code><code>"</code>
|}
For example, imagine that you have basic rules that should always be used in <code>base.css</code>, the preferred styles in <code>default.css</code>, and an older version of your style sheet in <code>old-2005.css</code>. You would write the following HTML to allow users to switch between these style sheets:
<div><pre><link type="text/css" rel="stylesheet" href="base.css">
<link type="text/css" rel="stylesheet" href="default.css" title="Current Site Style">
<link type="text/css" rel="alternate stylesheet" href="old-2005.css" title="Last Year's Style">
</pre></div>
These attributes establish <code>base.css</code> as a persistent style sheet, <code>default.css</code> as the preferred style sheet, and <code>old-2005.css</code> as an alternate style sheet.
Browser Support for Alternate Style Sheets
You know how to designate alternate style sheets with the <code><link></code> tag, but what browsers will use them? Not all web browsers fully implement the CSS specification, and alternate style sheets are one example of this.
On a browser that supports alternate style sheets, the user can select which style sheets to use from a menu option. In Firefox, this is found on the View menu, under Page Style. As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21fig01 Figure 21.1], the title properties from the <code><link></code> tag are used as menu choices; the user can also view the page without any style sheets.
<div style="text-align: center;"> Figure 21.1. Firefox allows selection of alternate style sheets. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/21fig01_alt.jpg [View full size image]]</div>[[Image:21fig01.jpg|500px]] </div>
As of early 2006, only Firefox and Opera support selection of alternate style sheets from the browser interface. Other browsers apply persistent and preferred style sheets, but don't allow switching out the preferred style sheet for an alternate style sheet.
Creating an Alternate Style Sheet
Why would you want to create an alternate style sheet? There are a number of valid reasons, including showing off your ability to use CSS to reformat and restyle a website easily. A better reason might be to meet specific user needs. Web accessibility proponent Joe Clark has promoted the use of "zoom" layouts to accommodate users with visual disabilities; see [http://joeclark.org/access/webaccess/zoom/ http://joeclark.org/access/webaccess/zoom/] for a full explanation.
<div>By the Way
You'll learn more about CSS and web accessibility in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch22.html#ch22 Hour 22].</div>
A zoom layout is simply a style sheet that has been designed to show a page in a single column, with high contrast, scalable large fonts, and simple navigation controls. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21ex03 Listing 21.3] is an example of a zoom style sheet, written for the Dunbar Project website, which was introduced in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20], "Page Layout in CSS." The colors yellow, violet, and lime are used as brighter versions of the colors in the original design of the site.
Listing 21.3. A "Zoom" Style Sheet
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* dunbar-zoom-21.3.css */<br /><br />body { background-color: black; color: white;<br />font-size: 125%; line-height: 1.25;<br />font-family: Verdana, sans-serif;<br />letter-spacing: 1px; /* one pixel extra */<br />word-spacing: 1px;<br />margin: 0; padding: 0; }<br /><br />a:link { color: violet; }<br />a:visited { color: lime; }<br />a:link:hover { color: black; background-color: violet; }<br />a:visited:hover<br />{ color: black; background-color: lime; }<br /><br />#header, #content, #sidebar, #footer<br />{ padding: 1em; margin: 1em;<br />border: 0.15em solid white; }<br />#header { border-color: lime; }<br />#sidebar { border-color: lime; }<br />#footer { border-color: violet; }<br />#header h1 { color: yellow; }<br /><br />#sitenav ol { padding: 0; margin: 0;<br />display: inline; }<br />#sitenav li { display: inline; padding-left: 1em; }<br />#sidebar li { display: block; }<br />table { border-collapse: collapse;<br />border: 0.15em solid yellow;<br />margin: 1em; } table th, table td<br />{ vertical-align: top; text-align: left;<br />padding: 0.2em 1em 0.2em 0.2em;<br />font-size: 125%; line-height: 1.25;<br />border-bottom: 0.15em solid yellow; }<br />th { color: lime; }<br />.mailingaddress<br />{ margin: 0 2em; color: lime; }<br /></pre></div><br />
|}
As you can see, this does not use any CSS for layout, and it makes for a larger, bolder presentation with bright colors against a dark background. Such a style sheet is useful for certain users with specific visual impairments. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21fig02 Figure 21.2] shows this style sheet displayed in a web browser; compare with the figures from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch20.html#ch20 Hour 20] to see the difference that an alternate style sheet can make.
<div style="text-align: center;"> Figure 21.2. A zoomed version of a website. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/21fig02_alt.jpg [View full size image]]</div>[[Image:21fig02.jpg|500px]] </div>
Making Alternate Style Sheets Stick
There's one problem with alternate style sheetsthey don't last. You can choose an alternate style sheet in your browser, but the minute you go to another page, or even reload the current page, you're back to the preferred style sheet.
One way to get around this limitation is to use HTML cookies, and server-side or client-side programming. A cookie is small bit of information stored by a web browser, associated with a specific website. Programming languages on both the server side and client side can access these cookies. JavaScript is an example of a client-side programming language that can manipulate cookies; for more about JavaScript, see Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch01.html#ch01 Hour 1], "CSS and JavaScript."
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Create a Zoom Style Sheet
Creating an alternate style sheet for users who need high contrast is a good exercise in minimalism. Learn how to do it by following these steps:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Start with a website you've created, perhaps in the course of reading this book.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Keep your original style sheet handy for reference, but start over with an empty style sheet to begin creating your zoom style sheet.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Set a dark background and light text with a body rule. Add some extra line spacing, letter spacing, and word spacing, as these can help make the page more readable.<br /><br /></div>
|-
| >
| >
|-
| <div>'''4. '''</div>
| <div>Add additional styles, but keeping within the general philosophy of simple, bold design without columns. Which elements such as colors and fonts can you preserve from the original design? Try to work those in so that the zoom version seems like a sibling of the original, rather than an unrelated design.<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Link the style sheet with <code><link type="alternate stylesheet"></code> and be sure to add a <code>title</code> attribute as well. When choosing a <code>title</code>, web designer jargon like "zoom" may confuse users. How about simply "High Contrast"?<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>View your creation in Firefox or Opera, and use the browser's style sheet switcher to test your new creation!<br /><br /></div>
|}
|}
./ ADD NAME=CH21LEV1SEC4.HTML
Summary
When creating any web pages, whether using CSS or not, it's important to keep the needs of your users in mind. Providing them with an attractive website is not in conflict with giving them an easy-to-use site. In fact, the two approaches are both complementary and necessary for making a truly great site.
Testing plays a major role in any CSS design, and you can't rely on your own judgment when catching possible mistakes. Three important resources are other web developers who can give advice about your design efforts, users in informal tests who point out unexpected errors, and CSS validation services that check your syntax and warn of omissions.
Web development using CSS is a balancing act, and the factors you'll have to weigh include using CSS for layout, supporting older browsers, and accounting for browser quirks. Because each site is unique, there's no universal answer; you need to use your own judgment to figure out what works for you.
Organizing your style sheets in a sensible manner will make life easier for you and anyone else who has to read your style sheet. Use comments whenever you think of it, and group your styles together in natural groupings. You'll thank yourself later, when you need to maintain the style sheet.
Alternate style sheets can give your users a choice of appearance, enhancing the site's overall usability and meeting specific needs, such as zoom text. Cookies can be used with PHP, JavaScript, or other programming languages to make these choices persistent.
./ ADD NAME=CH21LEV1SEC5.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and activities to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa1q1a1 Q.]'''
| I've created a design that is 1024 pixels wide but my web stats tell me that 35% of my audience is still using 800x640 resolution. What should I do?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa1q1 A.]'''
| You have several options here. The first is to simply give up the idea of fixed-width designs and redesign a more fluid site. Site designs that are fluid can expand or shrink to fit the user's screen, but they offer you less control over the end result.
You could redesign the same look to fit in an 800-pixel-wide window. Fixed-width resolution designs look best when they're around 700 pixels or so across. You could also make your page adaptable with minimum and maximum widths so that the content scales down better on smaller resolutions.
Finally, you could use server-side or client-side programming, such as PHP or JavaScript, respectively, to provide alternative style sheets based on the browser's resolution. One style sheet could take advantage of the full-width displays and offer your original 1024-pixel design, whereas the fallback would be designed simply, with fluid layout.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa1q2a2 Q.]'''
| How can I learn more about web programming?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa1q2 A.]'''
| Client-side and server-side programming practices are beyond the scope of this introductory book on CSS, but the Sams Teach Yourself catalog offers a wide range of books on web programming topics, such as Sams Teach Yourself JavaScript in 24 Hours, 4th Edition and Sams Teach Yourself PHP in 24 Hours, 3rd Edition.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q1a1 1.]'''
| Which of these is not a benefit of a well-organized style sheet?
<div># <div>It's easier to make changes later on, after the design goes live.</div>
# <div>The download time is quicker if your style sheet is nicely formatted.</div>
# <div>You can spot problems such as unexpected cascading or inheritance consequences more easily when you've grouped your style rules sensibly.</div>
# <div>If you hand the website off to someone else, it's easier for them to understand how the site's style rules function.</div></div>
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q2a2 2.]'''
| What do you need for effective user testing?
<div># <div>Nothing. Just follow your own instincts because you're a user too. You'll find out after the site goes live whether it's working or not.</div>
# <div>Five people, five tasks, and five lattes; have your volunteers attempt to accomplish specific goals at the site, and thank them with a bribe of an appropriate beverage.</div>
# <div>A usability lab with one-way mirrors, video cameras, and a million-dollar budget; if you have less than that, don't bother.</div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q3a3 3.]'''
| Why would you want to use cookies and server-side or client-side programming with alternate style sheets?
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q1 1.]'''
| All the listed benefits are the result of having a well organized style sheet, with the exception of (b). A style sheet that compresses together all your CSS rules on one line or otherwise lacks white space may actually load fractionally quicker because it is a few bytes shorter in size than one with more readable formattingbut this benefit is very small compared to the advantages of using indentation in readability and maintenance.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q2 2.]'''
| The answer is (b), but the lattes are optional. I prefer a nice cold cherry cola myself.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch21qa2q3 3.]'''
| When a browser lets you pick an alternate style sheet, it doesn't save that choice, which means the next time you view the page, or another page on the site, you're back to the original. Using cookies lets the designer code client-side or server-side solutions that save a user's style sheet choice.
|}
Exercises
Here's a list of projects you can undertake to reinforce what you've learned this hour:
* Look at a website you've worked on, or one that you've used before, and design a hypothetical usability test. Create at least five questions that could be answered by using the site, in the form of tasks that would be performed by an average user to the site. Some should be difficult, and some can be easy.
* In fact, if you've got the time and the inclination, do an informal user test as described earlier this hour. The results are always educational, even if they just tell you that you're on the right track.
* Look at some of the style sheets you've worked on, and see whether you can reorganize them to be easier to understand. Comments, comments, comments!
./ ADD NAME=CH22.HTML
mgivkl04p7355m86kdfnnln4jmu94wp
User:Bartlett/23
2
2127
39233
5527
2026-04-13T06:03:25Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39233
wikitext
text/x-wiki
23.HTML
Hour 23. User Interface and Generated Content
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* How you can change the appearance of the mouse pointer
* Which properties allow you to create outlines, and how an outline is different than a border
* How to use the system colors and fonts in your design, and why you'd want to in the first place
* How you can add content to a page, before or after specific elements
* Which properties let you control the appearance of quotation marks
* How to use generated content to add shadows to text
* How counters can be used to number lists and other elements automatically
The properties defined in the Cascading Style Sheets specification allow you to do more than simply place and present content. Specific properties also enable you to shape the user's experience directly through interaction with the operating system and browser; other properties let you add to the content of the page to build an appropriate presentation for the user.
|}
./ ADD NAME=CH23LEV1SEC1.HTML
User Interface Properties
The user interface (UI) of a computer program is the part that interacts with the person using the program. This interaction includes not only the visual output, but also the method of providing information to the program via mouse, keyboard, or other input device.
When talking about web content, you're dealing with several layers of user interface. The operating systembe it various versions of Windows, Mac OS, or Linux running XWindowsprovides a basic graphical user interface (GUI) layer, which creates the windows, menus, and boxes onscreen. The browser's user interface is built upon the operating system's UI and generally is designed to mesh with the operating system while adding appropriate controls for web surfing. A third layer of user interface is created by the content itself; a web page can be thought of as a UI for the information contained in the markup.
CSS Level 2.1 has several user interface properties examined in this part of the hour. These are not enough to fully control all interactions with the user, but they do enable you to alter some UI components and use information provided by the operating system to style the page.
Changing the Cursor Appearance
A key part of the web-user experience is showing what part of the GUI is currently being pointed to by a pointing device, such as a mouse. The mouse cursor could be controlled by a mouse or by another tool, such as a track-ball, a joystick, or a virtual mouse via the keyboard, for people who can't operate a normal mouse. For users with severe disabilities, mouse control can be approximated by pointer wands attached to the head, or even by eye-tracking sensors.
A mouse cursor is applicable only in certain contexts; in print or Braille, for example, there is no mouse cursor. The mouse cursor is disabled or ignored by screen readers for blind users, and it's also inapplicable for kiosk systems with touch panels or for small devices with touch screens, such as Palm or Pocket PC organizers.
It's important to keep in mind that a mouse cursor is just an indicator of potential action and not necessarily a choice that's been acted on; the cursor's location corresponds to the <code>:hover</code> pseudo-class in CSS, not to the <code>:active</code> or <code>:focus</code> pseudo-classes.
The CSS property <code>cursor</code> can be used to change the appearance of the mouse cursor; this change occurs whenever the mouse cursor is over the part of the page display corresponding to the display rule's selector. Because <code>:hover</code> is implied, it's not necessary to use that pseudo-class with the selector.
A <code>cursor</code> rule is written like this:
<div><pre>selector { cursor: cursor-type; }
</pre></div>
The values that can be assigned to the <code>cursor</code> property are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table01 Table 23.1]. The default value is <code>auto</code>, and if this value is set on a containing box, it is inherited by that box's children elements.
{| cellspacing="0" cellpadding="5"|+ Table 23.1. Values for the <code>cursor</code> Property
|-
| Value
| Effect
|-
| <code>auto</code>
| Lets the browser decide the shape of the cursor
|-
| <code>crosshair</code>
| Displays a crosshair cursor
|-
| <code>default</code>
| Displays the default cursor (usually an arrow)
|-
| <code>e-resize</code>
| Indicates that the object can be resized eastward
|-
| <code>help</code>
| Displays a help-available cursor (usually a question mark)
|-
| <code>move</code>
| Indicates a movable object's cursor (usually crossed arrows)
|-
| <code>n-resize</code>
| Indicates that the object can be resized northward
|-
| <code>ne-resize</code>
| Indicates that the object can be diagonally resized to the northeast
|-
| <code>nw-resize</code>
| Indicates that the object can be diagonally resized to the northwest
|-
| <code>pointer</code>
| Displays a link pointer cursor (usually a pointing hand)
|-
| <code>s-resize</code>
| Indicates that the object can be resized southward
|-
| <code>se-resize</code>
| Indicates that the object can be diagonally resized to the southeast
|-
| <code>sw-resize</code>
| Indicates that the object can be diagonally resized to the southwest
|-
| <code>text</code>
| Displays a text editing cursor (usually an I-shaped bar)
|-
| <code>wait</code>
| Displays a waiting cursor (usually an hourglass)
|-
| <code>w-resize</code>
| Indicates the object can be resized westward
|-
| <code>url(</code><code>address</code><code>)</code>
| Displays a cursor image from a given URL
|-
| <code>inherit</code>
| Uses the cursor value for the containing box
|}
Many of the values listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table01 Table 23.1] refer to compass directions. These cursors are intended to be used with client-side programming techniques such as JavaScript and AJAX to mark objects that are resizable when clicked and dragged. The compass directions are a bit misleading "north" simply means up, toward the top of the screen; "west" means left; "south" means down; and "east" means to toward the right. Therefore, a cursor with the value of <code>se-resize</code> indicates the object is resizable in a lower-right direction.
The <code>url()</code> value is written in a special format; you can write as many <code>url()</code> values as you like, and the browser displays the first one it is able to load and understand. After the last <code>url()</code> value, you should provide a "generic" cursor value from the list in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table01 Table 23.1], in case the <code>url()</code> cursors can't be displayed; for example, if the file format isn't understood by the browser. The concept of a generic default is similar to that of the <code>font-family</code> property and so should be familiar to you.
Because there is not a universal format for cursor files, you should use multiple <code>url()</code> values to provide cursor images in several file formats. For example, give a version of the cursor in SVG, <code>.tiff</code>, <code>.cur</code>, and <code>.gif</code> formats, in addition to supplying a generic value. Cursor images should usually be smallno more than around 40 by 40 pixels, and usually around 16 by 16.
<div>Watch Out!
Only Internet Explorer 6 for Windows supports the <code>url()</code> method for specifying a cursor image, so be sure to provide a backup cursor type as you would for fonts. Opera has limited support for cursor changes, especially the <code>-resize</code> values. The <code>progress</code> cursor was introduced in CSS 2.1, and is currently supported only by Firefox.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex01 Listing 23.1] is an HTML file that demonstrates the various cursors available in CSS. You can test these out yourself and see how your operating system and browser display each cursor type.
Listing 23.1. The Different Styles of Cursors
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- cursors-23.1.html --><br /><html><br /><head><br /><title>Changing Cursors</title><br /><style type="text/css"><br />table { border-spacing: 0.5em;<br />width: 100%; margin: 0;<br />empty-cells: hide; }<br />#a td { width: 25%; } #b td { width: 33%; }<br />td { padding: 1.5em 1em; text-align: center;<br />font-family: Verdana, sans-serif;<br />border: 3px solid silver;<br />text-align: right; }<br />td:first-child { text-align: left; }<br /></style><br /></head><br /><body><br /><table id="a"><br /><tr><td style="cursor: crosshair;">crosshair</td><br /><td style="cursor: default;">default</td><br /><td style="cursor: help;">help</td><br /><td style="cursor: pointer;">pointer</td></tr><br /><tr><td style="cursor: progress;">progress</td><br /><td style="cursor: text;">text</td><br /><td style="cursor: wait;">wait</td><br /><td style="cursor:" url('k-small.cur'),<br />url('k-small.tiff'),<br />url('k-small.gif'),<br />auto;">url()</td></tr><br /></table><br /><table id="b"><br /><tr><td style="cursor: nw-resize;">nw-resize</td><br /><td style="cursor: n-resize;">n-resize</td><br /><td style="cursor: ne-resize;">ne-resize</td></tr><br /><tr><td style="cursor: w-resize;">w-resize</td><br /><td style="cursor: move;">move</p></td><br /><td style="cursor: e-resize;">e-resize</td></tr><br /><tr><td style="cursor: sw-resize;">sw-resize</td><br /><td style="cursor: s-resize;">s-resize</td><br /><td style="cursor: se-resize;">se-resize</td></tr><br /></table><br /></body><br /></pre></div><br />
|}
The screenshot in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig01 Figure 23.1] is actually a composite of several screenshots; obviously, only one cursor can usually be displayed at a time, so I've combined images together to show you how one browser displays these cursors.
<div style="text-align: center;"> Figure 23.1. A variety of cursors on display. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/23fig01_alt.jpg [View full size image]]</div>[[Image:23fig01.jpg|500px]] </div>
<div>Did you Know?
Now you know how to change the cursor, but why would you want to? In most cases, the web browser automatically sets the style of the cursor to something sensible, which actually serves as a useful cue to the user. A <code>pointer</code> finger cursor, for example, lets users know that they are over a link. In general, you should change the cursor appearance only if you have a very good reason. For example, if you're using Asynchronous JavaScript and XML (AJAX) client-side programming to load information dynamically, you can change the cursor to <code>progress</code> or <code>wait</code> so the user is aware of the change. If you're using graphics for cursors, don't just set one for the whole page; create different graphics for links and input fields, and write appropriate rules to call them. Otherwise, your users will be confused when the cursor doesn't change over a text field or a hyperlink.</div>
Creating Outlines
An outline is a visual line surrounding an element. This sounds similar to a border, doesn't it? Unlike a border, an outline doesn't actually take up any space in the box model. Instead, it's laid over other elements. The outline is placed just outside of the border, and thus it will be displayed over the margin or even over other content if the margin is small and the outline is wide.
The appearance of the outline is set with the <code>outline-width</code>, <code>outline-style</code>, and <code>outline-color</code> properties, or the <code>outline</code> shorthand property that sets them all at once. The <code>outline-width</code> property can take the same types of values as the <code>border-width</code> property; the <code>outline-style</code> can accept <code>border-style</code> properties. Unlike the border properties (which are covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch16.html#ch16 Hour 16], "Borders and Boxes"), there are not outline properties for each side of a box; the outline must be consistently the same color, width, and style on all sides.
The <code>outline-color</code> value can be any normal color value, or <code>invert</code>, which means the outline is displayed in the opposite colors of the margins (or other content) over which it lies. Unlike borders, there is only one outline; you can't set separate outlines for different sides of the outlined element.
An outline is most useful for indicating focus or hover, although you can use it without the <code>:focus</code> or <code>:hover</code> pseudo-classes to simply draw an outline around anything. For example:
<div><pre>a:focus, a:hover { outline-width: medium;
outline-style: dotted;
outline-color: invert; }
h2 { outline: green 1px solid; }
</pre></div>
Outlines can be very useful if you are debugging your style sheets. Because an outline doesn't affect the width of the box model, this means that your outlines don't change the way the page is laid out. You can use outlines to highlight specific boxes and watch how they react with each other.
<div>Watch Out!
Internet Explorer (as of version 6.0) doesn't support the <code>outline-width</code>, <code>outline-style</code>, <code>outline-color</code>, or <code>outline</code> properties. Don't rely on your outlines being visible on someone else's browserbut if you're using Firefox, Safari, or Opera, you can still use outlines for troubleshooting.</div>
Using the System Colors and Fonts
The CSS language enables you to access certain qualities of the system or browser user interface and use these for color or font values. You can do this by using special keywords that correspond to the current system settings.
The system color keywords can be used with any CSS property that can be set to a specific color value<code>color</code>, <code>background-color</code>, <code>border-color</code>, and so on. These are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table02 Table 23.2]. These keywords are traditionally written in mixed case, with capital letters at the beginning of words for greater legibility. However, CSS is not case sensitive for color values, so if you write <code>activeborder</code> or <code>ACTIVEBORDER</code>, it means the same thing as <code>ActiveBorder</code>.
{| cellspacing="0" cellpadding="5"|+ Table 23.2. System Color Keywords
|-
| Value
| Effect
|-
| <code>ActiveBorder</code>
| The border color around the active window
|-
| <code>ActiveCaption</code>
| The background color of the caption on the active window
|-
| <code>AppWorkspace</code>
| The background color within the application's main window
|-
| <code>Background</code>
| The background color of the desktop
|-
| <code>ButtonFace</code>
| The background color of a three-dimensional button
|-
| <code>ButtonHighlight</code>
| The border color for the dark edge of a three-dimensional button
|-
| <code>ButtonShadow</code>
| The shadow color of a three-dimensional button
|-
| <code>ButtonText</code>
| The text color for a three-dimensional button
|-
| <code>CaptionText</code>
| The text color in a caption
|-
| <code>GrayText</code>
| The text color for disabled options (grayed out)
|-
| <code>Highlight</code>
| The background color for selected items
|-
| <code>HighlightText</code>
| The text color for selected items
|-
| <code>InactiveBorder</code>
| The border color around an inactive window
|-
| <code>InactiveCaption</code>
| The background color of the caption on an inactive window
|-
| <code>InactiveCaptionText</code>
| The text color of the caption on an inactive window
|-
| <code>InfoBackground</code>
| The background color for tooltips
|-
| <code>InfoText</code>
| The text color for tooltips
|-
| <code>Menu</code>
| The background color for menu items
|-
| <code>MenuText</code>
| The text color for menu items
|-
| <code>Scrollbar</code>
| The color of the scrollbar
|-
| <code>ThreeDDarkShadow</code>
| The dark shadow for a three-dimensional element
|-
| <code>THReeDFace</code>
| The background color for a three-dimensional element
|-
| <code>THReeDHighlight</code>
| The highlight color for a three-dimensional element
|-
| <code>ThreeDLightShadow</code>
| The border color for the light edge of a three-dimensional element
|-
| <code>ThreeDShadow</code>
| The shadow color for a three-dimensional element
|-
| <code>Window</code>
| The background color of a window
|-
| <code>WindowFrame</code>
| The border color of the frame around a window
|-
| <code>WindowText</code>
| The text color within a window
|}
For each of the values in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table02 Table 23.2], a descriptive adjective such as highlight, border, background, or text is given before the word color. These describe how the colors are used within the system user interface, but you don't have to use them for only those purposes in your style sheet. For example, you could set the text <code>color</code> to <code>Window</code>, and the <code>background-color</code> to <code>WindowText</code>; the AppWorkspace value could be used to set a box's <code>border</code>. Here are examples of how to use these values:
<div><pre>.showthis { color: window;
background-color: windowText;
border: 2px solid AppWorkspace; }
</pre></div>
You can also use the system font settings for various types of text within your style sheet. You do so by setting the font shorthand property to one of the system values shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table03 Table 23.3]. For example, to make a <code><div></code> use the font qualities for a system message box, use the following:
{| cellspacing="0" cellpadding="5"|+ Table 23.3. System Values for the <code>font</code> Property
|-
| Value
| Effect
|-
| <code>caption</code>
| Uses the same font values as system captions
|-
| <code>icon</code>
| Uses the same font values as system icons
|-
| <code>menu</code>
| Uses the same font values as system menus
|-
| <code>message-box</code>
| Uses the same font values as system message boxes
|-
| <code>small-caption</code>
| Uses the same font values as small system captions
|-
| <code>status-bar</code>
| Uses the same font values as the status bar
|}
<div><pre>div { font: message-box; }
</pre></div>
Each use of font in this manner sets the <code>font-size</code>, <code>font-style</code>, <code>font-weight</code>, <code>font-variant</code>, and <code>font-family</code> to the same values as the specified kind of system text. Subsequent rules can change those values, as shown here:
<div><pre>div { font: message-box;
font-weight: bold;
font-size: larger;
color: window;
background-color: windowText;
border: 2px solid AppWorkspace; }
</pre></div>
Why would you want to use system colors and fonts? Usually you wouldn't, actually. Websites have good reason to express their own individuality and style, and utilizing the user's system appearance doesn't mesh well with that. However, there are some cases, such as alert boxes, where you may very well want to mimic the effects of an operating system prompt.
There is a potential accessibility benefit: In general, you can be sure that system colors will be usable by someone with visual impairments because otherwise she couldn't operate her computer at all. Most users with special needs set their computers to high contrast, large fonts, and any other required properties.
However, the accessibility benefit of system styles is small compared with the negative effects of "sameness" and bland design; even users with poor vision can benefit from an attractive website design. User style sheets and alternate style sheets provide better accessibility options for all users in the long run.
./ ADD NAME=CH23LEV1SEC2.HTML
=== Creating Content ===
In CSS terminology, generated content consists of text or images that aren't present in the HTML markup but are added through CSS rules. The ability to generate content allows for even more flexibility in designing style sheets and alternate style sheets that effectively convey the information on the page to the user.
In overview, generating content depends on using the <code>:before</code> and <code>:after</code> pseudo-classes as selectors for rules with <code>content</code> property declarations. Text, attribute values, images, quotation marks, and numbered counters can all be added to HTML using CSS content generation.
<div>Watch Out!
Because of browser deficiencies, users who have turned off style sheets, or devices that can't display CSS, generated content is not always going to be available, so you shouldn't rely on generated content unless you know the browser on the other end can display it. Generated content is therefore only safe when you can be sure that it will actually be displayed to the end userfor example, if you are serving content to a specific browser. In some cases, you can use generated content to enhance the presentation without being dependent upon it as the only way to convey important information. In this hour, you will see an example of using generated content to create a specific text effect that enhances the web page for display in browsers that support CSS, but doesn't leave out users whose browsers don't produce generated content.</div>
The <code>:before</code> and <code>:after</code> Pseudo-Classes
To generate content, you must use the <code>:before</code> and <code>:after</code> pseudo-classes. These pseudo-classes define the point where you place additional material. Content can be added at the beginning or the end of an element.
To add content at the beginning of an element, you would write a rule like this:
<div><pre>element:before { declarations; }
</pre></div>
To insert the content after the element, the rule looks like this:
<div><pre>element:after { declarations; }
</pre></div>
You can combine this with any other CSS selectors, such as <code>class</code>, <code>id</code>, attribute, relationship, or pseudo-class selectors. You can't write a single rule that has both <code>:before</code> and <code>:after</code> selectors, but you can write one rule putting content before the element and another adding content after it.
The <code>content</code> Property
The material generated at the insertion point (either before or after the selector) is defined by the content property. This CSS property can be used only within a rule with a <code>:before</code> or <code>:after</code> pseudo-class selector. The values for <code>content</code> are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23table04 Table 23.4].
{| cellspacing="0" cellpadding="5"|+ Table 23.4. Values for the <code>content</code> Property
|-
| Value
| Effect
|-
| "<code>quoted-text</code>"
| Inserts the specified text
|-
| <code>attr(</code><code>attribute</code><code>)</code>
| Inserts the value of the specified attribute
|-
| <code>close-quote</code>
| Inserts an appropriate closing quote mark
|-
| <code>counter(</code><code>name</code><code>)</code>
| Inserts a counter's value
|-
| <code>counter(</code><code>name</code>, <code>marker-style</code><code>)</code>
| Inserts a counter's value
|-
| <code>counters(</code><code>name</code>, <code>string</code><code>)</code>
| Inserts a counter's value and a string
|-
| <code>counters(</code><code>name</code>, <code>string</code>, <code>marker-style</code><code>)</code>
| Inserts a counter's value and a string no-close-quote Suppresses the printing of a closing quote mark
|-
| <code>no-open-quote</code>
| Suppresses the printing of an opening quote mark
|-
| <code>open-quote</code>
| Inserts an appropriate opening quote mark
|-
| <code>url(</code><code>address</code><code>)</code>
| Inserts the contents of the specified URL
|}
The <code>content</code> property allows for multiple values, separated by spaces. Here is an example of a complex <code>content</code> rule:
<div><pre>.note:before { content: url('note.gif') "Note "
counter(notes) ": (" attr(title) ")"; }
</pre></div>
The content inserted consists of an image, quoted text, a counter reference, another bit of quoted text, an attribute value, and a final snippet of quoted text.
The specified content is added at the designated insertion point and becomes a virtual child element. Although the generated content inherits all appropriate properties from the element into which it was inserted, it can also be styled separately, as well.
<div>Watch Out!
Internet Explorer versions 6.0 and earlier don't display generated content. As suggested before, you should use generated content only if you can be certain which browser will be used or if you are using the generated content only to enhance, rather than to provide the full presentation.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex02 Listing 23.2] and is a brief (and deliberately incomplete) list of books by J.R.R. Tolkien, which will be used to demonstrate how content generation can be used.
Listing 23.2. A Simple HTML File Listing Some Works of Tolkien
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- generated-23.2.html --><br /><html><br /><head><br /><title>Author Data: J.R.R. Tolkien</title><br /><style type="text/css"><br />/* Insert style rules here */<br /></style><br /></head><br /><body><br /><h3>J.R.R. Tolkien</h3><br /><ul id="works"><br /><li class="book">The Hobbit</div><br /><li class="series" ><br /><ul title="Lord of the Rings"><br /><li class="book">The Fellowship of the Ring</li><br /><li class="book">The Two Towers</li><br /><li class="book">Return of the King</li><br /></ul><br /></li><br /><li class="book">The Silmarillion</li><br /></ul><br /></body><br /></html><br /></pre></div><br />
|}
The HTML file in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex02 Listing 23.2] defines a simple structure wherein book titles are identified by <code><li></code> list items with the book class, and related books are grouped within titled <code><ul></code> tags. There is no styling information provided, so the list appears plain and straightforward, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig02 Figure 23.2]. Note that the series title Lord of the Rings isn't shown because it is an attribute value and not text content.
<div style="text-align: center;"> Figure 23.2. No styles applied to the Tolkien book list.
[[Image:23fig02.jpg|500px]]
</div>
Adding Text and Images
You can insert text into a page by giving a quoted text value to the <code>content</code> property. The quotes around the value can be either double quotes (<code>"</code>) or single quotes (<code>'</code>); they have to match. You can use double quotes to surround single quotes (or apostrophes), or single quotes to surround double quotes. For example:
<div><pre>h1:before { content: "Kynn's Headline: "; }
h2:before, h2:after { content: '"'; }
</pre></div>
You can also insert text by using an attribute's value via the <code>attr()</code> function, which inserts the value of a specific attribute on the element. Here is an example combining quoted text with an attribute value to make the alternative text of an image visible, which is useful for testing your web pages:
<div><pre>img:after { content: " [ALT: " attr(alt) "]"; }
</pre></div>
If you want to insert an image before or after an element, you give a <code>url()</code> value. This is similar to providing a bullet image with the <code>list-style-image</code> property, although it can be done with any element.
<div>Watch Out!
Opera doesn't display images inserted with the <code>url()</code> function, although it displays generated text and attribute values just fine.</div>
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex03 Listing 23.3] is a style sheet that adds explanatory text, as well as a small graphic, to the HTML file's presentation. The most important rules here are the <code>content</code> rules, listed first after each selector.
Listing 23.3. Style Sheet Generating Text for Book List
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* generated-23.3.css */<br /><br />body { font-family: Verdana, sans-serif; }<br />h3:before<br />{ content: "BookBase: ";<br />font-size: small;<br />font-family: cursive, sans-serif;<br />color: white; background-color: black; }<br />h3:after<br />{ content: " (author index)";<br />font-weight: normal; font-size: small; }<br />.series ul:before<br />{ content: "Series: " attr(title)<br />" " url('series_l.gif');<br />font-weight: bold; }<br />.book:after<br />{ content: " " url('book_l.gif'); }<br />.series .book:after<br />{ content: " "url('bookinseries_l.gif'); }<br />li { list-style-type: square; }<br />li.series { list-style-type: none; }<br />.series ul li:first-child { margin-top: 0.5em; }<br />.series ul { margin-bottom: 0.5em; }<br />.series li { margin-left: 1em; }<br /></pre></div><br />
|}
Not all browsers support generated content, but Firefox, Opera, and Safari do. The results of applying the style sheet to the Tolkien listing are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig03 Figure 23.3]. You'll notice that separate books are followed by one icon, the name of a series with another icon, and books within a series by a third icon. The word series has also been added to further identify books within a particular series.
<div style="text-align: center;"> Figure 23.3. Firefox generating content for Tolkien list. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/23fig03_alt.jpg [View full size image]]</div>[[Image:23fig03.jpg|500px]] </div>
Generating Quotation Marks
You can use CSS to add quotation marks to your web page. This is most useful when you're dealing with multiple languages on the same site, where different languages have different quotation symbols. It's also applicable if you use the HTML element <code><q></code> to mark up your quotations.
To add quotations, first you must define which quotation marks should be used by using the <code>quotes</code> property. The values for <code>quotes</code> are pairs of symbols enclosed in double quotes themselves (or single quotes if they contain double-quote characters). The first pair is considered the outer pair of quotation symbols; inner quotes use the next pair in, and so on. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex04 Listing 23.4] gives an example, using doubled left-ticks and right-ticks for some quotes and square brackets for others. Your values for <code>quotes</code> don't have to be actual quotation marks; you can use any symbols or text.
Listing 23.4. Style Sheet That Adds Quotes to the Book List
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* generated-23.4.css */<br /><br />/* Set values for quotes */<br />ul { quotes: "[" "]"; }<br />ul li { quotes: "`" "'"; }<br />.series ul:before<br />{ content: "Series: " open-quote attr(title)<br />close-quote " " url('series_l.gif');<br />font-weight: bold; }<br />.book:before<br />{ content: open-quote; }<br />.book:after<br />{ content: close-quote " " url('book_l.gif'); }<br />.series .book:after<br />{ content: close-quote " " url('bookinseries_l.gif'); }<br /></pre></div><br />
|}
As shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex04 Listing 23.4], the <code>open-quote</code> or <code>close-quote</code> values for <code>content</code> designate the types of the quote marks to be generated. You can see the effect of these rules in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig04 Figure 23.4], which applies the updated style sheet to the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex02 Listing 23.2].
<div style="text-align: center;"> Figure 23.4. Quote marks inserted as generated content.
[[Image:23fig04.jpg|500px]]
</div>
Counters and Numbering
Generated content can also consist of counter values. A CSS counter is like a very simple variable from a programming language. Each counter is identified by a name and holds a numeric integer value, such as 1, 2, 335, or -5. The counter can be set to a specific value, increased or decreased by a certain amount, or displayed as part of a <code>content</code> rule.
You set a counter to a specific value by using the <code>counter-reset</code> property; whenever a CSS rule containing <code>counter-reset</code> is applied to a selector, the counter is reset to the specified value, or to zero if no value is given. The name of the counter must be specified in the <code>counter-reset</code> declaration. The counter increases whenever a <code>counter-increment</code> property is applied that designates a counter of the same name. The general syntax for <code>counter-reset</code> and <code>counter-increment</code> looks like this:
<div><pre>selector { counter-reset: name amount name amount ... ; }
selector { counter-increment: name amount name amount ...; }
</pre></div>
The <code>amount</code> can be omitted; for <code>counter-reset</code> this resets the counter to zero, and for <code>counter-increment</code> this increases the counter by one. You can reset or increment multiple counters by giving <code>name</code>-<code>amount</code> pairs (or just multiple counter names if you want to use the default <code>amount</code> values).
To display the counter value, use the function <code>counter()</code> or <code>counters()</code> within a content declaration. Each counter has a scope over which the counter applies, which consists of the element in which it was declared and its children; you can have multiple counters with the same name. The value of the current counter with a given <code>name</code> is specified by <code>counter</code>(<code>name</code>); the values of all counters with that <code>name</code> within the scope are given by <code>counters</code>(<code>name</code>, <code>delimiter</code>). The <code>delimiter</code> option specifies a string to be displayed between values. This lets you create nested lists with proper numbering.
An additional option can be supplied to the <code>counter()</code> and <code>counters()</code> functions, which selects a list style to be applied to the display of the counter. This can be any <code>list-style-type</code> value as covered in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch12.html#ch12 Hour 12], "Styling Links."
An example of counters in a style sheet can be seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex05 Listing 23.5]. This example counts books within a series and the total numbers of books from the HTML Tolkien book list.
Listing 23.5. Style Sheet for Adding Counters to the Book List
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* generated-23.5.css */<br /><br />#works { counter-reset: Total; }<br />.series { counter-reset: BooksInSeries; }<br />.book { counter-increment: BooksInSeries Total; }<br />.series:after { content: "Books in Series: "<br />counter(BooksInSeries, decimal);<br />margin-left: 2em;<br />text-decoration: overline;<br />display: block; }<br />#works:after { content: "Total books in index: "<br />counter(Total);<br />margin-top: 1em; display: block;<br />font-weight: bold; }<br /></pre></div><br />
|}
Some browsers do not support counters; Opera and Firefox display counters, whereas Safari and Internet Explorer (as of version 6.0) do not. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig05 Figure 23.5] shows how Firefox displays the HTML file from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex02 Listing 23.2] with the styles from [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex05 Listing 23.5] sheet applied.
<div style="text-align: center;"> Figure 23.5. Firefox displays counts for Tolkien's books.
[[Image:23fig05.jpg|500px]]
</div>
Generating Text Shadows
The original CSS Level 2 specification included a property, <code>text-shadow</code>, that allowed drop shadows to be generated around text, giving a three-dimensional look. Only one browser, Safari, supports <code>text-shadow</code>, and so the property was removed in CSS 2.1.
However, you can use generated content to create your own text shadows around certain text elements. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23ex06 Listing 23.6] has the code that creates text shadows; the explanation follows after.
Listing 23.6. Adding Shadows to Text
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre><!-- text-shadow-23.6.html --><br /><html><br /><head><br /><title>Text Shadows</title><br /><style type="text/css"><br />body {font-family: Verdana, sans-serif; }<br /><br />.shadow:before { color: gray; }<br /><br />.shadow[title] {<br />line-height: 2em;<br />margin: 0; }<br /><br />.shadow[title]:before {<br />display: block;<br />margin: 0 0 -2.10em 0.20em;<br />content: attr(title); }<br /><br />h1.shadow { color: white; }<br />h1.shadow:before { color: black; }<br /></style><br /></head><br /><body style="text-align: center;" ><br /><h1 class="shadow" title="Announcing..."><br />Announcing...</h1><br /><h2 class="shadow"<br />title="Teach Yourself CSS in 24 Hours!"><br />Teach Yourself CSS in 24 Hours!</h2><br /><p>Want to learn Cascading Style Sheets the easy way?<br />Read this book! It's fun! Give it a try!</p><br /><p class="shadow" title="Tell all your friends!"><br />Tell all your friends!</p><br /></body><br /></html><br /></pre></div><br />
|}
So what's going on here? Look carefully at the HTMLeach element that is to receive a text shadow has a <code>class</code> of <code>shadow</code>, as well as a <code>title</code> attribute that repeats the text of that element. This is then used in the <code>content</code> rule for the <code>.shadow[title]:before</code> selector in an <code>attr()</code> rule. That produces a copy of the text to be shadowed. Thanks to the <code>.shadow:before</code> rule, the color of this text will be <code>gray</code>.
Because the <code>.shadow[title]:before</code> rule sets the <code>display</code> to <code>block</code>, we end up with a repeat of the text on two linesone line in <code>black</code> (default) text, one in <code>gray</code> text. The <code>margin</code> rule of the <code>.shadow[title]:before</code> selector moves the <code>gray</code> text behind the <code>black</code> text, and the <code>line-height</code> rule on the <code>.shadow[title]</code> text is there to ensure there's enough room to do that.
[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig06 Figure 23.6] shows exactly how these rules come together and display a text shadow in a browser.
<div style="text-align: center;"> Figure 23.6. Shadows behind text, thanks to generated content.
[[Image:23fig06.jpg|500px]]
</div>
You can tweak the parameters here by changing the values for the margin rule; the difference from <code>2.0em</code> is the vertical offset for the text shadow, and the difference from <code>0.0em</code> is the horizontal offset. In this example, the final two rules set up a different color schemewhite on blackfor <code><h1></code> text shadows, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23fig06 Figure 23.6].
This method for text shadows works well as long as your text is all on one line. If it wraps around, everything is thrown off. You can insert a <code>white-space: nowrap</code> rule to prevent text wrapping.
If this method of creating text shadows seems arcane, don't feel too badit is quite complicated, and is an example of the type of hoops that web designers are often willing to jump through to gain a specific effect. You'll learn more about the types of accommodations necessary for browser quirks and bugs in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html#ch24 Hour 24], "Troubleshooting and Browser Hacks."
./ ADD NAME=CH23LEV1SEC3.HTML
Summary
Cascading Style Sheets enable your web designs to incorporate elements of the user interface into the presentation. Through CSS, you can change the cursor with the cursor property or draw highlights around certain items with the outline properties.
Colors and fonts can be tuned to fit the operating system or the user's browser preferences if you employ special keywords for the <code>color, background-color, border</code>, and <code>font</code> properties.
Additional information can be added to the HTML by style sheets using content generation. Quoted text, attribute values, images, quotation marks, and counters can be included via the <code>content</code> property. The <code>quotes</code> property specifies the styles of quotes to be used, and the <code>counter-reset</code> and <code>counter-increment</code> properties manage the values of the counters.
As with many advanced CSS features, content generation may be supported sporadically by the browsers. If the primary content of the site is supported or explained only by generated content, users without access to the style sheet are left out, so care should be taken whenever using these techniques.
./ ADD NAME=CH23LEV1SEC4.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and exercises to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa1q1a1 Q.]'''
| Can I use content generation to insert HTML tags before and after an element? That would be really cool.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa1q1 A.]'''
| It would indeed be cool, but the answer is no, you can't. Quoted text is inserted directly as text, not as markup, which means that if you wrap HTML tags around something, they won't be interpreted by the browser. Instead you'll just see those tags, in angle brackets, when viewing the page.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa1q2a2 Q.]'''
| Generating content doesn't sound reliable. It would be easier to just add the content to the HTML, and that works in Internet Explorer and every other browser! Why would I ever use generated content?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa1q2 A.]'''
| Content generation is useful and powerful, but as you say, it can be unreliable. In general, you're right; if you need to include some text in your output, you should put it in the HTML. There are a few cases where generated content is particularly useful, though, including sites where you may not have access to the content but can style it; alternate style sheets for specific presentations, such as a screen reader style sheet for visually impaired users; and XML files that don't inherently contain explanatory text. For more on XML and generated markup, see Bonus Web [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch02.html#ch02 Hour 2], "CSS and XML" (available on this book's website).
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q1a1 1.]'''
| Which of these options is not a valid declaration for the cursor property?
<div># <div><code>cursor: hourglass;</code></div>
# <div><code>cursor: ne-resize;</code></div>
# <div><code>cursor: url('target.cur'), crosshair;</code></div>
# <div><code>cursor: text;</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q2a2 2.]'''
| Your HTML contains <code><a></code> links of the class <code>button3d</code> that you want to style to look like three-dimensional buttons. How do you make members of this class appear as such, using the system <code>color</code> and <code>font</code> properties?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q3a3 3.]'''
| What does each of the following content rules accomplish?
<div># <div><code>a[href]:after { content: "[LINK: " attr(href) "]"; }</code></div>
# <div><code>h1:before { "#" counter(item); counter-increment: item; }</code></div>
# <div><code>blockquote p:before { content: open-quote; }</code></div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q1 1.]'''
| (a). <code>hourglass</code> is not a proper value for <code>cursor</code>; to display an hourglass or timer cursor, use the value <code>wait</code>.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q2 2.]'''
| Here is one way to write the appropriate style rules:
<div><pre>a.button3d:link {<br />display: block;<br />font: menu; color: ButtonText;<br />background-color: ButtonFace;<br />border-width: medium; border-type: outset;<br />border-color: ButtonHighlight; }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch23qa2q3 3.]'''
| The rules generate the following types of content:
<div># <div>All links are followed by an indication of their link target. This is a very handy rule if you are printing out documents.</div>
# <div>This numbers all <code><h1></code> elements.</div>
# <div>This starts all paragraphs within a <code><blockquote></code> with the opening quote character.</div></div>
|}
Exercises
Here are some projects that will help you get practice using the properties from this hour:
<div># <div>Experiment with changing the cursors on your website. Does it make it easier to use or harder to use if the cursors aren't set by the browser?</div>
# <div>Using the <code>:active</code> pseudo-class, extend the style rules from Quiz question 2 to create three-dimensional buttons that appear to depress when clicked.</div>
# <div>Use content generation to add notes to a web page explaining the function of each element. Style these notes in a different color or with a border around them.</div></div>
fsxayhghaeeqmcpikfpl8matsp0p936
User:Bartlett/22
2
2128
39232
5528
2026-04-13T06:03:24Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39232
wikitext
text/x-wiki
./ ADD NAME=CH22.HTML
Hour 22. Accessibility and Print Media
{| cellspacing="0" cellpadding="5" border="1"
|-
| What You'll Learn in This Hour:
* What hurdles people with disabilities face and how your use of CSS design can increase their accessibility to the Web
* Which standards relating to accessibility the W3C and the U.S. government have published
* How Aural Cascading Style Sheets are used and which browsers for visually impaired users support them
* How to specify rules for specific media types
* Which media types are supported by CSS and when they are used
* What kinds of things to consider when making a print style sheet
The promise inherent in the name "World Wide Web" is an information network that can be used by everyone across the entire world. To a large degree this promise has been fulfilled, although there are still many groups of users whose needs aren't adequately met. To address these needs, the Cascading Style Sheets recommendations included specific support for accessibility by people with disabilities and for internationalization and non-English languages.
Related to universal accessibility is the concept of alternate media types. Most style sheets are written for onscreen display in a web browser. However, CSS isn't restricted only to screen display; style sheets can be applied to printed versions of a page as well as to other media types.
|}
./ ADD NAME=CH22LEV1SEC1.HTML
=== What Is Accessibility? ===
When we talk about web accessibility, we're talking about the interaction between content and presentation and about ensuring that people who may have disabilities can use the result of that interaction. The content is the information you want to convey to your audience; it's not even necessarily the HTML code, but rather the information embodied by the HTML codeor by a Flash animation, GIF image, or multimedia movie. The presentation is the specific way you choose to express that information to your audience.
A basic principle of accessibility is that these two types of information, the content and the presentation, should be separated from each other. This allows for alternate versions of the presentation to be constructed, conveying the information in a way that the user can perceive it. If the content cannot be extracted from the presentation easily, an alternate version can be provided.
The classic example of this is the <code>alt</code> attribute on the HTML <code><img></code> tag (and the <code><area></code> tag as well). The content of a visual image is obviously going to be inaccessible to user who is blind; she simply can't see it. However, if a text equivalent of the image is supplied (by the <code>alt</code> attribute), her computer has information about what the image means, and it can provide that to the userfor example, by reading it out loud to her.
Users with disabilities often use assistive technology (AT) to enable access. Assistive technology is a broad category that not only includes Braille terminals and screen readers for blind users, but also includes magnification devices, voice recognition software, specialized input devices for those who can't type or use a mouse, and other hardware and software solutions.
Although assistive technology can solve many problems for users with special needs, it can't solve them all because it can work only with the information that is available. For example, if there is no <code>alt</code> attribute for an image, the assistive technology has no clue what to tell the user about the image's function and purpose. AT alone can't enable access; it requires cooperation from the web developer as well.
How People with Disabilities Use the Web
Most of the time when you hear about web accessibility, the focus is on blind and visually impaired users. The Web is commonly thought of as a visual medium; however, it's more accurate to say that it's an information medium, and the visual representation of information is simply the most common. A mistaken insistence that the Web is meant to be only visual can lead many web developers to inadvertently create websites that are inaccessible to users who can't see well.
A user who is blind commonly uses a screen reader, a software program that uses a synthetic voice to read the output of other programs. Examples of common screen readers include JAWS for Windows ([http://www.freedomscientific.com/ http://www.freedomscientific.com/]) and WindowsEyes ([http://www.gwmicro.com/ http://www.gwmicro.com/]). Screen readers depend on a web browser to retrieve and process web pages; for example, JAWS is integrated with Internet Explorer for web display.
Another option is a speaking web browser, which is essentially a browser with a specialized screen reader built into it; examples are IBM's Home Page Reader ([http://www.ibm.com/able/ http://www.ibm.com/able/]) and EmacSpeak for Linux/Unix ([http://emacspeak.sourceforge.net/ http://emacspeak.sourceforge.net/]). Also in use are Braille terminals, which display around 40 characters at a time using raised dots in a row.
All these access solutions for blind users dramatically change the experience of using the typical website. Rather than experience the content as a two-dimensional visual display, a user hears (or feels) the content in a sequential, linear order. On most page designs this means having to wade through the navigation options and banner ads before finally reaching the main content of the page.
Users who can see, but not necessarily see well, often employ other solutions to access web content. For some, screen magnification software, which allows sections of the screen to be increased to many times their original size, may be necessary for ease of reading. A user with less severe requirements may simply increase his default font size to allow for comfortable reading.
Color blindness may cause someone to be unable to distinguish content within color graphics or to have difficulty discerning text against the background colors. The use of color as the only means of conveying information can restrict access by users who are color-blind or who can't see at all.
Compared with users with visual disabilities, deaf or hearing-impaired users are relatively fortunate when using the Web because most sites don't make heavy use of sound. However, those users can miss sound cues, audio files, and the sound tracks of multimedia presentations.
Users who are unable to use a keyboard or a mouse often employ creative means to provide equivalent input to their computers. For example, a quadriplegic user who is unable to use his arms or hands may move the mouse pointer by moving a pointer wand worn on his head.
One of the broadest groups of users with disabilities is also the least understood when it comes to web accessibilityusers with cognitive disabilities. This wide category includes everything from relatively simple dyslexia to extreme mental retardation. Many individuals with varying cognitive impairments regularly use the Web as a primary information source, and they should not be discounted as a potential audience for your site simply because of their disabilities.
CSS Enables Access
Because the W3C created the CSS specifications with the needs of disabled users in mind, Cascading Style Sheets, if applied correctly, have great potential to meet the needs of those users. The primary benefit of using CSS is the separation of presentation from content; using CSS with HTML (especially Strict HTML) makes it clear which code is meant for presentational effects and which is the structured information of the page.
The CSS language has many features specifically intended to benefit users with visual disabilities, mainly because style sheet properties primarily define visual appearance. Media-specific alternate style sheets and rules can be created for screen readers, Braille terminals, and Braille printers. Aural CSS properties, described later in this hour, give control over the pitch, frequency, and even apparent location of synthesized speech.
Using relative measurements, such as ems instead of absolute font sizes, allows your style sheets to adapt to user preferences, either in browser settings or in a user style sheet. This lets users with special needs for font or color choices continue to access your site even if the styles you've set are not sufficient for their needs.
Style sheets do little to benefit deaf, hard of hearing, physically restricted, or cognitively impaired users, although a CSS-styled website based on sound usability and design principles will provide benefits for users both with and without these disabilities. Many cognitively disabled users specifically benefit from nontextual information cues, such as color, layout, and graphics.
Accessibility Standards and CSS
To fully test your CSS designs on all possible web browsers and AT devices, you'd have to spend a fortune; you already know how hard it can be to fully test a CSS design on mainstream browsers, and adding assistive technology software and hardware to the mix makes the task nearly impossible. So what is a web developer to do?
The solution is for those with expertise in assistive technologies to gather information on accessibility and create a set of recommendations for web developers to follow. By learning these standards, a web developer won't have to spend time researching every possible access method, but can instead be reasonably sure that a page created according to those principles will be accessible to a broad audience of users.
W3C's Web Content Accessibility Guidelines
The World Wide Web Consortium, in addition to publishing CSS, HTML, XHTML, XML, and other language specifications, also established the Web Accessibility Initiative (WAI). The purpose of the WAI is to create and distribute information on making the Web more accessible to people with disabilities. The WAI has issued guidelines for browser programmers, web editing tool programmers, and web developers that suggest how to improve web accessibility.
Most of us aren't programming browsers or authoring environments, so the WAI recommendation we're concerned with is the Web Content Accessibility Guidelines (WCAG), a list of checkpoints that can be used to measure the accessibility of your website.
Each WCAG checkpoint has a priority rating of one, two, or three, where priority one checkpoints are the most important and priority three the least. The WCAG checkpoints most applicable to CSS design are:
* Provide text alternatives for non-text elements (priority one)
Most images used in style sheets, such as backgrounds or list bullets, are purely decorative, and thus don't require additional alternatives.
* Don't use color as the only way to convey information (priority one)
Make sure that the content can be understood if CSS colors aren't displayed.
* Design pages that function even if style sheets are turned off (priority one)
Test your page in Lynx, or with styles turned off in your browser, to ensure the pages still function properly.
* Style sheets should be used instead of presentational markup (priority two)
After reading this book, this should be an easy one for you to meet! See also [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/app01.html#app01 Appendix A], "Replacing Presentational HTML with CSS."
* Use relative values for styles instead of absolute values (priority two)
For example, use <code>x-large</code>, <code>smaller</code>, or <code>3em</code> instead of pixels or points for fonts; this is more responsive to users' own preferences.
* Use foreground and background colors that contrast well with each other (priority three)
Colors that don't stand out well cause problems for users with poor vision or color blindness.
This list is far from complete, but these are the checkpoints that are most relevant for CSS developers. If a web page or site conforms to all the priority one checkpoints (not just those listed here), it is said to be Single-A accessible. Meeting the priority one and two checkpoints equates to Double-A accessibility, and Triple-A accessibility means that all checkpoints of any priority level are met.
Many governments, schools, and other public institutions around the world have adopted Double-A accessibility as a standard for their sites; Single-A accessibility is considered the minimum for a public website.
<div>Did you Know?
You can use several websites to measure the accessibility of your website. These automatic checkers don't discover every problem, but they can help you get started on solving accessibility hurdles you may have accidentally introduced.
Examples of accessibility evaluators include Access Valet at [http://valet.webthing.com/access/ http://valet.webthing.com/access/], Cynthia Says at [http://www.cynthiasays.com/ http://www.cynthiasays.com/], TAW Online at [http://www.tawdis.net/ http://www.tawdis.net/], and WAVE at [http://wave.webaim.org/ http://wave.webaim.org/]. You can find a full list of accessibility evaluators and other useful online tools on the World Wide Web Consortium's site ([http://www.w3.org/WAI/ER/tools http://www.w3.org/WAI/ER/tools]).</div>
U.S. Government's Section 508
As part of employment and civil rights regulations, the U.S. Federal government requires all agencies to make their public and internal sites accessible to people with disabilities. Known as Section 508 (from the applicable section of the Rehabilitation Act), these regulations affect how agencies can purchase and use information technologyaccessibility is a requirement for hardware, software, and websites employed by the government.
<div>By the Way
If you're not an American or don't work for the U.S. Federal government, you might think these rules don't apply to youand you're right. Section 508 is not an attempt to regulate the private sector, just Federal agencies. However, as the U.S. Federal government is the largest employer of information technology in the world, these rules have far-reaching influence and may be considered as a model for future accessibility standards. Therefore, it's important to be familiar with these requirements and how they apply to web development that uses CSS.</div>
The requirements for web page accessibility are based on the W3C's Web Content Accessibility Guidelines; specifically, most of the priority one checkpoints with a few additions. Those include the following:
* Make online forms compatible with assistive technology.
* Inform users whether a timed response is required, and if so, allow for extra time to be requested.
* Allow users to skip over lists of repetitive links, such as a navigation bar. A common way to do this is to create a link that jumps ahead in the page to the main content.
Many of these requirementsand the WCAG checkpointsdon't deal directly with Cascading Style Sheets and should be handled by the way you create your HTML (and are thus beyond the scope of this book). However, even in those cases, CSS can still be used to enhance the style and accessibility of your page.
{| cellspacing="0" cellpadding="5" border="1"
|-
| Try it Yourself: Disable Your Web Access
What's it like to be a computer user with disabilities? Most of us who are visually dependentwe are forced to use our eyes to access the Webdon't have a good idea of what it's like to have limitations on our Internet access. Here's a simple exercise you can try that doesn't exactly mimic any specific disabilities, but is useful in raising your awareness:
{| border="0"
|-
| <div>'''1. '''</div>
| <div>Sit down at your computer and open up your web browser.<br /><br /></div>
|-
| <div>'''2. '''</div>
| <div>Go into the preferences or configuration section of your browser and start turning things off. Anything you can turn off that relates to displaying content, do it.<br /><br /></div>
|-
| <div>'''3. '''</div>
| <div>Turn off images. Turn off JavaScript and Java. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22fig01 Figure 22.1] shows how you do this in Firefox; it's similar in most other browsers as well.<br /><br /><div style="text-align: center;"> Figure 22.1. Disabling content preferences in Firefox on Mac OS X. <div>[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/images/22fig01_alt.jpg [View full size image]]</div>[[Image:22fig01.jpg|500px]] </div><br /></div>
|-
| >
| >
|-
| <div>'''4. '''</div>
| <div>While you're at it, if you can disable style sheets, or force your own fonts and colors, do that too. (In Firefox, set the Advanced and Colors options under Fonts and Colors.)<br /><br /></div>
|-
| <div>'''5. '''</div>
| <div>Mute your computer's speakers.<br /><br /></div>
|-
| <div>'''6. '''</div>
| <div>Unplug your mouse and throw it out the window. No, don't really do that; just set it aside for now, and eschew the use of it for this exercise.<br /><br /></div>
|-
| <div>'''7. '''</div>
| <div>Now visit your favorite websites and see how well you can use them. Try sites you've designed as well. Are you able to accomplish the basic functions of each site easily? Is it designed to be easily usable by someone with limitations, or does it shut out users with special needs?<br /><br /></div>
|-
| <div>'''8. '''</div>
| <div>You may want to read up on your operating system's accessibility features such as keyboard access. Most of us don't realize how to turn them on and off until we actually need them. Remember, we're all getting olderit's quite likely that you will need accessibility features yourself as you age! Will the Web be usable by you then?<br /><br /></div>
|}
|}
./ ADD NAME=CH22LEV1SEC2.HTML
Aural Cascading Style Sheets
Aural properties for Cascading Style Sheets were first proposed as an extension to CSS level 1 and were incorporated into the CSS level 2 specification. In the CSS 2.1 update, they've been assigned to an optional appendix; they're not widely applicable to, nor supported by, existing browsers. These properties enable you to control the sound properties of spoken text, just as the visual properties control the visual properties of text and other elements.
Browsers That Understand Aural CSS
Unfortunately, this list is quite short. There are no mainstream browsers that support aural CSS properties. The EmacSpeak browser, developed for Linux and Unix by one of the primary authors of the aural properties of the CSS level 2 specification, is the only browser that supports aural CSS.
<div>Did you Know?
If you're running a Unix-based system, you can download EmacSpeak from T.V. Raman's website at [http://emacspeak.sourceforge.net/ http://emacspeak.sourceforge.net/].</div>
Currently, screen readers and speaking browsers, such as JAWS for Windows and Home Page Reader, do not support aural CSS either; they use their own rules, which are not fully CSS compliant, to determine how to speak each page. Future versions may support aural CSS, though.
Because of this lack of support, there's little reason today to spend much time with aural style sheets; this is unfortunate because many of the properties are quite useful both for disability access and potentially for general use. Because these properties don't cause any problems in existing browsersthey're all completely ignoredit doesn't hurt anything to include them; there is a very low cost of failure when an aural CSS property is not supported.
Future versions of browsers, screen readers, and other access methods may support aural CSS; one particularly interesting proposal is for multi-modal access methods that would provide both visual and aural renditions simultaneously.
Aural CSS Properties
Rules using aural CSS properties are written just like rules for any other property, with a selector and a declaration of property names and values. You could use the <code>@media</code> selector described later in this hour to limit these rules only to media type <code>aural</code>, although by their very nature these properties apply only to text that is spoken by the computer.
<div>Watch Out!
You might think that simply setting rules with the <code>aural</code> media type would allow you to create separate style sheets for blind users with screen readers. For example, this seems a natural way to hide "skip navigation" links:
<div><pre>@media aural { .nav { display: none; } }
</pre></div>
The problem here is that screen readers aren't fully <code>aural</code> browsers; what most of them do is literally read the screen out loud. Thus many times something that is hidden in the visual presentation is also hidden in the screen reader's audio output. This rule simply won't work as desired, even if it's encapsulated in a style sheet linked with <code><link media="aural"></code>, on most modern assistive technology. This is disappointing and limits the effectiveness of CSS for overcoming accessibility barriers; for some work-arounds, see [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch24.html# Hour 24], "Troubleshooting and Browser Hacks."</div>
Because aural CSS is so poorly supported, I won't give an extensive tutorial on each property; if you want specifics, you can consult the aural properties section of the CSS specification. In this hour I'll just tell you enough to know the general capabilities of aural CSS.
Volume and Voices
The characteristics of the voice speaking the content of the page are determined by several properties relating to volume, pitch, and other qualities. These properties are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table01 Table 22.1] along with the range of values allowed.
{| cellspacing="0" cellpadding="5"|+ Table 22.1. Volume and Voice Aural Properties
|-
| valign="bottom" | Property Name
| valign="bottom" | Values
|-
| <code>pitch</code>
| <code>frequency</code>, <code>x-low</code>, <code>low</code>, <code>medium</code>, <code>high</code>, <code>x-high</code>, <code>inherit</code>
|-
| <code>pitch-range</code>
| <code>variation-number</code>, <code>inherit</code>
|-
| <code>richness</code>
| <code>richness-number</code>, <code>inherit</code>
|-
| <code>speech-rate</code>
| <code>words-per-minute</code>, <code>x-slow</code>, <code>slow</code>, <code>medium</code>, <code>fast</code>, <code>x-fast</code>, <code>faster</code>, <code>slow</code>, <code>inherit</code>
|-
| <code>stress</code>
| <code>stress-number</code>, <code>inherit</code>
|-
| <code>voice-family</code>
| <code>specific-family</code>, <code>generic-family</code>, <code>inherit</code>
|-
| <code>volume</code>
| <code>volume-number</code>, <code>percentage</code>, <code>silent</code>, <code>x-soft</code>, <code>soft</code>, <code>medium</code>, <code>loud</code>, <code>x-loud</code>, <code>inherit</code>
|}
The <code>voice-family</code> property is similar to <code>font-family</code>; you can define a specific voice, which may or may not be supported by the aural CSS browser, or you can use one of three generic voice families: <code>male</code>, <code>female</code>, or <code>child</code>. There's no standard list of voice types beyond this, and so the use of specific voices (such as <code>robot</code>, <code>Spock</code>, or <code>"Britney Spears"</code>) depends on the browser.
Pausing and Cues
Aural CSS properties enable you either to insert pauses to break up the aural reading, either before or after an element, or to insert specific sound files, called audio cues. These properties are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table02 Table 22.2].
{| cellspacing="0" cellpadding="5"|+ Table 22.2. Pausing and Cues Aural Properties
|-
| valign="bottom" | Property Name
| valign="bottom" | Values
|-
| <code>cue</code>
| Shorthand property, setting <code>cue-after</code> and <code>cue-before</code>
|-
| <code>cue-after</code>
| <code>sound-url</code>, <code>none</code>, <code>inherit</code>
|-
| <code>cue-before</code>
| <code>sound-url</code>, <code>none</code>, <code>inherit</code>
|-
| <code>pause</code>
| Shorthand property, setting <code>pause-after</code> and <code>pause-before</code>
|-
| <code>pause-after</code>
| <code>time-measurement</code>, <code>percentage</code>, <code>inherit</code>
|-
| <code>pause-before</code>
| <code>time-measurement</code>, <code>percentage</code>, <code>inherit</code>
|}
Cues are normal sound files, usually <code>.wav</code> or <code>.au</code> files, and are indicated by <code>url()</code> notation. Pauses are measured in seconds (<code>s</code>) or milliseconds (<code>ms</code>), such as <code>2s</code> or <code>30ms</code>.
Three-Dimensional Sounds
Most humans without hearing impairments hear sound in three dimensions. Aural Cascading Style Sheets enable you to designate a specific location, within three dimensions, from which a sound could originate. Consider a transcript of an interview, marked up with voice properties similar to those of the appropriate speakers, where the interviewer's voice is heard on the left side, and the subject of the interview is heard on the right. A question from the audience could come from behind and below while an overhead announcement originates from directly above the listener.
The properties that place each sound in a specific location are shown on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table03 Table 22.3].
{| cellspacing="0" cellpadding="5"|+ Table 22.3. Three-Dimensional Sound Aural Properties
|-
| Property Name
| Values
|-
| <code>azimuth</code>
| <code>angle</code>, <code>left-side</code>, <code>far-left</code>, <code>left</code>, <code>center-left</code>, <code>center</code>, <code>center-right</code>, <code>right</code>, <code>far-right</code>, <code>right-side</code>, <code>behind</code>, <code>leftwards</code>, <code>rightwards</code>, <code>inherit</code>
|-
| <code>elevation</code>
| <code>angle</code>, <code>below</code>, <code>level</code>, <code>above</code>, <code>higher</code>, <code>lower</code>, <code>inherit</code>
|}
Angles are measured in degrees (<code>deg</code>), grads (<code>grad</code>), or radians (<code>rad</code>), such as <code>90deg</code>, <code>100grad</code>, or <code>1.571rad</code>, which are all (approximately) a right angle. A <code>0deg</code> azimuth is directly in front of the listener, and <code>0deg</code> elevation is level with the listener.
Choosing What to Speak
Just as the display and visibility properties let you hide what is shown visually, aural CSS also lets you control what is vocalized and how that's done. You can even add the equivalent of a background image by specifying a background sound to be played while an element is spoken. These properties are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table04 Table 22.4].
{| cellspacing="0" cellpadding="5"|+ Table 22.4. Speaking Method Aural Properties
|-
| Property Name
| Value
|-
| <code>play-during</code>
| <code>background-sound</code>, <code>mix</code>, <code>repeat</code>, <code>auto</code>, <code>none</code>, <code>inherit</code>
|-
| <code>speak</code>
| <code>normal</code>, <code>none</code>, <code>spell-out</code>, <code>inherit</code>
|-
| <code>speak-header</code>
| <code>always</code>, <code>once</code>, <code>inherit</code> (table cells only)
|-
| <code>speak-numeral</code>
| <code>continuous</code>, <code>digits</code>, <code>inherit</code>
|-
| <code>speak-punctuation</code>
| <code>code</code>, <code>none</code>, <code>inherit</code>
|}
The <code>play-during</code> property enables you to specify whether a background file is mixed in with any other background sounds already playing (from a containing element) or whether it replaces the other sound.
./ ADD NAME=CH22LEV1SEC3.HTML
=== Media-Specific Style Sheets ===
Using CSS, you can create style sheets that are media specific, meaning that they should be applied to only one particular type of output device. An output device is any physical hardware device that can present web contentvisually or otherwiseas well as the software necessary to allow for that presentation, such as a printer driver or a screen reader.
In [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4], "Using CSS with HTML," you learned the basics of the <code><link></code> element and its attribute <code>media</code>, which enable you to tie style sheets to categories of output media. In this hour, you'll expand your knowledge of media types and learn how to write rules within one style sheet that apply to different media.
Categories of Media Types
The full list of media types defined in CSS is listed on [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table05 Table 22.5]. A given browser is required to support only those media types appropriate for that browser. For example, a set-top box doesn't need to support screen, aural, or print media types. The typical visual browser uses two media types: <code>screen</code> and <code>print</code>. Opera also supports the <code>projection</code> media type in full-screen kiosk mode.
{| cellspacing="0" cellpadding="5"|+ Table 22.5. Media Types in CSS
|-
| Media Type
| Description
|-
| <code>aural</code>
| Pages read out loud by synthesized voice; for example, screen readers for the blind.
|-
| <code>braille</code>
| Content represented by raised dot characters on Braille terminals for blind users.
|-
| <code>emboss</code>
| Pages printed out as raised dots in Braille, on thick paper.
|-
| <code>handheld</code>
| Content displayed on a limited-size handheld screen.
|-
| <code>print</code>
| Pages printed out on paper.
|-
| <code>projection</code>
| Content displayed as slides or transparencies projected on a large screen.
|-
| <code>screen</code>
| Pages displayed on a color monitor.
|-
| <code>tty</code>
| Content printed on teletype devices or other media with limited display capabilities, which print only characters of a fixed size and type.
|-
| <code>tv</code>
| Pages displayed on a television screen, possibly taking advantage of sound capabilities but with limited interaction.
|}
Media type values are used in <code><link></code> tags and <code>@import</code> rules for the purpose of specifying which style sheets to use, and they are also used to classify certain rules within a style sheet as applicable.
<div>Did you Know?
The media types described here are obviously not enough to fully capture the diversity of access methods available to web users of the 21st century. For example, the <code>handheld</code> media type assumes that a handheld device will be monochrome, but we've already seen a number of color handheld devices become available. Also, there is a large difference between a PDA, a pocket computer, and a cell phone, although these are all grouped under the term "<code>handheld</code>."
The W3C realizes these deficiencies and is developing a better classification system for the CSS level 3 recommendation; you can read the current drafts at [http://www.w3.org/Style/CSS/current-work http://www.w3.org/Style/CSS/current-work]. Also, the W3C's Composite Capabilities/Preferences Profile (CC/PP) work is moving toward a standardized way of describing end-user device characteristics; see [http://www.w3.org/Mobile/CCPP/ http://www.w3.org/Mobile/CCPP/] for more.</div>
Linking and Importing Media-Specific Style Sheets
You've already seen in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch04.html#ch04 Hour 4] how to use a media type with the <code><link></code> tag in HTML:
<div><pre><link type="text/css" rel="stylesheet" media="print, emboss" href="paged-output.css">
</pre></div>
Such a link would load only the style sheet if the browser were currently printing to a standard or Braille printer.
An <code>@import</code> rule at the beginning of a style sheet can also be set to specify style sheets applicable to certain media types:
<div><pre>@import url("site.css");
@import url("screen.css") screen, tv;
@import url("dots.css") braille;
</pre></div>
These rules always load the <code>site.css</code> file, and load <code>screen.css</code> for display on a computer or television screen and <code>dots.css</code> for a Braille display terminal.
<div>Watch Out!
Internet Explorer on Windows does not support <code>@import</code> rules with media types. For compatibility with Internet Explorer, you should use some other method of linking media-specific style sheets, such as the <code><link></code> tag or the <code>@media</code> rule described next.</div>
Using the <code>@media</code> Rule
Within the same style sheet, you can mix rules for different media types by using an <code>@media</code> rule. This is a special type of rule that surrounds your other CSS rules and applies them only to certain media types. The basic form of this rule is
<div><pre>@media media-type {
selector { declaration; }
selector { declaration; }
...
}
</pre></div>
That last curly brace is important because it marks the end of the <code>@media</code> rule. Any rules within the <code>@media</code> rule's braces are applied only to the media type listed. [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22ex01 Listing 22.1] has several examples of the <code>@media</code> rule limiting certain rules to only certain types of output devices.
Listing 22.1. A Style Sheet with <code>@media</code> Rules
{| cellspacing="0" cellpadding="5" border="1"
|-
| <div><pre>/* media-rules-22.1.css */<br /><br />@media print {<br />body { font: 10pt "Times New Roman", serif;<br />color: black; background-color: white; }<br />.footer { border-top: 1px solid black;<br />font-size: 8pt; }<br />}<br /><br />@media screen {<br />body { font-family: Verdana, sans-serif;<br />color: white; background-color: #330000; }<br />.footer { padding: 2em; font-size: smaller;<br />border: 1em solid green; color: #330000;<br />background-color: white; }<br />}<br /></pre></div><br />
|}
./ ADD NAME=CH22LEV1SEC4.HTML
CSS Properties for the <code>print</code> Medium
By far the most common medium you'll be concerned withbesides <code>screen</code>is <code>print</code>. Nearly all computers have printers attached, and it's common for users to print a page as a way of making a permanent copy of the content.
CSS rules can be used to format the appearance of the printed page. You can control the layout, fonts, line spacing, display characteristics, and more, separately from the way a page is displayed on the screen. A specific style sheet for printing is a nice addition to any CSS-based website.
Browsers and Printing
Printing a web page is often a risky proposition. The combination of text, tables, style rules, frames, and low-resolution GIF images often results in a poor-looking printed document. Most of the time, browsers don't print nearly as well as they display onscreen. You can overcome some of these problems with a print style sheet.
To link in a style sheet for printing, simply use the HTML <code><link></code> tag as described previously. You can also use an <code>@import</code> rule or an <code>@media</code> rule in the main style sheet with the appropriate media type. Multiple <code><link></code> tags let you provide one style sheet for rules common to all media typesone for screen display and one for printing, like the following:
<div><pre><link type="text/css" rel="stylesheet" media="all" href="all.css">
<link type="text/css" rel="stylesheet" href="screen.css">
<!-- default value for media attribute is screen -->
<link type="text/css" rel="stylesheet" media="print" href="print.css">
</pre></div>
Measurements for Printing
When you're creating a style sheet for printing, you can use additional units of measurement that would be inappropriate or meaningless on a computer monitor. These units correspond to real-world units of measurement used in printing and are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22table06 Table 22.6].
{| cellspacing="0" cellpadding="5"|+ Table 22.6. Units of Measurement Appropriate for Printing
|-
| Unit
| Measurement
|-
| <code>cm</code>
| Centimeters
|-
| <code>in</code>
| Inches (<code>1in = 2.54cm</code>)
|-
| <code>mm</code>
| Millimeters (<code>1mm = 0.1cm</code>)
|-
| <code>pc</code>
| Picas (<code>1pc = 12pt</code>)
|-
| <code>pt</code>
| Points (<code>72pt = 1in</code>)
|}
These units can be used with any CSS property that requires a measurement value. For example, the following rule sets a padding value in centimeters:
<div><pre>@media print { h1 { padding: 1cm 2cm 1cm 1cm; } }
</pre></div>
Designing CSS for Print
When creating style rules or style sheets for the print medium, it's important to remember how the medium differs from the computer screen. The point of using a different style sheet for print is to make the resulting hardcopy easier to read and use.
Many printers out there will be black-and-white, although color printers are used often. However, many users avoid printing in full color simply to save ink. Therefore, you want to make sure you're not relying on color entirely.
A printed page is clearly not interactive. When someone is printing a page, they're usually doing it for the content. Therefore, things such as navigation bars and hypertext links are pretty useless. You can't click on a piece of paper.
The <code>display</code>, <code>visibility</code>, and <code>text-decoration</code> properties can help with this. You may want to enclose your navigation bar in a <code><div class="nav"></code> and set rules like the following:
<div><pre>.nav { display: none; }
a:link, a:visited { text-decoration: none; }
</pre></div>
Areas with dark backgrounds and light colors consume a lot of black ink. Changing these to black text on a white background, is a friendly thing to do when creating a style sheet for print. You'll save a lot of ink for your users who choose to print your pages out.
As described earlier in the hour, you can use exact units such as centimeters or inches when printing, as well as points for font sizes. Be careful not to assume that your users' papers will be the same size as yours, though. For example, a user may just decide to print out your web page in landscape mode (wider than it is long) instead of portrait.
./ ADD NAME=CH22LEV1SEC5.HTML
Summary
Users with disabilities are as entitled to use the Web as anyone else, but often they are unable to access sites because of careless web design. Using Cascading Style Sheets is an excellent first step toward developing a site that can be used by everyone, as style sheets separate presentation from content.
Assistive technology devices and software can often enable access by disabled users, but only if sites are designed in accordance with web accessibility standards. The W3C has produced Web Content Accessibility Guidelines that are an invaluable resource for web developers and that form the basis of the U.S. Government's Section 508 regulations for Federal agency sites.
Aural CSS properties let you determine qualities of the voice used to read content out loud, such as the pitch, speed, and "family" of the voice. Unfortunately, almost no browsers support aural CSS currently, thus limiting its usefulness.
Alternate style sheets for different access devices are classified by the media types to which they apply. You can set the media type of a CSS rule in several ways: by linking to a style sheet containing the rule with the <code><link></code> element in HTML; by using <code>@import</code> to import a style sheet with that rule; or by wrapping the CSS rule in an <code>@media</code> rule. Visual browsers support the <code>screen</code> media type, and nearly all of them also support the <code>print</code> media type.
Designing for the print medium requires a different approach than doing so for the screen. Scrolling, links, interactivity, and paging are all changed, so you need to think carefully about how to devise your print styles.
./ ADD NAME=CH22LEV1SEC6.HTML
Workshop
The workshop contains a Q&A section, quiz questions, and an exercise to help reinforce what you've learned in this hour. If you get stuck, the answers to the quiz can be found after the questions.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q1a1 Q.]'''
| Is Section 508 the same as the Americans with Disabilities Act (ADA)? What are the ADA requirements for web accessibility?
|-
| >
| >
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q1 A.]'''
| Section 508 and the ADA are different sets of regulations. Section 508 applies only to Federal agencies, whereas the ADA is applicable to a number of private and public sector entities. There are no formal ADA regulations for web accessibility as there are for Section 508; however, the ADA requires organizations to avoid discrimination on basis of disability when providing services. For detailed commentary on legal requirements for accessibility, see Cynthia Waddell's essays on the website of the International Center for Disability Resources on the Internet ([http://www.icdri.org/ http://www.icdri.org/]).
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q2a2 Q.]'''
| Can tables be made accessible? Frames? JavaScript? Java? Flash? PDF?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q2 A.]'''
| Yes. You can make tables and frames accessible by using HTML markup carefully and by providing additional attributes or elements, such as <code><noframes></code>. If a certain technology or file format can't be made accessible directly, the content within it can be presented in an alternate, accessible format, such as a transcript or HTML version.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q3a3 Q.]'''
| I need more control over the print layout than what CSS gives me (and the browsers don't support). What other options are there?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa1q3 A.]'''
| As an alternative to CSS's print-related properties, you may want to investigate Extensible Stylesheet Language Formatting Objects (XSL-FO). Formatting objects use XML elements with attribute values related to CSS and are usually created by applying an Extensible Stylesheet Language Transformations (XSLT) sheet. Obviously, this is advanced stuff, but if you need advanced layout capabilities for print, this may be what you are looking for. See the W3C's XSL page at [http://www.w3.org/Style/XSL/ http://www.w3.org/Style/XSL/] for more.
|}
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q1a1 1.]'''
| Do the Web Content Accessibility Guidelines suggest that color should be avoided in web design?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q2a2 2.]'''
| Which of the following is not an aural CSS property?
<div># <div><code>voice-family</code></div>
# <div><code>stress</code></div>
# <div><code>accent</code></div>
# <div><code>speak-numeral</code></div></div>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q3a3 3.]'''
| Your navigation bar has a <code>class</code> of <code>navbar</code>, and you've decided you don't want it to appear when the page is printed. How do you write such a rule using <code>@media</code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q4a4 4.]'''
| Which of the following is not a unit of measurement in CSS?
<div># <div><code>in</code></div>
# <div><code>mm</code></div>
# <div><code>ft</code></div>
# <div><code>pc</code></div></div>
|}
Answers
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q1 1.]'''
| No. This is a common misunderstanding; the restriction is on using color as the only way to convey information. If you also provide that information in the HTML tags or the text content, your colors are not a problem at all.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q2 2.]'''
| <code>c.</code> There is no <code>accent</code> property in CSS.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q3 3.]'''
| Here is one way to write a rule to hide the <code>navbar</code> class:
<div><pre>@media print { .navbar { display: none; } }<br /></pre></div><br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/Sams%20Teach%20Yourself%20CSS%20in%2024%20Hours_2ndEd/0672329069/ch.htm#ch22qa2q4 4.]'''
| <code>c.</code> Feet are not a valid unit of measurement in CSS; inches, millimeters, and picas are.
|}
Exercise
Because most browsers don't have good support for printing CSS styles, it can be rather hit-and-miss designing a print style sheet. However, this is still probably one of the best exercises: It forces you to think through some of the assumptions you make when designing a page. For example, you've probably laid out your page in percentages or pixels, for online display. Do those measurements work well in print, or would it be better to use centimeters or inches? What do you want to do about links on the page? Present them as underlined text, even though they can't be clicked on? Remove the underlines? Or remove the navigation bar entirely? Choose a style sheet you've worked on in the past and redesign it for printed output.
Next, how would you redesign the same style sheet for the aural media type?
./ ADD NAME=CH23.HT
9f2jzu50rttbyvwoztmnszhxxq9znwk
User:Foxall/01
2
2132
39237
5907
2026-04-13T06:03:27Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39237
wikitext
text/x-wiki
=Hour 1. A C# Programming Tour =
Learning a new programming language can be intimidating. If you've never programmed before, the act of typing seemingly cryptic text to produce sleek and powerful applications probably seems like a black art, and you may wonder how you'll ever learn everything you need to know. The answer is, of course, one step at a time. The first step to learning a language is the same as that of any other activity�building confidence. Programming is part art and part science. Although it may seem like magic, it's more akin to illusion; after you know how things work, a lot of the mysticism goes away, freeing you to focus on the mechanics necessary to produce the desired result.
In this hour, you'll complete a quick tour that takes you step-by-step through creating a complete, albeit small, C# program. I've yet to see a "Hello World" program that's the least bit helpful (they usually do nothing more than print "hello world" to the screen�oh, fun). So instead, you'll create a picture-viewer application that lets you view Windows bitmaps and icons on your computer. You'll learn how to let a user browse for a file and how to display a selected picture file on the screen, both of which are skills that will come in handy in later applications that you create. Creating large, commercial solutions is accomplished by way of a series of small steps. After you've finished creating this small project, you'll have an overall feel for the development process.
The highlights of this hour include the following:
* Building a simple, yet functional, C# application
* Letting a user browse a hard drive
* Displaying a picture from a file on disk
* Getting familiar with some programming lingo
* Learning about the Visual Studio�C# IDE
I hope that by the end of this hour, you'll realize just how much fun it is to program using C#.
=== Starting C# ===
You must become familiar with a few terms before you begin to create programs in C#:
* Distributable Component The final, compiled version of a project. Components can be distributed to other people and other computers and do not require C# to run (although the .NET Framework is required, which you'll learn about in coming hours). Distributable components are also called programs. In [ch22.htm#ch22 Hour 22], "Deploying a Solution," you'll learn how to distribute the Picture Viewer program that you're about to build to other computers.
* Project A collection of files that can be compiled to create a distributable component (program). There are many types of projects, and complex applications may consist of many projects, such as a Windows Application project and support DLL projects.
* Solution A collection of projects and files that compose an application or component.
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| C# is a complete development environment; every tool you'll need to create your C# projects is accessed from within Visual Studio. The Visual Studio-C# environment is called the IDE, short for Integrated Development Environment, and it is the design framework in which you build applications. To work with C# projects, you must first start the Visual Studio IDE.
|}
Start the C# IDE now by choosing Microsoft Visual Studio .NET from within the Microsoft Visual Studio .NET folder on your Start menu.
| align="right" | [ch01.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec2.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC02.HTM
| align="right" | [ch01lev1sec1.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec3.htm [[Image:next.gif|41px|Next Section]]]
|}
Creating a New Project
When you first start Visual Studio .NET, you're shown the Visual Studio Start Page tab within the IDE. Using this page, you can open projects created previously or create new ones (see [01.htm#ch01fig01 Figure 1.1]). For this quick tour, you're going to create a new Windows application, so click New Project to display the New Project dialog box shown in [01.htm#ch01fig02 Figure 1.2].
<div style="text-align: center;">Figure 1.1. You can open existing projects or create new projects from the Visual Studio Start page.
[[Image:01fig01.jpg|500px|graphics/01fig01.jpg]]
</div>
<div style="text-align: center;">Figure 1.2. The New Project dialog box allows you to create many types of .NET projects.
[[Image:01fig02.jpg|500px|graphics/01fig02.jpg]]
</div>
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you don't see the Visual Studio Start page, chances are that you've changed the default settings. [ch02.htm#ch02 Hour 2], "Navigating C#," shows you how to change them back. For now, be aware that you can create a new project from the File menu in addition to using the techniques described in this hour.
|}
You can create many types of projects with C#, as well as with the other supported languages of the .NET platform. The New Project dialog box is used to specify the type of C# project you want to create. If the Visual C# Projects folder isn't selected, click it to display the C# project types and then make sure the Windows Application icon is selected (if it's not, click it once to select it). At the bottom of the New Project dialog box is a Name text box, in which you specify the name of the project you're creating; in the Location text box, you can enter the location in which to save the project files.
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| You should always set these values to something meaningful before creating a project, or you'll have more work to do later if you want to move or rename the project.
|}
Type Picture Viewer into the Name text box to name your project. There's no need to change the location where the project files are to be saved at this time, so go ahead and create the new Windows Application project by clicking OK. C# creates the new project, complete with one form (design window) for you to begin building the interface for your application (see [01.htm#ch01fig03 Figure 1.3]).
<div style="text-align: center;">Figure 1.3. New Windows applications start with a blank form; the fun is just beginning!
[[Image:01fig03.jpg|500px|graphics/01fig03.jpg]]
</div>
Your C# environment may look different from that shown in the figures of this hour, depending on the edition of C# you're using, whether you've already played with C#, and other factors such as the resolution of your monitor. All the elements discussed in this hour, however, exist in all editions of C#. (If your IDE doesn't have a window displayed that is shown in a figure, use the View menu to display the window.)
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To create a program that can be run on another computer, you start by creating a project, and then you compile the project into a component, such as an executable (a program a user can run) or a DLL (a component that can be used by other programs and components). The compilation process is discussed in detail in [ch22.htm#ch22 Hour 22], "Deploying a Solution." The important thing to note at this time is that when you hear someone refer to creating or writing a program, just as you are creating the Picture Viewer program now, they're referring to the completion of all steps up to and including compiling the project to a distributable file.
|}
| align="right" | [ch01lev1sec1.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec3.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC03.HTM
| align="right" | [ch01lev1sec2.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec4.htm [[Image:next.gif|41px|Next Section]]]
|}
Understanding the C# Environment
The first time you run C#, you'll notice that the IDE contains a lot of windows, such as the Properties window on the right, which is used to view and set properties of objects. In addition to these windows, the IDE contains a lot of tabs, such as the Toolbox tab on the left edge of the IDE (refer to [ch01lev1sec2.htm#ch01fig03 Figure 1.3]). Clicking a tab displays an associated window. Try this now: click the Toolbox tab to display the Toolbox window. You can also hover the mouse over a tab for a few seconds to display the window. To hide the window, simply move the mouse off the window. To close the window completely, click the Close (X) button in the window's title bar.
You can adjust the size and position of any of these windows, and you can even hide and show them at will. You'll learn how to customize your design environment in [ch02.htm#ch02 Hour 2], "Navigating C#."
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Unless specifically instructed to do so, do not double-click anything in the C# design environment. Double-clicking most objects produces an entirely different outcome than single-clicking does. If you mistakenly double-click an object on a form, a code window is displayed. At the top of the code window is a set of tabs: one for the form design and one for the code. Click the tab for the form design to hide the code window and return to the form.
|}
The Properties window at the right side of the design environment is perhaps the most important window, and it's the one you'll use most often. If your computer's display is set for 640x480, you can probably see only a few properties at this time. This makes it difficult to view and set properties as you create projects. I highly recommend that you don't attempt development with Visual Studio at a resolution below 800x600. Personally, I prefer 1024x768 because it offers plenty of work space. To change your display settings, right-click your desktop and select Properties.
| align="right" | [ch01lev1sec2.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec4.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC04.HTM
| align="right" | [ch01lev1sec3.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec5.htm [[Image:next.gif|41px|Next Section]]]
|}
Changing the Characteristics of Objects
Almost everything you work with in C# is an object. Forms, for instance, are objects, as are all the items you can put on a form to build an interface, such as list boxes and buttons. There are many types of objects ([ch03.htm#ch03 Hour 3], "Understanding Objects and Collections," discusses objects in detail). Objects, in turn, are classified by type. For instance, a form is a Form object, whereas items you can place on a form are called Control objects, or controls. Some objects don't have a physical appearance, but exist only in code. You'll learn about these kinds of objects in later hours.
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Every object, regardless of whether it has a physical appearance, has a distinct set of attributes known as properties. You have certain properties about you, such as your height and hair color, and C# objects have properties as well, such as Height and BackColor. Properties define the characteristics of an object. When you create a new object, the first thing you need to do is set its properties so that the object appears and behaves in the way you desire. To display the properties of an object, click the object in its designer. Click the form now to ensure that its properties are displayed in the Properties window.
|}
| align="right" | [ch01lev1sec3.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec5.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC05.HTM
| align="right" | [ch01lev1sec4.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec6.htm [[Image:next.gif|41px|Next Section]]]
|}
Naming Objects
The property you should set first for any new object is the Name property. Press F4 to display the Properties window (if it's not already visible), and notice the Name given to your default form (the first property listed in the Properties window)�Form1. When you first create an object, C# gives the object a unique, generic name based on the object's type. Although these names are functional, they aren't very descriptive. For instance, C# named your form Form1, but it's common to have dozens of forms in a project, and it would be extremely difficult to manage a complicated project if all forms were distinguishable only by a number (Form2, Form3, and so forth).
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In actuality, what you're creating is a form class, or template, that will be used to create and show forms at runtime. For the purpose of this quick tour, I simply refer to it as a form. See [ch05.htm#ch05 Hour 5], "Building Forms�Part I," for more information.
|}
To better manage your forms, you should give each one a descriptive name. C# gives you the chance to name new forms as they're created. Because C# created this default form for you, you didn't get a chance to name it, so you must change both the filename and name of the form. Change the name of the form now by clicking the Name property and changing the text from Form1 to fclsViewer. Notice that this did not change the filename of the form as it is displayed in the Solution Explorer window. Change the filename now by right-clicking Form1.cs in the Solution Explorer window, choosing Rename from the context menu, and changing the text from Form1.cs to fclsViewer.cs. In future examples, I won't have you change the filename each time because you'll have enough steps to accomplish as it is. I do recommend, however, that you always change your filenames to something meaningful in your 'real' projects.
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I use the fcls prefix here to denote that the file is a form class. There are different types of classes, so using a prefix helps differentiate the classes in code. You're not required by C# to use object prefixes, but I highly recommend that you do so. In [ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays," you'll learn the benefits of using a naming convention as well as the standard prefixes for many .NET objects.
|}
| align="right" | [ch01lev1sec4.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec6.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC06.HTM
| align="right" | [ch01lev1sec5.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec7.htm [[Image:next.gif|41px|Next Section]]]
|}
Setting the Text Property of the Form
Notice that the text that appears in the form's title bar says Form1. This is because C# sets the form's title bar text to the name of the form when it is first created, but doesn't change it when you change the name of the form. The text in the title bar is determined by the value of the Text property of the form. Click the form once more so that its properties appear in the Properties window. Use the scrollbar in the Properties window to locate the Text property in the Properties window and then change the text to Picture Viewer.
| align="right" | [ch01lev1sec5.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec7.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC07.HTM
| align="right" | [ch01lev1sec6.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec8.htm [[Image:next.gif|41px|Next Section]]]
|}
Giving the Form an Icon
Everyone who has used Windows is familiar with icons, which are the little pictures used to represent programs. Icons most commonly appear in the Start menu next to the name of their respective programs. In C#, you not only have control over the icon of your program file, you can also give every form in your program a unique icon if you want to.
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The instructions that follow assume you have access to the source files for the examples in this book. They are available at [http://www.samspublishing.com/detail_sams.cfm?item=0672320800 www.samspublishing.com/detail_sams.cfm?item=0672320800]. You don't have to use the icon I've provided for this example; you can use any icon of your choice. If you don't have an icon available, you can skip this section without affecting the outcome of the example.
|}
To give the form an icon, follow these steps:
# In the Properties window, click the Icon property to select it.
# When you click the Icon property, a small button with three dots appears to the right of the property. Click this button.
# To locate the HourOne.ico file or another ico file of your choice, use the Open dialog box that appears. When you've found the icon, double-click it, or click it once to select it and then click Open.
After you've selected the icon, it appears in the Icon property along with the word (Icon). A small version of the icon appears in the upper-left corner of the form, as well. Whenever this form is minimized, this is the icon that's displayed on the Windows taskbar. (Note: This doesn't change the icon for the project as a whole. In [ch22.htm#ch22 Hour 22], you'll learn how to assign an icon to your distributable file.)
| align="right" | [ch01lev1sec6.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec8.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC08.HTM
| align="right" | [ch01lev1sec7.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec9.htm [[Image:next.gif|41px|Next Section]]]
|}
Changing the Size of the Form
Next, you're going to change the Width and Height properties of the form. The Width and Height values are shown collectively under the Size property; Width appears to the left of the comma, Height to the right. You can change the Width or Height by changing the corresponding number in the Size property. Both values represent the number of pixels of the dimension. To display and adjust the Width and Height properties separately, click the small plus sign (+) next to the Size property (see [01.htm#ch01fig04 Figure 1.4]).
<div style="text-align: center;">Figure 1.4. Some properties can be expanded to show more specific properties.
[[Image:01fig04.jpg|500px|graphics/01fig04.jpg]]
</div>
Change the Width property to 400 and the Height to 325. To commit a property change, press Tab or click a different property or window. Your screen should now look like the one in [01.htm#ch01fig05 Figure 1.5].
<div style="text-align: center;">Figure 1.5. A change in the Properties window is reflected as soon as the change is committed.
[[Image:01fig05.jpg|500px|graphics/01fig05.jpg]]
</div>
When you first created this project, C# saved a copy of the source files in their initial state. The changes you've made so far exist only in memory; if you were to turn your computer off at this time (don't do this), you would lose any and all work up to this point. You should get into the habit of saving your work frequently. Save the project now by choosing Save All from the File menu or by clicking the Save All button on the toolbar (it has a picture of stacked disks on it).
| align="right" | [ch01lev1sec7.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec9.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC09.HTM
| align="right" | [ch01lev1sec8.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec10.htm [[Image:next.gif|41px|Next Section]]]
|}
Adding Controls to a Form
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Now that your form has its properties set, you need to add objects to the form to produce a user interface. Objects that can be placed on a form are called controls. Some controls have a visible interface with which a user can interact, whereas others are always invisible to the user. You'll use controls of both types in this example. On the left side of the screen is a tab titled Toolbox. Click the Toolbox tab now to display the Toolbox window shown in [01.htm#ch01fig06 Figure 1.6]. The toolbox contains all the controls available in the project, such as labels and text boxes.
|}
<div style="text-align: center;">Figure 1.6. The toolbox is used to select controls to build a user interface.
[[Image:01fig06.jpg|500px|graphics/01fig06.jpg]]
</div>
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| You can add a control to a form in three ways, and [ch05.htm#ch05 Hour 5] explains them in detail. In this hour, you'll use the technique of double-clicking a tool in the toolbox.
|}
The toolbox closes itself soon after you've added a control to a form and the pointer is no longer over the toolbox. To make the toolbox stay visible, click the little picture of a pushpin located in the toolbox's title bar.
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Refer to [ch02.htm#ch02 Hour 2], "Navigating C#," for more information on customizing the design environment.
|}
Your Picture Viewer interface will consist of the following controls:
* Two Button controls
* A PictureBox control
* An OpenFileDialog control
| align="right" | [ch01lev1sec8.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec10.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC10.HTM
| align="right" | [ch01lev1sec9.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec11.htm [[Image:next.gif|41px|Next Section]]]
|}
Designing an Interface
It's generally best to design the user interface of a form and then add the code behind the interface that makes the form functional. The user interface for your Picture Viewer program will consist of a View Picture button, a Close button, and a PictureBox in which to display a picture.
Adding a Visible Control to a Form
Start by adding a Button control to the form. Do this by double-clicking the Button item in the toolbox. C# then creates a new button and places it in the upper-left corner of the form (see [01.htm#ch01fig07 Figure 1.7]).
<div style="text-align: center;">Figure 1.7. When you double-click a control in the toolbox, the control is added to the upper-left corner of the form.
[[Image:01fig07.jpg|500px|graphics/01fig07.jpg]]
</div>
Using the Properties window, set the button's properties as follows (note that you may want to change the Properties list to alphabetical, if it is not already, to make it easier to find these properties by name):
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnSelectPicture</code>
|-
| <code>Text</code>
| <code>Select Picture</code>
|-
| <code>Location</code>
| <code>301</code>,<code>10</code> (Note: 301 is the x coordinate, 10 is the y coordinate.)
|-
| <code>Size</code>
| <code>85,23</code>
|}
You're now going to create a button that the user can click to close the Picture Viewer program. Rather than adding a new button to the form, you're going to create a copy of the button you've already defined. To do this, right-click the button on the form and choose Copy from its shortcut menu. Next, right-click anywhere on the form and choose Paste from the form's shortcut menu. The new button appears over the button you copied, and it is selected by default. Change the properties of the new button as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnQuit</code>
|-
| <code>Text</code>
| <code>Quit</code>
|-
| <code>Location</code>
| <code>301</code>,<code>40</code>
|}
The last control you need to add to the form is a PictureBox control. A PictureBox has many capabilities, but its primary purpose is to show pictures�which is precisely what you'll use it for in this example. Add a new PictureBox control to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>picShowPicture</code>
|-
| <code>BorderStle</code>
| <code>FixedSingle</code>
|-
| <code>Location</code>
| <code>8</code>,<code>8</code>
|-
| <code>Size</code>
| <code>282</code>, <code>275</code>
|}
After you've made these property changes, your form will look like the one in [01.htm#ch01fig08 Figure 1.8]. Click the Save All button on the toolbar to save your work.
<div style="text-align: center;">Figure 1.8. An application's interface doesn't have to be complex to be useful.
[[Image:01fig08.jpg|500px|graphics/01fig08.jpg]]
</div>
| align="right" | [ch01lev1sec9.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec11.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC11.HTM
| align="right" | [ch01lev1sec10.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec12.htm [[Image:next.gif|41px|Next Section]]]
|}
Adding an Invisible Control to a Form
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| So far, all the controls that you've used sit on a form and have a physical appearance. However, not all controls have a physical appearance. Such controls, referred to as invisible-at-runtime controls, aren't designed for user interactivity, but they're designed to give you, the programmer, functionality beyond the standard features of C#.
|}
To allow the user to select a picture to display, you need to give her the capability to locate a file on her hard drive. You've probably noticed in the past that whenever you choose to open a file from within any Windows application, the dialog box displayed is almost always the same. It doesn't make any sense to force each and every developer to write the code necessary to perform standard file operations. Instead, Microsoft has exposed the functionality via a control that you can use in your project. This control is called the OpenFileDialog control, and it will save you dozens of hours that you would otherwise spend trying to duplicate common functionality.
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Other controls besides the OpenFileDialog control give you file functionality. For example, the SaveFileDialog control provides features for enabling the user to save a file.
|}
Scroll the toolbox until you can see the OpenFileDialog control, and then double-click it to add it to your form. (You may have to scroll the toolbox, which is done by clicking the up arrow toward the top of the window or the down arrow toward the bottom.) Note that the control isn't placed on the form, but it appears in a special area below the form (see [01.htm#ch01fig09 Figure 1.9]). This happens because the OpenFileDialog control has no interface to display to a user. It does have an interface, a dialog box that you can display as necessary, but it has nothing to display directly on a form.
<div style="text-align: center;">Figure 1.9. Controls that have no interface appear below the form designer.
[[Image:01fig09.jpg|500px|graphics/01fig09.jpg]]
</div>
Select the OpenFileDialog control and change its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>ofdSelectPicture</code>
|-
| <code>Filter</code>
| <code>Windows Bitmaps|*.BMP|JPEG Files|*.JPG</code>
|-
| <code>Title</code>
| <code>Select Picture</code>
|}
The Filter property determines the filtering of the control. The text that appears before the pipe symbol (<code>|</code>) is the descriptive text of the file type, whereas the text after the pipe symbol is the pattern to use to filter files; you can specify more than one filter type. Text entered into the Title property appears in the title bar of the Open File dialog box.
| align="right" | [ch01lev1sec10.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec12.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC12.HTM
| align="right" | [ch01lev1sec11.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec13.htm [[Image:next.gif|41px|Next Section]]]
|}
Coding an Interface
The graphical interface for your Picture Viewer program is now complete, so click the pushpin in the title bar of the toolbox to close it. Now, you have to write code for the program to be capable of performing actions. C# is an event-driven language, which means that code is executed in response to events. These events may come from users, such as a user clicking a button, or from Windows itself (see [ch04.htm#ch04 Hour 4], "Understanding Events," for a complete explanation of events). Currently, your application looks nice but it won't do a darn thing. The user can click the Select Picture button, for example, until the cows come home, but nothing will happen because you haven't told the program what to do when the user clicks the button.
You're going to write code to accomplish two tasks. First, you're going to write code that lets the user browse his or her hard drives to locate and select a picture file and then display the file in the picture box (this sounds a lot harder than it is). Second, you're going to add code to the Quit button that shuts down the program when the user clicks the button.
Letting a User Browse for a File
The first bit of code you're going to write will allow the user to browse his or her hard drives, select a file, and then show the selected picture in the PictureBox control. This code will execute when the user clicks the Select Picture button; therefore, it's added to the Click event of that button (you'll learn all about events in later hours). When you double-click a control on a form in Design view, the default event for that control is created and displayed in a code window. The default event for a Button control is its Click event, which makes sense because clicking a button is its most common purpose. Double-click the Select Picture button now to access its Click event in the code window (see [01.htm#ch01fig10 Figure 1.10]).
<div style="text-align: center;">Figure 1.10. You will write all code in a window such as this.
[[Image:01fig10.jpg|500px|graphics/01fig10.jpg]]
</div>
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| When you access an event, C# builds an event handler, which is essentially a template procedure in which you add the code that executes when the event is fired. The cursor is already placed within the code procedure, so all you have to do is add code. You will also notice that the open and closing braces are preset for your new event procedure. The braces, in this case, define the beginning and end of your procedure. You will soon see that C# requires many open and closing braces({ } ). By the time you're done with this book, you'll be madly clicking away as you write your own code to make your applications do exactly what you want them to do�well, most of the time. For now, just enter the code as I present it here.
|}
It's very important that you get in the habit of commenting your code, so the first line you're going to enter is a comment. Beginning a statement with the characters <code>//</code> designates the statement as a comment; the compiler won't do anything with the statement, so you can enter whatever text you want after the double slashes. Type the following statement exactly as it appears and press the Enter key at the end of the line.
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| For more information on creating good comments, see [ch16.htm#ch16 Hour 16], "Debugging Your Code."
|}
<pre>// Show the open file dialog box.
</pre>
The next statement you'll enter triggers a method of the OpenFileDialog control that you added to the form. You'll learn all about methods in [ch03.htm#ch03 Hour 3], "Understanding Objects and Collections." For now, think of a method as a mechanism to make a control take action. The ShowDialog method tells the control to show its Open dialog box and let the user select a file. The ShowDialog method returns a value that indicates its success or failure, which we are then comparing to a predefined result (<code>DialogResult.OK</code>). Don't worry too much about what is happening here, because you'll be learning the details of this in later hours. In a nutshell, the ShowDialog method is called to let a user browse for a file, and if the user selects a file, more code gets executed. Of course, there is a lot more to using the OpenFileDialog control than I present in this basic example, but this simple statement gets the job done. Enter the following if statement followed by an open brace:
<pre>if (ofdSelectPicture.ShowDialog() == DialogResult.OK)
{
</pre>
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Open and closing braces are necessary for this if statement because they denote that multiple lines will be part of this construct.
|}
Time for another comment. Enter this statement and remember to press Enter at the end of each code line.
<pre>// Load the picture into the picture box.
</pre>
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Don't worry about indenting the code by pressing the Tab key or using spaces. C# .NET automatically indents code for you.
|}
You're now going to enter the next line of code. This statement, which appears within the if construct, is the line of code that actually displays the picture in the picture box. (If you're itching to know more about graphics, take a look at [ch10.htm#ch10 Hour 10], "Drawing and Printing.")
Enter the following statement:
<pre>picShowPicture.Image = Image.FromFile(ofdSelectPicture.FileName);
</pre>
In addition to displaying the selected picture, your program is going to display the path and filename of the picture in the title bar. When you first created the form, you changed the Text property of the form using the Properties window. To create dynamic applications, properties need to be constantly adjusted at runtime, and this is done using code. Enter the following three lines of code:
<pre>// Show the name of the file in the form's caption.
this.Text = String.Concat("Picture Viewer (" + ofdSelectPicture.FileName + ")");
}
</pre>
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| C# is case sensitive! You must enter all code using the same case as shown in the text.
|}
Checking Your Program Entry Point
All C# programs must contain an entry point. The Main() method is the entry point. In this sample you need to change the reference from Form1 to fclsViewer (this is necessary because we renamed the form earlier) . This statement will invoke the constructor on the form. C++ programmers will be familiar with the Main() entry point method, but they should take notice of the capitalization of Main. We will talk a bit more about the program entry point later in the book.
To update the entry point in this sample, press Ctrl+F to open the Find window, enter Form1, and click Find Next. Close the Find window and replace the text Form1 with fclsViewer. The updated statement should now read:
<pre>Application.Run(new fclsViewer());
</pre>
After you've entered all the code, your editor should look like that shown in [01.htm#ch01fig11 Figure 1.11].
<div style="text-align: center;">Figure 1.11. Make sure your code exactly matches the code shown here.
[[Image:01fig11.jpg|500px|graphics/01fig11.jpg]]
</div>
Terminating a Program Using Code
The last bit of code you'll write will terminate the application when the user clicks the Quit button. To do this, you'll need to access the Click event handler of the btnQuit button. At the top of the code window are two tabs. The current tab has the text fclsViewer.cs. Next to this is a tab that contains the text fclsViewer.cs [Design]. Click this tab now to switch from Code view to the form designer. If you receive an error when you click the tab, the code you entered is incorrect, and you need to edit it to make it the same as I've presented it. After the form designer is displayed, double-click the Quit button to access its Click event.
Enter the following code in the Quit button's Click event handler:
<pre>this.Close();
</pre>
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Close statement closes the current form. When the last loaded form in a program is closed, the application shuts itself down�completely. As you build more robust applications, you'll probably want to execute all kinds of clean-up routines before terminating your application, but for this example, closing the form is all you need to do.
|}
| align="right" | [ch01lev1sec11.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec13.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC13.HTM
| align="right" | [ch01lev1sec12.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec14.htm [[Image:next.gif|41px|Next Section]]]
|}
Running a Project
Your application is now complete. Click the Save All button (it looks like a stack of disks) on the toolbar, and then run your program by pressing F5. You can also run the program by clicking the button on the toolbar that looks like a right-facing triangle and resembles the Play button on a VCR (this button is also found on the Debug menu, and it is called Start). However, learning the keyboard shortcuts will make your development process move along faster. When you run the program, the C# interface changes, and the form you've designed appears floating over the design environment (see [01.htm#ch01fig12 Figure 1.12]).
<div style="text-align: center;">Figure 1.12. When in Run mode, your program executes the same as it would for an end user.
[[Image:01fig12.jpg|400px|graphics/01fig12.jpg]]
</div>
You're now running your program as though it were a standalone application running on another user's machine; what you see is exactly what someone else would see if they ran the program (without the C# design environment in the background, of course). Click the Select Picture button to display the Select Picture dialog box (see [01.htm#ch01fig13 Figure 1.13]). Use the dialog box to locate a picture file. When you've found a file, double-click it, or click once to select it and then click Open. The selected picture is then displayed in the PictureBox control, as shown in [01.htm#ch01fig14 Figure 1.14].
<div style="text-align: center;">Figure 1.13. The OpenFileDialog control handles all the details of browsing for files. Cool, huh?
[[Image:01fig13.jpg|500px|graphics/01fig13.jpg]]
</div>
<div style="text-align: center;">Figure 1.14. C# makes it easy to display pictures with very little work.
[[Image:01fig14.jpg|399px|graphics/01fig14.jpg]]
</div>
| align="right" | [ch01lev1sec12.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec14.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC14.HTM
| align="right" | [ch01lev1sec13.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec15.htm [[Image:next.gif|41px|Next Section]]]
|}
Summary
When you're done playing with the program, click the Quit button and then save your project by clicking Save All on the C# toolbar.
That's it! You've just created a bona fide C# program. You've used the toolbox to build an interface with which users can interact with your program, and you've written code in strategic event handlers to empower your program to do things. These are the basics of application development in C#. Even the most complicated programs are built using this basic approach; you build the interface and add code to make the application do things. Of course, writing code to do things exactly the way you want things done is where the process can get complicated, but you're on your way.
If you take a close look at the organization of the hours in this book, you'll see that I start out by teaching you the C# environment. I then move on to building an interface, and later I teach you all about writing code. This organization is deliberate. You might be a little anxious to jump in and start writing serious code, but writing code is only part of the equation. As you progress through the hours, you'll be building a solid foundation of development skills.
Soon, you'll pay no attention to the man behind the curtain�you'll be that man (or woman)!
| align="right" | [ch01lev1sec13.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec15.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC15.HTM
| align="right" | [ch01lev1sec14.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec16.htm [[Image:next.gif|41px|Next Section]]]
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[01.htm#qad1e5122 Q1:]'''
| Can I show bitmaps of file types other than BMP and JPG?
|-
| align="right" | ''' A1: '''
| Yes. The PictureBox supports the display of images with the extensions BMP, JPG, ICO, EMF, WMF, and GIF. The PictureBox can even save images to a file.
|-
| align="right" | '''[01.htm#qad1e5146 Q2:]'''
| Is it possible to show pictures in other controls?
|-
| align="right" | ''' A2: '''
| The PictureBox is the control to use when you are just displaying images. However, many other controls allow you to display pictures as part of the control. For instance, you can display an image on a Button control by setting the button's Image property to a valid picture.
|}
| align="right" | [ch01lev1sec14.htm [[Image:previous.gif|62px|Previous Section]]] [ch01lev1sec16.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
./ ADD NAME=CH01LEV1SEC16.HTM
| align="right" | [ch01lev1sec15.htm [[Image:previous.gif|62px|Previous Section]]] [ch02.htm [[Image:next.gif|41px|Next Section]]]
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[app01lev1sec1.htm#ch01ans01 1:]'''
| What type of C# project creates a standard Windows program?
|-
| align="right" | '''[app01lev1sec1.htm#ch01ans02 2:]'''
| What window is used to change the attributes (location, size, and so on) of a form or control?
|-
| align="right" | '''[app01lev1sec1.htm#ch01ans03 3:]'''
| How do you access the default event (code) of a control?
|-
| align="right" | '''[app01lev1sec1.htm#ch01ans04 4:]'''
| What property of a PictureBox do you set to display an image?
|-
| align="right" | '''[app01lev1sec1.htm#ch01ans05 5:]'''
| What is the default event for a Button control?
|}
Exercise
# Change your Picture Viewer program so that the user can also locate and select GIF files. (Hint: Change the Filter property of the OpenFileDialog control.)
# Alter the form in your Picture Viewer project so that the buttons are side by side in the lower-right corner of the form, rather than vertically aligned in the upper-right corner.
| align="right" | [ch01lev1sec15.htm [[Image:previous.gif|62px|Previous Section]]] [ch02.htm [[Image:next.gif|41px|Next Section]]]
|}
| align="right" | [01.htm#toppage Top]
|}
rw1whvc3rytkn9pchv33g84gqyjyt2b
User:Foxall/02
2
2133
39238
15819
2026-04-13T06:03:28Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39238
wikitext
text/x-wiki
== Hour 2. Navigating C# ==
The key to expanding your knowledge of C# is to become as comfortable as possible�as quickly as possible�with the C# design environment. Just as a carpenter doesn't think much about hammering a nail into a piece of wood, performing actions such as saving projects, creating new forms, and setting object properties should become second nature to you. The more comfortable you are with the tools of C#, the more you can focus your energies on what you're creating with the tools.
In this hour, you'll learn how to customize your design environment. You'll learn how to move, dock, float, hide, and show design windows, as well as how to customize menus and toolbars; you'll even create a new toolbar from scratch. After you've gotten acquainted with the environment, I'll teach you about projects and the files that they're made of (taking you beyond what was briefly discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour"), and I'll introduce you to the design windows with which you'll work most frequently. Finally, I'll show you how to get help when you're stuck.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec2.htm#ch02lev1sec2 Navigating C#]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec1.htm#ch02lev1sec1 Using the Visual Studio .NET Start Page to open and create projects]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec2.htm#ch02lev3sec1 Showing, hiding, docking, and floating design windows]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec2.htm#ch02lev3sec8 Customizing menus and toolbars]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec3.htm#ch02lev1sec3 Adding controls to a form using the toolbox]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec4.htm#ch02lev1sec4 Viewing and changing object attributes using the Properties window]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec5.htm#ch02lev1sec5 Working with the files that make up a project]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02lev1sec7.htm#ch02lev1sec7 How to get help]
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using the Visual Studio .NET Start Page
By default, the Visual Studio Start Page shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig01 Figure 2.1] is the first thing you see when you start C# (if C# isn't running, start it now). The Visual Studio Start Page is a gateway for performing tasks with C#. From this page, you can open previously edited projects, create new projects, edit your user profile, and browse information provided by Microsoft.
<div style="text-align: center;">Figure 2.1. The Visual Studio Start Page is the default starting point for all Visual Studio programming languages, including C#.
[[Image:02fig01.jpg|500px|graphics/02fig01.jpg]]
</div>
From this page, you can have C# load the last solution you edited, show the Open Project dialog box, show the New Project dialog box, or show an empty design environment. To view or edit the startup options, choose Options from the Tools menu to display the Options dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig02 Figure 2.2]. By default, the General section of the Environment folder is selected, which happens to contain the At Startup option.
<div style="text-align: center;">Figure 2.2. Use the At Startup setting to control the first thing you see when C# starts.
[[Image:02fig02.jpg|500px|graphics/02fig02.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If the Visual Studio Start Page doesn't appear when you start C#, check the settings on the Options form; you may need to change At Startup to Show Start Page.
|}
Creating New Projects
To create new projects, click New Project on the Visual Studio Start Page. This shows the New Project dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig03 Figure 2.3]. The Project Types list varies from machine to machine, depending on which products of the Visual Studio .NET family are installed. Of course, we're interested only in the C# Project types in this book.
<div style="text-align: center;">Figure 2.3. Use the New Project dialog box to create C# projects from scratch.
[[Image:02fig03.jpg|500px|graphics/02fig03.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can create many types of projects with C#, but this book focuses mostly on creating Windows Applications, perhaps the most common of the project types. You will learn about some of the other project types as well, but when you're told to create a new project, make sure the Windows Application template is selected unless you're told otherwise.
|}
When you create a new project, be sure to enter a name for it in the Name text box before clicking OK or double-clicking a project type icon. This ensures that the project is created with the proper path and filenames, eliminating work you would otherwise have to do to change these values later. After you specify a name, you can create the new project either by double-clicking the project type template icon or by clicking an icon once to select it and then clicking OK. After you've performed either of these actions, the New Project dialog box closes and a new project of the selected type is created.
By default, Visual Studio saves all your projects in subfolders of your My Documents folder. The hierarchy used by C# is
<pre>\My Documents\Visual Studio Projects\<Project Name> </pre>
Notice how the name you give your project is used as its folder name. This makes it easy to find the folders and files for any given project and is one reason that you should always give your projects descriptive names. You can use a path other than the default by specifying a specific path on the New Project dialog box, although you probably won't often need to do so.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can create a new project at any time (not just when starting C#) by opening the New submenu on the File menu and choosing Project.
|}
Opening an Existing Project
Over time, you'll open more projects than you create. There are essentially two ways to open projects from the Visual Studio Start Page. If it's one you've recently opened, the project name will appear in a list within a rectangle in the middle of the Start Page (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig01 Figure 2.1]). Because the name displayed for the project is the one given when it was created, this is yet another reason to give your projects descriptive names. Clicking a project name opens the project. I'd venture to guess that you'll use this technique 95% of the time. To open a project for the first time (such as when opening sample projects), click Open Project on the Visual Studio Start Page. Clicking this link displays a standard dialog box that you can use to locate and select a project file.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| As with creating new projects, you can open an existing project at any time, not just when starting C#, by selecting File, Open.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Navigating and Customizing the C# Environment
C# lets you customize many of its interface elements, such as windows and toolbars, enabling you to be more efficient in the work that you do. Create a new Windows Application now (use the New Project dialog box or select File, New) so that you can see and manipulate the design environment. Name this project Environment Tutorial. (This exercise won't create anything reusable, but it will help you learn how to navigate the design environment.) Your screen should look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig04 Figure 2.4].
<div style="text-align: center;">Figure 2.4. This is pretty much how the IDE appears when you first install C#.
[[Image:02fig04.jpg|500px|graphics/02fig04.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Your screen may not look exactly like that shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig04 Figure 2.4], but it'll be close. For example, the Output window won't be visible unless you've built a project. If you completed [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], the window will be visible. By the time you've finished this hour, you'll be able to change the appearance of the design environment to match this figure�or to any configuration you prefer.
|}
Working with Design Windows
Design windows, such as the Properties and Solution Explorer windows shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig04 Figure 2.4], provide functionality for building complex applications. Just as your desk isn't organized exactly like that of your co-workers, your design environment doesn't have to be the same as anyone else's, either.
A design window may be placed into one of four primary states:
* Closed
* Floating
* Docked
* Auto hidden
Showing and Hiding Design Windows
When a design window is closed, it doesn't appear anywhere. There is a difference between being closed and being hidden, as you'll learn shortly. To display a closed or hidden window, choose the corresponding menu item from the View menu. For example, if the Properties window isn't displayed in your design environment, you can display it by choosing Properties Window on the View menu (or press its keyboard shortcut�F4). Whenever you need a design window and can't find it, use the View menu to display it. To close a design window, click its Close button (the button on the right side of the title bar with the X on it), just as you would close an ordinary window.
Floating Design Windows
Floating design windows are visible windows that float over the workspace, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig05 Figure 2.5]. Floating windows are like typical application windows in that you can drag them around and place them anywhere you please, even on other monitors when you're using a multiple-display setup. In addition to moving a floating window, you can also change its size by dragging a border.
<div style="text-align: center;">Figure 2.5. Floating windows appear over the top of the design environment.
[[Image:02fig05.jpg|332px|graphics/02fig05.jpg]]
</div>
Docking Design Windows
Visible windows appear docked by default. A docked window is a window that appears attached to the side, top, or bottom of the work area or to some other window. The Properties window in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig04 Figure 2.4], for example, is docked to the right side of the design environment. To make a floating window a docked window, drag the title bar of the window toward the edge of the design environment to which you want to dock the window. As you drag the window, you'll drag a rectangle that represents the outline of the window. When you approach an edge of the design environment, the rectangle will change shape and "stick" in a docked position. If you release the mouse while the rectangle appears this way, the window will be docked. Although this is hard to explain, it's very easy to do.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can size a docked window by dragging its edge opposite the side that's docked. If two windows are docked to the same edge, dragging the border between them enlarges one while shrinking the other.
|}
To try this, you'll need to float a window that's already docked. To float a window, you "tear" the window away from the docked edge by dragging the title bar of the docked window away from the edge to which it is docked. Note that this technique won't work if a window is set to Auto Hide (which is explained next). Try docking and floating windows now by following these steps:
# Ensure that the Properties window is currently displayed (if it's not, show it using the View menu). Make sure the Properties window isn't set to Auto Hide by right-clicking its title bar and deselecting Auto Hide (if it's selected) from the shortcut menu, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig06 Figure 2.6].
<div style="text-align: center;">Figure 2.6. You can't float a window that's set to Auto Hide.
</div>
# Drag the title bar of the Properties window away from the docked edge. When the rectangle representing the border of the window changes shape, release the mouse button. The Properties window should now appear floating.
# Dock the window once more by dragging the title bar toward the right edge of the design environment. Again, release the mouse button when the rectangle changes shape.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| If you don't want a floating window to dock, regardless of where you drag it to, right-click the title bar of the window and choose Floating from the context menu. To allow the window to be docked again, right-click the title bar and choose Dockable.
|}
Auto Hiding Design Windows
A feature of C# design environment is the capability to auto hide windows. Although you might find this a bit disconcerting at first, after you get the hang of things, this is a very productive way in which to work because your workspace is freed up, yet design windows are available by simply moving the mouse. Windows that are set to Auto Hide are always docked; you can't set a floating window to Auto Hide. When a window auto hides, it appears as a tab on the edge to which it's docked�much like minimized applications are placed in the Windows taskbar.
Look at the left edge of the design environment in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig06 Figure 2.6]. Notice the two tabs on the left side of the IDE. One tab has a picture of two computers, and the other is labeled Toolbox. These tabs represent auto-hidden windows. To display an auto-hidden window, move the pointer over the tab representing the window. When you move the pointer over a tab, C# displays the design window so that you can use its features. When you move the pointer away from the window, the window automatically hides itself�hence the name. To make any window hide itself automatically, right-click its title bar and select Auto Hide from its shortcut menu. Alternatively, you can click the little picture of a pushpin appearing in the title bar next to the Close button to toggle the window's Auto Hide state.
Performing Advanced Window Placement
The techniques discussed in this section so far are basic methods for customizing your design environment. Things can actually get a bit more complicated if you want them to. Such complication presents itself primarily as the capability to create tabbed floating windows like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig05 Figure 2.5]. Notice that at the bottom of the floating window is a set of tabs. Clicking a tab shows its corresponding design window, replacing the window currently displayed. These tabs are created much the same way in which you dock and undock windows�by dragging and dropping. For instance, to make the Solution Explorer window a floating window of its own, you would drag the Solution Explorer window tab away from the floating window. As you do so, a rectangle appears, showing you the outline of the new window. Where you release the rectangle determines whether you dock the design window you're dragging or whether you make the window floating. To make a design window a new tab of an already floating window, drag its title bar and drop it in the title bar of a window that is already floating.
In addition to creating tabbed floating windows, you can dock two floating windows together. To do this, drag the title bar of one window over another window (other than over the title bar) until the shape changes, and then release the mouse. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig07 Figure 2.7] shows two floating windows that are docked to one another and a third window that is floating by itself.
<div style="text-align: center;">Figure 2.7. Floating, docked, floating and docked�the possibilities are numerous!
[[Image:02fig07.jpg|500px|graphics/02fig07.jpg]]
</div>
Using all the techniques discussed here, you can tailor the appearance of your design environment in all sorts of ways. There is no one best configuration. You'll find that different configurations work better for different projects and in different stages of development. For instance, when I'm designing the interface of a form, I want the toolbox to stay visible but out of my way, so I tend to make it float, or I turn off its Auto Hide property and leave it docked to the left edge of the design environment. However, after the majority of the interface elements have been added to a form, I want to focus on code. Then I dock the toolbox and make it auto hide itself; it's there when I need it, but it's out of the way when I don't. Don't be afraid to experiment with your design windows, and don't hesitate to modify them to suit your changing needs.
Working with Toolbars
Toolbars are the mainstay for performing functions quickly in almost all Windows programs (you'll probably want to add them to your own programs at some point, and [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09.htm#ch09 Hour 9], "Adding Menus and Toolbars to Forms," shows you how). Every toolbar has a corresponding menu item, and buttons on toolbars are essentially shortcuts to their corresponding menu items. To maximize your efficiency when developing with C#, you should become familiar with the available toolbars. As your C# skills progress, you can customize existing toolbars and even create your own toolbars to more closely fit the way you work.
Showing and Hiding Toolbars
C# includes a number of built-in toolbars for you to use when creating projects. Two toolbars are visible in most of the figures shown so far in this hour. The one on the top is the Standard toolbar, which you'll probably want displayed all the time. The second toolbar is the Layout toolbar, which provides useful tools for building forms.
The previous edition of Visual Studio had about 5 toolbars; Visual Studio .NET, on the other hand, has more than 20 toolbars! The toolbars you'll use most often as a C# developer are the Standard, Text Editor, and Debug toolbars. Therefore, this hour discusses each of these. In addition to these predefined toolbars, you can create your own custom toolbars to contain any functions you think necessary, which you'll learn how to do later in this hour.
To show or hide a toolbar, choose View, Toolbars to display a list of available toolbars. Toolbars currently displayed appear selected (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig08 Figure 2.8]). Click a toolbar name to toggle its visible state.
<div style="text-align: center;">Figure 2.8. Hide or show toolbars to make your work more efficient.
[[Image:02fig08.jpg|500px|graphics/02fig08.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| A quick way to access the list of toolbars is to right-click any visible toolbar.
|}
Docking and Resizing Toolbars
Just as you can dock and undock C#'s design windows, you can dock and undock the toolbars. Unlike the design windows, however, C#'s toolbars don't have a title bar that you can click and drag when they're in a docked state. Instead, each docked toolbar has a drag handle (a set of horizontal lines along its left edge). To float (undock) a toolbar, click and drag the grab handle away from the docked edge. After a toolbar is floating, it has a title bar. To dock a floating toolbar, click and drag its title bar to the edge of the design environment to which you want it docked. This is the same technique you use to dock design windows.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| A shortcut for docking a toolbar is to double-click its title bar.
|}
Although you can't change the size of a docked toolbar, you can resize a floating toolbar (a floating toolbar behaves like any other normal window). To resize a floating toolbar, move the pointer over the edge you want to stretch and then click and drag to the border to change the size of the toolbar.
Customizing Toolbars
As your experience with C# grows, you'll find that you use certain functions repeatedly. To increase your productivity, you can customize any of C#'s toolbars, and you can create your own from scratch. You can even customize the C# menu and create your own menus. To customize toolbars and menus, you use the Customize dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig09 Figure 2.9], which is accessed by choosing View, Toolbars, Customize.
<div style="text-align: center;">Figure 2.9. Create new toolbars or customize existing ones to fit the way you work.
[[Image:02fig09.jpg|383px|graphics/02fig09.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I strongly suggest that you don't modify the existing C# toolbars. Instead, create new toolbars. If you modify the predefined toolbars, you may find that you've removed tools that I refer to in later examples. If you do happen to change a built-in toolbar, you can reset it to its original state by selecting it in the Customize dialog box and clicking Reset.
|}
The Toolbars tab on the Customize dialog box shows you a list of all the existing toolbars and menus. The toolbars and menus currently visible have a check mark next to them. To toggle a toolbar or menu between visible and hidden, click its check box.
Creating a New Toolbar
You're now going to create a new toolbar to get a feel for how toolbar customization works. Your toolbar will contain only a single button, which will be used to call C#'s Help program.
To create your new toolbar, follow these steps:
# From the Toolbars tab of the Customize dialog box, click New.
# Enter My Help as the name for your new toolbar when prompted.
# Click OK to create the new toolbar.
After you've entered a name for your toolbar and clicked OK, your new toolbar appears, floating on the screen�most likely somewhere outside the Customize dialog box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig10 Figure 2.10]). Dock your toolbar now by double-clicking the blank area on the toolbar (the area where a button would ordinarily appear). Your screen should look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig11 Figure 2.11].
<div style="text-align: center;">Figure 2.10. New toolbars are pretty tiny; they have no buttons on them.
[[Image:02fig10.jpg|500px|graphics/02fig10.jpg]]
</div>
<div style="text-align: center;">Figure 2.11. It's easier to customize toolbars when they're docked.
[[Image:02fig11.jpg|500px|graphics/02fig11.jpg]]
</div>
Adding Buttons to a Toolbar
Now that you have an empty toolbar, the next step is to add the desired command buttons to it. Click the Commands tab of the Customize dialog box to display all the available commands.
The Commands tab contains the following:
* A list of command categories
* A list of the commands for the selected command category
The Categories list shows all available command categories, such as File and Edit functions. When you select a category, all the available commands for that category are shown in the list on the right.
You're going to add a toolbar button that appears as a Help icon and that actually displays Help when clicked.
To add the command button to your toolbar, follow these steps:
# Locate and select the category Help. All the available commands for the Help category will appear in the list on the right.
# From the Commands list, click and drag the Contents command to your custom toolbar. As you drag, the pointer changes to an arrow pointing to a small gray box. At the lower-right corner of the pointer is a little hollow box with an x in it. This indicates that the location over which the pointer is positioned is not a valid location to drop the command.
# As you drag the command over your toolbar (or any other toolbar for that matter), the x in the little box will change to a plus sign (+), indicating that the command can be placed in the current location. In addition, an insertion point (often called an I-beam because that's what it looks like) appears on the toolbar to indicate where the button would be placed if the command were dropped at that spot. When an I-beam appears on your toolbar and the pointer box contains a plus sign, release the mouse button. Your toolbar will now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig12 Figure 2.12].
<div style="text-align: center;">Figure 2.12. Building toolbars is a simple matter of dragging and dropping commands.
[[Image:02fig12.jpg|500px|graphics/02fig12.jpg]]
</div>
You can alter any button on a toolbar by right-clicking the button to access its shortcut menu and then choosing Change Button Image. Feel free to experiment with changing the image of the button on your custom toolbar, but be sure to leave the buttons on the built-in toolbars as they are.
To remove a button from a toolbar, drag the button to remove it from the toolbar and drop it somewhere other than on the same toolbar. If you drop the button onto another toolbar, the button is removed from the original toolbar and placed on the toolbar on which you dropped it. If you drop the button in a location where no toolbar exists, the button is simply removed from the toolbar.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can drag command buttons only in Customize mode. If you attempt to drag an item during normal operation, you'll simply click the button.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Although these techniques are illustrated using toolbars, they apply to menus, as well.
|}
Moving Buttons on a Menu or Toolbar
You should always attempt to group command buttons logically. For example, the Edit functions are all grouped together on the Standard toolbar, as are the File operations. A separator (space) is used to separate groups. To create a separator space, right-click the button that starts a new group and choose Begin a Group from the button's shortcut menu.
You probably won't get the exact groupings you want when you first add commands to a toolbar, but that's not a problem because you can change the position of a button at any time. To move a button on a toolbar, drag the button and drop it in the desired location (remember, you have to be in Customize mode to do this). To move a button from one toolbar to another, drag the button from its toolbar and drop it at the preferred location on the desired toolbar.
Now that your toolbar is complete (Hey, I never said it'd be fancy), click Close on the Customize dialog box to exit Customize mode. All toolbars, including the one you just created, are no longer in Customize mode and they can't be modified. Click the button you placed on your new toolbar and C#'s Help will appear.
Because your custom toolbar really doesn't do much, hide it now to save screen real estate by right-clicking any toolbar to display the Toolbar shortcut menu and then deselecting My Help.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| As you work your way through this book, you should always have the Standard toolbar and menu bar displayed on your screen.
|}
Typically, you should customize toolbars only after you're very familiar with the available functions and only after you know which functions you use most often. I recommend that you refrain from modifying any of the predefined toolbars until you're quite familiar with C#. As you become more comfortable with C#, you can customize the toolbars to make your project work area as efficient as possible.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Adding Controls to a Form Using the Toolbox
The toolbox is used to place controls, such as the common text box and list box, onto a form. The default toolbox you see when you first run C# is shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig13 Figure 2.13]. The buttons labeled Data, Components, Windows Forms, and so on are actually tabs, although they don't look like standard tabs. Clicking any of these tabs causes a related set of controls to appear. The default tab is the Windows Forms tab, and it contains many great controls you can place on Windows forms (the forms used to build Windows applications, in contrast to Web applications). All the controls that appear by default on the tabs are included with C#, and these controls are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7], "Working with Traditional Controls," and [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08.htm#ch08 Hour 8], "Advanced Controls." You'll learn how to add other controls to your toolbox as well.
<div style="text-align: center;">Figure 2.13. The standard toolbox contains many useful controls you can use to build robust user interfaces.
[[Image:02fig13.jpg|500px|graphics/02fig13.jpg]]
</div>
You can add a control to a form in one of three ways:
* In the toolbox, click the tool that you want to place on a form, and then click and drag on the form where you want the control placed (essentially, you're drawing the border of the control). The location at which you start dragging is used for the upper-left corner of the control, and the lower-right corner is the point at which you release the mouse button and stop dragging.
* Double-click the desired control in the toolbox. When you double-click a control in the toolbox, a new control of the selected type is placed in the upper-left corner of the form. The control's height and width are set to the default height and width of the selected control type.
* Drag a control from the toolbox and drop it somewhere on a form.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| If you prefer to draw controls on your forms by clicking and dragging, I strongly suggest that you dock the toolbox to the right or bottom edge of the design environment or float it; the toolbar tends to interfere with drawing controls when it's docked to the left edge, because it obscures part of the form.
|}
The very first item on the Windows Forms tab, titled Pointer, isn't actually a control. When the pointer item is selected, the design environment is placed in a select mode rather than in a mode to create a new control. With the pointer item selected, you can select a control (by clicking it) to display all its properties in the Properties window; this is the default behavior.
Setting Object Properties Using the Properties Window
When developing the interface of a project, you'll spend a lot of time viewing and setting object properties using the Properties window (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig14 Figure 2.14]). The Properties window contains four items:
* An object drop-down list
* A list of properties
* A set of tool buttons used to change the appearance of the properties grid
* A section showing a description of the selected property
<div style="text-align: center;">Figure 2.14. Use the Properties window to view and change properties of forms and controls.
[[Image:02fig14.jpg|500px|graphics/02fig14.jpg]]
</div>
Selecting an Object and Viewing Its Properties
The drop-down list at the top of the Properties window contains the name of the form with which you're currently working and all the controls (objects) on the form. To view the properties of a control, select it from the drop-down list or click the control on the form. You must have the pointer item selected in the toolbox to select an object by clicking it.
Viewing and Changing Properties
The first two buttons in the Properties window (Categorized and Alphabetic), enable you to select the format in which you view properties. When you select the Alphabetic button, the selected object's properties are listed in the Properties window in alphabetical order. When you click the Categorized button, all the selected object's properties are displayed by category. For example, the Appearance category contains properties such as BackColor and BorderStyle. When working with properties, select the view you're most comfortable with and feel free to switch back and forth between the views.
The Properties pane of the Properties window is used to view and set the properties of a selected object. You can set a property in one of the following ways:
* Type in a value
* Select a value from a drop-down list
* Click a Build button for property-specific options
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Many properties can be changed by more than one of these methods.
|}
To better understand how changing properties works, follow these steps:
# Start by creating a new Windows Application project. Name this project Changing Properties.
# Add a new text box to a form by double-clicking the TextBox tool in the toolbox. You're now going to change a few properties of the new text box.
# Select the Name property in the Properties window by clicking it, and then type in a name for the text box�call it txtComments.
# Click the BorderStyle property and try to type in the word Big�you can't; the BorderStyle property supports only selecting values from a list. You can type a value that exists in the list, however. When you selected the BorderStyle property, a drop-down arrow appeared in the value column. Click this arrow now to display a list of the values that the BorderStyle property accepts. Select FixedSingle and notice how the appearance of the text box changes. To make the text box appear three dimensional again, open the drop-down list and select Fixed3D.
# Select the BackColor property, type in some text, and press the Tab key to commit your entry. C# displays an Invalid Property Value error. This happened because, although you can type in text, you're restricted to entering specific values (in the case of BackColor, the value must be a number within a specific range or a named color). Click the drop-down arrow of the BackColor property and select a color from the drop-down list. (Selecting colors using the Color Palette is discussed later in this hour, and detailed information on using colors is provided in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10], "Drawing and Printing.")
# Select the Font property. Notice that a Build button appears (a small button with three dots on it). When you click the Build button, a dialog box specific to the property you've selected appears. In this instance, a dialog box that allows you to manipulate the font of the text box appears (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig15 Figure 2.15]). Different properties display different dialog boxes when you click their Build buttons.
<div style="text-align: center;">Figure 2.15. The Font dialog box gives you complete authority over the font of a control.
[[Image:02fig15.jpg|437px|graphics/02fig15.jpg]]
</div>
By clicking a property in the Properties window, you can easily tell the type of input the property requires.
Working with Color Properties
Properties that deal with colors, such as BackColor and ForeColor, are unique in the way in which they accept values, yet all color-related properties behave the same way. In C#, all colors are expressed as a set of three numbers, each number having a value from 0 to 255. The set of numbers represents the Red, Green, and Blue (RGB) components of the color, respectively.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The value 0,255,0, for instance, represents pure green, whereas the values 0,0,0 represent black and 255,255,255 represents white. (See [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10] for more information on the specifics of working with color.)
|}
A color rectangle is displayed for each color property in the Properties window; this color is the selected color for the property. Text is displayed next to the colored rectangle. This text is either the name of a color or a set of RGB values that defines the color. Clicking in a color property causes a drop-down arrow to appear, but the drop-down you get by clicking the arrow isn't a typical drop-down list. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig16 Figure 2.16] shows what the drop-down list for a color property looks like.
<div style="text-align: center;">Figure 2.16. The color drop-down list enables you to select from three sets of colors.
[[Image:02fig16.jpg|204px|graphics/02fig16.jpg]]
</div>
The color drop-down list is composed of three tabs: Custom, Web, and System. Most color properties use a system color by default. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10] goes into great detail on system colors, so I only want to mention here that system colors vary from computer to computer; they are the colors determined by the user when he or she right-clicks the desktop and chooses Properties from the desktop's shortcut menu. Use a system color when you want a color to be one of the user's selected system colors. When a color property is set to a system color, the name of the color appears in the property sheet.
The Custom tab shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig17 Figure 2.17] is used to specify a specific color, regardless of the user's system color settings; changes to system colors have no effect on the property. The most common colors appear on the palette of the Custom tab, but you can specify any color you desire.
<div style="text-align: center;">Figure 2.17. The Custom tab of the color drop-down list lets you specify any color imaginable.
[[Image:02fig17.jpg|204px|graphics/02fig17.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The colors visible in the various palettes are limited by the number of colors that can be produced by your video card. If your video card doesn't support enough colors, some will appear dithered, which means they will appear as dots of colors rather than as a true, solid color.
|}
The bottom two rows in the Custom color palette are used to mix your own colors. To assign a color to an empty color slot, right-click a slot in one of the two rows to access the Define Color dialog box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig18 Figure 2.18]). Use the controls on the Define Color dialog box to create the color you desire, and then click Add Color. The new color appears on the color palette in the slot you selected, and it is automatically assigned to the current property.
<div style="text-align: center;">Figure 2.18. The Define Color dialog box lets you create your own colors.
[[Image:02fig18.jpg|275px|graphics/02fig18.jpg]]
</div>
The Web tab is used to pick colors from a list of named colors for building Web pages.
Viewing Property Descriptions
It's not always immediately apparent just exactly what a property is or does�especially for new users of Visual Studio. The Description section at the bottom of the Properties window shows a simple description of the selected property (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig14 Figure 2.14]). To view a description, simply click a property or value area of a property.
You can hide or show the Description section of the Properties window at any time by right-clicking anywhere within the Properties window (other than in the value column or on the title bar) to display the Properties window shortcut menu and choosing Description. Each time you do this, you toggle the Description section between visible and hidden. To change the size of the Description box, click and drag the border between it and the Properties pane.
Managing Projects
Before you can effectively create an interface and write code, you need to understand what makes up a C# project and how to add and remove various components from within your own projects. In this section, you'll learn about the Solution Explorer window and how it's used to manage project files. You'll also learn specifics about projects and project files, as well as how to change a project's properties.
Managing Project Files with the Solution Explorer
As you develop projects, they'll become more and more complex, often containing many objects such as forms and modules. Each object is defined by one or more files. In addition, you can build complex solutions composed of more than one project. The Solution Explorer window shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig19 Figure 2.19] is the tool for managing all the files in a simple or complex solution. Using the Solution Explorer, you can add, rename, and remove project files, as well as select objects to view their properties. If the Solution Explorer window isn't visible on your screen, show it now by choosing Solution Explorer from the View menu.
<div style="text-align: center;">Figure 2.19. Use the Solution Explorer window to manage all the files that make up a project.
[[Image:02fig19.jpg|500px|graphics/02fig19.jpg]]
</div>
To better understand the Solution Explorer window, follow these steps:
# Locate the Picture Viewer program you created in the Quick Tour by choosing File, Open, and then clicking Project.
# Open the Picture Viewer project. The file you need to select is located in the Picture Viewer folder that C# created when the project was constructed. The file has the extension .sln (for solution). If you're asked whether you want to save the current project, choose No.
# Select the Picture Viewer project item in the Solution Explorer. When you do, a button becomes visible toward the top of the window. This button has a picture of pieces of paper and has the ToolTip Show All Files (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig20 Figure 2.20]). Click this button and the Solution Explorer displays all files in the project.
<div style="text-align: center;">Figure 2.20. Notice that the form you defined appears as two files in the Solution Explorer.
[[Image:02fig20.jpg|500px|graphics/02fig20.jpg]]
</div>
Your design environment should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig20 Figure 2.20]. If your screen looks much different from the one in this figure, use the techniques you've learned in this hour to change your design environment so that it's similar to the one shown here. Be sure to widen the Solution Explorer window so that you can read all the text it contains.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Some forms and other objects may be composed of more than one file. By default, C# hides project files that you don't directly manipulate. Click the plus sign (+) next to the form item and you'll see a sub item titled Form1.resx. You'll learn about these additional files in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05.htm#ch05 Hour 5], "Building Forms�Part I." For now, click the Show All Files button again to hide these related files.
|}
You can view any object listed within the Solution Explorer using the object's default viewer by double-clicking the object. Each object has a default viewer but may actually have more than one viewer. For instance, a form has a Form Design view as well as a Code view. By default, double-clicking a form in the Solution Explorer displays the form in Form Design view, where you can manipulate the form's interface.
You've already learned one way to access the code behind a form�double-click an object to access its default event handler. You'll frequently need to get to the code of a form without adding a new event handler. One way to do this is to use the Solution Explorer. When a form is selected in the Solution Explorer, buttons are visible at the top of the Solution Explorer window that allow you to display the code editor or the form designer, respectively.
You'll use the Solution Explorer window so often that you'll probably want to dock it to an edge and set it to Auto Hide, or perhaps keep it visible all the time. The Solution Explorer window is one of the easiest to get the hang of in C#; navigating the Solution Explorer window will be second nature to you before you know it.
Working with Solutions
In truth, the Solution Explorer window is the evolution of the Project Explorer window from versions of Visual Studio prior to .NET, and the two are similar in many ways. Understanding solutions is easier to do when you understand projects.
A project is what you create with C#. Often, the words project and program are used interchangeably; this isn't much of a problem if you understand the important distinctions. A project is the set of source files that make up a program or component, whereas a program is the binary file that you build by compiling source files into something such as a Windows executable file (.exe). Projects always consist of a main project file and may be made up of any number of other files, such as form files, module files, or class module files. The main project file stores information about the project�all the files that make up the project, for example�as well as properties that define aspects of a project, such as the parameters to use when the project is compiled into a program.
What then, is a solution? As your abilities grow and your applications increase in complexity, you'll find that to accomplish your development goals, you'll have to build multiple projects that work harmoniously. For instance, you might build a custom user control such as a custom data grid that you use within other projects you design, or you may isolate the business rules of a complex application into separate components to run on isolated servers. All the projects used to accomplish those goals are collectively called a solution. Therefore, a solution (at its most basic level) is really nothing more than a grouping of projects.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| You should group projects into a single solution only when the projects relate to one another. If you have a number of projects that you're working on, but each of them is autonomous, work with each project in a separate solution.
|}
Understanding Project Components
As I stated earlier, a project always consists of a main project file, and it may consist of one or more secondary files, such as files that make up forms or code modules. As you create and save objects within your project, one or more corresponding files are created and saved on your hard drive. All files that are created for C# source objects have the extension .cs, designating that they define C# objects. Make sure that you save your objects with understandable names, or things might get confusing as the size of your project grows.
All the files that make up a project are text files. Some objects, however, need to store binary information, such as a picture, for a form's BackgroundImage property. Binary data is stored in an XML file (which is still a text file). Suppose you had a form with an icon on it. You'd have a text file defining the form (its size, the controls on it, and the code behind it), and an associated resource file with the same name as the form file but with the extension .resx. This second file would be in XML format and would contain all the binary data needed to create the form.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you want to see what the source file of a form file looks like, use Notepad to open a form file on your computer. Don't save any changes to the file, however, or it may never work again.
|}
The following is a list of some of the components you may use in your projects:
* Forms Forms are the visual windows that make up the interface of your application. Forms are defined using a special type of module.
* Class Modules Class modules are a special type of module that enable you to create object-oriented applications. Throughout the course of this book, you're learning how to program using an object-oriented language, but you're mostly learning how to use objects supplied by C#. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects with Classes," you'll learn how to use class modules to create your own objects. Forms are derived from a special type of class module.
* User Controls User controls (formerly ActiveX controls, which are formerly OLE controls) are controls that can be used on the forms of other projects. For example, you could create a User control with a calendar interface for a contact manager. Creating user controls requires the skill of an experienced programmer; therefore, I won't be covering them in this book.
Setting Project Properties
C# projects have properties, just as other objects do, such as forms and controls. Projects have lots of properties, many of them relating to advanced functionality that I won't be covering in this book. However, you need to be aware of how to access project properties and how to change some of the more commonly used properties.
To access the properties for a project, right-click the project in the Solution Explorer window and choose Properties from the shortcut menu. Do this now.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In earlier versions of Visual Studio, you accessed the project properties via the Project menu. You can still do this, but you must have the project selected in the Solution Explorer, or the Properties menu won't appear on the Project menu. If you don't remember this, you could spend a lot of time trying to find the properties�I sure did.
|}
The Tree View control on the left side of the dialog box is used to display a property page (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig21 Figure 2.21]). When you first open the dialog box, the General page is visible. On this page, the setting you'll need to worry about most is the Startup Object property. The Startup Object setting determines the name of the class that contains the Main() method that you want called on program startup. The (Not Set) option, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig21 Figure 2.21], is valid if only one Main() method exists in your application.
<div style="text-align: center;">Figure 2.21. Project properties let you tailor aspects of the project as a whole.
[[Image:02fig21.jpg|500px|graphics/02fig21.jpg]]
</div>
The Output Type option determines the type of compiled component defined by this source project. When you create a new project, you select the type of project to create (such as Windows Application), so this field is always filled in. At times, you might have to change this setting after the project has been created, and this is the place to do so.
Notice that the project folder, project filename, and output name are displayed on this page as well. If you work with a lot of projects, you may find this information valuable, and this is certainly the easiest spot to obtain it.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The output name determines the filename created when you build a distributable component. Distributing applications is discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22.htm#ch22 Hour 22].
|}
As you work through the hours in this book, I'll refer to the Project Properties dialog box as necessary, explaining pages and items in context with other material.
Adding and Removing Project Files
When you first start C# and create a new Windows Application project, C# creates the project with a single form. You're not limited to having one form in a project, however; you can create new forms or add existing forms to your project at will. You can also create and add code files and classes, as well as other types of objects.
You can add a new or existing object to your project in one of three ways:
* Choose the appropriate menu item from the Project menu.
* Click the small drop-down arrow that is part of the Add New Item button on the Standard toolbar, and then choose the object type from the drop-down list that is displayed (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig22 Figure 2.22]).
* Right-click the project name in the Solution Explorer window, and then choose Add from the shortcut menu to access a submenu from which you can select object types.
When you select Add ObjectType from any of these menus, a dialog box appears, showing you the objects that can be added to the project. Your chosen item is selected by default (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig23 Figure 2.23]). Simply name the object and click Open to create a new object of the selected type. To create an object of a different type, click the type to select it, name it, and then click Open.
<div style="text-align: center;">Figure 2.23. Regardless of the menu option you select, you can add any type of object you want using this dialog box.
[[Image:02fig23.jpg|500px|graphics/02fig23.jpg]]
</div>
Adding new forms and modules to your project is easy, and you can add as many as you like. You'll come to rely more heavily on the Solution Explorer to manage all the objects in the project as the project becomes more complex.
Although it won't happen as often as adding project files, you may sometimes need to remove an object from a project. Removing objects from your project is even easier than adding them. To remove an object, simply right-click the object in the Solution Explorer window and select Exclude from Project. This removes the object from the file but does not delete the source file from the disk. Selecting Delete, on the other hand, removes the file from the project and deletes it from the disk. Don't select Delete unless you want to totally destroy the file and you're sure that you'll never need it again in the future.
Getting Help
Although C# was designed to be as intuitive as possible, you'll find that you occasionally need assistance in performing a task. It doesn't matter how much you know, C# is so complex and contains so many features that you'll have to use Help sometimes. This is particularly true when writing C# code; you won't always remember the command you need or the syntax of the command. Fortunately, C# includes a comprehensive Help feature.
To access Help from within the design environment, press F1. Generally speaking, when you press F1, C# shows you a help topic directly related to what you're doing. This is known as context-sensitive help, and when it works, it works well. For example, you can display help for any C# syntax or keyword (functions, objects, methods, properties, and so on) when writing C# code by typing the word into the code editor, positioning the cursor anywhere within the word (including before the first letter or after the last), and pressing F1. You can also get to help from the Help menu on the menu bar.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| C#'s Help won't be displayed if your program is in Run mode when you press F1. Instead, the help for your application will appear�if you've created Help.
|}
Help displays topics directly within the design environment instead of in a separate window. This is a new feature of .NET. Personally, I think this method is considerably inferior to the old style of Visual Studio having Help float above the design environment. When Help is displayed within the design environment, you can't necessarily see the code, form, or other object with which you're working. To make Help float above the design environment, choose Options from the Tools menu to display the Options dialog box, click Help in the Tree view on the left, and select External Help.
C# includes a Help feature called Dynamic Help. To display the Dynamic Help window, choose Dynamic Help from the Help menu. The Dynamic Help window shows Help links related to what it is you're working on (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#ch02fig24 Figure 2.24]). For instance, if you select a form, the contents of the Dynamic Help window show you Help links related to forms. If you click a text box, the contents of the Dynamic Help window adjust to show you Help links related to text boxes. This is an interesting feature, and you may find it valuable.
<div style="text-align: center;">
[[Image:02fig24.jpg|500px|graphics/02fig24.jpg]]
</div>
Summary
In this hour, you learned how to use the Visual Studio Start page�your gateway to C#. You learned how to create new projects and how to open existing projects. The C# environment is your workspace, toolbox, and so much more. You learned how to navigate the environment, including how to work with design windows (hide, show, dock, and float).
You'll use toolbars constantly, and now you know how to modify them to suit your specific needs. You learned how to create new toolbars and how to modify existing toolbars. This is an important skill that shouldn't be overlooked.
C# has many different design windows, and in this hour, you began learning about some of them in detail. You learned how to get and set properties using the Properties window, how to manage projects using the Solution Explorer, and how to add controls to a form using the toolbox. You'll use these skills often, so it's important to get familiar with them right away. Finally, you learned how to access C#'s Help feature, which I guarantee you will find very important as you learn to use C#.
C# is a vast and powerful development tool. Don't expect to become an expert overnight; this is simply impossible. However, by learning the tools and techniques presented in this hour, you've begun your journey. Remember, you'll use most of what you learned in this hour each and every time you use C#. Get proficient with these basics and you'll be building cool programs in no time!
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#qad1e9108 Q1:]'''
| How can I easily get more information about a property when the Description section of the Properties window just doesn't cut it?
|-
| align="right" | ''' A1: '''
| Click the property in question to select it, and then press F1; context-sensitive help applies to properties in the Properties window, as well.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/02.htm#qad1e9118 Q2:]'''
| I find that I need to see a lot of design windows at one time, but I can't find that "magic" layout. Any suggestions?
|-
| align="right" | ''' A2: '''
| Run at a higher resolution. Personally, I won't develop in less than 1024x768. As a matter of fact, all my development machines have two displays, both running at this resolution. You'll find that any investment you make in having more screen real estate will pay you big dividends.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans01 1:]'''
| How can you make the Visual Studio Start Page appear at startup if this feature has been disabled?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans02 2:]'''
| Unless instructed otherwise, you are to create what type of project when building examples in this book?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans03 3:]'''
| To make a docked design window appear when you hover over its tab and disappear when you move the mouse away from it, you change what setting of the window?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans04 4:]'''
| How do you access the Toolbars menu?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans05 5:]'''
| What design window do you use to add controls to a form?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans06 6:]'''
| What design window is used to change the attributes of an object?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans07 7:]'''
| To modify the properties of a project, you must select the project in what design window?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec2.htm#ch02ans08 8:]'''
| Which Help feature adjusts the links it displays to match what it is you are doing?
|}
Exercises
# Create a custom toolbar that contains Save All, Start, and Stop Debugging�three buttons you'll use a lot throughout this book.
# Use the Custom Color dialog box to create a color of your choice, and then assign the color to the BackColor property of a form.
gpm12b4ow6vg945k361v9fwa9gxooin
User:Foxall/03
2
2134
39239
7174
2026-04-13T06:03:28Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39239
wikitext
text/x-wiki
== Hour 3. Understanding Objects and Collections ==
So far, you've gotten an introduction to programming in C# by building a Picture Viewer project. You spent the previous hour digging into the IDE and learning skills critical to your success with C#. In this hour, you're going to start learning about some important programming concepts, namely objects.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The term object, as it relates to programming, may have been new to you prior to this book. The more you work with C#, the more you'll hear about objects. C# is a true object-oriented language. This hour isn't going to discuss object-oriented programming in any detail, because object-oriented programming is a very complex subject and is well beyond the scope of this book. Instead, you'll learn about objects in a more general sense. Everything you use in C# is an object, so understanding this material is critical to your success with C#. Forms are objects, for example, as are the controls you place on a form. Pretty much every element of a C# project is an object and belongs to a collection of objects. All objects have attributes (called properties), most have methods, and many have events. Whether creating simple applications or building large-scale enterprise solutions, you must understand what an object is and how it works. In this hour, you'll learn what makes an object an object, and you'll learn about collections.
|}
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec1.htm#ch03lev1sec1 Understanding objects]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec2.htm#ch03lev2sec1 Getting and setting properties]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec3.htm#ch03lev2sec3 Triggering methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec3.htm#ch03lev2sec4 Understanding method dynamism]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec4.htm#ch03lev2sec6 Writing object-based code]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec5.htm#ch03lev1sec5 Understanding collections]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec6.htm#ch03lev1sec6 Using the Object Browser]
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you've listened to the programming press at all, you've probably heard the term object oriented, and perhaps words such as polymorphism, encapsulation, and inheritance. In truth, these object-oriented features of C# are very exciting, but they're far beyond [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03 Hour 3]. You'll learn a little about object-oriented programming in this book, but if you're really interested in taking your programming skills to the next level, you should buy a book dedicated to the subject after you've completed this one.
|}
----
=== Understanding Objects ===
Object-oriented programming has been a technical buzzword for quite some time. Almost everywhere you look�the Web, publications, books�you read about objects. What exactly is an object? Strictly speaking, it is a programming structure that encapsulates data and functionality as a single unit and for which the only public access is through the programming structure's interfaces (properties, methods, and events). In reality, the answer to this question can be somewhat ambiguous because there are so many types of objects�and the number grows almost daily. However, all objects share specific characteristics, such as properties and methods.
The most commonly used objects in Windows applications are the form object and the control object. Earlier hours introduced you to working with forms and controls and even showed you how to set form and control properties. In your Picture Viewer project from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], for instance, you added a picture box and two buttons to a form. Both the PictureBox and the Button control are control objects, but each is a specific type of control object. Another, less-technical example uses pets. Dogs and cats are definitely different entities (objects), but they both fit into the category of Pet objects. Similarly, text boxes and buttons are each a unique type of object, but they're both considered a control object. This small distinction is important.
Understanding Properties
All objects have attributes used to specify and return the state of the object. These attributes are properties, and you've already used some of them in previous hours using the Properties window. Indeed, every object exposes a specific set of properties, but not every object exposes the same set of properties. To illustrate this point, I will continue with the Pet object concept. Suppose you have an object, and the object is a dog. This Dog object has a certain set of properties that are common to all dogs. These properties include attributes such as the dog's name, the color of its hair, and even the number of legs it has. All dogs have these same properties; however, different dogs have different values for these properties. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig01 Figure 3.1] illustrates such a Dog object and its properties.
<div style="text-align: center;">Figure 3.1. Properties are the attributes that describe an object.
[[Image:03fig01.gif|334px|graphics/03fig01.gof]]
</div>
Getting and Setting Properties
You've already seen how to read and change properties using the Properties window. The Properties window is available only at design time, however, and is used only for manipulating the properties of forms and controls. Most reading and changing of properties you'll perform will be done with C# code, not by using the Properties window. When referencing properties in code, you specify the name of the object first, followed by a period (.), and then the property name, as in the following syntax:
<pre>{ObjectName}.{Property}
</pre>
If you had a Dog object named Bruno, for example, you would reference Bruno's hair color this way:
<pre>Bruno.HairColor
</pre>
This line of code would return whatever value was contained in the HairColor property of the Dog object Bruno. To set a property to some value, you use an equal (=) sign. For example, to change the Dog object Bruno's Weight property, you would use a line of code such as the following:
<pre>Bruno.Weight = 90;
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| A little later in this hour, I discuss instantiation, which is the process of creating an object based on a template. It's important to note here that Bruno is a named instance of an object derived from a template or blueprint (called a class). Each object instance has its own set of data, such as property values. For example, you could also have a Dog object named Bonnie, which has a unique set of properties. In a more real-world example, consider how you can have two buttons on a form. Although they have different property values (such as Name), and they have different code within their Click events, they are both Button objects.
|}
When you reference a property on the left side of an equal sign, you're setting the value. When you reference a property on the right side of the equal sign, you're getting (reading) the value.
<pre>Bruno.Weight = 90;
</pre>
It's easier to see here that referencing the property on the left side of the equal sign indicates that you are setting the property to some value.
The following line of code places the value of the Weight property of the Dog object called Bruno into a temporary variable. This statement retrieves the value of the Weight property because the Weight property is referenced on the right side of the equal sign.
<pre>fltWeight = Bruno.Weight;
</pre>
Variables are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays." For now, think of a variable as a storage location. When the processor executes this code statement, it retrieves the value in the Weight property of the Dog object Bruno and places it in the variable (storage location) titled Weight. Assuming that Bruno's Weight is 90, as set in the previous example, the computer would process the following code statement:
<pre>fltWeight = 90;
</pre>
Just as in real life, some properties can be read but not changed. Suppose you had a Sex property to designate the gender of a Dog object. It's impossible for you to change a dog from a male to a female or vice versa (at least I think it is). Because the Sex property can be retrieved but not changed, it is a read-only property. You'll often encounter properties that can be set in Design view but become read-only when the program is running.
One example of a read-only property is the Height property of the Combo Box control. Although you can view the value of the Height property in the Properties window, you cannot change the value�no matter how hard you try. If you attempt to change the Height property using C# code, C# simply changes the value back to the default.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The best way to determine which properties of an object are read-only is to consult the online help for the object in question.
|}
Working with an Object and Its Properties
Now that you know what properties are and how they can be viewed and changed, you're going to experiment with properties in a simple project. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], you learned how to set the Height and Width properties of a form using the Properties window. Now, you're going to change the same properties using C# code.
The project you're going to create consists of a form with some buttons on it. One button will enlarge the form when clicked, whereas the other will shrink the form. This is a very simple project, but it illustrates rather well how to change object properties in C# code.
# Start by creating a new Windows Application project (from the File menu, choose New, Project).
# Name the project Properties Example.
# Use the Properties window to change the name of the form to fclsShrinkMe. (Click the form once to select it and press F4 to display the Properties window.)
# Next, change the Text property of the form to Grow and Shrink.
# Click the View Code button in Solution Explorer to view the code behind the form. Scroll down and locate the reference to Form1 and change it to fclsShrinkMe.
# Click the Form1.cs [Design] tab to return to the form designer.
When the project first runs, the default form will have a Height and Width as specified in the Properties window. You're going to add buttons to the form that a user can click to enlarge or shrink the form at runtime.
Add a new button to the form by double-clicking the Button tool in the toolbox. Set the new button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Set To
|-
| <code>Name</code>
| <code>btnEnlarge</code>
|-
| <code>Location</code>
| <code>111,70</code>
|-
| <code>Text</code>
| <code>Enlarge</code>
|}
Now for the Shrink button. Again, double-click the Button tool in the toolbox to create a new button on the form. Set this new button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Set To
|-
| <code>Name</code>
| <code>btnShrink</code>
|-
| <code>Location</code>
| <code>111,120</code>
|-
| <code>Text</code>
| <code>Shrink</code>
|}
Your form should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig02 Figure 3.2].
<div style="text-align: center;">Figure 3.2. Each button is an object, as is the form the buttons sit on.
[[Image:03fig02.jpg|500px|graphics/03fig02.jpg]]
</div>
To complete the project, you need to add the small amount of C# code necessary to modify the form's Height and Width properties when the user clicks a button. Access the code for the Enlarge button now by double-clicking the Enlarge button. Type the following statement exactly as you see it here. Do not hit the Enter key or add a space after you've entered this text.
<pre>this.Width
</pre>
When you typed the period, or "dot," as it's called, a small drop-down list appeared, like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig03 Figure 3.3]. C# is smart enough to realize that this represents the current object (more on this in a moment), and to aid you in writing code for the object, it gives you a drop-down list containing all the properties and methods of the form. This feature is called IntelliSense, and it is relatively new to Visual Studio. Because C# is fully object-oriented, you'll come to rely on IntelliSense drop-down lists in a big way; I think I'd rather dig ditches than program without them.
<div style="text-align: center;">Figure 3.3. IntelliSense drop- down lists, or auto-completion drop-down lists, make coding dramatically easier.
[[Image:03fig03.jpg|500px|graphics/03fig03.jpg]]
</div>
Use the Backspace key to completely erase the code you just entered and enter the following code in its place (press Enter at the end of each line):
<pre>this.Width = this.Width + 20;
this.Height = this.Height + 20;
</pre>
Again, the word <code>this</code> refers to the object to which the code belongs (in this case, the form). The word <code>this</code> is a reserved word; it's a word that you cannot use to name objects or variables because C# has a specific meaning for it. When writing code within a form module, as you are doing here, you should always use the <code>this</code> reserved word rather than using the name of the form. <code>this</code> is much shorter than using the full name of the current form, and it makes the code more portable (you can copy and paste the code into another form module and not have to change the form name to make the code work). Also, should you change the name of the form at any time in the future, you won't have to change references to the old name.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The word <code>this</code> is the equivalent to the <code>Me</code> reserved word in Visual Basic.
|}
The code you've entered simply sets the Width and Height properties of the form to whatever the current value of the Width and Height properties happens to be, plus 20 pixels.
Redisplay the form designer by selecting the tab titled Form1.cs [Design]; then double-click the Shrink button to access its Click event and add the following code:
<pre>this.Width = this.Width � 20;
this.Height = this.Height � 20;
</pre>
This code is very similar to the code in the Enlarge_Click event, except that it reduces the Width and Height properties of the form by 20 pixels.
Your screen should now look like [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig04 Figure 3.4].
<div style="text-align: center;">Figure 3.4. The code you've entered should look exactly like this.
[[Image:03fig04.jpg|500px|graphics/03fig04.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| As you create projects, it's a very good idea to save frequently. Save your project now by clicking the Save All button on the toolbar.
|}
Again, display the form designer by clicking the tab Form1.cs [Design]. Your Properties Example is now ready to be run! Press F5 to put the project in Run mode (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig05 Figure 3.5]).
<div style="text-align: center;">Figure 3.5. What you see is what you get�the form you created should look just as you designed it.
[[Image:03fig05.jpg|301px|graphics/03fig05.jpg]]
</div>
Click the Enlarge button a few times and notice how the form gets bigger. Next, click the Shrink button to make the form smaller. When you've clicked enough to satisfy your curiosity (or until you get bored), end the running program and return to Design mode by clicking the Stop Debugging button on the toolbar.
Understanding Methods
In addition to properties, most objects have methods. Methods are actions the object can perform, in contrast to attributes that describe the object. To understand this distinction, think about the Pet object example. A Dog object has a certain set of actions that it can perform. These actions, called methods in C#, include barking and tail wagging. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig06 Figure 3.6] illustrates the Dog object and its methods.
<div style="text-align: center;">Figure 3.6. Invoking a method causes the object to perform an action.
[[Image:03fig06.gif|334px|graphics/03fig06.gof]]
</div>
Triggering Methods
Think of methods as functions�which is exactly what they are. When you invoke a method, code is executed. You can pass data to the method, and methods may return values. However, a method is neither required to accept parameters (data passed by the calling code) nor required to return a value; many methods simply perform an action in code. Invoking (triggering) a method is similar to referencing the value of a property; you first reference the object's name, then a "dot," then the method name, followed by a set of parentheses, which can optionally contain any parameters that must be passed to the method.
<pre>{ObjectName}.{Method}();
</pre>
For example, to make the hypothetical Dog object Bruno bark using C# code, you would use this line of code:
<pre>Bruno.Bark();
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Method calls in C# must always have parentheses. Sometimes they'll be empty, but at other times they'll contain data.
|}
Invoking methods is simple; the real skill lies in knowing what methods an object supports and when to use a particular method.
Understanding Method Dynamism
Properties and methods go hand in hand, and at times a particular method may become unavailable because of one or more property values. For example, if you were to set the NumberofLegs on the Dog object Bruno equal to zero, the Walk and Fetch methods would obviously be inapplicable. If you were to set the NumberofLegs property back to four, you could then trigger the Walk or Fetch methods again. In C#, a method or property won't physically become unavailable�you can still call it, but doing so might cause an exception (error) or the call may be ignored.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Building an Object Example Project
The only way to really grasp what objects are and how they work is to use them. I've said this before but I can't say it enough: everything in C# is an object.
You're about to create a sample project that uses objects. If you're new to programming with objects, you'll probably find this a bit confusing. However, I'll walk you through step by step, explaining each section in detail.
The project you're going to create consists of a single form with one button on it. When the button is clicked, a line will be drawn on the form beginning at the upper-left corner of the form and extending to the lower-right corner.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10], "Drawing and Printing," you'll learn all about the drawing functionality within C#.
|}
Creating the Interface for the Drawing Project
Follow these steps to create the interface for your project:
# Create a new Windows Application project titled Object Example.
# Change the form's Text property to Object Example using the Properties window.
# Add a new button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnDraw</code>
|-
| <code>Location</code>
| <code>112,120</code>
|-
| <code>Text</code>
| <code>Draw</code>
|}
Writing the Object-Based Code
You're now going to add code to the Click event of the button. I'm going to explain each statement, and at the end of the steps, I'll show the complete code listing.
Object Example Project
# Double-click the button to access its Click event.
# Enter the first line of code as follows (remember to press Enter at the end of each statement):
<pre>System.Drawing.Graphics objGraphics = null;
</pre>
Objects don't materialize out of thin air; they have to be created. When a form is loaded into memory, it loads all its controls (that is, creates the control objects), but not all objects are created automatically like this. The process of creating an instance of an object is called instantiation. When you load a form, you instantiate the form object, which in turn instantiates its control objects. You could load a second instance of the form, which in turn would instantiate a new instance of the form and new instances of all controls. You would then have two forms in memory and two of each used control.
To instantiate an object in code, you create a variable that holds a reference to an instantiated object. You then manipulate the variable as an object. The statement you wrote in step 2 creates a new variable called objGraphics, which holds a reference to an object of type Graphics from the .NET Framework System.Drawing class. You also initialized the value for objGraphics to null. You learn more about variables in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays."
# Enter the second line of code exactly as shown here:
<pre>objGraphics = CreateGraphics();
</pre>
CreateGraphics is a method of the form. The CreateGraphics method is pretty complicated under the hood, and I discuss it in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10]. For now, understand that the method CreateGraphics instantiates a new object that represents the client area of the current form. The client area is the gray area within the borders and title bar of a form. Anything drawn onto the objGraphics object appears on the form. What you've done is set the variable objGraphics to point to an object that was returned by the CreateGraphics method. Notice how values returned by a property or method don't have to be traditional values such as numbers or text; they can also be objects.
# Enter the third line of code as shown next:
<pre>objGraphics.Clear(System.Drawing.SystemColors.Control);
</pre>
This statement clears the background of the form using whatever color the user has selected as the Windows forms color.
How does this happen? In step 3, you used the CreateGraphics method of the form to instantiate a new graphics object in the variable objGraphics. With the code statement you just entered, you're calling the clear method of the objGraphics object. The Clear method is a method of all Graphics objects used to clear the graphics surface. The Clear method accepts a single parameter�the color to which you want the surface cleared.
The value you're passing to the parameter looks fairly convoluted. Remember that "dots" are a method of separating objects from their properties and methods.
Knowing this, you can discern that System is an object (technically it's a Namespace, as discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24], "The 10,000-Foot View," but for our purposes it behaves just like an object) because it appears before any of the dots. However, there are multiple dots. What this means is that Drawing is an object property of the System object; it's a property that returns an object. So the dot following Drawing is used to access a member of the Drawing object, which in turn is a property of the System object. We're not done yet, however, because there is yet another dot. Again, this indicates that SystemColors, which follows a dot, is an object of the Drawing object, which in turn is…well, you get the idea. As you can see, object references can and do go pretty deep, and you'll use many dots throughout your code. The key points to remember are the following:
#* Text that appears to the left of a dot is always an object (or Namespace).
#* Text that appears to the right of a dot is a property reference or a method call.
#* Methods are never objects. In addition, methods are always followed by parentheses. If the text in question isn't followed by parentheses, it's definitely a property. Therefore, text that appears between two dots is a property that returns an object. Such a property is called an object property.
The final text in this statement is the word Control. Because Control is not followed by a dot, you know that it's not an object; therefore, it must be a property or a method. Because you expect this string of object references to return a color value to be used to clear the Graphics object, you know that Control must be a property or a method that returns a value. A quick check of the documentation (or simply realizing that the text isn't followed by a set of parentheses) would tell you that Control is indeed a property. The value of Control always equates to the color designated on the user's computer for the face of forms. By default, this is a light gray (often fondly referred to as battleship gray), but users can change this value on their computers. By using this property to specify a color rather than supplying the actual value for gray, you are assured that no matter the color scheme used on a computer, the code will clear the form to the proper system color. System colors are explained in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10].
# Enter the following statement:
<pre>objGraphics.DrawLine(System.Drawing.Pens.Chartreuse, 0, 0,
this.DisplayRectangle.Width, this.DisplayRectangle.Height);
</pre>
This statement draws a chartreuse line on the form. Within this statement is a single method call and three property references. Can you tell what's what? Immediately following objGraphics (and a dot) is DrawLine. Because no equal sign is present (and the text is followed by parentheses), you can deduce that this is a method call. As with the Clear() method, the parentheses after DrawLine() are used to enclose a value passed to the method. The DrawLine() method accepts the following parameters in the order in which they appear here:
#* A Pen
#* X value of first coordinate
#* Y value of first coordinate
#* X value of second coordinate
#* Y value of second coordinate
The DrawLine() method draws a straight line between coordinate one and coordinate two, using the pen specified in the Pen parameter. I'm not going to go into detail on pens here (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10]), but suffice it to say that a pen has characteristics such as width and color. Looking at the dots once more, notice that you're passing the Chartreuse property of the Pens object. Chartreuse is an object property that returns a predefined Pen object that has a width of 1 pixel and the color chartreuse.
You're passing 0 as the next two parameters. The coordinates used for drawing are defined such that 0,0 is always the upper-left corner of a surface. As you move to the right of the surface, X increases, and as you move down the surface, Y increases; you can use negative values to indicate coordinates that appear to the left or above the surface. The coordinate 0,0 causes the line to be drawn from the upper-left corner of the form's client area.
The object property DisplayRectangle is referenced twice in this statement. DisplayRectangle is a property of the form that holds information about the client area of the form. Here, you're simply getting the Width and Height properties of the client area and passing them to the DrawLine method. The result is that the end of the line will be at the lower-right corner of the form's client area.
# Last, you have to clean up after yourself by entering the following code statement:
<pre>objGraphics.Dispose();
</pre>
Objects often make use of other objects and resources. The underlying mechanics of an object can be truly boggling and almost impossible to discuss in an entry-level programming book. The net effect, however, is that you must explicitly destroy most objects when you're done with them. If you don't destroy an object, it may persist in memory and it may hold references to other objects or resources that exist in memory. This means you can create a memory leak within your application that slowly (or rather quickly) munches system memory and resources. This is one of the cardinal no-no's of Windows programming, yet the nature of using resources and the fact you're responsible for telling your objects to clean up after themselves makes this easy to do.
Objects that must explicitly be told to clean up after themselves usually provide a Dispose method. When you're done with such an object, call Dispose on the object to make sure it frees any resources it might be holding.
For your convenience, following are all the lines of code:
<pre>System.Drawing.Graphics objGraphics = null;
objGraphics = CreateGraphics();
objGraphics.Clear(System.Drawing.SystemColors.Control);
objGraphics.DrawLine(System.Drawing.Pens.Chartreuse, 0, 0,
this.DisplayRectangle.Width, this.DisplayRectangle.Height);
objGraphics.Dispose();
</pre>
Testing Your Object Example Project
Now the easy part. Run the project by pressing F5 or by clicking the Start button on the toolbar. Your form looks pretty much like it did at design time. Clicking the button causes a line to be drawn from the upper-left corner of the form's client area to the lower-right corner (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig07 Figure 3.7]).
<div style="text-align: center;">Figure 3.7. Simple lines and complex drawings are accomplished using objects.
[[Image:03fig07.jpg|301px|graphics/03fig07.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you receive any errors when you attempt to run the project, go back and make sure the code you entered exactly matches the code I've provided.
|}
Resize the form, larger or smaller, and click the button again. Notice that the form is cleared and a new line is drawn. If you were to omit the statement that invokes the Clear method (and you're welcome to stop your project and do so), the new line would be drawn, but any and all lines already drawn would remain.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you use Alt+Tab to switch to another application after drawing one or more lines, the lines will be gone when you come back to your form. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10], you'll learn why this is so and how to work around this behavior.
|}
Stop the project now by clicking Stop Debugging on the C# toolbar and then click Save All to save your project. What I hope you've gained from building this example is not necessarily that you can now draw a line (which is cool), but rather an understanding of how objects are used in programming. As with learning almost anything, repetition aids in understanding. Therefore, you'll be working with objects a lot throughout this book.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Understanding Collections
A collection is just what its name implies: a collection of objects. Collections make it easy to work with large numbers of similar objects by enabling you to create code that performs iterative processing on items within the collection. Iterative processing is an operation that uses a loop to perform actions on multiple objects, rather than writing the operative code for each object. In addition to containing an indexed set of objects, collections also have properties and may have methods. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig08 Figure 3.8] illustrates the structure of a collection.
<div style="text-align: center;">Figure 3.8. Collections contain sets of like objects, and they have their own properties and methods.
[[Image:03fig08.gif|324px|graphics/03fig08.gof]]
</div>
Continuing with the Dog/Pet object metaphor, think about what an Animals collection might look like. The Animals collection could contain one or more Pet objects, or it could be empty (containing no objects). All collections have a Count property that returns the total count of objects contained within the collection. Collections may also have methods, such as a Delete method used to remove objects from the collection or an Add method used to add a new object to the collection.
To better understand collections, you're going to create a small C# project that cycles through the Controls collection of a form, telling you the value of the Name property of every control on the form.
To create your sample project, follow these steps:
# Start C# now (if it's not already loaded) and create a new Windows Application project titled Collections Example.
# Change the text of the form to Collections Example by using the Properties window.
# Add a new button to the form by double-clicking the Button tool in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowNames</code>
|-
| <code>Location</code>
| <code>88,112</code>
|-
| <code>Size</code>
| <code>120,23</code>
|-
| <code>Text</code>
| <code>Show Control Names</code>
|}
# Next, add some text box and label controls to the form. As you add the controls to the form, be sure to give each control a unique name. Feel free to use any name you like, but you can't use spaces in a control name. You may want to drag the controls to different locations on the form so that they don't overlap.
# When you are finished adding controls to your form, double-click the Show Control Names button to add code to its Click event. Enter the following code:
<pre>for (int intIndex=0; intIndex < this.Controls.Count; intIndex++)
{
MessageBox.Show ("Control # " + intIndex.ToString() +
" has the name " + this.Controls[intIndex].Name);
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Every form has a Controls collection, which may or may not contain any controls. Even if no controls are on the form, the form still has a Controls collection.
|}
The first statement (the one that begins with for) accomplishes a few tasks. First, it initializes the variable intIndex to 0, and then tests the variable. It also starts a loop executing the statement block (loops are discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch15.htm#ch15 Hour 15], "Looping for Efficiency"), incrementing intIndex by one until intIndex equals the number of controls on the form, less one. The reason that intIndex must always be less than the Count property is that when referencing items in a collection, the first item is always item zero�collections are zero based. Thus, the first item is in location zero, the second item is in location one, and so forth. If you tried to reference an item of a collection in the location of the value of the Count property, an error would occur because you would be referencing an index that is one higher than the actual locations within the collection.
The MessageBox.Show() method (discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch18.htm#ch18 Hour 18], "Interacting with Users ") is a class available in the .NET Framework that is used to display a simple dialog box with text. The text that you are providing, which the MessageBox.Show() method will display, is a concatenation of multiple strings of text. (Concatenation is the process of adding strings together; it is discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13.htm#ch13 Hour 13], "Performing Arithmetic, String Manipulation, and Date/Time Adjustments.")
Run the project by pressing F5 or by clicking Start on the toolbar. Ignore the additional controls that you placed on the form and click the Show Control Names button. Your program will then display a message box similar to the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig09 Figure 3.9] for each control on your form (because of the loop). When the program is finished displaying the names of the controls, choose Stop Debugging from the Debug toolbar to stop the program, and then save the project.
<div style="text-align: center;">Figure 3.9. The Controls collection enables you to get to each and every control on a form.
[[Image:03fig09.jpg|298px|graphics/03fig09.jpg]]
</div>
Because everything in C# is an object, you can expect to use numerous collections as you create your programs. Collections are powerful, and the quicker you become comfortable using them, the more productive you'll become.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using the Object Browser
C# includes a useful tool that lets you easily view members, such as properties and methods, of all the objects in a project: the Object Browser (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig10 Figure 3.10]). This is extremely useful when dealing with objects that aren't well documented, because it enables you to see all the members an object supports. To view the Object Browser, display the Other Windows submenu of the View menu and choose Object Browser.
<div style="text-align: center;">Figure 3.10. The Object Browser lets you view all properties and methods of an object.
[[Image:03fig10.jpg|500px|graphics/03fig10.jpg]]
</div>
The Browse drop-down list in the upper-left corner of the Object Browser is used to determine the browsing scope. You can choose Active Project to view only the objects referenced in the active project, or you can choose Selected Components (the default) to view a set of selected objects. The Object Browser shows a preselected set of objects for Selected Components, but you can customize the object set by clicking the Customize button next to the Browse drop-down list. I wouldn't recommend changing the custom object set until you have some experience using C# objects and some experience using the Object Browser, as well.
The top-level nodes in the Objects tree are libraries. Libraries are usually DLL or EXE files on your computer that contain one or more objects. To view the objects within a library, simply expand the library node. As you select objects within a library, the list to the right of the Objects tree will show information regarding the members of the selected object (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#ch03fig10 Figure 3.10]). For even more detailed information, click a member in the list on the right, and the Object Browser will show information about the member in the gray area below the two lists.
Summary
In this hour, you learned all about objects. You learned how objects have properties, which are attributes that describe the object. Some properties can be set at design time using the Properties window, and most can also be set at runtime in C# code. You learned that referencing a property on the left side of the equal sign has the effect of changing a property, whereas referencing a property on the right side of the equal sign retrieves the property's value.
In addition to properties, you learned that objects have executable functions, called methods. Like properties, methods are referenced by using a "dot" at the end of an object reference. An object may contain many methods and properties, and some properties can even be objects themselves. You learned how to "follow the dots" to interpret a lengthy object reference.
Objects are often used as a group, called a collection. You learned that a collection often contains properties and methods, and that collections let you easily iterate through a set of like objects. Finally, you learned that the Object Browser can be used to explore all the members of an object in a project.
The knowledge you've gained in this hour is fundamental to understanding programming with C#, because objects and collections are the basis on which applications are built. After you have a strong grasp of objects and collections�and you will have by the time you've completed all the hours in this book�you'll be well on your way to fully understanding the complexities of creating robust applications using C#.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#qad1e12077 Q1:]'''
| Is there an easy way to get help about an object's member?
|-
| align="right" | ''' A1: '''
| Absolutely. C#'s context-sensitive Help extends to code as well as to visual objects. To get help on a member, write a code statement that includes the member (it doesn't have to be a complete statement), position the cursor within the member text, and press F1. For instance, to get help on the Count property of the controls collection, you could type this.Controls.Count, position the cursor within the word Count, and press F1.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#qad1e12096 Q2:]'''
| Are there any other types of object members besides properties and methods?
|-
| align="right" | ''' A2: '''
| Yes. An event is actually a member of an object, although it's not always thought of that way. Not all objects support events, however, but most objects do support properties and methods.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans01 1:]'''
| True or False: C# is a true object-oriented language.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans02 2:]'''
| An attribute that defines the state of an object is called a what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans03 3:]'''
| To change the value of a property, the property must be referenced on which side of an equal sign?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans04 4:]'''
| What is the term for when a new object is created from a template?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans05 5:]'''
| An external function of an object (one that is available to code using an object) is called a what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans06 6:]'''
| True or False: A property of an object can be another object.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans07 7:]'''
| A group of like objects is called what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec3.htm#ch03ans08 8:]'''
| What tool is used to explore the members of an object?
|}
Exercises
# Create a new project and add text boxes and a button to the form. Write code that, when clicked, places the text in the first text box into the second text box. Hint: Use the Text property of the text box controls.
# Modify the collections example in this hour to print the Height of all controls, rather than the name.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03lev1sec8.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04.htm [[Image:next.gif|41px|Next Section]]]
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/03.htm#toppage Top]
|}
po02v7mlkev2w4mi3orh970g0afr4fm
User:Foxall/04
2
2135
39240
5596
2026-04-13T06:03:29Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39240
wikitext
text/x-wiki
== Hour 4. Understanding Events ==
It's fairly easy to create an attractive interface for an application using C#'s integrated design tools. You can create beautiful forms that have buttons to click, text boxes in which to type information, picture boxes in which to view pictures, and many other creative and attractive elements with which users can interact. However, this is just the start of producing a C# program. In addition to designing an interface, you have to empower your program to perform actions in response to how a user interacts with the program and how Windows interacts with the program. This is accomplished by using events. In the previous hour, you learned about objects and their members�notably, properties and methods. In this hour, you'll learn about object events and event-driven programming, and you'll learn how to use events to make your applications responsive.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev1sec1 Understanding event-driven programming]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev2sec1 Triggering events]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev2sec3 Avoiding recursive events]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev2sec4 Accessing an object's events]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev2sec5 Working with event parameters]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec2.htm#ch04lev2sec8 Creating event handlers]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec1.htm#ch04lev2sec4 Dealing with orphaned events]
----
=== Understanding Event-Driven Programming ===
With "traditional" programming languages (often referred to as procedural languages), the program itself fully dictates what code is executed and when it's executed. When you start such a program, the first line of code in the program executes, and the code continues to execute in a completely predetermined path. The execution of code may, on occasion, branch and loop, but the execution path is completely controlled by the program. This often meant that a program was rather restricted in how it could respond to the user. For instance, the program might expect text to be entered into controls on the screen in a predetermined order, unlike in Windows, where a user can interact with different parts of the interface, often in any order the user chooses.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| C# incorporates an event-driven programming model. Event-driven applications aren't bound by the constraints of procedural programs. Instead of the top-down approach of procedural languages, event-driven programs have logical sections of code placed within events. There is no predetermined order in which events occur, and often the user has complete control over what code is executed in an event-driven program by interactively triggering specific events, such as by clicking a button. An event, along with the code it contains, is called an event procedure.
|}
Triggering Events
In the previous hour, you learned how a method is simply a function of an object. Events are a special kind of method; they are a way for objects to signal state changes that may be useful to clients of that object. Events are methods that can be called in special ways�usually by the user interacting with something on a form or by Windows itself, rather than being called from a statement in your code.
There are many types of events and many ways to trigger those events. You've already seen how a user can trigger the Click event of a button by clicking it. User interaction isn't the only thing that can trigger an event, however. An event can be triggered in one of the following four ways:
* Users can trigger events by interacting with your program.
* Objects can trigger their own events, as needed.
* The operating system (whichever version of Windows the user is running) can trigger events.
* You can trigger events by calling them using C# code.
Events Triggered Through User Interaction
The most common way an event is triggered is by a user interacting with a program. Every form, and almost every control you can place on a form, has a set of events specific to its object type. For example, the Button control has a number of events, including the Click event, which you've already used in previous hours. The Click event is triggered, and then the code within the Click event executes when the user clicks the button.
The Textbox control allows users to enter information using the keyboard, and it also has a set of events. The Textbox control has some of the same types of events as the Button control, such as a Click event, but the Textbox control also has events not supported by the Button control, such as a TextChanged event. The TextChanged event occurs each time the contents of the text box change, such as when the user types information into the text box. Because you can't enter text within a Button control, it makes sense that the Button control wouldn't have a TextChanged event. Each and every object that supports events supports a unique set of events.
Each type of event has its own behavior, and it's important to understand the events with which you work. The TextChanged event, for instance, exhibits a behavior that may not be intuitive to a new developer because the event fires each time the contents of the text box change. If you were to type the following sentence into an empty text box:
<pre>C# is very cool!
</pre>
the Change event would be triggered 16 times�once for each character typed�because each time you enter a new character, the contents of the text box are changed. Although it's easy to think that the Change event fires only when you commit your entry, such as by leaving the text box or pressing Enter, this is simply not how it works. Again, it's important to learn the nuances and the exact behavior of the events you're using. If you use events without fully understanding how they work, your program may exhibit unusual, and often very undesirable, results.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Triggering events (which are just a type of procedure) using C# code is discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods."
|}
Events Triggered by an Object
Sometimes an object triggers its own events. The most common example of this is the Timer control's Timer event. The Timer control doesn't appear on a form when the program is running; it appears only when you're designing a form. The Timer control's sole purpose is to trigger its Timer event at an interval that is specified in its Interval property.
By setting the Timer control's Interval property, you control the interval, in milliseconds, when the Timer event executes. After firing its Timer event, a Timer control resets itself and again fires its Timer event when the interval has passed. This occurs until the interval is changed, the Timer control is disabled, or the Timer control's form is unloaded. A common use of timers is to create a clock on a form. You can display the time in a label and update the time at regular intervals by placing the code to display the current time in the Timer event. You'll create a project with a Timer control in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08.htm#ch08 Hour 8], "Advanced Controls."
Events Triggered by the Operating System
Finally, Windows can trigger certain events within your program �events that you may not even know exist. For example, when a form is fully or partially obstructed by another window, the program needs to know when the offending window is resized or moved so that it can repaint the area of its window that's been hidden. Windows and C# work together in this respect. When the obstructing window is moved or resized, Windows tells C# to repaint the form, which C.htm# does. This also causes C# to raise the form's Paint event. You can place code into the Paint event to create a custom display for the form, such as drawing shapes on the form using a Graphics object. That way, every time the form repaints itself, your custom drawing code executes.
Avoiding Recursive Events
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| You must make sure never to cause an event to endlessly trigger itself. An event that continuously triggers itself is called a recursive event. To illustrate a situation that causes a recursive event, think of the text box's TextChanged event discussed earlier. The TextChanged event fires every time the text within the text box changes. Placing code into the TextChanged event that alters the text within the text box would cause the Change event to be fired again, which could result in an endless loop. Recursive events terminate when Windows returns a StackOverFlow exception (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig01 Figure 4.1]), indicating that Windows no longer has the resources to follow the recursion.
|}
<div style="text-align: center;">Figure 4.1. Recursive events eventually exhaust Windows's resources until an exception (error) occurs.
[[Image:04fig01.gif|376px|graphics/04fig01.gof]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| When you receive a StackOverFlow exception, you should look for a recursive event as the culprit.
|}
Recursive events can involve more than one event in the loop. For example, if Event A triggers Event B, which in turn triggers Event A, you can have recursion of the two events. Recursion can take place among a sequence of many events, not just one or two.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Uses for recursive procedures actually exist, such as when you are writing complex math functions. For instance, recursive events are often used to compute factorials. However, when you purposely create a recursive event, you must ensure that the recursion isn't infinite.
|}
Accessing an Object's Events
Accessing an object's events is simple, and if you've been following the examples in this book, you've already accessed a number of objects' default events. To access all of an object's events, you can use the Events icon (the lightning bolt) in the Properties window.
You're now going to create a project to get the feel for working with events. Start C# and create a new Windows Application project titled View Events, and then follow these steps:
# Use the toolbox to add a picture box to the form.
# Change the name of the picture box to picText.
# Click the Events button on the Properties window toolbar (the lightning bolt icon).
Your screen should look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig02 Figure 4.2]. Notice that the Properties window now lists all the events for the selected object; in your case, it is the picText PictureBox object.
<div style="text-align: center;">Figure 4.2. Double�click an event in the Properties window to create the desired event.
[[Image:04fig02.jpg|500px|graphics/04fig02.jpg]]
</div>
When you access a control's events, the default event for that type of control is selected. As you can see, the Click event is the default for a PictureBox. Scroll through the picText events and select the MouseDown event. Double-click the word MouseDown and C# will create the MouseDown event procedure and position you within it, ready to enter code (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig03 Figure 4.3]).
<div style="text-align: center;">Figure 4.3. C# creates an empty event procedure when you select an object's event for the first time.
[[Image:04fig03.jpg|500px|graphics/04fig03.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The code statement above the cursor is the event declaration. An event declaration is a statement that defines the structure of an event handler. Notice that this event declaration contains the name of the object, an underscore character (_), and then the event name. Following the event name is a set of parentheses. The items within the parentheses are called parameters, which is the topic of the next section. This is the standard declaration structure for an event procedure.
|}
The full event declaration for the Click event is the following:
<pre>private void picText_MouseDown(object sender, _
System.Windows.Forms.MouseEventArgs e)
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The words Private and Void are reserved words that indicate the scope and type of the method. Scope and type are discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11].
|}
Working with Event Parameters
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As mentioned previously, the items within the parentheses of an event declaration are called parameters. An event parameter is a variable that is created and assigned a value by C#. These parameter variables are used to get, and sometimes set, relevant information within the event. Multiple parameters within an event procedure are always separated by commas. A parameter contains data that relates to the event. This data may be a number, text, an object�almost anything. As you can see, the MouseDown event has two parameters. When the Click event procedure is triggered, C# automatically creates the parameter variables and assigns them values for use in this one execution of the event procedure; the next time the event procedure occurs, the values in the parameters are reset. You use the values in the parameters to make decisions or perform operations in your code.
|}
The MouseDown event of a form has the following parameters:
<pre>object sender
</pre>
and
<pre>System.Windows.Forms.MouseEventArgs e
</pre>
The first word identifies the type of data the parameter contains, followed by the name of the parameter. The first parameter, sender, holds a generic object. Object parameters can be any type of object supported by C#. It's not critical that you understand data types right now, just that you're aware that different parameter variables contain different types of information. Some contain text, others contain numbers, and still others (many others) contain objects. In the case of the sender parameter, it will always hold a reference to the control causing the event.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The sender parameter returns a reference to the control that causes the event. It's often best to use the sender parameter rather than referencing the control by name, so that if you change the name of the control, you won't have to update the code. Also, by referencing the sender object, the code becomes portable; you can copy and paste it into the event of a different control of the same type, and the code should work without modification.
|}
The e parameter, on the other hand, is where the real action is with the MouseDown event. The e parameter also holds an object; in this case the object is of the type <code>System.WinForms.MouseEventArgs</code>. This object has properties that relate to the MouseDown_event. To see them, type in the following code, but don't press anything after entering the dot (period):
<pre>e.
</pre>
When you press the period, you'll get a drop-down list showing you the members (properties and methods) of the e object (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig04 Figure 4.4]). Using the e object, you can determine a number of things about the occurrence of the MouseDown event. I've listed some of the more interesting items in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04table01 Table 4.1].
<div style="text-align: center;">Figure 4.4. IntelliSense drop-down lists alleviate the need for memorizing the makeup of hundreds of objects.
[[Image:04fig04.jpg|500px|graphics/04fig04.jpg]]
</div>
{| cellspacing="0" cellpadding="1" border="1"|+ Table 4.1. Commonly used members of <code>System.WinForms.MouseEventArgs</code>
|-
| Property
| Description
|-
| <code>Clicks</code>
| Returns the number of times the user clicked the mouse button.
|-
| <code>Button</code>
| Returns the button that was clicked (left, middle, right).
|-
| <code>X</code>
| Returns the horizontal coordinate at which the pointer was located when the user clicked.
|-
| <code>Y</code>
| Returns the vertical coordinate at which the pointer was located when the user clicked.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Each time the event occurs, the parameters are initialized by C# so that they always reflect the current occurrence of the event.
|}
Each event has parameters specific to it. For instance, the <code>TextChanged</code> event returns parameters different from the <code>MouseDown</code> event. As you work with events�and you'll work with a lot of events�you'll quickly become familiar with the parameters of each event type. You'll learn how to create parameters for your own methods in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11].
Deleting an Event Handler
Deleting an event handler involves more than just deleting the event procedure. When you add a new event handler to a class, C# automatically creates the event procedure for you and positions you to enter code within the event. However, C# does a little bit more for you "under the covers" to hook the event procedure to the control. It does this by creating a code statement in the hidden code of the class. Ordinarily, you don't have to worry about this statement. However, when you delete an event procedure, C# doesn't automatically delete the hidden code statement, and your code won't compile. The easiest way to correct this is to run the project; when C# encounters the error, it will show you the offending statement, which you can delete. Try this now:
# Delete the MouseDown procedure (don't forget to delete the open and close brackets of the procedure, as well as any code within them). This deletes the procedure.
# Press F5 to run the project. You'll receive a message that a build error has occurred. Click No to return to the code editor.
# A task for the error has been created in the Task List. Double-click the task and C# will take you to the offending statement. It will read:
<pre>this.pictureBox1.MouseDown += new
System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
</pre>
# Delete this statement, and now your code will compile and run.
Whenever you delete an event procedure, you will have to delete the corresponding statement that links the procedure to its object before the code will run.
Building an Event Example Project
You're now going to create a very simple project in which you'll use the event procedures of a text box. Specifically, you're going to write code to display a message when a user presses a mouse button on the text box, and you'll write code to clear the text box when the user releases the button. You'll be using the e parameter to determine which button the user has pressed.
Creating the User Interface
Create a new Windows application titled Events Example. Change the form's Text property to Events Demo.
Next, add a text box to the form by double-clicking the TextBox tool in the toolbox. Set the properties of the text box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtEvents</code>
|-
| <code>Location</code>
| <code>48</code>,<code>120</code>
|-
| <code>Size</code>
| <code>193</code>,<code>20</code>
|-
| <code>Text</code>
| <code>Click Me!</code>
|}
The only other control you need on your form is a label. Label controls are used to display static text; users cannot type text into a label. Add a new label to your form now by double-clicking the Label tool in the toolbox and then setting the Label control's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lblMessage</code>
|-
| <code>Location</code>
| <code>48</code>,<code>152</code>
|-
| <code>Size</code>
| <code>192</code>,<code>16</code>
|-
| <code>Text</code>
| <code>(</code><code>make blank</code><code>)</code>
|-
| <code>TextAlign</code>
| <code>MiddleCenter</code>
|}
Your form should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig05 Figure 4.5]. It's a good idea to save frequently, so save your project now by clicking the Save All button on the toolbar.
<div style="text-align: center;">Figure 4.5. A Label control that has no value in its Text property can be hard to see unless selected.
[[Image:04fig05.jpg|500px|graphics/04fig05.jpg]]
</div>
Creating Event Handlers
The interface for the Events Example project is complete�on to the fun part. You're now going to create the event procedures that empower your program to do something. The event that we're interested in first is the <code>MouseDown</code> event. Select the TextBox on your design form, and then click the Events icon on the Properties window toolbar.
The default event for text boxes is the TextChanged event, so it's the one now selected. You're not interested in the TextChanged event at this time, however. Scroll through the event list for the MouseDown event. Double-click MouseDown; C# then creates a new MouseDown event procedure for the text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig06 Figure 4.6]).
<div style="text-align: center;">.
[[Image:04fig06.jpg|500px|graphics/04fig06.jpg]]
</div>
Enter the following code into the MouseDown event procedure:
<pre>switch(e.Button)
{
case MouseButtons.Left:
lblMessage.Text = "You are pressing the left button!";
break;
case MouseButtons.Right:
lblMessage.Text = "You are pressing the right button!";
break;
case MouseButtons.Middle:
lblMessage.Text = "You are pressing the middle button!";
break;
}
</pre>
The Switch construct, which is discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14.htm#ch14 Hour 14], "Making Decisions in C# Code," compares the value of an expression to a list of possible values. In this instance, the expression is the value of e.Button (the Button property of the object e). When this code executes, the expression is compared to each Case statement in the order in which the statements appear. If and when a match is found, the code immediately following the Case statement that was matched gets executed. Therefore, the code you wrote looks at the value of e.Button and compares it to three values, one at a time. When the Switch construct determines which button has been pressed, it displays a message about it in the Label control.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In a more robust application, you would probably perform more useful and more complicated code. For instance, you may want to display a custom pop-up menu when the user clicks with the right button and execute a specific function when the user clicks with the middle button. All this is possible, and more.
|}
The nice thing about objects is that you don't have to commit every detail about them to memory. For example, you don't need to memorize the return values for each type of button (who wants to remember MouseButtons.Left anyway?). Just remember that the e parameter contains information about the event. When you type e and press the period, the IntelliSense drop-down list appears and shows you the members of e, one of which is Button.
Don't feel overwhelmed by all the object references you'll encounter throughout this book. Simply accept that you can't memorize them all, nor do you need to; you'll learn the ones that are important, and you'll use Help when you're stuck. Also, after you know the parent object in a situation, such as the e object in this example, it's easy for you to determine the objects and members that belong to it by using the IntelliSense drop-down lists.
You're now going to add code to the MouseUp event to clear the label's Text property when the user releases the button. First, you'll need to create the MouseUp event procedure. To do this, return to the Form Design view (click the Form1.cs[Design] tab). The Properties should still have the txtEvents object's events listed. If the events aren't shown in the Properties window, select txtEvents from the drop-down list box in the Properties window and click the events icon. Locate and double-click the MouseUp event from the events list.
All you're going to do in the MouseUp_event is clear the label. Enter the following code:
<pre>lblMessage.Text = "";
</pre> Testing Your Events Project
Run your project now by pressing F5. If you entered all the code correctly and you don't receive any errors, your form will be displayed as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#ch04fig07 Figure 4.7].
<div style="text-align: center;">Figure 4.7. A simple but functional example.
[[Image:04fig07.jpg|298px|graphics/04fig07.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Remember that C# is case sensitive. Entering only one character in the wrong case will cause your project to fail to compile.
|}
Click the text box with the left mouse button and watch the label. It will display a sentence telling you which button has been clicked. When you release the button, the text is cleared. Try this with the middle and right buttons, as well. When you click the text box with the right button, Windows displays the standard shortcut menu for text boxes. When this menu appears, you have to select something from it or click somewhere off the menu to trigger the MouseUp event. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09.htm#ch09 Hour 9], "Adding Menus and Toolbars to Forms," you'll learn how to add your own shortcut menus to forms and controls. When you're satisfied that your project is behaving as it should, from the Debug menu choose Stop Debugging to stop the project (or click the Close button on your form), and then save your work by clicking Save All on the toolbar.
Summary
In this hour, you learned about event-driven programming, including what events are, how to trigger events, and how to avoid recursive events. In addition, you've learned how to access an object's events and how to work with parameters. Much of the code you'll write will execute in response to an event of some kind. By understanding how events work, including being aware of the available events and their parameters, you'll be able to create complex C# programs that react to a multitude of user and system input.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#qad1e14038 Q1:]'''
| Is it possible to create custom events for an object?
|-
| align="right" | ''' A1: '''
| You can create custom events for objects created from your custom classes (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects with Classes"), but you cannot create custom events for existing C# objects such as forms and controls (without using some seriously advanced object-oriented techniques that are beyond the scope of this book).
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#qad1e14064 Q2:]'''
| Is it possible for objects that don't have an interface to support events?
|-
| align="right" | ''' A2: '''
| Yes. However, to use the events of such an object, the object variable must be dimensioned a special way or the events aren't available. This gets a little tricky and is beyond the scope of this book. If you have an object in code that supports events, look in Help for the keyword WithEvents for information on how to use such events.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans01 1:]'''
| Name three things that can cause events to occur.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans02 2:]'''
| True or False: All objects support the same set of events.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans03 3:]'''
| What is the default event type for a button?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans04 4:]'''
| The act of an event calling itself in a loop is called what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans05 5:]'''
| What is the easiest way to access a control's default event handler?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec4.htm#ch04ans06 6:]'''
| All control events pass a reference to the control causing the event. What is the name of the parameter that holds this reference?
|}
Exercises
# Create a project with a single text box. In the Resize event of the form, show the Width of the form in the text box.
# Create a project with a form and a text box. Add code to the TextChange event to cause a recursion when the user types in text. Hint: Concatenate a character to the end of the user's text using a statement such as <code>txtMyTextBox.Text = String. Concat(this. txtMyTextBox.Text,"a");</code>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04lev1sec4.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/part02.htm [[Image:next.gif|41px|Next Section]]]
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/04.htm#toppage Top]
|}
3v0io1hkxq6nr3yuotbga6rn79he8z7
User:Foxall/05
2
2136
39241
5597
2026-04-13T06:03:29Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39241
wikitext
text/x-wiki
./ ADD NAME=CH05.HTM
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/part02.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec1.htm [[Image:next.gif|41px|Next Section]]]
|}
----
Hour 5. Building Forms�Part I
With few exceptions, forms are the cornerstone of every Windows application's interface. Forms are essentially windows and the two terms are often used interchangeably. More accurately, "window" refers to what's seen by the user and what the user interacts with, whereas "form" refers to what you see when you design. Forms let users view and enter information in a program (such as the form you built in your Picture Viewer program in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour"). Such information may be text, pictures, graphs�almost anything that can be viewed onscreen. Understanding how to design forms correctly will enable you to begin creating solid interface foundations for your programs.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| C# uses a new forms engine called Windows Forms.
|}
Think of a form as a canvas on which you build your program's interface. On this canvas, you can print text, draw shapes, and place controls with which users can interact. The wonderful thing about C# forms is that they behave like a dynamic canvas; not only can you adjust the appearance of a form by manipulating what's on it, you can also manipulate specific properties of the form itself.
In previous hours, you manipulated the following form appearance properties:
* Text
* Height
* Left
* Top
* Width
The capability to tailor your forms, however, goes far beyond these simple manipulations.
There is so much to cover about Windows Forms that I've broken the material into two hours. In this hour, you'll learn the very basics of forms�adding them to a project, manipulating their properties, and showing and hiding them using C# code. Although you've done some of these things in previous hours, here you'll learn the nuts and bolts of the tasks you've performed. In the following hour, you'll learn more advanced form techniques.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec1.htm#ch05lev1sec1 Changing the name of a form]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev1sec2 Changing the appearance of a form]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec1 Displaying text on a form's title bar]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec3 Adding an image to a form's background]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec4 Giving a form an icon]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec5 Preventing a form from appearing in the taskbar]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec8 Specifying the initial display position of a form]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec9 Displaying a form in a normal, maximized, or minimized state]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm#ch05lev2sec10 Changing the mouse pointer]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec3.htm#ch05lev1sec3 Showing and hiding forms]
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/part02.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec1.htm [[Image:next.gif|41px|Next Section]]]
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#toppage Top]
|}
./ ADD NAME=CH05LEV1SEC1.HTM
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05lev1sec2.htm [[Image:next.gif|41px|Next Section]]]
|}
Changing the Name of a Form
The first thing you should do when you create a new object is give it a descriptive name, so that's the first thing I'll talk about in this hour. Start C# now (if it's not already running) and create a new Windows Application titled Forms Example. Using the Properties window, change the name of the form to fclsExample. When you need to create a new instance of this form, you'll use this name rather than the default generic name of Form1.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Remember, when you change the name of the startup form for your application, you need to update the class name in the entry point of your application (<code>static void Main()</code>). Refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1] for instructions on how to do this.
|}
Changing the Appearance of a Form
Take a moment to browse the rest of the form's properties in the Properties window. In this hour, I'll show you how to use the more common properties of the form to tailor its appearance.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Remember, to get help on any property at any time, select the property in the Properties window and press F1.
|}
Displaying Text on a Form's Title Bar
You should always set the text in a form's title bar to something meaningful. (Note: Not all forms have title bars, as you'll see later in this hour.) The text displayed in the title bar is the value placed in the form's Text property. Generally, the text should be one of the following:
* The name of the program. This is most appropriate when the form is the program's main or only form.
* The purpose of the form. This is perhaps the most common type of text displayed in a title bar. For example, if a form is used to select a printer, consider setting the Text property to Select Printer. When you take this approach, use active voice (for instance, don't use Printer Select).
* The name of the form. If you choose to place the name of the form into the form's title bar, use the "English" name, not the actual form name. For instance, if you've used a naming convention and named a form fclsLogin, use the text Login or Login Form.
Change the Text property of your form to Building Forms Example. Your form should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig01 Figure 5.1].
<div style="text-align: center;">Figure 5.1. Use common sense when setting title bar text.
[[Image:05fig01.jpg|500px|graphics/05fig01.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| As with most other form properties, you can change the Text property at any time using C# code.
|}
Changing a Form's Background Color
Although most forms appear with a gray background (this is part of the standard 3D color scheme in Windows), you can change a form's background to any color you like. To change a form's background color, you change its BackColor property. The BackColor property is a unique property in that you can specify a named color or an RGB value in the format Red, Green, Blue.
By default, the BackColor is set to the color named Control. This color is a system color and may not be gray. When Windows is first installed, it's configured to a default color scheme. In the default scheme, the color for forms and other objects is the familiar "battleship" gray. However, as a Windows user, you're free to change any system color you desire. For instance, some people with color blindness prefer to change their system colors to colors that have more contrast than the defaults so that objects are more clearly distinguishable. When you assign a system color to a form or control, the appearance of the object adjusts itself to the current user's system color scheme. This doesn't just occur when a form is first displayed; changes to the system color scheme are immediately propagated to all objects that use the affected colors.
Change the background color of your form to blue now by deleting the word Control in the BackColor property in the Properties window; in its place enter 0,0,255 and press Enter or Tab to commit your entry. Your form should now be blue because you entered an RGB value in which you specified no red, no green, and maximum blue (color values range from 0 to 255). In reality, you'll probably rarely enter RGB values. Instead, you'll select colors from color palettes. To view color palettes from which you can select a color for the BackColor property, click the drop-down arrow in the BackColor property in the Properties window (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig02 Figure 5.2]).
<div style="text-align: center;">Figure 5.2. All color properties have palettes from which you can choose a color.
[[Image:05fig02.jpg|202px|graphics/05fig02.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| System colors are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10], "Drawing and Printing."
|}
When the drop-down list appears, the color Blue on the Web tab is selected. This occurs because when you entered the RGB value 0,0,255, C# looked for a named color composed of the same values and it found blue. The color palettes were explained in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch02.htm#ch02 Hour 2], "Navigating C#," so I'm not going to go into detail about them here. For now, select the System tab to see a list of the available system colors and choose Control from the list to change the BackColor of your form back to the default Windows color.
Adding an Image to a Form's Background
In addition to changing the color of a form's background, you can also place a picture on it. To add a picture to a form, set the form's BackgroundImage property. When you add an image to a form, the image is "painted" on the form's background. All the controls that you place on the form appear on top of the picture.
Add an image to your form now by following these steps:
# Select the form.
# Click the BackgroundImage property in the Properties window.
# Click the Build button that appears next to the property (the small button with three dots).
# Use the Open dialog box that appears to locate and select an image file from your hard drive. (I used Blue Lace 16.BMP, which I found in my \WinNT folder.)
C# always tiles an image specified in a BackgroundImage property (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig03 Figure 5.3]). This means that if the selected picture isn't big enough to fill the form, C# will display additional copies of the picture, creating a tiled effect. If you want to display a single copy of an image on a form, anywhere on the form, you should use a picture box, as discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10].
<div style="text-align: center;">Figure 5.3. Images are tiled to fill the form.
[[Image:05fig03.jpg|500px|graphics/05fig03.jpg]]
</div>
Notice that to the left of the BackgroundImage property is a small box containing a plus sign. This indicates that there are related properties, or subproperties, of the BackgroundImage property. Click the plus sign now to expand the list of subproperties (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig03 Figure 5.3]). In the case of the BackgroundImage property, C# shows you a number of properties related to the image assigned to the property, such as its dimensions and image format.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Adding background images to forms can add pizzazz to a program, but it can also confuse users by making forms unnecessarily busy. Try to avoid adding images just because you can. Use discretion, and add an image to a form only when the image adds value to the interface.
|}
Removing an image from a form is just as easy as adding the image in the first place. To remove the picture that you just added to your form, right-click the BackgroundImage property name and choose Reset from the shortcut menu that appears.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You must right-click the Name column of the property, not the Value column. If you right-click the value of the property, you get a different shortcut menu that doesn't have a Reset option.
|}
Giving a Form an Icon
The icon assigned to a form appears in the left side of the form's title bar, in the taskbar when the form is minimized, and in the iconic list of tasks when you press Alt+Tab to switch to another application. The icon often represents the application; therefore, you should assign an icon to any form a user can minimize. If you don't assign an icon to a form, C# supplies a default icon to represent it when the form is minimized. This default icon is generic and unattractive, and you should avoid it.
In the past, it was recommended that every form have a unique icon related to the form's purpose. This has proved very difficult to accomplish in large applications. As an alternative, I recommend that you set the icon of the main form in your program to the icon that you want to represent your application, and then assign that icon to other forms as they are loaded rather than assigning them at design time. If this proves to be a hassle, just assign the same icon to all your forms.
You assign an icon to a form in much the same way you assign an image to the BackgroundImage property. Add an icon to your form now by clicking the form's Icon property in the Properties window, clicking the Build button that appears, and selecting an icon file from your hard drive. After you've selected the icon, it appears in the form's title bar to the left.
Run your project by pressing F5, and then click the form's Minimize button to minimize it to the taskbar. Look at the form in the taskbar; you'll see both the form's caption and the form's icon displayed (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig04 Figure 5.4]).
<div style="text-align: center;">Figure 5.4. Assigning meaningful icons to your forms makes your application easier to use.
[[Image:05fig04.jpg|500px|graphics/05fig04.jpg]]
</div>
Stop the project now by choosing Stop Debugging from the Debug menu.
Preventing a Form from Appearing in the Taskbar
Being able to display an icon for a minimized form is nice, but sometimes it's necessary to prevent a form from even appearing in the taskbar. For instance, if your application has a number of palette windows that float over a main form, it's unlikely that you'd want all but your main form to appear in the taskbar. To prevent a form from appearing in the taskbar, set the form's ShowInTaskbar property to false. If the user minimizes a form with its ShowInTaskbar property set to false, the user can still get to the application by pressing Alt+Tab, even though the program can't be accessed via the taskbar; C# won't allow the application to become completely inaccessible to the user.
Changing the Appearance and Behavior of a Form's Border
You may have noticed while working with other Windows programs that the borders of forms can vary. Some forms have borders that you can click and drag to change the size of the form, some have fixed borders that can't be changed, and still others have no borders at all. The appearance and behavior of a form's border is controlled by its FormBorderStyle property.
The FormBorderStyle property can be set to one of the following values:
* None
* FixedSingle
* Fixed3D
* FixedDialog
* Sizable
* FixedToolWindow
* SizableToolWindow
Run your project now by pressing F5, and move the mouse pointer over one of the borders of your form. This form has a sizable border, which means that the border can be resized by the user. Notice how the pointer changes from a large arrow to a line with arrows pointing on either side, indicating the direction you can stretch the border. When you move the pointer over a corner, you get a diagonal cursor that indicates you can stretch both of the sides that meet at the corner.
Stop the project now by choosing Stop Debugging from the Debug menu (or click the Close button on the form) and change the form's FormBorderStyle property to None. Your form should look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig05 Figure 5.5]. When you choose to not give a form a border, the title bar of the form is removed. Of course, when the title bar is gone, there is no visible title bar text, no control box, and no Minimize or Maximize buttons. Run your project by pressing F5, and notice how the form appears as it did in Form Design view�with no border or title bar. Without a border, the form cannot be resized by the user, and without a title bar, the form cannot be repositioned. Rarely is it appropriate to specify None for a form's BorderStyle, but in the event you need to do this, it's entirely possible.
<div style="text-align: center;">Figure 5.5. You can create forms without borders.
[[Image:05fig05.jpg|500px|graphics/05fig05.jpg]]
</div>
Stop the project (you should know how by now) and change the FormBorderStyle to FixedDialog. Press F5 to run the project again, and move the mouse pointer over a border of the form; the mouse pointer won't change, and you won't be able to stretch the borders of the form. Stop the project again and set the form's FormBorderStyle property to FixedToolWindow. This setting causes the title bar of the form to appear smaller than normal and the text to display in a smaller font (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig06 Figure 5.6]). In addition, the only thing displayed on the title bar besides the text is a Close button. C#'s various design windows, such as the Properties window and the toolbox, are good examples of tool windows.
<div style="text-align: center;">Figure 5.6. A tool window is a special window whose title bar takes up the minimum space possible.
[[Image:05fig06.jpg|500px|graphics/05fig06.jpg]]
</div>
The FormBorderStyle is a good example of how changing a single property can greatly affect the look and behavior of an object. Set the FormBorderStyle of the form back to Sizable, the default setting for new forms.
Adding Minimize, Maximize, and Control Box Buttons to a Form
Minimize and Maximize buttons make it easy for a user to quickly hide a form or make it fill the entire display. Adding a Minimize or Maximize button to your forms is as easy as setting a property (or two). To add a Minimize button to a form's title bar, set the form's MinimizeBox property to true. To add a Maximize button to a form, set its MaximizeBox property to true. Conversely, set the appropriate property to false to hide a button.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The form's ControlBox property must be set to true to display a Maximize and/or Minimize button on a form. When the ControlBox property of a form is set to true, a button with an X appears in the title bar at the right side, which the user can click to close the form. In addition, the form's icon is displayed in the left side of the title bar, and clicking it opens the form's System menu.
|}
Notice that the title bar of your form shows all three buttons to the far right. From left to right, these are Minimize, Maximize, and Close. Run the project now and right-click the title bar to open the control box's menu, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig07 Figure 5.7]. Notice that the icon isn't visible in the form's title bar. Some FormBorderStyle settings cause the icon to be hidden. When this occurs, right-clicking the title bar causes the menu to appear as though you clicked the icon. Close the form now by either selecting Close from the menu or clicking the Close button on the far right of the title bar.
<div style="text-align: center;">Figure 5.7. Clicking the icon of a form with a control box (or right-clicking a title bar) displays a system menu.
[[Image:05fig07.jpg|300px|graphics/05fig07.jpg]]
</div>
Changing the MaximizeBox or MinimizeBox properties of a form enables or disables the corresponding item on the system menu in addition to the button on the toolbar. Save your project now by clicking the Save All button on the toolbar.
Specifying the Initial Display Position of a Form
The location on the display (monitor) where a form first appears isn't random but is controlled by the form's StartPosition property. The StartPosition property can be set to one of the values in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05table01 Table 5.1].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 5.1. Values for the StartPosition Property
|-
| Value
| Description
|-
| Manual
| The Location property of the form determines where the form first appears.
|-
| CenterScreen
| The form appears centered in the display.
|-
| WindowsDefaultLocation
| The form appears in the Windows default location, which is toward the upper left of the display.
|-
| WindowsDefaultBounds
| The form appears in the Windows default location with its bounds (size) set to the Windows default bounds.
|-
| CenterParent
| The form is centered within the bounds of its parent form.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Generally, it's best to set the StartPosition property of all your forms to CenterParent, unless you have a specific reason to do otherwise. For the very first form that appears in you project, you might consider using the WindowsDefaultLocation (but I generally prefer CenterScreen).
|}
Displaying a Form in a Normal, Maximized, or Minimized State
Using the Size and Location properties of a form in conjunction with the StartPosition property enables you to display forms at any location and at any size. You can also force a form to appear minimized or maximized. Whether a form is maximized, minimized, or shown normally is known as the form's state, and it's determined by the WindowState property.
Look at your form's WindowState property now. New forms have their WindowState property set to Normal by default. When you run the project, as you have several times, the form displays in the same size as it appears in the form designer, at the location specified by the form's Location property. Change the WindowState property now to Minimized. Nothing happens in the Form Design view, but run your project by pressing F5 and you'll see that the form is immediately minimized to the taskbar.
Stop the project and change the WindowState property to Maximized. Again, nothing happens in the Form Design window. Press F5 to run the project and notice how the form immediately maximizes to fill the entire screen.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| When a form is maximized, it fills the entire screen regardless of the current screen resolution being used in Windows.
|}
Stop the project and change the WindowState property back to Normal. Rarely will you set a form's WindowState property at design time to Minimize, but you'll probably encounter situations in which you need to change (or determine) the WindowState at runtime. As with most properties, you can accomplish this using code. For example, the following statement would minimize a form: <code>this.WindowState = FormWindowState. Minimized</code>. You don't have to remember the names of the values when entering code; you'll get an IntelliSense drop-down list when you type the period.
Changing the Mouse Pointer
You've no doubt used a program that altered the cursor when the pointer was moved over an object. This behavior is prevalent in Web browsers, in which the cursor is changed to the shape of a pointing hand when moved over a hyperlink. Using the Cursor property, you can specify the image of the pointer displayed when the pointer is over a form (or control).
Click the Cursor property of the form in the Properties window now and a drop-down arrow appears. Click the arrow to view a list of cursors (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig08 Figure 5.8]). Selecting a cursor from the list causes the pointer to change to that cursor when positioned over the form. Change the Cursor property of the form to AppStarting and press F5 to run the project. Move the pointer over the form and notice that the cursor changes to the AppStarting cursor while over the form and reverts to the default cursor when moved off the form. Stop the project now and click Save All on the toolbar to save your work.
<div style="text-align: center;">Figure 5.8. Use the Cursor property to designate the image of the pointer when it's moved over the object.
[[Image:05fig08.jpg|209px|graphics/05fig08.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Rarely will you want to change the cursor for a form, but you may find occasion to change the Cursor property for specific controls. Whenever you find yourself changing the default cursor for a form or control, choose a cursor that is consistent in purpose with well-known commercial applications.
|}
Showing and Hiding Forms
[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/part03.htm#part03 Part III] of this book is devoted to programming in C#, and I've avoided going into much programming detail in this hour so that you can focus on the concepts at hand. However, knowing how to create forms does nothing for you if you don't have a way to show and hide them. Because C# can display a single form automatically only when a program starts, you have to write code to show and hide other forms.
Showing Forms
In C#, everything is an object, and objects are based on classes (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects with Classes," for information on creating classes). Because the definition of a form is a class, you have to create a new Form object using the class as a template. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], "Understanding Objects and Collections," I discussed objects and object variables, and these principles apply to creating forms.
As discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], the process of creating an object from a class (template) is called instantiation. The syntax you'll use most often to instantiate a form is the following:
<pre>{ formclassname } {objectvariable} = new {formclassname()} ;
</pre>
The parts of this declaration are as follows:
* formclassname the name of the class that defines the form.
* objectvariable This is the name for the form that you will use in code.
* The keyword new Indicates that you want to instantiate a new object for the variable.
Last, you specify the name of the class used to derive the object�your form class. If you have a form class named fclsLoginDialog, for example, you could create a new Form object using the following code:
<pre>fclsLoginDialog frmLoginDialog = new fclsLoginDialog();
</pre>
Thereafter, for as long as the object variable remains in scope (scope is discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays"), you can manipulate the Form object using the variable. For instance, to display the form, you call the Show method of the form or set the Visible property of the form to true using code such as this:
<pre>frmLoginDialog.Show();
</pre>
or
<pre>frmLoginDialog.Visible = true;
</pre>
The easiest way to get the hang of this is to actually do it. To begin, choose Add Windows Form from the Project menu to display the Add New Item dialog box. Change the name of the form to fclsMyNewForm.cs (as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#ch05fig09 Figure 5.9]), and click Open to create the new form.
<div style="text-align: center;">Figure 5.9. When you change the default name of a form, remember to leave the .cs extension.
[[Image:05fig09.jpg|500px|graphics/05fig09.jpg]]
</div>
Your project now has two forms, as you can see by viewing the Solution Explorer window. The new form is displayed in the form designer, but right now you need to work with the main form. At the top of the main design area is a set of tabs. Currently, the tab fclsMyNewForm.cs [Design] is selected. Click the tab titled Form1.cs [Design] to show the designer for the first form.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Notice how the designer uses the filename rather than the object name on the tabs. You could right-click Form1.cs in the Solutions Explorer window and choose Rename to change the name of the file and therefore the name that appears on the tabs. You should actually do this in all your projects for the default forms. However, I haven't done this throughout the book because it adds yet another step to each example, and I don't want to complicate things too much.
|}
Add a new button to your original form by double-clicking the Button item on the toolbox (be careful not to add the button to the new form by mistake). Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowForm</code>
|-
| <code>Location</code>
| <code>112,112</code>
|-
| <code>Text</code>
| <code>Show Form</code>
|}
Double-click the button to access its Click event (double-clicking a control is a shortcut for accessing its default event) and enter the following code:
<pre>fclsMyNewForm frmTest = new fclsMyNewForm();
frmTest.Show();
</pre>
The first statement creates a new object variable and instantiates an instance of the fclsMyNewForm form. The second statement uses the object variable, now holding a reference to a Form object, to display the form. Press F5 to run the project and click the button. (If the button doesn't appear on the form, you may have accidentally added it to the wrong form). When you click the button, a new instance of the second form is created and displayed. Move this form and click the button again. Each time you click the button, a new form is created. Stop the project now and click Save All on the toolbar.
Understanding Form Modality
You can present two types of forms to the user: modal and nonmodal forms. The modality of a form is determined by how you show the form rather than by how you create the form (both modal and nonmodal forms are created the same way).
A nonmodal window is a window that doesn't cause other windows to be disabled. The forms you created in this example are nonmodal, which is why you were able to continue clicking the button on the first form even though the second form was displayed. Another example of a nonmodal window is the Find and Replace window in Word (and in C#, as well). When the Find and Replace window is visible, the user can still access other windows.
When a form is displayed as a modal form, on the other hand, all other forms in the same application become disabled until the modal form is closed; the other forms won't accept any keyboard or mouse input. The user is forced to deal only with the modal form. When the modal form is closed, the user is free to work with other visible forms within the program. Modal forms are most often used to create dialog boxes in which the user works with a specific set of data and controls before moving on. For instance, the Print dialog box of Microsoft Word is a modal dialog box. When the Print dialog box is displayed, the user cannot work with the document on the main Word window until the Print dialog box is closed. Most secondary windows in any given program are modal windows.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can display one modal form from another modal form, but you cannot display a nonmodal form from a modal form.
|}
To show a form as a modal form, you call the form's ShowDialog method rather than its Show method. Change the code in your button's Click event to read:
<pre>fclsMyNewForm frmTest = new fclsMyNewForm();
frmTest.ShowDialog();
</pre>
When your code looks like this, press F5 to run the project. Click the button to create an instance of the second form. Then, move the second form away from the first window and try to click the button again. You can't�because you've created a modal form. Close the modal form now by clicking the Close button in the title bar. Now, the first form is enabled again and you can click the button once more. When you are done testing this, stop the running project.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You can test to see whether a form has been shown modally by testing the form's Modal property.
|}
Unloading Forms
After a form has served its purpose, you'll want it to go away. However, "go away" can mean one of two things. First, you can make a form disappear without closing it or freeing its resources (this is called hiding). To do so, set its Visible property to false. This hides the visual part of the form, but the form still resides in memory and can still be manipulated by code. In addition, all the variables and controls of the form retain their values when a form is hidden, so that if the form is displayed again, the form looks the same as it did when its Visible property was set to false.
Second, you can completely close a form and release the resources it consumes. You should close a form when it's no longer needed, so Windows can reclaim all resources used by the form. To do so, you invoke the Close method of the form like this:
<pre>this.Close();
</pre>
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], you learned how this is used to reference the current Form object. Because this represents the current Form object, you can manipulate properties and call methods of the current form using this. (<code>this.Visible = false</code>, and so forth).
The Close method tells C# to not simply hide the form, but to destroy it completely. If variables in other forms are holding a reference to the form you close, their references will be set to null and will no longer point to a valid Form object (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12] for information on null).
Select the fclsMyNewForm.cs [Design] tab to display the form designer for the second form, add a new button to the form, and set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnCloseMe</code>
|-
| <code>Location</code>
| <code>112,112</code>
|-
| <code>Text</code>
| <code>Close Me</code>
|}
Double-click the button to access its Click event and then enter the following statement:
<pre>this.Close();
</pre>
Next, run the project by pressing F5. Click the Show Form button to display the second form, and then click the second form's button. The form will disappear. Again, the form isn't just hidden; the form instance is unloaded from memory and no longer exists. You can create a new one by single-clicking the Show Form button on the first form. When you're finished, stop the running project and save your work.
Summary
In this hour, you've learned the basics of creating forms. You've learned how to add them to your project, how to set basic appearance properties, and how to show and hide them using C# code. In the next hour, you'll learn more advanced functionality for working with forms. After you've mastered the material in this hour as well as in the next hour, you'll be ready to dig into C#'s controls; that's where the fun of building an interface really begins!
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#qad1e16659 Q1:]'''
| How many form properties should I define at design time vs. runtime?
|-
| align="right" | ''' A1: '''
| You should set all properties that you can at design time. First, it'll be easier to work with the form because you can see exactly what the user will see. Also, debugging is easier because there's less code.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/05.htm#qad1e16669 Q2:]'''
| Should I let the user minimize and maximize all forms?
|-
| align="right" | ''' A2: '''
| Probably not. First, there's no point in letting a form be maximized if you haven't anchored and aligned controls so that they adjust their appearance when the form is resized. In fact, if a form's contents don't change when a form is resized (including maximized), the form should not have a sizable border or a Maximize button.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans01 1:]'''
| True or False: The text displayed in the form's title bar is determined by the value in the TitleBarText property.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans02 2:]'''
| The named color Control is what kind of color?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans03 3:]'''
| In what three places are a form's icon displayed?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans04 4:]'''
| A window with a smaller than normal title bar is called what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans05 5:]'''
| For a Minimize or Maximize button to be visible on a form, what other element must be visible?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans06 6:]'''
| What, in general, is the best value to use for the StartPosition property of a form?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans07 7:]'''
| To maximize, minimize, or restore a form in code, you set what property?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans08 8:]'''
| True or False: To display a form, you must create a variable in code.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec5.htm#ch05ans09 9:]'''
| What property do you set to make a hidden form appear?
|}
Exercises
# Create a semitransparent form with a picture in its background. (Hint: Change the form's Opaque property.) Does the image become transparent? Add some controls to the form. Does the image appear behind or in front of the controls? (Hint: To create a transparent form, set the form's Opacity to something other than 100%�try 50%.)
# Create a Windows Application with three forms. Give the startup form two buttons. Make the other two forms tool windows, and make one button display one tool window and the other button display the second tool window.
hm5gkppqtm24zjqqw0hneqjua5knpww
User:Foxall/06
2
2137
39242
5598
2026-04-13T06:03:30Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39242
wikitext
text/x-wiki
== Hour 6. Building Forms�Part II ==
A form is just a canvas, and although you can tailor a form by setting its properties, you'll need to add controls to it to make it functional. In the previous hour, you learned how to add forms to a project, how to set basic form properties, and how to show and hide forms. In this hour, you'll learn all about adding controls to a form, including arranging and aligning controls to create a pleasing and functional interface. You also learn how to create advanced multiple document interfaces (MDIs), as employed in applications such as Word. After you complete the material in this hour, you'll be ready to learn the details about the various controls available in C#.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec1.htm#ch06lev2sec1 Adding controls to a form]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec1.htm#ch06lev2sec2 Positioning, aligning, sizing, spacing, and anchoring controls]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec1.htm#ch06lev2sec3 Creating intelligent tab orders]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec1.htm#ch06lev2sec4 Adjusting the z-order of controls]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec3.htm#ch06lev1sec3 Creating transparent forms]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec2.htm#ch06lev1sec2 Creating forms that always float over other forms]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec5.htm#ch06lev1sec5 Creating multiple-document interfaces]
----
=== Working with Controls ===
As discussed earlier, controls are the objects that you place on a form for users to interact with. If you've followed the examples in the previous hours, you've already added controls to a form. However, you'll be adding a lot of controls to forms, and it's important for you to understand all aspects of the process. Following the drill-down in this hour, the next two hours will teach you the ins and outs of the very cool controls provided by C#.
Adding Controls to a Form
All the controls that you can add to a form can be found in the toolbox. By default, the toolbox appears as a docked window on the left side of the design environment. This location is useful when you're only occasionally adding controls to forms. However, when doing serious form-design work, I find it best to dock the toolbox to the right side of the design environment, where it doesn't overlap so much (if at all) onto the form with which you're working.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Remember that before you can undock a toolbar to move it to a new location, you must make sure it isn't set to Auto Hide.
|}
The buttons on the toolbox are actually considered tabs because clicking one of them displays a specific page of controls. For most of your design, you'll use the controls on the Win Forms tab. However, as your skills progress, you may find yourself using more complex and highly specialized controls found on the other tabs.
You can add a control to a form in three ways, and you're now going to perform all three methods. Create a new Windows Application called Adding Controls. Change the name of the default form to fclsAddingControls and set its Text property to Adding Controls. Update the main entry point in the Main() function to reflect the new class name by clicking the View Code button on the Solution Explorer toolbar and then locating the reference to Form1 and replacing it with <code>fclsAddingControls</code>. Click Form1.cs [Design] to return to the form designer.
The easiest way to add a control to a form is to double-click the control in the toolbox. Try this now: display the toolbox and double-click the TextBox tool. C# creates a new text box in the upper-left corner of the form. Of course, you're free to move and size the text box as you please. Nevertheless, when you double-click a control in the toolbox, C# always creates the control in the upper-left corner, with the default size for the type of control you're adding.
If you want a little more authority over where the new control is placed, you can drag a control to the form. Try this now: display the toolbox and then click the Button control and drag it to the form. When the cursor is roughly where you want the button created, release the mouse button.
The last and most precise method of placing a control on a form is to "draw" the control on a form. Display the toolbox now and click the ListBox tool once to select it. Next, move the pointer to where you want the upper-left corner of the list box to appear and then click and hold the mouse button. Drag the pointer to where you want the bottom-right corner of the list box to be and release the button. The list box is created with its dimensions set to the rectangle you drew on the form. This is by far the most precise method of adding controls to a form.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| If you prefer to draw controls on your forms by clicking and dragging, I strongly suggest that you dock the toolbox to the right or bottom edge of the design environment or float it. The toolbox tends to interfere with drawing controls when it's docked to the left edge, because it obscures part of the form.
|}
It's important to note that the very first item on the Windows Forms tab, titled Pointer, isn't actually a control. When the pointer item is selected, the design environment is placed in Select mode rather than in a mode to create a new control. With the pointer selected, you can select a control simply by clicking it, displaying all its properties in the Properties window. This is the default behavior of the development environment.
Manipulating Controls
Getting controls on a form is the easy part. Arranging them so that they create an intuitive and attractive interface is the challenge. Interface possibilities are nearly endless, so I can't tell you how to design any given interface. However, I can show you the techniques to move, size, and arrange controls so that they appear the way you want them to. By mastering these techniques, you'll be much faster at building interfaces, freeing your time for writing the code that makes things happen.
Using the Grid (Size and Snap)
When you first install C#, all forms appear with a grid of dots on them. When you draw or move controls on a form with a grid, the coordinates of the control automatically snap to the nearest grid coordinate. This offers some precision when adjusting the size and location of controls. In practical use, I often find the grid to be only slightly helpful because the size or location you want to specify often doesn't fit neatly with the grid locations. You can, however, control the granularity and even the visibility of the grid, and I suggest you do both.
You're now going to assign a higher level of granularity to the grid (the space between the grid points will be smaller). I find that this helps with design, without causing edges to snap to unwanted places.
To adjust the granularity of the grid on a form, you change the GridSize property (or the Width and Height subproperties of the GridSize property). Setting the Width or Height of the grid to a smaller number creates a smaller grid, which allows for finer control over sizing and placement, whereas using larger values creates a much larger grid and offers less control. With a larger grid, you'll find that edges snap to grid points much easier and at larger increments, making it impossible to fine-tune the size or position of a control. Change the GridSize property of your form now to 4,4. Notice that a lot more grid dots appear (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig01 Figure 6.1]).
<div style="text-align: center;">Figure 6.1. Grids can be distracting.
[[Image:06fig01.jpg|500px|graphics/06fig01.jpg]]
</div>
Try dragging the controls on your form or dragging their edges to size them. Notice that you have more control over the placement with the finer grid. Try changing the GridSize to a set of higher numbers, such as 25,25 and see what happens. When you're finished experimenting, change the GridSize values back to 4,4.
An unfortunate side effect of a smaller grid is that the grid can become quite distracting. Again, you'll decide what you like best, but I generally turn grids off on my form. You do this by setting the DrawGrid property of the form to false. Try hiding the grid of your form now.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| This property determines only whether the grid is drawn, not whether it's active; grids are always active, regardless of whether they're visible.
|}
Selecting a Group of Controls
As your skills grow, you'll find your forms becoming increasingly complex. Some forms may contain dozens, or even hundreds, of controls. C# has a set of features that makes it easy to align groups of controls.
Create a new Windows Application titled Align Controls. Change the name of the default form to fclsAlignControls and set its Text property to Control Alignment Example. Next, update the main entry point in the Main() function to reflect the new class name by clicking the View Code button on the Solution Explorer toolbar and then locating the reference to Form1 and replacing it with <code>fclsAlignControls</code>. Click Form1.cs [Design] to return to the form designer.
Double-click the TextBox tool in the toolbox to add a text box to the form. Set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txt1</code>
|-
| <code>Location</code>
| <code>20</code>, <code>20</code>
|-
| <code>Multiline</code>
| <code>True</code>
|-
| <code>Size</code>
| <code>100</code>, <code>30</code>
|-
| <code>Text</code>
| <code>txt1</code>
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you don't set the Multiline property of a text box to true, C# ignores the Height setting (the second value of the Size property) and instead, keeps the height at the standard height for a single-line text box.
|}
Use the same technique (double-click the TextBox item in the toolbox) to add two more text boxes to the form. Set their properties as follows:
Text Box 2:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txt2</code>
|-
| <code>Location</code>
| <code>90</code>, <code>80</code>
|-
| <code>Multiline</code>
| <code>True</code>
|-
| <code>Size</code>
| <code>50</code>, <code>50</code>
|-
| <code>Text</code>
| <code>txt2</code>
|}
Text Box 3:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txt3</code>
|-
| <code>Location</code>
| <code>140</code>, <code>200</code>
|-
| <code>Multiline</code>
| <code>True</code>
|-
| <code>Size</code>
| <code>100</code>, <code>60</code>
|-
| <code>Text</code>
| <code>txt3</code>
|}
Your form should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig02 Figure 6.2]. Save the project now by clicking the Save All button on the toolbar.
<div style="text-align: center;">Figure 6.2. It's easy to align and size controls as a group.
[[Image:06fig02.jpg|500px|graphics/06fig02.jpg]]
</div>
By default, clicking a control on a form selects it while deselecting any controls that were previously selected. To perform actions on more than one control, you need to select a group of controls. You can do so in one of two ways, the first of which is to lasso the controls. To lasso a group of controls, you first click and drag the mouse pointer anywhere on the form. As you drag the mouse, a rectangle is drawn on the form. When you release the mouse button, all controls intersected by the rectangle become selected. Note that you don't have to completely surround a control with the lasso (also called a marquee), you only have to intersect part of the control to select it. Try this now: click somewhere in the upper-right corner of the form and drag the pointer toward the bottom of the form without releasing the button (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig03 Figure 6.3]). When the rectangle has surrounded or intersected all the controls, release the button and the controls will be selected (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig04 Figure 6.4]).
<div style="text-align: center;">Figure 6.3. Click and drag to create a selection rectangle.
[[Image:06fig03.jpg|500px|graphics/06fig03.jpg]]
</div>
<div style="text-align: center;">Figure 6.4. All selected controls appear with a hatched border and sizing handles.
[[Image:06fig04.jpg|500px|graphics/06fig04.jpg]]
</div>
When a control is selected, it has a hatched border and a number of sizing handles (the rectangles in the hatched border at the corners and midpoints of the control). Pay careful attention to the sizing handles. The control with the black-centered sizing handles is the active control in the selected group. When you use C#'s tools, such as the alignment and formatting features, to work on a group of selected controls, the values of the active control are used. For example, if you were to align the left side of the selected controls shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig04 Figure 6.4], each of the controls would have its Left property value set to that of the active control. When you use the lasso technique to select a group of controls, you really don't have much authority over which control C# makes the active control. In this example, you want to align all controls to the control at the top, so you'll have to use a different technique to select the controls. Deselect all the controls now by clicking anywhere on the form (other than on a control).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| When the sizing handle of an active control is colored white, you can click and drag the handle to alter the size of the control. Not all sizing handles are movable at all times. For example, before you set the Multiline property of a text box to true, C# won't allow you to change the height of the text box, so only the sizing handles at the left and right edges are movable and therefore are colored white.
|}
The second technique for selecting multiple controls is to use the Shift or Ctrl key; this method is much like selecting multiple files in Windows Explorer. Click the bottom control (txt3) now to select it. Notice that its sizing handles are outlined in black; because it's the only control selected, it's automatically made the active control. Now hold down the Shift key and click the center control (txt2); txt2 and txt3 are now selected. However, txt2 is the active control (when multiple controls are selected, the active control has black-filled sizing handles rather than white). When you add a control to a group of selected controls, the newly selected control is always made the active control. Finally, with the Shift key still pressed, click txt1 to add it to the group of selected controls. All the controls should now be selected and txt1 should be the active control.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Clicking a selected control while Shift is held down deselects the control.
|}
You can combine the two selection techniques when needed. For instance, you could first lasso all controls to select them. If the active control isn't the one you want it to be, you could hold the Shift key down and click the control you want made active, thereby deselecting it. Clicking the control a second time while still holding down the Shift key would again select the control. Because the control would then be the last control added to the selected group, it would be made active.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you must click the same control twice, such as to deselect and then reselect, do so slowly. If you click too fast, C# interprets your actions as a double-click, and it creates a new event handler for the control.
|}
Aligning Controls
Now that you've selected all three controls, open C#'s Format menu (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig05 Figure 6.5]). The Format menu has a number of submenus containing functions to align, size, and format groups of controls. Open the Align submenu now to see the available options (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig06 Figure 6.6]).
<div style="text-align: center;">Figure 6.5. Use the Format menu to quickly whip an interface into shape.
[[Image:06fig05.jpg|500px|graphics/06fig05.jpg]]
</div>
<div style="text-align: center;">Figure 6.6. The Align menu makes it easy to align an edge of a group of controls.
[[Image:06fig06.jpg|247px|graphics/06fig06.jpg]]
</div>
The top three items on the Align menu are used to align the selected controls horizontally, and the middle three items align the selected controls vertically. The last item, To Grid, will snap the corners of all the selected controls to the nearest grid points. Choose Align Lefts now, and C# aligns the left edges of the selected controls. Notice how the Left edge of the active control is used as the baseline for the alignment (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig07 Figure 6.7]).
<div style="text-align: center;">Figure 6.7. The property values of the active control are always used as the baseline values.
[[Image:06fig07.jpg|500px|graphics/06fig07.jpg]]
</div>
Making Controls the Same Size
In addition to aligning controls, you can als o make all selected controls the same size�Height, Width, or Both. To do this, use the Make Same Size submenu on the Format menu (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig08 Figure 6.8]). Make all your controls the same size now by choosing Both from the Make Same Size menu. As with the Align function, the values of the active control are used as the baseline values.
<div style="text-align: center;">Figure 6.8. Use this menu to quickly make a group of controls the same size.
[[Image:06fig08.jpg|261px|graphics/06fig08.jpg]]
</div>
Evenly Spacing a Group of Controls
As many a salesman has said, "…and that's not all!" You can also make the spacing between controls uniform using the Format menu. Try this now: open the Vertical Spacing submenu of the Format menu and then choose Make Equal. All the controls are now evenly spaced. Next, choose Decrease from the Vertical Spacing menu and notice how the spacing between the controls decreases slightly. You can also increase the vertical spacing or completely remove vertical space from between controls using this menu. To perform the same functions on the horizontal spacing between controls, use the Horizontal Spacing submenu of the Format menu. Save your project now by clicking the Save All button on the toolbar.
Setting Property Values for a Group of Controls
You can change a property value in the Properties window when multiple controls are selected, and the change will be made to all controls. To do this, make sure all three controls are still selected and then display the Properties window.
When a group of controls is selected, the Properties window appears with some modifications (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig09 Figure 6.9]):
* No Name property is shown. This occurs because it's not allowable to have two controls with the same name, so C# won't even let you try.
* Only properties shared by all controls are displayed. If you had selected a label control and a text box, for example, only the properties shared by both control types would appear.
* For properties in which the values of the selected controls differ (such as the Location property in this example), the value is left empty in the Properties window.
<div style="text-align: center;">Figure 6.9. You can view the property values of many controls at once, with some caveats.
[[Image:06fig09.jpg|253px|graphics/06fig09.jpg]]
</div>
Entering a value in any property changes the corresponding property for all selected controls. To see how this works, change the BackColor property to a shade of yellow, and you'll see that all controls have their BackColor set to yellow.
Anchoring and Autosizing Controls
One of my favorite additions to the forms engine in C# is the capability to anchor controls to one or more edges of a form so that controls can now size themselves appropriately when the user sizes the form. In the past, you had to use a (usually cumbersome) third-party component or resort to writing code in the form Resize event to get this behavior, but it's an intrinsic capability of C#'s form engine.
The default behavior is that controls are docked to the top and left edges. What if you want a control to always appear in the lower-left corner of a form? This is precisely what the Anchor property is designed to handle.
The easiest way to understand how anchoring works is to do it.
# Create a new Windows Application called Anchoring Example.
# Change the name of the default form to fclsAnchoringExample and set the form's Text property to Anchoring Example.
# Change the main entry point to reflect the new form name.
# Add a new button to the form and name it btnAnchor.
# Run the project by pressing F5.
# Click and drag the border of the form to change its size.
Notice that no matter what size you change the form to, the button stays in the upper-left corner of the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig10 Figure 6.10]).
<div style="text-align: center;">Figure 6.10. By default, controls are anchored to the upper-left corner of the form.
[[Image:06fig10.jpg|500px|graphics/06fig10.jpg]]
</div>
Stop the running project now by choosing Stop Debugging from the Debug menu. Click the button on the form to select it, click the Anchor property, and then click the drop-down arrow that is displayed. You'll see a drop-down box that is unique to the Anchor property (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig11 Figure 6.11]).
<div style="text-align: center;">Figure 6.11. You use this unique drop-down box to set the Anchor property of a control.
[[Image:06fig11.jpg|500px|graphics/06fig11.jpg]]
</div>
The gray square in the center of the drop-down box represents the control whose property you are setting. The thin rectangles on the top, bottom, left, and right represent the possible edges to which you can dock the control; if a rectangle is filled in, the edge of the control facing that rectangle is docked to that edge of the form.
# Click the rectangle above the control so that it's no longer filled in, and then click the rectangle to the right of the control so that it is filled in.
# Click any other property to close the drop-down box. The Anchor property should now read LeftRight.
# Press F5 to run the project, and then drag an edge of the form to make it larger.
Pretty odd, huh? What C# has done is anchored the left edge of the button to the left edge of the form and anchored the right edge of the button to the right edge of the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig12 Figure 6.12]). Really, anchoring means keeping an edge of the control a constant relative distance from an edge of the form, and it's an unbelievably powerful tool for building interfaces. Now you can make forms that users can resize, but you write little or no code to make the interface adjust accordingly. One caveat: depending on their anchor settings, controls may disappear if the form is shrunk quite small.
<div style="text-align: center;">Figure 6.12. Anchoring is a powerful feature for creating adaptable forms.
[[Image:06fig12.jpg|500px|graphics/06fig12.jpg]]
</div>
Creating a Tab Order
Tab order is something that is often (emphasis on often) overlooked. You're probably familiar with tab order as a user, although you may not realize it. When you press Tab while on a form, the focus moves from the current control to the next control in the tab order. This allows easy keyboard navigation on forms. The tab order for controls on a form is determined by the TabIndex properties of the controls. The control with the TabIndex value of 0 is the first control that receives the focus when the form is shown. When you press Tab, the control with the TabIndex of 1 receives the focus. When you add a control to a form, C# assigns the next available TabIndex value. Each control has a unique TabIndex value, and TabIndex values are always used in ascending order.
If the tab order isn't set correctly for a form, pressing Tab will cause the focus to jump from control to control in no apparent order. This really isn't a way to impress users.
The forms engine in C# has a far superior way to set the tab order for controls on a form. Create a new Windows Application named Tab Order, change the name of the default form to fclsTabOrder, set the Text property of the form to Tab Order Example and update the entry point with the fclsTabOrder reference.
Add three text box controls to the form and set their properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
| Property
| Value
| Property
| Value
|-
| <code>Name</code>
| <code>TextBox1</code>
| <code>Name</code>
| <code>TextBox2</code>
| <code>Name</code>
| <code>TextBox37</code>
|-
| <code>Location</code>
| <code>90,120</code>
| <code>Location</code>
| <code>90,50</code>
| <code>Location</code>
| <code>90,190</code>
|}
Save the project by clicking the Save All button on the toolbar and then press F5 to run the project. Notice how the middle text box is the one with the focus. This is because it's the first one you added to the form and therefore has a TabIndex value of 0. Press Tab to move to the next control in the tab order (the top control); then press Tab once more and the focus jumps to the bottom control. Obviously, this isn't productive. Stop the project now by choosing Stop Debugging from the Debug menu (or simply close the form).
You're now going to set the tab order via the new visual method. Choose Tab Order from the View menu; notice how C# superimposes a set of numbers over the controls (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig13 Figure 6.13]). The number on a control indicates its TabIndex property value. Now it's very easy to see that the tab order is incorrect. Click the top control. Notice how the number over the control changes to 0. Click the middle control and you'll see its number change to 1. As you click controls, C# assigns the next highest number to the clicked control. Choose Tab Order from the View menu again to take the form out of Tab Order mode. Run the project again and you'll see that the top control is the first to get the focus, and pressing Tab now moves the focus logically.
<div style="text-align: center;">Figure 6.13. The numbers over each control indicate the control's TabIndex.
[[Image:06fig13.jpg|300px|graphics/06fig13.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To programmatically move the focus via the tab order, use the SelectNextControl() method of a control or a form.
|}
To remove a control from the tab sequence, set its TabStop property to false. When a control's TabStop property is set to false, users can still select the control with the mouse, but they can't enter the control using the Tab key. You should still set the TabIndex property to a logical value so that if the control receives the focus (such as by being clicked), pressing Tab will move the focus to the next logical control.
Layering Controls (Z-Order)
Tab order and visual alignment are key elements for effectively placing controls on forms. However, these two elements address control placement in only two dimensions�the x,y axis. At times, you may need to have controls overlap, although it's rare that you'll need to do so. Whenever two controls overlap, whichever control is added to the form most recently appears on top of the other (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig14 Figure 6.14]). You can control the ordering of controls using the Order submenu of the Format menu (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig15 Figure 6.15]).
<div style="text-align: center;">Figure 6.14. Controls can overlap.
[[Image:06fig14.jpg|500px|graphics/06fig14.jpg]]
</div>
<div style="text-align: center;">Figure 6.15. The Order menu is used to adjust the layering order of overlapping controls.
[[Image:06fig15.jpg|276px|graphics/06fig15.jpg]]
</div>
To send a control backward in the layering order, click it once to select it and then choose Send to Back from the Order menu. To bring the control forward in the layering order, select the control and choose Bring to Front from the Order menu.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| You can accomplish the same thing in C# code by invoking the BringToFront or SendToBack methods of a control.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating TopMost Windows
As you're probably aware, when you click a window it usually comes to the foreground and all other windows appear behind it. At times, you may want a window to stay on top of other windows, regardless of whether it's the current window (that is, it has the focus). An example of this is the Find window in C# and other applications such as Word. Regardless of which window has the focus, the Find form always appears floating over all other windows. Such a window is created by setting the form's TopMost property to true. Not exactly rocket science. However, that's the point; often a simple property change or method call is all it takes to accomplish what may otherwise seem to be a difficult task.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating Transparent Forms
A new property of forms that I think is very cool, yet I still can't come up with a reason to use it in a production application, is the Opacity property. This property controls the opaqueness of the form as well as all controls on the form. The default Opacity value of 100% means that the form and its controls are completely opaque (solid), whereas a value of 0% creates a completely transparent form (no real point in that). A value of 50% then, creates a form that is between solid and invisible (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig16 Figure 6.16]). I suppose you could write a loop that takes the Opaque property from 100% to 0% to fade out the form. Other than that, I don't know where to take advantage of this technique. But ain't it cool?
<div style="text-align: center;">
[[Image:06fig16.jpg|500px|graphics/06fig16.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec2.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch06lev1sec4.htm [[Image:next.gif|41px|Next Section]]]
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#toppage ]<br />
|}
Creating Scrollable Forms
A scrollable form is a form that can display scrollbars when its contents are larger than the physical size of the form. Not only is this a cool and necessary feature, it's also trivial to implement in your own applications.
The scrolling behavior of a form is determined by the following three properties:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Description
|-
| AutoScroll
| This property determines whether scrollbars will ever appear on a form.
|-
| AutoScrollMinSize
| The minimum size of the scroll region (area). If the size of the form is adjusted so that the client area of the form (the area of the form not counting borders and title bar) is smaller than the AutoScrollMinSize, scrollbars will appear.
|-
| AutoScrollMargin
| This property determines the margin given around controls during scrolling. This essentially determines how far past the edge of the outermost controls you can scroll.
|}
Again, it's easiest to understand this concept by doing it. Create a new Windows Application named AutoScroll Example, rename the default form to fclsAutoScroll, set the text of the form to AutoScroll Example, and update the entry point in Main().
Add a new Button control to the form by double-clicking the Button tool on the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnTest</code>
|-
| <code>Location</code>
| <code>110,120</code>
|-
| <code>Text</code>
| <code>Test</code>
|}
Save the project and press F5 to run it. Drag the borders of the control to make it larger and smaller. Notice that no matter how small you make the form, no scrollbars appear. This makes it possible to have controls on the form that are only partially visible or that can't be seen at all (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig17 Figure 6.17]).
<div style="text-align: center;">Figure 6.17. Without scrollbars, it's possible to have controls that can't be seen.
[[Image:06fig17.jpg|153px|graphics/06fig17.jpg]]
</div>
Stop the project now by choosing Stop Debugging from the Debug menu or by closing the form. Change the AutoScroll property of the form to true. At this point you still won't get scrollbars, because you need to adjust at least one of the other scroll properties. Change the AutoScrollMargin property to 50,50 and run the project once more. Make the form smaller by dragging a border or a corner, and you'll see scrollbars appear (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig18 Figure 6.18]). The AutoScrollMargin property creates a virtual margin (in pixels) around all the outermost controls on the form. If the form is sized to within the margin area of a control, scrollbars automatically appear.
<div style="text-align: center;">Figure 6.18. Scrollbars allow the user to view all parts of the form without needing to change the form's size.
[[Image:06fig18.jpg|500px|graphics/06fig18.jpg]]
</div>
The final property that affects scrolling is the AutoScrollMinSize. Use the AutoScrollMinSize property to create a fixed-size scrolling region. If the form is ever sized such that the visible area of the form is smaller than the scrolling region defined by AutoScrollMinSize, scrollbars appear.
Creating MDI Forms
All the projects you've created so far have been single-document interface (SDI) projects. In SDI programs, every form in the application is a peer of all other forms; no intrinsic hierarchy exists between forms. C# also lets you create multiple-document interface (MDI) programs. A MDI program contains one parent window (also called a container) and one or more child windows. A classic example of a MDI program is Microsoft Word 95 (200 behaves slightly different, depending on how it's set up). When you run Word 97, a single parent window appears. Within this parent window, you can open any number of documents, which appear in child windows. In a MDI program, all child windows share the same toolbar and menu bar, which appears on the parent window. One restriction of child windows is that they can exist only within the confines of the parent window. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig19 Figure 6.19] shows an example of Word running with a number of child document windows open.
<div style="text-align: center;">Figure 6.19. MDI applications consist of a single parent window and one or more child windows.
[[Image:06fig19.gif|500px|graphics/06fig19.gof]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| MDI applications can have any number of normal windows (dialog boxes, for example) in addition to child windows.
|}
You're now going to create a simple MDI project. Create a new Windows Application named MDI Example. Change the name of the default form to fclsMDIParent, change its Text property to MDI Parent, update the entry point, and change its IsMdiContainer property to true (If you don't set the IsMdiContainer property to true, this example won't work). The first thing you'll notice is that C# changed the client area to a dark gray and gave it a sunken appearance. This is the standard appearance for MDI parent windows, and all visible child windows appear in this area.
Create a new form by choosing Add Windows Form from the Project menu. Name the form fclsChild1.cs and change its Text property to Child 1. Add a third form to the project in the same way. Name it fclsChild2.cs and set its Text property to Child 2. Any form can be a child form (except, of course, a MDI parent form). To make a form a child form, you set its MDIParent property to a form that is defined as a MDI container.
Make sure the fclsMDIParent parent form is visible in the form designer. If it's not, you can display it by double-clicking it in the Solution Explorer. Next, double-click the form to access its default event�the Load event. Enter the following code:
<pre>fclsChild1 objChild = new fclsChild1();
objChild.MdiParent = this;
objChild.Show();
</pre>
By now, you should know what this code does. The first statement creates a new object variable of type fclsChild1 and initializes it to hold a new instance of a form. The last statement simply shows the form. What we're interested in here is the middle statement. It sets the MdiParent property of the form to the current form (<code>this</code> always references the current object), which is a MDI parent form because its IsMdiContainer property is set to true. When the new form is shown, it's shown as a MDI child. Save your work and then press F5 to run the project. Notice how the child form appears on the client area of the parent form. If you size the parent form so that one or more child windows can't fully be displayed, scrollbars appear (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig20 Figure 6.20]). If you were to remove the statement that set the MdiParent property, the form would simply appear floating over the parent form and would not be bound by the confines of the parent (it wouldn't be a child window).
<div style="text-align: center;">Figure 6.20. Child forms appear only within the confines of the parent form.
[[Image:06fig20.jpg|291px|graphics/06fig20.jpg]]
</div>
Stop the project by choosing Stop Debugging from the Debug menu. Display the Solution Explorer and double-click the fclsChild1 form in its designer to display it in the designer. Add a button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowChild2</code>
|-
| <code>Location</code>
| <code>105</code>,<code>100</code>
|-
| <code>Size</code>
| <code>85</code>,<code>23</code>
|-
| <code>Text</code>
| <code>Show Child 2</code>
|}
Double-click the button to access its Click event, and then add the following code:
<pre>fclsChild2 objChild = new fclsChild2();
objChild.MdiParent = this.MdiParent;
objChild.Show();
</pre>
This code shows the second child form. Note that two differences exist between this code and the code you entered earlier. First, the objChild variable creates a new instance of the fclsChild2 form rather than the fclsChild1 form. The second difference is how the parent is set. Because the child form is not a parent form, you can't simply set the second child's MdiParent property to this, because this doesn't refer to a parent form. However, you know that this.MdiParent references the parent form because this is precisely the property you set to make the form a child in the first place. Therefore, you can simply pass the parent of the first child to the second child, and they'll both be children of the same form.
Press F5 to run the project now. You'll see the button on the child form, so go ahead and click it (if you don't see the button, you may have mistakenly added it to the second child form). When you click the button, the second child form appears. Notice how this is also bound by the constraints of the parent form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig21 Figure 6.21]).
<div style="text-align: center;">Figure 6.21. Child forms are peers with one another.
[[Image:06fig21.jpg|500px|graphics/06fig21.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The MDI parent form has an ActiveMdiChild property, which you can use to get a reference to the currently active child window.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To make the parent form larger when the project is first run, you set the Height and Width properties of the form either at design time or at runtime in the Load event of the form.
|}
One thing about forms that is important to note is that you can create as many instances of a form as you desire. For instance, you could change the code in the button to create a new instance of fclsChild1. The form that would be created would be the same as theform that created it, complete with a button to create yet another instance. Although you probably won't apply this technique because you're just getting started with C#, you may find it quite useful in the future. For instance, if you wanted to create a text editor, you might define the text entry portion as one form but create multiple instances of the form as new text files are opened, much like Word does with documents.
Setting the Startup Object
The Startup object in Windows Applications is, by default, the first form added to the project. This also happens to be the form that C# creates automatically when you create the new Windows Application project. Although the Startup object of a project was discussed briefly in a previous hour, it's worth mentioning here as well. Every project must have a Startup object as the entry point to the program.
The class that contains the Main() method that you want called as the entry point of the application is determined by the Startup Object property. You can change the Startup object by right-clicking the project name in the Solution Explorer and choosing Properties. The Startup Object property appears on the first property page that displays (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#ch06fig22 Figure 6.22]).
<div style="text-align: center;">Figure 6.22. The Startup Object property determines the first class that gets initialized and executed.
[[Image:06fig22.jpg|500px|graphics/06fig22.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The setting of the Startup Object property isn't required if only one <code>Main()</code> method exists in the project.
|}
If MDI forms still confuse you, don't worry. Most of the applications you'll write as a new C# programmer will be SDI programs. As you become more familiar with creating C# projects in general, start experimenting with MDI projects. Remember, you don't have to make a program a MDI program simply because you can; make a MDI program if the requirements of the project dictate that you do so.
Summary
Understanding forms is critical because forms are the dynamic canvases on which you build your user interface. If you don't know how to work with forms, your entire application will suffer. Many things about working with forms go beyond simply setting properties, especially as you begin to think about the end user. As your experience grows, you'll get into the groove of form design and things will become second nature to you.
In this hour, you learned how to do some interesting things, such as creating transparent forms, as well as some high-end techniques, such as building an MDI application. You also learned how to create scrolling forms (an interface element that shouldn't be overlooked), and you spent a lot of time on working with controls on forms, which is important because the primary function of a form is as a place to host controls. In the next two hours, you'll learn the details of many of C#'s powerful controls that will eventually become important weapons in your vast development arsenal.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#qad1e19828 Q1:]'''
| Do I need to worry about the anchoring and scrolling capabilities of every form I create?
|-
| align="right" | ''' A1: '''
| Absolutely not. The majority of forms in most applications are dialog boxes. A dialog box is a modal form used to gather data from the user. A dialog box is usually a fixed size, which means that its border style is set to a style that cannot be sized. With a fixed-size form, you don't need to worry about anchoring or scrolling.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/06.htm#qad1e19841 Q2:]'''
| How do I know if a project is a candidate for a MDI interface?
|-
| align="right" | ''' A2: '''
| If the program will open many instances of the same type of form, it's a candidate for a MDI interface. For instance, if you're creating an image-editing program and the intent is to allow the user to open many images at once, MDI makes sense. Also, if you'll have many forms that will share a common toolbar and menu, you might want to consider MDI.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans01 1:]'''
| True or False: The first control selected in a series is always made the active control.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans02 2:]'''
| How many methods are there to add a control to a form from the toolbox?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans03 3:]'''
| If you double-click a tool in the toolbox, where on the form is it placed?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans04 4:]'''
| Which property fixes an edge of a control to an edge of a form?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans05 5:]'''
| Which property do you change to hide the grid on a form?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans06 6:]'''
| Which menu contains the functions for spacing and aligning controls?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec6.htm#ch06ans07 7:]'''
| Which property do you set to make a form a MDI parent?
|}
Exercises
# Use your knowledge of the Anchor property and modify the Picture Viewer project you built in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1] so that the main form can be sized. The buttons should always stay the size that they are and in the relative location in which they're placed, but the picture box should change size to show as much of the picture as possible, given the size of the form.
# Modify the MDI Example project in this hour so that the first child form shows another instance of itself, rather than showing an instance of the second child form.
rpry0s318hhqqs0avrhdw6kvvssooqb
User:Foxall/07
2
2138
39243
5599
2026-04-13T06:03:31Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39243
wikitext
text/x-wiki
== Hour 7. Working with the Traditional Controls ==
The previous two hours described in considerable detail how to work with forms. Forms are the foundation of a user interface but are rather useless by themselves. To create a usable interface, you'll need to use controls. Controls are the various widgets and doodads on a form with which a user interacts. Dozens of different types of controls exist, from the simple Label control used to display static text to the rather complicated Tree View control used to present trees of data like that found in Explorer. In this hour, I'll introduce you to the most common (and most simple) controls, which I call traditional controls. In the next hour, you'll learn about the more advanced controls that you can use to create professional-looking applications.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec1.htm#ch07lev1sec1 Displaying static text with the Label control]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec2.htm#ch07lev1sec2 Allowing users to enter text using a text box]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec2.htm#ch07lev2sec5 Creating password fields]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec4.htm#ch07lev2sec10 Working with buttons]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec4.htm#ch07lev2sec8 Using panels, group boxes, check boxes, and option buttons]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07lev1sec5.htm#ch07lev1sec5 Displaying lists with list boxes and combo boxes]
----
=== Displaying Static Text with the Label Control ===
Label controls are used to display static text to the user. By static, I mean that the user can't change the text directly (but you can change the text with code). Label controls are one of the most common controls used; fortunately, they're also one of the easiest. Labels are most often used to provide descriptive text for other controls, such as text boxes. Labels are also great for providing status-type information to a user, as well as for providing general instructions on a form.
Begin by creating a new Windows Application named Traditional Controls. Change the name of the default form to fclsControls, and change its Text property to Traditional Controls Example. Next, change the Main entry point to use flcsControls.
Add a new Label control to the form by double-clicking the Label item in the toolbox. The primary property of the Label control is the Text property, which determines the text displayed to the user. When a Label control is first added to a form, the Text property is set to the name of control�this isn't very useful. Set the properties of the new Label control as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lblMyLabel</code>
|-
| <code>Location</code>
| <code>5,6</code>
|-
| <code>Size</code>
| <code>100,25</code>
|-
| <code>Text</code>
| <code>Labels are for static text!</code>
|}
Notice how the label's text appears on two lines (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig01 Figure 7.1]). This occurs because the text is forced to fit within the size of a new Label control. In most cases, it's best to place label text on a single line. To do this, you could increase the width either by using the Properties window or by dragging the edge of the control, but there is an easier way. Double-click the Label control's AutoSize property now and notice how the label resizes itself automatically to fit the text on a single line. Double-clicking a property that accepts a set number of values cycles the property to the next value. The AutoSize property of new Label controls is false by default, so double-clicking this property changed it to <code>true</code>.
<div style="text-align: center;">
</div>
Allowing Users to Enter Text Using a Text Box
A Label control is usually the best control for displaying text a user can't change. However, when you need to let users enter or edit text, the text box is the tool for the job. If you've ever typed information on a form, you've almost certainly used a text box. Add a new text box to your form now by double-clicking the TextBox item in the toolbox. Set the text box's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtMyTextBox</code>
|-
| <code>Location</code>
| <code>128,4</code>
|-
| <code>Size</code>
| <code>136,20</code>
|}
When you first create a new text box, its Text property is set to its default name (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig02 Figure 7.2]). Unfortunately, the Text property isn't automatically changed when you change the name of the text box (which you should always do), so I recommend that you clear out the Text property of new text boxes. Delete the text in the Text property now and notice that the text box appears empty on the form.
<div style="text-align: center;">Figure 7.2. A new text box has its Text property set to its default name.
[[Image:07fig02.jpg|500px|graphics/07fig02.jpg]]
</div>
Although you'll probably want to clear the Text property of most of your text boxes at design time, understanding certain aspects of the text box is easier when a text box contains text. Set the text box's Text property to This is sample text. Remember to press Enter or Tab to commit your property change.
Specifying Text Alignment
Both the TextBox and the Label controls have a TextAlign property (as do many other controls). The TextAlign property determines the alignment of the text within the control�very much like the justification setting in a word processor. You can select from Left, Center, or Right.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Label controls allow you to set the vertical alignment and the horizontal alignment using the TextAlign property. This works best when AutoSize is set to false.
|}
Change the TextAlign property of the text box to Right, and see how the text becomes right-aligned within the text box. Next, change TextAlign to Center to see what center alignment looks like. As you can see, this property is pretty straightforward. Change the TextAlign property back to Left before continuing.
Creating a Multiline Text Box
In the previous hour, I talked about the sizing handles of a selected control. I mentioned how handles that can be sized appear filled with white, and handles that are locked appear with a gray center. Notice how only the left and right edges of the text box have white sizing handles. This means that you can adjust only the left and right edges of the control (you can alter only the width, not the height). This is because the text box is defined as a single-line text box, meaning it will display only one line of text. What would be the point of a really tall text box that showed only a single line?
To allow a text box to display multiple lines of text, set its Multiline property to true. Set the Multiline property of your text box to true now, and notice that all the sizing handles become white.
Change the Text property of the text box to This is sample text. A multiline text box will wrap its contents as necessary. Press Enter or Tab to commit the property change. Notice how the text box displays only part of what you entered because the control simply isn't big enough to show all the text (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig03 Figure 7.3]). Change the Size property to 136,60, and you'll then see the entire content of the text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig04 Figure 7.4]).
<div style="text-align: center;">Figure 7.3. A text box may contain more text than it can display.
[[Image:07fig03.jpg|500px|graphics/07fig03.jpg]]
</div>
<div style="text-align: center;">Figure 7.4. A multiline text box can be sized as large as necessary.
[[Image:07fig04.jpg|500px|graphics/07fig04.jpg]]
</div>
At times, you won't want a user to be able to interact with a control. For instance, you may implement a security model in your application, and if the user doesn't have the necessary privileges, you may not want the user to be able to alter data. The Enabled property, which almost every control has, determines whether the user can interact with the control. Change the Enabled property of the text box to false, and press F5 to run the project. Although no noticeable change occurs in the control in Design view, there is a big change to the control at runtime: the text appears in gray rather than black, and the text box won't accept the focus or allow you to change the text (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig05 Figure 7.5]).
<div style="text-align: center;">Figure 7.5. You can't interact with a text box whose Enabled property is set to false.
[[Image:07fig05.jpg|500px|graphics/07fig05.jpg]]
</div>
Stop the project now by choosing Stop Debugging from the Debug menu, and then change the control's Enabled property back to true.
Adding Scrollbars
Even though you can size a multiline text box, there may be times when the contents of the control are more than what can be displayed. If you believe that this is a possibility for a text box you're adding to a form, give the text box scrollbars by changing the ScrollBars property from None to Vertical, Horizontal, or Both.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| For a text box to display scrollbars, its Multiline property must be set to true.
|}
Change the ScrollBars property of your text box to Vertical and notice how scrollbars appear in the text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig06 Figure 7.6]).
<div style="text-align: center;">Figure 7.6. If a text box may contain lots of text, give it a scrollbar.
[[Image:07fig06.jpg|500px|graphics/07fig06.jpg]]
</div>
Limiting the Number of Characters a User Can Enter
You can limit the number of characters a user can type into a text box using the MaxLength property. All new text boxes are given the default value of 32767 for MaxLength, but you can change this as needed (up or down). Add a new text box to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtRestrict</code>
|-
| <code>Location</code>
| <code>128,80</code>
|-
| <code>MaxLength</code>
| <code>10</code>
|-
| <code>Size</code>
| <code>136,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Run the project by pressing F5 and then enter the following text into the text box: So you run and you run. Be sure to try to enter more than 10 characters of text�you can't (if you can, you're probably entering the text into the text box with scrollbars, rather than into the new text box). All that you're allowed to enter is So you run (10 characters). The text box allows only 10 characters, whether that's via entry using the keyboard or a Paste operation. The MaxLength property is most often used when the text box's content is to be written to a database, in which field sizes are usually restricted (using a database is discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21.htm#ch21 Hour 21], "Working with a Database").
Stop the project by choosing Stop Debugging from the Debug menu and then click Save All on the toolbar.
Creating Password Fields
You've probably used a password field: a text box that displays an asterisk for each character entered. Any text box can be made a password field by assigning a character to its PasswordChar field. Select the PasswordChar property of the second text box now (txtRestrict) and enter an asterisk (*) for the property value. Run the project once more and enter text into the text box. Now an asterisk is displayed for each character you enter (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig07 Figure 7.7]). Although the user doesn't see the actual text contained in the text box, referencing the Text property in code always returns the true text.
<div style="text-align: center;">Figure 7.7. A password field displays its password character for all entered text.
[[Image:07fig07.jpg|300px|graphics/07fig07.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| A text box will display password characters only if its Multiline property is set to false.
|}
Stop the project by choosing Stop Debugging from the Debug menu. Delete the asterisk from the PasswordChar field, and then save the project by clicking Save All on the toolbar.
Creating Buttons
Every dialog box that Windows displays has at least one button on it. Buttons enable a user to invoke a function with a click of the mouse. Create a new project named Button Example, change the name of the default form to fclsButtonExample, set the form's Text property to Button Example, and update the entry point Main() to reference fclsButtonExample instead of Form1. Next, add a new button to the form by double-clicking the Button item in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnClose</code>
|-
| <code>Location</code>
| <code>104,90</code>
|-
| <code>Text</code>
| <code>Close</code>
|}
Add a new text box to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtTest</code>
|-
| <code>Location</code>
| <code>92,40</code>
|-
| <code>TabIndex</code>
| <code>0</code>
|-
| <code>Text</code>
| (make blank)
|}
You're probably starting to see a pattern here. Whenever you add a new control to a form, the first thing you should do is give the control a descriptive name. If the control has a Text property, you should also change that to something meaningful. Your form should now look like [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig08 Figure 7.8].
<div style="text-align: center;">Figure 7.8. Users click buttons, such as the Close button, to make things happen.
[[Image:07fig08.jpg|500px|graphics/07fig08.jpg]]
</div>
There's no point in having a button that doesn't do anything, so double-click the button now to access its Click event, and then add the following statement:
<pre>this.Close();
</pre>
Recall from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05.htm#ch05 Hour 5], "Building Forms�Part I," that this statement closes the current form. Because you'll have only one form in the project, this has the effect of terminating the application. Press F5 to run the project. The cursor appears in the text box, which means that the text box has the focus (it has the lowest <code>TabIndex</code> property). Press Enter and note that nothing happens (this will make sense shortly). Next, click the button and the form will close.
Accept and Cancel Buttons
When creating dialog boxes, it's common to assign one button as the default button (called the Accept button). If a form has an Accept button, that button's Click event is fired when the user presses Enter, regardless of which control has the focus. This is great for dialog boxes in which the user enters some text and presses Enter to commit the data and close the form. To designate a button as an Accept button, use the following steps:
# Select the AcceptButton property of the form.
# Look at the AcceptButton property of your form now�it reads (none). Click the property to select it and a drop-down arrow appears.
# Click the down arrow and you'll get a list of the buttons on the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig09 Figure 7.9]). Choose btnClose to make it the Accept button. Notice how the button now appears with a dark border, indicating that it is the Accept button.
<div style="text-align: center;">Figure 7.9. You can designate only one button as a form's Accept button.
[[Image:07fig09.jpg|178px|graphics/07fig09.jpg]]
</div>
# Press F5 to run the project. Again, the text box has the focus. Press Enter, and you'll find that the form closes. Again, pressing Enter on a form that has a designated Accept button causes that button's Click event to fire the same as if the user clicked it with the mouse, regardless of which control has the focus.
The Accept button is a useful concept, and you should take advantage of this functionality when possible. Keep in mind that when you do create an Accept button for a form, you should also create a Cancel button. A Cancel button is a button that fires its Click event when the user presses the Esc key, regardless of which control has the focus. Generally, you place code in a Cancel button to shut down the form without committing any changes made by the user. To designate a button as a Cancel button, choose it as the CancelButton property of the form.
Adding a Picture to a Button
Although it's not standard practice, and you shouldn't overuse the technique because doing so causes clutter and can reduce the usefulness of your interface, it's possible to add a picture to a button. The two primary methods of doing this are to add the picture to the button at design time by loading a picture into the Image property of the control using the Properties window, or to bind the button to an image list. I'll discuss loading a picture using the Properties window here and the Image List control in the next hour. (Note: You can load an image at runtime using the technique discussed for the Picture Viewer program in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour.")
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To perform this operation, you'll need a small bitmap. I've provided one at [http://www.samspublishing.com/ www.samspublishing.com] called Close.bmp.
|}
Select the button and display its properties in the Properties window. Click the Image property to select it, and then click the button with the three dots. The Open File dialog box is displayed, allowing you to find and select a bitmap. Use this dialog box to locate and select the Close.bmp bitmap or another small bitmap of your choosing. Click Open to load the image into the button's Image property, and the picture will appear on your button (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig10 Figure 7.10]).
<div style="text-align: center;">Figure 7.10. The picture loaded into the Image property of a button appears on the button.
[[Image:07fig10.jpg|500px|graphics/07fig10.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Many controls have an Image property, and for the most part, they all work the same way as the Image property of the Button control.
|}
Notice that there is a problem with how the picture appears on the button�the image overlays the text. This problem is easily corrected.
Although a picture is displayed in the center of a button by default, you can specify the placement using the ImageAlign property. Click the ImageAlign property to display a drop-down arrow, and then click the arrow. The drop-down list contains a special interface for specifying the alignment of the picture (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig11 Figure 7.11]). Each rectangle in the drop-down list corresponds to an alignment (center-left, center-center, center-right, and so on) Click the center-left rectangle now and the image will be moved to the left of the text. So much for problem one…
<div style="text-align: center;">
</div>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating Containers and Groups of Option Buttons
In this section, you'll learn how to create containers for groups of controls using panels and group boxes. You'll also learn how to use the Check Box and Option Button controls in conjunction with these container controls to present multiple choices to a user.
Begin by creating a new Windows Application titled Options. Change the name of the default form to fclsOptions and set the form's Text property to Options. Next, change the entry point Main() to reference fclsOptions instead of Form1.
Using Panels and Group Boxes
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Controls can be placed on a form because the form is a container object�an object that can contain controls. A form is not the only type of container, however. Some controls act as containers as well, and a container may host one or more other containers. The Panel and Group Box controls are both container controls that serve a similar purpose, yet each is more suited to a particular application.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Panel control is a slimmed-down version of the Group Box control, so I won't be discussing it in depth. If you need a very basic container control without the additional features offered by the group box, such as a border and a caption, use the Panel control.
|}
The group box is a container control with properties that let you create a border (frame) and caption. Add a new group box to your form now by double-clicking the GroupBox item in the toolbox. When you create a new group box, it has a border by default, and its caption is set to the name of the control (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig12 Figure 7.12]).
<div style="text-align: center;">Figure 7.12. A group box acts like a form within a form.
[[Image:07fig12.jpg|500px|graphics/07fig12.jpg]]
</div>
Set the properties of the group box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>grpMyGroupBox</code>
|-
| <code>Location</code>
| <code>48,16</code>
|-
| <code>Size</code>
| <code>200,168</code>
|-
| <code>Text</code>
| <code>This is a group box</code>
|}
The group box is a fairly straightforward control. Other than defining a border and displaying a caption, the purpose of a group box is to provide a container for other controls. The next two sections, "[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07lev2sec9 Presenting Yes/No Options Using Check Boxes]" and "[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07lev2sec10 Working with Radio Buttons]," help demonstrate the benefits of using a group box as a container.
Presenting Yes/No Options Using Check Boxes
The check box is used to display true/false values on a form. You're now going to add a check box to your form�but not in the way you have been adding other controls. As you know by now, double-clicking the CheckBox item in the toolbox will place a new Check Box control on the form. However, this time you're going to place the check box on the Group Box control.
To place a control on a group box, you can use one of the following techniques:
* Add the control to the form, cut the control from the form, select the group box, and paste the control on the group box.
* Draw the control directly on the group box.
* Drop the control on the group box.
You're going to use the third method�dropping a new control directly on the group box. Follow these steps:
# Click the group box to select it.
# Click the CheckBox item in the toolbox and drag it to the group box.
# Release the mouse when you are over the group box.
You should now have a check box on your group box like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig13 Figure 7.13].
<div style="text-align: center;">Figure 7.13. Container controls hold other controls.
[[Image:07fig13.jpg|500px|graphics/07fig13.jpg]]
</div>
Move the check box around by clicking and dragging it. You'll notice that you can't move the check box outside the group box's boundaries. This is because the check box is a child of the group box, not of the form. Set the properties of the check box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>chkMyCheckBox</code>
|-
| <code>Location</code>
| <code>16,24</code>
|-
| <code>Size</code>
| <code>120,24</code>
|-
| <code>Text</code>
| <code>This is a check box</code>
|}
When the user clicks the check box, it changes its visible state from checked to unchecked. To see this behavior, press F5 to run the project and click the check box a few times.
When you're done experimenting, stop the running project. To determine the state of the check box in code, use its Checked property. You can also set this property at design time using the Properties window.
Working with Radio Buttons
Check boxes are excellent controls for displaying true/false values. Check boxes work independently of one another, however. If you have five check boxes on a form, each of them could be checked or unchecked. Radio buttons, on the other hand, are mutually exclusive to the container on which they are placed. This means that only one radio button per container may be selected at a time. Selecting one radio button automatically deselects any other radio buttons on the same container. Radio buttons are used to offer a selection of items to a user when the user is allowed to select only one item. To better see how mutual exclusivity works, you're going to create a small group of radio buttons.
Click the RadioButton item in the toolbox to begin dragging, move the pointer over the group box, and then release the button to drop a new radio button on the group box. Set the properties of the radio button as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>optOption1</code>
|-
| <code>Location</code>
| <code>19,65</code>
|-
| <code>Size</code>
| <code>104,24</code>
|-
| <code>Text</code>
| <code>This is option 1</code>
|}
You're going to copy this radio button and paste a copy of the control on the group box. Begin by right-clicking the radio button and choosing Copy from its context menu. Next, click the group box to select it, right-click the group box, and choose Paste from its context menu to create a new radio button. Set the properties of the radio button as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>optOption2</code>
|-
| <code>Checked</code>
| <code>true</code>
|-
| <code>Location</code>
| <code>19,96</code>
|-
| <code>Text</code>
| <code>This is option 2</code>
|}
Now that you have your two radio buttons (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig14 Figure 7.14]), run the project by pressing F5.
<div style="text-align: center;">Figure 7.14. Radio buttons restrict a user to selecting a single item.
[[Image:07fig14.jpg|500px|graphics/07fig14.jpg]]
</div>
Click the first radio button to select it, and notice how the second radio button becomes deselected automatically (its Checked property is set to false). Two radio buttons are sufficient to demonstrate the mutual exclusivity, but be aware that you could add as many radio buttons to the group box as you care to and the behavior would be the same. The important thing to remember is that mutual exclusivity is shared only by radio buttons placed on the same container. To create radio buttons that behave independently of one another, you would need to create a second set. You could easily create a new group box (or panel for that matter) and place the second set of radio buttons on the new container. The two sets of radio buttons would behave independently of one another, but mutual exclusivity would still exist among the buttons within each set.
Stop the running project and save your work.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Displaying a List with the List Box
The list box is used to present a list of items to a user. You can add items to and remove items from the list at any time with very little C# code. In addition, you can set up a list box so that a user can select only a single item or multiple items. When a list box contains more items than it can show because of the size of the control, scrollbars are automatically displayed.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The cousin of the list box is the combo box, which looks like a text box with a down-arrow button at its right side. Clicking a combo box's button causes the control to display a drop-down list box. Working with the lists of a combo box is pretty much identical to working with a list box, so I'll discuss the details of list manipulation in this section. In the next section, I'll discuss features specific to the combo box.
|}
Create a new project titled Lists. Change the name of the default form to fclsLists and set its Text property to Lists Example. Next, change the entry point Main() to reference fclsLists instead of Form1. Set the form's <code>Size</code> property to 300,320. Add a new list box control to the form by double-clicking the ListBox item in the toolbox. Set the properties of the list box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lstPinkFloydAlbums</code>
|-
| <code>Location</code>
| <code>72,32</code>
|-
| <code>Size</code>
| <code>160,121</code>
|}
Every item contained in a list box is a member of the list box's Items collection. Working with items, including adding and removing items, is performed using the Items collection. Most often, you'll manipulate the Items collection using code (which I'll show you a little bit later in this hour), but you can also work with the collection at design time using the Properties window.
Manipulating Items at Design Time
The Items collection is available as a property of the list box. Locate the Items property in the Properties window and click it to select it. The familiar button with three dots appears, indicating that you can do advanced things with this property. Click the button now to show the String Collection Editor. To add items to the collection, simply enter the items into the text box�one item to a line.
Enter the following items:
* Atom Heart Mother
* Saucer Full of Secrets
* Wish You Were Here
* Animals
* Echoes
* Piper at the Gates of Dawn
When you're finished, your screen should look like that shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig15 Figure 7.15]. Click OK to commit your entries and close the window. Notice that the list box contains the items that you entered.
<div style="text-align: center;">Figure 7.15. Use this dialog box to manipulate an Items collection at design time.
[[Image:07fig15.jpg|437px|graphics/07fig15.jpg]]
</div>
Manipulating Items at Runtime
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], "Understanding Objects and Collections," you learned all about objects, properties, methods, and collections. All this knowledge comes into play when manipulating lists at runtime. The Items property of a list box (and a combo box) is an object property that returns a collection (collections in many ways are like objects�they have properties and methods). To manipulate list items, you manipulate the Items collection.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Whether you choose to set values at design time or runtime depends on the situation. For example, if you don't know the values at design time, you'll have to set them at runtime. I recommend that you set values at design-time whenever possible.
|}
A list may contain duplicate values, as you'll see in this example. Because of this, C# needs another mechanism to treat each item in a list as a unique item. This is done by assigning each item in an Items collection a unique index. The first item in the list has an index of 0, the second an index of 1, and so on. The index is the ordinal position of an item relative to the first item in the Items collection, not the top item visible in the list.
Adding Items to a List
New items are added to the Items collection using the <code>Add</code> method of the collection. You're now going to create a button that adds an album to the list. Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnAddItem</code>
|-
| <code>Location</code>
| <code>104,160</code>
|-
| <code>Size</code>
| <code>96,23</code>
|-
| <code>Text</code>
| <code>Add an Item</code>
|}
Double-click the button to access its <code>Click</code> event and add the following code:
<pre>lstPinkFloydAlbums.Items.Add("Dark Side of the Moon");
</pre>
Notice that the Add method accepts a string argument�the text to add to the list.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Unlike items added at design time, items added through code aren't preserved when the program is ended.
|}
Press F5 to run the project now and click the button. When you do, the new album is added to the bottom of the list. Clicking the button a second time adds another item to the list with the same album name. The list box doesn't care whether the item already exists in the list; each call to the Add method of the Items collection adds a new item to the list. The Add method of the Items collection can be called as a function, in which case it returns the index (ordinal position of the newly added item in the underlying collection), as in the following:
<pre>int intIndex;
intIndex = lstPinkFloydAlbums.Items.Add("Dark Side of the Moon");
</pre>
Stop the running project and save your work before continuing.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| To add an item to an Items collection at a specific location in the list, use the Insert method. The <code>Insert</code> method accepts an index in addition to text. For instance, to add an item at the top of the list, you could use a statement such as <code>lstPinkFloydAlbums.Items.Insert(0,"Dark Side of the Moon");.</code> Remember, the first item in the list has an index of 0.
|}
Removing Items from a List
Removing an individual item from a list is as easy as adding an item and requires only a single method call: a call to the Remove method of the Items collection. The Remove method accepts a string, which is the text of the item to remove. You're now going to create a button that will remove an item from the list. Create a new button and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnRemoveItem</code>
|-
| <code>Location</code>
| <code>104,192</code>
|-
| <code>Size</code>
| <code>96,23</code>
|-
| <code>Text</code>
| <code>Remove an Item</code>
|}
Double-click the new button to access its Click event and enter the following statement:
<pre>lstPinkFloydAlbums.Items.Remove("Dark Side of the Moon");
</pre>
The Remove method tells C# to search the Items collection, starting at the first item (index = 0), and when an item is found that matches the specified text, to remove that item. As I stated earlier, you can have multiple items with the same text. The Remove method will remove only the first occurrence; after the text is found and removed, C# stops looking. Press F5 to run the project now. Click the Add an Item button a few times to add Dark Side of the Moon to the list (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig16 Figure 7.16]). Next, click the Remove an Item button and notice how C# finds and removes one instance of the item.
<div style="text-align: center;">Figure 7.16. The list box may contain duplicate entries, but each entry is a unique item in the Items collection.
[[Image:07fig16.jpg|300px|graphics/07fig16.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To remove an item at a specific index, use the RemoveAt method. For instance, to remove the first item in the list, you could use a statement such as <code>lstPinkFloydAlbums.Items.RemoveAt(0);</code>.
|}
Stop the running project and save your work.
Clearing a List
To completely clear the contents of a list box, use the Clear method. You are now going to add a button to the form that will clear the list when clicked. Add a new button to the form now and set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnClearList</code>
|-
| <code>Location</code>
| <code>104,224</code>
|-
| <code>Size</code>
| <code>96,23</code>
|-
| <code>Text</code>
| <code>Clear List</code>
|}
Double-click the new button to access its Click event and enter the following statement:
<pre>lstPinkFloydAlbums.Items.Clear();
</pre>
Press F5 to run the project, and then click the Clear List button. The Clear method doesn't care if an item was added at design time or runtime; Clear() always removes all items from the list. Stop the project and again save your work.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Remember, the Add, Insert, Remove, RemoveAt, and Clear methods are all methods of the Items collection, not of the list box itself. If you forget that these are members of the Items collection, you might get confused when you don't find them when you enter a period after typing a list box's name in code.
|}
Retrieving Information About the Selected Item in a List
By default, a list box allows only a single item to be selected by the user at one time. Whether a list allows multiple selections is determined by the SelectionMode property of the list box. You will need to understand how to work with the selected item in a list box that allows only a single selection (list boxes that allow multiple selections are more complex and are beyond the scope of the book).
Two properties provide information about the selected item: SelectedItem and SelectedIndex. It's important to note that these are properties of the list box itself, not of the Items collection of a list box. The <code>SelectedItem</code> method returns the text of the currently selected item. If no item is selected, an empty string is returned. At times, it's desirable to know the index of the selected item. This is returned by the SelectedIndex property of the list box. As you know, the first item in a list has the index of 0. If no item is selected, SelectedIndex returns a �1, which is never a valid index for an item.
You're now going to add a button to the form that, when clicked, displays the selected item's text and index in the Output window. First, change the Height property of the form to 320 to accommodate one more button. As you build your interfaces, you'll often have to make small tweaks such as this because it's nearly impossible to anticipate everything ahead of time. Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowItem</code>
|-
| <code>Location</code>
| <code>104,256</code>
|-
| <code>Size</code>
| <code>96,23</code>
|-
| <code>Text</code>
| <code>Show Selected</code>
|}
Double-click the new button to access its Click event and enter the following statements:
<pre>System.Diagnostics.Debug.WriteLine(lstPinkFloydAlbums.SelectedItem);
System.Diagnostics.Debug.WriteLine(lstPinkFloydAlbums.SelectedIndex);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| System.Diagnostics.Debug.WriteLine sends text to the Output window. If you are planning to write several debug statements, it may be helpful to declare the System.Diagnostics namespace at the beginning of your class. This permits you to use the methods of the namespace without having to qualify the entire namespace. For example, after the namespace System.Diagnostics is declared in the class, you could use a statement like the following:
<pre>Debug.WriteLine(lstPinkFloydAlbums.SelectedItem);<br /></pre>
Notice how you don't have to reference System.Diagnostics on this line; the compiler is able to determine this automatically.
To specify a namespace so that you can reference its objects without explicitly referencing the namespace, you add a using statement in the header of the class file (with the other using statements that C# automatically places in the header). For example, to reference the System.Diagnostics namespace, you could add a statement like this to the class's header:
<pre>using System.Diagnostics;<br /></pre>
Again, after you've added the namespace with a using statement, you can reference the namespace's objects without explicitly referencing <code>System.Diagnostics</code>, as seen next:
<pre>Debug.WriteLine(lstPinkFloydAlbums.SelectedItem);<br />Debug.WriteLine(lstPinkFloydAlbums.SelectedIndex);<br /></pre>
|}
Press F5 to run the project and click the Show Selected button. Take a look at the Output window. You'll see a blank line (the empty string returned by SelectedItem) and a �1, returned by <code>SelectedIndex</code> denoting that no item is selected. Click an item in the list to select it, and then click Show Selected again. This time, you'll see the text of the selected item and its index in the Output window (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig17 Figure 7.17]).
<div style="text-align: center;">Figure 7.17. The SelectedItem and SelectedIndex properties make it easy to determine which item is selected.
[[Image:07fig17.jpg|300px|graphics/07fig17.jpg]]
</div>
Stop the running project and save your work.
Sorting a List
List boxes and combo boxes have a <code>Sorted</code> property. By default, this property is set to false. Changing this property value to true causes C# to sort the contents of the list alphabetically. When the contents of a list are sorted, the index of each item in the Items collection is changed; therefore, you can't use an index value obtained prior to setting Sorted to true. Sorted is a property, not a member. You don't have to call Sorted to sort the contents of a list. Instead, as long as the Sorted property is set to true, C# enforces a sort order. This means that all items added using the Add method are automatically inserted into the proper location, in contrast to being inserted at the end of the list, which is the behavior of an unsorted list.
Creating Drop-Down Lists Using the Combo Box
List boxes are great, but they have two shortcomings. First, they take up quite a bit of space. Second, users can't enter their own values; they have to select from the items in the list. If you need to conserve space or if you want to allow a user to enter a value that may not exist in the list, use the Combo Box control.
Combo boxes have an Items collection that behaves exactly like that of the List Box control (refer to the previous section for information on manipulating lists). Here I will show you the basics of how a combo box works.
Add a new combo box to the form by double-clicking the ComboBox item in the toolbox. Set the combo box's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>cboColors</code>
|-
| <code>Location</code>
| <code>72,8</code>
|-
| <code>Size</code>
| <code>160,21</code>
|-
| <code>Text</code>
| (make blank)
|}
The first thing you should note is that the combo box has a Text property, whereas the list box doesn't. This works the same as the Text property of a text box. When the user selects an item from the drop-down list, the value of the selected item is placed in the Text property of the text box. The default behavior of a combo box is to allow the user to enter any text in the text box portion of the control�even if the text doesn't exist in the list. Shortly, I'll show you how to change this behavior.
Select the Items property of the combo box in the Properties window and click the button that appears. Add the following items to the String Collection editor and click OK to commit your entries.
* Black
* Blue
* Gold
* Green
* Red
* Yellow
Press F5 to run the project. Click the arrow at the right side of the combo box and a drop-down list appears (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#ch07fig18 Figure 7.18]).
<div style="text-align: center;">Figure 7.18. Combo boxes conserve space.
[[Image:07fig18.jpg|300px|graphics/07fig18.jpg]]
</div>
Next, try typing in the text Magenta. C# lets you do this. Indeed, you can type any text that you desire. Often, you'll want to restrict a user to entering only values that appear in the list. To do this, you change the DropDownStyle property of the combo box. Close the form to stop the running project and change the DropDownStyle property of the combo box to DropDownList. Press F5 to run the project again and try to type text into the combo box. You can't. However, if you enter a character that is the start of a list item, C# will select the closest matching entry.
As a matter of fact, clicking in the "text box" portion of the combo box opens the list the same as if you clicked the drop-down arrow. When set as a DropDownList, a combo box won't allow any text entry; therefore, the user is limited to selecting items from the list.
Stop the running project now and save your work. As you can see, the combo box and list box offer similar functionality. In fact, the coding of their lists is identical. However, each one of these controls serves a slightly different purpose. Which one is better? That depends entirely on the situation. As you use professional applications, pay attention to their interfaces; you'll start to get a feel for which control is appropriate in a given situation.
Summary
In this hour you learned how to present text to a user. You learned that the Label control is perfect for displaying static text (text the user can't enter) and that the text box is the control to use for displaying edited text. You can now create text boxes that contain many lines of text, and you know how to add scrollbars when the text is greater than what can be displayed in the control.
I don't think I've ever seen a form without at least one button on it. You've now learned how to add buttons to your forms and how to do some interesting things, such as adding a picture to a button. For the most part, working with buttons is a simple matter of adding one to a form, settings its Name and Text properties, and adding some code to its Click event�all of which you now know how to do.
Check boxes and option buttons are used to present true/false and mutually exclusive options, respectively. In this hour, you learned how to use each of these controls and how to use group boxes to logically group sets of related controls.
Last, you learned how to use list boxes and combo boxes to present lists of items to a user. You now know how to add items to a list at design time as well as runtime, and you know how to sort items. The List Box and Combo Box are powerful controls, and I encourage you to dig deeper into the functionality they possess.
Without controls, users would have nothing to interact with on your forms. In this hour, you learned how to use the standard controls to begin building functional interfaces. Keep in mind that I only scratched the surface of each of these controls and that most do far more than I've hinted at here. Mastering these controls will be easy for you, as you'll be using them a lot.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#qad1e25275 Q1:]'''
| Can I place radio buttons directly on a form?
|-
| align="right" | ''' A1: '''
| Yes. The form is a container, so all radio buttons placed on a form are mutually exclusive to one another. If you wanted to add a second set of mutually exclusive buttons, they'd have to be placed on a container control. In general, I think it's best to place radio buttons on a group box rather than on a form because the group box provides a border and a caption for the radio buttons and makes it much easier to move the set of radio buttons around when you're designing the form.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/07.htm#qad1e25285 Q2:]'''
| I've seen what appears to be list boxes that have a check box next to each item in the list. Is this possible?
|-
| align="right" | ''' A2: '''
| Yes. In C#, this is accomplished using an entirely different control: the checked list box.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans01 1:]'''
| Which control would you use to display text that the user can't edit?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans02 2:]'''
| What common property is shared by the Label control and text box 2and whose value determines what the user sees in the control?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans03 3:]'''
| To change the Height of a text box, you must set what property?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans04 4:]'''
| What is the default event of a Button control?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans05 5:]'''
| A button whose Click event is triggered when the user presses Enter, regardless of the control that has the focus, is called an…?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans06 6:]'''
| Which control would you use to display a yes/no value to a user?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans07 7:]'''
| How would you create two distinct sets of mutually exclusive option buttons?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans08 8:]'''
| To manipulate items in a list, you use what collection?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec7.htm#ch07ans09 9:]'''
| What method adds an item to a list in a specific location?
|}
Exercises
# Create a form with a text box and a combo box. Add a button that, when clicked, adds the contents of the text box to the combo box.
# Create a form with two list boxes. Add a number of items to one list box at design time using the Properties window. Create a button that, when clicked, removes the selected item in the first list and adds it to the second list.
6k87e4saxd6ay73g655cs8raoln2yg9
User:Foxall/08
2
2139
39244
5600
2026-04-13T06:03:32Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39244
wikitext
text/x-wiki
== Hour 8. Advanced Controls ==
The standard controls presented in the previous hour enable you to build many types of functional forms. However, to create truly robust and interactive applications, you've got to use the more advanced controls. As a Windows user, you've encountered many of these controls, such as the Tab control, which presents data on tabs, and the Tree View control, which displays hierarchical lists such as the one in Explorer. In this hour, you'll learn about these advanced controls and learn how to use them to make professional interfaces like those you're accustomed to seeing in commercial products.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08lev1sec1.htm#ch08lev1sec1 Creating timers]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08lev1sec2.htm#ch08lev1sec2 Creating tabbed dialog boxes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08lev1sec3.htm#ch08lev1sec3 Storing pictures in an Image List]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08lev1sec4.htm#ch08lev1sec4 Building enhanced lists using the List View control]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch08lev1sec5.htm#ch08lev1sec5 Creating hierarchical lists with the Tree View control]
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In many of the examples in this hour, I show you how to add items to collections at design time. Keep in mind that almost everything you can do at design time can also be accomplished with C# code at runtime.
|}
----
=== Creating Timers ===
One thing that all the controls you used in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7], "Working with Traditional Controls," have in common is that the user can interact with them. However, not all controls have this capability�or restriction, depending on how you look at it. Some controls are designed for use only by the developer. One such control is the Open File Dialog control you used in your Picture Viewer application in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour." Another control that is invisible at runtime is the Timer control. The Timer control's sole purpose is to trigger an event at a specified interval of time.
Create a new Windows Application titled Timer Example. Change the name of the default form to fclsTimerExample and then set its Text property to Timer Example. Next, be sure to set the Main() entry point of the project to fclsTimerExample or the project won't run. Add a new Timer control to your form by double-clicking the Timer item in the toolbox. Because the Timer control is invisible at runtime, it's added to the gray area at the bottom of the screen rather than placed on the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig01 Figure 8.1]). Set the properties of the Timer control as follows:
<div style="text-align: center;">Figure 8.1. Invisible-at-runtime controls are shown at the bottom of the designer, not on the form.
[[Image:08fig01.jpg|500px|graphics/08fig01.jpg]]
</div>
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>tmrClock</code>
|-
| <code>Enabled</code>
| <code>True</code>
|-
| <code>Interval</code>
| <code>1000</code>
|}
You probably noticed that there are very few properties for the Timer control, compared to the other controls with which you've worked. The key property of the Timer control is the Interval property. The Interval property determines how often the Timer control fires its Tick event. The Interval is specified in milliseconds, so a setting of 1,000 is equal to 1 second. The best way to understand how the timer works is to use it. Using the Timer and a Label control, you're now going to create a simple clock. The way the clock will work is that the timer will fire its Tick event once every second (because you'll set the Interval = 1000 milliseconds), and within the Tick event, the label's Text property will be updated with the current system time.
Add a new label to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lblClock</code>
|-
| <code>BorderStyle</code>
| <code>FixedSingle</code>
|-
| <code>Location</code>
| <code>96,120</code>
|-
| <code>Size</code>
| <code>100,23</code>
|-
| <code>Text</code>
| (make blank)
|-
| <code>TextAlign</code>
| <code>MiddleCenter</code>
|}
Next, double-click the Timer control to access its Tick event. When a timer is first enabled, it starts counting, in milliseconds, from 0. When the amount of time specified in the Interval property passes, the Tick event fires and the timer starts counting from 0 again. This continues until the timer is disabled (that is, when its Enabled property is set to False). Because you've set the Enabled property of the timer to True at design time, it will start counting as soon as the form on which it is placed is loaded. Enter the following statement in the Tick event:
<pre>DateTime dtCurrentTime = DateTime.Now;
lblClock.Text = dtCurrentTime.ToLongTimeString();
</pre>
The .NET Framework provides date/time functionality in the System namespace. The Now property of the DateTime class returns the current time. Using the ToLongTimeString method returns a string with a time format of hh:mm:ss. Using this class, property, and method, we set the Text property of the label to the current time of day, and it does this once a second. Press F5 to run the project now and you'll see the Label control acting as a clock, updating the time every second (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig02 Figure 8.2]).
<div style="text-align: center;">
</div>
Stop the running project now and save your work. Timers are powerful, but you must take care not to overuse them. For a timer to work, Windows must be aware of the timer and must constantly compare the current internal clock to the interval of the timer. It does all this so that it can notify the timer at the appropriate time to execute its Tick event. In other words, timers take system resources. This isn't a problem for an application that uses a few timers, but I wouldn't overload an application with a dozen timers unless I had no other choice.
Creating Tabbed Dialog Boxes
Windows 95 was the first version of Windows to introduce a tabbed interface. Since then, tabs have been unanimously adopted as a primary interface element. Tabs provide two primary benefits: the logical grouping of controls and the reduction of required screen space. Although tabs may look complicated, they are, in fact, extremely easy to build and use.
Create a new Windows Application named Tabs Example. Change the name of the default form to reference fclsTabs instead of Form1, set its Text property to Tabs Example, and modify the Main() entry point to fclsTabs. Next, add a new Tab control to your form by double-clicking the TabControl item in the toolbox. At first, the new control looks more like a panel than a set of tabs because it has no tabs. Set the Tab control's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>tabMyTabs</code>
|-
| <code>Location</code>
| <code>8,16</code>
|-
| <code>Size</code>
| <code>272,208</code>
|}
The tabs on a Tab control are part of the control's TabPages collection. Click the TabPages property of the Tab control in the Properties window and then click the small button that appears. C# then shows the TabPage Collection Editor. As you can see, your Tab control has no tabs. Click Add now to create a new tab (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig03 Figure 8.3]).
<div style="text-align: center;">Figure 8.3. New Tab controls have no tabs; you must create them.
[[Image:08fig03.jpg|487px|graphics/08fig03.jpg]]
</div>
Each tab in the collection is called a page. C# names each new page with TabPageX, in which X is a unique number. It's usually not necessary to change the name of a page, but you can if you choose. Each page has a number of properties, but the property you'll be concerned with most is the Text property because the value in the Text property is the text the user will see on the tab. Change the Text property of your tab page to Contacts, and then click Add to create a second page. Change the Text property of the second page to Appointments and click OK to close the dialog box. Your Tab control now has two tabs (pages).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| A shortcut to adding or removing a tab is to use the shortcuts provided in the description pane at the bottom of the Properties window.
|}
Each page on a Tab control acts as a container, much like the Panel and Group Box controls. This is why you can't drag the Tab control by clicking in the middle of it; to drag a container control, you have to click and drag the dotted border around the control. Add a text box to the first tab now by dragging the TextBox item from the toolbox and dropping in on the tab page. After it's on the page, drag it to approximately the center of the page. Next, click the Appointments tab, the same as if you were a user switching tabs. As you can see, the Appointments tab comes to the front, and the text box is no longer visible. C# has hidden the first page and shown you the second. Drag a check box from the toolbox and drop it on the tab page, and then click Contacts once more. Again, C# handles the details of showing and hiding the tab pages; you no longer see the check box, but you do see the text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig04 Figure 8.4]).
<div style="text-align: center;">Figure 8.4. The Tab control makes it easy to create a tabbed interface.
[[Image:08fig04.jpg|500px|graphics/08fig04.jpg]]
</div>
By understanding two simple programming elements, you'll be able to do 99% of what you need to with the Tab control. The first is that you will, at times, need to know which tab is selected. The SelectedIndex property of the control (not of the TabPages collection) sets and returns the index of the currently selected tab�0 for the first tab, 1 for the second, and so forth. The second thing you need to know is how to tell when the user switches tabs. The Tab control has a SelectedIndexChanged event, which fires whenever the selected tab is changed. In this event, you can check the value of SelectedIndex to determine the tab that has been selected. The only tricky part here is that each tab page has its own set of events, so to get to the events of the Tab control itself, you'll have to use the techniques discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04.htm#ch04 Hour 4], "Understanding Events."
Storing Pictures in an Image List
Many of the controls I'll be discussing in this hour support the capability to attach pictures to different types of items. For instance, the Tree View control, which is used in Explorer for navigating folders, displays images next to each folder node. Not all these pictures are the same; the control uses specific pictures to denote information about each node. It would have been possible for Microsoft to make each control store its images internally, but that would be highly inefficient because it wouldn't allow controls to share the same pictures; you'd have to store the pictures in each control that needed them. Instead, Microsoft created a control dedicated to storing pictures and serving them to other controls: the Image List.
Create a new Windows Application named Lists and Trees. Change the name of the default form to fclsListsAndTrees, set its Text property to Lists and Trees Example, and set the entry point of the project to reference fclsListsAndTrees instead of Form1. Next, add a new Image List control by double-clicking the ImageList item in the toolbox. Like the timer, the Image List is an invisible-at-runtime control, so it appears below the form. Change the name of the Image List to imgMyImages.
The sole purpose of an Image List control is to store pictures and make them available to other controls. The pictures of an Image List are stored in the Images collection of the control. Click the Images property of the control in the Properties window and then click the small button that appears. C# then displays the Image Collection Editor, which is similar to other editors you've used in this hour. Click Add to display the Open dialog box and use this dialog box to locate and select a 16x16 pixel bitmap. If you don't have a 16x16 pixel bitmap, you can create one using Microsoft Paint, or you can download samples I've provided at [http://www.samspublishing.com/detail_sams.cfm?item=0672322870 http://www.samspublishing.com/detail_sams.cfm?item=0672322870]. After you've added an image, click OK to close the Image Collection Editor.
Take a look at the ImageSize property of the Image control. It should read 16,16. If it doesn't, the bitmap you selected is not 16x16 pixels; this property sets itself to the dimensions of the first picture added to the Image List.
You can't always rely on the background where a picture will be displayed to be white�or any other color for that matter. Because of this, the Image List has a TransparentColor property. By default, this is set to Transparent, which essentially means that no color in the picture is transparent (if the pictures in the Image List are icons, rather than bitmaps, the transparent portion of the icons will remain transparent). If you designate a specific color for the TransparentColor property, when a picture is served from the Image List to another control, all occurrences of the specified color will appear transparent�the background will show through. This gives you the power to create pictures that can be served to controls without concern about the color on which the picture will appear.
That's all there is to adding images to an Image List. The power of the Image List resides in its capability to be linked to by other controls that can access the pictures it stores.
Building Enhanced Lists Using the List View
The List View control is like a list box on steroids�and then some. The List View can be used to create simple lists, multicolumn grids, and icon trays. The right pane in Explorer is a List View. (You may not know it, but you can change the appearance of the List View in Explorer by right-clicking it and using the View submenu of the context menu that appears.) The primary options you have available for changing the appearance of your List Views are Large Icons, Small Icons, List, and Details. These correspond exactly to the display options available for a List View by way of its View property. You're going to create a List View with a few items on it and experiment with the different views�including showing a picture for the items.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| I can only scratch the surface of this great control here. After you've learned the basics in this hour, I highly recommend that you spend some time with the control, the help text, and whatever additional material you can find. I use the List View all the time; it's a very powerful tool to have in your arsenal because displaying lists is so common.
|}
Add a List View to your form now by double-clicking the ListView item in the toolbox. Set the properties of the List View as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lvwMyListView</code>
|-
| <code>Location</code>
| <code>8,8</code>
|-
| <code>Size</code>
| <code>275,97</code>
|-
| <code>SmallImageList</code>
| <code>imgMyImages</code>
|-
| <code>View</code>
| <code>Details</code>
|}
As you can see, you can attach an Image List to a control via the Properties window (or with code). Not all controls support the Image List, but those that do make it as simple as setting a property to link to an Image List. The List View actually allows linking to two Image Lists: one for large icons (32x32 pixels) and one for small images. In this example, you're going to use only small pictures. If you wanted to use the large format, you could hook up a second Image List containing larger images to the List View's LargeImageList control.
Creating Columns
When you changed the View property to Details, an empty header was placed at the top of the control. The contents of this header are determined by the columns defined in the Columns collection.
Select the Columns property on the Properties window and click the small button that appears. C# then displays the ColumnHeader Collection Editor window. Click Add to create a new header and change its Text to Name and its Width to 120. Click Add once more to create a second column and change its Text to State. Click OK to save your column settings and close the window. Your list view should now have two named columns (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig05 Figure 8.5]).
<div style="text-align: center;">Figure 8.5. List Views enable you to present multicolumn lists.
[[Image:08fig05.jpg|500px|graphics/08fig05.jpg]]
</div>
Adding List Items
You're now going to add two items to the list view.
# Click the Items property in the Properties window and then click the small button that appears, which displays the ListViewItem Collection Editor dialog box.
# Click Add to create a new item, and change the item's Text to James Foxall.
# Next, open the drop-down list for the ImageIndex property. Notice how the list contains the picture in the linked Image List control (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig06 Figure 8.6]). Select the image.
<div style="text-align: center;">Figure 8.6. Pictures from a linked Image List are readily available to the control.
[[Image:08fig06.jpg|487px|graphics/08fig06.jpg]]
</div>
# The Text property of an item determines the text displayed for the item in the List View. If the View property is set to Details and multiple columns have been defined, the value of the Text property appears in the first column. Subsequent column values are determined by the SubItems collection.
# Click the SubItems property and then click the small button that appears, which displays the ListViewSubItem Collection Editor. The item that appears in the list refers to the text of the item itself, which you don't want to change.
# Click Add to create a new sub item and change its text to Nebraska.
# Click OK to return to the ListViewItem Collection Editor.
# Click the Add button to create another item. This time, change the Text property to your name and use the techniques you just learned to add a sub item. For the Text property of the sub item, enter your state of residence.
# When you're finished, click OK to close the ListViewItem Collection Editor. Your List View should now contain two list items (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig07 Figure 8.7]).
<div style="text-align: center;">Figure 8.7. List views offer much more functionality than a standard list box.
[[Image:08fig07.jpg|500px|graphics/08fig07.jpg]]
</div>
# Next, experiment with the View property of the List View control to see how the various settings affect the appearance of the control. The Large Icons setting doesn't display an icon, because you didn't link an Image List control to the LargeImageList property of the List View.
# Press F5 to run the project and try selecting your name by clicking your state. You can't. The default behavior of the List View is only to consider the clicking of the first column as selecting an item.
# Stop the project and change the FullRowSelect property to True; then run the project once more.
# Click your state again, and this time your name becomes selected (actually, the entire row becomes selected). Personally, I prefer to set up all my List Views with FullRowSelect set to True, but this is just a personal preference. Stop the project now and save your work.
Manipulating a List View Using Code
You've just learned the basics of working with a List View control. Although you performed all the steps in Design view, you'll probably manipulate your list items using code because you won't necessarily know ahead of time what to display in the list, so I'll show you how.
Adding List Items Using Code
Adding an item using code is very simple�if the item you are adding is simple. To add an item to your list view, you use the Add method of the Items collection, like this:
<pre>lstMyListView.Items.Add("Mark Haro");
</pre>
If the item is to have a picture, you can specify the index of the picture as a second parameter, like this:
<pre>lstMyListView.Items.Add("Luis Haro",0);
</pre>
If the item has sub items, things get more complicated. The Add method allows you only to specify the text and image index. To access the additional properties of a list item, you need to get a reference to the item in code. Remember that new items have only one sub item; you have to create additional items. The Add method of the Items collection returns a reference to the newly added item. Knowing this, you can create a new variable to hold a reference to the item, create the item, and manipulate anything you choose to about the item using the variable (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays," for information on using variables). The following code creates a new item and appends a sub item to its SubItems collection:
<pre>ListViewItem objListItem;
objListItem = lstMyListView.Items.Add("Yvette Webster", 0);
objListItem.SubItems.Add("Tennessee");
</pre> Determining the Selected Item in Code
The List View control has a collection that contains a reference to each selected item in the control: the SelectedItems collection. If the MultiSelect property of the List View is set to True, as it is by default, the user can select multiple items by holding down the Ctrl or Shift keys when clicking items. This is why the List View supports a SelectedItems collection rather than a SelectedItem property. To gather information about a selected item, you refer to it by its index. For example, to print the text of the first selected item (or the only selected item if just one is selected), you could use code like this:
<pre>if (lstMyListView.SelectedItems.Count > 0)
System.Diagnostics.Debug.WriteLine(lstMyListView.SelectedItems[0].Text);
</pre>
The reason you check the Count property of the SelectedItems collection is that if no items are selected, you would cause a runtime error by attempting to reference element 0 in the SelectedItems collection.
Removing List Items Using Code
To remove a list item, use the Remove method of the Items collection. The Remove Item method accepts and expects a reference to a list item. For instance, to remove the currently selected item, you could use a statement such as
<pre>lstMyListView.Items.Remove(lstMyListView.SelectedItems[0]);
</pre>
or
<pre>lstMyListView.Items.RemoveAt(0);
</pre>
Again, you'd want to make sure an item is actually selected before using this statement.
Removing All List Items
If you're filling a List View using code, you'll probably want to clear the contents of the List View first. That way, if the code to fill the List View is called a second time, you won't create duplicate entries. To clear the contents of a List View, use the Clear method of the Items collection, like this:
<pre>lstMyListView.Items.Clear();
</pre>
The List View control is an amazingly versatile tool. As a matter of fact, I rarely use the standard list box now, preferring to use the List View because of its added functionality, such as displaying an image for an item. I've barely scratched the surface here, but you now know enough to begin using this awesome tool in your own development.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating Hierarchical Lists with the Tree View
The Tree View control is used to present hierarchical data. Perhaps the most commonly used Tree View control is found in Explorer, where you can use the Tree View to navigate the folders and drives on your computer. The Tree View is perfect for displaying hierarchical data, such as a departmental display of employees. In this section, I'll teach you the basics of the Tree View control so that you can use this great interface element in your applications.
The Tree View's items are contained in a Nodes collection. To add items to the tree, you append them to the Nodes collection. As you can probably see by now, after you understand the basics of objects and collections, you can apply that knowledge to almost everything in C#. For instance, the skills you learned in working with the Items collection of the List View control are similar to the skills needed for working with the Nodes collection of the Tree View control.
Add a Tree View control to your form now by double-clicking the TreeView item in the toolbox. Set the Tree View control's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>tvwLanguages</code>
|-
| <code>ImageList</code>
| <code>imgMyImages</code>
|-
| <code>Location</code>
| <code>8,128</code>
|-
| <code>Size</code>
| <code>272,97</code>
|}
Adding Nodes to a Tree View
To add a node, call the Add method of the Nodes collection. Add a new button to your form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnAddNode</code>
|-
| <code>Location</code>
| <code>8,240</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>Add Node</code>
|}
Double-click the button to access its Click event and enter the following code:
<pre>tvwLanguages.Nodes.Add("Sam Chun");
tvwLanguages.Nodes.Add("C#");
</pre>
Press F5 to run the project, and then click the button. Two nodes will appear in the tree, one for each Add method call (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig08 Figure 8.8]).
<div style="text-align: center;">Figure 8.8. Nodes are the items that appear in a tree.
[[Image:08fig08.jpg|301px|graphics/08fig08.jpg]]
</div>
Notice how both nodes appear at the same level in the hierarchy; neither node is a parent or child of the other. If all your nodes are going to be at the same level in the hierarchy, you should consider using a List View instead, because what you're creating is simply a list.
Stop the project and return to the button's <code>Click</code> event. Any given node can be both a parent to other nodes and a child of a single node. For this to work, each node has its own Nodes collection. This can get confusing, but if you realize that children nodes belong to the parent node, it starts to make sense (but it still gets confusing in practice). You're now going to create a new button that adds the same two nodes as before but makes the second node a child of the first. Create a new button and set its properties as shown:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnCreateChild</code>
|-
| <code>Location</code>
| <code>96,240</code>
|-
| <code>Size</code>
| <code>80,23</code>
|-
| <code>Text</code>
| <code>Create Child</code>
|}
Double-click the new button to access its Click event and add the following code:
<pre>TreeNode objNode;
objNode = tvwLanguages.Nodes.Add("Wendy Chun");
objNode.Nodes.Add("C#");
</pre>
This code is similar to what you created in the List View example. The Add method of the Nodes collection returns a reference to the newly created node. Thus, this code creates a variable of type TreeNode (variables are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12]), creates a new node whose reference is placed in the variable, and then adds a new node to the Nodes collection of the first node. To see the effect that this has, press F5 to run the project and click the new button. You'll see a single item in the list, with a plus sign to the left of it. This plus sign indicates that child nodes exist. Click the plus sign, and the node is expanded to show its children (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#ch08fig09 Figure 8.9]).
<div style="text-align: center;">Figure 8.9. You can create as deep a hierarchy as you need.
[[Image:08fig09.jpg|301px|graphics/08fig09.jpg]]
</div>
This example is a simple one�a single parent node having a single child node. However, the principles used here are the same as those used to build complex trees with dozens or hundreds of nodes.
Removing Nodes
Removing a node is simply a matter of calling the Remove method of the Nodes collection. The Remove method accepts and expects a valid node, so you must know which node to remove. Again, the Nodes collection works very much like the Items collection in the List View control, so the same ideas apply. For example, the currently selected node is returned in the SelectedNode property of the Tree View. So, to remove the currently selected node, you could use this statement:
<pre>tvwLanguages.Nodes.Remove(tvwLanguages.SelectedNode);
</pre>
If this statement is called when no node is selected, an error would occur. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], you'll learn all about data types and equalities, but here's a preview: If an object variable doesn't reference an object, it is equivalent to the C# keyword null. Knowing this, you could validate whether an item is selected with a little bit of logic, like this:
<pre>if (!(tvwLanguages.SelectedNode == null))
tvwLanguages.Nodes.Remove(tvwLanguages.SelectedNode);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Removing a parent node causes all its children to be removed as well.
|}
Clearing All Nodes
To clear all nodes in a Tree View, invoke the <code>Clear</code> method of the Nodes collection, like this:
<pre>tvwLanguages.Nodes.Clear();
</pre>
As with the List View, I've only scratched the surface of the Tree View. Spend some time becoming familiar with the basics of the Tree View, as I've shown here, and then dig a bit deeper to discover the not-so-obvious power and flexibility of this control.
Summary
C# includes a number of controls that go beyond the standard functionality of the traditional controls discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7]. In this hour, I discussed the most commonly used advanced controls. You learned how to use the Timer control to trigger events at predetermined intervals. You also learned how to use the tab to create the tabbed dialog boxes with which you're so familiar.
Also in this hour, you learned how to add pictures to an Image List so that other controls can use them. The Image List makes it easy to share pictures among many controls, making it a very useful tool. Finally, I taught you the basics of the List View and Tree View controls; two controls you can use to build high-end interfaces that present structured data. The more time you spend with all these controls, the better you will become at creating great interfaces.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#qad1e28118 Q1:]'''
| What if I need a lot of timers, but I'm concerned about system resources?
|-
| align="right" | ''' A1: '''
| When possible, use a single timer for multiple duties. This is extremely easy when two events occur at the same interval�why bother creating a second timer? When two events occur at different intervals, you can use some decision skills along with static variables (discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12]) to share Timer events.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/08.htm#qad1e28132 Q2:]'''
| What else can I do with an Image List?
|-
| align="right" | ''' A2: '''
| You can assign a unique picture to a node in a Tree View when the node is selected. You can also display an image in the tab of a tab page in a Tab control. There are a lot of uses, and as you learn more about advanced controls, you'll see additional opportunities for using images from an Image List.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans01 1:]'''
| What increment of time is applied to the <code>Interval</code> property of the Timer control?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans02 2:]'''
| What collection is used to add new tabs to a Tab control?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans03 3:]'''
| What property returns the index of the currently selected tab?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans04 4:]'''
| True or False: You should use different Image List controls for storing images of different sizes.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans05 5:]'''
| To see columns in a List View control, the View property must be set to what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans06 6:]'''
| The additional columns of data that can be attached to an item in a list view are stored in what collection?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans07 7:]'''
| What property of what object would you use to determine how many items are in a List View?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans08 8:]'''
| Each item in a Tree View is called a what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec8.htm#ch08ans09 9:]'''
| How do you make a node the child of another node?
|}
Exercises
# Add a second Image List to your project with the List View. Place an icon (32x32 pixels) in this Image List and link the Image List to the LargeImageList property of the List View control. Change the View to Large Icons. Does the icon appear next to a list item? If not, is there a property of an item you can set so that it does?
# Create a new project and add a List View, a button, and a text box to the default form. When the button is clicked, create a new item in the List View using the text entered into the text box.
ljdg01q8r6k97fq2ig25ioyk8j8cp6d
User:Foxall/24
2
2140
39261
5601
2026-04-13T06:03:40Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39261
wikitext
text/x-wiki
./ ADD NAME=CH24.HTM
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec8.htm [[Image:previous.gif|62px|Previous Section]]] [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec1.htm [[Image:next.gif|41px|Next Section]]]
|}
----
Hour 24. The 10,000-Foot View
You know a lot about C# by now. You can create projects, use forms and controls to build an interface, and you know how to add menus and toolbars to a form. You've also learned how to create modules and procedures and how to write code to make things happen. You can use variables, make decisions, perform looping, and even debug your code. The question you may be thinking now is, "Where to next?"
Throughout this book, I've focused my discussions on C#. When it comes to Microsoft's .NET platform, however, C# is just part of the picture. In this hour, I provide an overview of Microsoft's .NET platform so that you can see how C# relates to .NET as a whole. By the time you finish this hour, you'll understand the various pieces of .NET and how they are interrelated. Hopefully, you'll be able to combine this information with your current personal and professional needs to determine the facets of .NET that you want to explore in more detail.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec1.htm#ch24lev1sec1 Introduction to the .NET Framework]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec2.htm#ch24lev1sec2 Appreciating the Common Language Runtime (CLR)]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec3.htm#ch24lev1sec3 Understanding Microsoft Intermediate Language (IL)]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec4.htm#ch24lev1sec4 Working with namespaces]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec5.htm#ch24lev1sec5 The Common Type System]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24lev1sec6.htm#ch24lev1sec6 Garbage collection]
The .NET Framework
The components and technology that make up Microsoft .NET are collectively called the .NET Framework. The framework comprises numerous classes and includes components such as the Common Language Runtime, Microsoft Intermediate Language, and ADO.NET. In the following sections, I'll explain the various pieces that make up the .NET Framework.
Common Language Runtime (CLR)
A language runtime is what allows an application to run on a target computer; it consists of code that is shared among all applications developed using a supported language. A runtime contains the "guts" of language code, such as code that draws forms to the screen, handles user input, and manages data. The runtime of .NET is called the Common Language Runtime (CLR).
Unlike runtimes for other languages, the CLR is designed as a multilanguage runtime. For example, C# and Visual Basic both use the CLR. In fact, currently more than 15 language compilers are being developed to use the CLR.
Because all .NET languages share the CLR, they share the same IDE, the same forms engine, the same exception-handling mechanism, the same garbage collector (discussed shortly), and much more. One benefit of the multilanguage capability of the CLR is that programmers can leverage their knowledge of a given .NET language. For example, some developers on a team may be comfortable with C#, whereas others are more comfortable with Visual Basic. Because both languages share the same runtime, both can be integrated to deliver a solution. In addition, a common exception-handling mechanism is built into the CLR so that exceptions can be thrown from code written in one language and caught in code written in another .NET language.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Code that runs within the CLR is called managed code because the code and resources used by the code (variables, objects, and so on) are fully managed by the CLR. C# is restricted to working only in managed code, but some languages (such as C++) are capable of dropping to unmanaged code�code that isn't managed by the CLR. One big advantage with working in managed code is that the CLR provides garbage collection�the automatic freeing up of unused resources. You'll learn a bit more about garbage collection later in this hour.
|}
Another advantage of the CLR is that all .NET tools share the same debugging and code-profiling tools. In the past, languages such as Visual Basic were limited to their own debugging tools, whereas languages such as C++ had many third-party debugging tools available. Now, all languages share the same tools. This means that as advancements are made to the debugging tools of one product, they're made to tools of all products because the tools are shared. This aspect goes beyond debugging tools. For example, add-ins to the IDE (such as code managers) are just as readily available to C# as they are to Visual Basic�or any other .NET language, for that matter.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Although Microsoft hasn't announced any official plans to do so, it's possible that Microsoft could produce a version of the CLR that runs on other operating systems, such as Macintosh or Linux. If this occurs, the applications that you've written for Windows should run on a newly supported operating system with little or no modification.
|}
Microsoft Intermediate Language
As you can see in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#ch24fig01 Figure 24.1], all .NET code, regardless of the language syntax used, compiles to Intermediate Language (IL) code. IL code is the only code the CLR understands; it doesn't understand C#, Visual Basic, or any other developer syntax. It's IL that gives .NET its multilanguage capabilities; as long as an original source language can be compiled to IL, it can become a .NET language. For example, people are developing a .NET compiler for COBOL�a mainframe language with a long history. This compiler will take existing COBOL code and compile it to IL so that it will run within the .NET Framework using the CLR. COBOL itself isn't a Windows language and doesn't support many of the features found in a true Windows language (such as a Windows Forms engine), so you can imagine the excitement of COBOL programmers at the prospect of being able to leverage their existing code and programming skills to create powerful Windows applications.
<div style="text-align: center;">Figure 24.1. These are the steps taken to turn developer code into a running component.
[[Image:24fig01.gif|495px|graphics/24fig01.gof]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| One of the potential drawbacks of IL is that it may be susceptible to reverse compilation. This has many people questioning the security of .NET code and the security of the .NET Framework, in general. If code security is a serious concern for you, I encourage you to research this matter on your own.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| IL code isn't the final step in the process of compiling and running an application. For a processor (CPU) to execute programmed instructions, those instructions must be in machine-language format. When you run a .NET application, a just-in-time compiler (called a JITter) compiles the IL to machine-language instructions that the processor can understand. IL code is processor independent, which again brings up the possibility that JITters could be built to create machine code for computers that are using something other than Intel-compatible processors. If Microsoft were to offer a CLR for operating systems other than Windows, much of the differences would lie in the way IL would be compiled by the JITter.
|}
As .NET evolves, changes made to the CLR will benefit all .NET applications. For example, if Microsoft finds a way to further increase the speed at which forms are drawn to the screen by making improvements to the CLR, all .NET applications will immediately benefit from the improvement. Optimizations made to a specific syntax compiler, such as the one that compiles C# code to IL, are language specific, however. This means that even though all .NET languages compile to IL code and use the CLR, it's possible for one language to have small advantages over another because of the way in which the language's code is compiled to IL.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Namespaces
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As I mentioned earlier, the .NET Framework is composed of classes�many classes. Namespaces are the method used to create a hierarchical structure of all these classes and they help prevent naming collisions. A naming collision occurs when two classes have the same name. Because namespaces provide a hierarchy, it's possible to have two classes with the same name, as long as they exist in different namespaces. Namespaces, in effect, create a scope for classes.
|}
The base namespace in the .NET Framework is the System namespace. The System namespace contains classes for garbage collection (discussed shortly), exception handling, data typing, and so much more. The System namespace is just the tip of the iceberg. There are literally dozens of namespaces. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#ch24table01 Table 24.1] lists some of the more common namespaces, many of which you've used in this book. All the controls that you've placed on forms and even the forms themselves, for example, belong to the System.Windows.Forms namespace. Use [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#ch24table01 Table 24.1] as a guide; if a certain namespace interests you, I suggest that you research it further in the Visual Studio .NET online help.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 24.1. Commonly Used Namespaces
|-
| valign="middle" | Namespace
| valign="middle" | Description
|-
| Microsoft.CSharp
| Contains classes that support compilation and code generation using the C# language.
|-
| Microsoft.VisualBasic
| Contains classes that support compilation and code generation using the Visual Basic language.
|-
| System
| Contains fundamental classes and base classes that define commonly used value and reference data types, event handlers, interfaces, attributes, and exceptions. This is the base namespace of .NET.
|-
| System.Data
| Contains classes that constitute the ADO.NET architecture.
|-
| System.Diagnostics
| Contains classes that enable you to debug your application and to trace the execution of your code.
|-
| System.Drawing
| Contains classes that provide access to the Graphical Device Interface (GDI) basic graphics functionality.
|-
| System.IO
| Contains classes that allow reading from and writing to data streams and files.
|-
| System.Net
| Contains classes that provide a simple programming interface to many of the protocols found on the network.
|-
| System.Security
| Contains classes that provide the underlying structure of the CLR security system.
|-
| System.Web
| Contains classes that provide interfaces that enable browser/server communication.
|-
| System.Windows.Forms
| Contains classes for creating Windows-based applications that take advantage of the rich user-interface features available in the Microsoft Windows operating system.
|-
| System.Xml
| Contains classes that provide standards-based support for processing XML.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| All Microsoft-provided namespaces begin with either System or Microsoft. Other vendors can provide their own namespaces, and it's possible for you to create your own custom namespaces as well, but that's beyond the scope of this book.
|}
Common Type System
The Common Type System in the CLR is the component that defines how data types are declared and used. The fact that the CLR can support cross-language integration to the level it does is largely because of the Common Type System. In the past, each language used its own data types and managed data in its own way. This made it very difficult for applications developed in different languages to communicate, because no standard way existed in which to pass data between them.
The Common Type System ensures that all .NET applications use the same data types, provides for self-describing type information (called metadata), and controls all the data manipulation mechanisms so that data is handled (stored and processed) in the same way among all .NET applications. This allows data (including objects) to be treated the same way in all .NET languages.
=== Garbage Collection ===
Although I've talked a lot about objects (you can't talk about anything .NET related without talking about objects), I've avoided discussing the underlying technical details of how .NET creates, manages, and destroys objects. Although you don't need to know the complex minutiae of how .NET works with objects, you do need to understand a few details of how objects are destroyed.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As I discussed in previous hours, setting an object variable to <code>null</code> or letting it go out of scope destroys the object. However, as I mentioned in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects Using Classes," this isn't the whole story. The .NET platform uses a garbage collector for destroying objects. The specific type of garbage collection implemented by .NET is called reference-tracing garbage collection. Essentially, the garbage collector monitors the resources used by a program, and when resources reach a defined threshold, the garbage collector proceeds to look for unused objects. When the garbage collector finds an unused object, it destroys it, freeing all the memory and resources the object was using.
|}
An important thing to remember about garbage collection is that releasing an object by setting it to null or letting an object variable go out of scope doesn't mean the object will be destroyed immediately. The object won't be destroyed until the garbage collector is triggered to go looking for unused objects.
Summary
Now that you've completed this book, you should have a solid working understanding of developing applications with C#. Nevertheless, you've just embarked on your journey. One of the things I love about developing applications is that there is always something more to learn, and there's always a better approach to a development problem. In this hour, I acquainted you with the "bigger picture" of Microsoft's .NET platform by exposing you to the .NET Framework and its various components. Consider the information you learned in this hour a primer; what you do with this information and where you go from here is entirely up to you.
I wish you the best of luck on your programming endeavors!
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#qad1e69464 Q1:]'''
| The .NET Framework seems incredibly complex and daunting. How should I go about learning it?
|-
| align="right" | ''' A1: '''
| I wouldn't recommend that you attempt to learn the entire framework; I have no plans to do so, either. Instead, focus on areas of interest or research facets of the framework as the need arises. For instance, if security is very important to you, learn about System.Security. Attempting to learn everything you can about the framework may not be as productive as spending your time mastering user-interface design and general programming skills.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#qad1e69474 Q2:]'''
| Does an end user have to have the Common Language Runtime on his or her computer to run my .NET application?
|-
| align="right" | ''' A2: '''
| Yes. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22.htm#ch22 Hour 22], "Deploying a Solution," I discussed how to deploy a solution, as well as how to include the Common Language Runtime. If you know for a fact that your end user has the runtime, you can remove it from your setup, vastly reducing the size of your setup program.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans01 1:]'''
| The classes and technology that make up .NET's underlying infrastructure are called what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans02 2:]'''
| What is the name of the shared .NET runtime?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans03 3:]'''
| True or False: Each .NET language uses its own code editor and debugging tools.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans04 4:]'''
| True or False: Code that runs within the Common Language Runtime is called unmanaged code.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans05 5:]'''
| Code written in a .NET language such as C# is compiled to what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans06 6:]'''
| What are namespaces?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans07 7:]'''
| One of the things that gives .NET its multilanguage capabilities is that all data is declared and managed in the same way across all languages. This is handled by .NET's what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec24.htm#ch24ans08 8:]'''
| What destroys objects, freeing all the resources that they consume?
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/24.htm#toppage Top]
|}
mcs194db2pg6i2hy14othesq9hjq4z0
User:Foxall/23
2
2141
39260
5602
2026-04-13T06:03:39Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39260
wikitext
text/x-wiki
== Hour 23. Introduction to Web Development ==
Visual Studio .NET, more than any previous Microsoft technology, offers incredible Web development tools and functionality. In fact, .NET is very much about programming for the Web. Creating Web applications requires a thorough understanding of all the skills you've acquired in this book�and more. In addition to the complexities of programming that you've dealt with, such as creating forms, writing code, and so on, additional concerns exist, such as Web protocols, firewalls, Web servers, and scalability. Teaching you how to create Web applications is beyond the scope of this book. However, it's important that you're at least a little familiar with the concepts and technologies involved with Microsoft's .NET Internet programming strategy. This hour gives you an overview of the .NET Web programming technologies.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec1.htm#ch23lev1sec1 XML]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec2.htm#ch23lev1sec2 SOAP (Simple Object Access Protocol)]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec3.htm#ch23lev1sec3 ASP.NET]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec4.htm#ch23lev1sec4 Web Forms]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch23lev1sec5.htm#ch23lev1sec5 XML Web services]
----
=== XML ===
XML (eXtensible Markup Language) is a universal format for transferring data across the Internet. On the surface, XML files are simply text files. However, this is oversimplifying things. The beauty in XML is that XML files themselves contain not only data, but self-describing information (metadata) about the data. The fact that XML files are text files makes it relatively easy to move them across boundaries (such as firewalls) and platforms.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Semantic tags are used to describe data in an XML file, and a starting and ending tag are used to define an element. The data between a starting and ending tag is the value of the element. Tags are similar to HTML tags and have the following format:
|}
<pre><tagname>data</tagname>
</pre>
For example, you could store a color in an element titled BackColor, like this:
<pre><BackColor>Blue</BackColor>
</pre>
It's important to note that XML tags are case sensitive; therefore, BackColor is not the same as backcolor, and both elements could exist in the same XML file.
Elements can be nested as long as the starting and ending tags of elements don't overlap. For example, two customers could be stored in an XML file like this:
<pre><Customer>
<Name>John Smith</Name>
<OrderItemID>Elder Scrolls: Morrowind</OrderItemID>
<Price>$20.00</Price>
</Customer>
<Customer>
<Name>Jane Aroogala</Name>
<OrderItemID>Ultima VII: The Black Gate</OrderItemID>
<Price>$62.00</Price>
</Customer>
</pre>
XML files can be much more complex, but this simple example should suffice to show you that XML documents are text documents that can store just about any type of data you can think of. In fact, Microsoft is using XML in just about everything, from ADO.NET to XML Web services.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
SOAP
To pass structured data across the Web (such as passing objects or calling methods on objects), the sender and receiver must agree on how the data will be transmitted. SOAP (Simple Object Access Protocol) is Microsoft's new protocol used to exchange structured data over the Web using an XML format. SOAP is lightweight (doesn't consume a lot of resources or bandwidth) and makes use of the widely accepted HTTP protocol. SOAP is fundamental to Microsoft's .NET strategy because it allows different applications on multiple platforms to share structured data and interoperate across the Web.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
ASP.NET
ASP.NET is the next evolution of ASP (Active Server Pages). ASP.NET is a framework for creating applications that reside on a Web server and that are run from within a client browser. ASP.NET enables you to program Web-based client-server applications using tools and methodologies much like those used to create traditional applications.
ASP.NET solutions execute on a Web server running Microsoft Internet Information Server (IIS). Therefore, to create ASP.NET solutions, you'll need to have some knowledge of IIS.
In a nutshell, ASP.NET is used to dynamically generate Web pages by serving up Web Forms (discussed shortly). For example, you may create an e-commerce site where a user may choose to view all products by category. Using ASP.NET, you could dynamically build and display a Web page containing the appropriate list of products. The server would execute the code to build the new Web page and then send the page to the user's browser as an HTML document.
Web Forms
Web Forms are similar to Windows Forms applications (which you've been creating and programming throughout this book). However, Web Forms are designed specifically to run in a browser over the Web. Although Web Forms are designed to run within any browser by default, you can target deployment to a specific browser to take advantage of a particular browser's features.
To create a Web Forms application, you choose ASP.NET Web Application on the New Project dialog box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/23.htm#ch23fig01 Figure 23.1]). Be aware that to create and test a Web Forms application, you will have to have a Web server installed. If you don't have a Web server installed and configured, you'll receive a message similar to that shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/23.htm#ch23fig02 Figure 23.2], and you'll be prevented from creating the project.
<div style="text-align: center;">Figure 23.1. A Web Forms project is different from a Windows Forms project.
[[Image:23fig01.jpg|500px|graphics/23fig01.jpg]]
</div>
<div style="text-align: center;">Figure 23.2. To create a Web Forms application, you will need to install and configure a Web server.
[[Image:23fig02.gif|414px|graphics/23fig02.gof]]
</div>
Comparing Windows Forms to Web Forms
Creating a Web Form application may offer many advantages. For example, to deploy a Web Form application, you have to deploy only to a Web server (not to all client machines). After it is set up on the server, users can run the program simply by pointing their browsers to the proper URL. Contrast this with the need to deploy a Windows Application to hundreds or thousands of users' computers. Another benefit of Web Forms is that applications are essentially platform independent because the code runs on the server and the browser is the only thing running on the client side. When deciding whether to make an application Windows-Forms based or Web-Forms based, consider the following.
Deployment
As mentioned previously, Windows applications built on Windows Forms are installed and executed on the user's machine. Web Forms, however, run within a browser and therefore do not require deployment to a client machine. Rather than having to install updates on every client as you do with a Windows Forms application, with a Web Forms application you need to update only the server (which must be running the .NET Framework).
Graphics
Windows Forms include the capability to interact with the Windows graphics device interface (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10.htm#ch10 Hour 10], "Drawing and Printing," for information on the GDI) to create intricate graphics with excellent performance. Web Forms can access the GDI on a Web server. However, round-trips are required for screen updates, which can negatively affect the performance of drawing graphics.
Responsiveness
When an application requires a high degree of interactivity with the user (such as screen updates, lots of event code, and data validation), Windows Forms provide the best performance because they run on the client machine. Most interactive processes with Web Forms require round-trips to the server, which again can negatively affect the responsiveness of an application.
Text Formatting and Control Positioning
Windows Forms provide exceptional capability of placing controls (for example, Windows Forms support snapping to grids). Displaying text on a Windows Form, however, requires using controls such as a label or a text box. Making text flow on a Windows Form (such as flowing around other controls when adjusting to the sizing of a form) can be very difficult to accomplish. In addition, formatting text can be problematic because most controls support only one font at a time.
Web Forms, on the other hand, are served to clients as HTTP Web pages, which excel at formatting and flowing text. Web Forms aren't as precise as Windows Forms when it comes to placing controls, however.
.NET Platform Installation
To run a Windows Forms application, users must have the .NET Framework installed on their computer. Web Forms, however, are installed on the server; therefore, the .NET Framework must be installed on the server but isn't needed on the client. The client needs only a Web browser. It is important to note that future service packs of Windows will likely include the latest .NET Framework�but don't depend on this.
Security and System Resources
Windows Forms applications can have complete control over system resources such as the Registry and also may be restricted using the operating system's security features. Web Forms are restricted by the user's browser security settings and thus have very limited access to system resources.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
XML Web Services
Perhaps the technology that Microsoft is most excited about in .NET is XML Web services. Microsoft describes an XML Web service as "a unit of application logic providing data and services to other applications." It's easiest to think of XML Web services as applications that reside on a server without a user interface, providing objects to clients. The following are a few practical examples of what can be done with XML Web services:
* A company could create stock quote XML Web services that clients could use to get real-time stock quotes.
* A doctor's office could expose scheduling functions so that clients could use their mobile devices to schedule appointments.
* A government office could expose tax-related objects, which businesses could use to get accurate tax rates.
* A company could expose data that is paid for by subscription. When clients access the data via the Web service's objects, a billing system could track the number of accesses.
* An auction company such as eBay could expose its bidding system as authenticated XML Web services, and third-party vendors could create their own front ends to placing bids on the auction site.
Obviously, this list just scratches the surface. Microsoft ambitiously envisions everyone exposing application logic as XML Web services. Although this may not become a reality in the near future (indeed, XML Web services may never take off like Microsoft hopes), many companies are generating a lot of excitement about this technology.
As a programmer, a lot of the details of XML Web services are handled for you by .NET. For example, SOAP and XML are used to marshal objects and method calls across the Web so that you don't have to worry about the details of the plumbing. Because a standard protocol is used to marshal this information, you don't have to worry about the language or the platform used to implement the XML Web services�almost any type of client can consume XML Web services (C#, Visual Basic, Java, and so on). Clients don't even have to be Windows based or even be PCs; Web-enabled phones and other wireless devices can consume XML Web services.
Writing code to consume XML Web services is actually similar to writing code to access an Automation server. First, you create a Web reference, which is much like creating a reference to an Automation library such as Excel or ADO. After you've got a reference to the XML Web services, the objects become available in code, and you can browse them as you would "traditional" objects.
To create XML Web services, you have to have a sound understanding of creating objects by programming classes, and you have to learn ASP.NET�the underlying technology of XML Web services. The .NET Framework handles the details of using SOAP to allow clients to interact with your XML Web services, so you focus most of your attention on creating useful objects rather than on details of the underlying plumbing.
Programming for the Web is an exciting proposition, and one that can't be entered into lightly. To create robust Web applications requires an understanding of a lot of technologies, including Web servers, protocols, firewalls, security, object-oriented programming concepts, and much more. By completing this book, you're gaining a solid understanding of application development with C#, and you're building a set of skills that you can use to move into Web programming. If you're interested in Web development, you should consider purchasing a book dedicated to the subject, such as ''Sams Teach Yourself C# Web Programming in 21 Days''.
=== Q&A ===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/23.htm#qad1e68577 Q1:]'''
| Can I use XML files within my applications?
|-
| align="right" | ''' A1: '''
| Yes, you can design your own XML files and use them any way you see fit. For example, you could save a configuration file in an XML file with a scheme you've designed. For more information, look at the documentation on <code>System.Xml</code> in the online Help.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans01 1:]'''
| What does XML stand for?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans02 2:]'''
| An element is designated in an XML document using the what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans03 3:]'''
| True or False: XML tag names are case sensitive.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans04 4:]'''
| What is the name of the protocol used by .NET to marshal object requests across the Web?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans05 5:]'''
| What forms engine is used to create forms that run over the Internet?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans06 6:]'''
| Which forms engine provides for faster response to user interaction?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans07 7:]'''
| Where is the .NET Framework installed for Windows Forms applications? Web Forms applications?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec23.htm#ch23ans08 8:]'''
| What is the name of the ASP.NET technology used to expose application logic as objects over the Web?
|}
p24kw6dzh96gc6q6bl3g65e6c9bg38l
User:Foxall/22
2
2142
39259
5603
2026-04-13T06:03:39Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39259
wikitext
text/x-wiki
== Hour 22. Deploying a Solution ==
Now you've learned how to create a C# application, and you're just itching to create some project and send it to the world. Fortunately, Visual Studio includes the tools you need to create a setup program for an application. In this hour, you'll learn how to use these tools to create a setup program that a user can run to install an application you've developed. In fact, you'll be creating a setup program for the Picture Viewer application you created in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour."
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev1sec1 Creating a custom setup program]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec2.htm#ch22lev1sec2 Installing the output of a project]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev3sec1 Changing the installation location of a file]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev3sec2 Specifying build options]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev2sec2 Adding files to an installation]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev2sec3 Creating a custom folder on installation]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch22lev1sec1.htm#ch22lev2sec4 Creating a shortcut on the Start menu]
----
=== Creating a Custom Setup Program ===
A custom setup program (the program the user runs to install a program) is the result of building a special type of project in C#. Throughout most of this book, you've created projects of the type Windows Application. To create a custom setup program, you start with a different type of project. Start Visual Studio and choose to create a new project now. On the New Project dialog box, click the Setup and Deployment Projects item to display its contents, and then click Setup Project (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig01 Figure 22.1]). This is the project type to use when you distribute Windows Applications; use the Web Setup Project item when distributing Web projects. Enter the name TYCSharp Picture Viewer and click OK to create the project.
<div style="text-align: center;">Figure 22.1. Create a Setup Project to distribute Windows Applications.
[[Image:22fig01.jpg|500px|graphics/22fig01.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The name you give your Setup Project is the name that will appear in the setup wizard when the user installs your program. Unfortunately, the name you use for this project can't be the same as the one you used for the project whose output you are distributing (for reasons you'll learn shortly). This is why I had you put TYCSharp (for Teach Yourself C#) in the project name.
|}
The interface for a Setup Project consists primarily of two panes. The pane on the left side represents the file system of the target machine (the computer on which the software is being installed).
The pane on the right shows the contents of the selected item in the left pane (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig02 Figure 22.2]). You really can do a lot when creating custom setup programs, but as you'll see, accessing the features to modify your setup program isn't all that intuitive.
<div style="text-align: center;">Figure 22.2. The interface for creating a setup program isn't intuitive.
[[Image:22fig02.jpg|500px|graphics/22fig02.jpg]]
</div>
Adding the Output of a Project
At this point, the setup program doesn't install anything; you need to add the output of another project. For the purposes of creating a setup program, the final file (EXE, DLL, and so on) produced in building a C# project is called the output of the project. The setup program is used to install the output of a project on the user's computer. The first step to including a project's output is to add the project to the setup program project. Because you're creating a setup program for the Picture Viewer you created in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], you need to add the Picture Viewer project to the current solution.
Add the project to the solution now by right-clicking the solution name in the Solution Explorer window and then choosing Existing Project from the Add menu. Use the Add Existing Project dialog box to locate your Picture Viewer project and add it to the current solution. The Picture Viewer project should now appear in the Solution Explorer (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig03 Figure 22.3]).
<div style="text-align: center;">Figure 22.3. To distribute the output of a project, the project must be part of the solution.
[[Image:22fig03.jpg|332px|graphics/22fig03.jpg]]
</div>
Now that the Picture Viewer project is part of the solution, you have to tell the setup program to install the output of the Picture Viewer project. This is where things get a bit odd because the Project menu changes according to what project you have selected in the Project Explorer. What you're going to do next is have the Setup Project install the final executable of your Picture Viewer project.
# Click the TYCSharp Picture Viewer project in the Solution Explorer before continuing. If you don't do this, you won't find the appropriate menu items when you open the Project menu.
# Open the Project menu and then open the Add submenu.
# Choose Project Output to display the Add Project Output Group dialog box that appears in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig04 Figure 22.4]. Make sure that the project selected is Picture Viewer and that Primary Output is selected as well.
<div style="text-align: center;">Figure 22.4. Choosing Primary Output ensures that the distributable file of the project is installed on the user's machine.
[[Image:22fig04.jpg|324px|graphics/22fig04.jpg]]
</div>
# Click OK to commit your selections.
# Next, click the Application Folder in the left pane to view its contents. Notice that it now contains the primary output from the Picture Viewer project. This means that the EXE built by the Picture Viewer project will be installed in whatever folder the user designates as the application folder.
Changing the Installation Location of a File
You have complete control over where on the user's computer a file is installed. Most program files (such as the output of the Picture Viewer project) are installed in an application folder. The Application Folder has the following path by default:
<pre>[ProgramFilesFolder][\Manufacturer][\ProductName]
</pre>
Users can change this when they run your setup program. However, you might want to change the default folder as well, which is what you'll do next.
Right-click the Application Folder in the left pane and choose Properties Window from its Context menu. In the Properties Window, notice that the DefaultLocation property contains the information that defines the default installation location. The items in brackets are tokens that get replaced when the user is running the setup program. The Manufacturer token pulls its value from the company name you entered when you installed C#. Go ahead and change the DefaultLocation property to the following:
<pre>[ProgramFilesFolder]\[ProductName]
</pre>
This new property value eliminates one folder in the final path.
Specifying the Build Options of a Project's Output
At this point, the setup program installs the final output of the Picture Viewer program, which is an EXE. However, you have more control over the output of a project than just the file type. For example, you can specify the icon assigned to the EXE file. Right-click the Picture Viewer project in the Solution Explorer and choose Properties from its context menu to display the Picture Viewer Property Pages dialog box. Next, click General in the list on the left to display the General options for the project (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig05 Figure 22.5]).
<div style="text-align: center;">Figure 22.5. Use this dialog box to tailor the output of a project.
[[Image:22fig05.jpg|500px|graphics/22fig05.jpg]]
</div>
The icon specified appears wherever a shortcut is created for your program. The default icon assigned to executables isn't all that attractive (and even less meaningful), so I recommend that you assign a custom icon. Go ahead and click the Application Icon item to select it, and then click the Build button (<code>...</code>) that appears to the right of the Application Icon. Select the same icon that you used for the Picture Viewer's form.
Adding a File to the Install
You aren't limited to installing the output of a project; you can install any file that you choose. For example, you might want to include sample data or support files with your program. You're now going to install a bitmap with your application so that the user has something to view. Again, select the TYCSharp Picture Viewer project in the Solution Explorer or you won't have the appropriate items on the Project menu. Next, add a file by opening the Project menu and then choosing File from the submenu. Locate a BMP or JPG on your system, click it to select it, and then click Open to add the file to the install project.
Adding a Custom Folder to the Install
The pane on the left lists folders that correspond to folders on the user's computer. You can add other folders to this list. These folders may already exist on the user's computer (such as the user's Favorites folder) or may be a brand-new folder that your install creates. Add a new folder to the install now by right-clicking the File System on Target Machine item in the left pane (the first item) and choosing Add Special Folder from its context menu. As you can see, you can select from a number of folders that already exist on the user's computer. Now, however, you're going to create a custom folder:
# Choose Custom Folder (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig06 Figure 22.6]). The new folder is added to the left pane.
<div style="text-align: center;">Figure 22.6. It's easy to select existing folders or create new ones.
[[Image:22fig06.jpg|338px|graphics/22fig06.jpg]]
</div>
# Change the name of the new folder to Pictures.
# Click Application Folder again. Notice that the BMP file you selected for installation appears in the Application Folder.
# Drag the bitmap to the Pictures folder you just created. Now, when the picture is installed, it will be installed in the Pictures folder.
Creating a Shortcut on the Start Menu
The Setup Project doesn't automatically create shortcuts for your application�you have to create these yourself. Most applications create a shortcut in the Programs folder on the Start menu (or in a subfolder of the Project folder). You're going to create a shortcut for the Picture Viewer program. This shortcut will be placed in the Programs folder on the Start menu.
Click the Application Folder to view its contents. Right-click the Primary Output from Picture Viewer item and choose Create Shortcut to Primary Output from Picture Viewer. C# creates the shortcut item and places it in the Application Folder. Drag the shortcut to the User's Programs Menu item in the left pane. Now, when the user installs your program, a shortcut will be placed in the Programs folder on the user's Start menu.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Apparently, an issue with .NET prohibits the user from moving the shortcuts for .NET applications after they're installed. Hopefully, Microsoft will eventually correct this. As it stands, however, if the user moves the shortcuts, Windows will move them back. For this reason alone, you should pick a good name for your folder.
|}
Defining the Build Configuration for the Setup Program
When you create a setup program, you can choose to include debug information. This information allows you to perform advanced debugging using techniques beyond the scope of this book. When distributing to other machines, you may want to leave out this debugging information and instead create a Release build. Release builds are smaller and faster than Debug builds. Change your installation to a Release build by choosing Configuration Manager from the Build menu and selecting Release from the drop-down list (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig07 Figure 22.7]). Click Close to save your changes.
<div style="text-align: center;">Figure 22.7. Release builds are smaller and faster than Debug builds.
[[Image:22fig07.jpg|453px|graphics/22fig07.jpg]]
</div>
Installing the Common Language Runtime (CLR)
The Common Language Runtime (discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24], "The 10,000-Foot View") allows any Visual Studio .NET language (C#, Visual Basic .NET, and so on) to run on a computer. For a user to run your C# application, the Common Language Runtime (CLR) must exist on the user's computer. By default, your new setup program contains the CLR; therefore, the CLR will be installed when your application is installed (if the current version of the CLR isn't already installed on the user's computer). If you know for a fact that your end user already has the CLR installed (such as when distributing an update to your application), you can omit the CLR from your installation�creating a much smaller installation file (14MB smaller in my tests). The CLR is listed in your Solution Explorer as dotnetfxredist_x86_enu.msm (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig08 Figure 22.8]). To remove the CLR from your installation, right-click the item and choose Exclude from its context menu.
<div style="text-align: center;">Figure 22.8. The CLR looks like this in the Solution Explorer.
[[Image:22fig08.jpg|332px|graphics/22fig08.jpg]]
</div>
Building the Setup Program
That's it, you're done! All you have left is to actually build the program. Choose Build Solution from the Build menu to create the distributable file. As Visual Studio is building the file, a small animation appears in the status bar. This is because it can take some time to build a file, especially for large solutions compiling on slower machines with minimum RAM. When Visual Studio is done building the setup program, the status bar will read Build Succeeded. The setup program can be found in the Release subfolder of the TYCSharp Picture Viewer project folder. The file has the extension of MSI, which indicates that the file is a Windows Installer Package.
Running a Custom Setup Program
You should always test your setup programs before distribution. (I recommend that you test your setup wizard on a separate machine when possible.) You're now going to run the custom setup program that you've built, but you'll just do it on your current machine. Shut down C# now, saving your work if prompted. Double-click the installation program in the Release folder to start your custom setup program. The setup program is a wizard (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig09 Figure 22.9]), so installation for an end user is pretty simple. Click Next to pass the Welcome page.
<div style="text-align: center;">Figure 22.9. Your final setup program is in the form of a wizard.
[[Image:22fig09.jpg|500px|graphics/22fig09.jpg]]
</div>
The second page in your setup program is where the user can specify the installation folder. Notice that the default path is what you specified when you created the setup program (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig10 Figure 22.10]). The wizard even allows the user to install the application for shared use; you don't have to worry about the details. Clicking Disk Cost shows all installed drives, their disk space, and the disk space required by the setup program. Click Next to accept the default path and continue.
<div style="text-align: center;">Figure 22.10. The user can change your default installation path.
[[Image:22fig10.jpg|500px|graphics/22fig10.jpg]]
</div>
The last page of your setup wizard is used to ask for confirmation before installing the files (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig11 Figure 22.11]). You can add a lot more functionality to your setup program, and doing so might create additional pages in the final setup wizard. However, this example is pretty straightforward, so there's not much to the wizard. Click Next to install the Picture Viewer program. After the program is installed, users will get one last wizard page telling them the installation is complete (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig12 Figure 22.12]).
<div style="text-align: center;">Figure 22.11. Clicking Next from here causes your program to be installed.
[[Image:22fig11.jpg|500px|graphics/22fig11.jpg]]
</div>
<div style="text-align: center;">Figure 22.12. A successful installation!
[[Image:22fig12.jpg|500px|graphics/22fig12.jpg]]
</div>
Open up the Start menu and look at the contents of your Programs folder; you should see the shortcut to your Picture Viewer program. Click the shortcut to start your program. That's it! You've just created an installation program that installs the Picture Viewer program, and you can now distribute your program to other computers�even if they don't have C# installed.
=== Uninstalling an Application You've Distributed ===
All Windows applications should provide a facility for easily being removed from the user's computer. Most applications provide this functionality in the Add/Remove Programs dialog box, and yours is no exception. Open the Start menu, choose Settings, and then click Control Panel. Locate the Add/Remove Programs icon and double-click it. Scroll down in your Add/Remove programs dialog box until you find the Picture Viewer program (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#ch22fig13 Figure 22.13]). To uninstall the program, click it to select it and then click Remove.
<div style="text-align: center;">Figure 22.13. Your program can be uninstalled using the Add/Remove Programs dialog box.
[[Image:22fig13.jpg|500px|graphics/22fig13.jpg]]
</div>
Summary
In this hour, you learned how to create a custom setup program to distribute an application you've built using C#. You learned how to work with folders on the user's computer, how to create shortcuts, how to install files, and how to install the output of a C# project. Custom setup programs can get quite complex, but even the most advanced ones build on the foundation of skills you learned in this hour. Creating a useful program is a very rewarding experience. Nevertheless, your level of satisfaction will increase dramatically the first time you have a user running your creation on the user's own computer.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#qad1e66918 Q1:]'''
| Should I always include the Common Language Runtime (CLR) in my setup programs?
|-
| align="right" | ''' A1: '''
| That depends. If you're planning on distributing to a lot of users, it's probably best to include the CLR. If you're just distributing to a few users and you're sure they have the CLR, it may not be so important.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/22.htm#qad1e66934 Q2:]'''
| Can I install multiple applications in a single setup program?
|-
| align="right" | ''' A2: '''
| Yes. Just add each project as you did the Picture Viewer project, and be sure to include the output of each project.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans01 1:]'''
| To create a custom setup program, you start by creating what type of Visual Studio project?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans02 2:]'''
| The final build file of a project (EXE, DLL, and so on) is referred to as the what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans03 3:]'''
| True or False: To include the output of a project, the project must be added to the solution containing the setup program.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans04 4:]'''
| Which build option creates smaller and faster builds?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans05 5:]'''
| How do you add a file to an installation?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans06 6:]'''
| If the Project menu doesn't have the menu options for creating a setup program, what might be wrong?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans07 7:]'''
| How do you add folders to the custom setup program?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec22.htm#ch22ans08 8:]'''
| How do you create a shortcut for a file in a setup program?
|}
Exercises
# Modify the setup program you created in this hour so that the shortcut created appears on the Start menu with the name Picture Viewer. Also, give the shortcut the same icon you assigned to the Picture Viewer program.
# Modify the setup program that you created in this hour so that it creates a custom folder within the Programs folder on the Start menu. Install the shortcut to this folder.
qj6f1v6aer4wrl0bxxlf9l4ixm64cup
User:Foxall/21
2
2143
39258
5604
2026-04-13T06:03:38Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39258
wikitext
text/x-wiki
== Hour 21. Working with a Database ==
You've heard it so many times that it's almost a cliché: This is the information age. Information is data, and managing information means working with databases. Database design is a skill unto itself, and entire books are devoted to database design and management. In this hour, you'll learn the basics of working with a database using ADO.NET, Microsoft's newest database technology. Although high-end solutions are built around advanced database technologies such as Microsoft's SQL Server, the Microsoft Jet database (used by Microsoft Access) is more readily available and easier to learn, so you'll build working examples that use a Jet database.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec1.htm#ch21lev1sec1 Introduction to ADO.NET]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec2.htm#ch21lev1sec2 Connecting to a database]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec3.htm#ch21lev2sec2 Understanding DataTables]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec3.htm#ch21lev2sec3 Creating a DataAdapter]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec3.htm#ch21lev2sec5 Referencing fields in a DataRow]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec3.htm#ch21lev2sec6 Navigating records]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec3.htm#ch21lev2sec6 Adding, editing, and deleting records]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch21lev1sec4.htm#ch21lev1sec4 Building an ADO.NET example]
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You'll learn a lot in this hour, but realize that this material is really the tip of the iceberg. Database programming can be, and often is, very complex. This hour is intended to get you writing database code as quickly as possible, but if you plan on doing a lot of database programming, you'll want to consult a dedicated book (or two) on the subject.
|}
Start by creating a new Windows Application named Database Example. Change the name of the default form to fclsMain and set its Text property to Database Example. Next, click the View Code button on the Solution Explorer window to access the form's code, scroll down and locate the procedure Main(), and change the reference of Form1 to fclsMain. Finally, click the Form1.cs tab to return to the form designer.
----
=== Introduction to ADO.NET ===
ADO.NET is the .NET platform's new database technology, and it builds on ADO (Active Data Objects). ADO.NET defines DataSet and DataTable objects that are optimized for moving disconnected sets of data across intranets and Internets, including through firewalls. At the same time, ADO.NET includes the traditional Connection and Command objects, as well as an object called a DataReader that resembles a forward-only, read-only ADO recordset. Together these objects provide the very best performance and throughput for retrieving data from a database.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Connecting to a Database
To access data in a database, you must first establish a connection using an ADO.NET connection object. Two connection objects are included in the .NET Framework: the OleDbConnection object, for working with the same OLE DB data providers you would access through traditional ADO, and the SqlConnection object, for optimized access to Microsoft SQL Server. Because these examples connect to the Microsoft Jet Database, you'll be using the OleDbConnection object. To create an object variable of type OleDbConnection and initialize the variable to a new connection, you could use a statement such as the following:
<pre>OleDbConnection cnADONetConnection = new OleDbConnection();
</pre>
To use ADO.NET, the first step that you need to take is to add the proper Namespace to your project. Double-click the form now to access its events. Scroll to the top of the class and add the following <code>using</code> statement on the line below the other <code>using</code> statements:
<pre>using System.Data.OleDb;
</pre>
You're going to create a module-level variable to hold the connection, so place the cursor below the left bracket (<code>{</code>) that follows the statement <code>public class fclsMain : System.Windows.Forms.Form</code> and press Enter to create a new line. Enter the following statement:
<pre>OleDbConnection m_cnADONetConnection = new OleDbConnection();
</pre>
Before using this connection, you must specify the data source to which you want to connect. This is done through the ConnectionString property of the ADO.NET connection object. The ConnectionString contains connection information such as the name of the provider, username, and password. The ConnectionString might contain many connection parameters; the set of parameters available varies depending on the source of data that you are connecting to. Some of the parameters used in the OLE DB ConnectionString are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21table01 Table 21.1]. If you specify multiple parameters, separate them with a semicolon.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 21.1. Possible Parameters for ConnectionString
|-
| Parameter
| Description
|-
| <code>Provider=</code>
| The name of the data provider (Jet, SQL, and so on) to use.
|-
| <code>Data Source=</code>
| The name of the data source (database) to connect to.
|-
| <code>UID=</code>
| A valid username to use when connecting to the data source.
|-
| <code>PWD=</code>
| A password to use when connecting to the data source.
|-
| <code>DRIVER=</code>
| The name of the database driver to use. This isn't required if a DSN is specified.
|-
| <code>SERVER=</code>
| The network name of the data source server.
|}
The Provider= parameter is one of the most important at this point and is governed by the type of database you're accessing. For example, when accessing a SQL database, you specify the provider information for SQL; when accessing a Jet database, you specify the provider for Jet. In this example, you'll be accessing a Jet (Microsoft Access) database, so you'll use the provider information for Jet.
In addition to specifying the provider, you're also going to specify the database. I've provided a sample database at the Web site for this book. This code assumes that you've placed the database in a folder called C:\Temp. If you are using a different folder, you'll need to change the code accordingly.
To specify the ConnectionString property of your ADO.NET connection, place the following statement in the Load event of your form:
<pre>m_cnADONetConnection.ConnectionString =
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\temp\contacts.mdb";
</pre>
After the connection string is defined, a connection to a data source is established by using the Open() method of the connection object. The Open() method has the following syntax:
<pre>objectvariable.Open();
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Refer to the online documentation for information on the connection strings for providers other than Jet.
|}
When you attach to an unsecured Jet database, it's not necessary to provide a username and password. When attaching to a secured Jet database, however, you'll have to provide a username and a password. This is done by passing the username and password as parameters in the ConnectionString property. The sample database I've provided isn't secured, so it's not necessary to provide a username and password.
Closing a Connection to a Data Source
You should always explicitly close a connection to a data source. This means that you should not rely on a variable going out of scope to close a connection, but you should force an explicit disconnect via code. This is accomplished by calling the Close() method of the connection object.
You're now going to write code to explicitly close the connection when the form is closed. Start by clicking the Form1.cs tab to return to the form designer. Next, click the Events button on the Properties window (the lightening bolt) to access the list of events for the form. Double-click the Closed event to create a new event handler. Enter the following statement in the Closed event:
<pre>m_cnADONetConnection.Close();
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Manipulating Data
The easiest way to manipulate data using ADO.NET is to create a DataTable object containing the resultset of a table, query, or stored procedure. Using a DataTable, you can add, edit, delete, find, and navigate records. The following sections explain how to use DataTables.
Understanding DataTables
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| DataTables contain a snapshot of the data in the data source. You generally start by filling a DataTable, and then you manipulate the results of the DataTable before finally sending the changes back to the data source. The DataTable is populated using the Fill() method of a DataAdapter object, and changes are sent back to the database using the Update() method of a DataAdapter. Any changes made to the DataTable appear only in the local copy of the data until you call the Update() method. Having a local copy of the data reduces contention by preventing users from blocking others from reading the data while it is being viewed. This is similar to the Optimistic Batch Client Cursor in ADO.
|}
Creating a DataAdapter
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| To populate a DataTable, you need to create a DataAdapter, an object that provides a set of properties and methods to retrieve and save data between a DataSet and its source data. The DataAdapter you're going to create will use the connection you've already defined to connect to the data source and will then execute a query you'll provide. The results of that query will be pushed into a DataTable.
|}
Just as two ADO.NET connection objects are in the .NET Framework, there are two ADO.NET DataAdapter Objects as well: the OleDbDataAdapter and the SqlDataAdapter. Again, you'll be using the OleDbDataAdapter because you aren't connecting to Microsoft SQL Server.
The constructor for the DataAdapter optionally takes the command to execute when filling a DataTable or DataSet, as well as a connection specifying the data source. (You could have multiple connections open in a single project.) This constructor has the following syntax:
<pre>OleDbDataAdapter cnADONetAdapter = new
OleDbDataAdapter([CommandText],[Connection]);
</pre>
To add the DataAdapter to your project, first add the following statement immediately below the statement you entered to declare the m_cnADONewConnection object.
<pre>OleDbDataAdapter m_daDataAdapter = new OleDbDataAdapter();
</pre>
Next, add the following statement to the Load event of the form, immediately following the statement that creates the connection:
<pre>_daDataAdapter =
new OleDbDataAdapter("Select * From Contacts",m_cnADONetConnection);
</pre>
Because you're going to use the DataAdapter to update the original data source, you need to specify the insert, update, and delete statements to use to submit changes from the DataTable to the data source. ADO.NET lets you customize how updates are submitted by allowing you to manually specify these statements as database commands or stored procedures. In this case, you're going to have ADO.NET automatically generate these statements for you by creating a CommandBuilder object. Enter the following statement to create the CommandBuilder.
<pre>OleDbCommandBuilder m_cbCommandBuilder =
new OleDbCommandBuilder(m_daDataAdapter);
</pre>
When you create the CommandBuilder, you pass into the constructor the DataAdapter that you want the CommandBuilder to work with. The CommandBuilder then registers for update events on the DataAdapter and provides the insert, update, and delete commands as needed. You don't need to do anything further with the CommandBuilder.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| When using a Jet database, the CommandBuilder object can create the dynamic SQL code only if the table in question has a primary key defined.
|}
Creating and Populating DataTables
You're going to create a module-level DataTable in your project. First, create the DataTable variable by adding the following statement on the line below the statement you entered previously to declare a new module-level m_daDataAdapter object:
<pre>DataTable m_dtContacts = new DataTable();
</pre>
You are going to use an integer variable to keep track of the user's current position within the DataTable. To do this, add the following statement immediately below the statement you just entered to declare the new DataTable object:
<pre>int m_rowPosition = 0;
</pre>
Next, add the following statement to the Load event of the form, immediately following the statement that creates the CommandBuilder:
<pre>m_daDataAdapter.Fill(m_dtContacts);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Because the DataTable doesn't hold a connection to the data source, it's not necessary to close it when you're finished.
|}
Your class should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig01 Figure 21.1].
<div style="text-align: center;">Figure 21.1. This code accesses a database and creates a DataTable that can be used anywhere in the class.
[[Image:21fig01.jpg|500px|graphics/21fig01.jpg]]
</div>
Referencing Columns in a DataRow
DataTables contain a collection of DataRows. To access a row within the DataTable, you specify the ordinal of that DataRow. For example, you could access the first row of your DataTable like this:
<pre>DataRow m_rwContact = m_dtContacts.Rows[0];
</pre>
Data elements in a DataRow are called columns. For example, two columns, ContactName and State, are in the Contacts table I've created. To reference the value of a column, you can pass the column name to the DataRow like this:
<pre>m_rwContact["ContactName"] = "Bob Brown";
</pre>
or
<pre>Debug.WriteLine(m_rwContact["ContactName"]);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you spell a column name incorrectly, an exception occurs when the statement executes at runtime.
|}
You're now going to create a procedure that is used to display the current record in the database. To display the data, you need to add a few controls to the form. Create a new text box and set its properties as follows (you'll probably need to click the Properties button on the Properties window to view the text box's properties rather than its events):
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtContactName</code>
|-
| <code>Location</code>
| <code>48,112</code>
|-
| <code>Size</code>
| <code>112,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Add a second text box to the form and set its properties according to the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtState</code>
|-
| <code>Location</code>
| <code>168,112</code>
|-
| <code>Size</code>
| <code>80,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Next, click the Form1.cs tab in the IDE to return to the code window. Position the cursor after the right bracket that ends the fclsMain_Closed() event and press Enter a few times to create some blank lines. Next, enter the following procedure in its entirety:
<pre>private void ShowCurrentRecord()
{
if (m_dtContacts.Rows.Count==0)
{
txtContactName.Text = "";
txtState.Text = "";
return;
}
txtContactName.Text =
m_dtContacts.Rows[m_rowPosition]["ContactName"].ToString();
txtState.Text = m_dtContacts.Rows[m_rowPosition]["State"].ToString();
}
</pre>
Ensure that the first record is shown when the form loads by adding the following statement to the Load event, after the statement that fills the DataTable:
<pre>this.ShowCurrentRecord();
</pre>
You've now ensured that the first record in the DataTable is shown when the form first loads. Next, you'll learn how to navigate and modify records in a DataTable.
Navigating and Modifying Records
The ADO.NET DataTable object supports a number of methods that can be used to access its DataRows. The simplest of these is the ordinal accessor that you used in your ShowCurrentRecord() method. Because the DataTable has no dependency on the source of the data, this same functionality is available regardless of where the data came from.
You're now going to create buttons that the user can click to navigate the DataTable.
The first button is used to move to the first record in the DataTable. Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnMoveFirst</code>
|-
| <code>Location</code>
| <code>16,152</code>
|-
| <code>Size</code>
| <code>32,23</code>
|-
| <code>Text</code>
| <code><<</code>
|}
Double-click the button and add the following code to its Click event:
<pre>m_rowPosition = 0;
this.ShowCurrentRecord();
</pre>
A second button is used to move to the previous record in the DataTable. Add another button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnMovePrevious</code>
|-
| <code>Location</code>
| <code>56,152</code>
|-
| <code>Size</code>
| <code>32,23</code>
|-
| <code>Text</code>
| <code><</code>
|}
Double-click the button and add the following code to its Click event:
<pre>if (m_rowPosition > 0)
{
m_rowPosition = m_rowPosition-1;
this.ShowCurrentRecord();
}
</pre>
A third button is used to move to the next record in the DataTable. Add a third button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnMoveNext</code>
|-
| <code>Location</code>
| <code>96,152</code>
|-
| <code>Size</code>
| <code>32,23</code>
|-
| <code>Text</code>
| <code>></code>
|}
Double-click the button and add the following code to its Click event:
<pre>if (m_rowPosition < m_dtContacts.Rows.Count-1)
{
m_rowPosition = m_rowPosition + 1;
this.ShowCurrentRecord();
}
</pre>
A fourth button is used to move to the last record in the DataTable. Add yet another button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnMoveLast</code>
|-
| <code>Location</code>
| <code>136,152</code>
|-
| <code>Size</code>
| <code>32,23</code>
|-
| <code>Text</code>
| <code>>></code>
|}
Double-click the button and add the following code to its Click event:
<pre>If (m_dtContacts.Rows.Count !=0)
{
m_rowPosition = m_dtContacts.Rows.Count-1;
this.ShowCurrentRecord();
}
</pre> Editing Records
To edit records in a DataTable, simply change the value of a particular column in the desired DataRow. Remember, however, that changes are not made to the original data source until you call Update() on the DataAdapter, passing in the DataTable containing the changes.
You're now going to add a button that the user can click to update the current record. Add a new button to the form now and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnSave</code>
|-
| <code>Location</code>
| <code>176,152</code>
|-
| <code>Size</code>
| <code>40,23</code>
|-
| <code>Text</code>
| <code>Save</code>
|}
Double-click the Save button and add the following code to its Click event:
<pre>if (m_dtContacts.Rows.Count !=0)
{
m_dtContacts.Rows[m_rowPosition]["ContactName"]= txtContactName.Text;
m_dtContacts.Rows[m_rowPosition]["State"] = txtState.Text;
m_daDataAdapter.Update(m_dtContacts);
}
</pre> Creating New Records
Adding records to a DataTable is performed very much like editing records. However, to create a new row in the DataTable, you must first call the NewRow() method. After creating the new row, you can set its column values. The row isn't actually added to the DataTable, however, until you call the Add() method on the DataTable's RowCollection.
You're now going to modify your interface so that the user can add new records. You'll use one text box for the contact name and a second text box for the state. When the user clicks a button you'll provide, the values in these text boxes will be written to the Contacts table as a new record.
Start by adding a group box to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>grpNewRecord</code>
|-
| <code>Location</code>
| <code>16,192</code>
|-
| <code>Size</code>
| <code>264,64</code>
|-
| <code>Text</code>
| <code>New Contact</code>
|}
Next, add a new text box to the group box and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtNewContactName</code>
|-
| <code>Location</code>
| <code>8,24</code>
|-
| <code>Size</code>
| <code>112,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Add a second text box to the group box and set its properties as shown:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtNewState</code>
|-
| <code>Location</code>
| <code>126,24</code>
|-
| <code>Size</code>
| <code>80,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Finally, add a button to the group box and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnAddNew</code>
|-
| <code>Location</code>
| <code>214,24</code>
|-
| <code>Size</code>
| <code>40,23</code>
|-
| <code>Text</code>
| <code>Add</code>
|}
Double-click the Add button and add the following code to its Click event:
<pre>DataRow drNewRow = m_dtContacts.NewRow();
drNewRow["ContactName"] = txtNewContactName.Text;
drNewRow["State"] = txtNewState.Text;
m_dtContacts.Rows.Add(drNewRow);
m_daDataAdapter.Update(m_dtContacts);
m_rowPosition = m_dtContacts.Rows.Count-1;
this.ShowCurrentRecord();
</pre>
Notice that after the new record is added, the position is set to the last row and the ShowCurrentRecord() procedure is called. This causes the new record to appear in the text boxes you created earlier.
Deleting Records
To delete a record from a DataTable, you call the Delete() method on the DataRow to be deleted. Add a new button to your form (not to the group box) and set its properties as shown in the following table.
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnDelete</code>
|-
| <code>Location</code>
| <code>224,152</code>
|-
| <code>Size</code>
| <code>56,23</code>
|-
| <code>Text</code>
| <code>Delete</code>
|}
Double-click the Delete button and add the following code to its Click event:
<pre>if (m_dtContacts.Rows.Count !=0)
{
m_dtContacts.Rows[m_rowPosition].Delete();
m_daDataAdapter.Update(m_dtContacts);
m_rowPosition=0;
this.ShowCurrentRecord();
}
</pre>
Your form should now look like that in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig02 Figure 21.2].
<div style="text-align: center;">Figure 21.2. A basic data-entry form.
[[Image:21fig02.jpg|314px|graphics/21fig02.jpg]]
</div>
Running the Database Example
Press F5 to run the project. If you entered all the code correctly, and you placed the Contacts database into the C:\Temp folder (or modified the path used in code), the form should display without errors, and the first record in the database will appear. Click the navigation buttons to move forward and backward. Feel free to change the information of a contact, click the Save button, and your changes will be made to the underlying database. Next, enter your name and state into the New Contact section of the form and click Add. Your name will be added to the database and displayed in the appropriate text boxes.
Using the Data Form Wizard
Visual Basic .NET includes a tool to help introduce you to ADO.NET�the Data Form Wizard. In this section, you're going to use the Data Form Wizard to create a form that is bound to the same database you used in the previous example.
Start by creating a new Windows Application titled Data Form Example. The Data Form Wizard is run by adding it to your project as a form template. Choose Add Windows Form from the Project menu to display the Add New Item dialog box, click the Data Form Wizard icon, change the name to fclsDataForm.cs (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig03 Figure 21.3]), and click Open to start the wizard.
<div style="text-align: center;">
</div>
The first page of the wizard is simply an introduction. Click Next to get to the first "real" page. This next page is used to choose the dataset you want to bind to the form. ADO.NET datasets hold a collection of DataTables. Enter AllContacts into the text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig04 Figure 21.4]) and click Next to continue.
<div style="text-align: center;">
</div>
The next page of the wizard is used to specify a connection to a data source (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig05 Figure 21.5]). Note: Because you haven't previously defined a connection to the Contacts database, your drop-down list will be empty. Click the New Connection button to display the Data Link Properties dialog box. Notice that this dialog box opens with the Connection page visible. Click the Provider tab to see the list of installed providers on your computer (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig06 Figure 21.6]), choose Microsoft Jet 4.0 OLE DB Provider to select it, and then click the Connection tab once more.
<div style="text-align: center;">
</div>
<div style="text-align: center;">
</div>
Now that you've selected the provider, you need to locate and select the data source (your Jet database). Click the build button next to the database name text box, and then locate and select the contacts.mdb database. Next, click Test Connection to make sure the information you have supplied creates a valid connection to the database. If the test succeeded, click OK to close the Data Link Properties dialog box. The database should now appear in the Connection drop-down list. Click Next to continue.
The next step in completing the wizard is to choose the table or tables you want to use (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig07 Figure 21.7]). The tables you choose here will be used to supply the data that is bound to your form. Double-click the Contacts table to add it to the Selected Items list and click Next to continue.
<div style="text-align: center;">
</div>
This page shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig08 Figure 21.8] is used to specify the columns that you want bound on the form. The two columns in your Contacts table are already selected by default, so click Next to continue.
<div style="text-align: center;">
</div>
The last step of the wizard is specifying the style in which you want the data to appear (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig09 Figure 21.9]). Because the previous example had you add individual controls for each column, leave the All Records in a Grid radio button, selected (this will create a data grid). Click Finish to create your new data form, which will appear in the form designer (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig10 Figure 21.10]).
<div style="text-align: center;">Figure 21.9. The Data Form Wizard gives you a number of choices for displaying your data.
[[Image:21fig09.jpg|500px|graphics/21fig09.jpg]]
</div>
<div style="text-align: center;">Figure 21.10. This bound grid was created by the Data Form Wizard.
[[Image:21fig10.jpg|414px|graphics/21fig10.jpg]]
</div>
To test your form, you'll have to display it. Click Form1.cs to display the designer for the default form in your project and add a new button to the form. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowDataForm</code>
|-
| <code>Location</code>
| <code>96,120</code>
|-
| <code>Size</code>
| <code>104,23</code>
|-
| <code>Text</code>
| <code>Show Data Form</code>
|}
Next, double-click the button to access its Click event and add the following code:
<pre>fclsDataForm objDataForm = new fclsDataForm ();
objDataForm.Show();
</pre>
Press F5 to run the project, and then click the button and your bound form will appear. To load the grid with records, click the Load button (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#ch21fig11 Figure 21.11]).
Stop the running project, click fclsDataForm.cs in the Solution Explorer, and then click the View Code button on the Solution Explorer to view the class. Notice that the Data Form Wizard created all the ADO.NET code for you, and even included rudimentary error handling.
The Data Form Wizard is a great way to get started with ADO.NET, but it will take you only so far. To create robust ADO.NET applications, you will need to find one or more dedicated resources that focus on the intricacies of ADO.NET.
Summary
Most commercial applications use some sort of database. Becoming a good database programmer requires extending your skills beyond being just a good programmer. There is so much to know about optimizing database and database code, creating usable database interfaces, creating a database scheme�the list goes on. However, writing any database application begins with the basic skills you learned in this hour. You learned how to connect to a database, create and populate a DataTable, and navigate the records in the DataTable. In addition, you learned how to edit records and how to add and delete records. Finally, you learned how to use the Data Form Wizard to create a basic ADO.NET bound form. You are now prepared to write simple, yet functional, database applications.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#qad1e65222 Q1:]'''
| If I want to connect to a data source other than Jet, how do I know what connect string to use?
|-
| align="right" | ''' A1: '''
| Not only is different connection information available for different types of data sources, but also for different versions of different data sources. The best way of determining the connection string is to consult the documentation for the data source to which you want to attach.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/21.htm#qad1e65235 Q2:]'''
| What if I don't know where the database will be at runtime?
|-
| align="right" | ''' A2: '''
| For file-based data sources such as Jet, you can add an Open File dialog control to the form and let the user browse and select the database. Then, concatenate the file with the rest of the connection information (such as the provider string).
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans01 1:]'''
| What is the name of the data access components used in the .NET Framework?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans02 2:]'''
| What is the name given to a collection of DataRows?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans03 3:]'''
| How do I get data into and out of a DataTable?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans04 4:]'''
| What object is used to connect to a data source?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans05 5:]'''
| What argument of a connection string contains information about the type of data being connected to?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans06 6:]'''
| The functionality of a DataTable (read-only, updateable, and so forth) is determined by what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans07 7:]'''
| What are the two .NET data providers supplied as part of the .NET Framework?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec21.htm#ch21ans08 8:]'''
| What method of a DataTable object do you call to create a new row?
|}
Exercises
# Create a new project that connects to the same database used in this example. Rather than displaying a single record in two text boxes, put a list box on the form and fill the list box with the names of the people in the database.
# Further extend the project you built in exercise 1 by adding a Name text box below the list. When the user clicks a name in the list, show the name in the text box. If the user clicks another name, update the database with any changes made in the text box to the previously selected name.
esc55sycnod2l9a39yeub7cg8bjpjll
User:Foxall/09
2
2144
39245
20213
2026-04-13T06:03:32Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39245
wikitext
text/x-wiki
== Hour 9. Adding Menus and Toolbars to Forms ==
The use of a Graphical User Interface (GUI) for interacting with and navigating programs is one of the greatest features of Windows. In spite of this, a fair number of Windows users still rely primarily on the keyboard, preferring to use a mouse only when absolutely necessary. Data-entry people in particular never take their hands off the keyboard. Many software companies receive support calls from angry customers because a commonly used function is accessible only by using a mouse. Menus are the easiest way for a user who relies on the keyboard to navigate your program. Visual Studio and C# make it easier than ever to create menus for your applications. In this hour, you'll learn how to build, manipulate, and program menus on a form. In addition, I'll teach you how to use the Toolbar control to create attractive and functional toolbars. Finally, you'll learn how to "finish off" a form with a status bar.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec1.htm#ch09lev2sec1 Adding, moving, and deleting menu items]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec1.htm#ch09lev2sec3 Creating checked menu items]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec2.htm#ch09lev1sec2 Programming menus]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec2.htm#ch09lev2sec4 Implementing context menus]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec2.htm#ch09lev2sec5 Assigning shortcut keys]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec3.htm#ch09lev1sec3 Creating toolbar items]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec3.htm#ch09lev2sec8 Defining toggle buttons and separators]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch09lev1sec4.htm#ch09lev1sec4 Creating a status bar]
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Building Menus
When I said that C# makes building menus easier than ever, I wasn't kidding. Building menus is now an immediately gratifying process. I can't stress enough how important it is to have good menus, and now that it's so easy to do, there is no excuse for not putting menus in an application.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| When running an application for the first time, users often scan the menus before opening a manual. (Most users never open the manual!) When you provide comprehensive menus, you make your program easier to learn and use.
|}
Adding Menu Items
Adding menus to a form is accomplished by way of a control: the Main Menu control. The Main Menu control is a bit odd in that it's the only control I know of that sits at the bottom of the form in the space reserved for controls without an interface (like a Timer control), yet actually has a visible interface on the form. Start by creating a new Windows Application project named Menus and More.
# Change the name of the default form to fclsMenusAndMore, set its Text to Menus and More, and change the Main entry point of the project to reference fclsMenusAndMore instead of Form1.
# Next, add a new Main Menu control to your form by double-clicking the MainMenu item in the toolbox. As you can see, the control is added to the pane at the bottom of the form designer. Take a look at the top of the form�you'll see the text Type Here (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig01 Figure 9.1]).
<div style="text-align: center;">Figure 9.1. A menu has no items when first added to a form.
[[Image:09fig01.jpg|500px|graphics/09fig01.jpg]]
</div>
# Click this text and type &File. As you begin typing, C# displays two new boxes that say Type Here (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig02 Figure 9.2]).
<div style="text-align: center;">Figure 9.2. Creating a menu item automatically prepares the control for more items.
[[Image:09fig02.jpg|500px|graphics/09fig02.jpg]]
</div>
Notice the Properties window (if it's not visible, press F4 to show it). The text you just entered created a new menu item. Each menu item is an object; therefore, the item has properties. (You may have to press Tab to commit your entry and then click the text you typed once more to see its properties.)MenuItem1 isn't very descriptive, so change the name of the item to mnuFileMenu.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| You may have been wondering why I had you enter the ampersand (&) in front of the word File. Take a look at your menu now, and you'll see that C# doesn't display the ampersand; instead, it displays the text with the F underlined, as in File. The ampersand, when used in the Text property of a menu item, tells C# to underline the character immediately following it. For top-level menu items, such as the File item you just created, this underlined character is known as an accelerator key. Pressing Alt+ an accelerator key opens the menu as if the user had clicked it. You should avoid assigning the same accelerator key to more than one top-level menu item on a given menu. When the menu item appears on a drop-down menu, in contrast to being a top-level item, the underlined character is called a hotkey. When a menu is visible (open), the user can press a hotkey to trigger the corresponding menu item the same as if it was clicked. Again, don't use the same hotkey for more than one item on the same menu.
|}
# Click the Type Here text that appears to the immediate right of the File item and enter the text &Help. C# gives you two more Type Here items, the same as when you entered the File item. Adding new menu items is a matter of clicking a Type Here box and entering the text for an item.
# Press Tab to commit your entry and then click the text you typed once more to select it. Change the name of your new menu item in the Properties window to mnuHelpMenu.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you click a Type Here box below an existing menu item, you'll add a new item to the same menu as the item above the box. If you click the Type Here box to the right of a menu item, you'll create a submenu using the menu to the left of the box as the entry point for the submenu. As you've already seen, clicking the Type Here box along the top of the menu bar creates a top-level menu.
|}
# Click once more on the File item to display a Type Here box below the item. Click this box and enter the text &Quit.
# Press Tab to commit your entry and then click the new item once more to select it. Change the name of the new item to mnuQuit. Now is a good time to save your work, so click Save All on the toolbar.
Moving and Deleting Menu Items
Deleting and moving menu items are even easier processes than adding new items. To delete a menu item, right-click it and choose Delete from the context menu that appears. To move an item, drag it from its current location and drop it in the location in which you want it placed.
Creating Checked Menu Items
A menu item that isn't used to open a submenu can display a check mark next to its text. Check marks are used to create menu items that have state�the item is either selected or it is not selected. You're now going to create a checked menu item. Click the Type Here box below the Quit menu item and enter Ask before closing and then change the name of this new item (remember to press Tab to commit your entry and then click the item again to select it) to mnuAskBeforeClosing. Next, change the Checked property of the new item to true. Notice that the menu item now has a check mark next to it (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig03 Figure 9.3]).
<div style="text-align: center;">Figure 9.3. Menu items can be used to indicate state.
[[Image:09fig03.jpg|500px|graphics/09fig03.jpg]]
</div>
Press F5 to run the project. The menu will appear on your form, just as you designed it (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig04 Figure 9.4]). Click the File menu to open it and then click Quit; nothing happens. In the next section, I'll show you how to add code to menu items to make them actually do something. Stop the project before continuing.
Programming Menus
As I've said before, every menu item is a unique object�this is why you were able to change the name for each item you created. Although individual menu items aren't controls, per se, adding code behind them is very similar to adding code behind a control. You're now going to add code to the Quit and Ask Before Closing menu items.
# Click the File menu now to open it.
# Double-click the Quit menu item. Just as when you double-click a control, C# displays the code editor with the default event for the menu item you've clicked. For menu items, this is the Click event.
# Enter the following code:
<pre>this.Close();
</pre>
As you know by now, this code closes the current form, which has the effect of stopping the project because this is the only form and it's designated as the Main entry point object.
# Switch back to the form designer (click the Form1.cs [Design] tab).
You're now going to create the code for the Ask Before Closing button. This code will invert the Checked property of the menu item; if <code>Checked = True</code>, it will be set to false and vice versa.
# Double-click the Ask Before Closing item to access its Click event and enter the following code:
<pre>mnuAskBeforeClosing.Checked = (!mnuAskBeforeClosing.Checked);
</pre>
The logical negation operator (<code>!</code>) is used to perform a negation of a Boolean value. Don't worry, I discuss this in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13.htm#ch13 Hour 13], "Performing Arithmetic, String Manipulation, and Date/Time Adjustments." For now, realize that if the current value of the Checked property is true, <code>(!Checked)</code> returns false. If Checked is currently false, <code>(!Checked)</code> returns true. Therefore, the checked value will toggle between true and false each time the menu item is clicked.
# Press F5 to run the project. Open the File menu by pressing Alt+F (remember, the F is the accelerator key).
# Next, click the Ask Before Closing button�it becomes unchecked. Click the menu item once more and it becomes checked again.
# Click it a third time to remove the check mark, and then click Quit to close the form.
Did you notice that you weren't asked whether you really wanted to quit? This is because the quit code hasn't been written to consider the checked state of the Ask Before Closing button.
# Return to the Click event of the Quit button and change its code to look like this:
<pre>if (mnuAskBeforeClosing.Checked)
{
if (MessageBox.Show("Do you really wish to exit?","Quit
Verification",MessageBoxButtons.YesNo) == DialogResult.No)
return;
}
this.Close();
</pre>
Now when the user selects the Quit button, C# considers the checked state of the Ask Before Closing menu item. If the item is checked, C# asks users whether they really want to exit. If a user chooses No, the procedure quits and the form doesn't unload. This code may be a bit foreign to you now, but you'll learn the ins and outs of making decisions (executing code based on conditions) and message boxes in later hours.
# Press F5 to run the project. Open the File menu, click the Ask Before Closing item to select it, and then click Quit.
# This time, C# asks you to confirm your intentions rather than immediately closing the form. Go ahead and close the form, and then click Save All on the toolbar to save your work.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| When designing your menus, look at some of the many popular Windows applications available and consider the similarities and differences between their menus and yours. Although your application may be quite unique and therefore may have very different menus from other applications, similarities probably exist as well. When possible, make menu items in your application follow the same structure and design as similar items in the popular programs. This will shorten the learning curve of your application, reduce user frustration, and save you time.
|}
Implementing Context Menus
Context menus are the pop-up menus that appear when you right-click an object on a form. Context menus get their name from the fact that they display context-sensitive choices�menu items that relate directly to the object that's right-clicked. Most C# controls have a default context menu, but you can assign custom context menus if you desire. Add a new text box to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtMyTextbox</code>
|-
| <code>Location</code>
| <code>96,122</code>
|-
| <code>Size</code>
| <code>100,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Press F5 to run the project, and then right-click the text box to display its context menu (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig05 Figure 9.5]). This menu is the default context menu for the <code>Text Box</code> control; it is functional but limited. Stop the project now and return to Design view.
<div style="text-align: center;">Figure 9.5. Most items have a default context menu.
[[Image:09fig05.jpg|300px|graphics/09fig05.jpg]]
</div>
Creating context menus is very much like creating regular menus. Context menus, however, are created using a different control: the Context Menu control.
# Add a new context menu to the form by double-clicking the ContextMenu item in the toolbox. Like the Main Menu control, the Context Menu control is placed in the pane below the form designer. When the control is selected, a Context Menu item appears at the top of the form.
# Clicking the Context Menu box opens the context menu, which is empty by default. Click the Type Here box and enter the text Clear text box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig06 Figure 9.6]). You've just created a context menu with a single menu item.
<div style="text-align: center;">Figure 9.6. Context menus are edited much like regular menus.
[[Image:09fig06.jpg|500px|graphics/09fig06.jpg]]
</div>
# Change the name of the new menu item to mnuClearTextbox, and then double-click the item to access its Click event.
Enter the following code:
<pre>txtMyTextbox.Text = "";
</pre>
# Linking a control to a context menu is accomplished by setting a property. Display the form designer once more, and then click the Text Box control to select it and display its properties in the Properties window.
# Change the ContextMenu property of the text box to ContextMenu1; the context menu is now linked to the text box. Press F5 to run the project.
# Enter some text into the text box and then right-click the text box; your custom context menu appears in place of the default context menu.
# Choose Clear Text Box from the context menu, and the contents of the text box will clear. Stop the project and save your work.
Assigning Shortcut Keys
If you've spent any time learning a Microsoft application, you've most likely learned some keyboard shortcuts. For instance, pressing Alt+P in any application that prints has the same effect as opening the File menu and choosing Print. You can add the same type of shortcuts to your menus by following these steps:
# Click the Main Menu control at the bottom of the form designer, click File on its menu, and then click Quit to select the Quit menu item.
# Next, click the Shortcut property in the Properties window and then click the down arrow that appears. This list contains all the shortcut keys that can be assigned to a menu item.
# Locate and select CtrlQ (for Quit) in the list (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig07 Figure 9.7]).
<div style="text-align: center;">Figure 9.7. A shortcut key is assigned using the shortcut property of a menu item.
[[Image:09fig07.jpg|193px|graphics/09fig07.jpg]]
</div>
# Press F5 to run the project once more. Next, press Ctrl+Q, and the application will behave just as though you opened the File menu and clicked the Quit item.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Although it's not always possible, try to assign logical shortcut key combinations. The meaning of F6 is hardly intuitive, for example, but when assigning modifiers such as Ctrl with another character, you have some flexibility. For instance, the key combination of Ctrl+Q might be a more intuitive shortcut key for Quit than Ctrl+T.
|}
Using the Toolbar Control
Generally speaking, when a program has a menu (as most programs should), it should also have a toolbar. Toolbars are one of the easiest ways for a user to access program functions. Unlike menu items, toolbar items are always visible and therefore are immediately available. In addition, toolbar items have ToolTips, which allow a user to discover a toolbar button's purpose simply by hovering the pointer over the button.
Toolbar items are really shortcuts for menu items; every item on a toolbar should have a corresponding menu item. Remember that some users prefer to use the keyboard, in which case they need to have keyboard access to functions via menus.
The actual items you place on a toolbar depend on the features supported by the application. However, the mechanics of creating toolbars and toolbar items is the same, regardless of the buttons you choose to use. Toolbars are created using the Toolbar control.
# Add a new Toolbar control to your form now by double-clicking the ToolBar item in the toolbox. A new toolbar is then added to the top of your form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig08 Figure 9.8]). Change the name of the toolbar to tbrMainToolbar.
<div style="text-align: center;">
</div>
Every toolbar you've used displays pictures on buttons. The Toolbar control gets the pictures for its buttons from an Image List control.
# Go ahead and add an Image List control to the form now and change its name to imgMyPictures.
# Add a new 16x16 pixel bitmap to the Images collection of the Image List control (you can use a picture you created or use one from the samples I've made available on the Web site).
# When you're finished adding the new button, close the Image Collection Editor and select the Toolbar control on the form.
# Set the ImageList property of the toolbar to use the image list you've just created.
Adding Toolbar Buttons Using the Buttons Collection
Like many other controls you've already learned about, the Toolbar control supports a special collection: the Buttons collection. The Buttons collection contains the buttons that appear on the toolbar. Click the Buttons property in the Properties window and then click the small button that appears; the ToolBarButton Collection Editor displays. The list of button members is empty because new toolbars have no buttons. Click Add to create a new button, and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>tbbQuit</code>
|-
| <code>ImageIndex</code>
| <code>0</code>
|-
| <code>Text</code>
| <code>Quit</code>
|-
| <code>ToolTipText</code>
| <code>Quit this application</code>
|}
Click OK to close the ToolBarButton Collection Editor. Your new button is now visible on the toolbar. As you can see, text appears below the picture in the button, but this is not how most toolbars appear. Not a problem�access the Buttons collection once more and clear the Text property of the button.
Programming Toolbars
Unlike menus, where each menu item receives its own Click event, the Toolbar control has one common Click event that fires when the user clicks any button on the toolbar. Double-click the Toolbar control on the form to access the toolbar's ButtonClick event (close the button editor first if it's open). Enter the following code:
<pre>if (e.Button == tbbQuit)
this.Close();
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In a nontrivial program, the ideal way to set this up would be to create a method that is called both by the Click event of the menu item and by clicking the equivalent toolbar button. This reduces duplication of code and eliminates bugs (the Quit button doesn't honor the Ask Before Closing option in this example, even though the menu item does).
|}
The e object is discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods." For now, realize that the Button property of the e object is an object property that holds a reference to the button that is clicked. This code uses an if statement to determine if the clicked button is the Quit button. If the Quit button was clicked, the form closes. When you have many buttons on a toolbar, a switch statement is much more useful than an if statement, as you'll see in the next section. (Decision-making constructs such as if and switch statements are discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14.htm#ch14 Hour 14], "Making Decisions in C# Code.")
Creating Toggle Buttons
The button that you've created for your toolbar is a standard push-style button. When the user clicks it with the mouse, the button will appear to be pressed while the user holds down the mouse button and will return to a normal state when the user releases the mouse button. Although this is the style you'll use for most of your toolbar buttons, the Toolbar control supports other styles as well. One such style is the toggle button. A toggle button, much like the check mark of a menu item, is used to denote state. When a toggle button is clicked, it appears in a pressed state and stays that way until clicked again, in which case it returns to its normal appearance. Microsoft Word has a number of such buttons. For instance, the paragraph alignment buttons are all toggle buttons�the button that corresponds to the current paragraph's alignment appears to be pressed.
Add a new button to your toolbar now and change its name to tbbInvisible. Change its Text property to Invisible and its Style to ToggleButton. Click OK to close the editor and the new button will appear on the toolbar. Take note that you didn't have to designate a picture for the toolbar item (but you usually should). Because you don't want the toolbar's height to be larger than necessary, change the TextAlign property of the Toolbar control to Right. Your toolbar should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig09 Figure 9.9].
<div style="text-align: center;">
</div>
Again, double-click the toolbar to access its ButtonClick event. Now that there are two buttons, the simple if statement is no longer suited to determining the button pushed. Change the code in your procedure to match the following:
<pre>switch (tbrMainToolbar.Buttons.IndexOf(e.Button))
{
case 0:
this.Close();
break;
case 1:
txtMyTextbox.Visible = (!tbbInvisible.Pushed);
break;
}
</pre>
This code is a bit more complex than the previous code. The switch construct compares one value to many possible values, looking for a match. In this case, the <code>IndexOf()</code> method of the Buttons collection is used to determine the index of the clicked tool button (the first button is 0, the second is 1, and so forth). The index is then compared to values using the case statements, and when a match is found, the appropriate code executes. Again, don't worry too much about the details of the switch statement, because you'll learn everything you need to know about it in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14.htm#ch14 Hour 14], "Making Decisions in C# Code." The new statement that you're interested in at the moment is where the Visible property of the text box is set. Remember, the logical negation operator (<code>!</code>) negates a value. Therefore, this statement sets the Visible property of the text box to the negation of the pushed state of the tbbInvisible button. In other words, when the button is pushed, the text box is hidden, and when the button is not pushed, the text box is visible.
Press F5 to run the project now and notice that the text box is visible. Click the Invisible button on the toolbar and note that its appearance changes to a pushed state and the text box becomes hidden (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig10 Figure 9.10]). Click the button again to return the button's state to normal, and the text box reappears. When you're finished, stop the project and save your work.
<div style="text-align: center;">Figure 9.10. Toggle-style buttons appear "pressed" when clicked.
[[Image:09fig10.jpg|300px|graphics/09fig10.jpg]]
</div>
Creating Separators
As you add more and more buttons to a toolbar, it becomes evident that you need a way to logically group buttons. Placing related buttons next to one another is a great start toward building a good toolbar. However, a toolbar may be a bit difficult to use even if its buttons are placed in a logical order, unless the buttons are separated into groups. Placing a space between sets of related buttons creates button groups. You're now going to add a separator space to your toolbar.
Add a new button to your toolbar using the Buttons collection in the Properties window. Change its name to tbbSeparator1 and change its Style to Separator. When you change the Style property of the button to Separator, it disappears from the toolbar, or at least it seems to. When a button is designated as a separator, it's simply an empty placeholder used to create a space between two buttons. Because this separator is at the end row of buttons, you can't see it. Move it to the second position by selecting it in the ToolBarButton Collection Editor and clicking the up arrow that appears to the right of the Members list; this arrow and the one below it are used to move a button up or down in the list. Click OK to save your changes and your toolbar will now have a space between the two buttons (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig11 Figure 9.11]).
<div style="text-align: center;">Figure 9.11. Separators are used to create spaces between groups of buttons.
[[Image:09fig11.jpg|500px|graphics/09fig11.jpg]]
</div>
Press F5 to run the project once more and click the Invisible button; the text box no longer becomes hidden. This is a common problem when working with toolbars. Remember how the switch statement looks at the index of the clicked button? The index is the ordinal position of a button in the Buttons collection. When you changed the order of the buttons by moving the separator button up in the list, you changed the index of the separator button and the button it displaced�the tbbInvisible button. The tbbInvisible button now has an index of two (because it's the third button). Change the case statement in the ButtonClick event that compares the case to 1 so that it compares it to 2, and your code will work again. As you fine-tune your toolbars, you need to be conscious of any code that's been written to work with the indexes of buttons in the Buttons collection.
Creating Drop-Down Menus for Toolbar Buttons
You need to be familiar with one last type of toolbar button. Create a new button using the Buttons collection in the Properties window. Change the name of the new button to tbbDropdown, clear the Text property, and set the button's Style property to DropDownButton. Finally, set the DropDownMenu property to ContextMenu1 and click OK to commit your changes. Notice how the button has a drop-down arrow on it. Press F5 to run the project and click the drop-down arrow; the menu that you designated in the DropDownMenu property appears (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig12 Figure 9.12]). As you can see, the DropDownMenu property makes it easy to integrate drop-down menus with your toolbars.
<div style="text-align: center;">
</div>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating a Status Bar
The last control I'm going to show you is the Status Bar control. The status bar isn't nearly as fancy, or even as useful, as other controls, such as the Toolbar or the Main Menu. It's also not that hard to work with. Nevertheless, a status bar adds value to an application in that it makes additional information available, and users have come to expect it. In its simplest form, a status bar displays a text caption and sizing grip�the three diagonal lines to the right of the control that the user can drag with the mouse to change the size of the form.
Add a new status bar to the form now by double-clicking the StatusBar item in the toolbox. Change the name of the status bar to sbrMyStatusBar. The Text property determines the text displayed in the left side of the status bar. Notice that the Text is set to the default name of the control. Change the Text property to Menus and Toolbars Example now, and notice how the text in the status bar changes (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig13 Figure 9.13]).
<div style="text-align: center;">Figure 9.13. Status bars dress out a form.
[[Image:09fig13.jpg|500px|graphics/09fig13.jpg]]
</div>
If a form's border is sizable, the user can click and drag the sizing grip at the right side of the status bar to change the size of the form. The status bar isn't smart enough to realize when a form's border can't be resized; you'll have to change the SizingGrip property of the status bar to false to hide the grip.
The default behavior of the status bar is quite simple, consisting of text and a sizing grip. However, you can create more complex status bars with this control. The Status Bar control contains a Panels collection. To see how a panel works, select the Panels property in the Properties window and click the small button that appears. On the StatusBarPanel Collection Editor, click Add to create a new panel. Set the Text of the panel to Panel Text, set the AutoSize property to Contents, and click OK to save your changes. Nothing looks different, right? This is because one last thing is required to display the status bar panels. Change the ShowPanels property of the status bar to true now, and the status bar will display its panel (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#ch09fig14 Figure 9.14]). You can add multiple panels to a Status Bar control and even tailor the appearance of each panel by changing the border style or displaying an image from a linked Image List control. The status bar is such a simple control that you may overlook using it. However, I encourage you to use it when appropriate.
Summary
Menus, toolbars, and status bars add tremendous value to an application by greatly enhancing its usability. In this hour, you learned how to use the Main Menu control to build comprehensive menus for your applications. You learned how to add, move, and delete menu items and how to define accelerator and shortcut keys to facilitate better navigation via the keyboard. You also saw how toolbars provide shortcuts for accessing common menu items. You learned how to use the Toolbar control to create functional toolbars complete with bitmaps, drop-downs, and logical groupings. Finally, you discovered how to use the status bar to "dress out" the application. Implementing these items is an important part of the interface design process for an application, and you now have the skills necessary to start putting them into your own programs.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#qad1e31135 Q1:]'''
| I have a number of forms with nearly identical menus. Do I really need to take the time to create menus for all these forms?
|-
| align="right" | ''' A1: '''
| Not as much as you think. Create a Main Menu control that has the common items on it, and then copy and paste the control to other forms. You can then build on this menu structure, saving you a lot of time.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/09.htm#qad1e31145 Q2:]'''
| I've seen applications that allow the end user to customize the menus and toolbars. Can I do that with the C# menus and toolbars?
|-
| align="right" | ''' A2: '''
| No. To accomplish this behavior, you would have to purchase a third-party component.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A] Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans01 1:]'''
| True or False: Form menu bars are created using the Context Menu control.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans02 2:]'''
| To create an accelerator or hotkey, preface the character with a(n):
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans03 3:]'''
| If you've designed a menu using a Main Menu control, but that menu isn't visible on the form designer, how do you make it appear?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans04 4:]'''
| To place a check mark next to a menu item, you set what property of the item?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans05 5:]'''
| How do you add code to a menu item?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans06 6:]'''
| Toolbar items are part of what collection?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans07 7:]'''
| To create a separator on a toolbar, you create a new button and set what property?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans08 8:]'''
| True or False: Every button on a toolbar has its own Click event.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec9.htm#ch09ans09 9:]'''
| What must you do to have panels appear on a status bar?
|}
Exercises
# Modify the code you created for the toolbar that closes the form to take into consideration the checked status of the Ask Before Closing menu item.
# Implement a toggle button that works just like the Ask Before Closing menu item.
a8rdluogqwalauvhnxuuc2whyqmw0hg
User:Foxall/10
2
2145
39247
5606
2026-04-13T06:03:33Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39247
wikitext
text/x-wiki
== Hour 10. Drawing and Printing ==
C# provides an amazingly powerful array of drawing capabilities. However, this power comes at the price of a steep learning curve. Drawing isn't intuitive; you can't sit down for a few minutes with the online Help text and start drawing graphics. After you learn the basic principles involved, however, you'll find that drawing isn't that complicated. In this hour, you'll learn the basic skills for drawing shapes and text to a form or other graphical surface. You'll learn about pens, colors, and brushes. In addition, you'll learn how to persist graphics on a form�and even how to create bitmaps that exist solely in memory.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec1.htm#ch10lev1sec1 Understanding the Graphics object]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec2.htm#ch10lev1sec2 Working with pens]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec3.htm#ch10lev1sec3 Using system colors]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec4.htm#ch10lev1sec4 Working with rectangles]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec5.htm#ch10lev1sec5 Drawing shapes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec6.htm#ch10lev1sec6 Drawing text]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec7.htm#ch10lev1sec7 Persisting graphics on a form]
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Understanding the Graphics Object
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The code within the Windows operating system that handles drawing everything to the screen, including text, lines, and shapes, is called the Graphics Device Interface (GDI). The GDI processes all drawing instructions from applications as well as from Windows itself and generates the proper output for the current display. Because the GDI generates what you see onscreen, it has the responsibility of dealing with the particular display driver installed on the computer and the settings of the driver, such as resolution and color depth. This means that applications don't have to worry about these details; you write code that tells the GDI what to output and the GDI does whatever is necessary to produce that output. This behavior is called device independence because applications can instruct the GDI to display text and graphics using code that is independent of the particular display device.
|}
C# code communicates with the GDI primarily via a Graphics object. The basic process is the following:
* An object variable is created to hold a reference to a Graphics object.
* The object variable is set to a valid Graphics object (new or existing).
* To draw or print, you call methods of the Graphics object.
Creating a Graphics Object for a Form or Control
If you want to draw directly to a form or control, you can easily get a reference to the drawing surface by calling the CreateGraphics() method of the object in question. For example, to create a Graphics object that draws to a text box, you could use code such as:
<pre>System.Drawing.Graphics objGraphics;
objGraphics = this.textBox1.CreateGraphics();
</pre>
When you call CreateGraphics(), you're setting the object variable to hold a reference to the Graphics object of the form or control's client area. The client area of a form is the gray area within the borders and title bar of the form. The client area of a control is usually the entire control. All drawing and printing done using the Graphics object is sent to the client area. In the code shown previously, the Graphics object references the client area of a text box, so all drawing methods called on the Graphics object would draw on the text box only.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| When you draw directly to a form or control, the object in question doesn't persist what is drawn on it. If the form is obscured in any way, such as by a window covering it or by minimizing the form, the next time the form is painted, it won't contain anything that was drawn on it. Later in this hour, I'll teach you how to persist graphics on a form.
|}
Creating a Graphics Object for a New Bitmap
You don't have to set a Graphics object to the client area of a form or control; you can also set a Graphics object to a bitmap that exists only in memory. For performance reasons, you might want to use a memory bitmap to store temporary images or to use as a place to build complex graphics before sending them to a visible element. To do this, you first have to create a new bitmap. To create a new bitmap, you declare a variable to hold a reference to the new bitmap, and then you create a new bitmap using the following syntax:
<pre>Bitmap variable = new Bitmap(width, height, pixelformat);
</pre>
The width and height arguments are exactly what they appear to be: the width and height of the new bitmap. The pixelformat argument, however, is less intuitive. This argument determines the color depth of the bitmap and may also specify whether the bitmap has an alpha layer (used for transparent portions of bitmaps). [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10table01 Table 10.1] lists a few of the common values for PixelFormat (see C#'s online Help for the complete list of values and their meanings). Note that the pixelformat parameter is referenced as <code>System.Drawing.Imaging.PixelFormat</code>.<code>formatenumeration</code>.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 10.1. Common Values for PixelFormat
|-
| Value
| Description
|-
| <code>Format16bppGrayScale</code>
| The pixel format is 16 bits per pixel. The color information specifies 65,536 shades of gray.
|-
| <code>Format16bppRgb555</code>
| The pixel format is 16 bits per pixel. The color information specifies 32,768 shades of color, of which 5 bits are red, 5 bits are green, and 5 bits are blue.
|-
| <code>Format24bppRgb</code>
| The pixel format is 24 bits per pixel. The color information specifies 16,777,216 shades of color, of which 8 bits are red, 8 bits are green, and 8 bits are blue.
|}
For example, to create a new bitmap that is 640 pixels wide by 480 pixels tall and has a pixel depth of 24 bits, you could use the following statement:
<pre>objMyBitMap = new Bitmap(640, 480,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
</pre>
After the bitmap is created, you can create a Graphics object that references the bitmap using the FromImage() method, like this:
<pre>objGraphics = Graphics.FromImage(objMyBitMap);
</pre>
Now, any drawing or printing done using objGraphics would be performed on the memory bitmap. For the user to see the bitmap, you'd have to send the bitmap to a form or control. You'll do this in the section "[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch10lev1sec7.htm#ch10lev1sec7 Persisting Graphics on a Form]."
Disposing of an Object
When you're finished with a Graphics object, you should call its Dispose() method to ensure that all resources used by the Graphics object are freed. Simply letting an object variable go out of scope doesn't ensure that the resources used by the object are freed. Graphics objects can use considerable resources, so you should always call Dispose() when you're finished with any graphics object (including Pens and other types of objects).
C# also supports a way of automatically disposing object resources. This can be accomplished utilizing C#'s <code>using</code> statement. The <code>using</code> statement wraps a declared object or objects in a block and disposes of those objects after the block is done. As a result, after the code is executed in a block, the block is exited and the resources are disposed of on exit. Following is the syntax for the <code>using</code> statement and a small sample:
<pre>using (expression | type identifier = initializer)
{
// Statements to execute
}
using (MyClass objClass = new MyClass())
{
objClass.Method1();
objClass.Method2();
}
</pre>
One thing to keep in mind is that the using statement acts as a wrapper for an object within a specified block of code; therefore, it is only useful for declaring objects that are used and scoped within a method (scope is discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays").
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Working with Pens
A pen is an object that defines line-drawing characteristics. Pens are used to define color, line width, and line style (solid, dashed, and so on), and pens are used with almost all the drawing methods you'll learn about in this hour.
C# supplies a number of predefined pens, and you can also create your own. To create your own pen, use the following syntax:
<pre>Pen variable = new Pen(color, width);
</pre>
After a pen is created, you can set its properties to adjust its appearance. For example, all Pen objects have a DashStyle property that determines the appearance of lines drawn with the pen. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10table02 Table 10.2] lists the possible values for DashStyle.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 10.2. Possible Values for DashStyle
|-
| valign="middle" | Value
| valign="middle" | Description
|-
| <code>Dash</code>
| Specifies a line consisting of dashes.
|-
| <code>DashDot</code>
| Specifies a line consisting of a pattern of dashes and dots.
|-
| <code>DashDotDot</code>
| Specifies a line consisting of alternating dashes and double dots.
|-
| <code>Dot</code>
| Specifies a line consisting of dots.
|-
| <code>Solid</code>
| Specifies a solid line.
|-
| <code>Custom</code>
| Specifies a custom dash style. The Pen object contains properties that can be used to define the custom line.
|}
The enumeration for DashStyle is part of the Drawing.Drawing2D object. Therefore, to create a new pen and use it to draw an ellipse, for example, you could use the following code:
<pre>Pen objMyPen = new Pen(System.Drawing.Color.DarkBlue, 3);
objMyPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
</pre>
C# includes many standard pens, which are available via the System.Drawing.Pens class, as in the following:
<pre>objPen = System.Drawing.Pens.DarkBlue;
</pre>
When drawing using the techniques discussed shortly, you can use custom pens or system-defined pens�it's your choice.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using System Colors
At some point, you may have changed your Windows theme, or perhaps you changed the image or color of your desktop. What you may not be aware of is that Windows enables you to customize the colors of almost all Windows interface elements. The colors that Windows allows you to change are called system colors. To change your system colors, right-click the desktop and choose Properties from the shortcut menu to display the Display Properties dialog box, and then click the Appearance tab (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig01 Figure 10.1]). To change the color for a specific item, you can select the item from the Item drop-down list, or you can click the element in the top half of the tab.
<div style="text-align: center;">Figure 10.1. The Display Properties dialog box lets you select the colors of most Windows interface elements.
[[Image:10fig01.jpg|404px|graphics/10fig01.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| On Windows XP, you'll need to click Advanced on the Appearance tab to change your system colors.
|}
When you change a system color using the Display Properties dialog box, all loaded applications should change their appearance to match your selection. In addition, when you start any new applications, they should also match their appearance to your selection. If you had to write code to manage this behavior, you would have to write a lot of code, and you would be justified in avoiding the whole thing. However, making an application adjust its appearance to match the user's system color selections is actually quite trivial; therefore, there's no reason not to do it.
To designate that an interface color should stay in sync with a user's system colors, you assign a system color to a color property of the item in question (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig02 Figure 10.2]). [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10table03 Table 10.3] lists the system colors you can use. For example, if you wanted to ensure that the color of a button matches the user's corresponding system color, you would assign the system color named Control to the BackColor property of the Button control.
<div style="text-align: center;">Figure 10.2. System colors are assigned using the System palette tab.
[[Image:10fig02.gif|204px|graphics/10fig02.gof]]
</div>
Fortunately, when you create new forms and when you add controls to forms, C# automatically assigns the proper system color to the appropriate properties. Another good thing is that when a user changes a system color using the Display Properties dialog box, C# automatically updates the appearance of objects that use system colors; you don't have to write a single line of code to do this.
Be aware that you aren't limited to assigning system colors to their logically associated properties. You can assign system colors to any color property you want, and you can also use system colors when drawing. This allows you, for example, to draw custom interface elements that match the user's system colors. Be aware, however, that if you do draw with system colors, C# won't update the colors automatically when the user changes system colors; you would have to redraw the elements with the new system color.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Users don't just change their system colors for aesthetic purposes. I work with a programmer who is color blind. He's modified his system colors so that he can see things better on the screen. If you don't allow your applications to adjust to the color preferences of the user, you may make using your program unnecessarily difficult, or even impossible, for someone with color blindness.
|}
{| cellspacing="0" cellpadding="1" border="1"|+ Table 10.3. Properties of the SystemColors Class
|-
| valign="middle" | Enumeration
| valign="middle" | Description
|-
| <code>ActiveBorder</code>
| The color of the filled area of an active window border.
|-
| <code>ActiveCaption</code>
| The color of the background of an active caption bar (title bar).
|-
| <code>ActiveCaptionText</code>
| The color of the text of the active caption bar (title bar).
|-
| <code>AppWorkspace</code>
| The color of the application workspace. The application workspace is the area in a multiple-document view that is not being occupied by child windows.
|-
| <code>Control</code>
| The color of the background of push buttons and other 3D elements.
|-
| <code>ControlDark</code>
| The color of shadows on a 3D element.
|-
| <code>ControlDarkDark</code>
| The color of darkest shadows on a 3D element.
|-
| <code>ControlLight</code>
| The color of highlights on a 3D element.
|-
| <code>ControlLightLight</code>
| The color of lightest highlights on a 3D element.
|-
| <code>ControlText</code>
| The color of the text on buttons and other 3D elements.
|-
| <code>Desktop</code>
| The color of the Windows desktop.
|-
| <code>GrayText</code>
| The color of the text on a user-interface element when it's unavailable.
|-
| <code>Highlight</code>
| The color of the background of highlighted text. This includes selected menu items as well as selected text.
|-
| <code>HighlightText</code>
| The color of the foreground of highlighted text. This includes selected menu items as well as selected text.
|-
| <code>HotTrack</code>
| The color used to represent hot tracking.
|-
| <code>InactiveBorder</code>
| The color of an inactive window border.
|-
| <code>InactiveCaption</code>
| The color of the background of an inactive caption bar.
|-
| <code>InactiveCaptionText</code>
| The color of the text of an inactive caption bar.
|-
| <code>Info</code>
| The color of the background of the ToolTip.
|-
| <code>InfoText</code>
| The color of the text of the ToolTip.
|-
| <code>Menu</code>
| The color of the menu background.
|-
| <code>MenuText</code>
| The color of the menu text.
|-
| <code>ScrollBar</code>
| The color of the scrollbar background.
|-
| <code>Window</code>
| The color of the background in the client area of a window.
|-
| <code>WindowFrame</code>
| The color of the frame around a window.
|-
| <code>WindowText</code>
| The color of the text in the client area of a window.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" |
|}
Working with Rectangles
Before learning how to draw shapes, you need to understand the concept of a rectangle as it relates to C# programming. A rectangle isn't necessarily used to draw a rectangle (although it can be). Rather, a rectangle is a structure used to hold bounding coordinates used to draw a shape. Obviously, a square or rectangle can fit within a rectangle. However, so can circles and ellipses. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig03 Figure 10.3] illustrates how most shapes can be bound by a rectangle.
<div style="text-align: center;">Figure 10.3. Rectangles are used to define the bounds of most shapes.
[[Image:10fig03.gif|316px|graphics/10fig03.gof]]
</div>
To draw most shapes, you must have a rectangle. The rectangle you pass to a drawing method is used as a bounding rectangle; the proper shape (circle, ellipse, and so on) is always drawn. Creating a rectangle is easy. First, you set the dimensions of a variable as Rectangle and then you set the X, Y, Width, and Height properties of the object variable. The X, Y value is the coordinate of the upper-left corner of the rectangle. For example, the following code creates a rectangle that has its upper-left corner at coordinate 0,0, has a width of 100, and a height of 50:
<pre>Rectangle rectBounding = new Rectangle();
rectBounding.X = 0;
rectBounding.Y = 0;
rectBounding.Width = 100;
rectBounding.Height = 50;
</pre>
The Rectangle object enables you to send the X, Y, Height, and Width values as part of its initialize construct. Using this technique, you could create the same rectangle with only a single line of code:
<pre>Rectangle rectBounding = new Rectangle(0,0,100,50);
</pre>
You can do a number of things with a rectangle after it's defined. Perhaps the most useful is the capability to enlarge or shrink the rectangle with a single statement. You enlarge or shrink a rectangle using the Inflate() method. The most common syntax of Inflate() is the following:
<pre>object.Inflate(changeinwidth, changeinheight);
</pre>
When called this way, the rectangle width is enlarged (the left side of the rectangle remains in place) and the height is enlarged (the top of the rectangle stays in place). To leave the size of the height or width unchanged, pass 0 as the appropriate argument. To shrink a dimension, specify a negative number.
If you're going to do much with drawing, you'll use a lot of Rectangle objects, and I strongly suggest that you learn as much about them as you can.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Drawing Shapes
Now that you've learned about the Graphics object, pens, and rectangles, you'll probably find drawing shapes to be fairly simple. Shapes are drawn by calling methods of a Graphics object. Most methods require a rectangle, which is used as the bounding rectangle for the shape, as well as a pen. In this section, I'll show you what you need to do to draw different shapes.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I've chosen to discuss only the most commonly drawn shapes. The Graphics object contains many methods for drawing additional shapes.
|}
Drawing Lines
Drawing lines is accomplished with the DrawLine() method of the Graphics object. DrawLine() is one of the few drawing methods that doesn't require a rectangle. The syntax for DrawLine() is
<pre>object.DrawLine(pen, x1, y1, x2, y2);
</pre>
<code>Object</code> refers to a Graphics object and <code>pen</code> refers to a Pen object, both of which have already been discussed. X1, Y1 is the coordinate of the starting point of the line, whereas X2, Y2 is the coordinate of the ending point; C# draws a line between the two points, using the specified pen.
Drawing Rectangles
Drawing rectangles (and squares for that matter) is accomplished using the DrawRectangle() method of a Graphics object. As you might expect, DrawRectangle() accepts a pen and a rectangle. Following is the syntax for calling DrawRectangle() in this way:
<pre>object.DrawRectangle(pen, rectangle);
</pre>
If you don't have a Rectangle object (and you don't want to create one), you can call DrawRectangle() using the following format:
<pre>object.DrawRectangle(pen, X, Y, width, height);
</pre> Drawing Circles and Ellipses
Drawing circles and ellipses is accomplished by calling the DrawEllipse() method. If you're familiar with geometry, you'll note that a circle is simply an ellipse that has the same height as it does width. This is why no specific method exists for drawing circles; DrawEllipse() works perfectly. Like the DrawRectangle() method, DrawEllipse() accepts a Pen and a Rectangle. The rectangle is used as a bounding rectangle�the width of the ellipse is the width of the rectangle, whereas the height of the ellipse is the height of the rectangle. DrawEllipse() has the following syntax:
<pre>object.DrawEllipse(pen, rectangle);
</pre>
In the event that you don't have a Rectangle object defined (and again you don't want to create one), you can call DrawEllipse() with this syntax:
<pre>object.DrawEllipse(pen, X, Y, Width, Height);
</pre> Clearing a Drawing Surface
To clear the surface of a Graphics object, call the Clear() method, passing it the color to paint the surface, like this:
<pre>objGraphics.Clear(Drawing.SystemColors.Control);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Drawing Text
Printing text on a Graphics object is very similar to drawing a shape, and the method name even contains the word Draw, in contrast to Print. To draw text on a Graphics object, call the DrawString() method. The basic format for DrawString() looks like this:
<pre>object.DrawString(stringoftext, font, brush, topX, leftY);
</pre>
A few of these items are probably new to you. The argument <code>stringoftext</code> is fairly self-explanatory; it's the string you want to draw on the Graphics object. The <code>topX</code> and <code>leftY</code> arguments represent the coordinate at which drawing will take place; they represent the upper-left corner of the string, as illustrated in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig04 Figure 10.4].
<div style="text-align: center;">Figure 10.4. The coordinate specified in DrawString() represents the upper-left corner of the printed text.
[[Image:10fig04.gif|500px|graphics/10fig04.gof]]
</div>
The arguments <code>brush</code> and <code>font</code> aren't so obvious. Both arguments accept objects. A brush is similar to a pen. However, whereas a pen describes the characteristics of a line, a brush describes the characteristics of a fill. For example, both pens and brushes have a color, but where pens have an attribute for defining a line style, such as dashed or solid, a brush has an attribute for a fill pattern, such as solid, hatched, weave, or trellis. When drawing text, a solid brush is usually sufficient. You can create brushes in much the same way as you create pens, or you can use one of the standard brushes available from the System.Drawing.Brushes class.
A Font object defines characteristics used to format text, including the character set (Times New Roman, Courier, for example), size (point size), and style (bold, italic, normal, underline, and so on). To create a new Font object, you could use code such as the following:
<pre>Font objFont;
objFont = new System.Drawing.Font("Arial", 30);
</pre>
The text <code>Arial</code> in this code is the name of a font installed on my computer. In fact, Arial is one of the few fonts installed on all Windows computers. If you supply the name of a font that doesn't exist, C# will use a default font. The second parameter is the point size of the text. If you want to use a style other than normal, you can provide a style value as a third parameter, like this:
<pre>objFont = new System.Drawing.Font("Arial Black", 30,FontStyle.Bold);
</pre>
or
<pre>objFont = new System.Drawing.Font("Arial Black", 30,FontStyle.Italic);
</pre>
In addition to creating a Font object, you can also use the font of an existing object, such as a Form. For example, the following statement prints text to a Graphics object using the font of the current form:
<pre>objGraphics.DrawString("This is the text that prints!",
this.Font,System.Drawing.Brushes.Azure, 0, 0);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Persisting Graphics on a Form
You'll often use the techniques discussed in this hour to draw to a form. However, you may recall from earlier hours that when you draw to a form (actually, you draw to a Graphics object that references a form), the things that you draw aren't persisted; the next time the form paints itself, the drawn elements will disappear. For example, if the user minimizes the form or obscures the form with another window, the next time the form is painted, it will be missing any and all drawn elements that were obscured. You can use a couple of approaches to deal with this behavior:
* Place all code that draws to the form in the form's Paint event.
* Draw to a memory bitmap and copy the contents of the memory bitmap to the form in the form's Paint event.
If you're drawing only a few items, placing the drawing code in the Paint event might be a good approach. However, consider a situation in which you've got a lot of drawing code. Perhaps the graphics are drawn in response to user input, so you can't re-create them all at once. In these situations, the second approach is clearly better.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Build a Graphics Project Example
You're now going to build a project that uses the skills you've already learned to draw to a form. In this project, you'll use the technique of drawing to a memory bitmap to persist the graphics each time the form paints itself.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The project you're about to build is perhaps the most difficult yet. I'll explain each step of the process of creating this project, but I won't spend any time explaining the objects and methods that I've already discussed.
|}
To make things interesting, I've used random numbers to determine font size as well as the X, Y coordinate of the text you're going to draw to the form. The Random class and its Next() method will be used to generate pseudo-random numbers. To generate a random number within a specific range (such as a random number between 1 and 10), you use the following:
<pre>randomGenerator.Next(1,10);
</pre>
I don't want you to dwell on the details of how the ranges of random numbers are created. However, at times, you may need to use a random number, so I thought I'd spice things up a bit and teach you something cool at the same time.
Start by creating a new Windows Application titled Persisting Graphics.
Change the name of the default form to fclsMain, set the form's Text property to Persisting Graphics, and change the entry point of the project to reference fclsMain instead of Form1. The interface of your form will consist of a text box and a button. When the user clicks the button, the contents of the text box will be drawn on the form in a random location and a random font size. Add a new text box to your form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtInput</code>
|-
| <code>Location</code>
| <code>56,184</code>
|-
| <code>Size</code>
| <code>100,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnDrawText</code>
|-
| <code>Location</code>
| <code>160,184</code>
|-
| <code>Text</code>
| <code>Draw Text</code>
|}
Let the code fly!
As I mentioned earlier, all drawing is going to be performed using a memory bitmap, which will then be drawn on the form. You will reference this bitmap in multiple places, so you're going to make it a module-level variable by following these steps:
# Double-click the Form to access its Load event.
# Locate the statement <code>public class fclsMain : System.Windows.Forms.Form</code> and position your cursor immediately after the left bracket ({) on the next line.
# Press Enter to create a new line.
# Enter the following statement:
<pre>private System.Drawing.Bitmap m_objDrawingSurface;
</pre>
For the bitmap variable to be used, it must reference a Bitmap object. A good place to initialize things is in the form's Load event, so put your cursor back in the Load event now and enter the following code:
<pre>// Create a drawing surface with the same dimensions as the client
// area of the form.
m_objDrawingSurface = new Bitmap(this.ClientRectangle.Width,
this.ClientRectangle.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
InitializeSurface();
</pre>
Your procedure should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig05 Figure 10.5].
<div style="text-align: center;">Figure 10.5. Make sure your code appears exactly as it does here.
[[Image:10fig05.jpg|500px|graphics/10fig05.jpg]]
</div>
The first statement creates a new bitmap in memory. Because the contents of the bitmap are to be sent to the form, it makes sense to use the dimensions of the client area of the form as the size of the new bitmap�which is exactly what you've done. The final statement calls a procedure that you haven't yet created.
Position the cursor after the closing bracket (}) of the fclsMain_Load event and press Enter to create a new line. You're now going to write code to initialize the bitmap. The code will clear the bitmap to the system color named Control and then draw an ellipse that has the dimensions of the bitmap. (I've added comments to the code so that you can follow along with what's happening; all the concepts in this code have been discussed already.) Enter the following in its entirety:
<pre>private void InitializeSurface()
{
Graphics objGraphics;
Rectangle rectBounds;
// Create a Graphics object that references the bitmap and clear it.
objGraphics = Graphics.FromImage(m_objDrawingSurface);
objGraphics.Clear(SystemColors.Control);
//Create a rectangle the same size as the bitmap.
rectBounds = new Rectangle(0, 0,
m_objDrawingSurface.Width,m_objDrawingSurface.Height);
//Reduce the rectangle slightly so the ellipse won't appear on the border.
rectBounds.Inflate(-1, -1);
// Draw an ellipse that fills the form.
objGraphics.DrawEllipse(Pens.Orange, rectBounds);
// Free up resources.
objGraphics.Dispose();
}
</pre>
Your procedure should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig06 Figure 10.6].
<div style="text-align: center;">Figure 10.6. Again, verify that your code is entered correctly.
[[Image:10fig06.jpg|500px|graphics/10fig06.jpg]]
</div>
If you run your project now, you'll find that nothing is drawn to the form. This is because the drawing is being done to a bitmap in memory, and you haven't yet added the code to copy the bitmap to the form. The place to do this is in the form's Paint event so that the contents of the bitmap are sent to the form every time the form paints itself. This ensures that the items you draw always appear on the form.
Create an event handler for the form's Paint event by first returning to the form designer and selecting the form. Click the Event icon (the lightning bolt) in the Properties window and then double-click Paint to create a Paint event. Add the following code to the Paint event:
<pre>Graphics objGraphics ;
//You can't modify e.Graphics directly.
objGraphics = e.Graphics;
// Draw the contents of the bitmap on the form.
objGraphics.DrawImage(m_objDrawingSurface, 0,0,
m_objDrawingSurface.Width,
m_objDrawingSurface.Height);
objGraphics.Dispose();
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The previous code can be rewritten as follows when utilizing the <code>using</code> statement mentioned earlier in this chapter; notice how the Dispose() method is not required anymore.
<pre>using (Graphics objGraphics = e.Graphics)<br />{<br />objGraphics.DrawImage(m_objDrawingSurface,0,0, m_objDrawingSurface.Width<br />m_objDrawingSurface.Height);<br />}<br /></pre>
|}
The e parameter of the Paint event has a property that references the Graphics object of the form. However, you can't modify the Graphics object using the e parameter (it's read-only), which is why you've created a new Graphics object to work with and then set the object to reference the form's Graphics object. The method DrawImage() draws the image in a bitmap to the surface of a Graphics object, so the last statement is simply sending the contents of the bitmap to the form.
If you run the project now, you'll find that the ellipse appears on the form. Furthermore, you can cover the form with another window or even minimize it, and the ellipse will always appear on the form when it's displayed again.
The last thing you're going to do is write code that draws the contents entered into the text box on the form. The text will be drawn with a random size and location. Return to the form designer and double-click the button to access its <code>Click</code> event. Add the following code:
<pre>Graphics objGraphics;
Font objFont;
int intFontSize, intTextX, intTextY;
Random randomGenerator = new Random();
// If no text has been entered, get out.
if (txtInput.Text == "") return;
// Create a graphics object using the memory bitmap.
objGraphics = Graphics.FromImage(m_objDrawingSurface);
// Create a random number for the font size. Keep it between 8 and 48.
intFontSize = randomGenerator.Next(8,48);
// Create a random number for the X coordinate of the text.
intTextX = randomGenerator.Next(0,this.ClientRectangle.Width);
// Create a random number for the Y coordinate of the text.
intTextY = randomGenerator.Next(0,this.ClientRectangle.Height);
// Create a new font object.
objFont = new System.Drawing.Font("Arial", intFontSize, FontStyle.Bold);
// Draw the user's text.
objGraphics.DrawString(txtInput.Text, objFont,
System.Drawing.Brushes.Red, intTextX, intTextY);
// Clean up.
objGraphics.Dispose();
// Force the form to paint itself. This triggers the Paint event.
this.Invalidate();
</pre>
The comments I've included should make the code fairly self-explanatory. However, the last statement bears discussing. The Invalidate() method of a form invalidates the client rectangle. This operation tells Windows that the appearance of the form is no longer accurate and that the form needs to be repainted. This, in turn, triggers the Paint event of the form. Because the Paint event contains the code that copies the contents of the memory bitmap to the form, invalidating the form causes the text to appear. If you don't call Invalidate() here, the text won't appear on the form (but it is still drawn on the memory bitmap).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you draw elements that are based on the size of the form, you'll need to call <code>Invalidate()</code> in the Resize event of the form; resizing a form doesn't trigger the form's Paint event.
|}
The last thing you need to do is make sure you free up the resources used by your module-level <code>Graphics</code> object. Using the Properties window, add an event handler for the Closed event of the form now and enter the following statement:
<pre>m_objDrawingSurface.Dispose();
</pre>
Your project is now complete! Click Save All on the toolbar to save your work, and then press F5 to run the project. You'll notice immediately that the ellipse is drawn on the form. Type something into the text box and click the button. Click it again. Each time you click the button, the text is drawn on the form using the same brush, but with a different size and location (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#ch10fig07 Figure 10.7]).
<div style="text-align: center;">
</div>Summary
You won't need to add drawing capabilities to every project you create. However, when you need the capabilities, you need the capabilities. In this hour, you learned the basic skills for drawing to a graphics surface, which can be a form, control, memory bitmap, or one of many other types of surfaces. You learned that all drawing is done using a Graphics object, and you now know how to create a Graphics object for a form or control and even how to create a Graphics object for a bitmap that exists in memory.
Most drawing methods require a pen and a rectangle, and you can now create rectangles and pens using the techniques you learned in this hour. After learning pens and rectangles, you've found that the drawing methods themselves are pretty easy to use. Even drawing text is a pretty easy process when you've got a Graphics object to work with.
Persisting graphics on a form can be a bit complicated, and I suspect this will confuse a lot of new C# programmers who try to figure it out on their own. However, you've now built an example that persists graphics on a form, and you'll be able to leverage the techniques involved when you have to do this in your own projects.
I don't expect you to be able to sit down for an hour and create an Adobe Photoshop knock-off. However, you now have a solid foundation on which to build. If you're going to attempt a project that performs a lot of drawing, you'll want to dig deeper into the Graphics object.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#qad1e35180 Q1:]'''
| What if I need to draw a lot of lines, one starting where another ends? Do I need to call DrawLine() for each line?
|-
| align="right" | ''' A1: '''
| The Graphics object has a method called DrawLines(), which accepts a series of points. The method draws lines connecting the sequence of points.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/10.htm#qad1e35199 Q2:]'''
| Is there a way to fill a shape?
|-
| align="right" | ''' A2: '''
| The Graphics object includes methods that draw filled shapes, such as FillEllipse() and FillRectangle().
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans01 1:]'''
| What object is used to draw to a surface?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans02 2:]'''
| To set a Graphics object to draw to a form directly, you call what method of the form?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans03 3:]'''
| What object defines the characteristics of a line? A fill pattern?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans04 4:]'''
| How do you make a color property adjust with the user's Windows settings?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans05 5:]'''
| What object is used to define the bounds of a shape to be drawn?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans06 6:]'''
| What method do you call to draw an irregular ellipse? A circle?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans07 7:]'''
| What method do you call to print text on a Graphics surface?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec10.htm#ch10ans08 8:]'''
| To ensure that graphics persist on a form, the graphics must be drawn on the form in what event?
|}
Exercises
# Modify the example in this hour to use a font other than Arial. If you're not sure what fonts are installed on your computer, open the Start menu and choose Settings and then Control Panel. You'll have an option on the Control Panel for viewing your system fonts.
# Create a project that draws an ellipse that fills the form, much like the one you created in this hour. However, draw the ellipse directly to the form in the Paint event. Make sure that the ellipse is redrawn when the form is sized. (Hint: Invalidate the form in the form's Resize event.)
tsk169mi3r2gfmgjh9k7cm1oz12784a
User:Foxall/11
2
2146
39248
5607
2026-04-13T06:03:34Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39248
wikitext
text/x-wiki
== Hour 11. Creating and Calling Methods ==
You've now spent about 11 hours building the basic skills necessary to navigate C# and to create an application interface. Creating a good interface is extremely important, but it's only one step toward creating a Windows program. After you've created the basic interface of an application, you need to enable the program to do something. The program may perform an action all on its own, or it may perform actions based on a user interacting with the interface�either way, to make your application perform tasks, you write C# code. In this hour, you'll learn how to create sets of code (called classes), and how to create and call isolated code routines (called methods).
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec1.htm#ch11lev1sec1 Creating static class members]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec2.htm#ch11lev1sec2 Creating methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec4.htm#ch11lev1sec4 Calling methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec5.htm#ch11lev1sec5 Exiting methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec4.htm#ch11lev2sec3 Passing parameters]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec4.htm#ch11lev2sec4 Avoiding recursive methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11lev1sec6.htm#ch11lev1sec6 Working with tasks]
----
=== Creating Class Members ===
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| A class is a place to store the code you write. Before you can begin writing C# code, you must start with a class. As mentioned in previous hours, a class is used as a template to create an object (which may have properties and/or methods). Properties and methods of classes can be either instance members or static members. Instance members are associated with an instance of a class�an object created from a class using the keyword new. On the other hand, static members belong to the class as a whole, not to a specific instance of a class. You've already worked with one class using instance members to create a form (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05.htm#ch05 Hour 5], "Building Forms�Part I, for more information).When you double-click an object on a form, you access events that reside in the form's class module.
|}
Other languages, such as Visual Basic, differentiate between class methods and public methods that are globally available outside of a class. C# requires all methods to exist in the context of a class, but a globally available method can be achieved by defining static methods in your class. Static methods are always available regardless of whether an instance of the class exists. In fact, you can't access a static member through an instance of a class, and attempting to do so results in an exception (error).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Classes are used as templates for the instantiation of objects. I discuss the specifics of creating objects in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects Using Classes." Most of the techniques discussed in this hour apply to class modules with instance members (methods that are part of an instantiated object), but I'm going to focus this discussion on static members because they are easier to use (you can create and use static methods without getting into the complications of creating objects).
|}
Although you could place all your program's code into a single class module, it's best to create different modules to group different sets of code. In addition, it's best not to place code that isn't specifically related to a form within a form's class module; place such code in the logical class or in a specialized class module.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The current development trend centers on object-oriented programming, which revolves around class modules. I'll give you a primer on object-oriented programming in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], but this is a very advanced topic so I won't be covering it in detail. I highly recommend that you read a dedicated object-oriented book, such as ''''''Sams Teach Yourself Object-Oriented Programming in 21 Days'', after you are comfortable with the material in this book.
|}
One general rule for using static members is that you should create classes to group related sets of code. This isn't to say you should create dozens of classes. Rather, group related methods into a reasonably sized set of classes. For instance, you might want to create one class that contains all your printing routines and another that holds your data-access routines. In addition, I like to create a general-purpose class in which to place all the various routines that don't necessarily fit into a more specialized class.
Start C# now and create a new Windows Application project named Static Methods.
Change the name of the default form to fclsExample, set its Text property to Method Example, and set the Main() entry point of the project to reference fclsExample instead of Form1. Change the Size property of the form to 371, 300. Next, add a new class to the project by choosing Add Class from the Project menu. C# then displays the Add New Item dialog box, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig01 Figure 11.1].
<div style="text-align: center;">Figure 11.1. All new project items are added using this dialog box.
[[Image:11fig01.jpg|500px|graphics/11fig01.jpg]]
</div>
Note that this is the same dialog box used to add new forms. Change the name of the class to clsStaticExample.cs and click Open. C# then creates the new class and positions you in the code window�ready to enter code (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig02 Figure 11.2]).
<div style="text-align: center;">Figure 11.2. Classes have no graphical interface, so you always work with them in the code editor.
[[Image:11fig02.jpg|500px|graphics/11fig02.jpg]]
</div>
Save your project now by clicking Save All on the toolbar.
Writing Methods
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| After you've created the class(es) in which to store your code, you can begin writing methods. A method is a discrete set of code that can be executed. Methods are much like events, but rather than being executed by a user interacting with a form or control, methods are executed when called by a code statement.
|}
The first thing to keep in mind is that every method should perform a specific function, and it should do it very well. You should avoid creating methods that perform many tasks. As an example of the use of methods, consider that you want to create a set of code that, when called, draws an ellipse on a form. You also want a second method to clear the form. If you placed both sets of code into the same method, the ellipse would be drawn and then would immediately be erased. By placing each set of code in its own method, you can draw the ellipse by calling one method and then erase it at any time by calling the other method. By placing these routines in a class rather than attaching them to a specific form, you also make the methods available to any form that may need them.
There are two types of methods in C#:
* Methods that return a value
* Methods that do not return a value (void)
There are many reasons to create a method that returns a value. For example, a method can return true or false, depending on whether it was successful in completing its task. You could also write a method that accepts certain parameters (data passed to the method, in contrast to data returned by the method) and returns a value based on those parameters. For example, you could write a method that lets you pass it a sentence, and in return it passes back the number of characters in the sentence. The possibilities are limited only by your imagination. Just keep in mind that a method doesn't have to return a value.
Declaring Methods That Don't Return Values
Because you've already created a class, you're ready to create methods (to create a method, you first declare it within a class).
Position the cursor to the right of the closed brace (<code>}</code>) that signifies the end of the public clsStaticExample block and press Enter to create a new line. Enter the following three statements:
<pre>public static void DrawEllipse(System.Windows.Forms.Form frm)
{
}
</pre>
Next, position your cursor to the right of the open brace (<code>{</code>) and press Enter to create a new line between the two braces. This is where you'll place the code for the method.
The declaration of a method (the statement used to define a method) has a number of parts. The first word, public, is a keyword (a word with a special meaning in C#). The keyword public defines the scope of this method, designating that the method can be called from code contained in modules other than the one containing the defined method (scope is discussed in detail in the next hour). You can use the keyword private in place of public to restrict access of the method to code only in the module in which the method resides.
The word static is another C# keyword. As mentioned earlier, static members belong to a class as a whole, not to a specific instance of a class. This will allow the DrawEllipse() method to be accessed from other classes without having to instantiate an clsStaticExample object.
The word void is another C# keyword. The void keyword is used to declare a method that doesn't return a value. Later in this hour, you will learn how to create methods that do return values.
The third word, DrawEllipse, is the actual name of the method and can be any string of text you want it to be. Note, however, that you can't assign a name that is a keyword, nor can you use spaces within a name. In this example, the method is going to draw an ellipse on the form, so you used the name DrawEllipse. You should always give method names that reflect their purpose. You can have two methods with the same name only if they have different scope (discussed in the next hour).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Some programmers prefer the readability of spaces in names, but in many instances, such as when naming a method, spaces can't be used. A common technique is to use an underscore (_) in place of a space, such as in Draw_Ellipse. This isn't a recommended practice, however.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Immediately following the name of the method is a set of parentheses surrounding some text. Within these parentheses you can define parameters�data to be passed to the method by the calling program. In this example, you've created a parameter that accepts a reference to a form. The routine will draw an ellipse on whatever form is passed to the parameter.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Parentheses must always be supplied, even when a procedure doesn't accept any parameters (in which case nothing is placed between the parentheses).
|}
Add the following code to your DrawEllipse method:
<pre>System.Drawing.Graphics objGraphics;
System.Drawing.Rectangle recDrawRectangle;
recDrawRectangle = frm.DisplayRectangle;
recDrawRectangle.Inflate(-5, -5);
objGraphics = frm.CreateGraphics();
objGraphics.Clear(System.Drawing.SystemColors.Control);
objGraphics.DrawEllipse(System.Drawing.Pens.Blue, recDrawRectangle);
objGraphics.Dispose();
</pre>
Much of this code is similar to a code example discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], "Understanding Objects and Collections," so I'm not going to go over it in detail. Basically, this routine creates a rectangle with the same dimensions as the client rectangle of the supplied form. Then, the Inflate method is used to reduce the size of the rectangle by 5 pixels in each dimension. Finally, a graphics object is created and set to reference the client area of the supplied form, and a rectangle is drawn within the boundaries of the rectangle.
When you've finished entering your code, it should look like that in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig03 Figure 11.3].
<div style="text-align: center;">Figure 11.3. All code for a method must reside between the open and close braces of the method.
[[Image:11fig03.jpg|500px|graphics/11fig03.jpg]]
</div>
Now you're going to create a procedure that erases the ellipse from a form. Place the caret (cursor) at the end of the closing brace (} ) for the DrawEllipse() method and press enter to create a new line. Enter the following three statements:
<pre>public static void ClearEllipse(System.Windows.Forms.Form frm)
{
}
</pre>
Add the following line of code to the ClearEllipse() method on a new line between the opening and closing braces:
<pre>frm.Refresh();
</pre>
This single line of code forces the designated form to refresh itself. Because the ellipse that was drawn by the first procedure isn't part of the form (it was simply drawn onto the form), the ellipse is cleared.
Declaring Methods That Return Values
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The two methods you've created so far don't return values. You're now going to declare a method that returns a value. Here's the general syntax for the method you will create:
|}
<pre>[modifiers] datatype MethodName(parameters)
</pre>
You'll notice one key difference between declaring a method that doesn't return a value and declaring one that does: you have to define the data type of the value returned. Previously, you used the keyword void to declare that no value was being returned. Data types are discussed in detail in the next hour, so it's not important that you fully understand them now. It is important, however, that you understand what is happening.
The data type entered before the method name denotes the type of data returned by the method. The method that you're about to enter returns a numeric value of type integer. If the method were to return a string of text, it would be declared as string. It is very important that you declare the proper data type for your functions.
Position the cursor to the right of the closing brace for the ClearEllipse() method, press Enter to create a new line, and enter the following three statements:
<pre>public static int ComputeLength(string strText)
{
}
</pre>
Add the following code to a new line between the two braces:
<pre>return strText.Length;
</pre>
When you create a method that returns a value, you use the C# keyword return to return whatever value you want the method to return. In this example, you're using the built-in Length() method of the string class to determine the number of characters within the string that's passed to the method. This value is returned as the value of the method. (You could, of course, avoid writing the function altogether and just use the String.Length() method in the calling code, but this makes a good example.) Your methods should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig04 Figure 11.4].
<div style="text-align: center;">Figure 11.4. Classes often contain many methods.
[[Image:11fig04.jpg|500px|graphics/11fig04.jpg]]
</div>
Creating the User Interface of Your Project
Now that you've written this example's procedures, you need to create the interface for the project. Click the Form1.cs [Design] tab in the IDE to display the form designer for the default form.
You'll need three buttons on this form�one to call each of your methods. Add the first button to the form by double-clicking the Button icon in the toolbox and then set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| Name
| btnDrawEllipse
|-
| Location
| 0,0
|-
| Size
| 80,23
|-
| Text
| Draw Ellipse
|}
Add a second button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| Name
| btnClearEllipse
|-
| Location
| 283,0
|-
| Size
| 80,23
|-
| Text
| Clear Ellipse
|}
Finally, add the third button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| Name
| btnComputeLength
|-
| Location
| 0,250
|-
| Size
| 100,23
|-
| Text
| Compute Length
|}
The last control you need to add to your form is a text box. When the user clicks the Compute Length button, the button's Click event will call the ComputeLength function, passing it the text entered into the text box. It will then display the length of the text in the Output window (this works only when running in the IDE, not when compiled as an application).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Output window is a Visual Studio design window to which you can print text. I use the Output window a lot in examples throughout the remaining hours. When you send text to the Output window, Visual Studio ensures that the Output window is visible. You can display it at any time while working in the IDE by choosing Other Windows from the View menu and then selecting Output. Be aware that the Output window is not available to a compiled component.
|}
Add a text box to the form by double-clicking the Textbox icon in the toolbox. Set the new text box's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| Name
| txtInputForLength
|-
| Location
| 110,250
|-
| Text
| (make blank)
|}
Your form should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig05 Figure 11.5]. You're now ready to write the C# code to call your methods.
<div style="text-align: center;">Figure 11.5. This form is not all that attractive, but it's functional enough for our purposes.
[[Image:11fig05.jpg|500px|graphics/11fig05.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Calling Methods
Calling a method is fairly simple. However, just as methods that return values are declared differently from methods that do not, calling these two types of methods differs as well. You're first going to write code to call the two methods you declared as void (methods that don't return values). Double-click the Draw Ellipse button to access its Click event and take a look at the event declaration:
<pre>private void btnDrawEllipse_Click(object sender, System.EventArgs e)
{
}
</pre>
As you can see, event handlers are methods. The only real difference is that event methods are called automatically in response to the user doing something, rather than being called by code you write. In this case, the btnDrawEllipse_Click() event is called when the user clicks the btnDrawEllipse button. This method is declared as private, so only methods within this module could call this method (yes, you can call event methods). Add the following statement to this Click event:
<pre>clsStaticExample.DrawEllipse(this);
</pre>
To call the DrawEllipse method, you must precede it with the name of the class in which it is defined. The method name and parentheses always come next. If the method expects one or more parameters, place them within the parentheses. In this case, the DrawEllipse() procedure expects a reference to a form. By specifying the keyword this, you're passing a reference to the current form.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| When you type in the class name <code>clsStaticExample</code> followed by a period, C# displays the methods defined for the <code>clsStaticExample</code> class. Also, notice that when you type in the left parenthesis for the <code>DrawEllipse()</code> <code>method</code> , C# displays a ToolTip showing the parameters expected by the method (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig06 Figure 11.6]). It can be difficult to remember the parameters expected by all methods (not to mention the proper order in which to pass them), so this little feature will save you a great deal of time and frustration.
|}
<div style="text-align: center;">Figure 11.6. C# displays the parameters expected of a method.
[[Image:11fig06.jpg|500px|graphics/11fig06.jpg]]
</div>
You're now going to place a call to the ClearEllipse() method in the Click event of the Clear Ellipse button. Display the form in Design view again and double-click the Clear Ellipse button to access its Click event. Add the following statement:
<pre>clsStaticExample.ClearEllipse(this);
</pre>
All that's left to do is add code that computes the length of the string entered by the user. Again, display the form in Design view. Double-click the Compute Length button to access its Click event and enter the following statements (recall from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7], "Working with Traditional Controls," that Debug.WriteLine() sends text to the Output window.):
<pre>int intLength;
intLength = clsStaticExample.ComputeLength(txtInputForLength.Text);
System.Diagnostics.Debug.WriteLine("length = " + intLength);
</pre>
The first line creates a new variable to hold the return value of the ComputeLength() method (the next hour covers variables). The second statement calls the ComputeLength() method. When calling a method that returns a value, think of the method in terms of the value it returns. For example, when you set a form's Height property, you set it with code like this:
<pre>MyForm.Height = 200;
</pre>
This statement sets a form's height to 200. Suppose you had a method that returned a value that you wanted to use to set the form's Height property. Thinking of the method in terms of the value it returns, you could replace the literal value with a method call, as in the following:
<pre>MyForm.Height = MyClass.MyMethod();
</pre>
Try to look at the statement you just entered using this way of thinking. When you do, you see that the statement in this example really says, "Set the variable intLength equal to the value returned by the method ComputeLength()." If ComputeLength() returned the value 20, for example, the line of code would behave as though it were written like this:
<pre>intLength = 20;
</pre>
When calling methods, you must treat the method call the same as you would treat the literal value returned by the method. This often means placing a method call on the right side of an equal sign.
The last line of code you entered outputs the result of the method call to the Output window in the IDE (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7]). The text "length =" and the value of intLength are concatenated (joined together), to produce one string of text that gets displayed. You'll learn about concatenation in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13.htm#ch13 Hour 13], "Performing Arithmetic, String Manipulation, and Date/Time Adjustments." The project is now complete. Click Save All on the toolbar to save your work, and then press F5 to run the project. Click the Draw Ellipse button and an ellipse is drawn on the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig07 Figure 11.7]).
<div style="text-align: center;">Figure 11.7. Clicking the button calls the method that draws the ellipse in the house that Jack built.
[[Image:11fig07.jpg|372px|graphics/11fig07.jpg]]
</div>
Here's what is happening when you click the Draw Ellipse button:
# The Draw Ellipse button's Click event is triggered.
# The method call statement within the Click event is executed.
# Code execution jumps to the DrawEllipse() method.
# All code within the DrawEllipse() method gets executed.
# Execution returns to the Click event.
Click the Clear Ellipse button now to clear the form. When you click this button, the following occurs:
# The Clear Ellipse button's Click event is triggered.
# The method call statement within the Click event is executed.
# Code execution jumps to the ClearEllipse() method.
# All code within the ClearEllipse() method gets executed.
# Execution returns to the Click event.
Finally, enter some text into the text box and click the Compute Length button. Here's what happens:
# The Compute Length button's Click event is triggered.
# The reference to the ComputeLength method causes code execution to jump to that method.
# The ComputeLength() method determines the length of the string. This value is passed back as the result of the method.
# Execution returns to the Click event.
# The result of the method is placed in the variable intLength.
# The rest of the code within the Click event executes. The final result is the length of the string, which is printed in the Output window (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig08 Figure 11.8]).
<div style="text-align: center;">Figure 11.8. <code>System.Diagnostics.Debug.WriteLine</code> sends text to the Output window.
[[Image:11fig08.jpg|500px|graphics/11fig08.jpg]]
</div>
Passing Parameters
Parameters are used within a method to allow the calling code to pass data into the method; methods help eliminate module and global variables. You've already seen how parameters work�parameters are created within the parentheses of a method declaration. A parameter definition consists of the data type and a name for the parameter, as shown here:
<pre>public static void MyMethod(string strMyStringParameter)
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| After you've read about variables in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays," this structure will make a lot more sense. Here, I just want you to get the general idea of how to define and use parameters.
|}
You can define multiple parameters for a method by separating them with a comma, like this:
<pre>public static void MyMethod(string strMyStringParameter,
int intMyIntegerParameter)
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| A calling method passes data to the parameters by way of arguments. This is mostly a semantic issue; when defined in the declaration of a method, the item is called a parameter. When the item is part of the statement that calls the method, it's called an argument. Arguments are passed within parentheses�the same as parameters are defined. If a procedure has multiple arguments, you separate them with commas. For example, you could pass values to the method just defined using a statement such as this:
|}
<pre>MyClass.MyProcedure("This is a string", 11);
</pre>
The parameter acts like an ordinary variable within the method. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12] discusses variables in depth. For now, just realize that variables are storage entities whose values can be changed. In the call statement shown previously, I sent literal values to the procedure. I could have also sent the values of variables like this:
<pre>MyClass.MyProcedure(strAString, intAnInteger);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| An important thing to note about passing variables in C# is that parameters are passed by value rather than by reference. When passed by value, the method receives a copy of the data; changes to the parameter don't affect the value of the original variable. When passed by reference, the parameter is actually a pointer to the original variable. Changes made to the parameter within the method propagate to the original variable. To pass a parameter by reference, you preface the parameter definition with the keyword ref as shown here:
|}
<pre>public static void MyMethod(ref string strMyStringParameter,
int intMyIntegerParameter)
</pre>
Parameters defined without ref are passed by value; this is the default behavior of parameters in C#. Therefore, in this declaration, the first parameter is passed by reference, whereas the second parameter is passed by value.
Avoiding Recursive Methods
It's possible to call methods in such a way that a continuous loop occurs. Consider the following procedures:
<pre>public static void DoSomething()
{
DoSomethingElse();
}
public static void DoSomethingElse()
{
DoSomething();
}
</pre>
Calling either of these methods produces an infinite loop of methods calls and results in the error shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig09 Figure 11.9].
<div style="text-align: center;">
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| This endless loop is known as a recursive loop. Without getting too technical, C# allocates some memory for each method call in an area known as the stack. Only a finite amount of space is on the stack, so infinite recursion eventually uses all the available stack space and an exception occurs. This is a serious error, and steps should be taken to avoid such recursion.
|}
Legitimate uses exist for recursion, most notably in the use of algorithms such as those used in calculus. Deliberate recursion techniques don't create infinite recursion, however. There is always a point where the recursion stops (hopefully, before the stack is consumed). If you have an interest in such algorithms, you should consider reading a book dedicated to the subject.
Exiting Methods
Ordinarily, code within a method executes from beginning to end�literally. However, when a return statement is reached, execution immediately returns to the statement that made the method call; you can force execution to leave the method at any time by using a return statement. If C# encounters a return statement, the method terminates immediately, and code returns to the statement that called the method.
As you build your applications, you'll find that the number of methods and classes expands rather quickly. At times, you'll realize that a method isn't finished or that you had to use a "hack" (a less-desirable solution) to solve a problem. You'll need an easy way to keep these things straight so that you can revisit the code as needed. You'll learn a powerful way to do this in the next section.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Working with Tasks
One of the most exciting IDE enhancements from previous versions of Visual Studio, in my opinion, is the new Task List. Tasks are really all about managing code. If your Task List window isn't displayed, show it now by choosing Show Tasks from the View menu and then choosing All. Tasks are used to keep track of critical spots in code or things that need to be done. C# automatically creates some tasks for you, and you can create your own as needed.
One instance in which C.htm# creates tasks is when your code has compile (build) errors. Because C# knows the exact error and the offending statement, it creates an appropriate task. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig10 Figure 11.10] shows the Task List containing a build error. Notice how the task's description tells you the exact problem. Double-clicking a system-generated task takes you directly to the related statement (double-clicking a task that you created has a different effect, as discussed shortly). If the task exists in a class that isn't loaded, C# loads the class and then takes you to the statement. This greatly simplifies the process of addressing compile errors in code; you can simply work through the list of tasks rather than compile, fix an error, try compiling again, fix the next error, and so on.
<div style="text-align: center;">Figure 11.10. Tasks help you keep track of critical spots in code.
[[Image:11fig10.jpg|500px|graphics/11fig10.jpg]]
</div>
In addition to system-generated tasks, you can create your own tasks as often and wherever needed. In the past, it was common to place certain comments such as "TODO" in code where you needed to address something. These comments often were forgotten. When you wanted to address the issues, you had to perform a text search in your code. This was a highly inefficient process.
Now you can create a task wherever you need to. Creating a task is easy. Right-click the code statement to which you want to attach the task and choose Add Task List Shortcut from the context menu. C# creates a task shortcut at the statement (as indicated by a blue arrow in the left margin of the code window) and adds the task to the Task List window. The default description for the next task is the actual code statement you flagged (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#ch11fig11 Figure 11.11]). To change this text, click the description in the Task List to put it in Edit mode and then change the text. To go directly to the statement to which a task is attached, double-click the shortcut arrow next to the task in the Task List (the arrow is the same one that appears in the left margin of the code window).
<div style="text-align: center;">Figure 11.11. Tasks make it easy to track issues that need to be addressed.
[[Image:11fig11.jpg|500px|graphics/11fig11.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Another way to create a task is to insert a comment that literally starts with TODO:�Visual Studio .NET will then automatically create a task using the comment.
|}
You don't have to attach a task to a code statement. To create a task that isn't attached to code, click the first row of the Task List. The default text <code>Click here to add a new task</code> goes away, and you're free to enter the description for your new task.
To delete a task you created, click once on the task in the Task List to select it, and then right-click the task and choose Delete from the context menu. You can't delete a task that was created by C# as a result of a build error�you must correct the error to make the task go away.
Tasks are an incredibly simple, yet useful, tool. I highly encourage you to use them in your development.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
In this hour, you learned how a method is a discrete set of code designed to perform a task or related set of tasks. Methods are where you write C# code. Some methods may be as short as a single line of code, whereas others are pages in length. You learned how to define methods and how to call them. Creating and calling methods is critical to your success in programming with C#; be sure to avoid creating recursive methods! Because you use methods so often, they'll become second nature to you in no time.
Classes are used to group methods. In this hour, I focused on the class module (which is little more than a container for methods) and static methods. Remember to group related methods in the same class and to give each class a descriptive name. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], you'll build on your experience with classes and methods and work with instance classes.
Finally, you learned about Visual Studio's new Task List feature. You now know that C# creates some tasks for you but that you are free to create tasks as you see fit. You learned how to easily jump to a statement that's related to a task and how to create tasks that aren't related to a specific code statement. The Task List is a powerful tool to have in your arsenal, and I encourage you to use it.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#qad1e37796 Q1:]'''
| Do I need to pay much attention to scope when defining my methods?
|-
| align="right" | ''' A1: '''
| It may be tempting to create all your methods as public static, but this is bad coding practice for a number of reasons. For one thing, you will find that in larger projects, you'll have methods with the same name that do slightly different things. Usually, these routines are relevant only within a small scope. If the method isn't needed at the public level, don't define it for public access.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/11.htm#qad1e37824 Q2:]'''
| How many classes is a "reasonable" amount?
|-
| align="right" | ''' A2: '''
| This is hard to say. There really is no right answer. Instead of worrying about an exact count, you should strive to make sure that your classes are logical and that they contain only appropriate methods and properties.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans01 1:]'''
| What are the entities called that are used to house methods?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans02 2:]'''
| True or False: To access methods in a class module, you must first create an object.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans03 3:]'''
| Data that has been passed into a method by a calling statement is called a
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans04 4:]'''
| To pass multiple arguments to a method, separate them with a
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans05 5:]'''
| The situation in which a method or set of methods continue to call each other in a looping fashion is called
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec11.htm#ch11ans06 6:]'''
| How do you attach a task to a code statement?
|}
Exercises
# Create a method as part of a form that accepts a string and outputs to the string. Add code to the TextChanged event of a text box to call the procedure, passing the contents of the text box as the argument.
# Create a single method that calls itself. Call this method from the Click event of a button and observe the error that results.
rzoqh0et61bvkkd4lz2i4zkg62ei47a
User:Foxall/12
2
2147
39249
5608
2026-04-13T06:03:34Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39249
wikitext
text/x-wiki
== Hour 12. Using Constants, Data Types, Variables, and Arrays ==
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As you write your C# methods, you'll regularly need to store and retrieve various pieces of information. In fact, I can't think of a single application I've written that didn't need to store and retrieve data in code. For example, you might want to keep track of how many times a method has been called, or you may want to store a property value and use it at a later time. Such data can be stored as constants, variables, or arrays. Constants are named values that you define once at design time but that can be referenced as often as needed. Variables, on the other hand, are like storage bins; you can retrieve or replace the data in a variable as often as you need to. Arrays act like grouped variables, allowing you to store many values in a single array variable.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Whenever you define one of these storage entities, you must decide the type of data it will contain. For example, is a new variable going to hold a string value (text) or perhaps a number? If it will hold a number, is the number a whole number, an integer, or something else entirely? After you determine the type of data to store, you must choose the level of visibility that the data has to other methods within the project (this visibility is known as scope). In this hour, you'll learn the ins and outs of C# new data types, how to create and use these "storage" mechanisms, and you'll learn how to minimize problems in your code by reducing scope.
|}
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec1.htm#ch12lev1sec1 Understanding data types]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec1.htm#ch12lev2sec1 Determining data type]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec1.htm#ch12lev2sec1 Converting data to different data types]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec2.htm#ch12lev1sec2 Defining and using constants]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec3.htm#ch12lev1sec3 Dimensioning and referencing variables]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec3.htm#ch12lev2sec6 Working with arrays]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec4.htm#ch12lev1sec4 Determining scope]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec5.htm#ch12lev1sec5 Using a naming convention]
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I cover a lot of important material in this hour, but you'll notice a lack of hands-on examples. You're going to use variables throughout the rest of this book, and you've already used them in earlier hours. I've used the space in this hour to teach you the meat of the subject; you'll get experience with the material in other hours.
|}
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Understanding Data Types
In any programming language, it's critical that the compiler, the part of the Visual Studio framework that interprets the code you write into a language the computer can understand, fully understands the type of data you're manipulating in code. For example, if you asked the compiler to add the following values, it would get confused:
<pre>659 / "Dog"
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| When the compiler gets confused, it either refuses to compile the code (which is the preferred situation because you can address the problem before your users run the application), or it will halt execution and display an exception (error) when it reaches the confusing line of code. (These two types of errors are discussed in detail in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch16.htm#ch16 Hour 16], "Debugging Your Code.") Obviously, you can't subtract 659 by the word "Dog"; these two values are different types of data. In C#, these two values are said to have two different data types. In C#, constants, variables, and arrays must always be defined to hold a specific type of information.
|}
Determining Data Type
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Data typing�the act of defining a constant, a variable, or an array's data type�can be confusing. To C#, a number is not a number. A number that contains a decimal value is different from a number that does not. C# can perform arithmetic on numbers of different data types, but you can't store data of one type in a variable with an incompatible type. Because of this limitation, you must give careful consideration to the type of data you plan to store in a constant, a variable, or an array at the time you define it. C# supports two categories of data types: value types and reference types. The main difference between these two types is how their values are stored in memory. As you continue to create more complex applications, this difference may have an impact on your programming. For this book, however, this distinction is minimal. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12table01 Table 12.1] lists the C# data types and the range of values they can contain.
|}
{| cellspacing="0" cellpadding="1" border="1"|+ Table 12.1. The C# Data Types
|-
| valign="middle" | Data Type�Value
| valign="middle" | Value Range
|-
| bool
| true or false
|-
| byte
| 0 to 255
|-
| char
| a single character
|-
| decimal
| �79,228,162,514,264,337,593,543,950,335 to �7.9228162514264337593543950335. Use this data type for currency values
|-
| double
| �1.79769313486232E308 to �4.94065645841247E-324 for negative values; 4.94065645841247E�324 to 1.79769313486232E308 for positive values
|-
| float
| �3.402823E38 to �1.401298E�45 for negative values; 1.401298E�45 to 3.402823E38 for positive values
|-
| int
| �2,147,483,648 to 2,147,483,647.
|-
| long
| �9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
|-
| sbyte
| �128 to 127
|-
| short
| �32,768 to 32,767
|-
| uint
| Integers in the range from 0 to 4,294,967,295
|-
| ulong
| Integers in the range from 0 to 10^20
|-
| ushort
| Integers in the range from 0 to 65,535
|}
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Data Type�Reference
| valign="middle" | Value Range
|-
| string
| 0 to approximately 2 billion characters
|-
| object
| Any type can be stored in a variable type Object
|}
C# supports unsigned data types for short, int, and long (the types prefaces with u, such as uint). Because negative numbers are excluded (there is no sign) this has the effect of doubling the positive values for a short, an int, or a long. Signed data types are preferable and should be used unless you have a very good reason for doing otherwise (such as declaring a variable that will never hold a negative value).
==== Tips for Determining Data Type ====
The list of data types may seem daunting at first, but you can follow some general guidelines for choosing among them. As you become more familiar with the different types, you'll be able to fine-tune your data type selection.
Following are some helpful guidelines for using data types:
* If you want to store text, use the string data type. The string data type can be used to store any valid keyboard character, including numbers and nonalphabetic characters.
* If you want to store only the values true or false, use the bool data type.
* If you want to store a number that contains no decimal places and is greater than �32,768 and smaller than 32,767, use the short data type.
* If you need to store numbers with no decimal places but with values larger or smaller than short allows, use the int or long data types.
* If you need to store numbers that contain decimal places, use the float data type. The float data type should work for almost all your values containing decimals, unless you're writing incredibly complex mathematical applications or need to store very large numbers; in that case, use a double.
* If you need to store currency amounts, use the decimal data type.
* If you need to store a single character, use the char data type.
Casting Data from One Data Type to Another
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Under some circumstances, C# won't allow you to move data of one type into a variable of another type. The process of changing a value's data type is known as casting. C# supports two types of casting: implicit and explicit. Implicit conversions are done automatically by the compiler. These conversions guarantee that no data is lost in the conversion. For instance, you can set the value of a variable declared as double to the value of a variable declared as float without an explicit cast because there is no risk of losing data; (the double data type holds a higher value than does a float.
|}
Explicit casting is required when a potential exists for data loss or when converting a larger data type into a smaller data type. If you tried to place a value in a variable when the value was higher than the variable's supported data type, some data would be lost. Therefore, C# requires that these types of conversions be explicitly written using the cast operator. For instance, you can set the value of a variable declared as short to the value of a variable declared as integer using the following syntax:
<pre>short MyShortInterger;
int MyInteger = 1000;
MyShortInterger = (short) MyInteger;
</pre>
Notice here that 1000 would fit in a short, so data wouldn't actually be lost if no explicit cast were performed. However, C# doesn't care; it's the potential for data loss that causes C# to require explicit casts.
[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12table02 Table 12.2] lists some of the type conversions that can be done implicitly with no loss of information.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 12.2. Safe Conversions
|-
| Type
| Can Be Safely Converted To
|-
| byte
| char, short, int, long, float, double, decimal
|-
| short
| int, long, float, double, decimal
|-
| int
| long, float, double, decimal
|-
| long
| float, double, decimal
|-
| float
| double, decimal
|-
| double
| decimal
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Defining and Using Constants
When you hard-code numbers in your code (such as in intVotingAge = 19;), a myriad of things can go wrong. Hard-coded numbers are generally referred to as "magic numbers" because they're often shrouded in mystery; the meaning of such a number is obscure because the digits themselves give no indication as to what the number represents. Constants are used to eliminate the problems of magic numbers.
You define a constant as having a specific value at design time, and that value never changes throughout the life of your program. Constants offer the following benefits:
* Elimination or reduction of data entry problems It is much easier, for example, to remember to use a constant named c_pi than it is to enter 3.14159265358979 everywhere that pi is needed. The compiler will catch misspelled or undeclared constants, but it doesn't care one bit what you enter as a literal value. (Incidentally, you can retrieve the value of pi using System.Math.PI, so you don't have to worry about creating your own constant!)
* Code is easier to update If you hard-coded a mortgage interest rate at 6.785, and rates were changed to 7.00, you would have to change every occurrence of 6.785 in code. In addition to the possibility of data entry problems, you'd run the risk of changing a value of 6.785 that had nothing to do with the interest rate�perhaps a value that represented a savings bond yield. With a constant, you change the value once, and all code uses the new value.
* Code is easier to read Magic numbers are often anything but intuitive. Well-named constants, on the other hand, add clarity to code. For example, which of the following statements makes the most sense?
<pre>decInterestAmount = ((decLoanAmount * 0.075) * 12);
</pre>
* or
<pre>decInterestAmount = ((decLoanAmount * c_fltInterestRate) * _
c_intMonthsInTerm);
</pre>
Constant definitions have the following syntax:
<pre>const datatype name = value; </pre>
For example, to define a constant to hold the value of pi, you could use a statement such as this:
<pre>const float c_pi = 3.14159265358979;
</pre>
Note how I prefix the constant name with c_. I do this so that it's easier to determine what's a variable and what's a constant when reading code. See the section on [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec5.htm#ch12lev1sec5 naming conventions] later in this hour for more information.
After a constant is defined, you can use the constant's name anywhere in code in place of the constant's value. For example, to output the result of two times the value of pi, you could use a statement like this (the * character is used for multiplication and is covered in the next hour):
<pre>Debug.WriteLine(c_pi * 2);
</pre>
Using the constant is much easier and less error prone than typing this:
<pre>Debug.WriteLine(3.14159265358979 * 2);
</pre>
Constants can be referenced only in the scope in which they are defined. I discuss scope in the section "[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12lev1sec4.htm#ch12lev1sec4 Determining Scope]."
Declaring and Referencing Variables
Variables are similar to constants in that when you reference a variable's name in code, C# substitutes the variable's value in place of the variable name when the code executes. This doesn't happen at compile time, however. Instead, it happens at runtime�the moment the variable is referenced. This is because variables, unlike constants, may have their values changed at any time.
Declaring Variables
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The act of defining a variable is called declaring. (Variables with scope other than local are dimensioned in a slightly different way, as discussed in the section on scope.) You've already defined variables in previous hours, so the statement should look familiar to you:
|}
<pre>datatype variablename = initialvalue; </pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| It's possible to declare multiple variables of the same type on a single line. However, this is often considered bad form because it tends to make the code harder to read.
|}
You don't have to specify an initial value for a variable, although being able to do so in the declaration statement is very cool and useful. For example, to create a new string variable and initialize it with a value, you could use two statements, such as the following:
<pre>string strName;
strName = "Chris Bermejo";
</pre>
However, if you know the initial value of the variable at design time, you can include it on the declaration statement, like this:
<pre>string strName = "Chris Bermejo";
</pre>
Note, however, that supplying an initial value doesn't make this a constant; it's still a variable, and the content of the variable can be changed at any time. This method of creating an initial value eliminates a code statement and makes the code a bit easier to read because you don't have to go looking to see where the variable is initialized.
It's important to note that C# is a strongly typed language; therefore, you must always declare the data type of a variable. In addition, C# requires that all variables be initialized before they're used.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Visual Basic programmers should note that C# will not default numeric variables to 0 or strings to empty strings.
|}
For example, the following statements would result in a compiler error in C#: <code>Type or namespace "single" could not be found</code>.
<pre>single sngMyValue;
Debug.WriteLine(sngMyValue + 2);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You cannot use a reserved word to name a constant or a variable. For instance, you couldn't use public or private as variable names.
|}
Passing Literal Values to a Variable
The syntax of passing a literal value (a hard-coded value such as 6 or "test") to a variable depends on the data type of the variable.
For strings, you must pass the value in quotes, like this:
<pre>strCollegeName = "Bellevue University";
</pre>
There is one caveat when assigning literal values to strings: C# interprets slashes (<code>\</code>) as being a special type of escape sequence. If you pass a literal string containing one or more slashes to a variable, you'll get an error. What you have to do in such instances is preface the literal with the symbol <code>@</code>, like this:
<pre>strFilePath = @"c:\Temp";
</pre>
When C# encounters the <code>@</code> symbol, it knows not to treat slashes in the string as escape sequences.
To pass a literal value to a char variable, use single quotes instead of double quotes, like this:
<pre>chaMyCharacter = 'j';
</pre>
For numeric values, you don't enclose the value in anything:
<pre>IntAnswerToEverything = 42;
</pre> Using Variables in Expressions
Variables can be used anywhere an expression is expected. The arithmetic functions, for example, operate on expressions. You could add two literal numbers and store the result in a variable like the following:
<pre>IntMyVariable = 2 + 5;
</pre>
You could replace either or both literal numbers with numeric variables or constants, as shown next:
<pre>IntMyVariable = intFirstValue + 5;
IntMyVariable = 2 + intSecondValue;
IntMyVariable = intFirstValue + intSecondValue;
</pre>
Variables are a fantastic way to store values during code execution, and you'll use variables all the time�from performing decisions and creating loops to using them only as a temporary place to stick a value. Remember to use a constant when you know the value at design time and the value won't change. When you don't know the value ahead of time or the value may change, use a variable with a data type appropriate to the function of the variable.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| In C#, variables are created as objects. Feel free to create a variable and explore the members of the variable. You do this by entering the variable name and pressing a period (this will work only after you've entered the statement that defines the variable).
|}
Working with Arrays
An array is a special type of variable�it's a variable with multiple dimensions. Think of an ordinary variable as a single mail slot. You can retrieve or change the contents of the mail slot by referencing the variable. An array is like having an entire row of mail slots (called elements). You can retrieve and set the contents of any of the individual mail slots at any time by referencing the single array variable. You do this by using an index that points to the appropriate slot.
Declaring Arrays
Before you can use an array, you must first declare it (the same as you have to declare variables). Consider the following statements:
<pre>string[] strMyArray;
strMyArray = new string[10];
</pre>
The first statement declares strMyArray as an array, and the second statement defines the array as having 10 string elements.
The number in brackets specifies how many "mail slots" the array variable will contain, and it can be a literal value, a constant, or the value of another variable.
Referencing Array Variables
To place a value in an array index, you specify the index number when referencing the variable. Most computer operations consider 0 to be the first value in a series�not 1, as you might expect. This is how array indexing behaves. For example, for an array dimensioned with 10 elements, you would reference the elements sequentially using the indexes 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. Notice that the upper index is one fewer than the total elements because 0 is the first index, not 1. Therefore, to place a value in the first element of the array variable, you would use 0 as the index, like this:
<pre>strMyArray[0] = "This value goes in the first element";
</pre>
The data type specified for the array variable is used for all the elements in the array. This is where the object data type can come in handy. For example, suppose you wanted to store the following pieces of information in an array: Name, City, State, Age, and DateOfBirth. As you can see, you need to store string values for Name, City, and State, but you need to store a number for Age. By dimensioning an array variable as data type object, you can store all these different types of data in the array; C# will determine the data type of each element as the data is placed into it. The following shows an example of a declaration of such an array:
<pre>object[] objPersonalInfo;
objPersonalInfo = new object[10];
</pre>
Again, after it's defined, you can reference the array variable as you would an ordinary variable, with the exception that you must include an index. For example, you could populate the array using code like this:
<pre>objPersonalInfo[0] = "James Foxall";
objPersonalInfo[1] = "Papillion";
objPersonalInfo[2] = "Nebraska";
objPersonalInfo[3] = 32;
</pre> Creating Multidimensional Arrays
Array variables require only one declaration, yet they can store numerous pieces of data; this makes them perfect for storing sets of related information. The array example shown previously is a single-dimension array. Arrays can be much more complex than this example and can have multiple dimensions of data. For example, a single array variable could be defined to store the personal information shown previously for different people. Multidimensional arrays are declared with multiple parameters such as the following:
<pre>int[,] intMeasurements;
intMeasurements = new int[3,2];
</pre>
These statements create a two-dimensional array. The first dimension (defined as having three elements) serves as an index to the second dimension (defined as having two elements). Suppose you wanted to store the height and weight of three people in this array. You reference the array as you would a single-dimension array, but you include the extra parameter index. The two indexes together specify an element, much like coordinates in Battleship relate to specific spots on the game board. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12fig01 Figure 12.1] illustrates how the elements are related.
<div style="text-align: center;">Figure 12.1. Two-dimensional arrays are like a wall of mail slots.
[[Image:12fig01.gif|478px|graphics/12fig01.gof]]
</div>
Elements are grouped according to the first index specified; think of the first set of indexes as being a single-dimension array. For example, to store the height and weight of a person in the array's first dimension, you could use code such as the following:
<pre>intMeasurements[0,0] = FirstPersonsHeight;
intMeasurements[0,1] = FirstPersonsWeight; </pre>
I find it helpful to create constants for the array elements, which makes array references much easier to understand. Consider the following:
<pre>const int c_Height = 0;
const int c_Weight = 1;
intMeasurements[0,c_Height] = FirstPersonsHeight;
intMeasurements[0,c_Weight] = FirstPersonsWeight;
</pre>
You could then store the height and weight of the second and third person like this:
<pre>intMeasurements[1,c_Height] = SecondPersonsHeight;
intMeasurements[1,c_Weight] = SecondPersonsWeight;
intMeasurements[2,c_Height] = ThirdPersonsHeight;
intMeasurements[2,c_Width] = ThirdPersonsWeight; </pre>
In this array, I've used the first dimension to differentiate people. I've used the second dimension to store a height and weight for each element in the first dimension.
Because I've consistently stored heights in the first slot of the array's second dimension and weights in the second slot of the array's second dimension, it becomes easy to work with these pieces of data. For example, you can retrieve the height and weight of a single person as long as you know the first dimension index used to store the data. You could, for instance, print out the total weight of all three people using the following code:
<pre>Debug.WriteLine(intMeasurements[0,c_Weight] + intMeasurements[1,c_Weight] +
intMeasurements[2,c_Weight]);
</pre>
When working with arrays, keep the following points in mind:
* The first element in any dimension of an array has an index of 0.
* Dimension an array to hold only as much data as you intend to put into it.
* Dimension an array with a data type appropriate to the values to be placed in the array's elements.
Arrays are an extremely powerful and easy way to store and work with related sets of data in C# code. Arrays can make working with larger sets of data much simpler and more efficient than using other methods. To maximize your effectiveness with arrays, study the for loop discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch15.htm#ch15 Hour 15], "Looping for Efficiency." Using a for loop, you can quickly iterate through all the elements in an array.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| This section discussed the rectangular type of a C# multidimensional array. C# also supports another type of multidimensional array called jagged. Jagged arrays are an array of one-dimensional arrays, each of which can be of different lengths. However, teaching jagged arrays is beyond the scope of this book.
|}
Determining Scope
Constants, variables, and arrays are extremely useful ways to store and retrieve data in C# code. Hardly a program is written that doesn't use at least one of these elements. To properly use them, however, it's critical that you understand scope.
You had your first encounter with scope in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods," with the keywords private and public. You learned that code is written in procedures and that procedures are stored in modules. Scope refers to the level that a constant, a variable, an array, or a procedure can be "seen" in code. For a constant or variable, scope can be one of the following:
* Block level
* Method level (local)
* Private level
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Scope has the same effect on array variables as it does on ordinary variables. For the sake of clarity, I'll reference variables in this discussion on scope, but understand that what I discuss applies equally to arrays.
|}
The different levels of scope are explained in the following sections.
Understanding Block Scope
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Block scope, also called structure scope, is when a variable is declared within a structure, and if so, it gives the variable block scope.
|}
Structures are coding constructs that consist of two statements as opposed to one. For example, the standard <code>do</code> structure is used to create a loop; it looks like this:
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| C# uses the word structure to mean a user-defined type. However, when talking about code, structure is also used to mean a block of code that has a beginning and an end. For the purpose of this discussion, it is this code block that I am referring to.
|}
<pre>do
<statements to execute in the loop
while(i <10)
</pre>
Another example is the for loop, which looks like this:
<pre>for (int I = 1; i<10;i++)
{
<statements to execute when expression is True>
}
</pre>
If a variable is declared within a structure, the variable's scope is confined to the structure; the variable isn't created until the declaration statement occurs, and it's destroyed when the structure completes. If a variable is needed only within a structure, think about declaring it within the structure to give it block scope. Consider the following example:
<pre>if (blnCreateLoop)
{
int intCounter ;
for (intCounter=1; intCounter<=100; intCounter++)
// Do something
}
</pre>
By placing the variable declaration statement within the if structure, you ensure that the variable is created only if it is needed. In fact, you can create a block simply by enclosing statements in opening and closing braces like this:
<pre>{
int intMyVariable = 10;
Console.WriteLine(intMyVariable);
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The various structures, including looping and decision-making structures, are discussed in later hours.
|}
Understanding Method-Level (Local) Scope
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| When you declare a constant or variable within a method, that constant or variable has method-level, or local, scope. Most of the variables you'll create will have method scope. In fact, all the variables you've created in previous hours have had method-level scope. You can reference a local constant or variable within the same method, but it isn't visible to other methods. If you try to reference a local constant or variable from a method other than the one in which it's defined, C# returns a compile error to the method making the reference (the variable or constant doesn't exist). It's generally considered the best practice to declare all your local variables at the top of a method, but C# doesn't care where you place declaration statements within a method. Note, however, that if you place a declaration statement within a structure, the corresponding variable will have block scope, not local scope.
|}
Understanding Private-Level Scope
When a constant or variable has private-level scope, it can be viewed by all methods within the class containing the declaration. To methods in all other classes, however, the constant or variable doesn't exist. To create a constant or variable with private-level scope, you must place the declaration within a class but not within a method. Class member declarations are generally done at the beginning of the class (right after the opening brace of the class). Use private-level scope when many methods must share the same variable and when passing the value as a parameter is not a workable solution.
For all modules other than those used to generate forms, it's easy to add code to the declarations section; simply add the declaration statements just after the class declaration line and prior to any method definitions, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12fig02 Figure 12.2].
<div style="text-align: center;">Figure 12.2. The declarations section exists above all declared methods.
[[Image:12fig02.jpg|500px|graphics/12fig02.jpg]]
</div>
Classes used to generate forms have lots of system-generated code within them, so it might not be so obvious where to place private-level variables. C# inserts many private statements in classes used to build forms, so place your variable declarations after any and all form-type declaration statements in such classes (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12fig03 Figure 12.3]).
<div style="text-align: center;">Figure 12.3. The declarations section includes the C# generated statements.
[[Image:12fig03.jpg|500px|graphics/12fig03.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| In general, the smaller the scope the better. When possible, give a variable block or local scope. If you have to increase scope, attempt to make the variable a private-level variable. You should use public variables only when absolutely necessary (and there are times when it is necessary to do so). The higher the scope, the more possibilities exist for problems and the more difficult it is to debug those problems.
|}
Naming Conventions
To make code more self-documenting (always an important goal) and to reduce the chance of programming errors, you need an easy way to determine the exact data type of a variable or the exact type of a referenced control in C# code.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Variable naming conventions have long been a hot topic. With the release of .NET, Microsoft has officially recommended that you not use naming conventions (although it's hard to imagine why). As a professional developer, I find this idea counterproductive, and most other developers I have spoken with have no plans to abandon using naming conventions. Because I so firmly believe in them and because they aid the learning process, I have used them, and I teach them in this book. Please be aware that if you don't like naming conventions, you don't have to use them. However, I strongly recommend that you do use naming conventions; the benefits they provide are considerable.
|}
Using Prefixes to Denote Data Type
[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12table03 Table 12.3] lists the prefixes of the common data types.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 12.3. Prefixes for Common Data Types
|-
| valign="middle" | Data Type
| valign="middle" | Prefix
| valign="middle" | Value
|-
| Boolean
| <code>bln</code>
| <code>blnLoggedIn</code>
|-
| Byte
| <code>byt</code>
| <code>bytAge</code>
|-
| Char
| <code>chr</code>
| <code>chrQuantity</code>
|-
| Decimal
| <code>dec</code>
| <code>decSalary</code>
|-
| Double
| <code>dbl</code>
| <code>dblCalculatedResult</code>
|-
| Integer
| <code>int</code>
| <code>intLoopCounter</code>
|-
| Long
| <code>lng</code>
| <code>lngCustomerID</code>
|-
| Object
| <code>obj</code>
| <code>objWord</code>
|-
| Short
| <code>sho</code>
| <code>shoTotalParts</code>
|-
| String
| <code>str</code>
| <code>strFirstName</code>
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The prefix of obj should be reserved for when a specific prefix isn't available. The most common use of this prefix is when referencing Automation libraries of COM applications. For instance, when automating Microsoft Word, you create an instance of Word's Application object. Because no prefix exists specifically for Word objects, obj works just fine (that is, <code>Word.Application objWord = new Word.Application);</code>.
|}
Denoting Scope Using Variable Prefixes
Prefixes are useful not only to denote data types, they also can be used to denote scope (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#ch12table04 Table 12.4]). In particularly large applications, a scope designator is almost a necessity. Again, C# doesn't care whether you use prefixes, but consistently using prefixes benefits you as well as others who have to review your code.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 12.4. Prefixes for Variable Scope
|-
| valign="middle" | Prefix
| valign="middle" | Description
| valign="middle" | Example
|-
| <code>g</code>
| Global
| <code>g_strSavePath</code>
|-
| <code>m</code>
| Private to class
| <code>m_blnDataChanged</code>
|-
| (no prefix)
| Nonstatic variable, local to method
|
|}
Other Prefixes
Prefixes aren't just for variables. All standard objects (including forms and controls) can use a three-character prefix. There are simply too many controls and objects to list all the prefixes here, although you will find that I use control prefixes throughout this book.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
In this hour, you learned how to eliminate magic numbers by creating constants. By using constants in place of literal values, you increase code readability, reduce the possibilities of coding errors, and make it much easier to change a value in the future.
In addition, you learned how to create variables for data elements in which the initial value isn't known at design time or for elements whose values will be changed at runtime. You learned how arrays add dimensions to variables and how to declare and reference them in your code.
C# enforces strict data typing, and in this hour you learned about the various data types and how they're used, as well as tips for choosing data types and functions for converting data from one type to another. Finally, you learned about scope�a very important programming concept�and how to manage scope within your projects.
Writing code that can be clearly understood even by those who didn't write it is a worthwhile goal. Naming prefixes goes a long way toward accomplishing this goal. In this hour you learned the naming prefixes for the common data types, and you learned to use prefixes to denote scope.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#qad1e41129 Q1:]'''
| Are any performance tricks related to the many data types?
|-
| align="right" | ''' A1: '''
| One trick when using whole numbers (values with no decimal places) is to use the data type that matches your processor. For instance, most current home and office computers have 32-bit processors. The C# integer data type is made up of 32 bits. Believe it or not, C# can process an integer variable faster than it can process a short variable, even though the short variable is smaller. This has to do with the architecture of the CPU, memory, and bus. The explanation is complicated, but the end result is that you should usually use integer rather than short, even when working with values that don't require the larger size of the integer.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/12.htm#qad1e41139 Q2:]'''
| Are arrays limited to two dimensions?
|-
| align="right" | ''' A2: '''
| Although I showed only two dimensions (that is, intMeasurements[3,1]), arrays can have many dimensions, such as intMeasurements[3,3,3,4]. The technical maximum is 60 dimensions, but you probably won't use more than three.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans01 1:]'''
| What data type would you use to hold currency values?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans02 2:]'''
| Which data type can be used to hold any kind of data and essentially serves as a generic data type?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans03 3:]'''
| What values does C# support for type bool?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans04 4:]'''
| What can you create to eliminate magic numbers by defining a literal value in one place?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans05 5:]'''
| What type of data element can you create in code that can have its value changed as many times as necessary?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans06 6:]'''
| What are the first and last indexes of an array dimensioned using <code>string_strMyArray[5]</code>?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans07 7:]'''
| What word is given to describe the visibility of a constant or variable?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec12.htm#ch12ans08 8:]'''
| In general, is it best to limit the scope of a variable or to use the widest scope possible?
|}
Exercises
# Create a project with a text box, a button, and a label control. When the user clicks the button, move the contents of the text box to a variable, and then move the contents of the variable to the Text property of the label. (Hint: a string variable will do the trick.)
# Rewrite the following code so that a single array variable is used rather than two standard variables. (Hint: Do not use a multidimensional array.)
<pre>string strFirstName;
string strLastName ;
strFirstName = "Allison";
strLastName = "Bermejo";</pre>
1l5chxnpeed9yvukijvk1ohfjhb28ig
User:Foxall/14
2
2148
39251
5609
2026-04-13T06:03:35Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39251
wikitext
text/x-wiki
== Hour 14. Making Decisions in C# Code ==
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods," you learned how to separate code into multiple methods to be called in any order required. But if you had to separate each small code routine into its own method, your projects would quickly become unmanageable. Instead of creating numerous methods, you can use decision-making techniques to execute or omit specific lines of code within a single method. Decision-making constructs or coding structures allow you to execute (or omit) code based on the current situation, such as the value of a variable. C# includes two constructs that allow you to make any type of branching decision you can think of: if…else and switch.
In this hour, you'll learn how to use the decision constructs provided by C# to perform robust yet efficient decisions in C# code. In addition, you'll learn how to use the goto statement to redirect code. You'll probably create decision constructs in every application you build, so the quicker you master these skills, the easier it will be to create robust applications.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14lev1sec1.htm#ch14lev1sec1 Making decisions using if statements]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14lev1sec1.htm#ch14lev2sec1 Expanding the capability of if statements using else]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14lev1sec2.htm#ch14lev1sec2 Evaluating an expression for multiple values using the switch statement]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch14lev1sec3.htm#ch14lev1sec3 Redirecting code flow using goto]
----
=== Making Decisions Using if Statements ===
By far the most common decision-making construct used in programming is the if construct. A simple if construct looks like this:
<pre>if (expression)
... statement to execute when expression is true;
</pre>
The if construct uses Boolean logic, as discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13.htm#ch13 Hour 13], "Performing Arithmetic, String Manipulation, and Date/Time Adjustments," to evaluate an expression to either true or false. The expression may be simple (<code>if (x == 6)</code>) or complicated (<code>if (x==6 && y>10)</code>). If the expression evaluates to true, the statement or block of statements (if enclosed in braces) gets executed. If the expression evaluates to false, C# doesn't execute the statement or statement block for the if construct.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Remember that compound, also frequently called block statements, can be used anywhere a statement is expected. A compound statement consists of zero or more statements enclosed in braces (<code>{}</code>). Following is an example of the if construct using a block statement:
|}
<pre>if (expression)
{
statement 1 to execute when expression is true;
statement 2 to execute when expression is true;
... statement n to execute when expression is true;
}
</pre>
You're going to create a simple if construct in a C# project. Create a new Windows Application named Decisions. Rename the default form to fclsDecisions, set the Text property of the form to Decisions Example, and update the entry point Main() to reference fclsDecisions instead of Form1.
Add a new text box to the form by double-clicking the Textbox icon in the toolbox. Set the properties of the text box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtInput</code>
|-
| <code>Location</code>
| <code>44,44</code>
|-
| <code>Text</code>
| <code>(make blank)</code>
|}
Next, add a new button to the form by double-clicking the Button icon in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnIsLessThanHundred</code>
|-
| <code>Location</code>
| <code>156,42</code>
|-
| <code>Size</code>
| <code>100,23</code>
|-
| <code>Text</code>
| <code>Is text < 100?</code>
|}
Your form should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#ch14fig01 Figure 14.1].
<div style="text-align: center;">Figure 14.1. You'll use the if statement to determine whether the value of the text entered into the text box is less than 100.
[[Image:14fig01.jpg|500px|graphics/14fig01.jpg]]
</div>
You're now going to add code to the button's Click event. This code will use a simple if construct and the int.Parse() method. The int.Parse() method is used to convert text into its numeric equivalent, and you'll use it to convert the text in txtInput into an integer. The if statement will then determine whether the number entered into the text box is less than 100. Double-click the button now to access its Click event, and enter the following code:
<pre>if (int.Parse(txtInput.Text)< 100 )
MessageBox.Show("The text entered is less than 100.");
</pre>
This code is simple when examined one statement at a time. Look closely at the first statement and recall that a simple if statement looks like this:
<pre>if (expression)
statement; </pre>
In the code you entered, expression is
<pre>int.Parse(txtInput.Text)< 100
</pre>
What you are doing is asking C# to evaluate whether the parsed integer is less than 100. If it is, the evaluation returns true. If the value is greater than or equal to 100, the expression returns false. If the evaluation returns true, execution proceeds with the line immediately following the if statement and a message is displayed. If the evaluation returns false, the line statement (or block of statements) following the if statement doesn't execute and no message is displayed.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If the user leaves the text box empty or enters a string, an exception will be thrown. Therefore, you'd normally implement exception handling around this type of code. You'll learn about exception handling in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch16.htm#ch16 Hour 16], "Debugging Your Code."
|}
Executing Code When Expression Is False
If you want to execute some code when expression evaluates to false, include the optional else keyword, like this:
<pre>if (expression)
statement to execute when expression is true;
else
statement to execute when expression is false;
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you want to execute code only when expression equates to false, not when true, use the not-equal operator (<code>!=</code>) in the expression. Refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13.htm#ch13 Hour 13] for more information on Boolean logic.
|}
By including an else clause, you can have one or more statements execute when expression is true and other statements execute when the expression is false. In the example you've built, if a user enters a number less than 100, the user will get a message. However, if the number is greater than or equal to 100, the user receives no feedback. Modify your code to look like the following, which ensures that the user always gets a message:
<pre>if (int.Parse(txtInput.Text)< 100 )
MessageBox.Show("The text entered is less than 100.");
else
MessageBox.Show("The text entered is greater than or equal to 100.");
</pre>
Now, if the user enters a number less than 100, the message <code>The text entered is less than 100</code> is displayed, but nothing more. When C# encounters the else statement, it ignores the statement(s) associated with the else statement. The statements for the else condition execute only when expression is false. Likewise, if the user enters text that is greater than or equal to 100, the message <code>The text entered is greater than or equal to 100</code> is displayed, but nothing more; when expression evaluates to false, execution immediately jumps to the else statement.
Click Save All on the toolbar to save your work and then press F5 to run the project. Enter a number into the text box and click the button. A message box appears, telling you whether the number you entered is less than or greater than 100 (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#ch14fig02 Figure 14.2]).
<div style="text-align: center;">Figure 14.2. As implied with this message box, if gives you great flexibility in making decisions.
[[Image:14fig02.jpg|301px|graphics/14fig02.jpg]]
</div>
Feel free to enter other numbers and click the button as often as you like. When you're satisfied that the code is working, choose Stop Debugging from the Debug menu.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Get comfortable with if; chances are you'll include at least one in every project you create.
|}
Nesting if Constructs
As mentioned earlier, you can nest if statements to further refine your decision making. The format you use can be something like the following:
<pre>if ( expression1 )
if ( expression2 )
...
else
...
else
...
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Evaluating an Expression for Multiple Values Using switch
At times, the if construct isn't capable of handling a decision situation without a lot of extra work. One such situation is when you need to perform different actions based on numerous possible values of an expression, not just true or false. For instance, suppose you wanted to perform actions based on a user's profession. The following shows what you might create using if:
<pre>if (strProfession =="programmer")
...
else if (strProfession =="teacher")
...
else if (strProfession =="accountant")
...
else
...
</pre>
As you can see, this structure can be a bit hard to read. If the number of supported professions increases, this type of construction will get harder to read and debug. In addition, executing many if statements like this is rather inefficient from a processing standpoint.
The important thing to realize here is that each else…if is really evaluating the same expression (strProfession) but considering different values for the expression. C# includes a much better decision construct for evaluating a single expression for multiple possible values: switch.
A switch construct looks like the following:
<pre>switch (expression)
{
case value1:
...
jump-statement
default:
...
jump-statement
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| default is used to define code that executes only when expression doesn't evaluate to any of the values in the case statements. Use of default is optional.
|}
Here's the Profession example shown previously, but this time switch is used:
<pre>switch (strProfession)
{
case "teacher" :
MessageBox.Show("You educate our young");
break;
case "programmer":
MessageBox.Show("You are most likely a geek");
break;
case "accountant":
MessageBox.Show("You are a bean counter");
break;
default:
MessageBox.Show("Profession currently not supported in switch statement");
break;
}
</pre>
The flow of the switch statement is as follows: When the case expression is matched, the code statement or statements within the case are executed. This must be followed by a jump-statement, such as break, to transfer control out of the case body.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you create a case construct but fail to put code statements or a jump-statement within the case, execution will fall through to the next case statement, even if the expression doesn't match.
|}
The switch makes decisions much easier to follow. Again, the key with switch is that it's used to evaluate a single expression for more than one possible value.
Building a switch Example
You're now going to build a project that uses expression evaluation in a switch construct. This simple application will display a list of animals in a combo box to the user. When the user clicks a button, the application will display the number of legs of the animal in the list (if an animal is selected). Create a new Windows Application named Switch Example. Rename the default form to flcsSwitchExample, set the form's Text property to Switch Example, and update the entry point in procedure Main() to reference flcsSwitchExample instead of Form1.
Next, add a new combo box to the form by double-clicking the ComboBox item on the toolbox. Set the combo box's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>cboAnimals</code>
|-
| <code>Location</code>
| <code>80,100</code>
|-
| <code>Text</code>
| <code>(make blank)</code>
|}
Next, you'll add some items to the list. Click the Items property of the combo box, and then click the Build button that appears in the property to access the String Collection Editor for the combo box. Enter the text as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#ch14fig03 Figure 14.3]; be sure to press Enter at the end of each list item to make the next item appear on its own line.
<div style="text-align: center;">Figure 14.3. Each line you enter here becomes an item in the combo box at runtime.
[[Image:14fig03.jpg|437px|graphics/14fig03.jpg]]
</div>
Next you'll add a Button control. When the button is clicked, a <code>switch</code> construct will be used to determine which animal the user has selected and to tell the user how many legs the selected animal has. Add a new button to the form by double-clicking the Button tool in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowLegs</code>
|-
| <code>Location</code>
| <code>102,140</code>
|-
| <code>Text</code>
| <code>Show Legs</code>
|}
Your form should now look like the one in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#ch14fig04 Figure 14.4]. Click Save All on the toolbar to save your work before continuing.
<div style="text-align: center;">Figure 14.4. This example uses only a combo box and a button control.
[[Image:14fig04.jpg|314px|graphics/14fig04.jpg]]
</div>
All that's left to do is add the code. Double-click the Button control to access its Click event, and then enter the following code:
<pre>switch (cboAnimals.Text)
{
case "Bird":
MessageBox.Show("The animal has 2 legs.");
break;
case "Dog":
// Notice there is no code here to execute.
case "Cat":
MessageBox.Show("The animal has 4 legs.");
break;
case "Snake":
MessageBox.Show("The animal has no legs.");
break;
case "Centipede":
MessageBox.Show("The animal has 100 legs.");
break;
default:
MessageBox.Show("You did not select from the list!");
break;
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Here's what's happening: The switch construct compares the content of the cboAnimals combo box to a set of predetermined values. Each case statement is evaluated in the order in which it appears in the list. Therefore, the expression is first compared to "Bird." If the content of the combo box is Bird, the MessageBox.Show() method immediately following the case statement is called, followed by the break statement, which transfers control outside of the switch construct. If the combo box doesn't contain Bird, C# looks to see if the content is "Dog," and so on. Notice that the Dog case contains no code, therefore the execution of the code in the following case (Cat) is executed if the text Dog was selected (this is known as execution falling through). In this situation, you end up with the correct output. However, what happens if you move the Snake case in front of Cat? You'd end up telling the user that the dog has no legs! When using this technique, you must be careful that all situations will produce desired behavior.
|}
Each successive case statement is evaluated in the same way. If no matches are found for any of the case statements, the MessageBox.Show() method in the default statement is called. If there were no matches and no default statement, no code would execute.
As you can see, adding a new animal to the list can be as simple as adding a case statement.
Press F5 to run your project now and give it a try. Select an animal from the list and click the button. Try clearing the contents of the combo box and clicking the button. When you're finished, choose Stop Debugging from the Debug menu to stop the project and click Save All on the toolbar.
Branching Within Code Using goto
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Decision structures are used to selectively execute code. When a decision statement is encountered, C# evaluates an expression and diverts code according to the result. You don't have to use a decision structure to divert code, however, because C# includes a statement that can be used to jump code execution to a predetermined location within the current procedure: the goto statement. Before I talk about how to use goto, I want to say that under most circumstances, it's considered bad coding practice to use a goto. Code that's heavily laden with gotos is difficult to read and debug because the execution path is so convoluted. Such code is often called spaghetti code, and should be avoided at all costs. I'd say that in 90% of the situations in which goto is used, a better approach to the problem exists, and I'll show an example of just such a case shortly. Nevertheless, goto, like all other statements, is a tool. Although it's not needed as often as some of the other C# statements are, it's still a useful tool to have at your disposal�when used judiciously.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| To jump to a specific location in code, you must first define the jump location using a code label. A code label is not the same as a Label control that you place on a form. You create a code label by positioning the cursor on a new line in a method, typing in a name for the label followed by a colon, and pressing Enter. Code labels can't contain spaces and they can't be a C# reserved word. For instance, you can't create a code label called try, because try is a reserved word in C#. However, you could create a label called TryThis, because TryThis isn't a reserved word. Code labels act as pointers that you can jump to using goto. The following shows an example using goto to jump code execution to a label.
|}
<pre>private void btnGoto_Click(object sender, System.EventArgs e)
{
long lngCounter = 0;
IncrementCounter:
lngCounter++;
if (lngCounter < 5000) goto IncrementCounter;
}
</pre>
This code does the following:
* Dimensions a long variable called lngCounter.
* Sets the new variable to 0.
* Defines a code label titled IncrementCounter. One or more goto statements can be used to jump code execution to this label at any time.
* Increments lngCounter by 1.
* Uses an if statement to determine if lngCounter has exceeded 5000. If it hasn't, a goto statement forces code execution back to the IncrementCounter label, where lngCounter is incremented and tested again, creating a loop.
This code works, and you're welcome to try it. However, this is terrible code. Remember how I said that the use of a goto can often be replaced by a better coding approach? In this case, C# has specific looping constructs that you'll learn about in the next hour. These looping constructs are far superior to building your own loop under most conditions, so you should avoid building a loop using a goto statement. In fact, one of the biggest misuses of goto is using it in place of one of C#'s internal looping constructs. In case you're interested, here's the loop that would replace the use of goto in this example:
<pre>for(long lngCounter = 0; lngCounter<=5000; lngCounter++)
...
</pre>
This discussion may leave you wondering why you would ever use goto. One situation in which I commonly use goto statements is to create single exit points. As you know, you can force execution to leave a method at any time using return. Often, clean-up code is required before a method exits. In a long method, you may have many return statements. However, such a method can be a problem to debug because clean-up code may not be run under all circumstances. Because all methods have a single entry point, it makes sense to give them a single exit point. With a single exit point, you use a goto statement to go to the exit point, rather than use a return statement. The following procedure illustrates using goto to create a single exit point:
<pre>private void btnGoto_Click(object sender, System.EventArgs e)
{
...
...
// If it is necessary to exit the code, perform a goto to
// the PROC_EXIT label, rather than using an Exit statement.
PROC_EXIT:
...
return;
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
In this hour you learned how to use C#'s decision constructs to make decisions in C# code. You learned how to use if statements to execute code when an expression evaluates to true and to use else to run code when the expression evaluates to false. For more complicated decisions, you learned how to use else…if to add further comparisons to the decision construct and nest if structures for more flexibility.
In addition to if, you learned how to use switch to create powerful decision constructs to evaluate a single expression for many possible values. You learned how you can check for multiple possible values using a fall through case statement. Finally, you learned how to use goto to jump to any predefined position in code.
Decision-making constructs are often the backbone of applications. Without the capability to run specific sets of code based on fluctuating situations, your code would be very linear and hence very limited. Get comfortable with the decision constructs and make a conscious effort to use the best construct for any given situation. The better you are at writing decision constructs, the faster you'll be able to product solid and understandable code.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#qad1e45927 Q1:]'''
| What if I want to execute code only when an expression in an if statement is false, not true? Do I need to place the code in an else clause, and no code after the if?
|-
| align="right" | ''' A1: '''
| This is where Boolean logic helps. What you need to do is make the expression evaluate to true for the code you want to run. This is accomplished using the not operator (!) in the expression, like this:
<pre>if (!expression)<br />. . .<br /></pre>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/14.htm#qad1e45943 Q2:]'''
| How important is the order in which case statements are created?
|-
| align="right" | ''' A2: '''
| This all depends on the situation. In the example given in the text in which the selected animal was considered and the number of legs it has was displayed, the order of the Dog case was important. If all case statements contained code, the order has no effect.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans01 1:]'''
| Which decision construct should you use to evaluate a single expression to either true or false?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans02 2:]'''
| Evaluating expressions to true or false for both types of decision constructs is accomplished using ________ logic.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans03 3:]'''
| If you want code to execute when the expression of an if statement evaluates to false, include an ____ clause.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans04 4:]'''
| Which decision construct should you use when evaluating the result of an expression that may equate to one of many possible values?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans05 5:]'''
| Is it possible that more than one case statement may have its code execute?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans06 6:]'''
| True or False: You can use goto to jump code execution to a different method.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec14.htm#ch14ans07 7:]'''
| To use goto to jump execution to a new location in code, what must you create as a pointer to jump to?
|}
Exercises
# Create a project that allows the user to enter text into a text box. Use an if construct to determine whether the text entered is Circle, Triangle, Square, or Pentagon, and display the number of sides the entered shape has. If the text doesn't match one of these shapes, let the users know that they must enter a shape.
# Rewrite the following code using only an if structure; the new code should not contain a goto.
<pre>...
if (!blnAddToAge) goto SkipAddToAge;
lngAge++;
SkipAddToAge:
...</pre>
0dybeg787o3xeo6ibwwk16j74sd8dv8
User:Foxall/15
2
2149
39252
5610
2026-04-13T06:03:36Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39252
wikitext
text/x-wiki
== Hour 15. Looping for Efficiency ==
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As you develop your C# programs, you'll encounter situations in which you'll need to execute the same code statement or statements repeatedly. Often, you'll need to execute these statements a specific number of times, but you may need to execute them as long as a certain condition persists (an expression is true) or until a condition occurs (an expression becomes true). C# includes constructs that enable you to easily define and execute these repetitive code routines: loops. This hour shows you how to use the two major looping constructs to make your code smaller, faster, and more efficient.
|}
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch15lev1sec1.htm#ch15lev1sec1 Looping a specific number of times using for statements]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch15lev1sec2.htm#ch15lev1sec2 Looping an indeterminate number of times using do…while and while statements]
----
=== Looping a Specific Number of Times Using for Statements ===
The simplest type of loop to create is the for loop, which has been around since the earliest forms of the BASIC language. With a for loop, you instruct C# to begin a loop by starting a counter at a specific value. C# then executes the code within the loop, increments the counter by a defined incremental value, and repeats the loop until the counter reaches an upper limit you've set. The following is the syntax for the basic for loop:
<pre>for ([initializers]; [expression]; [iterators]) statement </pre> Initiating the Loop Using For
The for statement both sets up and starts the loop. The for statement has the components shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/15.htm#ch15table01 Table 15.1].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 15.1. Components of the for Statement
|-
| Part
| Description
|-
| initializers
| A comma-separated list of expressions or assignment statements to initialize the loop counters.
|-
| expression
| An expression that can be implicitly converted to boolean. The expression is used to test the loop-termination criteria.
|-
| iterators
| Expression statement(s) to increment or decrement the loop counters.
|-
| statement
| The embedded statement(s) to execute.
|}
The following is a simple example of a for loop, followed by an explanation of what it's doing:
<pre>for (int intCounter = 1; intCounter <= 100; intCounter++)
Debug.WriteLine(intCounter);
</pre>
This for statement initializes an Integer named intCounter at 1; the condition intCounter <= 100 is tested and returns true; therefore, the statement debug.WriteLine(lngCounter) is executed. After the statement(s) are executed, the variable intCounter is incremented (intCounter++). This loop would execute 100 times, printing the numbers 1 through 100 to the Output debug window.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| To use the Debug object, you need to use the System.Diagnostics namespace.
|}
To execute multiple statements within a for loop, braces { } are used; a single line for statements does not require braces. Here is the previous for loop written to execute multiple statements:
<pre>for (int intCounter = 1; intCounter <= 100; intCounter++)
{
Debug.WriteLine(intCounter);
Debug.WriteLine(intCounter-1);
}
</pre> Exiting a for Loop Early
There may be times when you'll want to terminate a for loop before the expression evaluates to true. To exit a for loop at any time, use the break statement.
Building a for Loop Example
You're now going to create a method containing two for loops�one nested within the other. The first loop is going to count from 1 to 100 and set the Width property of a Label control to the current counter value; this will emulate a Windows progress meter. The second loop will be used to slow the execution of the first loop�an old programmer's trick using a for loop.
Create a new Windows Application named ForExample. Set the form's Text to For Statement Example. Add a Label control to the form by double-clicking the Label tool in the toolbox. Set the label's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lblMeter</code>
|-
| <code>BackColor</code>
| (Set to a light blue or any color you like.)
|-
| <code>Location</code>
| <code>100,100</code>
|-
| <code>Text</code>
| (make blank)
|-
| <code>Size</code>
| <code>100,17</code>
|}
Next, add a button to the form by double-clicking the Button item in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnForLoop</code>
|-
| <code>Location</code>
| <code>88,125</code>
|-
| <code>Size</code>
| <code>125,23</code>
|-
| <code>Text</code>
| <code>Run a For Loop</code>
|}
Your form should look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/15.htm#ch15fig01 Figure 15.1].
<div style="text-align: center;">Figure 15.1. This simple project will emulate a progress meter.
[[Image:15fig01.jpg|500px|graphics/15fig01.jpg]]
</div>
All that's left to do is to write the code. Double-click the button to access its Click event and enter the following:
<pre>for (int intLabelWidth=1; intLabelWidth<=100; intLabelWidth++)
{
lblMeter.Width = intLabelWidth;
lblMeter.Refresh();
for (int intPauseCounter=1; intPauseCounter<=600000; intPauseCounter++);
}
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Using a loop to create a delay is actually a very poor and outdated coding technique. Other options can be used for creating a delay, such as calling System.Threading.Thread.Sleep(). This example is designed to illustrate nested loops�which it does, not to show the best way to create a delay.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Remember that C# is case sensitive. (Hint: for, int, and long are all lowercase).
|}
The first line starts the first for loop. It starts by creating and initializing the variable intLabelWidth; next comes an expression used to evaluate the variable, and the third part is the iterator, which increments intLabelWidth by one each time the loop completes.
The first statement within this for loop sets the width of the Label control to the value of intLabelWidth. The next statement calls the Refresh method of the Label control to ensure that it paints itself. Often, painting catches up when the CPU has idle time. Because you want the transition from a small label to a large one to be smooth, you need to make sure the label paints itself after each update to its Width property. After all the statements within the braces execute, intLabelWidth is incremented by one (intLabelWidth++) and the expression is evaluated once more. This means that the code within the loop will execute 100 times.
The next statement starts a second for loop using the intPauseCounter variable, creating and initializing intPauseCounter to 1 and setting the upper limit of the loop to 600,000. Following this for statement is a semicolon(;) with no statement before it. This creates an empty statement. Why is there no code for this for statement of the lngPauseCounter loop? This loop is used simply to create a delay within the processor. Most computers are so fast that if you didn't add a delay here, the first for loop would update the label's width from 1 to 100 so fast that you might not even see it update!
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I wrote this code on a 1.33GHz (1,333MHz) machine; you may have to alter this value if your processor speed is much different. If you have a slower CPU, reduce this value. If you have a much faster processor, increase this value. Wait until you test this code before making changes to the upper limit, however. Again, using another method, such as calling System.Threading.Thread.Sleep(), would allow precise control over the delay, regardless of the speed of the machine.
|}
Click Save All on the toolbar and press F5 to run the project. The label starts with a width of 100. Click the button, and you'll see the label's width change to 1 and then increment to 100. If the speed is too slow or too fast, stop the project and adjust the upper limit of the inner for loop.
If you were to forgo a loop and write each and every line of code necessary to draw the label with a width from 1 to 100, it would take 100 lines of code. Using a simple for loop, you performed the same task in just a few lines. In addition, a for loop allowed you to create a pause during the update.
A for loop is best when you know the number of times you want the loop to execute. This doesn't mean that you have to actually know the number of times you want the loop to execute at design time; it simply means that you must know the number of times you want the loop to execute when you first start the loop. You can use a variable to define any of the arguments of the for loop, as illustrated in the following code:
<pre>int intUpperLimit=100;
for (int intCounter=1; intCounter<=intUpperLimit;intCounter++)
Debug.WriteLine(intCounter);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| One of the keys to writing efficient code is to eliminate redundancy. If you find yourself typing the same (or a similar) line of code repeatedly in the same procedure, chances are it's a good candidate for a loop (and you may even want to place the duplicate code in its own method).
|}
Using do…while to Loop an Indeterminate Number of Times
In some situations, you won't know the exact number of times a loop needs to be performed�not even when the loop begins. When you need to create such a loop, using the do…while loop is the best solution.
The do…while comes in a number of flavors. Its most basic form has the following syntax:
<pre>do statement while (expression); </pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The following is used to execute multiple statements:
<pre>do<br />{<br />[Statements]<br />} while (expression); </pre>
|}
Ending a do…while
A do…while without some sort of exit mechanism or defined condition is an endless loop. In its most basic form, nothing is present to tell the loop when to stop looping. At times you may need an endless loop (game programming is an example), but more often, you'll need to exit the loop when a certain condition is met. Like the for loop, you can use the break statement to exit a do…while loop at any time. For example, you could expand the do…while we're discussing to include a break statement like the following:
<pre>do
{
[Statements]
if (expression)
break;
} while (x==x); </pre>
In this code, the loop would execute until expression evaluates to true. Generally, the expression is based on a variable that's modified somewhere within the loop. Obviously, if the expression never changes, the loop never ends.
The second flavor of the while loop is the while…do loop. The following is a simple while…do loop:
<pre>while (expression) statement </pre>
As long as expression evaluates to true, the loop continues to occur. If expression evaluates to false when the loop first starts, the code between the statement(s) doesn't execute�not even once.
The difference between the do…while and the while…do loops is that the code statements within the do…while loop always execute at least once; expression isn't evaluated until the loop has completed its first cycle. Therefore, such a loop executes at least once, regardless of the value of expression. The while loop evaluates the expression first; therefore, the statements associated with it may not execute at all.
Creating a do…while Example
You're now going to create an example using a do…while loop that updates a label to once again simulate a progress meter. This loop performs the same purpose as the for loop you created in the previous example, but its structure is quite different.
If your for example is currently running, choose Stop Debugging from the Debug menu. Add another button to the formand set the new button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnDoLoop</code>
|-
| <code>Location</code>
| <code>88,160</code>
|-
| <code>Size</code>
| <code>125,23</code>
|-
| <code>Text</code>
| <code>Run a Do Loop</code>
|}
Your form should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/15.htm#ch15fig02 Figure 15.2].
<div style="text-align: center;">Figure 15.2. You'll use the same form for both loop examples.
[[Image:15fig02.jpg|500px|graphics/15fig02.jpg]]
</div>
Double-click the new button to access its Click event and then enter the following code:
<pre>int intLabelWidth=1;
while (intLabelWidth != 100)
{
lblMeter.Width = intLabelWidth;
lblMeter.Refresh();
intLabelWidth++; // Increment by one.
for (int intPauseCounter=1; intPauseCounter<=600000; intPauseCounter++);
}
</pre>
Again, this code is more easily understood when broken down, as shown in the following list:
* The first line creates the intLabelWidth variables and sets it to 1.
* A while statement is used to start a loop. This loop will execute until intLabelWidth has the value 100. It can also be read as "the statements will execute while intLabelWidth does not equal 100."
* The Label's Width property is set to the value of intLabelWidth.
* The Label is forced to refresh its appearance.
* The intLabelWidth variable is incremented by 1.
* A for loop is used to slow down the procedure, just as it was in the previous example. Again, this is just to illustrate nested loops. Calling System.Threading.Thread.Sleep() would be a better way to create a delay.
* Click Save All on the toolbar to save the project, and then press F5 to run it. Click the Run a Do Loop button to see the progress meter set itself to 1 pixel and then update itself by 1 until it reaches 100 pixels.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| I wanted to show you how both types of loops could be used to accomplish the same task. In this example, however, the for loop is clearly the best approach because you know the starting values and the number of times to loop when the loop starts.
|}
You've now seen how to perform the same function with two entirely different coding techniques. This is fairly common when creating programs; usually, multiple ways exist to approach a solution to a given problem. Simply being aware of your options makes writing code that much easier. When you hear of people optimizing their code, they're usually looking for a different, faster approach to a problem they've already solved.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
Looping is a powerful technique that allows you to write tighter code. Tighter code is code consisting of fewer lines, is more efficient, and is usually�but not always�more readable. In this hour, you learned to write for loops for situations in which you know the precise number of times you want a loop executed. Remember, it's not necessary to know the number of iterations at design time, but you must know the number at runtime to use a for loop. You learned how to use iterators to increment the counter of a for loop, and even how to exit a loop prematurely using break.
In this hour, you also learned how to use the very powerful do…while loop. The do…while loop enables you to create very flexible loops that can handle almost any looping scenario. You learned how evaluating expression in a do…while loop makes the loop behave differently than when evaluating the expression in a while…do loop. If a for loop can't do the job, some form of the do…while or while…do loop will.
In addition to learning the specifics about loops, you've seen firsthand how multiple solutions to a problem can exist. Often, one approach is clearly superior to all other approaches, although you may not always find it. Other times, one approach may be only marginally superior, or multiple approaches may all be equally applicable. Expert programmers are able to consistently find the best approaches to any given problem. With time, you'll be able to do the same.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/15.htm#qad1e47323 Q1:]'''
| Are there any specific cases in which one loop is appropriate over another?
|-
| align="right" | ''' A1: '''
| Usually, when you have to walk an index or sequential set of elements (such as referencing all elements in an array), the for loop is the best choice.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/15.htm#qad1e47333 Q2:]'''
| Should I be concerned about the performance differences between the two types of loops?
|-
| align="right" | ''' A2: '''
| With today's fast processors, chances are good that the performance difference between the two loop types in any given situation will be overshadowed by the readability and functionality of the best choice of loop. If you have a situation in which performance is critical, write the loop using all the ways you can think of, benchmark the results, and choose the fastest loop.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec15.htm#ch15ans01 1:]'''
| True or False: You have to know the start and end values of a for loop at design time to use this type of loop.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec15.htm#ch15ans02 2:]'''
| Is it possible to nest loops?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec15.htm#ch15ans03 3:]'''
| What type of loop would you most likely need to create if you didn't have any idea how many times the loop would need to occur?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec15.htm#ch15ans04 4:]'''
| If you evaluate the expression in a do…while on the while statement, is it possible that the code within the loop may never execute?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec15.htm#ch15ans05 5:]'''
| What statement do you use to terminate a do…while without evaluating the expression on the do or while statements?
|}
Exercises
# The status meter example using do…while has a deliberate "bug." The meter will display only to 99 (the label's width will adjust only to 99 pixels, not 100). The problem has to do with how the expression is evaluated. Find and correct this problem.
# Use two for loops nested within each other to size a label in two dimensions. Have the outer loop change the Width of the label from 1 to 100 and have the inner loop change the Height from 1 to 100. Don't be surprised by the result�the end result is rather odd.
c3zwvjtr1nqk5uznqnrbwfb9awio8f8
User:Foxall/16
2
2150
39253
5611
2026-04-13T06:03:36Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39253
wikitext
text/x-wiki
== Hour 16. Debugging Your Code ==
No one writes perfect code. You're most certainly familiar with those problems that prevent code from executing properly�they're called bugs. Being new to C#, your code will probably contain a fair number of bugs. As you gain proficiency, the number of bugs in your code will decrease, but they will never disappear entirely. Debugging is a skill and an art. This book can't teach you how to debug every possible build or runtime error you may encounter; however, in this hour you will learn the basic skills necessary to trace and correct most bugs in your code.
The highlights of this hour include the following:
* Adding comments to your code
* Identifying the two basic types of errors
* Working with break points
* Using the Command window
* Using the Output window
* Creating a structured error handler
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Task List window is useful for addressing build errors in code. However, because its use goes beyond this simple debugging application, I discuss the Task List in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods."
|}
Before proceeding, create a new Windows Application project named Debugging Example. Change the name of the default form to fclsDebuggingExample, set its Text property to Debugging Example, and change the Main() entry point of the project to reference fclsDebuggingExample instead of Form1.
Add a new text box to the form by double-clicking the TextBox item in the toolbox. Set the text box's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>txtInput</code>
|-
| <code>Location</code>
| <code>88,112</code>
|-
| <code>Size</code>
| <code>120,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Next, add a new button to the form by double-clicking the Button item in the toolbox, and then set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnPerformDivision</code>
|-
| <code>Location</code>
| <code>96,144</code>
|-
| <code>Size</code>
| <code>104,23</code>
|-
| <code>Text</code>
| <code>Perform Division</code>
|}
Your form should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig01 Figure 16.1].
<div style="text-align: center;">Figure 16.1. This simple interface will help teach you debugging techniques.
[[Image:16fig01.jpg|500px|graphics/16fig01.jpg]]
</div>
All this little project will do is divide 100 by whatever is entered into the text box. As you write the code to accomplish this, various bugs will be introduced (on purpose), and you'll learn to correct them. Save your project now by clicking the Save All button on the toolbar.
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Adding Comments to Your Code
One of the simplest things you can do to reduce bugs from the start�and make tracking down existing bugs easier�is to add comments to your code. A code comment is simply a line of text that C# knows isn't actual code. Comment lines are stripped from the code when the project is compiled to create a distributable component, so comments don't affect performance. C#'s code window shows comments as green text. This makes it easier to read and understand procedures. You should consider adding comments to the top of each procedure stating the purpose of the procedure. In addition, you should add liberal comments throughout all procedures, detailing what's occurring in the code.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| Comments are meant to be read by humans, not by computers. Strive to make your comments intelligible. Keep in mind that a comment that is hard to understand is not much better than no comment at all. Also, remember that comments serve as a form of documentation. Just as documentation for an application must be clearly written, code comments should also follow good writing principles.
|}
To create a comment, precede the comment text with two forward slash marks (<code>//</code>). For example, a simple comment might look like this:
<pre>// This is a comment because it is preceded with double forward slashes.
</pre>
Comments can also be placed at the end of a line of code, like this:
<pre>int intAge; // Used to store the user's age in years.
</pre>
Everything to the right of and including the double forward slashes in this statement is a comment. C# also supports a second type of comment. This allows for comments to span multiple lines without forcing the developer to add <code>//</code> characters to each line. The comment begins with an open comment mark of a forward slash, followed by an asterisk (<code>/*</code>), and the comment closes with a close mark of an asterisk followed by a forward slash (<code>*/</code>). For example, a comment can look like this:
<pre>/* Chapter 16 in Sams TY C#
focuses on debugging code, a topic
every developer spends a lot of time on. */
</pre>
By adding comments to your code, you don't have to rely on memory to decipher the code's purpose or mechanics. If you've ever had to go back and work with code you haven't looked at in a while, or had to work with someone else's code, you probably already have a great appreciation for comments.
Double-click the button now to access its <code>Click</code> event and add the following two lines of code (comments, actually):
<pre>// This procedure divides 100 by the value entered in
// the text box txtInput.
</pre>
Notice that after you enter the second forward slash, both slashes turn green. Comments, whether single line (<code>//</code>) or multiline (<code>/*</code> comments <code>*/</code>), will be displayed in a green font in Visual Studio.
When creating code comments, strive to do the following:
* Document the purpose of the code (the why, not the how).
* Clearly indicate the thinking and logic behind the code.
* Call attention to important turning points in code.
* Reduce the need for readers to run a simulation of code execution in their heads.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| C# also supports an additional type of comment denoted with three slashes (///). When the C# compiler encounters these comments, it processes them into an XML file. These types of comments are often used to create documentation for code. Creating XML files from comments is beyond the scope of this book, but if these features intrigue you, I highly recommend that you look into it.
|}
Identifying the Two Basic Types of Errors
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Essentially, two types of errors can occur in code: compile errors and runtime errors. A compile error (commonly called a build error) is an error in code that prevents C#'s compiler from being able to process the code. C# won't compile a project that has a build error in it. A method call with incorrect parameters, for example, will generate a build error. Runtime errors are errors that don't occur at compile time but are encountered when the project is being run. Runtime errors are usually a result of trying to perform an invalid operation on a variable.
|}
For example, the following code won't generate a compile error:
<pre>intResult = 10 / intSomeOtherVariable;
</pre>
Under most circumstances, this code won't even generate a runtime error. However, what happens if the value of intSomeOtherVariable is 0? Ten divided by zero is infinity, which won't fit into intResult (intResult is an Integer variable). Attempting to run the code with the variable having a value of 0 causes C# to return a runtime error. Runtime errors are called exceptions, and when an exception is created, it is said to be thrown (that is, C# throws an exception when a runtime error occurs). When an exception is thrown, code execution stops at the offending statement and C# displays an error message. You can prevent C# from stopping execution when an exception is thrown by writing special code to handle the exception (writing error handlers is discussed later in this hour).
Add the following statements to the Click event, right below the two comment lines:
<pre>long lngAnswer;
lngAnswer = 100 / long.Parse(txtInput.Text);
MessageBox.Show("100/" + txtInput.Text + " is " + lngAnswer)
</pre>
The missing semicolon in the MessageBox.Show line is intentional; type in the preceding line of code exactly as it appears. Although you've missed the ending semicolon, C# doesn't return an immediate error. However, notice how C# displays a wavy red line at the end of the statement. Notice the Description in the Task List following an exclamation point and a red, wavy line; C# displays a tip explaining the nature of the error (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig02 Figure 16.2]).
<div style="text-align: center;">Figure 16.2. Using wavy underlines, C# highlights build errors in the code window.
[[Image:16fig02.jpg|500px|graphics/16fig02.jpg]]
</div>
Press F5 to run the project. When you do, C# displays a message that a build error was found and asks you whether you want to continue. Because the code won't run, there's no point in continuing, so click No to return to the code editor. Take a look at the Task List (if it's not displayed, use the View menu to show it). All build errors in the current project appear in the Task List (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig02 Figure 16.2]). To view a particular offending line of code, double-click an item in the Task List.
Build errors are very serious errors in that they prevent code from being compiled; therefore, they completely prevent execution. Build errors must be corrected before you can run the project. Double-click the build error in the Task List to go directly to the error.
Correct the problem by adding a semicolon to the end of the line. After you've made this change, press F5 to run the project. C# no longer returns a build error; you've just successfully debugged a problem! Click the Perform Division button now, and you'll receive another error (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig03 Figure 16.3]).
<div style="text-align: center;">Figure 16.3. A runtime exception halts code execution at the offending line.
[[Image:16fig03.jpg|444px|graphics/16fig03.jpg]]
</div>
This time, the error is a runtime error, or exception. If an exception occurs, you know that the code compiled without a problem because build errors prevent code from compiling and executing. This particular exception is a Format exception. Format exceptions generally occur when you attempt to perform a method using a variable, and the variable is of an incompatible data type for the specified operation. Click Break to view the offending line of code. C# denotes the offending statement with a green arrow (the arrow indicates the current statement). At this point, you know that the statement has a "bug," and you know it is related to data typing. Choose Stop Debugging from the Debug menu now to stop the running project and return to the code editor.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using C#'s Debugging Tools
C# includes a number of debugging tools to help you track down and eliminate bugs. In this section, you'll learn how to use break points, the Command window, and the Output window�three tools that form the foundation of any debugging arsenal.
Working with Break Points
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| The same way an exception halts the execution of a method, you can deliberately stop execution at any statement of code by creating a break point. When C# encounters a break point while executing code, execution is halted at the break statement, prior to it being executed. Break points enable you to query or change the value of variables at a specific instance in time, and they let you step through code execution one line at a time.
|}
You're going to create a break point to help troubleshoot the exception in your MessageBox.Show() statement.
Adding a break point is simple. Just click in the gray area to the left of the statement at which you want to break code execution. When you do so, C# displays a red circle, denoting a break point at that statement (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig04 Figure 16.4]). To clear a break point, click the red circle.
<div style="text-align: center;">Figure 16.4. Break points give you control over code execution.
[[Image:16fig04.jpg|500px|graphics/16fig04.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Break points are saved with the project. This makes it much easier to suspend a debugging session; you don't have to reset all your break points each time you open the project.
|}
Set a new break point on the statement shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig04 Figure 16.4] (the statement where <code>lngAnswer</code> is set). Do this by clicking in the gray area to the left of the statement. After you've set the break point, press F5 to run the program. Again, click the button. When C# encounters the break point, code execution is halted and the procedure with the break point is shown. In addition, the cursor is conveniently placed at the statement with the current break point. Notice the yellow arrow overlaying the red circle of the break point (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig05 Figure 16.5]). This yellow arrow marks the next statement to be executed. It just so happens that the statement has a break point, so the yellow arrow appears over the red circle (the yellow arrow won't always be over a red circle, but it will always appear in the gray area aligned with the next statement to execute).
<div style="text-align: center;">Figure 16.5. A yellow arrow denotes the next statement to be executed.
[[Image:16fig05.jpg|500px|graphics/16fig05.jpg]]
</div>
When code execution is halted at a break point, you can do a number of things. See [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16table01 Table 16.1] for a list of the most common actions. For now, press F5 to continue program execution. Again, you get the Format exception. Click Break to access the code procedure with the error.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 16.1. Actions That Can Be Taken at a Break Point
|-
| valign="middle" | Action
| valign="middle" | Keystroke
| valign="middle" | Description
|-
| Continue Code Execution
| F5
| Continues execution at the current break statement.
|-
| Step Into
| F11
| Executes the statement at the break point and then stops at the next statement. If the current statement is a function call, F11 enters the function and stops at the first statement in the function.
|-
| Step Over
| F10
| Executes the statement at the break point and then stops at the next statement. If the current statement is a function call, the function is run in its entirety; then execution stops at the statement following the function call.
|-
| Step Out
| Shift+F11
| Runs all the statements in the current procedure and halts execution at the statement following the one that called the current procedure.
|}
Using the Command Window
Break points themselves aren't usually sufficient to debug a procedure. In addition to break points, you'll often use the Command window to debug code. The Command window is a Visual Studio IDE window that generally appears only when your project is in Run mode. If the Command window isn't displayed, press Ctrl+Alt+A to display it now (or use the Other Views submenu of the View menu). Using the Command window, you can type in code statements that C# executes immediately. You'll use the Command window now to debug our problem statement example.
Type the following statement into the Command window and press Enter:
<pre>? txtInput.Text
</pre>
Although not intuitive, the <code>?</code> character has been used in programming for many years as a shortcut for the word "print." The statement that you entered simply prints the contents of the Text property of the text box.
Notice how the command window displays <code>""</code> on the line below the statement you entered. This indicates that the text box contains an empty string (also called a zero-length string). The statement throwing the exception is attempting to use the <code>long.Parse()</code> method to convert the contents of the text box to a Long. The <code>long.Parse()</code> method expects data to be passed to it, yet the text box has no data (the Text property is empty). Consequently, a Format exception occurs.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Generally, when you receive a Format exception, you should look at any variables or properties being referenced to ensure that the data they contain is appropriate data for the statement. Often, you'll find that the code is trying to perform an operation that is inappropriate for the data being supplied.
|}
You can do a number of things to prevent this error. The most obvious is to ensure that the text box contains a value before attempting to use the <code>long.Parse()</code> method. You'll do this now. C# doesn't allow you to modify code when in break mode, so choose Stop Debugging from the Debug menu before continuing.
Add the following statement to your method, right above the statement that throws the exception (the one with the break point):
<pre>if (txtInput.Text == "") return;
</pre>
Press F5 to run the project once more, and then click the button. This time, C# won't throw an exception, and it won't halt execution at your break point; the test you just created causes code execution to leave the procedure before the statement with the break point is reached.
Type your name into the text box and click the button again. Now that the text box is no longer empty, execution passes the statement with the exit test and stops at the break point. Press F5 to continue executing the code, and again you'll receive an exception. Click Break to enter Break mode, and type the following into the Command window (be sure to press Enter when done):
<pre>? txtInput.Text
</pre>
The Command window prints your name.
Well, you eliminated the problem of not supplying any data to the <code>long.Parse()</code> method, but something else is wrong. Press F5 to continue executing the code and take a closer look at the exception text. The last statement in the text says <code>Input string was not in a correct format</code>. It apparently still doesn't like what's being passed to the <code>long.Parse()</code> method. By now, it may have occurred to you that no logical way exists to convert alphanumeric text to a number; <code>long.Parse()</code> needs a number to work with. You can easily test this by entering a number into the text box. Do this now by clicking Break, choosing Stop Debugging from the Debug menu, and pressing F5 to run the project. Enter a number into the text box and click the button. Code execution again stops at the break point. Press F11 to execute the statement. No errors this time! Press F5 to continue execution and C# will display the message box (finally). Click OK to dismiss the message box and then close the form to stop the project.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| You can use the Command window to change the value of a variable in addition to printing the value.
|}
Because the <code>long.Parse()</code> method expects a number, yet the text box contains no intrinsic way to force numeric input, you have to accommodate this situation in your code. You will learn how to deal with exceptions later on in this chapter using a catch statement.
Using the Output Window
The Output window (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig06 Figure 16.6]) is used by C# to display various status messages and build errors. The most useful feature of the Output window, for general use, is the capability to send data to it from a running application. This is especially handy when debugging applications.
<div style="text-align: center;">Figure 16.6. The Output window displays a lot of useful information�if you know what you're looking for.
[[Image:16fig06.gif|500px|graphics/16fig06.gof]]
</div>
You've already used the Output window in previous hours, but you might not have seriously considered its application as related to debugging. As you can see from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig06 Figure 16.6], some data sent to the Output window by C# isn't that intuitive�in fact, you can ignore much of what is automatically sent to the Output window. What you'll want to use the Output window for is printing data for debugging (as you have done and will do throughout this book). Therefore, it's no coincidence that printing to the Output window is accomplished via the Debug object.
To print data to the Output window, use the WriteLine() method of the Debug object, like this:
<pre>Debug.WriteLine("Results = " + lngResults);
</pre>
The Debug object is a member of the <code>System.Diagnostics</code> namespace. Therefore, to define the scope for <code>Debug.WriteLine</code> statements, you will need to add using System.Diagnostics to the header section of your class (along with the other using statements C# creates automatically.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you do not add using System.Diagnostics to the top of your code file, you can still access Debug.WriteLine() by writing out the full expression: System.Diagnostics.Debug.WriteLine().
|}
Whatever you place within the parentheses of the <code>WriteLine()</code> method is what is printed to the Output window. Note that you can print literal text and numbers, variables, or expressions. <code>WriteLine()</code> is most useful in cases where you want to know the value of a variable, but you don't want to halt code execution using a break point. For instance, suppose you have a number of statements that manipulate a variable. You can sprinkle <code>WriteLine()</code> statements into the code to print the variable's contents at strategic points. When you do this, you'll want to print some text along with the variable's value so that the output makes sense to you. For example:
<pre>Debug.WriteLine("Results of area calculation = " + sngArea);
</pre>
You can also use <code>WriteLine()</code> to create checkpoints in your code, like this:
<pre>Debug.WriteLine("Passed Checkpoint 1");
// Execute statement here
Debug.WriteLine("Passed Checkpoint 4");
// Execute another statement here
Debug.WriteLine("Passed Checkpoint 3");
</pre>
Many creative uses exist for the Output window. Just remember that the Output window isn't available to a compiled component; calls to the Debug object are ignored by the compiler when creating distributable components.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Writing an Error Handler Using '''<code>try...catch...finally</code>'''
It's very useful to have C# halt execution when an exception occurs. When the code is halted while running with the IDE, you receive an error message and you're shown the offending line of code. However, when your project is run as a compiled program, unhandled exceptions will cause the program to terminate (crash to the desktop). This is one of the most undesirable things an application can do. Fortunately, you can prevent exceptions from stopping code execution (and terminating compiled programs) by writing code specifically designed to deal with exceptions. Exception-handling code is used to instruct C# on how to deal with an exception, rather than relying on C#'s default behavior.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| C# supports structured error handling (a formal way of dealing with errors) in the form of a try block and/or catch block(s) and/or a finally block. Creating structured error-handling code can be a bit confusing at first, and like most coding principles, it is best understood by doing it.
|}
Create a new Windows Application called Structured Error Handling. Change the name of the default form to flcsErrorHandlingExample, set its Text property to Try…Catch…Finally, and change the Main() entry point of the project to reference fclsErrorHandlingExample instead of Form1. Next, add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnCatchException</code>
|-
| <code>Location</code>
| <code>104,128</code>
|-
| <code>Size</code>
| <code>96,23</code>
|-
| <code>Text</code>
| <code>Catch Exception</code>
|}
Double-click the button and add the following code.
<pre>try
{
Debug.WriteLine("Try");
}
catch
{
Debug.WriteLine("Catch");
}
finally
{
Debug.WriteLine("Finally");
}
Debug.WriteLine("Done Trying");
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Remember to add using System.Diagnostics to the top of your class so that you can use the <code>Debug.WriteLine()</code> statement.
|}
As you can see, the <code>try</code>, <code>catch</code>, and <code>finally</code> statements use the braces ({ } ) to enclose statements. The try, catch, and finally structure is used to wrap code that may cause an exception; it provides the means of dealing with thrown exceptions. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16table02 Table 16.2] explains the sections of this structure.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 16.2. try, catch, and finally Structure
|-
| valign="middle" | Part
| valign="middle" | Description
|-
| try
| The try section is where you place code that may cause an exception. You may place all of a procedure's code within the try section, or just a few lines.
|-
| catch
| Code within a general catch clause executes only when an exception occurs; it's the code you write to catch any exception. There may be multiple catch clauses to handle specific exceptions.
|-
| finally
| Code within the finally section occurs when the code within the try and/or code within the catch sections completes. This section is where you place your "clean up" code�code that you want always executed regardless of whether an exception occurs.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Three possible forms of <code>try</code> statements are the following:
* A try block followed by one or more catch blocks.
* A try block followed by a finally block.
* A try block followed by one or more catch blocks, followed by a finally block.
This example is using a try block followed by a catch block, followed by a finally block.
|}
Press F5 to run the project and then click the button. Next, take a look at the contents of the Output window. The Output window should contain the following lines of text:
<pre>Try
Finally
</pre>
<code>Done Trying</code>
Here's what happened:
# The try block begins, and code within the try section executes.
# No exception occurs, so code within the catch section doesn't execute.
# When all statements within the try section finish executing, the code within the finally section executes.
# When all statements within the finally section finish executing, execution jumps to the statement immediately following the try, catch, and finally statements.
Stop the project now by choosing Stop Debugging from the Debug menu. Now that you understand the basic mechanics of the try, catch, and finally structure, you're going to add statements within the structure so that an exception occurs and gets handled.
Change the contents of the code to match this code:
<pre>long lngNumerator = 10;
long lngDenominator = 0;
long lngResult;
try
{
Debug.WriteLine("Try");
lngResult = lngNumerator / lngDenominator;
}
catch
{
Debug.WriteLine("Catch");
}
finally
{
Debug.WriteLine("Finally");
}
Debug.WriteLine("Done Trying");
</pre>
Again, press F5 to run the project; then click the button and take a look at the Output window. This time, the text in the Output window should read
<pre>Try
Catch
Finally
</pre>
<code>Done Trying</code>
Notice that this time the code within the catch section is executed. This is because the statement that sets <code>lngResult</code> causes a DivideByZero exception. Had this statement not been placed within a catch block, C# would have raised the exception and an error dialog box would have appeared. However, because the statement is placed within the try block, the exception is "caught." This means that when the exception occurred, C# directed execution to the catch section (you do not have to use a catch section, in which case caught exceptions are simply ignored). Notice also how the code within the finally section executed after the code within the catch section. Remember, code within the finally section always executes, regardless of whether an exception occurs.
Dealing with an Exception
Catching exceptions so that they don't crash your application is a noble thing to do, but it's only part of the error-handling process. Usually, you'll want to tell the user (in a friendly way) that an exception has occurred. You'll probably also want to tell the user what type of exception occurred. To do this, you have to have a way of knowing what exception was thrown. This is also important if you intend to write code to deal with specific exceptions. The catch statement enables you to specify a variable to hold a reference to an Exception object. Using this Exception object, you can get information about the exception. The following is the syntax used to place the exception in an Exception object:
<pre>catch ( Exception variablename) </pre>
Modify your catch section to match the following:
<pre>catch (Exception objException)
{
Debug.WriteLine("Catch");
MessageBox.Show("An error has occurred: " + objException.Message);
}
</pre>
The Message property of the Exception object contains the text that describes the specific exception that occurs. Run the project, click the Catch Exception button, and C# displays your custom error message (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#ch16fig07 Figure 16.7]).
<div style="text-align: center;">Figure 16.7. Structured exception handling lets you decide what to do when an exception occurs.
[[Image:16fig07.jpg|361px|graphics/16fig07.jpg]]
</div>
Handling an Anticipated Exception
At times, you'll anticipate a specific exception being thrown. For example, you may write code that attempts to open a file when the file does not exist. In such an instance, you'll probably want the program to perform certain actions when this exception is thrown. When you anticipate a specific exception, you can create a catch section designed specifically to deal with that one exception.
Recall from the previous section that you can retrieve information about the current exception using a catch statement such as catch (Exception). By creating a generic Exception variable, this catch statement will catch any and all exceptions thrown by statements within the try section. To catch a specific exception, change the data type of the exception variable to a specific exception type. Remember the code you wrote earlier that caused a Format exception when an attempt was made to pass an empty string to the long.Parse() method? You could have used a try structure to deal with the exception, using code such as this:
<pre>long lngAnswer;
try
{
lngAnswer = 100 / long.Parse(txtInput.Text);
MessageBox.Show("100/" + txtInput.Text + " is " + lngAnswer);
}
catch (System.FormatException)
{
MessageBox.Show("You must enter a number in the text box.");
}
catch
{
MessageBox.Show("Caught an exception that wasn't a format exception.");
}
</pre>
Notice that two catch statements are in this structure. The first catch statement is designed to catch only a Format exception; it won't catch exceptions of any other type. The second catch statement doesn't care what type of exception is thrown; it catches all of them. This second catch statement acts as a "catch all" for any exceptions that aren't Format exceptions, because catch sections are evaluated from top to bottom, much like case statements in the switch structure. You could add more catch sections to catch other specific exceptions if the situation calls for it.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
In this hour, you learned the basics for debugging applications. You learned how adding useful and plentiful comments to your procedures makes debugging easier. However, no matter how good your comments are, you'll still have bugs.
You learned about the two basic types of errors: build errors and runtime errors (exceptions). Build errors are easier to troubleshoot because the compiler tells you exactly what line contains a build error and generally provides useful information about the error. Exceptions, on the other hand, can crash your application if not handled properly. You learned how to track down exceptions using break points, the Command window, and the Output window. Finally, you learned to how to make your applications more robust by creating structured error handlers using the <code>try</code> structure.
No book can teach you everything you need to know to write bug-free code. However, this hour taught you the basic skills to track down and eliminate many types of errors in your programs. As your skills as a programmer improve, so will your debugging abilities.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#qad1e50188 Q1:]'''
| Should I alert the user that an exception has occurred to just let the code keep running?
|-
| align="right" | ''' A1: '''
| If you've written code to handle the specific exception, then there's probably no need to tell the user about it. However, if an exception occurs that the code doesn't know how to address, you should provide the user with the exception information so that he or she can report the problem and you can fix it.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#qad1e50198 Q2:]'''
| Should I comment every statement in my application?
|-
| align="right" | ''' A2: '''
| Probably not. However, you should consider commenting every decision-making and looping construct in your program. Usually, these sections of code are pivotal to the success of the procedure, and it's not always obvious what they do.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/16.htm#qad1e50208 Q3:]'''
| I'm tired of writing out the full qualifier System.Diagnostics.Debug.WriteLine(). Is there anyway to shorten this?
|-
| align="right" | ''' A3: '''
| Yes, by adding a <code>using</code> directive for the System.Diagnostics namespace, you will be able to access its members without having to specify the namespace. This will shorten all your System.Diagnostics.Debug.WriteLine() statements to Debug. WriteLine().
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans01 1:]'''
| What type of error prevents C# from compiling and running code?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans02 2:]'''
| What is the name of a runtime error: an error that usually occurs as a result of attempting to process inappropriate data?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans03 3:]'''
| What character is used to denote a single line comment?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans04 4:]'''
| To halt execution at a specific statement in code, you set a what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans05 5:]'''
| Explain the yellow arrow and red circles that can appear in the gray area in the code editor.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans06 6:]'''
| What IDE window would you use to poll the contents of a variable in Break mode?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec16.htm#ch16ans07 7:]'''
| True or False: You must always specify a catch section in a try structure.
|}
Exercises
# In the code example that sets lngAnswer to the result of a division expression, change lngAnswer from a long to a single (call it sngAnswer). Next, remove the if statement that tests the contents of the text box before performing the division. Do you get the same exceptions that you did when the variable was a long? Why or why not?
# Rewrite the code that sets lngAnswer to the result of a division expression so that the code is wrapped in a try structure. Remove the if statements that perform data validation, and create two catch sections�one for each of the possible exceptions that may be thrown.
ofphabubfxse05fobwm1o0ydu9ze1y6
User:Foxall/20
2
2151
39257
5612
2026-04-13T06:03:38Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39257
wikitext
text/x-wiki
== Hour 20. Controlling Other Applications Using Automation ==
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17.htm#ch17 Hour 17], "Designing Objects Using Classes," you learned how to use classes to create objects. In that hour, I mentioned that objects could be exposed to outside applications�Excel, for example, exposes most of its functionality as a set of objects. The process of using objects from another application is called Automation. The externally accessible objects of an application compose its object model. Using Automation to manipulate a program's object model enables you to reuse components. For instance, you can use Automation with Excel to perform complex mathematical functions using the code that's been written and tested within Excel, rather than having to write and debug the complex code yourself.
|}
Programs that expose objects are called servers, and the programs that consume those objects are called clients. Creating automation servers requires advanced skills, including a very thorough understanding of programming classes. Creating clients to use objects from other applications, on the other hand, is relatively simple. In this hour, you'll learn how to create a client application that uses objects of an external server application.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch20lev1sec1.htm#ch20lev1sec1 Creating a reference to an automation library]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch20lev1sec2.htm#ch20lev1sec2 Creating an instance of an automation server]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch20lev1sec3.htm#ch20lev1sec3 Manipulating the objects of an automation server]
To understand Automation, you're going to build a Microsoft Excel client�a program that automates Excel via Excel's object model.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| This exercise is designed to work with Excel 2000 or Excel XP. If you don't have Excel installed on your computer, you won't be able to complete the exercise.
|}
Create a new Windows Application named Automate Excel. Change the name of the default form to fclsMain, set its Text property to Automate Excel, and then set the entry point in Main() to reference fclsMain instead of Form1. Next, add a button to the form by double-clicking the Button item in the toolbox and set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| Name
| <code>btnAutomateExcel</code>
|-
| Location
| <code>96,128</code>
|-
| Size
| <code>104,23</code>
|-
| Text
| <code>Automate Excel</code>
|}
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating a Reference to an Automation Library
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| To use the objects of a program that supports Automation (a server), you have to reference the program's type library. A program's type library (also called object library) is a file that contains a description of the program's object model. After you've referenced the type library of an automation server (also called a component), you can access the objects of the server as though they were internal C# objects.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| To create a reference to a type library, first display the Add Reference dialog box by choosing Add Reference from the Project menu (do this now). A number of types of components support automation. Of course, .NET is the latest technology, but in the case of Excel, we're interested in the COM components. COM stands for Component Object Model, and it's been the technology for working with objects within windows for many years. Microsoft's .NET platform is designed to replace COM. This isn't going to happen overnight, however; literally thousands of objects are built on COM technology. In fact, all the Microsoft Office products up to and including Office XP are based on COM.
|}
Click the COM tab now to display the available COM components (programs that have a type library) on your computer. Scroll the list and locate the Microsoft Excel X Object Library (where X is the version of Excel installed on your computer). Double-click the Excel item to add it to the list of selected components at the bottom of the Add Reference dialog box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/20.htm#ch20fig01 Figure 20.1]).
<div style="text-align: center;">Figure 20.1. To use an object library, you need to reference it first.
[[Image:20fig01.jpg|500px|graphics/20fig01.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you don't see an entry for Microsoft Excel, you probably don't have Excel installed on your computer; therefore, this code won't work.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Click OK now to add the reference to your project. C# doesn't work directly with COM components. Instead, it interacts through a wrapper, a set of code and objects that works as an intermediary between C# and a COM component. Chances are that your machine doesn't have an existing wrapper for Excel; if this is the case, C# automatically creates the wrapper and references the component.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating an Instance of an Automation Server
Referencing a type library allows C# to integrate the available objects of the type library with its own internal objects. After this is done, you can create object variables based on object types found in the type library. Excel has an object called Application, which acts as the primary object in the Excel object model. In fact, most Office programs have an Application object. How do you know what objects an automation server supports? The only sure way is to consult the documentation of the program in question or use the Object Browser discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], "Understanding Objects and Collections."
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In this example, you'll be using about a half-dozen members of an Excel object. This doesn't even begin to scratch the surface of Excel's object model, and it isn't intended to. What you should learn from this example is the mechanics of working with an automation server. If you choose to automate a program in your own projects, you'll want to consult the program's developer documentation to learn about its object model; you're sure to be surprised at the functionality available to you.
|}
Double-click the button to access its Click event, and then enter the following code, which creates a new Excel Application:
<pre>Excel.Application objExcel = new Excel.Application();
</pre>
Notice that C# included Excel in its IntelliSense drop-down list of available objects. It was able to do this because you referenced Excel's type library. Excel is the reference to the server and Application is an object supported by the server. This statement creates a new Application object based on the Excel object model.
Manipulating the Server
After you have an instance of an object from an automation server, manipulating the server (creating objects, setting properties, calling methods, and so forth) is accomplished by manipulating the object.
Forcing Excel to Show Itself
When Excel is started using Automation, it's loaded but not shown. By remaining hidden, it allows the developer to use its functionality and then close Excel without the user ever knowing what happened. For instance, you could create an instance of an Excel object, perform a complicated formula to obtain a result, close Excel, and return the result to the user�all without the user ever seeing Excel. In this example, you want to see Excel so that you can see what your code is doing. Fortunately, showing Excel couldn't be easier. Add the following statement to make Excel visible:
<pre>objExcel.Visible = true;
</pre> Creating an Excel Workbook and Worksheet
In Excel, a Workbook is the file in which you work and store your data; you can't manipulate data without a Workbook. When you first start Excel from the Start menu, an empty Workbook is created for you. However, when you start Excel via Automation, Excel doesn't create a Workbook; you have to do it yourself. To create a new Workbook, you use the Add method of the Workbooks collection. After the Workbook has been created, you need to set up a worksheet. Enter the following statements:
<pre>//start a new workbook and a worksheet.
Excel.Workbook objBook =
objExcel.Workbooks.Add(System.Reflection.Missing.Value);
Excel.Worksheet objSheet = (Excel.Worksheet)objBook.Worksheets.get_Item(1);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Notice how <code>System.Reflection.Missing.Value</code> is being passed into the Add() method. This is because the Add() method supports a default parameter and C# does not support default parameters. Using the <code>System.Reflection.Missing.Value</code> as the parameter in the Add() method enables the COM's late-binding service to use the default value for the indicated parameter value.
|}
Working with Data in an Excel Workbook
In this section, you're going to manipulate data in the worksheet. The following describes what you'll do:
# Add data to four cells in the worksheet.
# Select the four cells.
# Total the selected cells and place the sum into a fifth cell.
# Bold all five cells.
To manipulate cells in the worksheet, you manipulate the Range object, which is an object property of the Worksheet object. Entering data into a cell involves first selecting a cell and then passing data to it. Selecting a cell is accomplished by setting a range object by calling the get_Range () method of the Worksheet object; the get_Range () method is used to select one or more cells. The get_Range () method accepts a starting column and row and an ending column and row. If you want to select only a single cell, as we do here, you can substitute the ending column and row with System.Reflection.<code>Missing.Value parameter</code>. After a range is set, you pass data to the selected range by using the set_Value() method on the Range object. Sound confusing? Well, it is to some extent. Programs that support Automation are often vast and complex, and programming them is usually far from intuitive.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| <code>range.set_Value(Missing.Value,"75")</code> is used for Excel 10 (Excel XP). Use <code>range.Value = "75"</code> for Excel 9 (Excel 2000).
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| If the program you want to automate has a macro builder (as most Microsoft products do), you can save yourself a lot of time and headache by creating macros of the tasks you want to automate. The "macros" are actually code, and in the case of Microsoft products, they're VBA code.
|}
The following section of code uses the techniques just described to add data to four cells. Enter this code into your procedure:
<pre>Excel.Range objRange;
objRange = objSheet.get_Range("A1", System.Reflection.Missing.Value);
// For EXCEL9 Use objRange.Value method in place of all of the
// objRange.set_Value() statements used in this example. i.e.
// objRange.Value = "75";
objRange.set_Value(System.Reflection.Missing.Value, 75 );
objRange = objSheet.get_Range("B1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 125 );
objRange = objSheet.get_Range("C1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 255 );
objRange = objSheet.get_Range("D1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 295 );
</pre>
The next step is to have Excel total the four cells. You'll do this by using the get_Range() method to select the cell in which to place the total, and then use set_Value() method again to create the total by passing it a formula, rather than a literal value. Enter the following code into your procedure:
<pre>objRange = objSheet.get_Range("E1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, "=SUM(RC[-4]:RC[-1])" );
</pre>
Next, you'll select all five cells and bold them. Enter the following statements to accomplish this:
<pre>objRange = objSheet.get_Range("A1", "E1");
objRange.Font.Bold=true;
</pre>
The last thing you need to do is destroy the object reference by setting the object variable to null. Excel will remain open even though you've destroyed the Automation instance (not all servers will do this). Add this last statement to your procedure:
<pre>objExcel=null;
</pre>
To help you ensure that everything is entered correctly, [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/20.htm#ch20list01 Listing 20.1] shows the procedure in its entirety.
===== Listing 20.1 Code to Automate Excel =====
<pre>private void btnAutomateExcel_Click(object sender, System.EventArgs e)
{
Excel.Application objExcel = new Excel.Application();
objExcel.Visible = true;
//start a new workbook and a worksheet.
Excel.Workbook objBook =
objExcel.Workbooks.Add(System.Reflection.Missing.Value);
Excel.Worksheet objSheet =
Excel.Worksheet)objBook.Worksheets.get_Item(1);
Excel.Range objRange;
objRange = objSheet.get_Range("A1", System.Reflection.Missing.Value);
// For EXCEL9 Use objRange.Value method in place of all of the
// objRange.set_Value() statements used in this example. i.e.
// objRange.Value = "75";
objRange.set_Value(System.Reflection.Missing.Value, 75 );
objRange = objSheet.get_Range("B1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 125 );
objRange = objSheet.get_Range("C1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 255 );
objRange = objSheet.get_Range("D1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value, 295 );
objRange = objSheet.get_Range("E1", System.Reflection.Missing.Value);
objRange.set_Value(System.Reflection.Missing.Value,
"=SUM(RC[-4]:RC[-1])" );
objRange = objSheet.get_Range("A1", "E1");
objRange.Font.Bold=true;
objExcel=null;
}
</pre> Testing Your Client Application
Now that your project is complete, press F5 to run it and then click the button to automate Excel. If you entered the code correctly, Excel will start, data will be placed into four cells, the total of the four cells will be placed into a fifth cell, and all cells will be made bold (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/20.htm#ch20fig02 Figure 20.2]).
<div style="text-align: center;">Figure 20.2. You can control almost every aspect of Excel using its object model.
[[Image:20fig02.jpg|500px|graphics/20fig02.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Automating applications, particularly Office products such as Excel and Word, requires a lot of system resources. If you intend to perform a lot of automation, you should use the fastest machine with the most RAM that you can afford.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
In this hour, you learned how a program can make available an object model that client applications can use to manipulate the program. You learned that the first step in automating a program (server) is to reference the type library of the server. After the type library is referenced, the objects of the server are available as though they're internal C# objects. As you have seen, the mechanics of automating a program aren't that difficult�they build on the object-programming skills you've already learned in this book. The real challenge comes in learning the object model of a given server and in making the most productive use of the objects available.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/20.htm#qad1e60730 Q1:]'''
| What are some applications that support Automation?
|-
| align="right" | ''' A1: '''
| All the Microsoft Office products, as well as Microsoft Visio, support Automation. You can create a useful application by building a client that makes use of multiple automation servers. For instance, you could calculate data in Excel and then format and print the data in Word.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/20.htm#qad1e60746 Q2:]'''
| Can you automate a component without creating a reference to a type library?
|-
| align="right" | ''' A2: '''
| Yes, but this gets considerably more complicated than when using a type library. First, you can't early bind to objects, because C# knows nothing about the objects. This means you have no IntelliSense drop-down list to help you navigate the object model; the chances for bugs in this situation are almost unbearably large. To use late binding in Visual C#, use the System.Type.InvokeMember method.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec20.htm#ch20ans01 1:]'''
| Before you can early bind objects in an automation server, you must do what?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec20.htm#ch20ans02 2:]'''
| What is the most likely cause of not seeing a type library listed in the Add References dialog box?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec20.htm#ch20ans03 3:]'''
| For C# to use a COM library, it must create a:
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec20.htm#ch20ans04 4:]'''
| To manipulate a server via automation, you manipulate:
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec20.htm#ch20ans05 5:]'''
| To learn about the object library of a component, you should:
|}
Exercises
# Modify the Excel example to save the Workbook. Hint: Consider the SaveAs() method of the Workbooks collection.
# If you have Word installed, add the Word type library to a new project, create an object variable that holds a reference to Word's Application object, create a new document, and send some text to the document.
n2jumajqr4s7bfr9irqs3vml41rep0d
User:Foxall/17
2
2152
39254
5613
2026-04-13T06:03:37Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39254
wikitext
text/x-wiki
== Hour 17. Designing Objects Using Classes ==
You learned about what makes an object an object in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], "Understanding Objects and Collections." Since that hour, you've learned how to manipulate objects such as forms and controls. The real power of leveraging objects comes from being able to design and implement custom objects of your own design. In this hour, you'll learn how to create your own objects by using classes (in contrast to using static methods). You'll learn how to define the template for an object and how to create your own custom properties and methods.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev2sec1 Encapsulating data and code using classes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev2sec2 Comparing instance member classes with static member classes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev2sec3 Constructors and destructors]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev2sec4 Creating an object interface]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev3sec1 Exposing object attributes as properties]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec1.htm#ch17lev3sec2 Exposing methods]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec2.htm#ch17lev1sec2 Instantiating objects from classes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec2.htm#ch17lev2sec5 Binding an object reference to a variable]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec2.htm#ch17lev2sec7 Understanding object lifetime]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch17lev1sec2.htm#ch17lev2sec6 Releasing object references]
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| There is simply no way to become an expert on programming classes in a single hour. However, when you've finished with this hour, you'll have a working knowledge of creating classes and deriving custom objects from those classes; consider this hour a primer on object-oriented programming. I strongly encourage you to seek other texts that focus on object-oriented programming after you feel comfortable with the material presented throughout this book.
|}
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Understanding Classes
Classes enable you to develop applications using object-oriented programming (OOP) techniques (recall that I discussed OOP briefly in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3]). Classes are templates that define objects. Although you may not have known it, you have been programming with classes throughout this book. When you create a new form in a C# project, you are actually creating a class that defines a form; forms instantiated at runtime are derived from the class. Using objects derived from predefined classes, such as a C# Form class, is just the start of enjoying the benefits of object-oriented programming�to truly realize the benefits of OOP, you must create your own classes.
The philosophy of programming with classes is considerably different from that of "traditional" programming. Proper class-programming techniques can make your programs better, both in structure and in reliability. Class programming forces you to consider the logistics of your code and data more thoroughly, causing you to create more reusable and extensible object-based code.
Encapsulating Data and Code Using Classes
An object derived from a class is an encapsulation of data and code; that is, the object comprises its code and all the data it uses. For example, suppose that you need to keep track of employees in an organization and that you need to store many of pieces of information for each employee, such as Name, Date Hired, and Title. In addition, suppose you need methods for adding and removing employees, and you want all this information and functionality available to many functions within your application. You could use static methods to manipulate the data. However, this would most likely require many variable arrays, as well as code to manage the arrays.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| A better approach is to encapsulate all the employee data and functionality (adding and deleting routines and so forth) into a single, reusable object. Encapsulation is the process of integrating data and code into one entity�an object. Your application, as well as external applications, could then work with the employee data through a consistent interface�the Employee object's interface (An interface is a set of exposed functionality�essentially, code routines.)
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Creating objects for use outside of your application is beyond the scope of this book. The techniques you'll learn in this hour, however, are directly applicable to creating externally creatable objects.
|}
The encapsulation of data and code is the key detail of classes. By encapsulating the data and the routines to manipulate the data into a single object by way of a class, you free application code that needs to manipulate the data from the intricacies of data maintenance. For example, suppose company policy has changed so that when a new employee is added to the system, a special tax record needs to be generated and a form needs to be printed. If the data and code routines weren't encapsulated in a common object but were written in various places throughout your code, you would need to modify each and every module that contained code to create a new employee record. By using a class to create an object, you need to change only the code in one location: within the object. As long as you don't modify the interface of the object (discussed shortly), all the routines that use the object to create a new employee will instantly have the policy change in effect.
Comparing Instance Members with Static Members
You learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch11.htm#ch11 Hour 11], "Creating and Calling Methods," that C# does not support global methods, but supports only class methods. By creating static methods, you create methods that can be accessed from anywhere in the project through the class.
Instance methods are similar to static methods in how they appear in the C# design environment and in the way in which you write code within them. However, the behavior of classes at runtime differs greatly from that of static members. With static members, all static data is shared by all members of the class. In addition, there are never multiple instances of the static class data. With instance member classes, objects are instantiated from a class and each object receives its own set of data. Static methods are accessed through the class, whereas nonstatic methods (also called instance methods) are accessed through instances of the class.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Instance methods differ from static methods in more ways than just in how their data behaves. When you define a static method, it is instantly available to other classes within your application. However, instant member classes aren't immediately available in code. Classes are templates for objects. At runtime, your code doesn't interact with the code in the class per se, but it instantiates objects derived from the class. Each object acts as its own class "module" and thus it has its own set of data. When classes are exposed externally to other applications, the application containing the class's code is called the server. Applications that create and use instances of objects are called clients. When you use instances of classes in the application that contains those classes, the application itself acts as both a client and a server. In this hour, I'll refer to the code instantiating an object derived from a class as client code.
|}
Begin by creating a new Windows Application titled Class Programming Example. Change the name of the default form to fclsClassExample and set its Text property to Class Example. Next, change the entry point of the project in the method Main() to reference fclsClassExample instead of Form1. Add a new class to the project by choosing Add Class from the Project menu. Save the class with the name clsMyClass.cs (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#ch17fig01 Figure 17.1]).
<div style="text-align: center;">Figure 17.1. Classes are added to a project the same as other object files are added.
[[Image:17fig01.jpg|500px|graphics/17fig01.jpg]]
</div>
Constructors and Destructors
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| As you open your new class file, you'll notice that C# added the public class declaration and a method called clsMyClass(). This is known as the class constructor. A constructor has the same name as the class, includes no return type, and has no return value. A class constructor is called whenever a class object is instantiated. Therefore, it's normally used for initialization if some code needs to be executed automatically when a class is instantiated. If a constructor isn't specified in your class definition, the Common Language Runtime (CLR) will provide a default constructor.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Objects consume system resources. The .NET Framework (discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24], "The 10,000-Foot View") has a built-in mechanism to free resources used by objects. This mechanism is called the Garbage Collector [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24] as well). Essentially, the garbage collector determines when an object is no longer being used and then destroys the object. When the garbage collector destroys an object, it calls the object's destructor method. If you aren't careful about how to implement a destructor method, you can cause problems. I recommend that you seek a book dedicated to object-oriented programming to learn more about constructors and destructors.
|}
Creating an Object Interface
For an object to be created from a class, the class must expose an interface. As I mentioned earlier, an interface is a set of exposed functionality (essentially, code routines/methods). Interfaces are the means by which client code communicates with the object derived from the class. Some classes expose a limited interface, whereas some expose complex interfaces. The content and quantity of your class's interface is entirely up to you.
The interface of a class consists of one or more of the following members:
* Properties
* Methods
* Events
For example, assume that you are creating an Employee object (that is, a class used to derive employee objects). You must first decide how you want client code to interact with your object. You'll want to consider both the data contained within the object and the functions the object can perform. You might want client code to be able to retrieve the name of an employee and other information such as sex, age, and the date of hire. For client code to get these values from the object, the object must expose an interface member for each of the items. Recall from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3] that values exposed by an object are called properties. Therefore, each piece of data discussed here would have to be exposed as a property of the Employee object.
In addition to properties, you can expose functions�such as a Delete or AddNew function. These functions may be simple in nature or very complex. The Delete function of the Employee object, for example, might be quite complex. It would need to perform all the actions necessary to delete an employee, including such things as removing the employee from an assigned department, notifying accounting to remove the employee from the payroll, notifying security to revoke the employee's security access, and so on. Publicly exposed functions of an object, as you should remember from [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch03.htm#ch03 Hour 3], are called methods.
Properties and methods are the most commonly used interface members. Although designing properties and methods may be new to you, by now using them isn't; you've been using properties and methods in almost every hour so far. Here, you're going to learn the techniques for creating properties and methods for your own objects.
For even more interaction between the client and the object, you can expose custom events. Custom object events are similar to the events of a form or a text box. However, with custom events you have complete control over the following:
* The name of the event
* The parameters passed to the event
* When the event occurs
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Events in C# are based on delegates. Creating custom events is complicated, and I'll be covering only custom properties and methods in this hour.
|}
Properties, methods, and events together make up an object's interface. This interface acts as a contract between the client application and the object. Any and all communication between the client and the object must transpire through this interface (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#ch17fig02 Figure 17.2]).
<div style="text-align: center;">Figure 17.2. Clients interact with an object via the object's interface.
[[Image:17fig02.gif|500px|graphics/17fig02.gof]]
</div>
The technical details of the interaction between the client and the object by way of the interface are, mercifully, handled by C#. Your responsibility is to define the properties, methods, and events of an object so that its interface is logical, consistent, and exposes all the functionality a client needs to use the object.
Exposing Object Attributes as Properties
Properties are the attributes of objects. Properties can be read-only, or they can allow both reading and writing of their values. For example, you may want to let a client retrieve the value of a property containing the path of the component, but not let the client change it because you can't change the path of a running component.
You can add properties to a class in two ways. The first is to declare public variables. Any variable declared as public instantly becomes a property of the class (technically, it's referred to as a field). For example, suppose you have the following statement in the Declarations section of a class:
<pre>public long Quantity;
</pre>
Clients could read from and write to the property using code such as the following:
<pre>objMyObject.Quantity = 139;
</pre>
This works, but significant limitations exist that make this approach less than desirable:
* You can't execute code when a property value changes. For example, what if you wanted to write the quantity change to a database? Because the client application can access the variable directly, you have no way of knowing when the value of the variable changes.
* You can't prevent client code from changing a property, because the client code accesses the variable directly.
* Perhaps the biggest problem is this: How do you control data validation? For instance, how could you ensure that Quantity was never set to a negative value?
You simply can't work around these issues using a public variable. Instead of exposing public variables, you should create class properties using property procedures.
Property procedures enable you to execute code when a property is changed, to validate property values, and to dictate whether a property is read-only, write-only, or both readable and writable. Declaring a property procedure is similar to declaring a method, but with some important differences. The basic structure of a property looks like this:
<pre>Private int privatevalue;
public int propertyname
{
get
{
return privatevalue; // Code to return the property's value .
}
set
{
privatevalue = value; // Code that accepts a new value.
}
}
</pre>
The first word in the property declaration simply designates the scope of the property (public or private). Properties declared with public are available to code outside of the class (they can be accessed by client code). Properties declared as private are available only to code within the class. Immediately following public or private are the data type and property name.
Place your cursor after the left bracket following the statement <code>public class clsMyclass</code> and press Enter to create a new line. Type the following statements into your class:
<pre>private int m_intHeight;
public int Height
{
get
{
}
set
{
}
}
</pre>
You might be wondering why you just created a module-level variable of the same name as your property procedure (with a naming prefix, of course). After all, I just finished preaching about the problems of using a module-level variable as a property. A property has to get its value from somewhere, and a module-level variable is usually the best place to store it. The property procedure will act as a wrapper for this variable. Notice here that the variable is private rather than public. This means that no code outside of the class can view or modify the contents of this variable; as far as client code is concerned, this variable doesn't exist.
Between the property declaration statement and its closing brace are two constructs: the get construct and a set construct. Each of these constructs is discussed in its own section.
Creating Readable Properties Using the get Accessor
The get accessor is used to place code that returns a value for the property when read by the client. If you remove the get accessor and its corresponding brackets, clients won't be able to read the value of the property. It's rare that you'll want to create such a property, but you can.
Think of the get accessor as a method; whatever you return as the result of the method becomes the property value. Add the following statement between the get brackets:
<pre>return m_intHeight;
</pre>
You return the value of the property by using the return keyword followed by the value.
Creating Writable Properties Using the set Accessor
The set accessor is where you place code that accepts a new property value from client code. If you remove the set <code>accessor (and its corresponding brackets)</code>, clients won't be able to change the value of the property. Leaving the get accessor and removing the set accessor creates a read-only property; clients can retrieve the value of the property but they cannot change it.
Add the following statement between the set brackets:
<pre>m_intHeight = value;
</pre>
The set clause uses a special variable called value, which is provided automatically by C# and always contains the value being passed to the property by the client code. The statement you just entered assigns the new value to the module-level variable.
As you can see, the property method is a wrapper around the module-level variable. When the client code sets the property, the set accessor stores the new value in the variable. When the client retrieves the value of the property, the get accessor returns the value in the module-level variable.
So far, the property code, with its get and set accessor, doesn't do anything different from what it would do if you were to simply declare a public variable (only the property procedure requires much more code). However, look at this variation of the same set accessor:
<pre>set
{
if (value >=10)
m_intHeight = value;
}
</pre>
This set accessor restricts the client to setting the Height property to a value greater than 10. If a value less than 10 is passed to the property, the property procedure is exited without setting <code>m_intHeight</code>. You're not limited to performing only data validation; you can pretty much add whatever code you desire and even call other methods. Go ahead and add the verification statement to your code so that the set accessor looks like this one. Your code should now look like the procedure shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#ch17fig03 Figure 17.3].
<div style="text-align: center;">Figure 17.3. This is a property procedure, complete with data validation.
[[Image:17fig03.jpg|500px|graphics/17fig03.jpg]]
</div>
Exposing Functions as Methods
Unlike a property that acts as an object attribute, methods are functions exposed by an object. A method can return a value, but it doesn't have to. Create the following method in your class now. Enter this code on the line following the closing bracket for the declared public int Height property:
<pre>public long AddTwoNumbers(int intNumber1, int intNumber2)
{
return intNumber1 + intNumber2;
}
</pre>
Recall that methods defined with a data-type return values, whereas methods defined with void don't. To make a method private to the class and therefore invisible to client code, declare the method as private rather than public.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Instantiating Objects from Classes
After you obtain a reference to an object and assign it to a variable, you can manipulate the object using an object variable. You're going to do this now.
Click the Form1.cs Design tab to view the form designer and add a button to the form by double-clicking the Button item in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnCreateObject</code>
|-
| <code>Location</code>
| <code>104,120</code>
|-
| <code>Size</code>
| <code>88,23</code>
|-
| <code>Text</code>
| <code>Create Object</code>
|}
Next, double-click the button to access its Click event and enter the following code:
<pre>clsMyClass objMyObject = new clsMyClass();
MessageBox.Show(objMyObject.AddTwoNumbers(1,2).ToString());
</pre>
The first statement creates a variable of type clsMyClass. (Declaring variables was discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], "Using Constants, Data Types, Variables, and Arrays.") The new keyword tells C# to create a new object, and the text following new is the name of the class to use to derive the object (remember, classes are object templates). The last statement calls the AddTwoNumbers method of your class and displays the result in a message box after converting the return value to a string.
Notice that C# displayed an IntelliSense drop-down list with all the members of the class (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#ch17fig04 Figure 17.4]).
<div style="text-align: center;">Figure 17.4. C# displays IntelliSense drop-down lists for members of early-bound objects.
[[Image:17fig04.jpg|500px|graphics/17fig04.jpg]]
</div>
Go ahead and run the project by pressing F5, and then click the button to make sure everything is working correctly. When finished, stop the project and save your work.
Binding an Object Reference to a Variable
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| An object can contain any number of properties, methods, and events; every object is different. When you write code to manipulate an object, C# has to understand the interface of the object or your code won't work. Resolving the interface members (the properties, methods, and events of the object) occurs when an object variable is bound to an object. The two forms of binding are early binding and late binding. In addition, binding can occur at runtime or at compile time. It is important that you have at least a working understanding of binding if you are to create code based on classes. Although I can't explain the intricacies and technical details of early binding versus late binding in this hour, I will teach you what you need to know to perform each type of binding.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Benefits exist to both types of binding, but early binding is generally superior to late binding because code that uses late-bound objects requires more work (time and resources) by C# than code that uses early-bound objects.
|}
Late Binding an Object Variable
When you declare a variable using the generic data type Object, you are late binding to the object.
Unfortunately, C# requires you to handle additional details when late binding to an object (unlike Visual Basic, which handles the details for you). Late binding is beyond the scope of this book, so I'll be focusing on early binding in this hour.
Late binding requires a great deal of overhead, and it adversely affects the performance of an application. Therefore, late binding isn't the preferred method of binding. Late binding does have some attractive uses; however, most of these are related to using objects outside your application, not for using objects derived from classes within the project.
One of the main drawbacks of late binding is the inability for the compiler to check the syntax of the code manipulating an object. Because C# doesn't know anything about the members of a late-bound object, the compiler has no way of knowing whether you're using a member correctly�or even if the member you're referencing exists. This can result in a runtime exception or some other unexpected behavior.
As explained in the previous hour, runtime exceptions are more problematic than build errors because they're usually encountered by end users and under varying circumstances. When you late bind objects, it's easy to introduce these types of problems; therefore, a real risk exists of throwing exceptions with late binding. As you'll see in the next section, early binding reduces a lot of these risks.
Early Binding an Object Variable
For a member of an object to be referenced, C# must determine and use the internal ID of the specified member. You don't have to know this ID yourself; just be aware that C# needs to know the ID of a member to use it. When an object is early bound (declared as a specific type of object), C# is able to gather the necessary ID information at compile time. This results in considerably faster calls to object members at runtime. In addition, C# can validate a member call at compile time, reducing the chance of errors in your code.
Early binding occurs when you declare a variable as a specific type of object, rather than just as object.
The following are important reasons to use early binding:
* Speed.
* More speed.
* Objects, their properties, and their methods appear in IntelliSense drop-down lists.
* The compiler can check for syntax and reference errors in your code so that many problems are found at compile time, rather than at runtime.
For early binding to take place, an object variable must be declared as a specific object type.
Releasing Object References
When an object is no longer needed, it should be destroyed so that all the resources used by the object can be reclaimed. Objects are destroyed automatically when the last reference to the object is released. Be aware, however, that objects aren't necessarily destroyed immediately when they are no longer referenced and that you don't have control over when they are destroyed. In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24], you'll learn how the garbage collector cleans up unused objects. In this hour, I'm going to focus on what you should do with an object when you're finished with it.
One way to release a reference to an object is simply to let the object variable holding the reference go out of scope, letting the garbage collection of .NET regain the memory space.
To explicitly release an object, set the object variable equal to null, like this:
<pre>objMyObject = null;
</pre>
When you set an object variable equal to null, you're assured that the object reference is fully released. However, just because the reference is released does not mean the object is destroyed! The garbage collector will periodically check for unused objects and reclaim the resources they consume, but this may occur a considerable length of time after the object is no longer used. Therefore, you should add a Dispose() method to all your classes. You should place clean-up code within your Dispose() method and always call Dispose() when you are finished with an object. One thing to keep in mind is that it is technically possible to have more than one variable referencing an object. When this occurs, calling Dispose() may cause clean-up code to execute and therefore cause problems for the code using the second object variable. As you can see, you need to consider many things when programming objects.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you don't correctly release resources used by your objects, your application may experience resource leaks, may become sluggish, and might consume more resources than it should. If your object uses resources (such as memory or hardware resources), you should implement a Dispose() method. In addition, you should always call the Dispose() method of an object you are finished with if the object has implemented a Dispose() method.
|}
Understanding the Lifetime of an Object
An object created from a class exists until the garbage collector (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24]) determines it is no longer used and then destroys the object. Fortunately, C# (or more specifically, the .NET Framework ) handles the details of keeping track of the references to a given object; you don't have to worry about this when creating or using objects. When all the references to an object are released, C# destroys the object. Your primary responsibility for destroying objects is to call Dispose() on any objects that you are finished with and to create a Dispose() method for your own classes that use resources. Beyond that, the garbage collector handles the details of destroying the objects.
* An object is created (and hence referenced) when an object variable is declared using the keyword new (for example, <code>clsMyClass objMyObject = new clsMyClass();</code>).
* An object is referenced when an object variable is assigned an existing object (for example, <code>objThisObject = objThatObject;</code>).
* An object reference is released when an object variable is set to null (see the section "[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#ch17lev2sec6 Releasing Object References]") or goes out of scope.
* When the last reference to an object is released, the object becomes eligible for garbage collection. Many factors, including available system resources, determine when the garbage collector executes next and destroys unused objects.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
Object-oriented programming is an advanced methodology that enables you to create more robust applications; programming classes is the foundation of OOP. In this hour, you learned how to create classes, which are the templates used to instantiate objects. You learned how to create a custom interface consisting of properties and methods and how to use the classes you've defined to instantiate and manipulate objects by way of object variables. You've also learned how you should implement a Dispose() method for classes that consume resources and how it is important to call Dispose() on objects that implement it to ensure that the object frees up its resources as soon as possible. Finally, you learned how objects aren't destroyed as soon as they are no longer needed; rather, they become eligible for garbage collection and are destroyed when the garbage collector next cleans up.
In this hour, you learned the basic mechanics of programming objects with classes. Object-oriented programming takes considerable skill, and you'll need to master the concepts in this book before you can really begin to take advantage of what OOP has to offer. Nevertheless, what you learned in this hour will take you further than you might think. Using an OOP methodology is as much a way of thinking as it is a way of programming; consider how things in your projects might work as objects, and before you know it, you'll be creating robust classes.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#qad1e52454 Q1:]'''
| Should I always try to place code into instance classes rather than static classes?
|-
| align="right" | ''' A1: '''
| Not necessarily. As with most things, there are no hard and fast rules. Correctly programming instance classes takes some skill and experience, and programming static is easier for the beginner. If you want to experiment with instance classes, I encourage you to do so. However, don't feel as though you have to place everything into instantiated classes.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/17.htm#qad1e52464 Q2:]'''
| I want to create a general class with a lot of miscellaneous methods�sort of a "catchall" class. What is the best way to do this?
|-
| align="right" | ''' A2: '''
| If you want to create some sort of utility class, I recommend calling the class something like clsUtility. Then you can use this class throughout your application to access the utility functions.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans01 1:]'''
| To create objects, you must first create a template. This template is called a:
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans02 2:]'''
| One of the primary benefits of object-oriented programming is that objects contain both their data and their code. This is called:
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans03 3:]'''
| With static classes, public variables and routines are always available to code via the static class in other modules. Is this true with public variables and routines in classes?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans04 4:]'''
| True or False: Each object derived from a class has its own set of class-level data.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans05 5:]'''
| What must you do to create a property that can be read but not changed by client code?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans06 6:]'''
| What is the best way to store the internal value of a property within a class?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans07 7:]'''
| Which is generally superior, early binding or late binding?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec17.htm#ch17ans08 8:]'''
| What is the best way to release an object you no longer need?
|}
Exercises
# Add a new property to your class called DropsInABucket. Make this property a Long, and set it up so that client code can read the property value but not set it. Finally, add a button to the form that, when clicked, prints the value of the property to the Output window. When this is working, modify the code so that the property always returns 1,000,000.
# Add a button to your form that creates two object variables of type clsMyClass(). Use the new keyword to instantiate a new instance of the class in one of the variables. Then set the second variable to reference the same object and print the contents of the Height property to the Output window.
ewm9r0207o1fyipjfnw7d9ryiyuzmo8
User:Foxall/18
2
2153
39255
5614
2026-04-13T06:03:37Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39255
wikitext
text/x-wiki
== Hour 18. Interacting with Users ==
Forms and controls are the primary means by which users interact with an application, and vice versa. However, program interaction can and often does go deeper than that. For example, a program can display customized messages to a user, and it can be finely tuned to deal with certain keystrokes or mouse clicks. In this hour, you'll learn how to create functional and cohesive interaction between your application and the user. In addition, you'll learn how to program the keyboard and the mouse so that you can expand the interactiveness of your program beyond what is natively supported by a form and its controls.
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch18lev1sec1.htm#ch18lev1sec1 Displaying messages using the MessageBox.Show() method]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch18lev1sec2.htm#ch18lev1sec2 Creating custom dialog boxes]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch18lev1sec3.htm#ch18lev1sec3 Interacting with the keyboard]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch18lev1sec4.htm#ch18lev1sec4 Using the common mouse events]
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Displaying Messages Using the MessageBox.Show() Method
A message box is a small dialog box that displays a message to the user. Message boxes are often used to tell the user the result of some action, such as <code>The file has been copied</code>. or <code>The file could not be found</code>. A message box is dismissed when the user clicks one of the message box's available buttons. Most applications have many message boxes, yet developers often don't display messages correctly. It's important to remember that when you display a message to a user, you're communicating with the user. In this section, I want to teach you not only how to use the MessageBox.Show() method to display messages, but how to use the statement effectively.
The MessageBox.Show() method can be used to tell a user something or ask the user a question. In addition to text, which is its primary function, you can also use this function to display an icon or display one or more buttons that the user can click. Although you are free to display whatever text you want, you must choose from a predefined list of icons and buttons.
A MessageBox.Show() method is an overloaded method. This means that the method was written with numerous constructs supporting various options. While coding in Visual Studio .NET, IntelliSense displays a drop-down scrolling list displaying any of the twelve overloaded MessageBox.Show method calls to aid in coding. Following are a few ways to call MessageBox.Show():
To display a message box with specified text, a caption in the title bar, and an OK button, use this syntax:
<pre>MessageBox.Show(MessageText, Caption);
</pre>
To display a message box with specified text, caption, and one or more specific buttons, use this syntax:
<pre>MessageBox.Show(MessageText, Caption, Buttons);
</pre>
To display a message box with specified text, caption, buttons, and icon, use this syntax:
<pre>MessageBox.Show(MessageText, Caption, Buttons, Icon);
</pre>
In all these statements, <code>MessageText</code> is the text to display in the message box, <code>Caption</code> determines what appears in the title bar, <code>Buttons</code> determines which buttons the user sees, and <code>Icon</code> determines what icon (if any) appears in the message box. Consider the following statement, which produces the message box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig01 Figure 18.1].
<div style="text-align: center;">
</div>
<pre>MessageBox.Show("This is a message.");
</pre>
As you can see, if you omit <code>Buttons</code>, C# displays only an OK button. You should always ensure that the buttons displayed are appropriate for the message.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Visual Basic MsgBox() function defaults the caption for the message box to the name of the project. There is no default in C#.
|}
Specifying Buttons and an Icon
The Buttons parameter contains the "meat" of the message box statement. Using the Buttons parameter, you can display a button (or buttons) in the message box. The Buttons parameter type is MessageBoxButtons, and the allowable values are shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table01 Table 18.1].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 18.1. Allowable Enumerators for MessageBoxButtons
|-
| Members
| Description
|-
| <code>AbortRetryIgnore</code>
| Displays Abort, Retry, and Ignore buttons.
|-
| <code>OK</code>
| Displays OK button only.
|-
| <code>OKCancel</code>
| Displays OK and Cancel buttons.
|-
| <code>YesNoCancel</code>
| Displays Yes, No, and Cancel buttons.
|-
| <code>YesNo</code>
| Displays Yes and No buttons.
|-
| <code>RetryCancel</code>
| Displays Retry and Cancel buttons.
|}
Because the Buttons parameter is an enumerated type, C# gives you an IntelliSense drop-down list when specifying a value for this parameter. Therefore, committing these values to memory isn't all that important; you'll fairly quickly commit the ones you use most often to memory.
The Icon parameter determines the symbol displayed in the message box. The Icon parameter is an enumeration from the MessageBoxIcon type. The MessageBoxIcon has the values shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table02 Table 18.2].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 18.2. Enumerators for MessageBoxIcon
|-
| Members
| Description
|-
| Asterisk
| Displays a symbol consisting of a lowercase letter i in a circle.
|-
| Error
| Displays a symbol consisting of a white X in a circle with a red background.
|-
| Exclamation
| Displays a symbol consisting of an exclamation point in a triangle with a yellow background.
|-
| Hand
| Displays a symbol consisting of a white X in a circle with a red background.
|-
| Information
| Displays a symbol consisting of a lowercase letter i in a circle.
|-
| None
| Displays no symbol.
|-
| Question
| Displays a symbol consisting of a question mark in a circle.
|-
| Stop
| Displays a symbol consisting of a white X in a circle with a red background.
|-
| Warning
| Displays a symbol consisting of an exclamation point in a triangle with a yellow background.
|}
The Icon parameter is also an enumerated type; therefore, C# gives you an IntelliSense drop-down list when specifying a value for this parameter.
The message box in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig02 Figure 18.2] was created with the following statement:
<pre>MessageBox.Show("I'm about to do something...","MessageBox sample",
MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
</pre> <div style="text-align: center;">Figure 18.2. Assign the Information icon to general messages.
[[Image:18fig02.jpg|299px|graphics/18fig02.jpg]]
</div>
The message box in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig03 Figure 18.3] was created with a statement almost identical to the previous one, except that the second button is designated the default button. If a user presses the Enter key with a message box displayed, the message box acts as though the user clicked the default button. You'll want to give careful consideration to the default button in each message box. For example, if the application is about to do something that the user probably doesn't want to do, it's best to make the Cancel button the default button�in case the user is a bit quick when pressing the Enter key. Following is the statement used to generate the message box in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig03 Figure 18.3].
<div style="text-align: center;">Figure 18.3. The default button has a dark border.
[[Image:18fig03.jpg|301px|graphics/18fig03.jpg]]
</div>
<pre>MessageBox.Show("I'm about to do something...","MessageBox sample",
MessageBoxButtons.OKCancel,MessageBoxIcon.Information,
MessageBoxDefaultButton.Button2);
</pre>
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig04 Figure 18.4], the Error icon is shown. The Error icon is best used in rare circumstances, such as when an exception has occurred. Overusing the Error icon is like crying wolf�when a real problem emerges, the user might not take notice. Notice here how I've displayed only the OK button. If something has already happened and there's nothing the user can do about it, don't bother giving the user a Cancel button. The following statement generated the message box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig04 Figure 18.4].
<div style="text-align: center;">Figure 18.4. If users have no control over what has occurred, don't give them a Cancel button.
[[Image:18fig04.jpg|301px|graphics/18fig04.jpg]]
</div>
<pre>MessageBox.Show("Something bad has happened!","MessageBox sample",
MessageBoxButtons.OK,MessageBoxIcon.Error);
</pre>
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig05 Figure 18.5], a question has been posed to the user, so I chose to display the Question icon. Also note how I assumed that the user would probably choose No, so I made the second button the default. In the next section, you'll learn how to determine which button the user clicks. Here's the statement used to generate the message box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig05 Figure 18.5]:
<pre>MessageBox.Show("Would you like to format your hard drive now?",
"MessageBox sample",MessageBoxButtons.YesNo,MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
</pre> <div style="text-align: center;">Figure 18.5. Message boxes can be used to ask a question.
[[Image:18fig05.jpg|330px|graphics/18fig05.jpg]]
</div>
As you can see, designating buttons and icons is not all that difficult. The real thought comes in determining which buttons and icons are appropriate for a given situation.
Determining Which Button Is Clicked
You'll probably find that many of your message boxes are simple, containing only an OK button. For other message boxes, however, you'll need to determine which button a user clicks. Why give the user a choice if you're not going to act on that choice? The MessageBox.Show() method returns the button clicked as a DialogResult enumeration. The DialogResult has the following values, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table03 Table 18.3].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 18.3. Enumerators for DialogResult
|-
| Members
| Description
|-
| Abort
| Return value Abort, usually sent from a button labeled Abort.
|-
| Cancel
| Return value Cancel, usually sent from a button labeled Cancel.
|-
| Ignore
| Return value Ignore, usually sent from a button labeled Ignore.
|-
| No
| Return value No, usually sent from a button labeled No.
|-
| None
| Nothing is returned from the dialog box. The model dialog will continue running.
|-
| OK
| Return value OK, usually sent from a button labeled OK.
|-
| Retry
| Return value Retry, usually sent from a button labeled Retry.
|-
| Yes
| Return value Yes, usually sent from a button labeled Yes.
|}
Performing actions based on the button clicked is a matter of using one of the decision constructs. For example:
<pre>if (MessageBox.Show("Would you like to do X?","MessageBox sample",
MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes)
// Code to do X would go here.
</pre>
As you can see, MessageBox.Show() is a method that gives you a lot of "bang for your buck"; it offers considerable flexibility.
Crafting Good Messages
The MessageBox.Show() method is surprisingly simple to use, considering all the different forms of messages it enables you to create. The real trick is in providing appropriate messages to users and appropriate times. In addition to considering the icon and buttons to display in a message, you should follow these guidelines for crafting message text.
* Use a formal tone. Don't use large words, and avoid using contractions. Strive to make the text immediately understandable and not overly fancy; a message box is not a place to show off your literary skills.
* Limit messages to two or three lines. Lengthy messages are not only harder for users to read, but they can also be intimidating. When a message box is used to ask a question, make the question as simple as possible.
* Never make users feel as though they've done something wrong. Users will, and do, make mistakes, but you should craft messages that take the sting out of the situation.
* Spell check all message text. Visual Studio's code editor doesn't spell check for you, so you should type your messages into a program such as Word and spell check the text before pasting it into your code. Spelling errors have an adverse effect on a user's perception of a program.
* Avoid technical jargon. Just because someone uses software doesn't mean that he or she is a technical person; explain things in plain English.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Creating Custom Dialog Boxes
Most of the time, the MessageBox.Show() method should be a sufficient means to display messages to a user. At times, however, the MessageBox.Show() method is too limited for a given purpose. For example, suppose you wanted to display a lot of text and therefore wanted a message box that was sizable by the user.
Custom dialog boxes are nothing more than standard modal forms with one notable exception: one or more buttons are designated to return a dialog result, the same as the buttons on a message box shown with the MessageBox.Show() method.
You're now going to create a custom dialog box. Create a new Windows Application titled Custom Dialog Example. Change the name of the default form to fclsMain, set its Text property to Custom Dialog Box Example, and set the Main() entry point of the project to reference fclsMain rather than Form1. Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowCustomDialogBox</code>
|-
| <code>Location</code>
| <code>72,180</code>
|-
| <code>Size</code>
| <code>152,23</code>
|-
| <code>Text</code>
| <code>Show Custom Dialog Box</code>
|}
Next, you're going to create the custom dialog box. Add a new form to the project by choosing Add Windows Form from the Project menu. Save the new form with the name fclsCustomDialogBox.cs. Change the Text property of the new form to This is a custom dialog box. Add a new text box to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtCustomMessage</code>
|-
| <code>Location</code>
| <code>8,8</code>
|-
| <code>Locked</code>
| <code>true</code>
|-
| <code>Multiline</code>
| <code>true</code>
|-
| <code>Size</code>
| <code>276,224</code>
|-
| <code>Text</code>
| <code>Custom message goes here</code>
|}
For a custom dialog box to return a result like a standard message box does, it must have buttons that are designated to return a dialog result. This is accomplished by setting the DialogResult property of a button (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig06 Figure 18.6]).
<div style="text-align: center;">Figure 18.6. The DialogResult property determines the return value of the button.
[[Image:18fig06.jpg|500px|graphics/18fig06.jpg]]
</div>
Add a new button to the form and set its properties as shown in the following table. This button will act as the custom dialog box's Cancel button.
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnCancel</code>
|-
| <code>DialogResult</code>
| <code>Cancel</code>
|-
| <code>Location</code>
| <code>128,240</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>Cancel</code>
|}
Last, you need to create an OK button for the custom dialog box. Create another button and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnOK</code>
|-
| <code>DialogResult</code>
| <code>OK</code>
|-
| <code>Location</code>
| <code>208,240</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>OK</code>
|}
Specifying a dialog result for one or more buttons is the first step in making a form a custom dialog box. The second part of the process is in how the form is shown. As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch05.htm#ch05 Hour 5], "Building Forms�Part I," forms are displayed by calling the Show method of the form or setting its visible property to true. However, to show a form as a custom dialog box, you call the ShowDialog method instead. When a form is displayed using ShowDialog, the following occurs:
* The form is shown modally.
* If the user clicks a button that has its DialogResult property set to return a value, the form is immediately closed and that value is returned as the result of the ShowDialog method call.
Notice how you don't have to write code to close the form; clicking a button with a dialog result closes the form automatically. This simplifies the process of creating custom dialog boxes. Return to the first form in the form designer by clicking the Form1.cs [Design] tab.
Double-click the button you created and add the following code:
<pre>fclsCustomDialogBox objCustomDialogBox = new fclsCustomDialogBox();
if (objCustomDialogBox.ShowDialog() == DialogResult.OK)
MessageBox.Show("You clicked OK.");
else
MessageBox.Show("You clicked Cancel.");
objCustomDialogBox = null;
</pre>
Press F5 to run the project, click the button to display your custom dialog box (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig07 Figure 18.7]), and then click one of the available dialog box buttons. When you're satisfied the project is working correctly, stop the project and save your work.
<div style="text-align: center;">Figure 18.7. The ShowDialog method enables you to create custom message boxes.
[[Image:18fig07.jpg|300px|graphics/18fig07.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you click the Close (X) button in the upper-right corner of the form, the form is closed and the code behaves as if you've clicked Cancel; the else code occurs.
|}
The capability to create custom dialog boxes is a powerful feature. Usually, a call to MessageBox.Show() will suffice, but when you need more control over the appearance and contents of a message box, creating a custom dialog box is the way to go.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Interacting with the Keyboard
Most every control handles its own keyboard input; however, on occasion, you'll want to handle keyboard input directly. For example, you might want to perform an action when the user presses a specific button or releases a specific button. Most controls support three events that you can use to work directly with keyboard input. These are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table04 Table 18.4].
{| cellspacing="0" cellpadding="1" border="1"|+ Table 18.4. Events That Handle Keyboard Input
|-
| Event Name
| Description
|-
| <code>KeyDown</code>
| Occurs when a key is pressed down while the control has the focus.
|-
| <code>KeyPress</code>
| Occurs when a key is pressed (the key has been pushed down and then released) while the control has the focus.
|-
| <code>KeyUp</code>
| Occurs when a key is released while the control has the focus.
|}
These events fire in the same order in which they appear in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table04 Table 18.4]. Suppose, for example, that the user presses a key while a text box has the focus. The following list shows how the events would fire for the text box:
# When the user presses a key, the KeyDown event fires.
# When the user releases a key, the KeyPress event fires.
# After the KeyPress event fires, the KeyUp event fires, completing the cycle of keystroke events.
You're now going to create a project that illustrates handling keystrokes. This project has a text box that will refuse to display the letter "k." Start by creating a new Windows Application titled Keyboard Example. Change the name of the default form to fclsKeyboardExample, set its Text property to Keyboard Example, and set the Main() entry point of the project to reference fclsKeyboardExample instead of Form1. Add a new text box to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtInput</code>
|-
| <code>Location</code>
| <code>24,80</code>
|-
| <code>Multiline</code>
| <code>true</code>
|-
| <code>Size</code>
| <code>240,120</code>
|-
| <code>Text</code>
| (make blank)
|}
You're going to add code to the KeyPress event of the text box to "eat" keystrokes made with the letter "k." Select the text box on the form and open the events list in the Properties window (Remember, this is the lightning bolt icon). Scroll through the list and locate the KeyPress event. Next, double-click the KeyPress event to access it in code. Your code editor should look now look like [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig08 Figure 18.8].
<div style="text-align: center;">Figure 18.8. The KeyPress event is a good place to handle keyboard entry.
[[Image:18fig08.jpg|500px|graphics/18fig08.jpg]]
</div>
As you learned in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch04.htm#ch04 Hour 4], "Understanding Events," the e parameter contains information about the occurrence of this event. In the keyboard events, the e parameter contains information about the key being pressed; therefore, it's what you'll be using to work with the keystroke made by the user.
The key being pressed is available as the KeyChar property of the e parameter. You are going to write code that handles the keystroke when the key being pressed is "k." Add the following code to the KeyPress event:
<pre>if (e.KeyChar == 'k')
e.Handled = true;
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Be sure to surround the k with single quotes, not double-quotes, because you're dealing with a character (char), not a string.
|}
I would imagine that you're curious about the Handled property of the e object. When you set this property to true, you are telling C# that you handled the keystroke, and C# should ignore it. To see the effect this has, press F5 to run the project and enter the following into the text box:
Heard any good jokes lately?
What you'll end up with is the text shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig09 Figure 18.9].
<div style="text-align: center;">Figure 18.9. Notice how the letter k was "eaten" by your code.
[[Image:18fig09.jpg|301px|graphics/18fig09.jpg]]
</div>
Go ahead, try to enter another "k"�you can't. Next, try to enter an uppercase "K"; C# allows you to do this because uppercase and lowercase characters are considered different characters. Want to catch all "Ks," regardless of case? You could do so by adding the <code>OR (||)</code> operand to your decision construct, like this:
<pre>if (e.KeyChar == 'k'|| e.KeyChar == 'K')
e.Handled = true;
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| It's not often that I need to catch a keypress, but every now and then I do. The three keystroke events have always made it easy to do what I need to do, but if there's any caveat I've discovered, it's that you need to give careful consideration to which event you choose (such as KeyPress or KeyUp, for example). Different events work best in different situations, and the best thing to do is to start with what seems like the most logical event, test the code, and change the event if necessary.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using the Common Mouse Events
As with keyboard input, most controls support mouse input natively; you don't have to write code to deal with mouse input. However, at times you need more control than that offered by the native functionality of a control. C# supports six events that enable you to deal with mouse input directly. These events are listed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18table05 Table 18.5], in the order in which they occur.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 18.5. Events Used to Handle Mouse Input
|-
| Event Name
| Description
|-
| <code>MouseEnter</code>
| Occurs when the pointer enters a control.
|-
| <code>MouseMove</code>
| Occurs when the pointer moves over a control.
|-
| <code>MouseHover</code>
| Occurs when the pointer hovers over a control.
|-
| <code>MouseDown</code>
| Occurs when the pointer is over a control and a button is pressed.
|-
| <code>MouseUp</code>
| Occurs when the pointer is over a control and a button is released.
|-
| <code>MouseLeave</code>
| Occurs when the pointer leaves a control.
|}
You're now going to build a project that illustrates interacting with the mouse, using the MouseMove event. This project will allow a user to draw on a form, much like you can draw in a paint program. Begin by creating a new Windows Application titled Mouse Paint. Change the name of the default form to fclsMousePaint, set its Text property to Paint with the Mouse, and set the Main() entry point of the project to reference fclsMousePaint instead of Form1.
Next, double-click the form to access its default event, the Load event. Enter the following statement into the load event:
<pre>m_objGraphics = this.CreateGraphics();
</pre>
You've already used a graphics object a few times. What you're doing here is setting a graphics object to the client area of the form; any drawing performed on the object will appear on the form. Because you're going to draw to this graphics object each time the mouse moves over the form, there's no point in creating a new graphics object each time you need to draw to it. Therefore, you're going to make m_objGraphics a module-level variable, which will be instantiated only once�in the Load event of the form. Enter this statement below the opening curly-brace after the public class fclsMousePaint class declaration:
<pre>private Graphics m_objGraphics;
</pre>
As I've said previously, you should always destroy objects when you're done with them. In this case, you want the object to remain in existence for the life of the form. Therefore, you'll destroy it in the Closed event of the form, which occurs when the form is unloaded. Return to the Form1.cs[Design] tab, open the events list in the Property window and double-click the Closed event to create and open the code window to the Closed event. Enter the following statement in the Closed event:
<pre>m_objGraphics.Dispose();
</pre>
Your form should now look like the one shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig10 Figure 18.10].
The last bit of code you need to add is the code that will draw on the form. You're going to place code in the MouseMove event of the form to do this. First, the code will make sure the left mouse button is held down. If it's not, no drawing will take place; the user must hold down the mouse button to draw. Next, a rectangle will be created. The coordinates of the mouse pointer will be used to create a very small rectangle that will be passed to the DrawEllipse method of the graphics object. This has the effect of drawing a tiny circle right where the mouse pointer is positioned. Again, Return to the Form1.cs[Design] tab, open the events list in the Property window, and double-click the MouseMove event to create and open the code window to the MouseMove event. Add the following code to this event:
<pre>Rectangle rectEllipse = new Rectangle() ;
if (e.Button != MouseButtons.Left) return;
rectEllipse.X = e.X - 1;
rectEllipse.Y = e.Y - 1;
rectEllipse.Width = 2;
rectEllipse.Height = 2;
m_objGraphics.DrawEllipse(System.Drawing.Pens.Blue, rectEllipse);
</pre>
Like all events, the e object contains information related to the event. In this example, you are using the X and Y properties of the e object, which is the coordinate of the pointer when the event fires. In addition, you're checking the Button property of the object to make sure the user is pressing the left button.
Your project is now complete! Save your work by clicking Save All on the toolbar, and then press F5 to run the project. Move your mouse over the form�nothing happens. Now, hold down the left mouse button and move the mouse. This time, you'll be drawing on the form (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#ch18fig11 Figure 18.11]).
<div style="text-align: center;">
</div>
Notice that the faster you move the mouse, the more space appears between circles. This shows you that the user is able to move the mouse faster than the MouseMove event can fire, so you can't get every single movement of the mouse. This is important to remember.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
Forms and controls allow for a lot of flexibility in the way a user interacts with an application. However, solid interactivity goes beyond what is placed on a form. In this hour, you learned how to use the MessageBox.Show() method to create informational dialog boxes. You learned how to specify an icon, buttons, and even how to designate a specific button as the default button. You also learned some valuable tips to help you create the best messages possible. You'll create message boxes frequently, so mastering this skill is important.
Finally, you learned how to interact with the keyboard and the mouse directly, through numerous events. Sometimes, the mouse or keyboard capabilities of a control fall short of what you want to accomplish. By understanding the concepts presented in this hour, you can go beyond the native capabilities of controls to create a rich, interactive experience for your users.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#qad1e55907 Q1:]'''
| Is it possible to capture keystrokes at the form level, rather than capturing them in control events?
|-
| align="right" | ''' A1: '''
| Yes. For the form's keyboard-related events to fire when a control has the focus, however, you must set the form's KeyPreview property to true. The control's keyboard events will still fire, unless you set <code>KeyAscii = 0</code> in the form's KeyPress event and <code>KeyCode = 0</code> in the form's KeyDown event.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/18.htm#qad1e55926 Q2:]'''
| You don't seem to always specify a button in your MessageBox.Show() statements throughout this book. Why?
|-
| align="right" | ''' A2: '''
| If you don't explicitly designate a button or buttons, C# displays the OK button. Therefore, if all you want is an OK button, you do not need to pass a value to the buttons argument.
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec18.htm#ch18ans01 1:]'''
| What minimal argument should you supply when calling MessageBox.Show()?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec18.htm#ch18ans02 2:]'''
| If you don't supply a value for the title parameter of MessageBox.Show(), what gets displayed in the title bar of the message?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec18.htm#ch18ans03 3:]'''
| What type of data is always returned by the MessageBox.Show() method?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec18.htm#ch18ans04 4:]'''
| Which event fires first, the KeyUp or KeyPress event?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec18.htm#ch18ans05 5:]'''
| How do you determine which button is being pressed in a mouse-related event?
|}
Exercises
# Modify your custom dialog box project so that the OK button is the Accept button of the form. That way, the user has only to press Enter to dismiss the dialog box. Next, make the Cancel button the Cancel button of the form so that the user can press the Esc key to dismiss the form as well.
# Modify your mouse paint project so that the form clears each time the user starts drawing. Hint: Clear the graphics object in the MouseDown event.
bw9tcvx247ln9yd3g72neenq6sl007k
User:Foxall/19
2
2154
39256
5615
2026-04-13T06:03:37Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39256
wikitext
text/x-wiki
== Hour 19. Performing File Operations ==
It's very difficult to imagine any application other than a tiny utility program that doesn't make use of the file system. In this hour, you'll learn how to use the controls to make it easy for a user to browse and select files. In addition, you'll learn how to use the System.IO.File and System.IO.Directory objects to manipulate the file system. Using these objects, you can delete files and directories, move them, rename them, and more. These objects are powerful, but please remember: play nice!
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch19lev1sec1.htm#ch19lev1sec1 Using the Open File Dialog and Save File Dialog controls]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch19lev1sec2.htm#ch19lev1sec2 Manipulating files with System.IO.File]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch19lev1sec3.htm#ch19lev1sec3 Manipulating directories with System.IO.Directory]
----
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Using the Open File Dialog and Save File Dialog Controls
In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch01.htm#ch01 Hour 1], "A C# Programming Tour," you used the Open File Dialog control to enable a user to browse for pictures to display in your Picture Viewer program. In this section, you'll move beyond those basics to learn important details about working with the Open File Dialog control, as well as its sister control, the Save File Dialog.
You're going to build a project to illustrate most of the file-manipulation concepts discussed in this hour. Before continuing, create a new Windows Application titled Manipulating Files. Change the name of the default form to fclsManipulatingFiles, set its Text to Manipulating Files, and then set the entry point of the project to fclsManipulatingFiles. Add a new text box to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>txtSource</code>
|-
| <code>Location</code>
| <code>95,8</code>
|-
| <code>Size</code>
| <code>184,20</code>
|-
| <code>Text</code>
| (make blank)
|}
Using the Open File Dialog Control
The Open File Dialog control is used to display a dialog box that enables the user to browse and select a file (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig01 Figure 19.1]). It's important to note that usually the Open File Dialog doesn't actually open a file, but it allows a user to select a file that is then opened by code within the application.
<div style="text-align: center;">Figure 19.1. The Open File dialog box is used to browse and select files.
[[Image:19fig01.jpg|500px|graphics/19fig01.jpg]]
</div>
Add a new Open File Dialog to your project now by double-clicking the OpenFileDialog item in the toolbox. The Open File Dialog doesn't have an interface per se, so it appears in the area below the form rather than on it. For the user to browse for files, you have to manipulate the Open File Dialog using its properties and methods.
You're going to add a button to the form that, when clicked, allows a user to locate and select a file. If a user selects a file, the filename will be placed in the text box you've created. Go ahead and add a button to the form now, and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnOpenFile</code>
|-
| <code>Location</code>
| <code>8,8</code>
|-
| <code>Size</code>
| <code>80,23</code>
|-
| <code>Text</code>
| <code>Source</code>
|}
Next, double-click the button and add the following code to its Click event:
<pre>openFileDialog1.InitialDirectory = @"C:\";
openFileDialog1.Title = "Select a File";
</pre>
The first statement specifies the directory to display when the dialog box is first shown. If you don't specify a directory for the InitialDirectory property, the active system directory is used (for example, the last directory browsed to with a different Open File dialog box).
The Title property of the Open File Dialog determines the text displayed in the title bar of the Open File dialog box. If you don't specify text for the Title property, C# displays the word Open in the title bar.
Different types of files have different extensions. The Filter property determines what types of files appear in the Open File dialog box (refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig01 Figure 19.1]). A filter is specified in the following format:
<pre>Description|*.extension </pre>
The text that appears before the pipe symbol (<code>|</code>) is the descriptive text of the file type to filter on, whereas the text after the pipe symbol is the pattern used to filter files. For example, to display only Windows bitmap files, you could use a filter such as the following:
<pre>control.Filter = "Windows Bitmaps|*.bmp";
</pre>
You can specify more than one filter type. To do this, add a pipe symbol (<code>|</code>) between the filters, like this:
<pre>control.Filter = "Windows Bitmaps|*.bmp|JPEG Files|*.jpg";
</pre>
You're going to restrict your Open File dialog box to show only text files, so enter the following statement in your btnOpenFile_Click code:
<pre>openFileDialog1.Filter = "Text Files|*.txt";
</pre>
When you have more than one filter, you can specify which filter appears selected by default using the <code>FilterIndex</code> property. Although you've specified only one filter type in this example, it's still a good idea to designate the default filter, so add this statement to your code:
<pre>openFileDialog1.FilterIndex = 1;
</pre>
Finally, you need to show the Open File dialog box and take action based on whether the user selects a file. The ShowDialog() method of the Open File Dialog control acts much like the method of forms by the same name, returning a result that indicates the user's selection on the dialog box. Enter the following statements into your procedure:
<pre>if (openFileDialog1.ShowDialog() != DialogResult.Cancel)
txtSource.Text = openFileDialog1.FileName;
else
txtSource.Text = "";
</pre>
This code just places the selected filename into the text box txtSource. If the user clicks Cancel, the contents of the text box are cleared.
Press F5 to run the project and click the button. You'll get the same dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig01 Figure 19.1] (with different files and directories, of course). Select a text file, click Open, and C# places the name of the file into the text box.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| By default, the Open File Dialog won't allow the user to enter a filename that doesn't exist. You can override this behavior by setting the CheckFileExists property of the Open File Dialog to false.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Open File Dialog control has the capability to allow the user to select multiple files. It's rare that you need to do this (I don't recall ever needing this capability in one of my projects), so I won't go into the details here. If you're interested, take a look at the Multiselect property of the Open File Dialog in the Help text.
|}
The Open File Dialog control makes allowing a user to browse and select a file almost trivial. Without this code, you would have to write an amazing amount of very difficult code and would still probably not come up with all the functionality supported by this control.
Using the Save File Dialog Control
The Save File Dialog control is very similar to the Open File Dialog control, but it is used to allow a user to browse directories and specify a file to save, rather than open. Again, it's important to note that the Save File Dialog doesn't actually save a file, it is used to enable a user to specify a file to save; you'll have to write code to do something with the filename returned by the control.
You're going to use the Save File Dialog to let the user specify a filename. This filename will be the target of various file operations you'll learn about later in this hour. Create a new text box on your form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>txtDestination</code>
|-
| <code>Location</code>
| <code>95,40</code>
|-
| <code>Size</code>
| <code>184,20</code>
|-
| <code>Text</code>
| (make blank)
|}
You're now going to create a button that, when clicked, enables the user to specify a filename to save a file. Add a new button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnSaveFile</code>
|-
| <code>Location</code>
| <code>8,40</code>
|-
| <code>Size</code>
| <code>80,23</code>
|-
| <code>Text</code>
| <code>Destination</code>
|}
Of course, none of this will work without adding a Save File dialog box. Double-click the SaveFileDialog item in the toolbox to add a new control to the project.
Next, double-click the new button (btnSaveFile) and add the following code to its Click event:
<pre>saveFileDialog1.Title = "Specify Destination Filename";
saveFileDialog1.Filter = "Text Files|*.txt";
saveFileDialog1.FilterIndex = 1;
saveFileDialog1.OverwritePrompt = true;
</pre>
The first three statements set properties that are identical to those of the Open File Dialog. The OverwritePrompt property, however, is unique to the Save File Dialog. When this property is set to true, C# asks users to confirm their selections when they choose a file that already exists, as shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig02 Figure 19.2]. I highly recommend that you prompt the user about replacing files by ensuring the OverwritePrompt property is set to true.
<div style="text-align: center;">Figure 19.2. It's a good idea to get confirmation before replacing an existing file.
[[Image:19fig02.jpg|291px|graphics/19fig02.jpg]]
</div>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If you want the Save File dialog box to prompt users when the file they specify doesn't exist, set the CreatePrompt property of the Save File Dialog control to true.
|}
The last bit of code you need to add places the selected filename in the txtDestination text box. Enter the code as shown here:
<pre>if (saveFileDialog1.ShowDialog() != DialogResult.Cancel)
txtDestination.Text = saveFileDialog1.FileName;
</pre>
Press F5 to run the project. Then click each of the buttons and select a file. When you're satisfied that your selections are being sent to the appropriate text box, stop the project and save your work. If your selected filenames aren't being sent to the proper text box, verify that your code is correct.
The Open File Dialog and Save File Dialog controls are very similar in their design and appearance, but each serves a specific purpose. Throughout the rest of this hour, you'll be using the interface you've just created.
Manipulating Files with the File Object
.NET includes a powerful object called System.IO (technically, System and IO are Namespaces, but they behave like objects). Using various properties, methods, and object properties of System.IO, you can do just about anything you can imagine with the file system. In particular, the System.IO.File and System.IO.Directory objects provide you with extensive file and directory (folder) manipulation.
In the following sections, you'll continue to expand the project that you created earlier in this hour. You'll be writing code that manipulates the filenames selected using the Open File Dialog and Save File Dialog controls.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The code you'll write in the following sections is "the real thing." For instance, the code for deleting a file really deletes a file. Don't forget this as you test your project; the files selected as the source and as the destination will be affected by your actions. I provide the cannon; it's up to you not to shoot yourself in the foot.
|}
Determining Whether a File Exists
Before attempting any operation on a file, such as copying or deleting it, it's a good idea to make certain the file exists. For example, if the user doesn't click the Source button to select a file but types the name and path of a file into the text box instead, the user could type an incorrect filename. Attempting to manipulate a nonexistent file could result in an exception, which you don't want to happen. Because you're going to work with the source file selected by the user in many routines, you're going to write a central function that can be called to determine whether the source file exists. The function uses the Exists() method of the System.IO.File object to determine whether the file exists.
Add the following method to your Form class:
<pre>bool SourceFileExists()
{
if (!System.IO.File.Exists(txtSource.Text))
{
MessageBox.Show("The source file does not exist!");
return false;
}
else
return true;
}
</pre>
The Exists() method accepts a string containing the filename (with path) of the file to verify. If the file exists, Exists() returns true; otherwise, it returns false.
Copying a File
Copying files is a common task. For instance, you may want to create an application that backs up important data files by copying them to another location. For the most part, copying is pretty safe�as long as you specify a destination filename that doesn't already exist. Copying files is accomplished using the Copy() method of the System.IO.File object.
You're now going to add a button to your form. When the user clicks this button, the file specified in the source text box will be copied to a new file with the name given in the destination text box. Add a button to your form now and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnCopyFile</code>
|-
| <code>Location</code>
| <code>96,80</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>Copy</code>
|}
Double-click the Copy button and add the following code:
<pre>if (!SourceFileExists()) return;
System.IO.File.Copy(txtSource.Text, txtDestination.Text);
MessageBox.Show("The file has been successfully copied.");
</pre>
The Copy() method has two arguments. The first is the file that you want to copy, and the second is the name and path of the new copy of the file. In this example, you're using the filenames in the two text boxes.
Press F5 to run the project and test your copy code now by following these steps:
# Click the Source button and select a text file.
# Click the Destination button to display the Save File dialog box. Don't select an existing file. Instead, type a new filename into the File Name text box and click Save. If you are asked whether you want to replace a file, click No and change your filename; don't use the name of an existing file.
# Click Copy to copy the file.
After you get the message box telling you the file was copied, you can use Explorer to locate the new file and open it. Stop the project and save your work before continuing.
Moving a File
When you move a file, the file is taken out of its current directory and placed into a new one. You can specify a new name for the file or use the original name. Moving a file is accomplished with the Move() method of the System.IO.File object. You're now going to create a button on your form that will move the file selected as the source to the path and the filename selected as the destination.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| I recommend that you use Notepad to create a text file and then use this temporary text file when testing this code and the rest of the examples that permanently alter or destroy a file.
|}
Add a new button to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnMove</code>
|-
| <code>Location</code>
| <code>96,112</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>Move</code>
|}
Double-click the Move button and add the following code to its Click event:
<pre>if (!SourceFileExists()) return;
System.IO.File.Move(txtSource.Text, txtDestination.Text);
MessageBox.Show("The file has been successfully moved.");
</pre>
Remember, if you specify a name for the destination that isn't the same as that of the source, the file will be given the new name when it's copied.
Deleting a File
Deleting a file can be a risky proposition. The Delete() method of System.IO.File deletes a file permanently�it doesn't send the file to the Recycle Bin. For this reason, you should take great care when deleting files. First and foremost, this means testing your code. When you write a routine to delete a file, be sure to test it under various conditions. For example, if you mistakenly referenced the destination text box instead of the source text box in this project, you could inadvertently delete the wrong file! Users aren't forgiving of such mistakes.
You're now going to add a button to your project that deletes the source file when clicked. Remember, be careful when testing this code. Add a button to the form now and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnDelete</code>
|-
| <code>Location</code>
| <code>96,144</code>
|-
| <code>Size</code>
| <code>75,23</code>
|-
| <code>Text</code>
| <code>Delete</code>
|}
Next, double-click the button and add the following code to its Click event:
<pre>if (!SourceFileExists()) return;
if (MessageBox.Show("Are you sure you want to delete the source file?", "Delete
[[Image:ccc.gif|18px|graphics/ccc.gif]]Verification",MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes)
{
System.IO.File.Delete(txtSource.Text);
MessageBox.Show("The file has been successfully deleted.");
}
</pre>
Notice that you've included a message box to confirm the user's intentions. It's a good idea to do this whenever you are about to perform a serious action that can't be undone. In fact, the more information you can give, the better. For example, I would suggest that if this were production code (code meant for end users) that you include the name of the file in the message box, so the user knows without a doubt what the program intends to do.
Renaming a File
When you rename a file, it remains in the same directory and nothing materially happens to the contents of the file�the name is changed to something else. Because the original file isn't altered, renaming a file isn't as risky as performing an action such as deleting the file. Nevertheless, it is frustrating trying to determine what happened to a file when it was mistakenly renamed. To rename a file, use the Move() method of System.IO.File, specifying a new filename but keeping the same path.
Retrieving a File's Properties
Although many don't realize it, files have a number of properties, such as the date the file was last modified. The easiest way to see these properties is to use Explorer. View the attributes of a file now by starting Explorer, right-clicking any file displayed in Explorer, and choosing Properties. Explorer then shows the File Properties window with information about the file (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig03 Figure 19.3]).
<div style="text-align: center;">
</div>
The System.IO.File object provides ways to get at most of the data displayed on the General tab of the File Properties dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig03 Figure 19.3]. Some of this data is available directly from the File object, whereas others are accessed using a FileAttributes object.
Getting Date and Time Information About a File
Getting the last created, last accessed, and last modified dates of a file is easy; the System.IO.File object supports a method for each of these dates. [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19table01 Table 19.1] lists the applicable methods and what they return.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 19.1. File Object Methods to Retrieve Data Information
|-
| valign="middle" | Property
| valign="middle" | Description
|-
| <code>GetCreationTime</code>
| Returns the date and time the file was created.
|-
| <code>GetLastAccessTime</code>
| Returns the date and time the file was last accessed.
|-
| <code>GetLastWriteTime</code>
| Returns the date and time the file was last modified.
|}
Getting the Attributes of a File
The attributes of a file (refer to the bottom of the dialog box shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig03 Figure 19.3]) aren't available as properties or methods of the System.IO.File object. Just how you determine an attribute's value is a bit complicated. The GetAttributes() method of System.IO.File returns a FileAttributes enumeration. This, in turn, acts as a set of flags for the various attributes. The method used to store these values is called bit packing. Bit packing is pretty complicated and has to do with the binary method in which values are stored in memory and on disk. Teaching bit packing is beyond the scope of this book�what I want to show you is how to determine if a certain flag is set in a value that is bit packed.
The first step to determining the attributes is to get the file attributes. To do this, create a FileAttributes variable and call GetAttributes(), like this:
<pre>System.IO.FileAttributes objfileAttributes ;
lngAttributes = System.IO.File.GetAttributes(txtSource.Text);
</pre>
After you have the flags in the variable, by <code>&</code>ing the variable with one of the flags shown in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19table02 Table 19.2] and then testing whether the result equals the flag, you can determine whether a particular attribute is set. For example, to determine whether a file's ReadOnly flag is set, you could use a statement like the following:
<pre>(objfileAttributes &
System.IO.FileAttributes.ReadOnly == System.IO.FileAttributes.ReadOnly)
</pre>
When you <code>&</code> a flag value with a variable, you'll get the flag value back if the variable contains the flag; otherwise, you'll get a zero back.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 19.2. File Attribute Flags
|-
| valign="middle" | Attribute
| valign="middle" | Meaning
|-
| <code>Archive</code>
| The file's archive status. Applications use this attribute to mark files for backup and removal.
|-
| <code>Directory</code>
| The file is a directory.
|-
| <code>Hidden</code>
| The file is hidden and therefore not included in an ordinary directory listing.
|-
| <code>Normal</code>
| The file is normal and has no other attributes set.
|-
| <code>ReadOnly</code>
| The file is a read-only file.
|-
| <code>System</code>
| The file is part of the operating system or is used exclusively by the operating system.
|-
| <code>Temporary</code>
| The file is a temporary file.
|}
Writing Code to Retrieve a File's Properties
Now that you know how to retrieve the properties of an object, you're going to use this knowledge to display the properties of the file specified in the source text box on your form. Begin by adding a new button to your form and setting its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>btnGetFileProperties</code>
|-
| <code>Location</code>
| <code>8,176</code>
|-
| <code>Size</code>
| <code>80,56</code>
|-
| <code>Text</code>
| <code>Get Properties of Source File</code>
|}
Next, add a text box to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| valign="middle" | Property
| valign="middle" | Value
|-
| <code>Name</code>
| <code>txtProperties</code>
|-
| <code>Location</code>
| <code>96,176</code>
|-
| <code>Multiline</code>
| <code>True</code>
|-
| <code>ScrollBars</code>
| <code>Vertical</code>
|-
| <code>Size</code>
| <code>184,88</code>
|-
| <code>Text</code>
| (make blank)
|}
The code you enter into the Click event of the button will be a bit longer than most of the code you've entered so far. Therefore, I'll show the code in its entirety, and then I'll explain what the code does. Double-click the button and add the following code to the button's Click event:
<pre>System.Text.StringBuilder stbProperties = new System.Text.StringBuilder("");
System.IO.FileAttributes fileAttributes ;
if (!SourceFileExists()) return;
// Get the dates.
stbProperties.Append("Created: ");
stbProperties.Append(System.IO.File.GetCreationTime(txtSource.Text));
stbProperties.Append("\r\n");
stbProperties.Append("Accessed: ");
stbProperties.Append(System.IO.File.GetLastAccessTime(txtSource.Text));
stbProperties.Append("\r\n");
stbProperties.Append("Modified: ");
stbProperties.Append(System.IO.File.GetLastWriteTime(txtSource.Text));
// Get File Attributes
fileAttributes = System.IO.File.GetAttributes(txtSource.Text);
stbProperties.Append("\r\n");
stbProperties.Append("Normal: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.Normal)
==System.IO.FileAttributes.Normal));
stbProperties.Append("\r\n");
stbProperties.Append("Hidden: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.Hidden)
==System.IO.FileAttributes.Hidden));
stbProperties.Append("\r\n");
stbProperties.Append("ReadOnly: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.ReadOnly)
==System.IO.FileAttributes.ReadOnly));
stbProperties.Append("\r\n");
stbProperties.Append("System: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.System)
==System.IO.FileAttributes.System));
stbProperties.Append("\r\n");
stbProperties.Append("Temporary File: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.Temporary)
==System.IO.FileAttributes.Temporary));
stbProperties.Append("\r\n");
stbProperties.Append("Archive: ");
stbProperties.Append(
Convert.ToBoolean((fileAttributes & System.IO.FileAttributes.Archive)
==System.IO.FileAttributes.Archive));
txtProperties.Text = stbProperties.ToString();
</pre>
All the various properties of the file are appended to the StringBuilder variable stbProperties. The <code>"\r\n"</code> denotes a carriage return and a linefeed, and appending this into the string ensures that each property appears on its own line.
The first statement declares an empty StringBuilder variable called stbProperties. The StringBuilder object was designed for optimizing string concatenation. You'll be using the append method of the StringBuilder class to create the file properties text. The second set of statements simply call the GetCreateTime(), GetLastAccessTime(), and GetLastWriteTime() methods to get the values of the date-related properties. Next, the attributes are placed in a variable by way of the GetAttributes() method, and the state of each attribute is determined. The Convert.ToBoolean() method is used so that the words True and False appear. Lastly, you assign the txtProperties.Text value to the created StringBuilder string.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| You've previously used the + to concatenate strings, and this will also work. But, when concatenating a large number of strings, you should use the StringBuilder object. The reason for this is that strings are immutable in .NET�they can never be changed. So every concatenation operation creates an entirely new string object, discarding both of the other strings. This can have a negative affect on performance.
|}
Press F5 to run the project, click Source to select a file, and then click the button to get and display the attributes. If you entered the code exactly as shown, the attributes of the file should appear in the text box as they do in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#ch19fig04 Figure 19.4].
<div style="text-align: center;">Figure 19.4. The System.IO.File object enables you to look at the properties of a file.
[[Image:19fig04.jpg|312px|graphics/19fig04.jpg]]
</div>Manipulating Directories with the Directory Object
Manipulating directories (folders) is very similar to manipulating files. However, rather than using System.IO.File, you use System.IO.Directory. Notice that when you specify a directory path, double slashes are used instead of just one. If any of these method calls confuse you, see the previous section on System.IO.File for more detailed information. Following are the method calls:
* To create a directory, call the CreateDirectory() method of System.IO.Directory, passing the name of the new folder, like this: (Note: As discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch12.htm#ch12 Hour 12], you must preference literal strings containing slashes with the <code>@</code> character.)
<pre>System.IO.Directory.CreateDirectory(@"c:\my new directory");
</pre>
* To determine whether a directory exists, call the Exists() method of System.IO.Directory, passing it the directory name in question, like this:
<pre>MessageBox.Show(Convert.ToString(System.IO.Directory.Exists(@"c:\temp")));
</pre>
* To move a directory, call the Move() method of System.IO.Directory. The Move() method takes two arguments. The first is the current name of the directory, and the second is the new name and path of the directory. When you move a directory, the contents of it are moved as well. The following illustrates a call to Move().
<pre>System.IO.Directory.Move(@"c:\current directory name",
@"d:\new directory name");
</pre>
* Deleting directories is even more perilous than deleting files; when you delete a directory, you also delete all files and subdirectories within the directory. To delete a directory, call the Delete() method of System.IO.Directory, passing it to the directory to delete. I can't tell you often enough that you have to be careful when calling this method; it can you get you into a lot of trouble. The following statement illustrates deleting a directory:
<pre>System.IO.Directory.Delete(@"c:\temp");
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
The Open File Dialog and Save File Dialog controls coupled with System.IO enable you to do many powerful things with a user's file system. In this hour, you learned how to let a user browse and select a file for opening, and how to let a user browse and select a file for saving. Determining a user's file selection is only the first part of the process, however. You also learned how to manipulate files and directories, including renaming, moving, and deleting, by using System.IO. Finally, you learned how to retrieve the properties and attributes of a file.
With the techniques shown in this hour, you should be able to do most of what you'll need to do with files and directories. None of this material is very difficult, but don't be fooled by the simplicity; use care whenever manipulating a user's file system.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#qad1e59343 Q1:]'''
| What if I want to perform an operation on a file, but something is preventing the operation, such as the file may be open or I don't have rights to the file?
|-
| align="right" | ''' A1: '''
| All the method calls have one or more exceptions that can be thrown in the event that the method fails. These method calls are listed in the online Help. You can use the techniques discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch16.htm#ch16 Hour 16], "Debugging Your Code," to trap the exceptions.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/19.htm#qad1e59359 Q2:]'''
| What if a user types a filename into one of the file dialog boxes, but the user doesn't include the extension?
|-
| align="right" | ''' A2: '''
| By default, both file dialog controls have their AddExtension properties set to true. When this property is set to true, C# automatically appends the extension of the currently selected filter.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A], "Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans01 1:]'''
| True or False: The Open File dialog box automatically opens a file.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans02 2:]'''
| What symbol is used to separate a filter description from its extension?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans03 3:]'''
| What objects are used to manipulate files?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans04 4:]'''
| What arguments are required by System.IO.File.Copy()?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans05 5:]'''
| How would you rename a file?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans06 6:]'''
| True or False: Files deleted with System.IO.File.Delete() are sent to the Recycle Bin.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec19.htm#ch19ans07 7:]'''
| What objects are used to manipulate folders?
|}
Exercises
# Create a project that enables a user to select a file with the Open Dialog control. Store the filename in a text box. Provide another button that, when clicked, creates a backup of the file by making a copy of it with the extension .bak.
# Create a project with a text box on it in which the user can type in a three-character file extension. Include a button that, when clicked, shows an Open File dialog box with the filter set to the extension entered by the user.
69vobc78363hr4q198hsyz4cgffgzb8
User:Foxall/13
2
2155
39250
5616
2026-04-13T06:03:35Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39250
wikitext
text/x-wiki
== Hour 13. Performing Arithmetic, String Manipulation, and Date/Time Adjustments ==
Just as arithmetic is a necessary part of everyday life, it's also vital to developing Windows programs. You probably won't write an application that doesn't add, subtract, multiply, or divide some numbers. In this hour, you'll learn how to perform arithmetic in code. You'll also learn about order of operator precedence, which determines how C# evaluates complicated expressions (or equations). After you understand operator precedence, you'll learn how to compare equalities�something you'll do all the time.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Boolean logic is the logic C# itself uses to evaluate expressions in decision-making constructs. If you've never programmed before, Boolean logic may be a new concept to you. However, in this hour I explain what you need to know about Boolean logic to create efficient code that performs as expected. Finally, I show you how to manipulate strings and work with dates and times.
|}
The highlights of this hour include the following:
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec1.htm#ch13lev1sec1 Performing arithmetic]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec1.htm#ch13lev2sec6 Understanding the order of operator precedence]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec2.htm#ch13lev1sec2 Comparing equalities]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec3.htm#ch13lev1sec3 Understanding Boolean logic]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec4.htm#ch13lev1sec4 Manipulating strings]
* [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch13lev1sec5.htm#ch13lev1sec5 Working with dates and times]
----
=== Performing Basic Arithmetic ===
To be a programmer, you have to have solid math skills; you'll be performing a lot of basic arithmetic when writing C# applications. To get the results you're looking for in any given calculation, you must
* Know the mathematical operator that performs the desired arithmetic function.
* Understand and correctly use order of precedence.
Using the correct mathematical operator is simple. Most are easy to commit to memory, and you can always look up the ones you're not quite sure of. I'm not going to go into great detail on any of the math functions (if you've made it this far, I'm sure you have a working grasp of math), but I will cover them all.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch07.htm#ch07 Hour 7], "Working with Traditional Controls," I mentioned how the System.Diagnostics.Debug.WriteLine() method prints text to the Output window. I use this method in the examples throughout this hour. You will not be asked to create a project in this chapter, but you may want to try some of these examples in a test project. Because we are planning to use several debug statements, it will be helpful to declare the System.Diagnostics namespace in the header of your class. This permits you to use the methods of the namespace without having to qualify the entire namespace. The following is the line you need to add at the beginning of your class (put it with the other using statements created automatically by C#):
<pre>using System.Diagnostics;<br /></pre>
For more specific information on the Debug object, refer to [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch16.htm#ch16 Hour 16], "Debugging Your Code."
|}
Performing Addition
Simple addition is performed using the standard addition symbol, the + character. The following line prints the sum of 4, 5, and 6:
<pre>Debug.WriteLine(4 + 5 + 6);
</pre>
You don't have to use a hard-coded value with arithmetic operators. You can use any of the arithmetic operators on numeric variables and constants. For example:
<pre>const int c_FirstValue = 4;
const int c_SecondValue = 5;
Debug.WriteLine(c_FirstValue + c_SecondValue);
</pre>
This bit of code prints the sum of the constants <code>c_FirstValue</code> and <code>c_SecondValue</code>, which, in this case, is 9.
Performing Subtraction and Negation
Like the addition operator, you're most likely familiar with the subtraction operator because it's the same one you would use on a calculator or when writing an equation: the � character. The following line of code prints 2 (the total of 6�4):
<pre>Debug.WriteLine(6 - 4);
</pre>
As with written math, the � character is also used to denote a negative number. For example, to print the value �<code>6</code>, you would use a statement such as the following:
<pre>Debug.WriteLine(-6);
</pre> Performing Multiplication
If you work with adding machines, you already know the multiplication operator. The multiplication character is the asterisk (*) character. You can enter this character using Shift+8 or by pressing the * key located in the upper row of the keypad section of the keyboard. Although you would ordinarily use an "x" when writing multiplication equations such as 6 = 3x2 on paper, you'll receive an error if you try this in code; you have to use the * character. The following statement prints 20 (5 multiplied by 4):
<pre>Debug.WriteLine(5 * 4);
</pre> Performing Division
Division is accomplished using the slash (/) operator. This operator is easy to remember if you think of division as fractions. For example, one-eighth is written as 1/8, which literally means one divided by eight. The following statement prints 8 (32 divided by 4):
<pre>Debug.WriteLine(32 / 4);
</pre>
C# overloads the division operator. This means that based on the input arguments, the results may vary. For example, C# division will return an integer when dividing integers, but it will return a fractional number if a float, a double, or a decimal data type is used. Hence, <code>32 / 5</code> will return <code>6</code>, dropping the remainder (2, in this case). If you wanted to return the actual value of the operation 32 / 5, you would have to specify the numbers with decimal places (that is, 32.0 / 5.0).
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| The modulus operator (%) can be used to find the remainder of an integer division.
|}
Performing Modulus Arithmetic
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Modulus arithmetic is the process of performing division on two numbers but keeping only the remainder. Modulus arithmetic is performed using the <code>%</code> operand, in contrast to using a slash (/) operator symbol. The following are examples of modulus statements and the values they would print:
|}
<pre>Debug.WriteLine(10 % 5); // Prints 0
Debug.WriteLine(10 % 3); // Prints 1
Debug.WriteLine(12 % 4.3); // Prints 3.4
Debug.WriteLine(13.6 % 5); // Prints 3.6
</pre>
The first two statements are relatively easy to understand: 5 goes into 10 twice with no remainder and 3 goes into 10 three times with a remainder of 1. C# processes the third statement as 4.3 going into 12 three times with a remainder of 3.4. In the last statement, C# performs the modulus operation as 5 going into 13.6 twice with a remainder of 3.6.
Determining the Order of Operator Precedence
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| When several arithmetic operations occur within a single equation (called an expression), C# must resolve the expression in pieces. The order in which these pieces are evaluated is known as operator precedence. To fully understand operator precedence, you have to brush up a bit on your algebra (most of the math you perform in code is algebraic).
|}
Consider the following expression:
<pre>Debug.WriteLine(6 * 5 + 4);
</pre>
Two arithmetic operations occur in this single expression. To evaluate the expression, C# must perform both operations: multiplication and addition. Which operation does C# perform first? Does it matter? Absolutely. If C# performs the multiplication before the addition, you end up with the following:
[[Image:13equ01.gif|150px|graphics/13equ01.gif]]
[[Image:13equ02.gif|162px|graphics/13equ02.gif]]
The final result would be that of C# printing 34. Now look at the same equation with the addition performed prior to multiplication:
[[Image:13equ03.gif|141px|graphics/13equ03.gif]]
[[Image:13equ04.gif|150px|graphics/13equ04.gif]]
In this case, C# would print 54�a drastically different number from the one computed when the multiplication is performed first. To prevent these types of errors, C# consistently performs arithmetic operations in the same order�the order of operator precedence (in this case, multiplication and then addition). [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/13.htm#ch13table01 Table 13.1] lists the order of operator precedence for arithmetic and Boolean operators. (Boolean operators are discussed later in this hour.) If you're familiar with algebra, you'll note that the order of precedence used by C# is the same as that used in algebraic formulas.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 13.1. C#'s Order of Operator Precedence, Highest to Lowest
|-
| Category
| Operators
|-
| Multiplicative
| <code>* / %</code>
|-
| Additive
| <code>+</code> <code>-</code>
|-
| Equality
| <code>==</code> (equal), <code>!=</code> (not equal)
|-
| Logical AND
| <code>&</code>
|-
| Logical XOR
| <code>^</code>
|-
| Logical OR
| <code>|</code>
|-
| Conditional AND
| <code>&&</code>
|-
| Conditional OR
| <code>||</code>
|-
| Conditional
| <code>?:</code>
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| Notice that two equal signs are used to denote equality, not one as you might expect.
|}
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| All comparison operators (discussed in the next section) have an equal precedence. When operators have an equal precedence, C# evaluates them from left to right. Notice that the multiplication and division operators have an equal precedence, so in an expression that has both, the operators would be evaluated from left to right. The same holds true for addition and subtraction. When expressions contain operators from more than one category (arithmetic, comparison, or logical), arithmetic operators are evaluated first, comparison operators are evaluated next, and logical operators are evaluated last.
|}
Just as when writing an equation on paper, you can use parentheses to override the order of operator precedence. Operations placed within parentheses are always evaluated first. Consider the previous example:
<pre>Debug.WriteLine(6 * 5 + 4);
</pre>
Using the order of operator precedence, C# evaluates the equation like this:
<pre>Debug.WriteLine((6 * 5) + 4);
</pre>
The multiplication is performed first, and then the addition. If you wanted the addition performed prior to the multiplication, you could write the statement like this:
<pre>Debug.WriteLine(6 * (5 + 4));
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| When writing complex expressions, you absolutely must keep in mind the order of operator precedence and use parentheses to override the default operator precedence when necessary. Personally, I try to always use parentheses so that I'm sure of what is happening and my code is easier to read.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Comparing Equalities
Comparing values, particularly variables, is even more common than performing arithmetic (but you need to know how C# arithmetic works before you can understand the evaluation of equalities).
Comparison operators are most often used in decision-making structures, as explained in the next hour. Indeed, these operators are best understood using a simple if decision structure. In an if construct, C# considers the expression on the if statement, and if the expression equates to true, the code statement(s) are executed. For example, the following is an if operation (a silly one at that) expressed in English, not in C# code:
IF DOGS BARK, THEN SMILE.
If this were in C# code format, C# would evaluate the if condition, which in this case is dogs bark. If the condition is found to be true, the code following the expression is Performing Arithmetic, String Manipulation, and Date/Time Adjustments performed. Because dogs bark, you'd smile. Notice how these two things (dogs barking and you smiling) are relatively unrelated. This doesn't matter; the point is that if the condition evaluates to true, certain actions (statements) occur.
You'll often compare the value of one variable to that of another variable or to a specific value when making decisions. The following are some basic comparisons and how C# evaluates them:
<pre>Debug.WriteLine(6 > 3); // Evaluates to true
Debug.WriteLine(3 == 4); // Evaluates to false
Debug.WriteLine(3 >= 3); // Evaluates to true
Debug.WriteLine(5 <= 4); // Evaluates to false
</pre>
Performing comparisons is pretty straightforward. If you get stuck writing a particular comparison, attempt to write it in English before creating it in code.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Understanding Boolean Logic
Boolean logic is a special type of arithmetic/comparison. Boolean logic is used to evaluate expressions down to either true or false. This may be a new concept to you, but don't worry; it's not difficult to understand. Boolean logic is performed using a logical operator. Consider the following sentence:
If black is a color and wood comes from trees then print "ice cream."
At first glance, it might seem that this is nonsensical. However, C# could make sense of this statement using Boolean logic. First, notice that three expressions are actually being evaluated within this single sentence. I've added parentheses in the following sentence to clarify two of the expressions. If (black is a color) and (wood comes from trees) then print "ice cream."
Boolean logic evaluates every expression to either true or false. Therefore, substituting true or false for each of these expressions yields the following:
if (true) And (true) then print "ice cream."
Now, for the sake of clarity, here is the same sentence with parentheses placed around the final expression to be evaluated:
If (True And True) then print "ice cream."
This is the point where the logical operators come into play. The And (&&) operator returns true if the expressions on each side of the And (&&) operator are true (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/13.htm#ch13table02 Table 13.2] for a complete list of logical operators). In the sentence we're considering, the expressions on both sides of the And (&&) operator are true, so the expression evaluates to true. Replacing the expression with true yields:
If True then print "ice cream."
This would result in the words "ice cream" being printed. If the expression had evaluated to false, nothing would be printed. As you'll see in the next hour, the decision constructs always fully evaluate their expressions to either true or false, and statements execute according to the results.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 13.2. Logical (Boolean) Operators
|-
| Operator
| Description
|-
| And (&&)
| Evaluates to true when the expressions on both sides are true.
|-
| Not (!)
| Evaluates to true when its expression evaluates to false; otherwise, it returns false (the true/false value of the expression is negated, or reversed).
|-
| Or (||)
| Evaluates to true if an expression on either side evaluates to true.
|-
| Xor (^)
| Evaluates to true if one, and only one, expression on either side evaluates to true.
|}
Each of these is discussed in the following sections.
Using the And (&&) Operator
The And (&&) operator is used to perform a logical conjunction. If the expressions on both sides of the And (&&) operator evaluate to true, the And (&&) operation evaluates to true. If either expression is false, the And (&&) operation evaluates to false, as illustrated in the following examples:
<pre>Debug.WriteLine(true && true); // Prints true
Debug.WriteLine(true && false); // Prints false
Debug.WriteLine(false && true); // Prints false
Debug.WriteLine(false && false); // Prints false
Debug.WriteLine((32 > 4) && (6 == 6)); // Prints true
</pre> Using the Not(!) Operator
The Not(!) operator performs a logical negation. That is, it returns the opposite of the expression. Consider the following examples:
<pre>Debug.WriteLine(! (true)); // Prints false
Debug.WriteLine(! (false)); // Prints true
Debug.WriteLine(! (5 == 5)); // Prints false
Debug.WriteLine(!(4 < 2)); // Prints true
</pre>
The first two statements are easy enough; the opposite of true is false and vice versa. For the third statement, remember that C#'s operator precedence dictates that arithmetic operators are evaluated first (even if no parentheses are used), so the first step of the evaluation would look like this:
<pre>Debug.WriteLine( ! (true));
</pre>
The opposite of true is false, of course, so C# prints false.
The fourth statement would evaluate to:
<pre>Debug.WriteLine( !(false));
</pre>
This happens because 4 is not less than 2, which is the expression C# evaluates first. Because the opposite of false is true, this statement would print true.
Using the Or (||) Operator
The Or(||) operator is used to perform a logical disjunction. If the expression to the left or right of the Or(||) operator evaluates to true, the Or(||) operation evaluates to true. The following are examples using Or(||) operations, and their results:
<pre>Debug.WriteLine(true || true); // Prints true
Debug.WriteLine(true || false); // Prints true
Debug.WriteLine(false || true); // Prints true
Debug.WriteLine(false || false); // Prints false
Debug.WriteLine((32 < 4) || (6 == 6)); // Prints true
</pre> Using the Xor (^) Operator
The Xor(^) operator performs a nifty little function. I personally haven't had to use it much, but it's great for those times when its functionality is required. If one�and only one�of the expressions on either side of the Xor(^) operator is true, the Xor(^) operation evaluates to true. Take a close look at the following statement examples to see how this works:
<pre>Debug.WriteLine(true ^ true); // Prints false
Debug.WriteLine(true ^ false); // Prints true
Debug.WriteLine(false ^ true); // Prints true
Debug.WriteLine(false ^ false); // Prints false
Debug.WriteLine((32 < 4) ^ (6 == 6)); // Prints true
</pre>
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Manipulating Strings
Recall from the previous hour that a string is text. Although string manipulation isn't technically arithmetic, the things that you do with strings are very similar to things you do with numbers, such as adding two strings together; string manipulation is much like creating equations. Chances are you'll be working with strings a lot in your applications. C# includes a number of methods that enable you to do things with strings, such as retrieve a portion of a string or find one string within another. In the following sections, you'll learn the basics of string manipulation.
Concatenating Strings of Text
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| C# makes it possible to "add" two strings of text together to form one string. Although purists will say it's not truly a form of arithmetic, it's very much like performing arithmetic on strings, so this hour was the logical place in which to present this material. The process of adding two strings together is called concatenation. Concatenation is very common. For example, you may want to concatenate variables with hard-coded strings to display meaningful messages to the user, such as <code>Are you sure you wish to delete the user XXX?</code>, where XXX is the contents of a variable.
|}
To concatenate two strings, you use the + operator as shown in this line of code:
<pre>Debug.WriteLine("This is" + "a test.");
</pre>
This statement would print:
<pre>This isa test.
</pre>
Notice that there is no space between the words is and a. You could easily add a space by including one after the word is in the first string or before the a in the second string, or you could concatenate the space as a separate string, like this:
<pre>Debug.WriteLine("This is" + " " + "a test.");
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:newterm.gif|85px|graphics/newterm.gif]]
| Text placed directly within quotes is called a literal. Variables are concatenated in the same way as literals and can even be concatenated with literals. The following code creates two variables, sets the value of the first variable to "Allan," and sets the value of the second variable to the result of concatenating the variable with a space and the literal "Reed":
|}
<pre>string strFullName;
string strFirstName = "Allan";
strFullName = strFirstName + " " + "Reed";
</pre>
The final result is that the variable strFullName contains the string Allan Reed. Get comfortable concatenating strings of text�you'll do this often.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| In C#, strings are immutable. What this means is that they never change. When you concatenate two strings together, neither is modified; instead a new string is created. Eventually, the garbage collector (discussed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch24.htm#ch24 Hour 24], "The 10,000-Foot View") will clean up the unused strings. However, if you're going to be concatenating a lot of strings, this could have an adverse effect on system resources (until the garbage collector springs into action). C# includes a highly efficient way to concatenate strings via <code>System.Text. StringBuilder</code>. Although I can't go into the details here, I highly encourage you to research this if you plan to concatenate a lot of strings at once.
|}
Using the Basic String Methods and Properties
The .NET Framework includes a number of functions that make working with strings of text considerably easier than it might be otherwise. These functions let you easily retrieve a piece of text from a string, compute the number of characters in a string, and even determine whether one string contains another. The following sections summarize the basic string functions.
Determining the Number of Characters Using Length
The Length property of the string object returns the variable's length. The following statement prints <code>26</code>, the total number of characters in the literal string <code>"Pink Floyd reigns supreme."</code> Remember, the quotes that surround the string tell C# that the text within them is a literal; they are not part of the string.
<pre>Debug.WriteLine(("Pink Floyd reigns supreme.").Length); // Prints 26
</pre> Retrieving Text from a String Using the Substring() Method
The Substring() method retrieves a part of a string.
The Substring() method can be used with the following parameters:
<pre>public string Substring(startposition,numberofcharacters);
</pre>
For example, the following statement prints <code>Queen</code>, the first five characters of the string.
<pre>Debug.WriteLine(("Queen to Queen's Level Three.").Substring(0,5));
</pre>
The arguments used in this Substring example are 0 and 5. The 0 indicates starting at the 0 position of the string (beginning). The <code>5</code> indicates the specified length to return (characters to retrieve).
The Substring() method is commonly used with the IndexOf() method (discussed shortly) to retrieve the path portion of a variable containing a filename and path combination, such as <code>c:\Myfile.txt</code>. If you know where the \character is, you can use Substring() to get the path.
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| If the number of characters requested is greater than the number of characters in the string, an exception (error) occurs. If you're unsure about the number of characters in the string, use the Length property of the string to find out. (Exception handling is reviewed in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/ch16.htm#ch16 Hour 16], "Debugging Your Code.")
|}
Determining Whether One String Contains Another Using IndexOf() Method
At times you'll need to determine whether one string exists within another. For example, suppose you let users enter their full name into a text box, and that you want to separate the first and last names before saving them into individual fields in a database. The easiest way to do this is to look for the space in the string that separates the first name from the last. You could use a loop to examine each character in the string until you find the space, but C# includes a string method that does this for you, faster and easier than you could do it yourself: the IndexOf() method. The basic IndexOf() method has the following syntax:
<pre>MyString.IndexOf(searchstring);
</pre>
The IndexOf() method of a string searches the string for the occurrence of a string passed as an argument. If the string is found, the location of character at the start of the string is returned. If the search string is not found within the other string, <code>-1</code> is returned. The IndexOf() method can be used with the following arguments:
* <code>public int IndexOf(</code><code>searchstring</code><code>);</code>
* <code>public int IndexOf(</code><code>searchstring, startinglocation</code><code>);</code>
* <code>public int IndexOf(</code><code>searchstring, startinglocation,</code> <code>numberofcharacterstosearch);</code>
The following code searches a variable containing the text <code>"Jayson Goss"</code>, locates the space, and uses the Substring() method and Length property to place the first and last names in separate variables.
<pre>string strFullName = "Jayson Goss";
string strFirstName, strLastName;
int intLocation, intLength;
intLength = strFullName.Length;
intLocation = strFullName.IndexOf(" ");
strFirstName = strFullName.Substring(0,intLocation );
strLastName = strFullName.Substring(intLocation + 1);
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bulb.gif|35px|graphics/bulb.gif]]
| This code assumes that a space will be found and that it won't be the first or last character in the string. In your applications, your code may need to be more robust, including checking to ensure that IndexOf() returned a value other than <code>-1</code>, which would indicate that no space was found.
|}
When this code runs, IndexOf() returns 6, the location in which the first space is found. Notice how I subtracted an additional character when using SubString() to initialize the strLastName variable; this was to take the space into account.
Trimming Beginning and Trailing Spaces from a String
As you work with strings, you'll often encounter situations in which spaces exist at the beginning or ending of strings. The .NET Framework includes the following four methods for automatically removing spaces from the beginning or end of a string:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Method
| Description
|-
| <code>String.Trim</code>
| Removes white spaces from the beginning and end of a string.
|-
| <code>String.TrimEnd</code>
| Removes characters specified in an array of characters from the end of a string.
|-
| <code>String.TrimStart</code>
| Removes characters specified in an array of characters from the beginning of a string.
|-
| <code>String.Remove</code>
| Removes a specified number of characters from a specified index position in a string.
|}
Working with Dates and Times
Dates are a unique beast. In some ways, they act like strings, in which you can concatenate and parse pieces. In other ways, dates seem more like numbers in that you can add to or subtract from them. Although you'll often perform math-type functions on dates (such as adding a number of days to a date or determining the number of months between two dates), you don't use the typical arithmetic operations. Instead, you use functions specifically designed for working with dates.
Understanding the DateTime Data Type
Working with dates is very common (suppose, for example, that you want your program to determine when a service contract expires). No matter the application, you'll probably need to create a variable to hold a date using the DateTime data type. You can get a date into a DateTime variable in several ways. Recall that when setting a string variable to a literal value, the literal is enclosed in quotes. When setting a numeric variable to a literal number, the number is not closed in quotes:
<pre>string strMyString = "This is a string literal" ;
int intMyInteger = 69 ;
</pre>
The more common way to set a DateTime variable to a literal date is to instantiate the variable passing in the date, like this (year, month, day):
<pre>DateTime objMyBirthday = new DateTime(1969,7,22);
</pre>
You cannot pass a string directly to a DateTime variable. For instance, if you let the user enter a date into a text box and you want to move the entry to a DateTime variable, you'll have to parse out the string to be able to adhere to one of the allowable DateTime constructors. The DateTime data type is one of the more complicated data types. This chapter will expose you to enough information to get started, but this is only the tip of the iceberg. I suggest reviewing the MSDN documentation of this curious data type for more information.
It's important to note that DateTime variables store a date and a time�always. For example, the following code:
<pre>DateTime objMyBirthday = new DateTime(1969,7,22);
Debug.WriteLine(objMyBirthday.ToString());
</pre>
Produces this output:
<pre>7/22/1969 12:00:00 AM
</pre>
Although a DateTime variable always holds a date and a time, on occasion, you'll only be concerned with either the date or the time. Notice that the previous example printed the time <code>12:00:00 AM</code>, even though no time was specified for the variable. This is the default time placed in a DateTime variable when only a date is specified. Later, I'll show you how to use the GetDateTimeFormats() method to retrieve just a date or a time.
Adding to or Subtracting from a Date or Time
To add a specific amount of time (such as one day or three months) to a specific date or time, you use methods of the DateTime class (see [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/13.htm#ch13table03 Table 13.3]). These methods do not change the value of the current DataTime variable; instead, they return a new DateTime instance whose value is the result of the operation.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 13.3. Available Data Adding Methods (Source MSDN)
|-
| Method
| Description
|-
| <code>Add</code>
| Adds the value of the specified TimeSpan instance to the value of this instance.
|-
| <code>AddDays</code>
| Adds the specified number of days to the value of this instance.
|-
| <code>AddHours</code>
| Adds the specified number of hours to the value of this instance.
|-
| <code>AddMilliseconds</code>
| Adds the specified number of milliseconds to the value of this instance.
|-
| <code>AddMinutes</code>
| Adds the specified number of minutes to the value of this instance.
|-
| <code>AddMonths</code>
| Adds the specified number of months to the value of this instance.
|-
| <code>AddSeconds</code>
| Adds the specified number of seconds to the value of this instance.
|-
| <code>AddYears</code>
| Adds the specified number of years to the value of this instance.
|}
For instance, to add six months to the date 7/22/69, you could use the following statements:
<pre>DateTime objMyBirthday = new DateTime(1969,7,22);
DateTime objNewDate = objMyBirthday.AddMonths(6);
</pre>
After this second statement executes, <code>objNewDate</code> contains the date <code>1/22/1970 12:00:00 AM</code>.
The following code shows sample addition methods and the date they would return:
<pre>objNewDate = objMyBirthday.AddYears(2); // Returns 7/22/1971 12:00:00 AM
objNewDate = objMyBirthday.AddMonths(5); // Returns 12/22/1971 12:00:00 AM
objNewDate = objMyBirthday.AddMonths(-1); // Returns 6/22/1971 12:00:00 AM
objNewDate = objMyBirthday.AddHours(7); // Returns 7/22/1969 7:00:00 AM
</pre> Retrieving Parts of a Date
Sometimes, it can be extremely useful to know just a part of a date. For example, you may have let a user enter his or her birth date, and you want to perform an action based on the month in which they were born. To retrieve part of a date, the DateTime class exposes properties such as Month, Day, Year, Hour, Minute, Second, and so on.
The following should illustrate the retrieval of some properties of the DateTime class(the instance date is still 7/21/1969):
<pre>objMyBirthday.Month // Returns 7
objMyBirthday.Day // Returns 22
objMyBirthday.DayOfWeek // Returns DayOfWeek.Monday
</pre>
{| cellspacing="0" cellpadding="0" border="0"
|-
| [[Image:bookpencil.gif|80px|graphics/bookpencil.gif]]
| The Hour property will return the hour in military format. Also, note that DayOfWeek returns an enumerated value.
|}
Formatting Dates and Times
As I stated earlier, at times you'll want to work with only the date or a time within a DateTime variable. In addition, you'll probably want to control the format in which a date or time is displayed. All this and more can be accomplished via the DateTime class by way of the following:
* Using the DateTime methods to retrieve formatted strings
* Using standard-format strings
* Using custom-format strings
I can't possibly show you everything regarding formatting a DateTime value here, but I do want to show you how to use formatting to output either the date portion or the time portion of a DateTime variable. (The DateTime class is comprehensive; you'll most likely want to investigate it more thoroughly as you continue in your programming efforts.)
The following illustrates some basic formatting methods available with the DateTime class. (Note that the instance date is still 7/22/1969 12:00:00 AM)
<pre>objMyBirthday.ToLongDateString(); // Returns Monday, July 21, 1969
objMyBirthday.ToShortDateString(); // Returns 7/21/1969
objMyBirthday.ToLongTimeString(); // Returns 12:00:00 AM
objMyBirthday.ToShortTimeString(); // Returns 12:00 AM
</pre> Retrieving the Current System Date and Time
C# gives you the capability to retrieve the current system date and time. Again, this is accomplished by way of the DateTime class. For example, the Today property returns the current system date. To place the current system date into a new DateTime variable, for example, you could use a statement such as this:
<pre>DateTime objToday = DateTime.Today;
</pre>
To retrieve the current system date and time, use the Now property of DateTime, like this:
<pre>DateTime objToday = DateTime.Now;
</pre>
Commit DateTime.Today and DateTime.Now to memory. You'll need to retrieve the system date and/or time in an application, and this is by far the easiest way to get that information.
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Summary
Being able to work with all sorts of data is crucial to your success as a C# developer. Just as you need to understand basic math to function in society, you need to be able to perform basic math in code to write even the simplest of applications. Knowing the arithmetic operators and understanding the order of operator precedence will take you a long way in performing math using C# code.
Boolean logic is a special form of evaluation used by C# to evaluate simple and complex expressions alike down to a value of true or false. In the following hours, you'll learn how to create loops and how to perform decisions in code. What you learned here about Boolean logic is critical to your success with loops and decision structures; you'll use Boolean logic perhaps even more often than you'll perform arithmetic.
Manipulating strings and dates each takes special considerations. In this hour, you learned how to work with both types of data to extract portions of values and to add pieces of data together to form a new whole. String manipulation is pretty straightforward, and you'll get the hang of it soon enough as you start to use some of the string functions. Date manipulation, on the other hand, can be a bit tricky. Even experienced developers need to refer to the online help at times. You learned the basics in this hour, but don't be afraid to experiment on your own.
Q&A
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/13.htm#qad1e44138 Q1:]'''
| Should I always specify parentheses to ensure that operators are evaluated as I expect them to be?
|-
| align="right" | ''' A1: '''
| C# never fails to evaluate expressions according to the order of operator precedence, so using parentheses isn't necessary when the order of precedence is correct for an expression. However, using parentheses assures you that the expression is being evaluated and may make the expression easier to read by other people. This really is your choice.
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/13.htm#qad1e44148 Q2:]'''
| I would like to learn more about the properties and methods available in the DateTime structure; where can I find all the members listed?
|-
| align="right" | ''' A2: '''
| I would look at the DateTime members documentation found within the .NET Framework documentation. This is available on the MSDN and as an installable option when installing Visual Studio .NET.
|}
{| cellspacing="0" cellpadding="0" border="0"
| align="right" | >
|}
Workshop
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01.htm#app01 Appendix A],"Answers to Quizzes/Exercises."
Quiz
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans01 1:]'''
| To get only the remainder of a division operation, you use which operator?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans02 2:]'''
| Which operation is performed first in the following expression�the addition or the multiplication?
[[Image:13equ05.gif|178px|graphics/13equ05.gif]]
<br />
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans03 3:]'''
| Does this expression evaluate to true or to false?
<pre>((true || true) && false) == !true<br /></pre>
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans04 4:]'''
| Which Boolean operator performs a logical negation?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans05 5:]'''
| The process of appending one string to another is called?
|-
| align="right" | '''[file:///C:/Documents%20and%20Settings/dani/Asztal/c%23in24h/app01lev1sec13.htm#ch13ans06 6:]'''
| What property can be used to return the month of a given date?
|}
Exercises
# Create a project that has a single text box on a form. Assume the user enters a first name, a middle initial, and a last name into the text box. Parse the contents into three variables�one for each part of the name.
# Create a project that has a single text box on a form. Assume the user enters a valid birthday into the text box. Use the date functions as necessary to tell the user the number of the month in which they were born.
j6p3n2qezysrio701la37d3lwd18ulp
User:Moncur/11
2
2157
39276
6010
2026-04-13T06:03:47Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39276
wikitext
text/x-wiki
= 11. Getting Data with Forms =
== The Basics of HTML Forms ==
Forms are among the most useful features of the HTML language. As you'll learn during this hour, adding JavaScript to forms can make them more interactive and provide a number of useful features. The first step in creating an interactive form is to create the HTML form itself.
=== Defining a Form ===
An HTML form begins with the <code><form></code> tag. This tag indicates that a form is beginning, and it enables form elements to be used. The <code><form></code> tag includes several attributes:
* <code>name</code> is simply a name for the form. You can use forms without giving them names, but you'll need to assign a name to a form in order to easily use it with JavaScript.
* <code>method</code> is either <code>GET</code> or <code>POST</code>; these are the two ways the data can be sent to the server.
* <code>action</code> is the CGI script that the form data will be sent to when submitted. You can also use the <code>mailto:</code> action to send the form's results to an email address, as described later in this hour.
* <code>enctype</code> is the MIME type the form's data will be encoded with. This is usually not necessary; see the "[Sending Form Results by Email]" section of this hour for an example that requires it.
For example, here is a <code><form></code> tag for a form named <code>Order</code>. This form uses the <code>GET</code> method and sends its data to a CGI script called <code>order.cgi</code> in the same directory as the web page itself:
<pre><form name="Order" method="GET" action="order.cgi"></pre>
For a form that will be processed entirely by JavaScript (such as a calculator or an interactive game), the <code>method</code> and <code>action</code> attributes are not needed. You can use a simple <code><form></code> tag that names the form:
<pre><form name="calcform"></pre>
The <code><form></code> tag is followed by one or more form elements. These are the data fields in the form, such as text fields, buttons, and check boxes. In the next section, you'll learn how JavaScript assigns objects to each of the form elements.
== Using the <code>form</code> Object with JavaScript ==
Each form in your HTML page is represented in JavaScript by a <code>form</code> object, which has the same name as the <code>NAME</code> attribute in the <code><form></code> tag you used to define it.
Alternatively, you can use the <code>forms</code> array to refer to forms. This array includes an item for each form element, indexed starting with 0. For example, if the first form in a document has the name <code>form1</code>, you can refer to it in one of two ways:
<pre>document.form1
document.forms[0]
</pre>
=== The <code>form</code> Object's Properties ===
Along with the elements, each <code>form</code> object also has a list of properties, most of which are defined by the corresponding <code><form></code> tag. You can also set these from within JavaScript. They include the following:
* <code>action</code> is the form's <code>action</code> attribute, or the program to which the form data will be submitted.
* <code>encoding</code> is the <code>MIME</code> type of the form, specified with the <code>enctype</code> attribute. In most cases, this is not needed. See the "[Sending Form Results by Email]" section of this hour for an example of its use.
* <code>length</code> is the number of elements in the form. You cannot change this property.
* <code>method</code> is the method used to submit the form, either <code>GET</code> or <code>POST</code>. This determines the data format used to send the form result to a CGI script, and does not affect JavaScript.
* <code>target</code> specifies the window in which the result of the form (from the CGI script) will be displayed. Normally, this is done in the main window, replacing the form itself, but you can use this attribute to work with pop-up windows or frames.
=== Submitting and Resetting Forms ===
The <code>form</code> object has two methods, <code>submit()</code> and <code>reset()</code>. You can use these methods to submit the data or reset the form yourself, without requiring the user to press a button. One reason for this is to submit the form when the user clicks an image or performs another action that would not usually submit the form.
; Watch Out!: If you use the <code>submit()</code> method to send data to a server or by email, most browsers will prompt the user to verify that he or she wants to submit the information. There's no way to do this behind the user's back.
=== Detecting Form Events ===
The <code>form</code> object has two event handlers, <code>onSubmit</code> and <code>onReset</code>. You can specify a group of JavaScript statements or a function call for these events within the <code><form></code> tag that defines the form.
If you specify a statement or a function for the <code>onSubmit</code> event, the statement is called before the data is submitted to the CGI script. You can prevent the submission from happening by returning a value of <code>false</code> from the <code>onSubmit</code> event handler. If the statement returns <code>true</code>, the data will be submitted. In the same fashion, you can prevent a Reset button from working with an <code>onReset</code> event handler.
== Scripting Form Elements ==
The most important property of the <code>form</code> object is the <code>elements</code> array, which contains an object for each of the form elements. You can refer to an element by its own name or by its index in the array. For example, the following two expressions both refer to the first element in the <code>order</code> form, the <code>name1</code> text field:
<pre>document.order.elements[0]
document.order.name1
</pre>
; By the Way: Both forms and elements can be referred to by their own names or as indices in the <code>forms</code> and <code>elements</code> arrays. For clarity, the examples in this hour use individual form and element names rather than array references. You'll also find it easier to use names in your own scripts.
If you do refer to forms and elements as arrays, you can use the <code>length</code> property to determine the number of objects in the array: <code>document.forms.length</code> is the number of forms in a document, and <code>document.form1.elements.length</code> is the number of elements in the <code>form1</code> form.
You can also access form elements using the W3C DOM. In this case, you use an <code>id</code> attribute on the form element in the HTML document, and use the <code>document.getElementById()</code> method to find the object for the form. For example, this statement finds the object for the text field called <code>firstname</code> and stores it in the <code>fn</code> variable:
<pre>fn = document.getElementById("firstname");</pre>
This allows you to quickly access a form element without first finding the <code>form</code> object. You can assign an <code>id</code> to the <code><form></code> tag and find the corresponding object if you need to work with the form's properties and methods.
; Did you Know?: See [Hour 13], "Using the W3C DOM," for details on the <code>document.getElementById()</code> method.
=== Text Fields ===
Probably the most commonly used form elements are text fields. You can use them to prompt for a name, an address, or any information. With JavaScript, you can display text in the field automatically. The following is an example of a simple text field:
<pre><input type="TEXT" name="text1" value="hello" size="30"></pre>
This defines a text field called <code>text1</code>. The field is given a default value of <code>"hello"</code> and allows up to 30 characters to be entered. JavaScript treats this field as a <code>text</code> object with the name <code>text1</code>.
Text fields are the simplest to work with in JavaScript. Each <code>text</code> object has the following properties:
* <code>name</code> is the name given to the field. This is also used as the object name.
* <code>defaultValue</code> is the default value and corresponds to the <code>VALUE</code> attribute. This is a read-only property.
* <code>value</code> is the current value. This starts out the same as the default value, but can be changed, either by the user or by JavaScript functions.
When you work with text fields, most of the time you will use the <code>value</code> attribute to read the value the user has entered or to change the value. For example, the following statement changes the value of a text field called <code>username</code> in the <code>order</code> form to <code>"John Q. User"</code>:
<pre>document.order.username.value = "John Q. User"</pre>
=== Text Areas ===
Text areas are defined with their own tag, <code><textarea></code>, and are represented by the <code>textarea</code> object. There is one major difference between a text area and a text field: Text areas enable the user to enter more than just one line of information. Here is an example of a text area definition:
<pre><textarea name="text1" rows="2" cols="70">
This is the content of the TEXTAREA tag.
</textarea>
</pre>
This HTML defines a text area called <code>text1</code>, with two rows and 70 columns available for text. In JavaScript, this would be represented by a text area object called <code>text1</code> under the <code>form</code> object.
The text between the opening and closing <code><textarea></code> tags is used as the initial value for the text area. You can include line breaks within the default value with the special character <code>\n</code>.
=== Working with Text in Forms ===
The <code>text</code> and <code>textarea</code> objects also have a few methods you can use:
* <code>focus()</code> sets the focus to the field. This positions the cursor in the field and makes it the current field.
* <code>blur()</code> is the opposite; it removes the focus from the field.
* <code>select()</code> selects the text in the field, just as a user can do with the mouse. All of the text is selected; there is no way to select part of the text.
You can also use event handlers to detect when the value of a text field changes. The <code>text</code> and <code>textarea</code> objects support the following event handlers:
* The <code>onFocus</code> event happens when the text field gains focus.
* The <code>onBlur</code> event happens when the text field loses focus.
* The <code>onChange</code> event happens when the user changes the text in the field and then moves out of it.
* The <code>onSelect</code> event happens when the user selects some or all of the text in the field. Unfortunately, there's no way to tell exactly which part of the text was selected. (If the text is selected with the <code>select()</code> method described previously, this event is not triggered.)
If used, these event handlers should be included in the <code><input></code> tag declaration. For example, the following is a text field including an <code>onChange</code> event that displays an alert:
<pre><input type="TEXT" name="text1" onChange="window.alert('Changed.');"></pre>
=== Buttons ===
One of the most useful types of form element is a button. Buttons use the <code><input></code> tag and can use one of three different types:
* <code>type=SUBMIT</code> is a Submit button. This button causes the data in the form fields to be sent to the CGI script.
* <code>type=RESET</code> is a Reset button. This button sets all the form fields back to their default value, or blank.
* <code>type=BUTTON</code> is a generic button. This button performs no action on its own, but you can assign it one using a JavaScript event handler.
All three types of buttons include a <code>name</code> attribute to identify the button and a <code>value</code> attribute that indicates the text to display on the button's face. A few buttons were used in the examples in [Hour 10], "Using Windows and Frames." As another example, the following defines a Submit button with the name <code>sub1</code> and the value <code>"Click Here"</code>:
<pre><input type="SUBMIT" name="sub1" value="Click Here"></pre>
If the user presses a Submit or a Reset button, you can detect it with the <code>onSubmit</code> or <code>onReset</code> event handlers, described earlier in this hour. For generic buttons, you can use an <code>onClick</code> event handler.
=== Check Boxes ===
A check box is a form element that looks like a small box. Clicking on the check box switches between the checked and unchecked states, which is useful for indicating Yes or No choices in your forms. You can use the <code><input></code> tag to define a check box. Here is a simple example:
<pre><input type="CHECKBOX" name="check1" value="Yes" checked></pre>
Again, this gives a name to the form element. The <code>value</code> attribute assigns a meaning to the check box; this is a value that is returned to the server if the box is checked. The default value is "on." The <code>checked</code> attribute can be included to make the box checked by default.
A check box is simple: It has only two states. Nevertheless, the <code>checkbox</code> object in JavaScript has four different properties:
* <code>name</code> is the name of the check box, and also the object name.
* <code>value</code> is the "true" value for the check box—usually <code>on</code>. This value is used by server-side programs to indicate whether the check box was checked. In JavaScript, you should use the <code>checked</code> property instead.
* <code>defaultChecked</code> is the default status of the check box, assigned by the <code>checked</code> attribute in HTML.
* <code>checked</code> is the current value. This is a Boolean value: <code>true</code> for checked and <code>false</code> for unchecked.
To manipulate the check box or use its value, you use the <code>checked</code> property. For example, this statement turns on a check box called <code>same</code> in the <code>order</code> form:
<pre>document.order.same.checked = true;</pre>
The check box has a single method, <code>click()</code>. This method simulates a click on the box. It also has a single event, <code>onClick</code>, which occurs whenever the check box is clicked. This happens whether the box was turned on or off, so you'll need to examine the <code>checked</code> property to see what happened.
=== Radio Buttons ===
Another element for decisions is the radio button, using the <code><input></code> tag's <code>RADIO</code> type. Radio buttons are also known as option buttons. These are similar to check boxes, but they exist in groups and only one button can be checked in each group. They are used for a multiple-choice or "one of many" input. Here's an example of a group of radio buttons:
<pre><input type="RADIO" name="radio1" value="Option1" checked> Option 1
<input type="RADIO" name="radio1" value="Option2"> Option 2
<input type="RADIO" name="radio1" value="Option3"> Option 3
</pre>
These statements define a group of three radio buttons. The <code>name</code> attribute is the same for all three (which is what makes them a group). The <code>value</code> attribute is the value passed to a script or a CGI program to indicate which button is selected—be sure you assign a different value to each button.
; By the Way: Radio buttons are named for their similarity to the buttons on old pushbutton radios. Those buttons used a mechanical arrangement so that when you pushed one button in, the others popped out.
As for scripting, radio buttons are similar to check boxes, except that an entire group of them shares a single name and a single object. You can refer to the following properties of the <code>radio</code> object:
* <code>name</code> is the name common to the radio buttons.
* <code>length</code> is the number of radio buttons in the group.
To access the individual buttons, you treat the <code>radio</code> object as an array. The buttons are indexed, starting with <code>0</code>. Each individual button has the following properties:
* <code>value</code> is the value assigned to the button. (This is used by the server.)
* <code>defaultChecked</code> indicates the value of the <code>checked</code> attribute and the default state of the button.
* <code>checked</code> is the current state.
For example, you can check the first radio button in the <code>radio1</code> group on the <code>form1</code> form with this statement:
<pre>document.form1.radio1[0].checked = true;</pre>
However, if you do this, be sure you set the other values to <code>false</code> as needed. This is not done automatically. You can use the <code>click()</code> method to do both of these in one step.
Like a check box, radio buttons have a <code>click()</code> method and an <code>onClick</code> event handler. Each radio button can have a separate statement for this event.
; Did you Know?: You can have more than one group of radio buttons on a page, and they will act independently. Assign a separate <code>name</code> attribute value to each group.
=== Drop-Down Lists ===
A final form element is also useful for multiple-choice selections. The <code><select></code> HTML tag is used to define a selection list, or a drop-down list of text items. The following is an example of a selection list:
<pre><select name="select1" SIZE="40">
<option value="choice1" SELECTED>This is the first choice.
<option value="choice2">This is the second choice.
<option value="choice3">This is the third choice.
</select>
</pre>
Each of the <code><option></code> tags defines one of the possible choices. The <code>value</code> attribute is the name that is returned to the program, and the text outside the <code><option></code> tag is displayed as the text of the option.
An optional attribute to the <code><select></code> tag, <code>multiple</code>, can be specified to allow multiple items to be selected. Browsers usually display a single-selection <code><select></code> as a drop-down list and a multiple-selection list as a scrollable list.
The object for selection lists is the <code>select</code> object. The object itself has the following properties:
* <code>name</code> is the name of the selection list.
* <code>length</code> is the number of options in the list.
* <code>options</code> is the array of options. Each selectable option has an entry in this array.
* <code>selectedIndex</code> returns the index value of the currently selected item. You can use this to check the value easily. In a multiple-selection list, this indicates the first selected item.
The <code>options</code> array has a single property of its own, <code>length</code>, which indicates the number of selections. In addition, each item in the <code>options</code> array has the following properties:
* <code>index</code> is the index into the array.
* <code>defaultSelected</code> indicates the state of the <code>selected</code> attribute.
* <code>selected</code> is the current state of the option. Setting this property to <code>true</code> selects the option. The user can select multiple options if the <code>multiple</code> attribute is included in the <code><select></code> tag.
* <code>name</code> is the value of the <code>name</code> attribute. This is used by the server.
* <code>text</code> is the text that is displayed in the option.
The <code>select</code> object has two methods—<code>blur()</code> and <code>focus()</code>—which perform the same purposes as the corresponding methods for <code>text</code> objects. The event handlers are <code>onBlur</code>, <code>onFocus</code>, and <code>onChange</code>, also similar to other objects.
; By the Way: You can change selection lists dynamically—for example, choosing a product in one list could control which options are available in another list. You can also add and delete options from the list.
Reading the value of a selected item is a two-step process. You first use the <code>selectedIndex</code> property, and then use the <code>value</code> property to find the value of the selected choice. Here's an example:
<pre>ind = document.navform.choice.selectedIndex;
val = document.navform.choice.options[ind].value;
</pre>
This uses the <code>ind</code> variable to store the selected index, and then assigns the <code>val</code> variable to the value of the selected choice. Things are a bit more complicated with a multiple selection: You have to test each option's <code>selected</code> attribute separately.
== Displaying Data from a Form ==
As a simple example of using forms, [Listing 11.1] shows a form with name, address, and phone number fields, as well as a JavaScript function that displays the data from the form in a pop-up window.
; Listing 11.1. A Form That Displays Data in a Pop-up Window
<pre><html>
<head>
<title>Form Example</title>
<script language="JavaScript" type="text/javascript">
function display() {
DispWin = window.open('','NewWin',
'toolbar=no,status=no,width=300,height=200')
message = "<ul><li><b>NAME: </b>" + document.form1.yourname.value;
message += "<li><b>ADDRESS: </b>" + document.form1.address.value;
message += "<li><b>PHONE: </b>" + document.form1.phone.value + "</ul>";
DispWin.document.write(message);
}
</script>
</head>
<body>
<h1>Form Example</h1>
Enter the following information. When you press the Display button,
the data you entered will be displayed in a pop-up window.
<form name="form1">
<p><b>Name:</b> <input type="TEXT" size="20" name="yourname">
</p>
<p><b>Address:</b> <input type="TEXT" size="30" name="address">
</p>
<p><b>Phone: </b> <input type="TEXT" size="15" name="phone">
</p>
<p><input type="BUTTON" value="Display" onClick="display();"></p>
</form>
</body>
</html>
</pre>
Here is a breakdown of how this HTML document and script work:
* The <code><script></code> section in the document's header defines a function called <code>display()</code> that opens a new window (as described in [Hour 10]) and displays the information from the form.
* The <code><form></code> tag begins the form. Because this form is handled entirely by JavaScript, no form action or method is needed.
* The <code><input></code> tags define the form's three fields: <code>yourname</code>, <code>address</code>, and <code>phone</code>. The last <code><input></code> tag defines the Display button, which is set to run the <code>display()</code> function.
; Did you Know?: As usual, you can download the listings for this hour from this book's website.
[Figure 11.1] shows this form in action. The Display button has been pressed, and the pop-up window shows the results.
== Sending Form Results by Email ==
One easy way to use a form is to send the results by email. You can do this without using any JavaScript, although you could use JavaScript to validate the information entered (as you'll learn later in this hour).
To send a form's results by email, you use the <code>mailto:</code> action in the form's <code>action</code> attribute. [Listing 11.2] is a modified version of the name and address form from [Listing 11.1] that sends the results by email.
; Listing 11.2. Sending a Form's Results by Email
<pre><html>
<head>
<title>Email Form Example</title>
</head>
<body>
<h1>Email Form Example</h1>
Enter the following information. When you press the Submit button,
the data you entered will be sent by email.
<form name="form1" action="mailto:user@host.com" enctype="text/plain" method="POST">
<p><b>Name:</b> <input type="TEXT" size="20" name="yourname">
</p>
<p><b>Address:</b> <input type="TEXT" size="30" name="address">
</p>
<p><b>Phone: </b> <input type="TEXT" size="15" name="phone">
</p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
</pre>
To use this form, change <code>user@host.com</code> in the <code>action</code> attribute of the <code><form></code> tag to your email address. Notice the <code>enctype=text/plain</code> attribute in the <code><form></code> tag. This ensures that the information in the email message will be in a readable plain-text format rather than encoded.
Although this provides a quick and dirty way of retrieving data from a form, the disadvantage of this technique is that it is highly browser dependent. Whether it will work for each user of your page depends on the configuration of his or her browser and email client.
; Watch Out!: Because this technique does not consistently work on all browsers, I don't recommend you use it. For a more reliable way of sending form results, you can use a CGI form-to-email gateway. Several free CGI scripts and services are available. You'll find links to them on this book's website.
== Try It Yourself Validating a Form ==
One of JavaScript's most useful purposes is validating forms. This means using a script to verify that the information entered is valid—for example, that no fields are blank and that the data is in the right format.
You can use JavaScript to validate a form whether it's submitted by email or to a CGI script, or is simply used by a script. [Listing 11.3] is a version of the name and address form that includes validation.
; Listing 11.3. A Form with a Validation Scrip
<pre><html>
<head>
<title>Form Example</title>
<script language="JavaScript" type="text/javascript">
function validate() {
if (document.form1.yourname.value.length < 1) {
alert("Please enter your full name.");
return false;
}
if (document.form1.address.value.length < 3) {
alert("Please enter your address.");
return false;
}
if (document.form1.phone.value.length < 3) {
alert("Please enter your phone number.");
return false;
}
return true;
}
</script>
</head>
<body>
<h1>Form Example</h1>
<p>Enter the following information. When you press the Submit button,
the data you entered will be validated, then sent by email.</p>
<form name="form1" action="mailto:user@host.com" enctype="text/plain" method="POST" onSubmit="return validate();">
<p><b>Name:</b> <input type="TEXT" size="20" name="yourname">
</p>
<p><b>Address:</b> <input type="TEXT" size="30" name="address">
</p>
<p><b>Phone: </b> <input type="TEXT" size="15" name="phone">
</p>
<p><input type="SUBMIT" value="Submit"></p>
</form>
</body>
</html>
</pre>
This form uses a function called <code>validate()</code> to check the data in each of the form fields. Each <code>if</code> statement in this function checks a field's length. If the field is long enough to be valid, the form can be submitted; otherwise, the submission is stopped and an alert message is displayed.
; By the Way: The validation in this script is basic—you could go further and ensure that the <code>phone</code> field contains only numbers, and the right amount of digits, by using JavaScript's string features described in [Hour 5], "Using Variables, Strings, and Arrays."
This form is set up to send its results by email, as in [Listing 11.2]. If you wish to use this feature, be sure to read the information about email forms earlier in this hour and change <code>user@host.com</code> to your desired email address.
The <code><form></code> tag uses an <code>onSubmit</code> event handler to call the <code>validate()</code> function. The <code>return</code> keyword ensures that the value returned by <code>validate()</code> will determine whether the form is submitted.
; Did you Know?: You can also use the <code>onChange</code> event handler in each form field to call a validation routine. This allows the field to be validated before the Submit button is pressed.
[Figure 11.2] shows this script in action, as displayed by Firefox. The form has been filled out except for the name, and a dialog box indicates that the name needs to be entered.
== Summary ==
During this hour, you've learned all about HTML forms and how they can be used with JavaScript. You learned about the <code>form</code> object and the objects for the various form elements, and used them in several example scripts.
You also learned how to submit a form by email, and how to use JavaScript to validate a form before it is submitted.
In the next hour, you'll look at CSS (Cascading Style Sheets)—a standards-compliant way to achieve just about any visual effect on a page, and the foundation for using JavaScript to change a page's appearance.
=== Q&A ===
; Q1: If I use JavaScript to add validation and other features to my form, can users with non-JavaScript browsers still use the form?
; A1: Yes, if you're careful. Be sure to use a Submit button rather than the <code>submit</code> action. Also, the CGI script might receive nonvalidated data, so be sure to include the same validation in the CGI script. Non-JavaScript users will be able to use the form, but won't receive instant feedback about their errors.
; Q2: Can I add new form elements on the fly or change them—for example, change a text box into a password field?
; A2: Not in the traditional way described in this hour. However, you can change any aspect of a page, including adding, removing, or changing form elements, using the W3C DOM. See [Hour 13] for details.
; Q3: Is there any way to create a large number of text fields without dealing with different names for all of them?
; A3: Yes. If you use the same name for several elements in the form, their objects will form an array. For example, if you defined 20 text fields with the name <code>member</code>, you could refer to them as <code>member[0]</code> through <code>member[19]</code>. This also works with other types of form elements.
; Q4: Is there a way to place the cursor on a particular field when the form is loaded, or after my validation routine displays an error message?
; A4: Yes. You can use the field's <code>focus()</code> method to send the cursor there. To do this when the page loads, you can use the <code>onLoad</code> method in the <code><body></code> tag. However, there is no way to place the cursor in a particular position within the field.
=== Quiz Questions ===
Test your knowledge of JavaScript and forms by answering the following questions.
''' 1:''' Which of these attributes of a <code><form></code> tag determines where the data will be sent?
# <code>action</code>
# <code>method</code>
# <code>name</code>
'''2:''' Where do you place the <code>onSubmit</code> event handler to validate a form?
# In the <code><body></code> tag
# In the <code><form></code> tag
# In the <code><input></code> tag for the Submit button
''' 3:''' What can JavaScript do with forms that a CGI script can't?
# Cause all sorts of problems
# Give the user instant feedback about errors
# Submit the data to a server
=== Quiz Answers ===
'''1.''' a. The <code>action</code> attribute determines where the data is sent.
''' 2.''' b. You place the <code>onSubmit</code> event handler in the <code><form></code> tag.
''' 3.''' b. JavaScript can validate a form and let the user know about errors immediately, without waiting for a response from a server.
=== Exercises ===
To further explore the JavaScript features you learned about in this hour, you can perform the following exercises:
* Change the <code>validate</code> function in [Listing 11.3] so that after a message is displayed indicating that a field is wrong, the cursor is moved to that field. (Use the <code>focus()</code> method for the appropriate form element.)
* Add a text field to the form in [Listing 11.3] for an email address. Add a feature to the <code>validate</code> function that verifies that the email address is at least five characters and that it contains the <code>@</code> symbol.
j618hyodv3m8nhjbws5wd1q9elenle4
User:Moncur/12
2
2158
39277
6084
2026-04-13T06:03:47Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39277
wikitext
text/x-wiki
<!- -
=12. Working with Style Sheets=
== Style and Substance ==
If you've ever tried to make a really good-looking web page, you've probably encountered some problems. First of all, HTML doesn't give you very much control over a page's appearance. For example, you can't change the amount of space between words—in fact, you can't even use two spaces between words because they'll be converted to a single space.
Second, even when you do your best to make a perfect-looking document using HTML, you will find that it doesn't necessarily display the same way on all browsers—or even on different computers running the same browser.
The reason for these problems is simple: HTML was never meant to handle such things as layout, justification, and spacing. HTML deals with a document's structure—in other words, how the document is divided into paragraphs, headings, lists, and other elements.
This isn't a bad thing. In fact, it's one of the most powerful features of HTML. You only define the structure of the document, so it can be displayed in all sorts of different ways without changing its meaning. For example, a well-written HTML document can be displayed in Netscape, Firefox, or Internet Explorer, which generally treat elements the same way—there is a space between paragraphs, headings are in big, bold text, and so on.
Because HTML only defines the structure, the same document can be displayed in a text-based browser, such as Lynx. In this case, the different elements will be displayed differently, but you can still tell which text is a heading, which is a list, and so on.
; By the Way: Text-based browsers aren't the only alternative way of displaying HTML. Browsers designed for the blind can read a web page using a speech synthesizer, with different voices or sounds that indicate the different elements.
As you should now understand, HTML is very good at its job—defining a document's structure. Not surprisingly, using this language to try to control the document's presentation will only drive you crazy.
Fortunately, the World Wide Web Consortium (W3C) realized that web authors need to control the layout and presentation of documents. This resulted in the Cascading Style Sheets (CSS) standard.
CSS adds a number of features to standard HTML to control style and appearance. More importantly, it does this without affecting HTML's capability to describe document structures. Although style sheets still won't make your document look 100% identical on all browsers and all platforms, it is certainly a step in the right direction.
Let's look at a real-world example. If you're browsing the Web with a CSS-supported browser and come across a page that uses CSS, you'll see the document exactly as it was intended. You can also turn off your browser's support for style sheets if you'd rather view all the pages in the same consistent way.
; Did you Know?: Using CSS and simplifying HTML markup is also helpful in making pages compatible with the various tiny browsers used on mobile phones.
== Defining and Using CSS Styles ==
You can define a CSS style sheet within an HTML document using the <code><style></code> tag. The opening <code><style></code> tag specifies the type of style sheet—CSS is currently the only valid type—and begins a list of styles to apply to the document. The <code></style></code> tag ends the style sheet. Here's a simple example:
<pre><style type="text/css">
H1 {color: blue;}
</style>
</pre>
Because the style sheet definition itself doesn't create any output on the page, you should place the <code><style></code> tags in the <code><head></code> section of the HTML document.
; Watch Out!: You can only use style sheet rules within the <code><style></code> tags. HTML tags are not valid within a style sheet.
=== Creating Rules ===
Each element within the <code><style></code> tags is called a rule. To create a rule, you specify the HTML elements that it will affect, as well as a list of properties and values that control the appearance of those elements. We'll look at the properties in the next section.
As a simple example, the following style sheet contains a single rule. All Level 1 headings are blue:
<pre><style type="text/css">
H1 {color: blue;}
</style>
</pre>
Each rule includes three components:
* A selector (<code>H1</code> in the example) describing which HTML tags will be affected
* One or more property names (<code>color</code> in the example)
* A value for each property name (<code>blue</code> in the example)
Each rule uses braces to surround the list of properties and values, and a semicolon after each value. The semicolon is optional if you are only specifying one property and value.
You can specify multiple HTML tags for the selector, as well as multiple properties and values. For example, the following style sheet specifies that all headings are blue, italic, and centered:
<pre><style type="text/css">
H1,H2,H3,H4,H5,H6 {color: blue;
font-style: italic;
text-align: center; }
</style>
</pre>
; By the Way: If you make a rule that sets the style of the <code><body></code> tag, it will affect the entire document. This becomes the default rule for the document, but you can override it with the styles of elements within the body of the page.
=== Setting Styles for Specific Elements ===
Rather than setting the style for all elements of a certain type, you can specify a style for an individual element only. For example, the following HTML tag represents a Level 1 heading colored red:
<pre><h1 style="color: red; text-align: center;">This is a red heading.</h1>
</pre>
This is called an inline style because it's specified in the HTML tag itself. You don't need to use <code><style></code> tags with this type of style. If you have used both, inline style rules override rules in a style sheet—for example, if the preceding tag appeared in a document that sets H1 headings to be blue in a style sheet, the heading would still be red.
=== Using <code>id</code> Attributes ===
You can also create a rule within a style sheet that will only apply to a certain element. The <code>id</code> attribute of an HTML tag enables you to assign a unique identifier to that element. For example, this tag defines a paragraph with the <code>id</code> attribute <code>intro</code>:
<pre><p id="intro">This is a paragraph</p>
</pre>
After you've assigned this attribute to the tag, you can include rules for it as part of a style sheet. CSS uses the pound sign (<code>#</code>) to indicate that a rule applies to a specific <code>id</code>. For example, the following style sheet sets the <code>intro</code> paragraph to be red in color:
<pre><style type="text/css">
# intro {color: red;}
</style>
</pre>
; Watch Out!: An <code>id</code> value should define a single element in a page. Most browsers will enable you to define more than one element with the same <code>id</code> value, but this is not valid and will not work consistently. It's best to use classes, as described in the next section, when you need to apply the same styles to multiple elements.
=== Using Classes ===
Although the <code>id</code> attribute is useful, you can only use each unique <code>id</code> value with a single HTML tag. If you need to apply the same style to several tags, you can use the <code>class</code> attribute instead. For example, this HTML tag defines a paragraph in a class called <code>smallprint</code>:
<pre><p class="smallprint">This is the small print</p>
</pre>
To refer to a class within a style sheet, you use a period followed by the class name. Here is a style sheet that defines styles for the <code>smallprint</code> class:
<pre><style type="text/css">
.smallprint {color: black;
font-size: 10px; }
</style>
</pre>
; By the Way: You can use a class on any number of elements within a page. You can also define multiple classes for an element, separated by spaces: <code>class="smallprint bold"</code>. When you do this, the CSS rules for all of the classes will be applied to the element.
== Using CSS Properties ==
CSS supports a wide variety of properties, such as <code>color</code> and <code>text-align</code>, in the previous example. The following sections list some of the most useful CSS properties for aligning text, changing colors, working with fonts, and setting margins and borders.
; Did you Know?: This is only an introduction to CSS, and there are many properties beyond those listed here. For more details about CSS, consult one of the web resources or books listed in [Appendix A], "Other JavaScript Resources."
=== Aligning Text ===
One of the most useful features of style sheets is the capability to change the spacing and alignment of text. Most of these features aren't available using standard HTML. You can use the following properties to change the alignment and spacing of text:
* <code>letter-spacing</code> Specifies the spacing between letters.
* <code>text-decoration</code> Enables you to create lines over, under, or through the text, or to choose blinking text. The value can be <code>none</code> (default), <code>underline</code>, <code>overline</code>, <code>line-through</code>, or <code>blink</code>. Blinking text is, thankfully, unsupported by most browsers.
* <code>vertical-align</code> Enables you to move the element up or down to align with other elements on the same line. The value can be <code>baseline</code>, <code>sub</code>, <code>super</code>, <code>top</code>, <code>text-top</code>, <code>middle</code>, <code>text-bottom</code>, and <code>bottom</code>.
* <code>text-align</code> Specifies the justification of text. This can be <code>left</code>, <code>right</code>, <code>center</code>, or <code>justify</code>.
* <code>text-transform</code> Changes the capitalization of text. <code>capitalize</code> makes the first letter of each word uppercase; <code>uppercase</code> makes all letters uppercase; and <code>lowercase</code> makes all letters lowercase.
* <code>text-indent</code> Enables you to specify the amount of indentation for paragraphs and other elements.
* <code>line-height</code> Enables you to specify the distance between the top of one line of text and the top of the next.
=== Changing Colors and Background Images ===
You can also use style sheets to gain more control over the colors and background images used on your web page. CSS includes the following properties for this purpose:
* <code>color</code> Specifies the color of the text within an element. This is useful for emphasizing text or for using a specific color scheme for the document. You can specify a named color (for example, <code>red</code>) or red, green, and blue values to define a specific color (for example, <code>#0522A5</code>).
* <code>background-color</code> Specifies the background color of an element. By setting this value, you can make paragraphs, table cells, and other elements with unique background colors. As with <code>color</code>, you can specify a color name or numeric color.
* <code>background-image</code> Specifies the URL for an image to be used as the background for the element. This is specified with the keyword <code>url</code> and a URL in parentheses, as in <code>url(/back.gif)</code>.
* <code>background-repeat</code> Specifies whether the background image is repeated (tiled). The image can be repeated horizontally, vertically, or both.
* <code>background-attachment</code> Controls whether the background image scrolls when you scroll through the document. <code>fixed</code> means that the background image stays still while the document scrolls; <code>scroll</code> means the image scrolls with the document (like background images on normal web documents).
* <code>background-position</code> Enables you to offset the position of the background image.
* <code>background</code> Provides a quick way to set all of the background elements in this list. You can specify all of the attributes in a single <code>background</code> rule.
; Did you Know?: The basic list of colors supported by most browsers for the <code>color</code> and <code>background-color</code> properties includes <code>aqua</code>, <code>black</code>, <code>blue</code>, <code>fuchsia</code>, <code>gray</code>, <code>green</code>, <code>lime</code>, <code>maroon</code>, <code>navy</code>, <code>olive</code>, <code>orange</code>, <code>purple</code>, <code>red</code>, <code>silver</code>, <code>teal</code>, <code>white</code>, and <code>yellow</code>.
=== Working with Fonts ===
Style sheets also enable you to control the fonts used on the web document and how they are displayed. You can use the following properties to control fonts:
* <code>font-family</code> Specifies the name of a font, such as <code>arial</code> or <code>helvetica</code>, to use with the element. Because not all users have the same fonts installed, you can list several fonts. The CSS specification also supports several generic font families that are guaranteed to be available: <code>serif</code>, <code>sans-serif</code>, <code>cursive</code>, <code>fantasy</code>, and <code>monospace</code>.
* <code>font-style</code> Specifies the style of a font, such as <code>normal</code>, <code>italic</code>, or <code>oblique</code>.
* <code>font-variant</code> This value is <code>normal</code> for normal text, and <code>small-caps</code> to display lowercase letters as small capitals.
* <code>font-weight</code> Enables you to specify the weight of text: <code>normal</code> or <code>bold</code>. You can also specify a numeric font weight for a specific amount of boldness.
* <code>font-size</code> The point size of the font.
* <code>font</code> This is a quick way to set all the font properties in this list. You can list all the values in a single <code>font</code> rule.
=== Margins and Borders ===
Last but not least, you can use style sheets to control the general layout of the page. The following properties affect margins, borders, and the width and height of elements on the web page:
* <code>margin-top, margin-bottom, margin-left, margin-right</code> Specify the margins of the element. You can specify the margins as an exact number or as a percentage of the page's width.
* <code>margin</code> Allows you to specify a single value for all four of the margins.
* <code>width</code> Specifies the width of an element, such as an image.
* <code>height</code> Specifies the height of an element.
* <code>float</code> Enables the text to flow around an element. This is particularly useful with images or tables.
* <code>clear</code> Specifies that the text should stop flowing around a floating image.
; Did you Know?: Along with these features, CSS style sheets enable you to create sections of the document that can be positioned independently. This feature is described in [Hour 13], "Using the W3C DOM."
=== Units for Style Sheets ===
Style sheet properties support a wide variety of units, or types of values you can specify. Most properties that accept a numeric value support the following types of units:
* <code>px</code> Pixels (for example, <code>15px</code>). Pixels are the smallest addressable units on a computer screen or other device. In some devices with non-typical resolutions (for example, handheld computers) the browser might rescale this value to fit the device.
* <code>pt</code> Points (for example, <code>10pt</code>). Points are a standard unit for font size. The size of text of a specified point size varies depending on the monitor resolution. Points are equal to 1/72 of an inch.
* <code>ex</code> Approximate height of the letter <code>x</code> in the current font (for example, <code>1.2ex</code>).
* <code>em</code> Approximate width of the letter <code>m</code> in the current font (for example, <code>1.5em</code>). This is usually equal to the <code>font-size</code> property for the current element.
* <code>%</code> Percentage of the containing object's value (for example, <code>150%</code>).
Which unit you choose to use is generally a matter of convenience. Point sizes are commonly used for fonts, pixel units for the size and position of layers or other objects, and so on.
== Creating a Simple Style Sheet ==
As an example of CSS, you can now create a web page that uses a wide variety of styles:
* For the entire body, the text is blue.
* Paragraphs are centered and have a wide margin on either side.
* Level 1, 2, and 3 headings are red.
* Bullet lists are boldface and green by default.
The following is the CSS style sheet to define these properties, using the <code><style></code> tags:
<pre><style type="text/css">
BODY {color: blue}
P {text-align: center;
margin-left:20%;
margin-right:20%}
H1, H2, H3 {color: red}
UL {color: green;
font-weight: bold}
</style>
</pre>
Here's a rundown of how this style sheet works:
* The <code><style></code> tags enclose the style sheet.
* The <code>BODY</code> section sets the page body's default text color to blue.
* The <code>P</code> section defines the style for paragraphs.
* The <code>H1, H2, H3</code> section defines the style for heading tags.
* The <code>UL</code> section defines a style for bullet lists.
To show how this style sheet works, [Listing 12.1] shows a document that includes this style sheet and a few examples of overriding styles for particular elements. [Figure 12.1] shows Internet Explorer's display of this example.
; Listing 12.1. An Example of a Document Using CSS Style Sheets
<pre><html>
<head><title>Style Sheet Example</title>
<style type="text/css">
BODY {color: blue}
P {text-align: center;
margin-left:20%;
margin-right:20%}
H1, H2, H3 {color: red}
UL {color: green;
font-weight: bold}
</style>
</head>
<body>
<h1>Welcome to this page</h1>
<p>The above heading is red, since we specified that H1-H3 headings
are red. This paragraph is blue, which is the default color for
the entire body. It's also centered and has 20% margins, which we
specified as the default for paragraphs.
</p>
<p style="color:black">This paragraph has black text, because it overrides
the default color in the paragraph tag. We didn't override the centering,
so this paragraph is also centered.</p>
<ul>
<li>This is a bullet list.
<li>It's green and bold, because we specified those defaults for bullet lists.
<li style="color:red">This item is red, overriding the default.
<li>This item is back to normal.
</ul>
<p>This is another paragraph with the default paragraph style.</p>
</body>
</html>
</pre>
; Did you Know?: Remember that you can download the code for this listing from this book's website.
== Using External Style Sheets ==
The preceding example only changes a few aspects of the HTML document's appearance, but it adds about 10 lines to its length. If you were trying to make a very stylish page and had defined new styles for all of the attributes, you would end up with a very long and complicated document.
For this reason, you can use a CSS style sheet from a separate file in your document. This makes your document short and to the point. More importantly, it enables you to define a single style sheet and use it to control the appearance of all of the pages on your site.
=== Linking to External Style Sheets ===
You can refer to an external CSS file by using the <code><link></code> tag in the <code><head></code> section of one or more HTML documents:
<pre><link rel="stylesheet" type="text/css" href="style.css">
</pre>
This tag refers to an external CSS style sheet stored in the <code>style.css</code> file.
; By the Way: Using external style sheets is a good practice because it separates content (HTML), presentation (CSS), and behavior (JavaScript). See [Hour 15], "Unobtrusive Scripting," for more information on best practices.
=== Creating External <code>.css</code> Files ===
After you've linked to an external <code>.css</code> file, you need to create the file itself. The external style sheet is a simple text file that you can create with the same editor you use for HTML documents.
The <code>.css</code> file should contain a list of CSS rules, in the same format you would use between <code><style></code> tags. However, the file should not include <code><style></code> tags or any other HTML tags. Here is what the styles from the previous example would look like as an external style sheet:
<pre>BODY {color: blue}
P {text-align: center;
margin-left:20%;
margin-right:20%}
H1, H2, H3 {color: red}
UL {color: green;
font-weight: bold}
</pre>
== Controlling Styles with JavaScript ==
The new W3C DOM (Document Object Model) makes it easy for JavaScript applications to control the styles on a page. Whether or not you use style sheets, you can use JavaScript to modify the style of any element on a page.
As you learned in [Hour 4], "Working with the Document Object Model (DOM)," the DOM enables you to access the entire HTML document and all of its elements as scriptable objects. You can change any object's style by modifying its <code>style</code> object properties.
The names and values of objects under the <code>style</code> object are the same as you've learned in this hour. For example, you can change an element's color by modifying its <code>style.color</code> attribute:
<pre>element.style.color="blue";
</pre>
Here, <code>element</code> represents the object for an element. There are many ways of finding an element's corresponding object, which you will learn about in detail in [Hour 13].
In the meantime, an easy way to find an element's object is to assign an identifier to it with the <code>id</code> attribute. The following statement creates an <code><nowiki><h1></nowiki></code> element with the identifier <code>"head1"</code>:
<pre><h1 id="head1">This is a heading</h1>
</pre>
Now that you've assigned an identifier, you can use the <code>getElementById()</code> method to find the DOM object for the element:
<pre>element = document.getElementById("head1");
</pre>
You can also use a shortcut to set styles and avoid the use of a variable by directly working with the <code>getElementbyId()</code> method:
<pre>document.getElementById("head1").style.color="blue";
</pre>
This statement combines the preceding examples by directly assigning the blue color style to the <code>head1</code> element of the page. You'll use this technique to create a dynamic page in the following Try It Yourself section.
== Try It Yourself — Creating Dynamic Styles ==
Using the DOM style objects, you can create a page that enables you to directly control the colors used in the page's text. To begin with, you will need a form with which to select colors. You can use <code><select></code> tags to allow a color choice:
<pre><select name="heading" onChange="changehead();">
<option value="black">Black</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
</select>
</pre>
; By the Way: If you are unsure of the syntax used in forms, you might want to review [Hour 11], "Getting Data with Forms."
Notice that this <code><select></code> definition uses <code>onChange</code> attributes in the <code><select></code> tags to call two functions, <code>changehead()</code> and <code>changebody()</code>, when their respective selection changes.
Combining two of these selections with some basic HTML results in the complete HTML document shown in [Listing 12.2].
; Listing 12.2. The HTML File for the Dynamic Styles Example
<pre><html>
<head>
<title>Controlling Styles with JavaScript</title>
<script language="Javascript" type="text/javascript" src="styles.js">
</script>
</head>
<body>
<h1 id="head1">
Controlling Styles with JavaScript</h1>
<hr>
<p id="p1">
Select the color for paragraphs and headings using the form below.
The colors you specified will be dynamically changed in this document.
The change occurs as soon as you change the value of either of the
drop-down lists in the form.
</p>
<form name="form1">
<b>Heading color: </b>
<select name="heading" onChange="changehead();">
<option value="black">Black</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
</select>
<br>
<b>Body text color: </b>
<select name="body" onChange="changebody();">
<option value="black">Black</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="yellow">Yellow</option>
</select>
</form>
</body>
</html>
</pre>
Notice that the <code><nowiki><h1></nowiki></code> tag has an <code>id</code> attribute of <code>"head1"</code>, and the <code><nowiki><p></nowiki></code> tag has an <code>id</code> of <code>"p1"</code>. These are the values the script will use in the <code>getElementById()</code> function. The <code><script></code> tag in the <code><nowiki><head></nowiki></code> section links the document to the <code>styles.js</code> script, which you will create next.
Save your HTML file as <code>styles.html</code>. You can test it in a browser now, but the dynamic features will not work until you create the JavaScript file containing the script functions. [Listing 12.3] shows the JavaScript code for this example.
; Listing 12.3. The JavaScript File for the Dynamic Styles Example
<pre>function changehead() {
i = document.form1.heading.selectedIndex;
headcolor = document.form1.heading.options[i].value;
document.getElementById("head1").style.color = headcolor;
}
function changebody() {
i = document.form1.body.selectedIndex;
doccolor = document.form1.body.options[i].value;
document.getElementById("p1").style.color = doccolor;
}
</pre>
This script first defines the <code>changehead()</code> function. This reads the index for the currently selected heading color, and then reads the color value for the index. This function uses the <code>getElementById()</code> method described in the previous section to change the color. The <code>changebody()</code> function uses the same syntax to change the body color.
Store your JavaScript file as <code>styles.js</code>, and be sure it is in the same folder as the HTML document you saved from [Listing 12.2].
To test the dynamic styles script, load [Listing 12.2] (<code>styles.html</code>) into the browser. Select the colors, and notice the immediate change in the heading or body of the page. [Figure 12.2] shows a typical display of this document after the colors have been changed.
== Summary ==
In this hour, you've used style sheets to control the appearance of web documents. You've learned the CSS syntax for creating style sheets, and used JavaScript to control the styles of a document.
In the next hour, you will move on to Dynamic HTML (DHTML) using layers and other features of the W3C DOM.
=== Q&A ===
''' Q1:''' What's the difference between changing the appearance of text with traditional tags, such as <code><nowiki><b></nowiki></code> and <code><nowiki><i></nowiki></code>, and using a style sheet?
''' A1: ''' Functionally, there is no difference. In principle, though, the HTML should define the structure of the document, and CSS should define the presentation.
''' Q2:''' What happens if two style sheets affect the same text?
''' A2: ''' The CSS specification is designed to allow style sheets to overlap, or cascade. Thus, you can specify a style for the body of the document and override it for specific elements, such as headings and paragraphs. You can even go one step further and override the style for one particular instance of an element. CSS has a set of rules governing which styles have precedence over others, although you might find that different browsers interpret CSS differently when you have many overlapping styles.
''' Q3:''' With CSS in one separate file and JavaScript in another, doesn't web development get confusing?
''' A3: ''' Yes, this can make a simple page unnecessarily complex. However, as you build more complex pages, you'll find it very helpful to have three separate files. This lets you deal with the content and structure (HTML), presentation (CSS), and behavior (JavaScript) separately.
'''Q4:''' What if users don't like the styles I use in my pages?
''' A4: ''' This is another distinct advantage style sheets have over browser-specific tags. With the latest browsers, users can choose a default style sheet of their own and override any properties they want.
=== Quiz Questions ===
Test your knowledge of style sheets and JavaScript by answering the following questions.
''' 1. ''' Which of the following tags is the correct way to begin a CSS style sheet?
# <code><style></code>
# <code><style type="text/css"></code>
# <code><style rel="css"></code>
''' 2. ''' Why isn't the normal HTML language very good at defining layout and presentation?
# Because it was designed by programmers.
# Because magazines feared the competition.
# Because its main purpose is to define document structure.
''' 3. ''' Which feature of new browsers allows you to use JavaScript statements to change styles?
# HTML 4.0
# The DOM
# CSS 2.0
=== Quiz Answers ===
''' 1. ''' b. You begin a CSS style sheet with the tag <code><style type="text/css"></code>.
''' 2. ''' c. HTML is primarily intended to describe the structure of documents.
''' 3. ''' b. The DOM (Document Object Model) enables you to change styles using JavaScript.
=== Exercises ===
If you want to gain more experience using CSS style sheets, try the following exercise:
* Modify [Listing 12.2] to include an <code><nowiki><h2></nowiki></code> tag with a subheading. Add a form element to select this tag's color, and a corresponding <code>changeh2</code> function in the script.
* Now that [Listing 12.2] has three different changeable elements, there is quite a bit of repetition in the script. Create a single <code>ChangeColor</code> function that takes a parameter for the element to change, and modify the <code>onChange</code> event handlers to send the appropriate element <code>id</code> value as a parameter to this function.
tsib2d3m1fpm9zoz9gg3s8std9a98of
User:Moncur/13
2
2159
39278
6043
2026-04-13T06:03:47Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39278
wikitext
text/x-wiki
=13. Using the W3C DOM=
== The DOM and Dynamic HTML ==
Due to the basic DOM of older browsers, JavaScript could only have a limited effect on a page. There were certain elements, such as forms and images, that you could control with JavaScript, but if you wanted to do something more complex—such as adding or removing several paragraphs, making a form appear out of nowhere, or displaying data dynamically within text—you were out of luck.
To escape this limitation, browser manufacturers created Dynamic HTML, or DHTML—an extended DOM that allowed JavaScript to manipulate more of a page. Unfortunately, this was still limiting—you had to work with certain defined parts of the page called layers rather than having complete control over the page.
Worse yet, Microsoft and Netscape created completely different and incompatible versions of DHTML, which led to some complicated and unreliable scripting.
Fortunately, you won't have to learn about those incompatible versions of DHTML because the W3C DOM has made them unnecessary. Although browsers still aren't perfectly interchangeable, today's browsers support enough of the standard DOM to enable you to fully control the content of pages without much concern over browser issues. In this hour and the next hour, you'll create several examples of DOM scripts that will work fine in all modern browsers.
; By the Way: There are still browser issues, of course. [Hour 15], "Unobtrusive Scripting," will show you how to deal with browser differences and how to minimize your chances of running into problems with new browsers.
== Understanding DOM Structure ==
In [Hour 4], "Working with the Document Object Model (DOM)," you learned about how some of the most important DOM objects are organized: The <code>window</code> object contains the <code>document</code> object, and so on. Although these objects were the only ones available in older browsers, the new DOM adds objects under the <code>document</code> object for every element of a page.
To better understand this concept, let's look at the simple HTML document in [Listing 13.1]. This document has the usual <code><head></code> and <code><body></code> sections, a heading, and a single paragraph of text.
; Listing 13.1. A Simple HTML Document
<pre><html>
<head>
<title>A simple HTML Document</title>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph</p>
</body>
</html>
</pre>
Like all HTML documents, this one is composed of various containers and their contents. The <code><html></code> tags form a container that includes the entire document, the <code><body></code> tags contain the body of the page, and so on.
In the DOM, each container within the page and its contents are represented by an object. The objects are organized into a tree-like structure, with the <code>document</code> object itself at the root of the tree, and individual elements such as the heading and paragraph of text at the leaves of the tree. [Figure 13.1] shows a diagram of these relationships.
In the following sections, you will examine the structure of the DOM more closely.
; By the Way: Don't worry if this tree structure confuses you; you can do almost anything by simply assigning IDs to elements and referring to them. This is the method used in earlier hours of this book, as well as in the Try It Yourself section of this hour. In [Hour 14], "Using Advanced DOM Features," you will look at more complicated examples that require you to understand the way objects are organized in the DOM.
=== Nodes ===
Each container or element in the document is called a node in the DOM. In the example in [Figure 13.1], each of the objects in boxes is a node, and the lines represent the relationships between the nodes.
You will often need to refer to individual nodes in scripts. You can do this by assigning an ID, or by navigating the tree using the relationships between the nodes.
=== Parents and Children ===
As you learned earlier in this book, each JavaScript object can have a parent—an object that contains it—and can also have children—objects that it contains. The DOM uses the same terminology.
In [Figure 13.1], the <code>document</code> object is the parent object for the remaining objects, and does not have a parent itself. The <code>html</code> object is the parent of the <code>head</code> and <code>body</code> objects, and the <code>h1</code> and <code>p</code> objects are children of the <code>body</code> object.
Text nodes work a bit differently. The actual text in the paragraph is a node in itself, and is a child of the <code>p</code> object. Similarly, the text within the <code><nowiki><h1></nowiki></code> tags is a child of the <code>h1</code> object.
; By the Way: In [Hour 14], you will learn methods of referring to objects by their parent and child relationships, as well as ways of adding and removing nodes from the document.
=== Siblings ===
The DOM also uses another term for organization of objects: siblings. As you might expect, this refers to objects that have the same parent—in other words, objects at the same level in the DOM object tree.
In [Figure 13.1], the <code>h1</code> and <code>p</code> objects are siblings: Both are children of the <code>body</code> object. Similarly, the <code>head</code> and <code>body</code> objects are siblings under the <code>html</code> object.
== Creating Positionable Elements (Layers) ==
Using the W3C DOM, you can control any element in a web page, such as a paragraph or an image. You can change an element's style, as you learned in the previous hour. You can also use the DOM to change the position, visibility, and other attributes of the element.
Before the W3C DOM and CSS2 standards, you could only reposition layers, special groups of elements defined with a proprietary tag. Although you can now position any element, it's still useful to work with groups of elements in many cases.
You can effectively create a layer, or a group of HTML objects that can be controlled as a group, using the <code><nowiki><div></nowiki></code> or <code><nowiki><span></nowiki></code> tags.
; By the Way: The <code><nowiki><div></nowiki></code> and <code><nowiki><span></nowiki></code> tags are part of the HTML 3.0 standard. <code><nowiki><span></nowiki></code> defines an arbitrary section of the HTML document, and does not specify any formatting for the text it contains. <code><nowiki><div></nowiki></code> is similar, but includes a line break before and after its contents.
To create a layer with <code><nowiki><div></nowiki></code>, enclose the content of the layer between the two division tags and specify the layer's properties in the <code>style</code> attribute of the <code><nowiki><div></nowiki></code> tag. Here's a simple example:
<pre><div id="layer1" style="position:absolute; left:100; top:100">
<p>This is the content of the layer.</p>
</pre>
This code defines a layer with the name <code>layer1</code>. This is a moveable layer positioned 100 pixels down and 100 pixels to the right of the upper-left corner of the browser window. You'll learn more details about the positioning properties in the next section.
; Did you Know?: As with all CSS properties, you can specify the <code>position</code> property and other layer properties in a <code><style></code> block, in an external style sheet, or in the <code>style</code> attribute of an HTML tag. You can also control these properties using JavaScript, as described later in this hour.
=== Setting Object Position and Size ===
You can use various properties in the <code>style</code> attribute of the <code></code> tag when you define a layer to set its position, visibility, and other features. The following properties control the object's position and size:
* <code>position</code> is the main positioning attribute and can affect the following properties. The <code>position</code> property can have one of three values:
** <code>static</code> defines items that are laid out in normal HTML fashion, and cannot be moved. This is the default.
** <code>absolute</code> specifies that an item will be positioned using coordinates you specify.
** <code>relative</code> defines an item that is offset a certain amount from the <code>static</code> position, where the element would normally have been laid out within the HTML page.
* <code>left</code> and <code>top</code> specify offsets for the position of the item. For absolute positioning, this is relative to the main browser window or a containing item. For relative positioning, it's relative to the usual static position.
* <code>right</code> and <code>bottom</code> are an alternative way to specify the position of the item. You can use these when you need to align the object's right or bottom edge.
* <code>width</code> and <code>height</code> are similar to the standard HTML <code>width</code> and <code>height</code> attributes and specify a width and height for the item.
* <code>z-index</code> specifies how items overlap. Normally indexes start with 1 and go up with each layer added "on top" of the page. By changing this value, you can specify which item is on top.
; By the Way: Properties such as <code>left</code> and <code>top</code> work in pixels by default. You can also use any of the units described in the previous hour: <code>px</code>, <code>pt</code>, <code>ex</code>, <code>em</code>, or percentages.
=== Setting Overflow Properties ===
Sometimes the content inside a layer is larger than the size the layer can display. Two properties affect how the layer is displayed in this case:
* <code>overflow</code> indicates whether the content of an element is cut off at the edges of the element, or whether a scroll bar allows viewing the rest of the item. Values include <code>visible</code> to display content outside the element; <code>hidden</code> to hide the clipped content; <code>scroll</code> to display scroll bars; <code>auto</code> to let the browser decide whether to display scroll bars; or <code>inherit</code> to use a parent object's setting.
* <code>clip</code> specifies the clipping rectangle for an item. Only the portion of the item inside this rectangle is displayed. Normally this is the same as the element's dimensions, but you can define an offset inside the element here.
=== Using Visibility Properties ===
Along with positioning objects, you can use CSS positioning to control whether the objects are visible at all, and how the document is formatted around them. These properties control how objects are displayed:
* <code>display</code> specifies whether an item is displayed in the browser. A value of "none" hides the object. Other values include <code>block</code> to display the object preceded and followed by line breaks, <code>inline</code> to display it without line breaks, and <code>list-item</code> to display it as part of a list.
* <code>visibility</code> specifies whether an item is visible. Values include <code>visible</code> (default), <code>hidden</code>, and <code>inherit</code>. A value of <code>inherit</code> means the item inherits the visibility of any item it appears within (such as a table or a paragraph).
The difference between <code>display</code> and <code>visibility</code> is that objects set to <code>display: none</code> will not be displayed at all, and the page will be laid out as if the element wasn't there. Objects set to <code>visibility: hidden</code> will still be included in the layout of the page, but as empty space.
=== Setting Background and Border Properties ===
You can use the following properties to set the color and background image for a layer or other object and control whether borders are displayed:
* <code>background-color</code> specifies the color for the background of any text in the layer.
* <code>background-image</code> specifies a background image for any text in the layer.
* <code>border-width</code> sets the width of the border for all four sides. This can be a numeric value or the keywords <code>thin</code>, <code>medium</code>, or <code>thick</code>.
* <code>border-style</code> sets the style of border. Values include <code>none</code> (default), <code>dotted</code>, <code>dashed</code>, <code>solid</code>, <code>double</code>, <code>groove</code>, <code>ridge</code>, <code>inset</code>, or <code>outset</code>.
* <code>border-color</code> sets the color of the border. As with other color properties, this can be a named color such as <code>blue</code> or an RGB color such as <code>#FF03A5</code>.
=== Controlling Positioning with JavaScript ===
As you learned in the previous hour, you can control the style attributes for an object with the attributes of the object's <code>style</code> property. You can control the positioning attributes listed in the previous section the same way.
Suppose you have created a layer with the following <code></code> tags:
<pre><div id="layer1" style="position:absolute; left:100; top:100">
<p>This is the content of the layer.</p>
</pre>
To move this layer up or down within the page using JavaScript, you can change its <code>style.top</code> attribute. For example, the following statements move the layer 100 pixels down from its original position:
<pre>var obj = document.getElementById("layer1");
obj.style.top=200;
</pre>
The <code>document.getElementById()</code> method returns the object corresponding to the layer's <code></code> tag, and the second statement sets the object's <code>top</code> positioning property to 200. As you learned in the previous hour, you can also combine these two statements:
<pre>document.getElementById("layer1").style.top = 200;</pre>
This simply sets the <code>style.top</code> property for the layer without assigning a variable to the layer's object. You will use this technique in this hour's Try It Yourself section.
; By the Way: Some CSS properties, such as <code>text-indent</code> and <code>border-color</code>, have hyphens in their names. When you use these properties in JavaScript, you combine the hyphenated sections and use a capital letter: <code>textIndent</code> and <code>borderColor</code>.
=== Try It Yourself — Creating a Movable Layer ===
As an example of positioning an element with JavaScript, you can now create an HTML document that defines a layer, and combine it with a script to allow the layer to be moved, hidden, or shown using buttons. [Listing 13.2] shows the HTML document that defines the buttons and the layer.
; Listing 13.2. The HTML Document for the Movable Layer Example
<pre><html>
<head>
<title>Positioning Elements with JavaScript</title>
<script language="javascript" type="text/javascript" src="position.js">
</script>
<style>
# square {
position:absolute;
top: 150;
left: 100;
width: 200;
height: 200;
border: 2px solid black;
padding: 10px;
background-color: #E0E0E0;
}
</style>
</head>
<body>
<h1>Positioning Elements</h1>
<hr>
<form name="form1">
<input type="button" name="left" value="<- Left" onClick="pos(-1,0);">
<input type="button" name="right" value="Right" ->"
onClick="pos(1,0);">
<input type="button" name="up" value="Up" onClick="pos(0,-1);">
<input type="button" name="down" value="Down" onClick="pos(0,1);">
<input type="button" name="hide" value="Hide" onClick="hideSquare();">
<input type="button" name="show" value="Show" onClick="showSquare();">
</form>
<hr>
<div id="square">
<p>This square is an absolutely positioned
layer that you can move using the buttons above.</p>
</body>
</html>
</pre>
In addition to some basic HTML, this document consists of the following:
* The <code><script></code> tag in the header reads a script called <code>position.js</code>, which you will create later in this section.
* The <code><style></code> section is a brief style sheet that defines the properties for the movable layer. It sets the <code>position</code> property to <code>absolute</code> to indicate that it can be positioned at an exact location, sets the initial position in the <code>top</code> and <code>left</code> properties, and sets <code>border</code> and <code>background-color</code> properties to make the layer clearly visible.
* The <code><input></code> tags within the <code><form></code> section define six buttons: four to move the layer left, right, up, or down, and two to control whether it is visible or hidden.
* The <code></code> section defines the layer itself. The <code>id</code> attribute is set to the value <code>"square"</code>. This <code>id</code> is used in the style sheet to refer to the layer, and will also be used in your script.
Type this document (or download it from this book's website) and save it. If you load it into a browser, you should see the buttons and the <code>"square"</code> layer, but the buttons won't do anything yet. The script in [Listing 13.3] adds the action to the HTML.
; Listing 13.3. The Script for the Movable Layer Example
<pre>var x=100,y=150;
function pos(dx,dy) {
if (!document.getElementById) return;
x += 10*dx;
y += 10*dy;
obj = document.getElementById("square");
obj.style.top=y;
obj.style.left=x;
}
function hideSquare() {
if (!document.getElementById) return;
obj = document.getElementById("square");
obj.style.display="none";
}
function showSquare() {
if (!document.getElementById) return;
obj = document.getElementById("square");
obj.style.display="block";
}
</pre>
The <code>var</code> statement at the beginning of the script defines two variables, <code>x</code> and <code>y</code>, that will store the current position of the layer. The <code>pos</code> function is called by the event handlers for all four of the movement buttons.
The parameters of the <code>pos()</code> function, <code>dx</code> and <code>dy</code>, tell the script how the layer should move: If <code>dx</code> is negative, a number will be subtracted from <code>x</code>, moving the layer to the left. If <code>dx</code> is positive, a number will be added to <code>x</code>, moving the layer to the right. Similarly, <code>dy</code> indicates whether to move up or down.
The <code>pos()</code> function begins by making sure the <code>getElementById()</code> function is supported, so it won't attempt to run in older browsers. It then multiplies <code>dx</code> and <code>dy</code> by 10 (to make the movement more obvious) and applies them to <code>x</code> and <code>y</code>. Finally, it sets the <code>top</code> and <code>left</code> properties to the new position, moving the layer.
Two more functions, <code>hideSquare()</code> and <code>showsquare()</code>, hide or show the layer by setting its <code>display</code> property to <code>"none"</code> (hidden) or <code>"block"</code> (shown).
To use this script, save it as <code>position.js</code> and then load the HTML document, [Listing 13.2], into your browser. [Figure 13.2] shows this script in action.
; By the Way: By assigning values to the layer's positioning properties repeatedly rather than at each click of a button, you can produce an animation effect. See [Hour 19], "Using Graphics and Animation," for an example of this technique.
== Summary ==
In this hour, you've learned a bit more about the structure of DOM objects that make up a page, how to use HTML and CSS to define a positionable layer, and how you can use positioning properties dynamically with JavaScript.
Layers are only a simple aspect of what you can do to a page with the W3C DOM. In the next hour, you'll learn how to manipulate the DOM tree to add elements, remove elements, and dynamically change the text within a page.
=== Q&A===
'''Q1:'''
What happens when my web page includes multiple HTML documents, such as when frames are used?
''' A1: '''
In this case, each window or frame has its own <code>document</code> object that stores the elements of the HTML document it contains.
'''Q2:'''
If the DOM allows any object to be dynamically changed, why does the positioning example need to use tags to define a layer?
''' A2: '''
The example could just as easily move a heading, or a paragraph. The layer is just a convenient way to group objects and to create a square object with a border.
'''Q3:'''
Exactly which browsers support positioning elements with the DOM?
''' A3: '''
Support for the W3C DOM first appeared in Internet Explorer 5.0 and Netscape 5.0, although it was buggy. Current browsers, such as Internet Explorer 6 and 7, Firefox 1.x, and Opera 7 and 8, have solid and consistent DOM support.
=== Quiz Questions ===
Test your knowledge of the W3C DOM by answering the following questions.
''' 1. '''
Which of the following tags is used to create a layer?
# <code><layer></code>
# <code><nowiki><div></nowiki></code>
# <code><style></code>
''' 2. '''
Which property controls an element's left-to-right position?
# <code>left</code>
# <code>width</code>
# <code>lrpos</code>
''' 3. '''
Which of the following CSS rules would create a heading that is not currently visible in the page?
# <code>H1 {visibility: invisible;}</code>
# <code>H1 {display: none;}</code>
# <code>H1 {style: invisible;}</code>
=== Quiz Answers ===
''' 1. '''
b. The <code><nowiki><div></nowiki></code> tag can be used to create positionable layers.
''' 2. '''
a. The <code>left</code> property controls an element's left-to-right position.
''' 3. '''
b. The <code>none</code> value for the <code>display</code> property makes it invisible. The <code>visibility</code> property could also be used, but its possible <code>values</code> are visible or <code>hidden</code>.
=== Exercises ===
If you want to gain more experience using the W3C DOM, try the following exercises:
* Modify the positioning example in Listings 13.2 and 13.3 to move the square one pixel at a time rather than ten at a time.
* Modify the positioning example to eliminate the <code></code> layer and move a paragraph element instead. You will need to move the <code>id</code> attribute to the paragraph.
l4x0s6as0lfp7uu1rbtt9n9gome8h3o
User:Moncur/14
2
2160
39279
6083
2026-04-13T06:03:48Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39279
wikitext
text/x-wiki
<!- -
=14. Using Advanced DOM Features=
== Working with DOM Nodes ==
As you learned in [Hour 13], "Using the W3C DOM," the DOM organizes objects within a web page into a tree-like structure. Each node (object) in this tree can be accessed in JavaScript. In the next sections you will learn how you can use the properties and methods of nodes to manage them.
; By the Way: The following sections only describe the most important properties and methods of nodes, and those that are supported by current browsers. For a complete list of available properties, see the W3C's DOM specification at [http://www.w3.org/TR/DOM-Level-2/ http://www.w3.org/TR/DOM-Level-2/].
=== Basic Node Properties ===
You have already used the <code>style</code> property of nodes to change their style sheet values. Each node also has a number of basic properties that you can examine or set. These include the following:
* <code>nodeName</code> is the name of the node (not the ID). For nodes based on HTML tags, such as <code><nowiki><p></nowiki></code> or <code><body></code>, the name is the tag name: <code>P</code> or <code>BODY</code>. For the document node, the name is a special code: <code>#document</code>. Similarly, text nodes have the name <code>#text</code>.
* <code>nodeType</code> is an integer describing the node's type: <code>1</code> for normal HTML tags, <code>3</code> for text nodes, and <code>9</code> for the document node.
* <code>nodeValue</code> is the actual text contained within a text node. This property is not valid for other types of nodes.
* <code>innerHTML</code> is the HTML content of any node. You can assign a value including HTML tags to this property and change the DOM child objects for a node dynamically.
; By the Way: The <code>innerHTML</code> property is not a part of the W3C DOM specification. However, it is supported by the major browsers, and is often the easiest way to change content in a page. You can also accomplish this in a more standard way by deleting and creating nodes, as described later in this hour.
=== Node Relationship Properties ===
In addition to the basic properties described previously, each node has a number of properties that describe its relation to other nodes. These include the following:
* <code>firstChild</code> is the first child object for a node. For nodes that contain text, such as <code>h1</code> or <code>p</code>, the text node containing the actual text is the first child.
* <code>lastChild</code> is the node's last child object.
* <code>childNodes</code> is an array that includes all of a node's child nodes. You can use a loop with this array to work with all the nodes under a given node.
* <code>previousSibling</code> is the sibling (node at the same level) previous to the current node.
* <code>nextSibling</code> is the sibling after the current node.
; Watch Out: Remember that, like all JavaScript objects and properties, the node properties and functions described here are case sensitive. Be sure you type them exactly as shown.
=== Document Methods ===
The <code>document</code> node itself has several methods you might find useful. You have already used one of these, <code>getElementById()</code>, to refer to DOM objects by their ID properties. The <code>document</code> node's methods include the following:
* <code>getElementById(</code><code>id</code><code>)</code> returns the element with the specified <code>id</code> attribute.
* <code>getElementsByTagName(</code><code>tag</code><code>)</code> returns an array of all of the elements with a specified tag name. You can use the wildcard <code>*</code> to return an array containing all the nodes in the document.
* <code>createTextNode(</code><code>text</code><code>)</code> creates a new text node containing the specified text, which you can then add to the document.
* <code>createElement(</code><code>tag</code><code>)</code> creates a new HTML element for the specified tag. As with <code>createTextNode</code>, you need to add the element to the document after creating it. You can assign content within the element by changing its child objects or the <code>innerHTML</code> property.
=== Node Methods ===
Each node within a page has a number of methods available. Which of these are valid depends on the node's position in the page, and whether it has parent or child nodes. These include the following:
* <code>appendChild(new)</code> appends the specified new node after all of the object's existing nodes.
* <code>insertBefore(new, old)</code> inserts the specified new child node before the specified old child node, which must already exist.
* <code>replaceChild(new, old)</code> replaces the specified old child node with a new node.
* <code>removeChild(node)</code> removes a child node from the object's set of children.
* <code>hasChildNodes()</code> returns a Boolean value of <code>true</code> if the object has one or more child nodes, or <code>false</code> if it has none.
* <code>cloneNode()</code> creates a copy of an existing node. If a parameter of <code>true</code> is supplied, the copy will also include any child nodes of the original node.
== Hiding and Showing Objects ==
We will now move on to a number of real-world examples using the DOM objects to manipulate web pages. As a simple example, you can create a script that hides or shows objects within a page.
As you learned in [Hour 13], objects have a <code>visibility</code> style property that specifies whether they are currently visible within the page:
<pre>Object.style.visibility="hidden"; // hides an object
Object.style.visibility="visible"; // shows an object</pre>
Using this property, you can create a script that hides or shows objects in either browser. [Listing 14.1] shows the HTML document for a script that allows two headings to be shown or hidden.
; Listing 14.1. Hiding and Showing Objects
<pre><html>
<head>
<title>Hiding and Showing Objects</title>
<script language="Javascript" type="text/javascript">
function ShowHide() {
if (!document.getElementById) return;
var head1 = document.getElementById("head1");
var head2 = document.getElementById("head2");
var showhead1 = document.form1.head1.checked;
var showhead2 = document.form1.head2.checked;
head1.style.visibility=(showhead1) ? "visible" : "hidden";
head2.style.visibility=(showhead2) ? "visible" : "hidden";
}
</script>
</head>
<body>
<h1 ID="head1">This is the first heading</h1>
<h1 ID="head2">This is the second heading</h1>
<p>Using the W3C DOM, you can choose
whether to show or hide the headings on
this page using the checkboxes below.</p>
<form name="form1">
<input type="checkbox" name="head1"
checked onClick="ShowHide();">
<b>Show first heading</b><br>
<input type="checkbox" name="head2"
checked onClick="ShowHide();">
<b>Show second heading</b><br>
</form>
</body>
</html>
</pre>
The <code><nowiki><h1></nowiki></code> tags in this document define headings with the identifiers <code>head1</code> and <code>head2</code>. The <code><form></code> section defines a form with two check boxes, one for each of the headings. When a check box is modified, the <code>onClick</code> method is used to call the <code>ShowHide()</code> function.
This function is defined within the <code><script></code> statements in the header. The function assigns the <code>head1</code> and <code>head2</code> variables to the objects for the headings, using the <code>getElementById()</code> method. Next, it assigns the <code>showhead1</code> and <code>showhead2</code> variables to the contents of the check boxes. Finally, the function uses the <code>style.visibility</code> attributes to set the visibility of the headings.
; Did you Know?: The lines that set the <code>visibility</code> property might look a bit strange. The <code>?</code> and <code>:</code> characters create conditional expressions, a shorthand way of handling <code>if</code> statements. To review conditional expressions, see [Hour 7], "Controlling Flow with Conditions and Loops."
[Figure 14.1] shows this example in action in Internet Explorer. In the figure, the second heading's check box has been unchecked, so only the first heading is visible.
== Modifying Text Within a Page ==
Next, you can create a simple script to modify the contents of a heading within a web page. As you learned earlier this hour, the <code>nodeValue</code> property of a text node contains its actual text, and the text node for a heading is a child of that heading. Thus, the syntax to change the text of a heading with the identifier <code>head1</code> would be
<pre>Var head1 = document.getElementById("head1");
Head1.firstChild.nodeValue = "New Text Here";</pre>
This assigns the variable <code>head1</code> to the heading's object. The <code>firstChild</code> property returns the text node that is the only child of the heading, and its <code>nodeValue</code> property contains the heading text.
Using this technique, it's easy to create a page that allows the heading to be changed dynamically. [Listing 14.2] shows the complete HTML document for this script.
; Listing 14.2. The Complete Text-Modifying Example
<pre><html>
<head>
<title>Dynamic Text in JavaScript</title>
<script language="Javascript" type="text/javascript">
function ChangeTitle() {
if (!document.getElementById) return;
var newtitle = document.form1.newtitle.value;
var head1 = document.getElementById("head1");
head1.firstChild.nodeValue=newtitle;
}
</script>
</head>
<body>
<h1 ID="head1">Dynamic Text in JavaScript</h1>
<p>Using the W3C DOM, you can dynamically
change the heading at the top of this
page. Enter a new title and click the
Change button.</p>
<form name="form1">
<input type="text" name="newtitle" size="25">
<input type="button" value="Change!" onClick="ChangeTitle();">
</form>
</body>
</html>
</pre>
This example defines a form that allows the user to enter a new heading for the page. Pressing the button calls the <code>ChangeTitle()</code> function, defined in the header. This function gets the value the user entered in the form, and changes the heading's value to the new text.
[Figure 14.2] shows this page in action in Internet Explorer after a new title has been entered and the Change button has been clicked.
== Adding Text to a Page ==
Next, you can create a script that actually adds text to a page. To do this, you must first create a new text node. This statement creates a new text node with the text "this is a test":
<pre>var node=document.createTextNode("this is a test");</pre>
Next, you can add this node to the document. To do this, you use the <code>appendChild</code> method. The text can be added to any element that can contain text, but we will use a paragraph. The following statement adds the text node defined previously to the paragraph with the identifier <code>p1</code>:
<pre>document.getElementById("p1").appendChild(node);</pre>
[Listing 14.3] shows the HTML document for a complete example that uses this technique, using a form to allow the user to specify text to add to the page.
; Listing 14.3. Adding Text to a Page:
<pre><html>
<head>
<title>Adding to a page</title>
<script language="Javascript" type="text/javascript">
function AddText() {
if (!document.getElementById) return;
var sentence=document.form1.sentence.value;
var node=document.createTextNode(" " + sentence);
document.getElementById("p1").appendChild(node);
document.form1.sentence.value="";
}
</script>
</head>
<body>
<h1>Create Your Own Content</h1>
<p id="p1">Using the W3C DOM, you can dynamically
add sentences to this paragraph. Type a sentence
and click the Add button.</p>
<form name="form1">
<input type="text" name="sentence" size="65">
<input type="button" value="Add" onClick="AddText();">
</form>
</body>
</html>
</pre>
In this example, the <code><nowiki><p></nowiki></code> section defines the paragraph that will hold the added text. The <code><form></code> section defines a form with a text field called <code>sentence,</code> and an Add button, which calls the <code>AddText()</code> function. This function is defined in the header.
The <code>AddText()</code> function first assigns the <code>sentence</code> variable to the text typed in the text field. Next, it creates a new text node containing the sentence, and appends the new text node to the paragraph.
Load this document into a browser to test it, and try adding several sentences by typing them and clicking the Add button. [Figure 14.3] shows Firefox's display of this document after several sentences have been added to the paragraph.
== Try It Yourself — Creating a Navigation Tree ==
One common use of JavaScript and the DOM is to create a dynamic tree-like navigation system for a site, with sections that can be expanded and collapsed. Although this is unnecessary for small sites, it's a good way to organize what may be hundreds of links for a larger site. To further experiment with the techniques you learned about in this hour, you can create a simple navigation tree using the DOM.
To begin, you will need an HTML document that defines the content of the navigation tree, shown in [Listing 14.4].
; Listing 14.4. The HTML for the Navigation Tree Example:
<pre><html>
<head><title>Creating a Navigation Tree</title>
<style>
A {text-decoration: none;}
# productsmenu,#supportmenu,#contactmenu {
display: none;
margin-left: 2em;
}
</style>
</head>
<body>
<h1>Navigation Tree Example</h1>
<p>The navigation tree below allows you to expand and
collapse items.</p>
<ul>
<li><a id="products" href="#">[+] Products</a>
<ul ID="productsmenu">
<li><a href="prodlist.html">Product List</a></li>
<li><a href="order.html">Order Form</a></li>
<li><a href="pricelist.html">Price List</a></li>
</ul>
</li>
<li><a id="support" href="#">[+] Support</a>
<ul id="supportmenu">
<li><a href="sforum.html">Support Forum</a></li>
<li><a href="scontact.html">Contact Support</a></li>
</ul>
</li>
<li><a ID="contact" href="#">[+] Contact Us</a>
<ul id="contactmenu">
<li><a href="contact1.html">Service Department</a></li>
<li><a href="contact2.html">Sales Department</a></li>
</ul>
</li>
</ul>
<script language="javascript" type="text/javascript" src="tree.js">
</script>
</body>
</html>
</pre>
In this document, the links are laid out as a nested list using <code><nowiki><ul></nowiki></code> and <code><nowiki><li></nowiki></code> tags. Using a standard list like this rather than <code></code> tags has two benefits: First, the browser formats the tree as a list with bullets automatically. Second, it supports older browser—seven a browser that does not support CSS or JavaScript will load and display the list correctly. It won't have the dynamic features, but the links will still work.
The tree has three main nodes: Products, Support, and Contact Us. Each one has a link you can click to display or hide the links in that section. The <code>id</code> attribute has been used on each <code><a></code> tag so the script can attach an event handler to it. Each node also has a submenu defined with <code><nowiki><ul></nowiki></code> and <code><nowiki><li></nowiki></code> tags. An <code>id</code> attribute is also used on the <code><nowiki><ul></nowiki></code> tag so the script can hide or display the list.
The <code><script></code> tag at the end of the document includes the script you will create next. The tag is placed after the body of the page so that the script can add event handlers to elements in the page.
The <code><style></code> block at the beginning of the document adds some formatting to the links, and uses the <code>display: none</code> attribute to initially hide the submenus. They will be revealed by the script when the link is clicked.
The script for this example is shown in [Listing 14.5].
; Listing 14.5. The JavaScript File for the Navigation Tree Example:
<pre>function Toggle(e) {
// Don't try this in old browsers
if (!document.getElementById) return;
// Get the event object
if (!e) var e = window.event;
// Which link was clicked?
whichlink = (e.target) ? e.target.id : e.srcElement.id;
// get the menu object
obj=document.getElementById(whichlink+"menu");
// Is the menu visible?
visible=(obj.style.display=="block")
// Get the key object (the link itself)
key=document.getElementById(whichlink);
// Get the name (Products, Contact, etc.)
keyname = key.firstChild.nodeValue.substring(3);
if (visible) {
// hide the menu
obj.style.display="none";
key.firstChild.nodeValue = "[+]" + keyname;
} else {
// show the menu
obj.style.display="block";
key.firstChild.nodeValue = "[-]" + keyname;
}
}
document.getElementById("products").onclick=Toggle;
document.getElementById("support").onclick=Toggle;
document.getElementById("contact").onclick=Toggle;
</pre>
The <code>Toggle()</code> function shows or hides a menu. It first determines which of the links triggered the event, and then uses the link's <code>id</code> attribute to find the objects for the menu and for the link itself. If the menu is currently visible, it is hidden, and if it is currently hidden, it is revealed. The appropriate symbol <code>[+]</code> or <code>[-]</code> is added to the link name and displayed by modifying the text node's <code>nodeValue</code> attribute.
The last three lines of the script assign the <code>Toggle()</code> function as the <code>onClick</code> event handler for the three top-level links of the tree.
To use this script, save it as <code>tree.js</code> in the same folder as the HTML document you created previously, and load the HTML file into a browser. [Figure 14.4] shows the example in action after all three nodes of the tree have been expanded.
; Did you Know?: To add items to the navigation tree, add links to the HTML file. If you add a new submenu, you need to assign an <code>id</code> attribute to the link, use the same word plus <code>menu</code> as the <code>id</code> of the menu, and assign its <code>onclick</code> event to the <code>Toggle()</code> function at the end of the script.
== Summary ==
In this hour, you learned some of the advanced features of the new W3C DOM (Document Object Model). You learned the functions and properties you can use to manage DOM objects, and used example scripts to hide and show elements within a page, modify text, and add text. Finally, you created a dynamic navigation tree using DOM features.
Congratulations—you've reached the end of Part III! Now that you've learned all about the DOM, you will move on to some advanced aspects of JavaScript. In the next hour, you will learn how to create scripts that unobtrusively handle multiple browsers, and some best practices for more involved scripting.
=== Q&A ===
'''Q1:'''
Can I avoid assigning an <code>id</code> attribute to every DOM object I want to handle with a script?
''' A1: '''
Yes. Although the scripts in this hour typically use the <code>id</code> attribute for convenience, you can actually locate any object in the page by using combinations of node properties such as <code>firstChild</code> and <code>nextSibling</code>. However, keep in mind that any change you make to the HTML can change an element's place in the DOM hierarchy, so the <code>id</code> attribute is a reliable way to handle this.
'''Q2:'''
Can I include HTML tags, such as <nowiki><b></nowiki>, in the new text I assign to a text node?
''' A2: '''
Text nodes are limited to text if you use the <code>nodeValue</code> attribute. However, the <code>innerHTML</code> property does not have this limitation and can be used to insert any HTML.
'''Q3:'''
Is there a reference that specifies which DOM properties and methods work in which browser versions?
''' A3: '''
Yes, several websites are available that keep up-to-date lists of browser features. Some of these are listed in [Appendix A], "Other JavaScript Resources."
=== Quiz Questions ===
Test your knowledge of the DOM by answering the following questions.
'''1.'''
If <code>para1</code> is the DOM object for a paragraph, what is the correct syntax to change the text within the paragraph to "New Text"?
# <code>para1.value="New Text";</code>
# <code>para1.firstChild.nodeValue="New Text";</code>
# <code>para1.nodeValue="New Text";</code>
''' 2.'''
Which of the following DOM objects never has a parent node?
# <code>body</code>
# <code>div</code>
# <code>document</code>
'''3.'''
Which of the following is the correct syntax to get the DOM object for a heading with the identifier <code>head1</code>?
# <code>document.getElementById("head1")</code>
# <code>document.GetElementByID("head1")</code>
# <code>document.getElementsById("head1")</code>
=== Quiz Answers ===
''' 1.'''
b. The actual text is the <code>nodeValue</code> attribute of the text node, which is a child of the paragraph node.
''' 2.'''
c. The <code>document</code> object is the root of the DOM object tree, and has no parent object.
''' 3.'''
a. <code>getElementById</code> has a lowercase g at the beginning, and a lowercase d at the end, contrary to what you might know about normal English grammar.
=== Exercises ===
If you want to gain more experience using the advanced DOM features you learned in this hour, try the following exercise:
* Add a third check box to [Listing 14.1] to allow the paragraph of text to be shown or hidden. You will need to add an <code>id</code> attribute to the <code><nowiki><p></nowiki></code> tag, add a check box to the form, and add the appropriate lines to the script.
* Add a fourth node to the navigation tree in [Listing 14.4], and make the appropriate changes to the script in [Listing 14.5] to make the new section of the tree expand and collapse correctly.
1e3y3s8muo3c5fql7f6hwmrb93n9gt8
User:Foxall/1
2
2178
39246
5944
2026-04-13T06:03:33Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39246
wikitext
text/x-wiki
=Hour 1. A C# Programming Tour =
Learning a new programming language can be intimidating. If you've never programmed before, the act of typing seemingly cryptic text to produce sleek and powerful applications probably seems like a black art, and you may wonder how you'll ever learn everything you need to know. The answer is, of course, one step at a time. The first step to learning a language is the same as that of any other activity�building confidence. Programming is part art and part science. Although it may seem like magic, it's more akin to illusion; after you know how things work, a lot of the mysticism goes away, freeing you to focus on the mechanics necessary to produce the desired result.
In this hour, you'll complete a quick tour that takes you step-by-step through creating a complete, albeit small, C# program. I've yet to see a "Hello World" program that's the least bit helpful (they usually do nothing more than print "hello world" to the screen�oh, fun). So instead, you'll create a picture-viewer application that lets you view Windows bitmaps and icons on your computer. You'll learn how to let a user browse for a file and how to display a selected picture file on the screen, both of which are skills that will come in handy in later applications that you create. Creating large, commercial solutions is accomplished by way of a series of small steps. After you've finished creating this small project, you'll have an overall feel for the development process.
The highlights of this hour include the following:
* Building a simple, yet functional, C# application
* Letting a user browse a hard drive
* Displaying a picture from a file on disk
* Getting familiar with some programming lingo
* Learning about the Visual Studio�C# IDE
I hope that by the end of this hour, you'll realize just how much fun it is to program using C#.
===Starting C#===
You must become familiar with a few terms before you begin to create programs in C#:
* Distributable Component The final, compiled version of a project. Components can be distributed to other people and other computers and do not require C# to run (although the .NET Framework is required, which you'll learn about in coming hours). Distributable components are also called programs. In [Hour 22], "Deploying a Solution," you'll learn how to distribute the Picture Viewer program that you're about to build to other computers.
* Project A collection of files that can be compiled to create a distributable component (program). There are many types of projects, and complex applications may consist of many projects, such as a Windows Application project and support DLL projects.
* Solution A collection of projects and files that compose an application or component.
;New term:C# is a complete development environment; every tool you'll need to create your C# projects is accessed from within Visual Studio. The Visual Studio-C# environment is called the IDE, short for Integrated Development Environment, and it is the design framework in which you build applications. To work with C# projects, you must first start the Visual Studio IDE.
Start the C# IDE now by choosing Microsoft Visual Studio .NET from within the Microsoft Visual Studio .NET folder on your Start menu.
===Creating a New Project===
When you first start Visual Studio .NET, you're shown the Visual Studio Start Page tab within the IDE. Using this page, you can open projects created previously or create new ones (see [Figure 1.1]). For this quick tour, you're going to create a new Windows application, so click New Project to display the New Project dialog box shown in [Figure 1.2].
Figure 1.1. You can open existing projects or create new projects from the Visual Studio Start page.
Figure 1.2. The New Project dialog box allows you to create many types of .NET projects.
;Book - Pencil:If you don't see the Visual Studio Start page, chances are that you've changed the default settings. [Hour 2], "Navigating C#," shows you how to change them back. For now, be aware that you can create a new project from the File menu in addition to using the techniques described in this hour.
You can create many types of projects with C#, as well as with the other supported languages of the .NET platform. The New Project dialog box is used to specify the type of C# project you want to create. If the Visual C# Projects folder isn't selected, click it to display the C# project types and then make sure the Windows Application icon is selected (if it's not, click it once to select it). At the bottom of the New Project dialog box is a Name text box, in which you specify the name of the project you're creating; in the Location text box, you can enter the location in which to save the project files.
;Bulb: You should always set these values to something meaningful before creating a project, or you'll have more work to do later if you want to move or rename the project.
Type Picture Viewer into the Name text box to name your project. There's no need to change the location where the project files are to be saved at this time, so go ahead and create the new Windows Application project by clicking OK. C# creates the new project, complete with one form (design window) for you to begin building the interface for your application (see [Figure 1.3]).
Figure 1.3. New Windows applications start with a blank form; the fun is just beginning!
Your C# environment may look different from that shown in the figures of this hour, depending on the edition of C# you're using, whether you've already played with C#, and other factors such as the resolution of your monitor. All the elements discussed in this hour, however, exist in all editions of C#. (If your IDE doesn't have a window displayed that is shown in a figure, use the View menu to display the window.)
;Book - Pencil:To create a program that can be run on another computer, you start by creating a project, and then you compile the project into a component, such as an executable (a program a user can run) or a DLL (a component that can be used by other programs and components). The compilation process is discussed in detail in [Hour 22], "Deploying a Solution." The important thing to note at this time is that when you hear someone refer to creating or writing a program, just as you are creating the Picture Viewer program now, they're referring to the completion of all steps up to and including compiling the project to a distributable file.
===Understanding the C# Environment===
The first time you run C#, you'll notice that the IDE contains a lot of windows, such as the Properties window on the right, which is used to view and set properties of objects. In addition to these windows, the IDE contains a lot of tabs, such as the Toolbox tab on the left edge of the IDE (refer tFigure 1.3]). Clicking a tab displays an associated window. Try this now: click the Toolbox tab to display the Toolbox window. You can also hover the mouse over a tab for a few seconds to display the window. To hide the window, simply move the mouse off the window. To close the window completely, click the Close (X) button in the window's title bar.
You can adjust the size and position of any of these windows, and you can even hide and show them at will. You'll learn how to customize your design environment in [Hour 2], "Navigating C#."
;Bulb: Unless specifically instructed to do so, do not double-click anything in the C# design environment. Double-clicking most objects produces an entirely different outcome than single-clicking does. If you mistakenly double-click an object on a form, a code window is displayed. At the top of the code window is a set of tabs: one for the form design and one for the code. Click the tab for the form design to hide the code window and return to the form.
The Properties window at the right side of the design environment is perhaps the most important window, and it's the one you'll use most often. If your computer's display is set for 640x480, you can probably see only a few properties at this time. This makes it difficult to view and set properties as you create projects. I highly recommend that you don't attempt development with Visual Studio at a resolution below 800x600. Personally, I prefer 1024x768 because it offers plenty of work space. To change your display settings, right-click your desktop and select Properties.
===Changing the Characteristics of Objects===
Almost everything you work with in C# is an object. Forms, for instance, are objects, as are all the items you can put on a form to build an interface, such as list boxes and buttons. There are many types of objects ([Hour 3], "Understanding Objects and Collections," discusses objects in detail). Objects, in turn, are classified by type. For instance, a form is a Form object, whereas items you can place on a form are called Control objects, or controls. Some objects don't have a physical appearance, but exist only in code. You'll learn about these kinds of objects in later hours.
;New term:Every object, regardless of whether it has a physical appearance, has a distinct set of attributes known as properties. You have certain properties about you, such as your height and hair color, and C# objects have properties as well, such as Height and BackColor. Properties define the characteristics of an object. When you create a new object, the first thing you need to do is set its properties so that the object appears and behaves in the way you desire. To display the properties of an object, click the object in its designer. Click the form now to ensure that its properties are displayed in the Properties window.
===Naming Objects===
The property you should set first for any new object is the Name property. Press F4 to display the Properties window (if it's not already visible), and notice the Name given to your default form (the first property listed in the Properties window)�Form1. When you first create an object, C# gives the object a unique, generic name based on the object's type. Although these names are functional, they aren't very descriptive. For instance, C# named your form Form1, but it's common to have dozens of forms in a project, and it would be extremely difficult to manage a complicated project if all forms were distinguishable only by a number (Form2, Form3, and so forth).
;Book - Pencil:In actuality, what you're creating is a form class, or template, that will be used to create and show forms at runtime. For the purpose of this quick tour, I simply refer to it as a form. See [Hour 5], "Building Forms�Part I," for more information.
To better manage your forms, you should give each one a descriptive name. C# gives you the chance to name new forms as they're created. Because C# created this default form for you, you didn't get a chance to name it, so you must change both the filename and name of the form. Change the name of the form now by clicking the Name property and changing the text from Form1 to fclsViewer. Notice that this did not change the filename of the form as it is displayed in the Solution Explorer window. Change the filename now by right-clicking Form1.cs in the Solution Explorer window, choosing Rename from the context menu, and changing the text from Form1.cs to fclsViewer.cs. In future examples, I won't have you change the filename each time because you'll have enough steps to accomplish as it is. I do recommend, however, that you always change your filenames to something meaningful in your 'real' projects.
;Book - Pencil:I use the fcls prefix here to denote that the file is a form class. There are different types of classes, so using a prefix helps differentiate the classes in code. You're not required by C# to use object prefixes, but I highly recommend that you do so. In [Hour 12], "Using Constants, Data Types, Variables, and Arrays," you'll learn the benefits of using a naming convention as well as the standard prefixes for many .NET objects.
===Setting the Text Property of the Form===
Notice that the text that appears in the form's title bar says Form1. This is because C# sets the form's title bar text to the name of the form when it is first created, but doesn't change it when you change the name of the form. The text in the title bar is determined by the value of the Text property of the form. Click the form once more so that its properties appear in the Properties window. Use the scrollbar in the Properties window to locate the Text property in the Properties window and then change the text to Picture Viewer.
===Giving the Form an Icon===
Everyone who has used Windows is familiar with icons, which are the little pictures used to represent programs. Icons most commonly appear in the Start menu next to the name of their respective programs. In C#, you not only have control over the icon of your program file, you can also give every form in your program a unique icon if you want to.
;Book - Pencil:The instructions that follow assume you have access to the source files for the examples in this book. They are available at [http://www.samspublishing.com/detail_sams.cfm?item=0672320800 www.samspublishing.com/detail_sams.cfm?item=0672320800]. You don't have to use the icon I've provided for this example; you can use any icon of your choice. If you don't have an icon available, you can skip this section without affecting the outcome of the example.
To give the form an icon, follow these steps:
# In the Properties window, click the Icon property to select it.
# When you click the Icon property, a small button with three dots appears to the right of the property. Click this button.
# To locate the HourOne.ico file or another ico file of your choice, use the Open dialog box that appears. When you've found the icon, double-click it, or click it once to select it and then click Open.
After you've selected the icon, it appears in the Icon property along with the word (Icon). A small version of the icon appears in the upper-left corner of the form, as well. Whenever this form is minimized, this is the icon that's displayed on the Windows taskbar. (Note: This doesn't change the icon for the project as a whole. In [Hour 22], you'll learn how to assign an icon to your distributable file.)
===Changing the Size of the Form===
Next, you're going to change the Width and Height properties of the form. The Width and Height values are shown collectively under the Size property; Width appears to the left of the comma, Height to the right. You can change the Width or Height by changing the corresponding number in the Size property. Both values represent the number of pixels of the dimension. To display and adjust the Width and Height properties separately, click the small plus sign (+) next to the Size property (see [Figure 1.4]).
Figure 1.4. Some properties can be expanded to show more specific properties.
Change the Width property to 400 and the Height to 325. To commit a property change, press Tab or click a different property or window. Your screen should now look like the one in [Figure 1.5].
Figure 1.5. A change in the Properties window is reflected as soon as the change is committed.
When you first created this project, C# saved a copy of the source files in their initial state. The changes you've made so far exist only in memory; if you were to turn your computer off at this time (don't do this), you would lose any and all work up to this point. You should get into the habit of saving your work frequently. Save the project now by choosing Save All from the File menu or by clicking the Save All button on the toolbar (it has a picture of stacked disks on it).
===Adding Controls to a Form===
;New term:Now that your form has its properties set, you need to add objects to the form to produce a user interface. Objects that can be placed on a form are called controls. Some controls have a visible interface with which a user can interact, whereas others are always invisible to the user. You'll use controls of both types in this example. On the left side of the screen is a tab titled Toolbox. Click the Toolbox tab now to display the Toolbox window shown in [Figure 1.6]. The toolbox contains all the controls available in the project, such as labels and text boxes.
Figure 1.6. The toolbox is used to select controls to build a user interface.
;Bulb: You can add a control to a form in three ways, and [Hour 5] explains them in detail. In this hour, you'll use the technique of double-clicking a tool in the toolbox.
The toolbox closes itself soon after you've added a control to a form and the pointer is no longer over the toolbox. To make the toolbox stay visible, click the little picture of a pushpin located in the toolbox's title bar.
;Book - Pencil:Refer to [Hour 2], "Navigating C#," for more information on customizing the design environment.
Your Picture Viewer interface will consist of the following controls:
* Two Button controls
* A PictureBox control
* An OpenFileDialog control
===Designing an Interface===
It's generally best to design the user interface of a form and then add the code behind the interface that makes the form functional. The user interface for your Picture Viewer program will consist of a View Picture button, a Close button, and a PictureBox in which to display a picture.
===Adding a Visible Control to a Form===
Start by adding a Button control to the form. Do this by double-clicking the Button item in the toolbox. C# then creates a new button and places it in the upper-left corner of the form (see [Figure 1.7]).
Figure 1.7. When you double-click a control in the toolbox, the control is added to the upper-left corner of the form.
Using the Properties window, set the button's properties as follows (note that you may want to change the Properties list to alphabetical, if it is not already, to make it easier to find these properties by name):
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnSelectPicture</code>
|-
| <code>Text</code>
| <code>Select Picture</code>
|-
| <code>Location</code>
| <code>301</code>,<code>10</code> (Note: 301 is the x coordinate, 10 is the y coordinate.)
|-
| <code>Size</code>
| <code>85,23</code>
|}
You're now going to create a button that the user can click to close the Picture Viewer program. Rather than adding a new button to the form, you're going to create a copy of the button you've already defined. To do this, right-click the button on the form and choose Copy from its shortcut menu. Next, right-click anywhere on the form and choose Paste from the form's shortcut menu. The new button appears over the button you copied, and it is selected by default. Change the properties of the new button as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnQuit</code>
|-
| <code>Text</code>
| <code>Quit</code>
|-
| <code>Location</code>
| <code>301</code>,<code>40</code>
|}
The last control you need to add to the form is a PictureBox control. A PictureBox has many capabilities, but its primary purpose is to show pictures�which is precisely what you'll use it for in this example. Add a new PictureBox control to the form and set its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>picShowPicture</code>
|-
| <code>BorderStle</code>
| <code>FixedSingle</code>
|-
| <code>Location</code>
| <code>8</code>,<code>8</code>
|-
| <code>Size</code>
| <code>282</code>, <code>275</code>
|}
After you've made these property changes, your form will look like the one in [Figure 1.8]. Click the Save All button on the toolbar to save your work.
Figure 1.8. An application's interface doesn't have to be complex to be useful.
===Adding an Invisible Control to a Form===
;New term:So far, all the controls that you've used sit on a form and have a physical appearance. However, not all controls have a physical appearance. Such controls, referred to as invisible-at-runtime controls, aren't designed for user interactivity, but they're designed to give you, the programmer, functionality beyond the standard features of C#.
To allow the user to select a picture to display, you need to give her the capability to locate a file on her hard drive. You've probably noticed in the past that whenever you choose to open a file from within any Windows application, the dialog box displayed is almost always the same. It doesn't make any sense to force each and every developer to write the code necessary to perform standard file operations. Instead, Microsoft has exposed the functionality via a control that you can use in your project. This control is called the OpenFileDialog control, and it will save you dozens of hours that you would otherwise spend trying to duplicate common functionality.
;Book - Pencil:Other controls besides the OpenFileDialog control give you file functionality. For example, the SaveFileDialog control provides features for enabling the user to save a file.
Scroll the toolbox until you can see the OpenFileDialog control, and then double-click it to add it to your form. (You may have to scroll the toolbox, which is done by clicking the up arrow toward the top of the window or the down arrow toward the bottom.) Note that the control isn't placed on the form, but it appears in a special area below the form (see [Figure 1.9]). This happens because the OpenFileDialog control has no interface to display to a user. It does have an interface, a dialog box that you can display as necessary, but it has nothing to display directly on a form.
Figure 1.9. Controls that have no interface appear below the form designer.
Select the OpenFileDialog control and change its properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>ofdSelectPicture</code>
|-
| <code>Filter</code>
| <code>Windows Bitmaps|*.BMP|JPEG Files|*.JPG</code>
|-
| <code>Title</code>
| <code>Select Picture</code>
|}
The Filter property determines the filtering of the control. The text that appears before the pipe symbol (<code>|</code>) is the descriptive text of the file type, whereas the text after the pipe symbol is the pattern to use to filter files; you can specify more than one filter type. Text entered into the Title property appears in the title bar of the Open File dialog box.
===Coding an Interface===
The graphical interface for your Picture Viewer program is now complete, so click the pushpin in the title bar of the toolbox to close it. Now, you have to write code for the program to be capable of performing actions. C# is an event-driven language, which means that code is executed in response to events. These events may come from users, such as a user clicking a button, or from Windows itself (see [Hour 4], "Understanding Events," for a complete explanation of events). Currently, your application looks nice but it won't do a darn thing. The user can click the Select Picture button, for example, until the cows come home, but nothing will happen because you haven't told the program what to do when the user clicks the button.
You're going to write code to accomplish two tasks. First, you're going to write code that lets the user browse his or her hard drives to locate and select a picture file and then display the file in the picture box (this sounds a lot harder than it is). Second, you're going to add code to the Quit button that shuts down the program when the user clicks the button.
===Letting a User Browse for a File===
The first bit of code you're going to write will allow the user to browse his or her hard drives, select a file, and then show the selected picture in the PictureBox control. This code will execute when the user clicks the Select Picture button; therefore, it's added to the Click event of that button (you'll learn all about events in later hours). When you double-click a control on a form in Design view, the default event for that control is created and displayed in a code window. The default event for a Button control is its Click event, which makes sense because clicking a button is its most common purpose. Double-click the Select Picture button now to access its Click event in the code window (see [Figure 1.10]).
Figure 1.10. You will write all code in a window such as this.
;New term:When you access an event, C# builds an event handler, which is essentially a template procedure in which you add the code that executes when the event is fired. The cursor is already placed within the code procedure, so all you have to do is add code. You will also notice that the open and closing braces are preset for your new event procedure. The braces, in this case, define the beginning and end of your procedure. You will soon see that C# requires many open and closing braces({ } ). By the time you're done with this book, you'll be madly clicking away as you write your own code to make your applications do exactly what you want them to do�well, most of the time. For now, just enter the code as I present it here.
It's very important that you get in the habit of commenting your code, so the first line you're going to enter is a comment. Beginning a statement with the characters <code>//</code> designates the statement as a comment; the compiler won't do anything with the statement, so you can enter whatever text you want after the double slashes. Type the following statement exactly as it appears and press the Enter key at the end of the line.
;Book - Pencil:For more information on creating good comments, see [Hour 16], "Debugging Your Code."
<pre>// Show the open file dialog box.
</pre>
The next statement you'll enter triggers a method of the OpenFileDialog control that you added to the form. You'll learn all about methods in [Hour 3], "Understanding Objects and Collections." For now, think of a method as a mechanism to make a control take action. The ShowDialog method tells the control to show its Open dialog box and let the user select a file. The ShowDialog method returns a value that indicates its success or failure, which we are then comparing to a predefined result (<code>DialogResult.OK</code>). Don't worry too much about what is happening here, because you'll be learning the details of this in later hours. In a nutshell, the ShowDialog method is called to let a user browse for a file, and if the user selects a file, more code gets executed. Of course, there is a lot more to using the OpenFileDialog control than I present in this basic example, but this simple statement gets the job done. Enter the following if statement followed by an open brace:
<pre>if (ofdSelectPicture.ShowDialog() == DialogResult.OK)
{
</pre>
;Book - Pencil:Open and closing braces are necessary for this if statement because they denote that multiple lines will be part of this construct.
Time for another comment. Enter this statement and remember to press Enter at the end of each code line.
<pre>// Load the picture into the picture box.
</pre>
;Bulb: Don't worry about indenting the code by pressing the Tab key or using spaces. C# .NET automatically indents code for you.
You're now going to enter the next line of code. This statement, which appears within the if construct, is the line of code that actually displays the picture in the picture box. (If you're itching to know more about graphics, take a look at [Hour 10], "Drawing and Printing.")
Enter the following statement:
<pre>picShowPicture.Image = Image.FromFile(ofdSelectPicture.FileName);
</pre>
In addition to displaying the selected picture, your program is going to display the path and filename of the picture in the title bar. When you first created the form, you changed the Text property of the form using the Properties window. To create dynamic applications, properties need to be constantly adjusted at runtime, and this is done using code. Enter the following three lines of code:
<pre>// Show the name of the file in the form's caption.
this.Text = String.Concat("Picture Viewer (" + ofdSelectPicture.FileName + ")");
}
</pre>
;Book - Pencil:C# is case sensitive! You must enter all code using the same case as shown in the text.
=== Checking Your Program Entry Point ===
All C# programs must contain an entry point. The Main() method is the entry point. In this sample you need to change the reference from Form1 to fclsViewer (this is necessary because we renamed the form earlier) . This statement will invoke the constructor on the form. C++ programmers will be familiar with the Main() entry point method, but they should take notice of the capitalization of Main. We will talk a bit more about the program entry point later in the book.
To update the entry point in this sample, press Ctrl+F to open the Find window, enter Form1, and click Find Next. Close the Find window and replace the text Form1 with fclsViewer. The updated statement should now read:
<pre>Application.Run(new fclsViewer());
</pre>
After you've entered all the code, your editor should look like that shown in [Figure 1.11].
Figure 1.11. Make sure your code exactly matches the code shown here.
===Terminating a Program Using Code===
The last bit of code you'll write will terminate the application when the user clicks the Quit button. To do this, you'll need to access the Click event handler of the btnQuit button. At the top of the code window are two tabs. The current tab has the text fclsViewer.cs. Next to this is a tab that contains the text fclsViewer.cs [Design]. Click this tab now to switch from Code view to the form designer. If you receive an error when you click the tab, the code you entered is incorrect, and you need to edit it to make it the same as I've presented it. After the form designer is displayed, double-click the Quit button to access its Click event.
Enter the following code in the Quit button's Click event handler:
<pre>this.Close();
</pre>
;Book - Pencil:The Close statement closes the current form. When the last loaded form in a program is closed, the application shuts itself down�completely. As you build more robust applications, you'll probably want to execute all kinds of clean-up routines before terminating your application, but for this example, closing the form is all you need to do.
===Running a Project===
Your application is now complete. Click the Save All button (it looks like a stack of disks) on the toolbar, and then run your program by pressing F5. You can also run the program by clicking the button on the toolbar that looks like a right-facing triangle and resembles the Play button on a VCR (this button is also found on the Debug menu, and it is called Start). However, learning the keyboard shortcuts will make your development process move along faster. When you run the program, the C# interface changes, and the form you've designed appears floating over the design environment (see [Figure 1.12]).
Figure 1.12. When in Run mode, your program executes the same as it would for an end user.
You're now running your program as though it were a standalone application running on another user's machine; what you see is exactly what someone else would see if they ran the program (without the C# design environment in the background, of course). Click the Select Picture button to display the Select Picture dialog box (see [Figure 1.13]). Use the dialog box to locate a picture file. When you've found a file, double-click it, or click once to select it and then click Open. The selected picture is then displayed in the PictureBox control, as shown in [Figure 1.14].
Figure 1.13. The OpenFileDialog control handles all the details of browsing for files. Cool, huh?
Figure 1.14. C# makes it easy to display pictures with very little work.
===Summary===
When you're done playing with the program, click the Quit button and then save your project by clicking Save All on the C# toolbar.
That's it! You've just created a bona fide C# program. You've used the toolbox to build an interface with which users can interact with your program, and you've written code in strategic event handlers to empower your program to do things. These are the basics of application development in C#. Even the most complicated programs are built using this basic approach; you build the interface and add code to make the application do things. Of course, writing code to do things exactly the way you want things done is where the process can get complicated, but you're on your way.
If you take a close look at the organization of the hours in this book, you'll see that I start out by teaching you the C# environment. I then move on to building an interface, and later I teach you all about writing code. This organization is deliberate. You might be a little anxious to jump in and start writing serious code, but writing code is only part of the equation. As you progress through the hours, you'll be building a solid foundation of development skills.
Soon, you'll pay no attention to the man behind the curtain�you'll be that man (or woman)!
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q1:'''
| Can I show bitmaps of file types other than BMP and JPG?
|-
| align="right" | ''' A1: '''
| Yes. The PictureBox supports the display of images with the extensions BMP, JPG, ICO, EMF, WMF, and GIF. The PictureBox can even save images to a file.
|-
| align="right" | '''Q2:'''
| Is it possible to show pictures in other controls?
|-
| align="right" | ''' A2: '''
| The PictureBox is the control to use when you are just displaying images. However, many other controls allow you to display pictures as part of the control. For instance, you can display an image on a Button control by setting the button's Image property to a valid picture.
|}
===Workshop===
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [Appendix A],"Answers to Quizzes/Exercises."
===Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''1'''
| What type of C# project creates a standard Windows program?
|-
| align="right" | '''2'''
| What window is used to change the attributes (location, size, and so on) of a form or control?
|-
| align="right" | '''3'''
| How do you access the default event (code) of a control?
|-
| align="right" | '''4'''
| What property of a PictureBox do you set to display an image?
|-
| align="right" | '''5'''
| What is the default event for a Button control?
|}
=== Exercise===
# Change your Picture Viewer program so that the user can also locate and select GIF files. (Hint: Change the Filter property of the OpenFileDialog control.)
# Alter the form in your Picture Viewer project so that the buttons are side by side in the lower-right corner of the form, rather than vertically aligned in the upper-right corner.
= Hour 2. Navigating C# =
The key to expanding your knowledge of C# is to become as comfortable as possible�as quickly as possible�with the C# design environment. Just as a carpenter doesn't think much about hammering a nail into a piece of wood, performing actions such as saving projects, creating new forms, and setting object properties should become second nature to you. The more comfortable you are with the tools of C#, the more you can focus your energies on what you're creating with the tools.
In this hour, you'll learn how to customize your design environment. You'll learn how to move, dock, float, hide, and show design windows, as well as how to customize menus and toolbars; you'll even create a new toolbar from scratch. After you've gotten acquainted with the environment, I'll teach you about projects and the files that they're made of (taking you beyond what was briefly discussed in [Hour 1], "A C# Programming Tour"), and I'll introduce you to the design windows with which you'll work most frequently. Finally, I'll show you how to get help when you're stuck.
The highlights of this hour include the following:
* Navigating C#
* Using the Visual Studio .NET Start Page to open and create projects
* Showing, hiding, docking, and floating design windows
* Customizing menus and toolbars
* Adding controls to a form using the toolbox
* Viewing and changing object attributes using the Properties window
* Working with the files that make up a project
* How to get help
===Using the Visual Studio .NET Start Page ===
By default, the Visual Studio Start Page shown in [Figure 2.1] is the first thing you see when you start C# (if C# isn't running, start it now). The Visual Studio Start Page is a gateway for performing tasks with C#. From this page, you can open previously edited projects, create new projects, edit your user profile, and browse information provided by Microsoft.
Figure 2.1. The Visual Studio Start Page is the default starting point for all Visual Studio programming languages, including C#.
From this page, you can have C# load the last solution you edited, show the Open Project dialog box, show the New Project dialog box, or show an empty design environment. To view or edit the startup options, choose Options from the Tools menu to display the Options dialog box shown in [Figure 2.2]. By default, the General section of the Environment folder is selected, which happens to contain the At Startup option.
Figure 2.2. Use the At Startup setting to control the first thing you see when C# starts.
;Book - Pencil:If the Visual Studio Start Page doesn't appear when you start C#, check the settings on the Options form; you may need to change At Startup to Show Start Page.
=== Creating New Projects ===
To create new projects, click New Project on the Visual Studio Start Page. This shows the New Project dialog box shown in [Figure 2.3]. The Project Types list varies from machine to machine, depending on which products of the Visual Studio .NET family are installed. Of course, we're interested only in the C# Project types in this book.
Figure 2.3. Use the New Project dialog box to create C# projects from scratch.
;Book - Pencil:You can create many types of projects with C#, but this book focuses mostly on creating Windows Applications, perhaps the most common of the project types. You will learn about some of the other project types as well, but when you're told to create a new project, make sure the Windows Application template is selected unless you're told otherwise.
When you create a new project, be sure to enter a name for it in the Name text box before clicking OK or double-clicking a project type icon. This ensures that the project is created with the proper path and filenames, eliminating work you would otherwise have to do to change these values later. After you specify a name, you can create the new project either by double-clicking the project type template icon or by clicking an icon once to select it and then clicking OK. After you've performed either of these actions, the New Project dialog box closes and a new project of the selected type is created.
By default, Visual Studio saves all your projects in subfolders of your My Documents folder. The hierarchy used by C# is
<pre>\My Documents\Visual Studio Projects\<Project Name> </pre>
Notice how the name you give your project is used as its folder name. This makes it easy to find the folders and files for any given project and is one reason that you should always give your projects descriptive names. You can use a path other than the default by specifying a specific path on the New Project dialog box, although you probably won't often need to do so.
;Book - Pencil:You can create a new project at any time (not just when starting C#) by opening the New submenu on the File menu and choosing Project.
=== Opening an Existing Project ===
Over time, you'll open more projects than you create. There are essentially two ways to open projects from the Visual Studio Start Page. If it's one you've recently opened, the project name will appear in a list within a rectangle in the middle of the Start Page (refer to [Figure 2.1]). Because the name displayed for the project is the one given when it was created, this is yet another reason to give your projects descriptive names. Clicking a project name opens the project. I'd venture to guess that you'll use this technique 95% of the time. To open a project for the first time (such as when opening sample projects), click Open Project on the Visual Studio Start Page. Clicking this link displays a standard dialog box that you can use to locate and select a project file.
;Book - Pencil:As with creating new projects, you can open an existing project at any time, not just when starting C#, by selecting File, Open.
===Navigating and Customizing the C# Environment ===
C# lets you customize many of its interface elements, such as windows and toolbars, enabling you to be more efficient in the work that you do. Create a new Windows Application now (use the New Project dialog box or select File, New) so that you can see and manipulate the design environment. Name this project Environment Tutorial. (This exercise won't create anything reusable, but it will help you learn how to navigate the design environment.) Your screen should look like the one shown in [Figure 2.4].
Figure 2.4. This is pretty much how the IDE appears when you first install C#.
;Book - Pencil:Your screen may not look exactly like that shown in [Figure 2.4], but it'll be close. For example, the Output window won't be visible unless you've built a project. If you completed [Hour 1], the window will be visible. By the time you've finished this hour, you'll be able to change the appearance of the design environment to match this figure�or to any configuration you prefer.
=== Working with Design Windows ===
Design windows, such as the Properties and Solution Explorer windows shown in [Figure 2.4], provide functionality for building complex applications. Just as your desk isn't organized exactly like that of your co-workers, your design environment doesn't have to be the same as anyone else's, either.
A design window may be placed into one of four primary states:
* Closed
* Floating
* Docked
* Auto hidden
=== Showing and Hiding Design Windows ===
When a design window is closed, it doesn't appear anywhere. There is a difference between being closed and being hidden, as you'll learn shortly. To display a closed or hidden window, choose the corresponding menu item from the View menu. For example, if the Properties window isn't displayed in your design environment, you can display it by choosing Properties Window on the View menu (or press its keyboard shortcut�F4). Whenever you need a design window and can't find it, use the View menu to display it. To close a design window, click its Close button (the button on the right side of the title bar with the X on it), just as you would close an ordinary window.
===Floating Design Windows===
Floating design windows are visible windows that float over the workspace, as shown in [Figure 2.5]. Floating windows are like typical application windows in that you can drag them around and place them anywhere you please, even on other monitors when you're using a multiple-display setup. In addition to moving a floating window, you can also change its size by dragging a border.
Figure 2.5. Floating windows appear over the top of the design environment.
===Docking Design Windows===
Visible windows appear docked by default. A docked window is a window that appears attached to the side, top, or bottom of the work area or to some other window. The Properties window in [Figure 2.4], for example, is docked to the right side of the design environment. To make a floating window a docked window, drag the title bar of the window toward the edge of the design environment to which you want to dock the window. As you drag the window, you'll drag a rectangle that represents the outline of the window. When you approach an edge of the design environment, the rectangle will change shape and "stick" in a docked position. If you release the mouse while the rectangle appears this way, the window will be docked. Although this is hard to explain, it's very easy to do.
;Book - Pencil:You can size a docked window by dragging its edge opposite the side that's docked. If two windows are docked to the same edge, dragging the border between them enlarges one while shrinking the other.
To try this, you'll need to float a window that's already docked. To float a window, you "tear" the window away from the docked edge by dragging the title bar of the docked window away from the edge to which it is docked. Note that this technique won't work if a window is set to Auto Hide (which is explained next). Try docking and floating windows now by following these steps:
# Ensure that the Properties window is currently displayed (if it's not, show it using the View menu). Make sure the Properties window isn't set to Auto Hide by right-clicking its title bar and deselecting Auto Hide (if it's selected) from the shortcut menu, as shown in [Figure 2.6].
Figure 2.6. You can't float a window that's set to Auto Hide.
# Drag the title bar of the Properties window away from the docked edge. When the rectangle representing the border of the window changes shape, release the mouse button. The Properties window should now appear floating.
# Dock the window once more by dragging the title bar toward the right edge of the design environment. Again, release the mouse button when the rectangle changes shape.
;Bulb: If you don't want a floating window to dock, regardless of where you drag it to, right-click the title bar of the window and choose Floating from the context menu. To allow the window to be docked again, right-click the title bar and choose Dockable.
Auto Hiding Design Windows
A feature of C# design environment is the capability to auto hide windows. Although you might find this a bit disconcerting at first, after you get the hang of things, this is a very productive way in which to work because your workspace is freed up, yet design windows are available by simply moving the mouse. Windows that are set to Auto Hide are always docked; you can't set a floating window to Auto Hide. When a window auto hides, it appears as a tab on the edge to which it's docked�much like minimized applications are placed in the Windows taskbar.
Look at the left edge of the design environment in [Figure 2.6]. Notice the two tabs on the left side of the IDE. One tab has a picture of two computers, and the other is labeled Toolbox. These tabs represent auto-hidden windows. To display an auto-hidden window, move the pointer over the tab representing the window. When you move the pointer over a tab, C# displays the design window so that you can use its features. When you move the pointer away from the window, the window automatically hides itself�hence the name. To make any window hide itself automatically, right-click its title bar and select Auto Hide from its shortcut menu. Alternatively, you can click the little picture of a pushpin appearing in the title bar next to the Close button to toggle the window's Auto Hide state.
===Performing Advanced Window Placement===
The techniques discussed in this section so far are basic methods for customizing your design environment. Things can actually get a bit more complicated if you want them to. Such complication presents itself primarily as the capability to create tabbed floating windows like the one shown in [Figure 2.5]. Notice that at the bottom of the floating window is a set of tabs. Clicking a tab shows its corresponding design window, replacing the window currently displayed. These tabs are created much the same way in which you dock and undock windows�by dragging and dropping. For instance, to make the Solution Explorer window a floating window of its own, you would drag the Solution Explorer window tab away from the floating window. As you do so, a rectangle appears, showing you the outline of the new window. Where you release the rectangle determines whether you dock the design window you're dragging or whether you make the window floating. To make a design window a new tab of an already floating window, drag its title bar and drop it in the title bar of a window that is already floating.
In addition to creating tabbed floating windows, you can dock two floating windows together. To do this, drag the title bar of one window over another window (other than over the title bar) until the shape changes, and then release the mouse. [Figure 2.7] shows two floating windows that are docked to one another and a third window that is floating by itself.
Figure 2.7. Floating, docked, floating and docked�the possibilities are numerous!
Using all the techniques discussed here, you can tailor the appearance of your design environment in all sorts of ways. There is no one best configuration. You'll find that different configurations work better for different projects and in different stages of development. For instance, when I'm designing the interface of a form, I want the toolbox to stay visible but out of my way, so I tend to make it float, or I turn off its Auto Hide property and leave it docked to the left edge of the design environment. However, after the majority of the interface elements have been added to a form, I want to focus on code. Then I dock the toolbox and make it auto hide itself; it's there when I need it, but it's out of the way when I don't. Don't be afraid to experiment with your design windows, and don't hesitate to modify them to suit your changing needs.
===Working with Toolbars===
Toolbars are the mainstay for performing functions quickly in almost all Windows programs (you'll probably want to add them to your own programs at some point, and [Hour 9], "Adding Menus and Toolbars to Forms," shows you how). Every toolbar has a corresponding menu item, and buttons on toolbars are essentially shortcuts to their corresponding menu items. To maximize your efficiency when developing with C#, you should become familiar with the available toolbars. As your C# skills progress, you can customize existing toolbars and even create your own toolbars to more closely fit the way you work.
===Showing and Hiding Toolbars===
C# includes a number of built-in toolbars for you to use when creating projects. Two toolbars are visible in most of the figures shown so far in this hour. The one on the top is the Standard toolbar, which you'll probably want displayed all the time. The second toolbar is the Layout toolbar, which provides useful tools for building forms.
The previous edition of Visual Studio had about 5 toolbars; Visual Studio .NET, on the other hand, has more than 20 toolbars! The toolbars you'll use most often as a C# developer are the Standard, Text Editor, and Debug toolbars. Therefore, this hour discusses each of these. In addition to these predefined toolbars, you can create your own custom toolbars to contain any functions you think necessary, which you'll learn how to do later in this hour.
To show or hide a toolbar, choose View, Toolbars to display a list of available toolbars. Toolbars currently displayed appear selected (see [Figure 2.8]). Click a toolbar name to toggle its visible state.
Figure 2.8. Hide or show toolbars to make your work more efficient.
;Bulb: A quick way to access the list of toolbars is to right-click any visible toolbar.
Docking and Resizing Toolbars
Just as you can dock and undock C#'s design windows, you can dock and undock the toolbars. Unlike the design windows, however, C#'s toolbars don't have a title bar that you can click and drag when they're in a docked state. Instead, each docked toolbar has a drag handle (a set of horizontal lines along its left edge). To float (undock) a toolbar, click and drag the grab handle away from the docked edge. After a toolbar is floating, it has a title bar. To dock a floating toolbar, click and drag its title bar to the edge of the design environment to which you want it docked. This is the same technique you use to dock design windows.
;Bulb: A shortcut for docking a toolbar is to double-click its title bar.
Although you can't change the size of a docked toolbar, you can resize a floating toolbar (a floating toolbar behaves like any other normal window). To resize a floating toolbar, move the pointer over the edge you want to stretch and then click and drag to the border to change the size of the toolbar.
===Customizing Toolbars===
As your experience with C# grows, you'll find that you use certain functions repeatedly. To increase your productivity, you can customize any of C#'s toolbars, and you can create your own from scratch. You can even customize the C# menu and create your own menus. To customize toolbars and menus, you use the Customize dialog box shown in [Figure 2.9], which is accessed by choosing View, Toolbars, Customize.
Figure 2.9. Create new toolbars or customize existing ones to fit the way you work.
;Book - Pencil:I strongly suggest that you don't modify the existing C# toolbars. Instead, create new toolbars. If you modify the predefined toolbars, you may find that you've removed tools that I refer to in later examples. If you do happen to change a built-in toolbar, you can reset it to its original state by selecting it in the Customize dialog box and clicking Reset.
The Toolbars tab on the Customize dialog box shows you a list of all the existing toolbars and menus. The toolbars and menus currently visible have a check mark next to them. To toggle a toolbar or menu between visible and hidden, click its check box.
===Creating a New Toolbar===
You're now going to create a new toolbar to get a feel for how toolbar customization works. Your toolbar will contain only a single button, which will be used to call C#'s Help program.
To create your new toolbar, follow these steps:
# From the Toolbars tab of the Customize dialog box, click New.
# Enter My Help as the name for your new toolbar when prompted.
# Click OK to create the new toolbar.
After you've entered a name for your toolbar and clicked OK, your new toolbar appears, floating on the screen�most likely somewhere outside the Customize dialog box (see [Figure 2.10]). Dock your toolbar now by double-clicking the blank area on the toolbar (the area where a button would ordinarily appear). Your screen should look like the one in [Figure 2.11].
Figure 2.10. New toolbars are pretty tiny; they have no buttons on them.
Figure 2.11. It's easier to customize toolbars when they're docked.
===Adding Buttons to a Toolbar===
Now that you have an empty toolbar, the next step is to add the desired command buttons to it. Click the Commands tab of the Customize dialog box to display all the available commands.
The Commands tab contains the following:
* A list of command categories
* A list of the commands for the selected command category
The Categories list shows all available command categories, such as File and Edit functions. When you select a category, all the available commands for that category are shown in the list on the right.
You're going to add a toolbar button that appears as a Help icon and that actually displays Help when clicked.
To add the command button to your toolbar, follow these steps:
# Locate and select the category Help. All the available commands for the Help category will appear in the list on the right.
# From the Commands list, click and drag the Contents command to your custom toolbar. As you drag, the pointer changes to an arrow pointing to a small gray box. At the lower-right corner of the pointer is a little hollow box with an x in it. This indicates that the location over which the pointer is positioned is not a valid location to drop the command.
# As you drag the command over your toolbar (or any other toolbar for that matter), the x in the little box will change to a plus sign (+), indicating that the command can be placed in the current location. In addition, an insertion point (often called an I-beam because that's what it looks like) appears on the toolbar to indicate where the button would be placed if the command were dropped at that spot. When an I-beam appears on your toolbar and the pointer box contains a plus sign, release the mouse button. Your toolbar will now look like the one in [Figure 2.12].
Figure 2.12. Building toolbars is a simple matter of dragging and dropping commands.
You can alter any button on a toolbar by right-clicking the button to access its shortcut menu and then choosing Change Button Image. Feel free to experiment with changing the image of the button on your custom toolbar, but be sure to leave the buttons on the built-in toolbars as they are.
To remove a button from a toolbar, drag the button to remove it from the toolbar and drop it somewhere other than on the same toolbar. If you drop the button onto another toolbar, the button is removed from the original toolbar and placed on the toolbar on which you dropped it. If you drop the button in a location where no toolbar exists, the button is simply removed from the toolbar.
;Book - Pencil:You can drag command buttons only in Customize mode. If you attempt to drag an item during normal operation, you'll simply click the button.
;Bulb: Although these techniques are illustrated using toolbars, they apply to menus, as well.
Moving Buttons on a Menu or Toolbar
You should always attempt to group command buttons logically. For example, the Edit functions are all grouped together on the Standard toolbar, as are the File operations. A separator (space) is used to separate groups. To create a separator space, right-click the button that starts a new group and choose Begin a Group from the button's shortcut menu.
You probably won't get the exact groupings you want when you first add commands to a toolbar, but that's not a problem because you can change the position of a button at any time. To move a button on a toolbar, drag the button and drop it in the desired location (remember, you have to be in Customize mode to do this). To move a button from one toolbar to another, drag the button from its toolbar and drop it at the preferred location on the desired toolbar.
Now that your toolbar is complete (Hey, I never said it'd be fancy), click Close on the Customize dialog box to exit Customize mode. All toolbars, including the one you just created, are no longer in Customize mode and they can't be modified. Click the button you placed on your new toolbar and C#'s Help will appear.
Because your custom toolbar really doesn't do much, hide it now to save screen real estate by right-clicking any toolbar to display the Toolbar shortcut menu and then deselecting My Help.
;Book - Pencil:As you work your way through this book, you should always have the Standard toolbar and menu bar displayed on your screen.
Typically, you should customize toolbars only after you're very familiar with the available functions and only after you know which functions you use most often. I recommend that you refrain from modifying any of the predefined toolbars until you're quite familiar with C#. As you become more comfortable with C#, you can customize the toolbars to make your project work area as efficient as possible.
Adding Controls to a Form Using the Toolbox
The toolbox is used to place controls, such as the common text box and list box, onto a form. The default toolbox you see when you first run C# is shown in [Figure 2.13]. The buttons labeled Data, Components, Windows Forms, and so on are actually tabs, although they don't look like standard tabs. Clicking any of these tabs causes a related set of controls to appear. The default tab is the Windows Forms tab, and it contains many great controls you can place on Windows forms (the forms used to build Windows applications, in contrast to Web applications). All the controls that appear by default on the tabs are included with C#, and these controls are discussed in detail in [Hour 7], "Working with Traditional Controls," and [Hour 8], "Advanced Controls." You'll learn how to add other controls to your toolbox as well.
Figure 2.13. The standard toolbox contains many useful controls you can use to build robust user interfaces.
You can add a control to a form in one of three ways:
* In the toolbox, click the tool that you want to place on a form, and then click and drag on the form where you want the control placed (essentially, you're drawing the border of the control). The location at which you start dragging is used for the upper-left corner of the control, and the lower-right corner is the point at which you release the mouse button and stop dragging.
* Double-click the desired control in the toolbox. When you double-click a control in the toolbox, a new control of the selected type is placed in the upper-left corner of the form. The control's height and width are set to the default height and width of the selected control type.
* Drag a control from the toolbox and drop it somewhere on a form.
;Bulb: If you prefer to draw controls on your forms by clicking and dragging, I strongly suggest that you dock the toolbox to the right or bottom edge of the design environment or float it; the toolbar tends to interfere with drawing controls when it's docked to the left edge, because it obscures part of the form.
The very first item on the Windows Forms tab, titled Pointer, isn't actually a control. When the pointer item is selected, the design environment is placed in a select mode rather than in a mode to create a new control. With the pointer item selected, you can select a control (by clicking it) to display all its properties in the Properties window; this is the default behavior.
Setting Object Properties Using the Properties Window
When developing the interface of a project, you'll spend a lot of time viewing and setting object properties using the Properties window (see [Figure 2.14]). The Properties window contains four items:
* An object drop-down list
* A list of properties
* A set of tool buttons used to change the appearance of the properties grid
* A section showing a description of the selected property
Figure 2.14. Use the Properties window to view and change properties of forms and controls.
===Selecting an Object and Viewing Its Properties===
The drop-down list at the top of the Properties window contains the name of the form with which you're currently working and all the controls (objects) on the form. To view the properties of a control, select it from the drop-down list or click the control on the form. You must have the pointer item selected in the toolbox to select an object by clicking it.
===Viewing and Changing Properties===
The first two buttons in the Properties window (Categorized and Alphabetic), enable you to select the format in which you view properties. When you select the Alphabetic button, the selected object's properties are listed in the Properties window in alphabetical order. When you click the Categorized button, all the selected object's properties are displayed by category. For example, the Appearance category contains properties such as BackColor and BorderStyle. When working with properties, select the view you're most comfortable with and feel free to switch back and forth between the views.
The Properties pane of the Properties window is used to view and set the properties of a selected object. You can set a property in one of the following ways:
* Type in a value
* Select a value from a drop-down list
* Click a Build button for property-specific options
;Book - Pencil:Many properties can be changed by more than one of these methods.
To better understand how changing properties works, follow these steps:
# Start by creating a new Windows Application project. Name this project Changing Properties.
# Add a new text box to a form by double-clicking the TextBox tool in the toolbox. You're now going to change a few properties of the new text box.
# Select the Name property in the Properties window by clicking it, and then type in a name for the text box�call it txtComments.
# Click the BorderStyle property and try to type in the word Big�you can't; the BorderStyle property supports only selecting values from a list. You can type a value that exists in the list, however. When you selected the BorderStyle property, a drop-down arrow appeared in the value column. Click this arrow now to display a list of the values that the BorderStyle property accepts. Select FixedSingle and notice how the appearance of the text box changes. To make the text box appear three dimensional again, open the drop-down list and select Fixed3D.
# Select the BackColor property, type in some text, and press the Tab key to commit your entry. C# displays an Invalid Property Value error. This happened because, although you can type in text, you're restricted to entering specific values (in the case of BackColor, the value must be a number within a specific range or a named color). Click the drop-down arrow of the BackColor property and select a color from the drop-down list. (Selecting colors using the Color Palette is discussed later in this hour, and detailed information on using colors is provided in [Hour 10], "Drawing and Printing.")
# Select the Font property. Notice that a Build button appears (a small button with three dots on it). When you click the Build button, a dialog box specific to the property you've selected appears. In this instance, a dialog box that allows you to manipulate the font of the text box appears (see [Figure 2.15]). Different properties display different dialog boxes when you click their Build buttons.
Figure 2.15. The Font dialog box gives you complete authority over the font of a control.
By clicking a property in the Properties window, you can easily tell the type of input the property requires.
===Working with Color Properties===
Properties that deal with colors, such as BackColor and ForeColor, are unique in the way in which they accept values, yet all color-related properties behave the same way. In C#, all colors are expressed as a set of three numbers, each number having a value from 0 to 255. The set of numbers represents the Red, Green, and Blue (RGB) components of the color, respectively.
;Book - Pencil:The value 0,255,0, for instance, represents pure green, whereas the values 0,0,0 represent black and 255,255,255 represents white. (See [Hour 10] for more information on the specifics of working with color.)
A color rectangle is displayed for each color property in the Properties window; this color is the selected color for the property. Text is displayed next to the colored rectangle. This text is either the name of a color or a set of RGB values that defines the color. Clicking in a color property causes a drop-down arrow to appear, but the drop-down you get by clicking the arrow isn't a typical drop-down list. [Figure 2.16] shows what the drop-down list for a color property looks like.
Figure 2.16. The color drop-down list enables you to select from three sets of colors.
The color drop-down list is composed of three tabs: Custom, Web, and System. Most color properties use a system color by default. [Hour 10] goes into great detail on system colors, so I only want to mention here that system colors vary from computer to computer; they are the colors determined by the user when he or she right-clicks the desktop and chooses Properties from the desktop's shortcut menu. Use a system color when you want a color to be one of the user's selected system colors. When a color property is set to a system color, the name of the color appears in the property sheet.
The Custom tab shown in [Figure 2.17] is used to specify a specific color, regardless of the user's system color settings; changes to system colors have no effect on the property. The most common colors appear on the palette of the Custom tab, but you can specify any color you desire.
Figure 2.17. The Custom tab of the color drop-down list lets you specify any color imaginable.
;Book - Pencil:The colors visible in the various palettes are limited by the number of colors that can be produced by your video card. If your video card doesn't support enough colors, some will appear dithered, which means they will appear as dots of colors rather than as a true, solid color.
The bottom two rows in the Custom color palette are used to mix your own colors. To assign a color to an empty color slot, right-click a slot in one of the two rows to access the Define Color dialog box (see [Figure 2.18]). Use the controls on the Define Color dialog box to create the color you desire, and then click Add Color. The new color appears on the color palette in the slot you selected, and it is automatically assigned to the current property.
Figure 2.18. The Define Color dialog box lets you create your own colors.
The Web tab is used to pick colors from a list of named colors for building Web pages.
===Viewing Property Descriptions===
It's not always immediately apparent just exactly what a property is or does�especially for new users of Visual Studio. The Description section at the bottom of the Properties window shows a simple description of the selected property (refer to [Figure 2.14]). To view a description, simply click a property or value area of a property.
You can hide or show the Description section of the Properties window at any time by right-clicking anywhere within the Properties window (other than in the value column or on the title bar) to display the Properties window shortcut menu and choosing Description. Each time you do this, you toggle the Description section between visible and hidden. To change the size of the Description box, click and drag the border between it and the Properties pane.
Managing Projects
Before you can effectively create an interface and write code, you need to understand what makes up a C# project and how to add and remove various components from within your own projects. In this section, you'll learn about the Solution Explorer window and how it's used to manage project files. You'll also learn specifics about projects and project files, as well as how to change a project's properties.
Managing Project Files with the Solution Explorer
As you develop projects, they'll become more and more complex, often containing many objects such as forms and modules. Each object is defined by one or more files. In addition, you can build complex solutions composed of more than one project. The Solution Explorer window shown in [Figure 2.19] is the tool for managing all the files in a simple or complex solution. Using the Solution Explorer, you can add, rename, and remove project files, as well as select objects to view their properties. If the Solution Explorer window isn't visible on your screen, show it now by choosing Solution Explorer from the View menu.
Figure 2.19. Use the Solution Explorer window to manage all the files that make up a project.
To better understand the Solution Explorer window, follow these steps:
# Locate the Picture Viewer program you created in the Quick Tour by choosing File, Open, and then clicking Project.
# Open the Picture Viewer project. The file you need to select is located in the Picture Viewer folder that C# created when the project was constructed. The file has the extension .sln (for solution). If you're asked whether you want to save the current project, choose No.
# Select the Picture Viewer project item in the Solution Explorer. When you do, a button becomes visible toward the top of the window. This button has a picture of pieces of paper and has the ToolTip Show All Files (see [Figure 2.20]). Click this button and the Solution Explorer displays all files in the project.
Figure 2.20. Notice that the form you defined appears as two files in the Solution Explorer.
Your design environment should now look like the one in [Figure 2.20]. If your screen looks much different from the one in this figure, use the techniques you've learned in this hour to change your design environment so that it's similar to the one shown here. Be sure to widen the Solution Explorer window so that you can read all the text it contains.
;Book - Pencil:Some forms and other objects may be composed of more than one file. By default, C# hides project files that you don't directly manipulate. Click the plus sign (+) next to the form item and you'll see a sub item titled Form1.resx. You'll learn about these additional files in [Hour 5], "Building Forms�Part I." For now, click the Show All Files button again to hide these related files.
You can view any object listed within the Solution Explorer using the object's default viewer by double-clicking the object. Each object has a default viewer but may actually have more than one viewer. For instance, a form has a Form Design view as well as a Code view. By default, double-clicking a form in the Solution Explorer displays the form in Form Design view, where you can manipulate the form's interface.
You've already learned one way to access the code behind a form�double-click an object to access its default event handler. You'll frequently need to get to the code of a form without adding a new event handler. One way to do this is to use the Solution Explorer. When a form is selected in the Solution Explorer, buttons are visible at the top of the Solution Explorer window that allow you to display the code editor or the form designer, respectively.
You'll use the Solution Explorer window so often that you'll probably want to dock it to an edge and set it to Auto Hide, or perhaps keep it visible all the time. The Solution Explorer window is one of the easiest to get the hang of in C#; navigating the Solution Explorer window will be second nature to you before you know it.
===Working with Solutions===
In truth, the Solution Explorer window is the evolution of the Project Explorer window from versions of Visual Studio prior to .NET, and the two are similar in many ways. Understanding solutions is easier to do when you understand projects.
A project is what you create with C#. Often, the words project and program are used interchangeably; this isn't much of a problem if you understand the important distinctions. A project is the set of source files that make up a program or component, whereas a program is the binary file that you build by compiling source files into something such as a Windows executable file (.exe). Projects always consist of a main project file and may be made up of any number of other files, such as form files, module files, or class module files. The main project file stores information about the project�all the files that make up the project, for example�as well as properties that define aspects of a project, such as the parameters to use when the project is compiled into a program.
What then, is a solution? As your abilities grow and your applications increase in complexity, you'll find that to accomplish your development goals, you'll have to build multiple projects that work harmoniously. For instance, you might build a custom user control such as a custom data grid that you use within other projects you design, or you may isolate the business rules of a complex application into separate components to run on isolated servers. All the projects used to accomplish those goals are collectively called a solution. Therefore, a solution (at its most basic level) is really nothing more than a grouping of projects.
;Bulb: You should group projects into a single solution only when the projects relate to one another. If you have a number of projects that you're working on, but each of them is autonomous, work with each project in a separate solution.
Understanding Project Components
As I stated earlier, a project always consists of a main project file, and it may consist of one or more secondary files, such as files that make up forms or code modules. As you create and save objects within your project, one or more corresponding files are created and saved on your hard drive. All files that are created for C# source objects have the extension .cs, designating that they define C# objects. Make sure that you save your objects with understandable names, or things might get confusing as the size of your project grows.
All the files that make up a project are text files. Some objects, however, need to store binary information, such as a picture, for a form's BackgroundImage property. Binary data is stored in an XML file (which is still a text file). Suppose you had a form with an icon on it. You'd have a text file defining the form (its size, the controls on it, and the code behind it), and an associated resource file with the same name as the form file but with the extension .resx. This second file would be in XML format and would contain all the binary data needed to create the form.
;Book - Pencil:If you want to see what the source file of a form file looks like, use Notepad to open a form file on your computer. Don't save any changes to the file, however, or it may never work again.
The following is a list of some of the components you may use in your projects:
* Forms Forms are the visual windows that make up the interface of your application. Forms are defined using a special type of module.
* Class Modules Class modules are a special type of module that enable you to create object-oriented applications. Throughout the course of this book, you're learning how to program using an object-oriented language, but you're mostly learning how to use objects supplied by C#. In [Hour 17], "Designing Objects with Classes," you'll learn how to use class modules to create your own objects. Forms are derived from a special type of class module.
* User Controls User controls (formerly ActiveX controls, which are formerly OLE controls) are controls that can be used on the forms of other projects. For example, you could create a User control with a calendar interface for a contact manager. Creating user controls requires the skill of an experienced programmer; therefore, I won't be covering them in this book.
===Setting Project Properties===
C# projects have properties, just as other objects do, such as forms and controls. Projects have lots of properties, many of them relating to advanced functionality that I won't be covering in this book. However, you need to be aware of how to access project properties and how to change some of the more commonly used properties.
To access the properties for a project, right-click the project in the Solution Explorer window and choose Properties from the shortcut menu. Do this now.
;Book - Pencil:In earlier versions of Visual Studio, you accessed the project properties via the Project menu. You can still do this, but you must have the project selected in the Solution Explorer, or the Properties menu won't appear on the Project menu. If you don't remember this, you could spend a lot of time trying to find the properties�I sure did.
The Tree View control on the left side of the dialog box is used to display a property page (see [Figure 2.21]). When you first open the dialog box, the General page is visible. On this page, the setting you'll need to worry about most is the Startup Object property. The Startup Object setting determines the name of the class that contains the Main() method that you want called on program startup. The (Not Set) option, as shown in [Figure 2.21], is valid if only one Main() method exists in your application.
Figure 2.21. Project properties let you tailor aspects of the project as a whole.
The Output Type option determines the type of compiled component defined by this source project. When you create a new project, you select the type of project to create (such as Windows Application), so this field is always filled in. At times, you might have to change this setting after the project has been created, and this is the place to do so.
Notice that the project folder, project filename, and output name are displayed on this page as well. If you work with a lot of projects, you may find this information valuable, and this is certainly the easiest spot to obtain it.
;Book - Pencil:The output name determines the filename created when you build a distributable component. Distributing applications is discussed in [Hour 22].
As you work through the hours in this book, I'll refer to the Project Properties dialog box as necessary, explaining pages and items in context with other material.
===Adding and Removing Project Files===
When you first start C# and create a new Windows Application project, C# creates the project with a single form. You're not limited to having one form in a project, however; you can create new forms or add existing forms to your project at will. You can also create and add code files and classes, as well as other types of objects.
You can add a new or existing object to your project in one of three ways:
* Choose the appropriate menu item from the Project menu.
* Click the small drop-down arrow that is part of the Add New Item button on the Standard toolbar, and then choose the object type from the drop-down list that is displayed (see [Figure 2.22]).
* Right-click the project name in the Solution Explorer window, and then choose Add from the shortcut menu to access a submenu from which you can select object types.
When you select Add ObjectType from any of these menus, a dialog box appears, showing you the objects that can be added to the project. Your chosen item is selected by default (see [Figure 2.23]). Simply name the object and click Open to create a new object of the selected type. To create an object of a different type, click the type to select it, name it, and then click Open.
Figure 2.23. Regardless of the menu option you select, you can add any type of object you want using this dialog box.
Adding new forms and modules to your project is easy, and you can add as many as you like. You'll come to rely more heavily on the Solution Explorer to manage all the objects in the project as the project becomes more complex.
Although it won't happen as often as adding project files, you may sometimes need to remove an object from a project. Removing objects from your project is even easier than adding them. To remove an object, simply right-click the object in the Solution Explorer window and select Exclude from Project. This removes the object from the file but does not delete the source file from the disk. Selecting Delete, on the other hand, removes the file from the project and deletes it from the disk. Don't select Delete unless you want to totally destroy the file and you're sure that you'll never need it again in the future.
Getting Help
Although C# was designed to be as intuitive as possible, you'll find that you occasionally need assistance in performing a task. It doesn't matter how much you know, C# is so complex and contains so many features that you'll have to use Help sometimes. This is particularly true when writing C# code; you won't always remember the command you need or the syntax of the command. Fortunately, C# includes a comprehensive Help feature.
To access Help from within the design environment, press F1. Generally speaking, when you press F1, C# shows you a help topic directly related to what you're doing. This is known as context-sensitive help, and when it works, it works well. For example, you can display help for any C# syntax or keyword (functions, objects, methods, properties, and so on) when writing C# code by typing the word into the code editor, positioning the cursor anywhere within the word (including before the first letter or after the last), and pressing F1. You can also get to help from the Help menu on the menu bar.
;Book - Pencil:C#'s Help won't be displayed if your program is in Run mode when you press F1. Instead, the help for your application will appear�if you've created Help.
Help displays topics directly within the design environment instead of in a separate window. This is a new feature of .NET. Personally, I think this method is considerably inferior to the old style of Visual Studio having Help float above the design environment. When Help is displayed within the design environment, you can't necessarily see the code, form, or other object with which you're working. To make Help float above the design environment, choose Options from the Tools menu to display the Options dialog box, click Help in the Tree view on the left, and select External Help.
C# includes a Help feature called Dynamic Help. To display the Dynamic Help window, choose Dynamic Help from the Help menu. The Dynamic Help window shows Help links related to what it is you're working on (see [Figure 2.24]). For instance, if you select a form, the contents of the Dynamic Help window show you Help links related to forms. If you click a text box, the contents of the Dynamic Help window adjust to show you Help links related to text boxes. This is an interesting feature, and you may find it valuable.
===Summary===
In this hour, you learned how to use the Visual Studio Start page�your gateway to C#. You learned how to create new projects and how to open existing projects. The C# environment is your workspace, toolbox, and so much more. You learned how to navigate the environment, including how to work with design windows (hide, show, dock, and float).
You'll use toolbars constantly, and now you know how to modify them to suit your specific needs. You learned how to create new toolbars and how to modify existing toolbars. This is an important skill that shouldn't be overlooked.
C# has many different design windows, and in this hour, you began learning about some of them in detail. You learned how to get and set properties using the Properties window, how to manage projects using the Solution Explorer, and how to add controls to a form using the toolbox. You'll use these skills often, so it's important to get familiar with them right away. Finally, you learned how to access C#'s Help feature, which I guarantee you will find very important as you learn to use C#.
C# is a vast and powerful development tool. Don't expect to become an expert overnight; this is simply impossible. However, by learning the tools and techniques presented in this hour, you've begun your journey. Remember, you'll use most of what you learned in this hour each and every time you use C#. Get proficient with these basics and you'll be building cool programs in no time!
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[Q1:'''
| How can I easily get more information about a property when the Description section of the Properties window just doesn't cut it?
|-
| align="right" | ''' A1: '''
| Click the property in question to select it, and then press F1; context-sensitive help applies to properties in the Properties window, as well.
|-
| align="right" | '''[Q2:'''
| I find that I need to see a lot of design windows at one time, but I can't find that "magic" layout. Any suggestions?
|-
| align="right" | ''' A2: '''
| Run at a higher resolution. Personally, I won't develop in less than 1024x768. As a matter of fact, all my development machines have two displays, both running at this resolution. You'll find that any investment you make in having more screen real estate will pay you big dividends.
===Workshop===
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [Appendix A], "Answers to Quizzes/Exercises."
===Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[ 1:'''
| How can you make the Visual Studio Start Page appear at startup if this feature has been disabled?
|-
| align="right" | '''[ 2:'''
| Unless instructed otherwise, you are to create what type of project when building examples in this book?
|-
| align="right" | '''[ 3:'''
| To make a docked design window appear when you hover over its tab and disappear when you move the mouse away from it, you change what setting of the window?
|-
| align="right" | '''[ 4:'''
| How do you access the Toolbars menu?
|-
| align="right" | '''[ 5:'''
| What design window do you use to add controls to a form?
|-
| align="right" | '''[ 6:'''
| What design window is used to change the attributes of an object?
|-
| align="right" | '''[ 7:'''
| To modify the properties of a project, you must select the project in what design window?
|-
| align="right" | '''[ 8:'''
| Which Help feature adjusts the links it displays to match what it is you are doing?
Exercises
# Create a custom toolbar that contains Save All, Start, and Stop Debugging�three buttons you'll use a lot throughout this book.
# Use the Custom Color dialog box to create a color of your choice, and then assign the color to the BackColor property of a form.
= Hour 3. Understanding Objects and Collections =
So far, you've gotten an introduction to programming in C# by building a Picture Viewer project. You spent the previous hour digging into the IDE and learning skills critical to your success with C#. In this hour, you're going to start learning about some important programming concepts, namely objects.
;New term:The term object, as it relates to programming, may have been new to you prior to this book. The more you work with C#, the more you'll hear about objects. C# is a true object-oriented language. This hour isn't going to discuss object-oriented programming in any detail, because object-oriented programming is a very complex subject and is well beyond the scope of this book. Instead, you'll learn about objects in a more general sense. Everything you use in C# is an object, so understanding this material is critical to your success with C#. Forms are objects, for example, as are the controls you place on a form. Pretty much every element of a C# project is an object and belongs to a collection of objects. All objects have attributes (called properties), most have methods, and many have events. Whether creating simple applications or building large-scale enterprise solutions, you must understand what an object is and how it works. In this hour, you'll learn what makes an object an object, and you'll learn about collections.
The highlights of this hour include the following:
* Understanding objects
* Getting and setting properties
* Triggering methods
* Understanding method dynamism
* Writing object-based code
* Understanding collections
* Using the Object Browser
;Book - Pencil:If you've listened to the programming press at all, you've probably heard the term object oriented, and perhaps words such as polymorphism, encapsulation, and inheritance. In truth, these object-oriented features of C# are very exciting, but they're far beyond [03.htm#ch03 Hour 3]. You'll learn a little about object-oriented programming in this book, but if you're really interested in taking your programming skills to the next level, you should buy a book dedicated to the subject after you've completed this one.
----
=== Understanding Objects ===
Object-oriented programming has been a technical buzzword for quite some time. Almost everywhere you look�the Web, publications, books�you read about objects. What exactly is an object? Strictly speaking, it is a programming structure that encapsulates data and functionality as a single unit and for which the only public access is through the programming structure's interfaces (properties, methods, and events). In reality, the answer to this question can be somewhat ambiguous because there are so many types of objects�and the number grows almost daily. However, all objects share specific characteristics, such as properties and methods.
The most commonly used objects in Windows applications are the form object and the control object. Earlier hours introduced you to working with forms and controls and even showed you how to set form and control properties. In your Picture Viewer project from [Hour 1], for instance, you added a picture box and two buttons to a form. Both the PictureBox and the Button control are control objects, but each is a specific type of control object. Another, less-technical example uses pets. Dogs and cats are definitely different entities (objects), but they both fit into the category of Pet objects. Similarly, text boxes and buttons are each a unique type of object, but they're both considered a control object. This small distinction is important.
Understanding Properties
All objects have attributes used to specify and return the state of the object. These attributes are properties, and you've already used some of them in previous hours using the Properties window. Indeed, every object exposes a specific set of properties, but not every object exposes the same set of properties. To illustrate this point, I will continue with the Pet object concept. Suppose you have an object, and the object is a dog. This Dog object has a certain set of properties that are common to all dogs. These properties include attributes such as the dog's name, the color of its hair, and even the number of legs it has. All dogs have these same properties; however, different dogs have different values for these properties. [Figure 3.1] illustrates such a Dog object and its properties.
Figure 3.1. Properties are the attributes that describe an object.
[[Image:03fig01.gif|334px|graphics/03fig01.gof]]
===Getting and Setting Properties===
You've already seen how to read and change properties using the Properties window. The Properties window is available only at design time, however, and is used only for manipulating the properties of forms and controls. Most reading and changing of properties you'll perform will be done with C# code, not by using the Properties window. When referencing properties in code, you specify the name of the object first, followed by a period (.), and then the property name, as in the following syntax:
<pre>{ObjectName}.{Property}
</pre>
If you had a Dog object named Bruno, for example, you would reference Bruno's hair color this way:
<pre>Bruno.HairColor
</pre>
This line of code would return whatever value was contained in the HairColor property of the Dog object Bruno. To set a property to some value, you use an equal (=) sign. For example, to change the Dog object Bruno's Weight property, you would use a line of code such as the following:
<pre>Bruno.Weight = 90;
</pre>
;Book - Pencil:A little later in this hour, I discuss instantiation, which is the process of creating an object based on a template. It's important to note here that Bruno is a named instance of an object derived from a template or blueprint (called a class). Each object instance has its own set of data, such as property values. For example, you could also have a Dog object named Bonnie, which has a unique set of properties. In a more real-world example, consider how you can have two buttons on a form. Although they have different property values (such as Name), and they have different code within their Click events, they are both Button objects.
When you reference a property on the left side of an equal sign, you're setting the value. When you reference a property on the right side of the equal sign, you're getting (reading) the value.
<pre>Bruno.Weight = 90;
</pre>
It's easier to see here that referencing the property on the left side of the equal sign indicates that you are setting the property to some value.
The following line of code places the value of the Weight property of the Dog object called Bruno into a temporary variable. This statement retrieves the value of the Weight property because the Weight property is referenced on the right side of the equal sign.
<pre>fltWeight = Bruno.Weight;
</pre>
Variables are discussed in detail in [Hour 12], "Using Constants, Data Types, Variables, and Arrays." For now, think of a variable as a storage location. When the processor executes this code statement, it retrieves the value in the Weight property of the Dog object Bruno and places it in the variable (storage location) titled Weight. Assuming that Bruno's Weight is 90, as set in the previous example, the computer would process the following code statement:
<pre>fltWeight = 90;
</pre>
Just as in real life, some properties can be read but not changed. Suppose you had a Sex property to designate the gender of a Dog object. It's impossible for you to change a dog from a male to a female or vice versa (at least I think it is). Because the Sex property can be retrieved but not changed, it is a read-only property. You'll often encounter properties that can be set in Design view but become read-only when the program is running.
One example of a read-only property is the Height property of the Combo Box control. Although you can view the value of the Height property in the Properties window, you cannot change the value�no matter how hard you try. If you attempt to change the Height property using C# code, C# simply changes the value back to the default.
;Book - Pencil:The best way to determine which properties of an object are read-only is to consult the online help for the object in question.
Working with an Object and Its Properties
Now that you know what properties are and how they can be viewed and changed, you're going to experiment with properties in a simple project. In [Hour 1], you learned how to set the Height and Width properties of a form using the Properties window. Now, you're going to change the same properties using C# code.
The project you're going to create consists of a form with some buttons on it. One button will enlarge the form when clicked, whereas the other will shrink the form. This is a very simple project, but it illustrates rather well how to change object properties in C# code.
# Start by creating a new Windows Application project (from the File menu, choose New, Project).
# Name the project Properties Example.
# Use the Properties window to change the name of the form to fclsShrinkMe. (Click the form once to select it and press F4 to display the Properties window.)
# Next, change the Text property of the form to Grow and Shrink.
# Click the View Code button in Solution Explorer to view the code behind the form. Scroll down and locate the reference to Form1 and change it to fclsShrinkMe.
# Click the Form1.cs [Design] tab to return to the form designer.
When the project first runs, the default form will have a Height and Width as specified in the Properties window. You're going to add buttons to the form that a user can click to enlarge or shrink the form at runtime.
Add a new button to the form by double-clicking the Button tool in the toolbox. Set the new button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Set To
|-
| <code>Name</code>
| <code>btnEnlarge</code>
|-
| <code>Location</code>
| <code>111,70</code>
|-
| <code>Text</code>
| <code>Enlarge</code>
|}
Now for the Shrink button. Again, double-click the Button tool in the toolbox to create a new button on the form. Set this new button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Set To
|-
| <code>Name</code>
| <code>btnShrink</code>
|-
| <code>Location</code>
| <code>111,120</code>
|-
| <code>Text</code>
| <code>Shrink</code>
|}
Your form should now look like the one shown in [Figure 3.2].
Figure 3.2. Each button is an object, as is the form the buttons sit on.
To complete the project, you need to add the small amount of C# code necessary to modify the form's Height and Width properties when the user clicks a button. Access the code for the Enlarge button now by double-clicking the Enlarge button. Type the following statement exactly as you see it here. Do not hit the Enter key or add a space after you've entered this text.
<pre>this.Width
</pre>
When you typed the period, or "dot," as it's called, a small drop-down list appeared, like the one shown in [Figure 3.3]. C# is smart enough to realize that this represents the current object (more on this in a moment), and to aid you in writing code for the object, it gives you a drop-down list containing all the properties and methods of the form. This feature is called IntelliSense, and it is relatively new to Visual Studio. Because C# is fully object-oriented, you'll come to rely on IntelliSense drop-down lists in a big way; I think I'd rather dig ditches than program without them.
Figure 3.3. IntelliSense drop- down lists, or auto-completion drop-down lists, make coding dramatically easier.
Use the Backspace key to completely erase the code you just entered and enter the following code in its place (press Enter at the end of each line):
<pre>this.Width = this.Width + 20;
this.Height = this.Height + 20;
</pre>
Again, the word <code>this</code> refers to the object to which the code belongs (in this case, the form). The word <code>this</code> is a reserved word; it's a word that you cannot use to name objects or variables because C# has a specific meaning for it. When writing code within a form module, as you are doing here, you should always use the <code>this</code> reserved word rather than using the name of the form. <code>this</code> is much shorter than using the full name of the current form, and it makes the code more portable (you can copy and paste the code into another form module and not have to change the form name to make the code work). Also, should you change the name of the form at any time in the future, you won't have to change references to the old name.
;Book - Pencil:The word <code>this</code> is the equivalent to the <code>Me</code> reserved word in Visual Basic.
The code you've entered simply sets the Width and Height properties of the form to whatever the current value of the Width and Height properties happens to be, plus 20 pixels.
Redisplay the form designer by selecting the tab titled Form1.cs [Design]; then double-click the Shrink button to access its Click event and add the following code:
<pre>this.Width = this.Width � 20;
this.Height = this.Height � 20;
</pre>
This code is very similar to the code in the Enlarge_Click event, except that it reduces the Width and Height properties of the form by 20 pixels.
Your screen should now look like [Figure 3.4].
Figure 3.4. The code you've entered should look exactly like this.
;Bulb: As you create projects, it's a very good idea to save frequently. Save your project now by clicking the Save All button on the toolbar.
Again, display the form designer by clicking the tab Form1.cs [Design]. Your Properties Example is now ready to be run! Press F5 to put the project in Run mode (see [Figure 3.5]).
Figure 3.5. What you see is what you get�the form you created should look just as you designed it.
Click the Enlarge button a few times and notice how the form gets bigger. Next, click the Shrink button to make the form smaller. When you've clicked enough to satisfy your curiosity (or until you get bored), end the running program and return to Design mode by clicking the Stop Debugging button on the toolbar.
Understanding Methods
In addition to properties, most objects have methods. Methods are actions the object can perform, in contrast to attributes that describe the object. To understand this distinction, think about the Pet object example. A Dog object has a certain set of actions that it can perform. These actions, called methods in C#, include barking and tail wagging. [Figure 3.6] illustrates the Dog object and its methods.
Figure 3.6. Invoking a method causes the object to perform an action.
[[Image:03fig06.gif|334px|graphics/03fig06.gof]]
===Triggering Methods===
Think of methods as functions�which is exactly what they are. When you invoke a method, code is executed. You can pass data to the method, and methods may return values. However, a method is neither required to accept parameters (data passed by the calling code) nor required to return a value; many methods simply perform an action in code. Invoking (triggering) a method is similar to referencing the value of a property; you first reference the object's name, then a "dot," then the method name, followed by a set of parentheses, which can optionally contain any parameters that must be passed to the method.
<pre>{ObjectName}.{Method}();
</pre>
For example, to make the hypothetical Dog object Bruno bark using C# code, you would use this line of code:
<pre>Bruno.Bark();
</pre>
;Book - Pencil:Method calls in C# must always have parentheses. Sometimes they'll be empty, but at other times they'll contain data.
Invoking methods is simple; the real skill lies in knowing what methods an object supports and when to use a particular method.
===Understanding Method Dynamism===
Properties and methods go hand in hand, and at times a particular method may become unavailable because of one or more property values. For example, if you were to set the NumberofLegs on the Dog object Bruno equal to zero, the Walk and Fetch methods would obviously be inapplicable. If you were to set the NumberofLegs property back to four, you could then trigger the Walk or Fetch methods again. In C#, a method or property won't physically become unavailable�you can still call it, but doing so might cause an exception (error) or the call may be ignored.
| align="right" | >
Building an Object Example Project
The only way to really grasp what objects are and how they work is to use them. I've said this before but I can't say it enough: everything in C# is an object.
You're about to create a sample project that uses objects. If you're new to programming with objects, you'll probably find this a bit confusing. However, I'll walk you through step by step, explaining each section in detail.
The project you're going to create consists of a single form with one button on it. When the button is clicked, a line will be drawn on the form beginning at the upper-left corner of the form and extending to the lower-right corner.
;Book - Pencil:In [Hour 10], "Drawing and Printing," you'll learn all about the drawing functionality within C#.
Creating the Interface for the Drawing Project
Follow these steps to create the interface for your project:
# Create a new Windows Application project titled Object Example.
# Change the form's Text property to Object Example using the Properties window.
# Add a new button to the form and set its properties as shown in the following table:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnDraw</code>
|-
| <code>Location</code>
| <code>112,120</code>
|-
| <code>Text</code>
| <code>Draw</code>
|}
Writing the Object-Based Code
You're now going to add code to the Click event of the button. I'm going to explain each statement, and at the end of the steps, I'll show the complete code listing.
===Object Example Project===
# Double-click the button to access its Click event.
# Enter the first line of code as follows (remember to press Enter at the end of each statement):
<pre>System.Drawing.Graphics objGraphics = null;
</pre>
Objects don't materialize out of thin air; they have to be created. When a form is loaded into memory, it loads all its controls (that is, creates the control objects), but not all objects are created automatically like this. The process of creating an instance of an object is called instantiation. When you load a form, you instantiate the form object, which in turn instantiates its control objects. You could load a second instance of the form, which in turn would instantiate a new instance of the form and new instances of all controls. You would then have two forms in memory and two of each used control.
To instantiate an object in code, you create a variable that holds a reference to an instantiated object. You then manipulate the variable as an object. The statement you wrote in step 2 creates a new variable called objGraphics, which holds a reference to an object of type Graphics from the .NET Framework System.Drawing class. You also initialized the value for objGraphics to null. You learn more about variables in [Hour 12], "Using Constants, Data Types, Variables, and Arrays."
# Enter the second line of code exactly as shown here:
<pre>objGraphics = CreateGraphics();
</pre>
CreateGraphics is a method of the form. The CreateGraphics method is pretty complicated under the hood, and I discuss it in detail in [Hour 10]. For now, understand that the method CreateGraphics instantiates a new object that represents the client area of the current form. The client area is the gray area within the borders and title bar of a form. Anything drawn onto the objGraphics object appears on the form. What you've done is set the variable objGraphics to point to an object that was returned by the CreateGraphics method. Notice how values returned by a property or method don't have to be traditional values such as numbers or text; they can also be objects.
# Enter the third line of code as shown next:
<pre>objGraphics.Clear(System.Drawing.SystemColors.Control);
</pre>
This statement clears the background of the form using whatever color the user has selected as the Windows forms color.
How does this happen? In step 3, you used the CreateGraphics method of the form to instantiate a new graphics object in the variable objGraphics. With the code statement you just entered, you're calling the clear method of the objGraphics object. The Clear method is a method of all Graphics objects used to clear the graphics surface. The Clear method accepts a single parameter�the color to which you want the surface cleared.
The value you're passing to the parameter looks fairly convoluted. Remember that "dots" are a method of separating objects from their properties and methods.
Knowing this, you can discern that System is an object (technically it's a Namespace, as discussed in [Hour 24], "The 10,000-Foot View," but for our purposes it behaves just like an object) because it appears before any of the dots. However, there are multiple dots. What this means is that Drawing is an object property of the System object; it's a property that returns an object. So the dot following Drawing is used to access a member of the Drawing object, which in turn is a property of the System object. We're not done yet, however, because there is yet another dot. Again, this indicates that SystemColors, which follows a dot, is an object of the Drawing object, which in turn is…well, you get the idea. As you can see, object references can and do go pretty deep, and you'll use many dots throughout your code. The key points to remember are the following:
#* Text that appears to the left of a dot is always an object (or Namespace).
#* Text that appears to the right of a dot is a property reference or a method call.
#* Methods are never objects. In addition, methods are always followed by parentheses. If the text in question isn't followed by parentheses, it's definitely a property. Therefore, text that appears between two dots is a property that returns an object. Such a property is called an object property.
The final text in this statement is the word Control. Because Control is not followed by a dot, you know that it's not an object; therefore, it must be a property or a method. Because you expect this string of object references to return a color value to be used to clear the Graphics object, you know that Control must be a property or a method that returns a value. A quick check of the documentation (or simply realizing that the text isn't followed by a set of parentheses) would tell you that Control is indeed a property. The value of Control always equates to the color designated on the user's computer for the face of forms. By default, this is a light gray (often fondly referred to as battleship gray), but users can change this value on their computers. By using this property to specify a color rather than supplying the actual value for gray, you are assured that no matter the color scheme used on a computer, the code will clear the form to the proper system color. System colors are explained in [Hour 10].
# Enter the following statement:
<pre>objGraphics.DrawLine(System.Drawing.Pens.Chartreuse, 0, 0,
this.DisplayRectangle.Width, this.DisplayRectangle.Height);
</pre>
This statement draws a chartreuse line on the form. Within this statement is a single method call and three property references. Can you tell what's what? Immediately following objGraphics (and a dot) is DrawLine. Because no equal sign is present (and the text is followed by parentheses), you can deduce that this is a method call. As with the Clear() method, the parentheses after DrawLine() are used to enclose a value passed to the method. The DrawLine() method accepts the following parameters in the order in which they appear here:
#* A Pen
#* X value of first coordinate
#* Y value of first coordinate
#* X value of second coordinate
#* Y value of second coordinate
The DrawLine() method draws a straight line between coordinate one and coordinate two, using the pen specified in the Pen parameter. I'm not going to go into detail on pens here (refer to [Hour 10]), but suffice it to say that a pen has characteristics such as width and color. Looking at the dots once more, notice that you're passing the Chartreuse property of the Pens object. Chartreuse is an object property that returns a predefined Pen object that has a width of 1 pixel and the color chartreuse.
You're passing 0 as the next two parameters. The coordinates used for drawing are defined such that 0,0 is always the upper-left corner of a surface. As you move to the right of the surface, X increases, and as you move down the surface, Y increases; you can use negative values to indicate coordinates that appear to the left or above the surface. The coordinate 0,0 causes the line to be drawn from the upper-left corner of the form's client area.
The object property DisplayRectangle is referenced twice in this statement. DisplayRectangle is a property of the form that holds information about the client area of the form. Here, you're simply getting the Width and Height properties of the client area and passing them to the DrawLine method. The result is that the end of the line will be at the lower-right corner of the form's client area.
# Last, you have to clean up after yourself by entering the following code statement:
<pre>objGraphics.Dispose();
</pre>
Objects often make use of other objects and resources. The underlying mechanics of an object can be truly boggling and almost impossible to discuss in an entry-level programming book. The net effect, however, is that you must explicitly destroy most objects when you're done with them. If you don't destroy an object, it may persist in memory and it may hold references to other objects or resources that exist in memory. This means you can create a memory leak within your application that slowly (or rather quickly) munches system memory and resources. This is one of the cardinal no-no's of Windows programming, yet the nature of using resources and the fact you're responsible for telling your objects to clean up after themselves makes this easy to do.
Objects that must explicitly be told to clean up after themselves usually provide a Dispose method. When you're done with such an object, call Dispose on the object to make sure it frees any resources it might be holding.
For your convenience, following are all the lines of code:
<pre>System.Drawing.Graphics objGraphics = null;
objGraphics = CreateGraphics();
objGraphics.Clear(System.Drawing.SystemColors.Control);
objGraphics.DrawLine(System.Drawing.Pens.Chartreuse, 0, 0,
this.DisplayRectangle.Width, this.DisplayRectangle.Height);
objGraphics.Dispose();
</pre>
Testing Your Object Example Project
Now the easy part. Run the project by pressing F5 or by clicking the Start button on the toolbar. Your form looks pretty much like it did at design time. Clicking the button causes a line to be drawn from the upper-left corner of the form's client area to the lower-right corner (see [Figure 3.7]).
Figure 3.7. Simple lines and complex drawings are accomplished using objects.
;Book - Pencil:If you receive any errors when you attempt to run the project, go back and make sure the code you entered exactly matches the code I've provided.
Resize the form, larger or smaller, and click the button again. Notice that the form is cleared and a new line is drawn. If you were to omit the statement that invokes the Clear method (and you're welcome to stop your project and do so), the new line would be drawn, but any and all lines already drawn would remain.
;Book - Pencil:If you use Alt+Tab to switch to another application after drawing one or more lines, the lines will be gone when you come back to your form. In [Hour 10], you'll learn why this is so and how to work around this behavior.
Stop the project now by clicking Stop Debugging on the C# toolbar and then click Save All to save your project. What I hope you've gained from building this example is not necessarily that you can now draw a line (which is cool), but rather an understanding of how objects are used in programming. As with learning almost anything, repetition aids in understanding. Therefore, you'll be working with objects a lot throughout this book.
| align="right" | >
Understanding Collections
A collection is just what its name implies: a collection of objects. Collections make it easy to work with large numbers of similar objects by enabling you to create code that performs iterative processing on items within the collection. Iterative processing is an operation that uses a loop to perform actions on multiple objects, rather than writing the operative code for each object. In addition to containing an indexed set of objects, collections also have properties and may have methods. [Figure 3.8] illustrates the structure of a collection.
Figure 3.8. Collections contain sets of like objects, and they have their own properties and methods.
[[Image:03fig08.gif|324px|graphics/03fig08.gof]]
Continuing with the Dog/Pet object metaphor, think about what an Animals collection might look like. The Animals collection could contain one or more Pet objects, or it could be empty (containing no objects). All collections have a Count property that returns the total count of objects contained within the collection. Collections may also have methods, such as a Delete method used to remove objects from the collection or an Add method used to add a new object to the collection.
To better understand collections, you're going to create a small C# project that cycles through the Controls collection of a form, telling you the value of the Name property of every control on the form.
To create your sample project, follow these steps:
# Start C# now (if it's not already loaded) and create a new Windows Application project titled Collections Example.
# Change the text of the form to Collections Example by using the Properties window.
# Add a new button to the form by double-clicking the Button tool in the toolbox. Set the button's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>btnShowNames</code>
|-
| <code>Location</code>
| <code>88,112</code>
|-
| <code>Size</code>
| <code>120,23</code>
|-
| <code>Text</code>
| <code>Show Control Names</code>
|}
# Next, add some text box and label controls to the form. As you add the controls to the form, be sure to give each control a unique name. Feel free to use any name you like, but you can't use spaces in a control name. You may want to drag the controls to different locations on the form so that they don't overlap.
# When you are finished adding controls to your form, double-click the Show Control Names button to add code to its Click event. Enter the following code:
<pre>for (int intIndex=0; intIndex < this.Controls.Count; intIndex++)
{
MessageBox.Show ("Control # " + intIndex.ToString() +
" has the name " + this.Controls[intIndex].Name);
}
</pre>
;Book - Pencil:Every form has a Controls collection, which may or may not contain any controls. Even if no controls are on the form, the form still has a Controls collection.
The first statement (the one that begins with for) accomplishes a few tasks. First, it initializes the variable intIndex to 0, and then tests the variable. It also starts a loop executing the statement block (loops are discussed in [Hour 15], "Looping for Efficiency"), incrementing intIndex by one until intIndex equals the number of controls on the form, less one. The reason that intIndex must always be less than the Count property is that when referencing items in a collection, the first item is always item zero�collections are zero based. Thus, the first item is in location zero, the second item is in location one, and so forth. If you tried to reference an item of a collection in the location of the value of the Count property, an error would occur because you would be referencing an index that is one higher than the actual locations within the collection.
The MessageBox.Show() method (discussed in detail in [Hour 18], "Interacting with Users ") is a class available in the .NET Framework that is used to display a simple dialog box with text. The text that you are providing, which the MessageBox.Show() method will display, is a concatenation of multiple strings of text. (Concatenation is the process of adding strings together; it is discussed in [Hour 13], "Performing Arithmetic, String Manipulation, and Date/Time Adjustments.")
Run the project by pressing F5 or by clicking Start on the toolbar. Ignore the additional controls that you placed on the form and click the Show Control Names button. Your program will then display a message box similar to the one shown in [Figure 3.9] for each control on your form (because of the loop). When the program is finished displaying the names of the controls, choose Stop Debugging from the Debug toolbar to stop the program, and then save the project.
Figure 3.9. The Controls collection enables you to get to each and every control on a form.
Because everything in C# is an object, you can expect to use numerous collections as you create your programs. Collections are powerful, and the quicker you become comfortable using them, the more productive you'll become.
| align="right" | >
Using the Object Browser
C# includes a useful tool that lets you easily view members, such as properties and methods, of all the objects in a project: the Object Browser (see [Figure 3.10]). This is extremely useful when dealing with objects that aren't well documented, because it enables you to see all the members an object supports. To view the Object Browser, display the Other Windows submenu of the View menu and choose Object Browser.
Figure 3.10. The Object Browser lets you view all properties and methods of an object.
The Browse drop-down list in the upper-left corner of the Object Browser is used to determine the browsing scope. You can choose Active Project to view only the objects referenced in the active project, or you can choose Selected Components (the default) to view a set of selected objects. The Object Browser shows a preselected set of objects for Selected Components, but you can customize the object set by clicking the Customize button next to the Browse drop-down list. I wouldn't recommend changing the custom object set until you have some experience using C# objects and some experience using the Object Browser, as well.
The top-level nodes in the Objects tree are libraries. Libraries are usually DLL or EXE files on your computer that contain one or more objects. To view the objects within a library, simply expand the library node. As you select objects within a library, the list to the right of the Objects tree will show information regarding the members of the selected object (refer to [Figure 3.10]). For even more detailed information, click a member in the list on the right, and the Object Browser will show information about the member in the gray area below the two lists.
===Summary===
In this hour, you learned all about objects. You learned how objects have properties, which are attributes that describe the object. Some properties can be set at design time using the Properties window, and most can also be set at runtime in C# code. You learned that referencing a property on the left side of the equal sign has the effect of changing a property, whereas referencing a property on the right side of the equal sign retrieves the property's value.
In addition to properties, you learned that objects have executable functions, called methods. Like properties, methods are referenced by using a "dot" at the end of an object reference. An object may contain many methods and properties, and some properties can even be objects themselves. You learned how to "follow the dots" to interpret a lengthy object reference.
Objects are often used as a group, called a collection. You learned that a collection often contains properties and methods, and that collections let you easily iterate through a set of like objects. Finally, you learned that the Object Browser can be used to explore all the members of an object in a project.
The knowledge you've gained in this hour is fundamental to understanding programming with C#, because objects and collections are the basis on which applications are built. After you have a strong grasp of objects and collections�and you will have by the time you've completed all the hours in this book�you'll be well on your way to fully understanding the complexities of creating robust applications using C#.
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q1:'''
| Is there an easy way to get help about an object's member?
|-
| align="right" | ''' A1: '''
| Absolutely. C#'s context-sensitive Help extends to code as well as to visual objects. To get help on a member, write a code statement that includes the member (it doesn't have to be a complete statement), position the cursor within the member text, and press F1. For instance, to get help on the Count property of the controls collection, you could type this.Controls.Count, position the cursor within the word Count, and press F1.
|-
| align="right" | '''Q2:'''
| Are there any other types of object members besides properties and methods?
|-
| align="right" | ''' A2: '''
| Yes. An event is actually a member of an object, although it's not always thought of that way. Not all objects support events, however, but most objects do support properties and methods.
===Workshop===
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [Appendix A], "Answers to Quizzes/Exercises."
===Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[ 1:'''
| True or False: C# is a true object-oriented language.
|-
| align="right" | '''[ 2:'''
| An attribute that defines the state of an object is called a what?
|-
| align="right" | '''[ 3:'''
| To change the value of a property, the property must be referenced on which side of an equal sign?
|-
| align="right" | '''[ 4:'''
| What is the term for when a new object is created from a template?
|-
| align="right" | '''[ 5:'''
| An external function of an object (one that is available to code using an object) is called a what?
|-
| align="right" | '''[ 6:'''
| True or False: A property of an object can be another object.
|-
| align="right" | '''[ 7:'''
| A group of like objects is called what?
|-
| align="right" | '''[ 8:'''
| What tool is used to explore the members of an object?
Exercises
# Create a new project and add text boxes and a button to the form. Write code that, when clicked, places the text in the first text box into the second text box. Hint: Use the Text property of the text box controls.
# Modify the collections example in this hour to print the Height of all controls, rather than the name.
| align="right" | [.htm [ch04.htm
| align="right" | [03.htm#toppage Top]
= Hour 4. Understanding Events =
It's fairly easy to create an attractive interface for an application using C#'s integrated design tools. You can create beautiful forms that have buttons to click, text boxes in which to type information, picture boxes in which to view pictures, and many other creative and attractive elements with which users can interact. However, this is just the start of producing a C# program. In addition to designing an interface, you have to empower your program to perform actions in response to how a user interacts with the program and how Windows interacts with the program. This is accomplished by using events. In the previous hour, you learned about objects and their members�notably, properties and methods. In this hour, you'll learn about object events and event-driven programming, and you'll learn how to use events to make your applications responsive.
The highlights of this hour include the following:
* Understanding event-driven programming
* Triggering events
* Avoiding recursive events
* Accessing an object's events
* Working with event parameters
* Creating event handlers
* Dealing with orphaned events
----
=== Understanding Event-Driven Programming ===
With "traditional" programming languages (often referred to as procedural languages), the program itself fully dictates what code is executed and when it's executed. When you start such a program, the first line of code in the program executes, and the code continues to execute in a completely predetermined path. The execution of code may, on occasion, branch and loop, but the execution path is completely controlled by the program. This often meant that a program was rather restricted in how it could respond to the user. For instance, the program might expect text to be entered into controls on the screen in a predetermined order, unlike in Windows, where a user can interact with different parts of the interface, often in any order the user chooses.
;New term:C# incorporates an event-driven programming model. Event-driven applications aren't bound by the constraints of procedural programs. Instead of the top-down approach of procedural languages, event-driven programs have logical sections of code placed within events. There is no predetermined order in which events occur, and often the user has complete control over what code is executed in an event-driven program by interactively triggering specific events, such as by clicking a button. An event, along with the code it contains, is called an event procedure.
Triggering Events
In the previous hour, you learned how a method is simply a function of an object. Events are a special kind of method; they are a way for objects to signal state changes that may be useful to clients of that object. Events are methods that can be called in special ways�usually by the user interacting with something on a form or by Windows itself, rather than being called from a statement in your code.
There are many types of events and many ways to trigger those events. You've already seen how a user can trigger the Click event of a button by clicking it. User interaction isn't the only thing that can trigger an event, however. An event can be triggered in one of the following four ways:
* Users can trigger events by interacting with your program.
* Objects can trigger their own events, as needed.
* The operating system (whichever version of Windows the user is running) can trigger events.
* You can trigger events by calling them using C# code.
Events Triggered Through User Interaction
The most common way an event is triggered is by a user interacting with a program. Every form, and almost every control you can place on a form, has a set of events specific to its object type. For example, the Button control has a number of events, including the Click event, which you've already used in previous hours. The Click event is triggered, and then the code within the Click event executes when the user clicks the button.
The Textbox control allows users to enter information using the keyboard, and it also has a set of events. The Textbox control has some of the same types of events as the Button control, such as a Click event, but the Textbox control also has events not supported by the Button control, such as a TextChanged event. The TextChanged event occurs each time the contents of the text box change, such as when the user types information into the text box. Because you can't enter text within a Button control, it makes sense that the Button control wouldn't have a TextChanged event. Each and every object that supports events supports a unique set of events.
Each type of event has its own behavior, and it's important to understand the events with which you work. The TextChanged event, for instance, exhibits a behavior that may not be intuitive to a new developer because the event fires each time the contents of the text box change. If you were to type the following sentence into an empty text box:
<pre>C# is very cool!
</pre>
the Change event would be triggered 16 times�once for each character typed�because each time you enter a new character, the contents of the text box are changed. Although it's easy to think that the Change event fires only when you commit your entry, such as by leaving the text box or pressing Enter, this is simply not how it works. Again, it's important to learn the nuances and the exact behavior of the events you're using. If you use events without fully understanding how they work, your program may exhibit unusual, and often very undesirable, results.
;Book - Pencil:Triggering events (which are just a type of procedure) using C# code is discussed in detail in [Hour 11], "Creating and Calling Methods."
Events Triggered by an Object
Sometimes an object triggers its own events. The most common example of this is the Timer control's Timer event. The Timer control doesn't appear on a form when the program is running; it appears only when you're designing a form. The Timer control's sole purpose is to trigger its Timer event at an interval that is specified in its Interval property.
By setting the Timer control's Interval property, you control the interval, in milliseconds, when the Timer event executes. After firing its Timer event, a Timer control resets itself and again fires its Timer event when the interval has passed. This occurs until the interval is changed, the Timer control is disabled, or the Timer control's form is unloaded. A common use of timers is to create a clock on a form. You can display the time in a label and update the time at regular intervals by placing the code to display the current time in the Timer event. You'll create a project with a Timer control in [Hour 8], "Advanced Controls."
===Events Triggered by the Operating System===
Finally, Windows can trigger certain events within your program �events that you may not even know exist. For example, when a form is fully or partially obstructed by another window, the program needs to know when the offending window is resized or moved so that it can repaint the area of its window that's been hidden. Windows and C# work together in this respect. When the obstructing window is moved or resized, Windows tells C# to repaint the form, which C.htm# does. This also causes C# to raise the form's Paint event. You can place code into the Paint event to create a custom display for the form, such as drawing shapes on the form using a Graphics object. That way, every time the form repaints itself, your custom drawing code executes.
===Avoiding Recursive Events ===
;New term:You must make sure never to cause an event to endlessly trigger itself. An event that continuously triggers itself is called a recursive event. To illustrate a situation that causes a recursive event, think of the text box's TextChanged event discussed earlier. The TextChanged event fires every time the text within the text box changes. Placing code into the TextChanged event that alters the text within the text box would cause the Change event to be fired again, which could result in an endless loop. Recursive events terminate when Windows returns a StackOverFlow exception (see [Figure 4.1]), indicating that Windows no longer has the resources to follow the recursion.
Figure 4.1. Recursive events eventually exhaust Windows's resources until an exception (error) occurs.
[[Image:04fig01.gif|376px|graphics/04fig01.gof]]
;Bulb: When you receive a StackOverFlow exception, you should look for a recursive event as the culprit.
Recursive events can involve more than one event in the loop. For example, if Event A triggers Event B, which in turn triggers Event A, you can have recursion of the two events. Recursion can take place among a sequence of many events, not just one or two.
;Book - Pencil:Uses for recursive procedures actually exist, such as when you are writing complex math functions. For instance, recursive events are often used to compute factorials. However, when you purposely create a recursive event, you must ensure that the recursion isn't infinite.
Accessing an Object's Events
Accessing an object's events is simple, and if you've been following the examples in this book, you've already accessed a number of objects' default events. To access all of an object's events, you can use the Events icon (the lightning bolt) in the Properties window.
You're now going to create a project to get the feel for working with events. Start C# and create a new Windows Application project titled View Events, and then follow these steps:
# Use the toolbox to add a picture box to the form.
# Change the name of the picture box to picText.
# Click the Events button on the Properties window toolbar (the lightning bolt icon).
Your screen should look like the one in [Figure 4.2]. Notice that the Properties window now lists all the events for the selected object; in your case, it is the picText PictureBox object.
Figure 4.2. Double�click an event in the Properties window to create the desired event.
When you access a control's events, the default event for that type of control is selected. As you can see, the Click event is the default for a PictureBox. Scroll through the picText events and select the MouseDown event. Double-click the word MouseDown and C# will create the MouseDown event procedure and position you within it, ready to enter code (see [Figure 4.3]).
Figure 4.3. C# creates an empty event procedure when you select an object's event for the first time.
;New term:The code statement above the cursor is the event declaration. An event declaration is a statement that defines the structure of an event handler. Notice that this event declaration contains the name of the object, an underscore character (_), and then the event name. Following the event name is a set of parentheses. The items within the parentheses are called parameters, which is the topic of the next section. This is the standard declaration structure for an event procedure.
The full event declaration for the Click event is the following:
<pre>private void picText_MouseDown(object sender, _
System.Windows.Forms.MouseEventArgs e)
</pre>
;Book - Pencil:The words Private and Void are reserved words that indicate the scope and type of the method. Scope and type are discussed in [Hour 11].
Working with Event Parameters
;New term:As mentioned previously, the items within the parentheses of an event declaration are called parameters. An event parameter is a variable that is created and assigned a value by C#. These parameter variables are used to get, and sometimes set, relevant information within the event. Multiple parameters within an event procedure are always separated by commas. A parameter contains data that relates to the event. This data may be a number, text, an object�almost anything. As you can see, the MouseDown event has two parameters. When the Click event procedure is triggered, C# automatically creates the parameter variables and assigns them values for use in this one execution of the event procedure; the next time the event procedure occurs, the values in the parameters are reset. You use the values in the parameters to make decisions or perform operations in your code.
The MouseDown event of a form has the following parameters:
<pre>object sender
</pre>
and
<pre>System.Windows.Forms.MouseEventArgs e
</pre>
The first word identifies the type of data the parameter contains, followed by the name of the parameter. The first parameter, sender, holds a generic object. Object parameters can be any type of object supported by C#. It's not critical that you understand data types right now, just that you're aware that different parameter variables contain different types of information. Some contain text, others contain numbers, and still others (many others) contain objects. In the case of the sender parameter, it will always hold a reference to the control causing the event.
;New term:The sender parameter returns a reference to the control that causes the event. It's often best to use the sender parameter rather than referencing the control by name, so that if you change the name of the control, you won't have to update the code. Also, by referencing the sender object, the code becomes portable; you can copy and paste it into the event of a different control of the same type, and the code should work without modification.
The e parameter, on the other hand, is where the real action is with the MouseDown event. The e parameter also holds an object; in this case the object is of the type <code>System.WinForms.MouseEventArgs</code>. This object has properties that relate to the MouseDown_event. To see them, type in the following code, but don't press anything after entering the dot (period):
<pre>e.
</pre>
When you press the period, you'll get a drop-down list showing you the members (properties and methods) of the e object (see [Figure 4.4]). Using the e object, you can determine a number of things about the occurrence of the MouseDown event. I've listed some of the more interesting items in [04.htm#ch04table01 Table 4.1].
Figure 4.4. IntelliSense drop-down lists alleviate the need for memorizing the makeup of hundreds of objects.
{| cellspacing="0" cellpadding="1" border="1"|+ Table 4.1. Commonly used members of <code>System.WinForms.MouseEventArgs</code>
|-
| Property
| Description
|-
| <code>Clicks</code>
| Returns the number of times the user clicked the mouse button.
|-
| <code>Button</code>
| Returns the button that was clicked (left, middle, right).
|-
| <code>X</code>
| Returns the horizontal coordinate at which the pointer was located when the user clicked.
|-
| <code>Y</code>
| Returns the vertical coordinate at which the pointer was located when the user clicked.
;Book - Pencil:Each time the event occurs, the parameters are initialized by C# so that they always reflect the current occurrence of the event.
Each event has parameters specific to it. For instance, the <code>TextChanged</code> event returns parameters different from the <code>MouseDown</code> event. As you work with events�and you'll work with a lot of events�you'll quickly become familiar with the parameters of each event type. You'll learn how to create parameters for your own methods in [Hour 11].
===Deleting an Event Handler===
Deleting an event handler involves more than just deleting the event procedure. When you add a new event handler to a class, C# automatically creates the event procedure for you and positions you to enter code within the event. However, C# does a little bit more for you "under the covers" to hook the event procedure to the control. It does this by creating a code statement in the hidden code of the class. Ordinarily, you don't have to worry about this statement. However, when you delete an event procedure, C# doesn't automatically delete the hidden code statement, and your code won't compile. The easiest way to correct this is to run the project; when C# encounters the error, it will show you the offending statement, which you can delete. Try this now:
# Delete the MouseDown procedure (don't forget to delete the open and close brackets of the procedure, as well as any code within them). This deletes the procedure.
# Press F5 to run the project. You'll receive a message that a build error has occurred. Click No to return to the code editor.
# A task for the error has been created in the Task List. Double-click the task and C# will take you to the offending statement. It will read:
<pre>this.pictureBox1.MouseDown += new
System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
</pre>
# Delete this statement, and now your code will compile and run.
Whenever you delete an event procedure, you will have to delete the corresponding statement that links the procedure to its object before the code will run.
Building an Event Example Project
You're now going to create a very simple project in which you'll use the event procedures of a text box. Specifically, you're going to write code to display a message when a user presses a mouse button on the text box, and you'll write code to clear the text box when the user releases the button. You'll be using the e parameter to determine which button the user has pressed.
===Creating the User Interface===
Create a new Windows application titled Events Example. Change the form's Text property to Events Demo.
Next, add a text box to the form by double-clicking the TextBox tool in the toolbox. Set the properties of the text box as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>txtEvents</code>
|-
| <code>Location</code>
| <code>48</code>,<code>120</code>
|-
| <code>Size</code>
| <code>193</code>,<code>20</code>
|-
| <code>Text</code>
| <code>Click Me!</code>
|}
The only other control you need on your form is a label. Label controls are used to display static text; users cannot type text into a label. Add a new label to your form now by double-clicking the Label tool in the toolbox and then setting the Label control's properties as follows:
{| cellspacing="0" cellpadding="1" border="1"
|-
| Property
| Value
|-
| <code>Name</code>
| <code>lblMessage</code>
|-
| <code>Location</code>
| <code>48</code>,<code>152</code>
|-
| <code>Size</code>
| <code>192</code>,<code>16</code>
|-
| <code>Text</code>
| <code>(</code><code>make blank</code><code>)</code>
|-
| <code>TextAlign</code>
| <code>MiddleCenter</code>
|}
Your form should now look like the one in [Figure 4.5]. It's a good idea to save frequently, so save your project now by clicking the Save All button on the toolbar.
Figure 4.5. A Label control that has no value in its Text property can be hard to see unless selected.
===Creating Event Handlers===
The interface for the Events Example project is complete�on to the fun part. You're now going to create the event procedures that empower your program to do something. The event that we're interested in first is the <code>MouseDown</code> event. Select the TextBox on your design form, and then click the Events icon on the Properties window toolbar.
The default event for text boxes is the TextChanged event, so it's the one now selected. You're not interested in the TextChanged event at this time, however. Scroll through the event list for the MouseDown event. Double-click MouseDown; C# then creates a new MouseDown event procedure for the text box (see [Figure 4.6]).
.
Enter the following code into the MouseDown event procedure:
<pre>switch(e.Button)
{
case MouseButtons.Left:
lblMessage.Text = "You are pressing the left button!";
break;
case MouseButtons.Right:
lblMessage.Text = "You are pressing the right button!";
break;
case MouseButtons.Middle:
lblMessage.Text = "You are pressing the middle button!";
break;
}
</pre>
The Switch construct, which is discussed in detail in [Hour 14], "Making Decisions in C# Code," compares the value of an expression to a list of possible values. In this instance, the expression is the value of e.Button (the Button property of the object e). When this code executes, the expression is compared to each Case statement in the order in which the statements appear. If and when a match is found, the code immediately following the Case statement that was matched gets executed. Therefore, the code you wrote looks at the value of e.Button and compares it to three values, one at a time. When the Switch construct determines which button has been pressed, it displays a message about it in the Label control.
;Book - Pencil:In a more robust application, you would probably perform more useful and more complicated code. For instance, you may want to display a custom pop-up menu when the user clicks with the right button and execute a specific function when the user clicks with the middle button. All this is possible, and more.
The nice thing about objects is that you don't have to commit every detail about them to memory. For example, you don't need to memorize the return values for each type of button (who wants to remember MouseButtons.Left anyway?). Just remember that the e parameter contains information about the event. When you type e and press the period, the IntelliSense drop-down list appears and shows you the members of e, one of which is Button.
Don't feel overwhelmed by all the object references you'll encounter throughout this book. Simply accept that you can't memorize them all, nor do you need to; you'll learn the ones that are important, and you'll use Help when you're stuck. Also, after you know the parent object in a situation, such as the e object in this example, it's easy for you to determine the objects and members that belong to it by using the IntelliSense drop-down lists.
You're now going to add code to the MouseUp event to clear the label's Text property when the user releases the button. First, you'll need to create the MouseUp event procedure. To do this, return to the Form Design view (click the Form1.cs[Design] tab). The Properties should still have the txtEvents object's events listed. If the events aren't shown in the Properties window, select txtEvents from the drop-down list box in the Properties window and click the events icon. Locate and double-click the MouseUp event from the events list.
All you're going to do in the MouseUp_event is clear the label. Enter the following code:
<pre>lblMessage.Text = "";
</pre>===Testing Your Events Project===
Run your project now by pressing F5. If you entered all the code correctly and you don't receive any errors, your form will be displayed as shown in [Figure 4.7].
Figure 4.7. A simple but functional example.
;Book - Pencil:Remember that C# is case sensitive. Entering only one character in the wrong case will cause your project to fail to compile.
Click the text box with the left mouse button and watch the label. It will display a sentence telling you which button has been clicked. When you release the button, the text is cleared. Try this with the middle and right buttons, as well. When you click the text box with the right button, Windows displays the standard shortcut menu for text boxes. When this menu appears, you have to select something from it or click somewhere off the menu to trigger the MouseUp event. In [Hour 9], "Adding Menus and Toolbars to Forms," you'll learn how to add your own shortcut menus to forms and controls. When you're satisfied that your project is behaving as it should, from the Debug menu choose Stop Debugging to stop the project (or click the Close button on your form), and then save your work by clicking Save All on the toolbar.
===Summary===
In this hour, you learned about event-driven programming, including what events are, how to trigger events, and how to avoid recursive events. In addition, you've learned how to access an object's events and how to work with parameters. Much of the code you'll write will execute in response to an event of some kind. By understanding how events work, including being aware of the available events and their parameters, you'll be able to create complex C# programs that react to a multitude of user and system input.
===Q&A===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''Q1:'''
| Is it possible to create custom events for an object?
|-
| align="right" | ''' A1: '''
| You can create custom events for objects created from your custom classes (see [Hour 17], "Designing Objects with Classes"), but you cannot create custom events for existing C# objects such as forms and controls (without using some seriously advanced object-oriented techniques that are beyond the scope of this book).
|-
| align="right" | '''Q2:'''
| Is it possible for objects that don't have an interface to support events?
|-
| align="right" | ''' A2: '''
| Yes. However, to use the events of such an object, the object variable must be dimensioned a special way or the events aren't available. This gets a little tricky and is beyond the scope of this book. If you have an object in code that supports events, look in Help for the keyword WithEvents for information on how to use such events.
| align="right" | >
===Workshop===
The Workshop is designed to help you anticipate possible questions, review what you've learned, and get you thinking about how to put your knowledge into practice. The answers to the quiz are in [Appendix A],"Answers to Quizzes/Exercises."
===Quiz===
{| cellspacing="16" cellpadding="0" border="0"
|-
| align="right" | '''[ 1:'''
| Name three things that can cause events to occur.
|-
| align="right" | '''[ 2:'''
| True or False: All objects support the same set of events.
|-
| align="right" | '''[ 3:'''
| What is the default event type for a button?
|-
| align="right" | '''[ 4:'''
| The act of an event calling itself in a loop is called what?
|-
| align="right" | '''[ 5:'''
| What is the easiest way to access a control's default event handler?
|-
| align="right" | '''[ 6:'''
| All control events pass a reference to the control causing the event. What is the name of the parameter that holds this reference?
Exercises
# Create a project with a single text box. In the Resize event of the form, show the Width of the form in the text box.
# Create a project with a form and a text box. Add code to the TextChange event to cause a recursion when the user types in text. Hint: Concatenate a character to the end of the user's text using a statement such as <code>txtMyTextBox.Text = String. Concat(this. txtMyTextBox.Text,"a");</code>
| align="right" | [.htm [part02.htm
| align="right" | [04.htm#toppage Top]
ajs7tga2gbhyo8ze6ucev1xh0c0go18
User:Nagy
2
2325
39282
6510
2026-04-13T06:03:49Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39282
wikitext
text/x-wiki
<div style="text-align: center;"><span class="plainlinks">[[m:User:Nagy|Nagy]] ([[m:User talk:Nagy|Discussion]] • [[Special:Contributions/Nagy|Contributions]])</span></div>
3a7qmntfthkjrpy5mfdm814wntwl9zu
User:JøMa
2
2528
39264
7222
2026-04-13T06:03:41Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39264
wikitext
text/x-wiki
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<div style="text-align: center; font-size: +20;">[[[:de:w:User:JøMa|ˈjøːˌmaˑ]]]</div>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
[[de:User:JøMa]]
jkjjbo2thdiedz9xbo3cj209y0v9096
39287
39264
2026-04-13T07:26:58Z
Redmin
5511
Fixing font size messed up by my bot
39287
wikitext
text/x-wiki
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<div style="text-align: center; font-size: 50px;">[[[:de:w:User:JøMa|ˈjøːˌmaˑ]]]</div>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
[[de:User:JøMa]]
50er94rdcaei5xgzzsailnpjsrfbvph
User:Beria
2
2574
39235
7926
2026-04-13T06:03:26Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39235
wikitext
text/x-wiki
<!--- Page title --->
<div style="position:absolute; z-index:100; right:45px; top:10px;" class="metadata"><small>''[[:pt:s:A minha pátria é a língua portuguesa|'''A minha pátria é a língua portuguesa!''']]''</small></div><div style="position:absolute; z-index:100; right:10px; top:10px;" class="metadata">[[File:Flags of Brazil and Portugal.svg|30px|link=:pt:CLPC]]</div></div>
<!--- Page style background --->
{| style="width: 100%; background-color: #e2e7f7; border: 2px solid #4888aa; -moz-border-radius:15px; vertical-align: top;"
| colspan="2" style="cellpadding=8; cellspacing=8" |
<!-- Qoute section -->
|-
| style="background-color: #EFF8FF; border: 1px solid #8888aa; -moz-border-radius:15px; border-right-width:4px; border-bottom-width:4px; vertical-align: top;" colspan="2"|
{| style="margin:auto; border-collapse:collapse; border-style:none; background-color:transparent; width:100% ; {{#if: | border: 1px solid #AAAAAA;}}" class="cquote"
| width="20" valign="top" style="color:#B2B7F2;font-size:35px;font-family:'Times New Roman',serif;font-weight:bold;text-align:left;padding:10px 10px;" | “
| valign="top" style="padding:4px 10px;" | <div style="font-family:'Palatino Linotype'; font-style: italic; font-size:16px">No man is an island entire of itself; every man is a piece of the continent, a part of the main; if a clod be washed away by the sea, Europe is the less, as well as if a promontory were, as well as any manner of thy friends or of thine own were; any man's death diminishes me, because I am involved in mankind. And therefore never send to know for whom the bell tolls; it tolls for thee.
| width="20" valign="bottom" style="color:#B2B7F2;font-size:36px;font-family:'Times New Roman',serif;font-weight:bold;text-align:right;padding:10px 10px;" | ”
|-
| colspan="3" style="padding-right: 4%" | <p style="font-size:smaller;text-align: right"><cite style="font-style:normal;">—[[:en:John Donne|John Donne]] in [[:s:Meditation_VII|''Meditation VII'']].</cite></p>
|}
<!-- Description section -->
|-
| style="width: 78%; background-color: #EFF8FF; border: 1px solid #8888aa; -moz-border-radius:15px; -moz-border-radius:15px; border-right-width:4px; border-bottom-width:4px; vertical-align: top;" rowspan="2"|
<div style="text-align:" justify;">
'''Name:''' <span style="color: #6495ED; font-size: 18pt; font-family: Edwardian Script ITC;"> Béria Lima </span> (Nickname: <span style="font-size: 18pt; font-family: Edwardian Script ITC;">Beh</span>)
'''In Wikimedia Projects since:''' ''5 October, 2007'' (''{{#if:|{{ontem hoje amanhã|{{#expr: + {{#expr:
<!--Days from all years past:-->
+ (({{CURRENTYEAR}} - 1) * 365)
+ ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 4)) / 4) <!--add a day for every leap-->
- ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 100)) / 100) <!--subtract 100 year exception-->
+ ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 400)) / 400) <!--readd 400 year exception-->
<!--Days so far this year:-->
+ {{ #ifexpr: <!--add days for past months this year--> <!--Gives 1 or 2 extra days because of February-->
({{CURRENTMONTH}} - 1) < 8
| ( ({{CURRENTMONTH}} - 1) * 30.5 round 0)
| ( ({{CURRENTMONTH}} - 1) * 30.5 + 0.9 round 0 )
}}
- {{ #ifexpr: ({{CURRENTMONTH}} <= 2) | 0 |
{{ #ifexpr: <!-- if leap year -->
({{CURRENTYEAR}} / 4) = ({{CURRENTYEAR}} / 4 round 0) <!--If divisible by 4-->
and ({{CURRENTYEAR}} / 100 != {{CURRENTYEAR}} / 100 round 0) <!--and not by 100-->
| 1 | 2
}}
}}
+ {{ #ifexpr: ({{CURRENTMONTH}} <= 2) | 0 |
{{ #ifexpr: <!--400 year exception-->
({{CURRENTYEAR}} / 400) = ({{CURRENTYEAR}} / 400 round 0)
| 1 | 0
}}
}}
+ {{CURRENTDAY}}
}}{{#ifexpr: {{CURRENTYEAR}} < 1 |
_ERROR - Can not handle dates before January 1, 1 A.D.
}} - {{#expr:
<!--Days from all years past:-->
+ ((2007 - 1) * 365)
+ (((2007 - 1) - ((2007 - 1) mod 4)) / 4) <!--add a day for every leap-->
- (((2007 - 1) - ((2007 - 1) mod 100)) / 100) <!--subtract 100 year exception-->
+ (((2007 - 1) - ((2007 - 1) mod 400)) / 400) <!--readd 400 year exception-->
<!--Days so far this year:-->
+ {{ #ifexpr: <!--add days for past months this year--> <!--Gives 1 or 2 extra days because of February-->
(10 - 1) < 8
| ( (10 - 1) * 30.5 round 0)
| ( (10 - 1) * 30.5 + 0.9 round 0 )
}}
- {{ #ifexpr: (10 <= 2) | 0 |
{{ #ifexpr: <!-- if leap year -->
(2007 / 4) = (2007 / 4 round 0) <!--If divisible by 4-->
and (2007 / 100 != 2007 / 100 round 0) <!--and not by 100-->
| 1 | 2
}}
}}
+ {{ #ifexpr: (10 <= 2) | 0 |
{{ #ifexpr: <!--400 year exception-->
(2007 / 400) = (2007 / 400 round 0)
| 1 | 0
}}
}}
+ 8
}}{{#ifexpr: 2007 < 1 |
_ERROR - Can not handle dates before January 1, 1 A.D.
}} }} }}|{{#expr:+ {{#expr:
<!--Days from all years past:-->
+ (({{CURRENTYEAR}} - 1) * 365)
+ ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 4)) / 4) <!--add a day for every leap-->
- ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 100)) / 100) <!--subtract 100 year exception-->
+ ((({{CURRENTYEAR}} - 1) - (({{CURRENTYEAR}} - 1) mod 400)) / 400) <!--readd 400 year exception-->
<!--Days so far this year:-->
+ {{ #ifexpr: <!--add days for past months this year--> <!--Gives 1 or 2 extra days because of February-->
({{CURRENTMONTH}} - 1) < 8
| ( ({{CURRENTMONTH}} - 1) * 30.5 round 0)
| ( ({{CURRENTMONTH}} - 1) * 30.5 + 0.9 round 0 )
}}
- {{ #ifexpr: ({{CURRENTMONTH}} <= 2) | 0 |
{{ #ifexpr: <!-- if leap year -->
({{CURRENTYEAR}} / 4) = ({{CURRENTYEAR}} / 4 round 0) <!--If divisible by 4-->
and ({{CURRENTYEAR}} / 100 != {{CURRENTYEAR}} / 100 round 0) <!--and not by 100-->
| 1 | 2
}}
}}
+ {{ #ifexpr: ({{CURRENTMONTH}} <= 2) | 0 |
{{ #ifexpr: <!--400 year exception-->
({{CURRENTYEAR}} / 400) = ({{CURRENTYEAR}} / 400 round 0)
| 1 | 0
}}
}}
+ {{CURRENTDAY}}
}}{{#ifexpr: {{CURRENTYEAR}} < 1 |
_ERROR - Can not handle dates before January 1, 1 A.D.
}} - {{#expr:
<!--Days from all years past:-->
+ ((2007 - 1) * 365)
+ (((2007 - 1) - ((2007 - 1) mod 4)) / 4) <!--add a day for every leap-->
- (((2007 - 1) - ((2007 - 1) mod 100)) / 100) <!--subtract 100 year exception-->
+ (((2007 - 1) - ((2007 - 1) mod 400)) / 400) <!--readd 400 year exception-->
<!--Days so far this year:-->
+ {{ #ifexpr: <!--add days for past months this year--> <!--Gives 1 or 2 extra days because of February-->
(10 - 1) < 8
| ( (10 - 1) * 30.5 round 0)
| ( (10 - 1) * 30.5 + 0.9 round 0 )
}}
- {{ #ifexpr: (10 <= 2) | 0 |
{{ #ifexpr: <!-- if leap year -->
(2007 / 4) = (2007 / 4 round 0) <!--If divisible by 4-->
and (2007 / 100 != 2007 / 100 round 0) <!--and not by 100-->
| 1 | 2
}}
}}
+ {{ #ifexpr: (10 <= 2) | 0 |
{{ #ifexpr: <!--400 year exception-->
(2007 / 400) = (2007 / 400 round 0)
| 1 | 0
}}
}}
+ 5
}}{{#ifexpr: 2007 < 1 |
_ERROR - Can not handle dates before January 1, 1 A.D.
}} }} }}'' days)
__NOTOC__
== My home(s) ==
[[File:Ponte D. Luís, Sé e Jardim do Morro vistos de Gaia.JPG|center|thumb|450px|[[:pt:Sé do Porto|Porto Cathedral]], [[:pt:Ponte Dom Luís I|Dom Luis I bridge]] and [[:pt:Serra do Pilar|Serra do Pilar Monastery]], 3 postcards of [[:en:Oporto|my town]].]]
[[File:Recife 2005 JAN 25 AncientAndModernCenter.jpg|center|thumb|450px|The new and the [[:en:Recife Antigo|old Recife]].]]
== Quotes ==
{| style="margin:auto; border-collapse:collapse; border-style:none; background-color:transparent; width:{{#if: | 100% | auto}}; {{#if: | border: 1px solid #AAAAAA;}}" class="cquote"
| width="20" valign="top" style="color:#B2B7F2;font-size:35px;font-family:'Times New Roman',serif;font-weight:bold;text-align:left;padding:10px 10px;" | “
| valign="top" style="padding:4px 10px;" | <div style="font-family:'Palatino Linotype'; font-style: italic; font-size:16px">La pensée est le labeur de l’intelligence, la rêverie en est la volupté.
| width="20" valign="bottom" style="color:#B2B7F2;font-size:36px;font-family:'Times New Roman',serif;font-weight:bold;text-align:right;padding:10px 10px;" | ”
|-
| colspan="3" style="padding-right: 4%" |<p style="font-size:smaller;text-align: right"><cite style="font-style:normal;">—[[:fr:Victor Hugo|Victor Hugo]] in [[:fr:Les Miserables|''Les Miserables'']].</cite></p>
|}
{| style="margin:auto; border-collapse:collapse; border-style:none; background-color:transparent; width:{{#if: | 100% | auto}}; {{#if: | border: 1px solid #AAAAAA;}}" class="cquote"
| width="20" valign="top" style="color:#B2B7F2;font-size:35px;font-family:'Times New Roman',serif;font-weight:bold;text-align:left;padding:10px 10px;" | “
| valign="top" style="padding:4px 10px;" | <div style="font-family:'Palatino Linotype'; font-style: italic; font-size:16px">There is in fact a heroism of virtue in the pride of this woman, who resists every seduction, the impulses of his own passion as well as the rapture of the senses</div>
| width="20" valign="bottom" style="color:#B2B7F2;font-size:36px;font-family:'Times New Roman',serif;font-weight:bold;text-align:right;padding:10px 10px;" | ”
|-
|colspan="3" style="padding-right: 4%" | <p style="font-size:smaller;text-align: right"><cite style="font-style:normal;">—[[:w:José de Alencar|José de Alencar]], in [[:s:pt:Senhora|''Senhora'']].</cite></p>
|}
{| style="margin:auto; border-collapse:collapse; border-style:none; background-color:transparent; width:{{#if: | 100% | auto}}; {{#if: | border: 1px solid #AAAAAA;}}" class="cquote"
| width="20" valign="top" style="color:#B2B7F2;font-size:35px;font-family:'Times New Roman',serif;font-weight:bold;text-align:left;padding:10px 10px;" | “
| valign="top" style="padding:4px 10px;" | <div style="font-family:'Palatino Linotype'; font-style: italic; font-size:16px">Der Irrtum ist viel leichter zu erkennen, als die Wahrheit zu finden; jener liegt auf der Oberfläche, damit läßt sich wohl fertig werden; diese ruht in der Tiefe, danach zu forschen ist nicht jedermanns Sache.
| width="20" valign="bottom" style="color:#B2B7F2;font-size:36px;font-family:'Times New Roman',serif;font-weight:bold;text-align:right;padding:10px 10px;" | ”
|-
| colspan="3" style="padding-right: 4%" |<p style="font-size:smaller;text-align: right"><cite style="font-style:normal;">—[[:de:Johann Wolfgang von Goethe|Johann Wolfgang von Goethe]] in [[:de:Maximen und Reflexionen|''Maximen und Reflexionen'']].</cite></p>
|}
== Other accounts ==
* [[:pt:User:Lucia Bot|Lucia Bot]]
* [[User:Ripchip Bot|Ripchip Bot]]
== [[:commons:Category:Images sent by Béria Lima|My pictures]] ==
<div style="width: 100%; -moz-column-count: 2;">
; Pictures taken by me
* [[:commons:Category:Files from Brazil by Béria Lima|Files from Brazil]]
* [[:commons:Category:Files from Portugal by Béria Lima|Files from Portugal]]
:* [[:commons:Category:Files from Aveiro by Béria Lima|Files from Aveiro]]
:* [[:commons:Category:Files from Braga by Béria Lima|Files from Braga]]
:* [[:commons:Category:Files from Lisboa by Béria Lima|Files from Lisbon]]
:* [[:commons:Category:Files from Porto by Béria Lima|Files from Oporto]]
:* [[:commons:Category:Files from Sintra by Béria Lima|Files from Sintra ]]
* [[:commons:Category:Files from Spain by Béria Lima|Files from Spain]]
; Files uploaded by me
* [[:commons:Category:Files from Flickr uploaded by Béria Lima|Files from Flickr]]
:* [[:commons:Category:Files of Lisboa uploaded by Béria Lima|Files of Lisbon from Flickr]]
:* [[:commons:Category:Files of Porto uploaded by Béria Lima|Files of Oporto from Flickr]]
* [[:commons:Category:Files from Wikimedia projects uploaded by Béria Lima|Files from Wikimedia projects]]
; Pictures of me
* [[:commons:Category:Béria Lima|Béria Lima]] (the category)
</div>
== Other Wikimedia projects ==
<!--- Projetos Correlatos! rsrs ----------->
<div style="clear:both;"></div>
<div style="text-align: center;">
{| class="toccolours"
| style="background:#d3d3d3;color:#a52a2a text-align:center;width:100%;" colspan="14" | <big style="font-size:110%;">'''My [[:en:WP:UP|User pages]] in other wiki projects'''</div></big>
|-
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikipedia-logo-pt.png|60px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikipedia-logo-en.png|60px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Commons-logo.svg|50px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikiquote-logo.png|50px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikinews-logo.svg|50px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikisource-logo.svg|50px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[image:Wikibooks-logo.png|60px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[Image:Wiktionary-logo-pt.png|60px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[Image:Wikiversity-logo.svg|60px]]</div>
| valign="middle" bgcolor="ffffff" | <div style="text-align: center;">[[Image:Test wiki logo.png|60px]]</div>
|-
<!-- Páginas de Usuário -->
| valign="middle" bgcolor="d3d3d3" | <div style="text-align: center;">'''[[:w:pt:User:Beria|((pt)) Wikipedia]]'''
| valign="middle" bgcolor="d3d3d3" | [[:en:User:Beria|((en)) Wikipedia]]
| valign="middle" bgcolor="d3d3d3" | [[commons:User:Beria|Commons]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:q:Usuário:Beria|Wikiquote]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:n:Usuário:Beria|Wikinews]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:s:Usuário:Beria|Wikisource]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:b:Usuário:Beria|Wikibooks]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:wikt:Usuário:Beria|Wikcionário]]
| valign="middle" bgcolor="d3d3d3" | [[:pt:v:Usuário:Beria|Wikiversidade]]
| valign="middle" bgcolor="d3d3d3" | <span class="plainlinks">[http://test.wikipedia.org/wiki/User:Beria Test Wiki]
|-
|}
<!--- Fim dos Projetos Correlatos! rsrs ----------->
<br style="clear:both" />
</div><!--
END OF MAIN BOX
START OF TOP RIGHT-FLOAT BOX (portrait)-->
<!-- Image section -->
| style="width: 20%; background-color: #EFF8FF; border: 1px solid #8888aa; -moz-border-radius:15px; border-right-width:4px; border-bottom-width:4px; vertical-align: top;" rowspan="1"|
[[Image:Spleen et ideal.jpg|220px|center|thumb|'''Spleen et Ideal'''<br /><p style="font-size:smaller;text-align: right">by Carlos Schwabe</p>]]
<!-- Userboxes section -->
|-
| style="width: 20%; background-color: #EFF8FF; border: 1px solid #8888aa; -moz-border-radius:15px; border-right-width:4px; border-bottom-width:4px; vertical-align: top; text-align: center; height: 10px;" rowspan="2"|
{|
[[Image:Crystal Clear app package.png|35px]] <big>'''Userboxes'''</big>
<!--- Babel -->
{{#babel:pt-N|en-3|es-2|ca-2|gl-2|mwl-2|fr-1|it-1|an-1|oc-1}}
<!-- Other userboxes -->
<!-- Meta Adm box -->
<div style="float:center; border:1px solid #999; margin:1px; width:238px">
{| cellspacing="0" style="width:238px; background:#EEE;"
| style="width:45px; height:45px; background:#DDD; text-align:center; font-size:14pt; color:black;" | '''[[File:Wikimedia Community Logo.svg|40 px]]'''
| style="font-size:8pt; padding:4pt; line-height:1.25em; color:#000;" | This user is an [[Meta:Administrators|administrator]] on Meta-Wiki. <small>(<span class="plainlinks">[{{fullurl:Special:Listusers|limit=1&username={{PAGENAMEE}} verify}}]</span>)</small>
|}</div>
<!-- Commons Adm box -->
<div style="float:center; border:1px solid #999; margin:1px; width:238px">
{| cellspacing="0" style="width:238px; background:#EEE;"
| style="width:45px; height:45px; background:#DDD; text-align:center; font-size:14pt; color:black;" | '''[[File:Commons-logo.svg|40 px]]'''
| style="font-size:8pt; padding:4pt; line-height:1.25em; color:#000;" | This user is an [[:commons:Commons:Administrators|administrator]] on Commons. <small>(<span class="plainlinks">[{{fullurl:commons:Special:Listusers|limit=1&username={{PAGENAMEE}} verify}}]</span>)</small>
|}</div>
<!-- Strategy Adm box -->
<div style="float:center; border:1px solid #999; margin:1px; width:238px">
{| cellspacing="0" style="width:238px; background:#EEE;"
| style="width:45px; height:45px; background:#DDD; text-align:center; font-size:14pt; color:black;" | '''[[File:Wikimedia Community Logo.svg|40 px]]'''
| style="font-size:8pt; padding:4pt; line-height:1.25em; color:#000;" | This user is an [[:strategy:Commons:Administrators|administrator]] on Strategy-Wiki. <small>(<span class="plainlinks">[{{fullurl:strategy:Special:Listusers|limit=1&username={{PAGENAMEE}} verify}}]</span>)</small>
|}</div>
<!-- Wikimedia Portugal -->
<div class="TemplateBUser" style="float:center; margin:1px; width:238px; border:1px solid #006300;">
{| border="0" cellspacing="0" cellpadding="1" style="background-color:#ffffff; color:#000000; width:100%;"
|-
|class="TemplateBUserLeft" style="width:45px; height:45px; background-color:#FFFFFF; color:#000000; text-align:center; vertical-align:middle;"|
[[Image:Wikimedia Portugal logo 135px.png|45px|Wikimedia Portugal logo 135px.png]]
|class="TemplateBUserInfo" style="padding:1px 4px; vertical-align:middle;"|
<div class="plainlinks TemplateBUserText" style="font-size:0.83em; direction:ltr; line-height:1.25;">Este utilizador é membro da [http://www.wikimedia.pt/ Wikimedia Portugal].</div>
|}</div>
<!-- Wikimedia Argentina -->
<div class="TemplateBUser" style="float:center; margin:1px; width:238px; border:1px solid #006300;">
{| border="0" cellspacing="0" cellpadding="1" style="background-color:#ffffff; color:#000000; width:100%;"
|-
|class="TemplateBUserLeft" style="width:45px; height:45px; background-color:#FFFFFF; color:#000000; text-align:center; vertical-align:middle;"|
[[File:Wikimedia Argentina logo.svg|45px|Wikimedia Argentina logo.svg]]
|class="TemplateBUserInfo" style="padding:1px 4px; vertical-align:middle;"|
<div class="plainlinks TemplateBUserText" style="font-size:0.83em; direction:ltr; line-height:1.25;">This user is member of [http://www.wikimedia.org.ar/ Wikimedia Argentina].</div>
|}</div>
<!-- IRC user -->
<div style="float: center; width: 238px; border: solid #1E90FF 1px; margin: 1px;">
{| cellspacing="0" style="width: 238px; color:#000000; background: #000000;"
| style="width: 45px; height: 45px; background: #77aaff; text-align: center; font-size:14pt; color:#FFCC11" |[[Image:Crystal kdmconfig.png|36px]]
| style="font-size: 8pt; padding: 4pt; line-height: 1.25em; background:#bbddff" | This user's [[IRC]] nick is '''Beria''' on the server '''[[:en:Freenode|Freenode]]'''.
|}</div><noinclude>
<!-- Time zone -->
<div style="float:center; border:1px solid #ccc; margin:1px;width:248px " class="wikipediauserbox ">
{| cellspacing="0" style="width:238px; background:#fff;"
| style="width:45px; height:45px; background:#ccc; text-align:center; font-size:12pt; color:black; padding:0 1px 0 0; line-height:1.25em; vertical-align: middle; " | [[Image:Nuvola apps kworldclock.png|43px|link=:en:Template:User time zone]]
| style="text-align:left; font-size:8pt; padding:0 4px 0 4px; height:45px; line-height:1.25em; color:black; vertical-align: middle; " | This user's time zone is '''[[:en:UTC-3|UTC-3]]'''.
|}</div>
<!-- Brazil <3 Portugal -->
<div style="float: center; border:solid #800 1px; margin: 1px;width:248px ">
{| cellspacing="0" style="width: 240px; background: #080;"
| style="width: 45px; height: 45px; background: #EEE; text-align: center; font-size: 12pt; color: #000;" | '''[[Image:Bandeira pt.gif|40px]]'''
| style="font-size: 8pt; padding: 4pt; line-height: 1.25em; color: #fff;" | This brazilian user loves '''[[Portugal|<span style="color:white">Portugal</span>]]'''.
| style="width: 45px; height: 45px; background: #EEE; text-align: center; font-size: 12pt; color: #000;" | '''[[Image:Flags of Brazil and Portugal.svg|50px]]'''
|}</div><div style="clear:both;"></div>
|}
|}</div>
9700os0b52emrkne0ifz8qdk1wz529o
User:Cekli829
2
2596
39236
9045
2026-04-13T06:03:26Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39236
wikitext
text/x-wiki
{{DISPLAYTITLE:<span style="font-family: 'Raceway'"><span style="display:none;">User:</span>Cekli</font><span style="color: blue;">8</span><span style="color: red;">2</span><span style="color: green;">9</span></span>}}
{| cellpadding="10" cellspacing="8" style="width: 100%; background-color: black; border: 5px solid gray; vertical-align: top; -moz-border-radius-topleft: 8px; -moz-border-radius-bottomleft: 8px; -moz-border-radius-topright: 8px; -moz-border-radius-bottomright: 8px;"
| colspan="2" style="padding: 0;" |
<span style="color: #ffeecc;">Təkliflərinizi <B>cekli829@gmail.com</B> ünvanına göndərə bilərsiniz.</span>
:<span style="color: #ffeecc;">Digər əlaqə vasitələri:</span>
:'''[https://www.facebook.com/tarkhan.pashazade Facebook (profile)]'''
:'''[https://www.facebook.com/pages/T%C9%99rxan-Pa%C5%9Fazad%C9%99/529113383837101?ref=hl Facebook (page)]'''
:'''[https://twitter.com/Cekli829 Twitter]'''
:'''[http://www.youtube.com/user/Cekli829/videos YouTube]'''
[[az:İstifadəçi:Cekli829]]
t48ec7u944wh95accf7aq4mt92caigc
User:Jagwar
2
2719
39263
7666
2026-04-13T06:03:41Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39263
wikitext
text/x-wiki
<div style="text-align: center;">
[[m:mg:|Home wiki]]
[[m:mg:User talk:Jagwar|Hametraka hafatra - Let a message - laisser un Message]]
</div>
Ny solonanarako manerana ny tetikasa Wikimedia dia Jagwar. Ao amin'ny tetikasa Wikimedia amin'ny teny malagasy no tena iasako. Raha manana hataka manokana ho ahy ianareo dia mametraha hafatra amin'ny alalan'ny fanindriana ny rohy eo ambony.
----
My nickname on all Wikimedia projects is Jagwar. I mainly work on Wikimedia projects in the Malagasy language. If you have a question or comment, leave a message on my talk page by following the link above.
----
Mon pseudonyme sur tous les projets Wikimedia est Jagwar. Je travaille principalement sur les projets malgachophones de Wikimedia. Si vous avez une quelconque demande à me faire, suivez le lien donné ci-dessus.
{{#babel: mg-N|fr-4|en-3|es-3|eo-2}}
7u9exat06hqeysjm5ibhgkegkot7qyx
User:Mwpnl
2
2743
39281
7869
2026-04-13T06:03:49Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39281
wikitext
text/x-wiki
For more information about me or to get in touch, please visit my [[m:User:Mwpnl|User page]] and [[m:User talk:Mwpnl|talk page]] on meta-wiki.
Thanks, [[m:User:Mwpnl|<span style="color: #2B88FE;">nl:'''Mark W'''</span>]] <small>(Mwpnl) ¦ [[m:User talk:Mwpnl|<span style="color: #66AA33;">talk</span>]]</small>
3scz47dtvg1yojpghsq85y3h2b1c92m
User:Mathonius
2
2748
39265
8136
2026-04-13T06:03:42Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39265
wikitext
text/x-wiki
{{#babel:nl|en-3|fr-1|de-1|so-0}}
<div style="text-align: center;">''Hello, I'm a member of the [[:m:SWMT|Small Wiki Monitoring Team]]. Feel free to leave me a message on [[:User talk:Mathonius|my talk page]].''<br />[[:m:User:Mathonius|(click here for my user page on meta.wikimedia)]]</div>
----
and4qmuel6h923wquy8q5i887u9wqsh
User:Frigotoni
2
2786
39262
8035
2026-04-13T06:03:40Z
DelintBot
5512
Replacing [[mw:Help:Lint errors/obsolete-tag|obsolete tags]]
39262
wikitext
text/x-wiki
<div style="text-align: center;">Hello, I am <span style="font-family:Bradley Hand ITC; color:black">'''Frigotoni'''</span>[[User talk:Frigotoni|<small> ...<span style="font-family:Segoe Script; color:navy" >'''i'm here'''</span></small>]]. I'm a member of the [[m:Small Wiki Monitoring Team|Small Wiki Monitoring Team]] and globally active in countervandalism. Feel free to leave me a message on [[m:User talk:Frigotoni|meta]] or on my [[m:it:Discussioni utente:Frigotoni|home]] Wiki. [[File:Face-grin.svg]]<small><br /><span class="plainlinks">[//toolserver.org/~pathoschild/crossactivity/?user=Frigotoni Crossactivity] & [//toolserver.org/~pathoschild/stalktoy/?target=Frigotoni StalkToy]</span> • If you need further information, you can click [[m:User:Frigotoni|here]]. Have I done something wrong? I apologise for this. Report it to me please.</small></div>
tbiw3p0yieb8rdokc4179ny5jcel5tp
garaad gacmeed
0
12679
39210
2026-04-12T19:43:19Z
~2026-22619-54
5525
artificial intelligence
39210
wikitext
text/x-wiki
{{-so-}}
== Magac ==
'''garaad gacmeed'''
=== Tarjumaad ===
* {{en}}: artificial intelligence
9i8n6tdxh553qf2l8pdhyv2sl5dk927