Welcome back! This second of the three workshops will hopefully teach you some more HTML skills, teach you some new tricks for some old tags, and introduce you to the wonders of web standards and good site design.
Back to main workshop page
When the Web first started really becoming popular, it was generally a mess. Different browsers made up their own rules and created their own tags. As you can imagine, this made web design hard for the poor people creating web pages, especially those of us doing it for fun or minimal profit. Equally bad, a lot of web designers wrote really poor HTML leading to all kinds of troubles ranging from long downloads to poor portability to other platforms (or alternate clients) to simple breakdowns from complexity. And so it was that the masses did cry out for some sort of salvation from the chaos.
A lo!, they were heard and the World Wide Web Consortium (W3C) was born. Well, it wasn't quite to the point of the masses wailing and gnashing their teeth, but something needed to be done. The W3C is charged with creating a set of standards for the Web so that all browsers can use the same set of language elements and everyone has an easier time of it. At this point, all major browsers have agreed to accept the W3C's standards, although in some cases support is spotty. (Generally, with recent browsers, you're safe.) Also, many browsers still support poor Web practices, although this is being phased out.
You can view the standards at the W3C's website. Currently,
HTML is up to
version 4.01. There are three flavors of this release, by the
way: transitional (you don't have to follow every rule to a T, but
you do generally behave yourself), strict (you do follow every
rule to a T), and frameset (for frames, see frames, below). Part of following the
standards means not using deprecated tags such as
<center> and <font>.
Another important part of following standards is following the document model. This includes structuring your HTML documents into separate head and body elements and starting your documents with the Document Type Definition (DTD) – the line that tells the client what kind of document to expect to be parsing. The latter is the first line that I instructed you to place in your HTML documents in the previous workshop. (Many editors, including emacs, will do this for you, by the way. However, check the type that it guesses, as it might not be correct!)
Another part of following the standards is use the closing tags
whenever they are available. While there are tags that don't have
closing elements (<br> and
<hr> are examples), there are also several tags
whose closing elements are often neglected. In these cases,
browsers are generally willing to parse the code, but don't count
on it. Probably the best example of this is the
<p> tag. My recollection is that initially it
didn't have a closing tag. Certainly, you seldom saw a
</p>. Since this was the case, many browsers
have long been forgiving about lone <p> tags
and treated them as paragraph breaks rather than as enclosing
paragraphs. However, this is no longer considered valid HTML and should not be
attempted. (It is also worth noting that browser behavior when
the </p> tag is omitted can be erratic and the
results can be undesirable. Because the
Back to top of page.
I deferred this topic from the introductory session with a certain amount of regret. The choice was made simply to avoid overwhelming you on the first day. However, lists are important and very useful tools. They are also relatively easy to use, so expect to do a lot with these guys.
A list is just a series of items arranged in a manner befitting this identity. There are three basic types of lists: the ordered, the unordered, and the definition. The first two are are simply a list of items either with some sort of ordering or a series of bullets. The latter is a series of terms and their definitions (structurally, anyway – you can use the same format for other similar needs). All lists have a certain structure in that there is an over start and stop tag for the list and a series of tags nested inside of these to indicate the items. Unlike tags we've seen previously, you must use multiple tags to make a list work.
Back to top of page.
An ordered list is delimited by <ol> (for
"ordered list,' of course) and </ol>.
Everything wrapped up within these tags should be part of the
ordered list. Each item within the list is delimited by a
<li> (think "list item") and a
</li> tag. Each of these pairs forms a
separate item with its own numeric (or alphabetical, but that
comes later) bullet. The bullets are auto-incremented by the
browser when it displays the list. (Woo-hoo!) It is worth
mentioning that the </li> tag is often omitted,
like the </p> tag. However, this is poor
HTML and should be avoided if only to be
standards compliant and explicit about what you mean.
An example of an ordered list:
<ol>
<li>Mercury</li>
<li>Venus</li>
<li>Earth</li>
<li>Mars</li>
<li>Jupiter</li>
<li>Saturn</li>
<li>Uranus</li>
<li>Neptune</li>
</ol>
This renders as:
Snazzy and pretty easy, too.
Back to top of page.
Think you have the hang of ordered lists, do you? Great, then
unordered lists will be a cake-walk. The only difference is that
the starting and closing tags are <ul> and
</ul>. Items are delimited in the same way.
The difference is that the browser doesn't put ordered bullets,
just simple bullets, beside the items. For example:
<ul>
<li>Mercury</li>
<li>Venus</li>
<li>Earth</li>
<li>Mars</li>
<li>Jupiter</li>
<li>Saturn</li>
<li>Uranus</li>
<li>Neptune</li>
</ul>
This renders as:
Back to top of page.
These lists are a bit different, although the basic principle
is the same. You delimit the overall list by the
<dl> tags (starting and stopping, of course).
Inside, you need two sets of tags: <dt> and
<dd>. These are used alternately, the former
designating a definition term and the latter the definition
definition. So you place the term in the <dt>
tags and then the definition in the <dd> tags.
Of course, you don't have to be used words plus definitions. You
could use this system for an annotated bibliography, a who's-who
listing, or anything else where you want to set the item name off
and then somehow describe it for the reader.
A functional example of the definition list is
<dl>
<dt>Pericenter</dt>
<dd>Position or time of closest approach between bodies in the
two-problem. Often used to denote the distance between the
bodies at this time, equal to (1-e) a.</dd>
<dt>Apocenter</dt>
<dd>Position or time of greatest separation between bodies in
the two-body problem. Often used to denote the distance between
the bodies at this time, equal to (1+e) a.</dd>
</dl>
This renders as:
Back to top of page.
A few final points. First of all, you can nest lists so that list items contain lists themselves. (Unordered lists as part of items in an unordered list, say. Or ordered lists as part of a definition – say a listing of Kepler's three laws in an entry for "Kepler.") As you nest unordered lists, the browser will choose how to display the bullets, usually altering them with each nested level. (In many browsers, they go from filled circles to open circles to filled squares.) Ordered lists stick with Roman numerals (by default), but do restart the numbering within each new list. Browsers also indent nested lists farther than the containing list so that the new lists is visually separated. However, if you nest too deeply, this can get out of hand as the list items will start appearing off the right side of the page! You can suggest other behaviors for all of these defaults with style sheets. But rest easy knowing the the default is usually pretty easy to understand. (For an example of nested lists, check out the top of this page.)
Never leave text and material inside a list but outside a list item. You have no idea what a browser will do with it and it could be very undesirable.
Back to top of page.
Tables are another heavily used element of HTML. They are terrifically useful for a variety of uses, but be warned: they can be over used and abused, especially for controlling page layout. Tables can also get very complex and difficult to read, so be careful and keep your style as clear as you can.
Personal feelings time: I see tables as useful for tabular data (duh), arranging things like photo albums, forms, and other simple layout needs. Using them to arrange the entire page, or even large fractions of it, is generally excessively complex and probably requires too many assumptions about the user's browser. Also, with the proliferation of tables to control layout, page sources have grown more difficult to read, edit, and to parse. The latter point applies particularly to alternate clients that aren't going to use the visual layout information, but need to be able to determine the important contents to the table. So my view on this is that tables are perfectly suited for tabular information (duh) and for some light use for page layout. (For example, arranging images in your online photo album or the biographies of the APS students and faculty.) As you learn more HTML and CSS, you'll find that there are lots of ways to handle most other situations and that these ways are easier, more flexible, and often make things look that much better anyway.
A table is delimited with <table> and
</table> tags. Everything inside of this must
be part of the table. Tables in HTML are row-oriented. That is, the language
is written so that you create the entries row-by-row with little
consideration about the existence of columns. (There has been
some progress made on this front recently, but the language still
reflects the row-oriented style.) Rows are delimited with
<tr> ("table row") tags. Within the row
delimiters you mainly find <td> ("table data")
tags that contain the actual cell data.
For example,
<table>
<tr>
<td>Planet</td>
<td>Distance from Sun (AU)</td>
</tr>
<tr>
<td>Mercury</td>
<td>0.4</td>
</tr>
<tr>
<td>Venus</td>
<td>0.7</td>
</tr>
<tr>
<td>Earth</td>
<td>1.0</td>
</tr>
<tr>
<td>Mars</td>
<td>1.5</td>
</tr>
</table>
Yields a table that looks like this.
| Planet | Distance from Sun (AU) |
| Mercury | 0.4 |
| Venus | 0.7 |
| Earth | 1.0 |
| Mars | 1.5 |
Back to top of page.
Well, that example table looks swell and all, but it's sort of dull-looking, isn't it? Here are some ways to liven it up.
Back to top of page.
HTML
includes another kind of table element tag,
<th>. Read this as "table header," and it
works just like a <td> tag. The difference is
that you use it in the header row. Most browsers will do
something nice like bold the contents and probably center them,
too. Next session, we'll also see that you can use style sheets
to do even more to those elements, but for now just setting them
apart a little bit is a big improvement.
Back to top of page.
You probably don't seen any kind of borders around the table or
the cells above. The <table> tag has a
border attribute. The border is set to an integer,
where 0 is (usually) the default. The integer tells the browser
how thick to make the border. So border="1" makes a
simple, thin little border around the table and the cells inside
it. (Do note, however, that the borders may not appear if the
cell is empty. There are ways to handle this, though. Style
sheets gives a robust way of doing it, but the kludge is to put
in the empty cell. This is the character
entity for a "non-breaking space" and this makes most browsers
think that there is something inside the cell, even if the viewer
doesn't see anything.) Setting border="2" makes a
thicker, somewhat more 3-D looking border. Setting
border="0" makes the border disappear.
Back to top of page.
It is also really handy to be able to control the size of the
table. There two attributes here, width and
height. The both take one of two kinds of numbers, a
value in pixels or a percent. To set the value in pixels, just
use an integer as in width="500". To set the value
in percent, you'll need the percent sign,
width="85%". The pixels version is pretty easy to
understand. The percent version tells the browser to set the
table to a certain percent of the width or height of the window.
By default the table should make itself large enough to hold the
content. If you think that the table looks better or is more
readable with more space of kept somewhat smaller than it wants to
be, then these are useful options.
As an aside, while I find myself using the width
attribute quite often, I don't believe that I have ever seen a
need for the height attribute in my own web
development work. This has something to do with how I use
tables, however.
Back to top of page.
Sometimes you want to merge two or more neighboring cells. For
this, you use the rowspan and colspan
attributes to the <td> tag. Each attribute
takes a positive integer value that tells the browser how many
rows or columns the cell is to include. For example,
colspan="3" says that the current cell should take
the next three columns, while rowspan="5" says that
the cell should include the next 5 rows. You can even get wacky
at say something like <td colspan="3"
rowspan="5">. This would make a big cell that takes 3
columns and 5 rows. Spiffy, no?
By the way, you might be wondering how the browser knows how
many columns you actually have. The answer is that it guesses
based on the row with the largest number of
<td> elements. Unlike LaTeX, if you add too
many (or too few) <td> tags to a row, it won't
tell you that things no longer match up. Your table will look
really stupid, though.
Back to top of page.
You'll also want to align your cell contents at times. There
are two attributes to the <td> tag that are
relevant here: align and valign. The
former controls the horizontal alignment and the latter the
vertical alignment. (I've always felt that the former should be
called "halign", but no one ever consults me on these
things. And see the fine mess we're in?). The align
attribute takes values left, center, and
right while the valign attribute takes
values top, center, and
bottom. What these do should be really obvious, so I
won't even waste time explaining.
I will, however, note that you can use these attributes on the
<tr> tag. In this case, the format is applied
to every cell in that row. Also, it needs to be noted that these
are also deprecated tags. You'll learn how to do the same thing
with style sheets next week.
Our example above, with these improvements, looks like:
<table border="1" align="center" width="50%">
<tr>
<th align="center" width="40%">Planet</td>
<th align="center" width="60%">Distance from Sun (AU)</td>
</tr>
<tr>
<td>Mercury</td>
<td align="center">0.4</td>
</tr>
<tr>
<td>Venus</td>
<td align="center">0.7</td>
</tr>
<tr>
<td>Earth</td>
<td align="center">1.0</td>
</tr>
<tr>
<td>Mars</td>
<td align="center">1.5</td>
</tr>
</table>
This renders as:
| Planet | Distance from Sun (AU) |
|---|---|
| Mercury | 0.4 |
| Venus | 0.7 |
| Earth | 1.0 |
| Mars | 1.5 |
Back to top of page.
Tables are complicated beasts and there are many other
attributes that you can set. For example, you can align the
entire table with the attribute center added to the
<table> tag. However, this is also a
deprecated attribute. (As usual, I'll tell you how to do this
correctly – and it's actually a bit of a trick that's not
commonly known, apparently – next time.) There are are also
such elements as <thead>,
<tbody>, and <tfoot> which
group rows into the header, body, and footer of the table. (Right
now, these are mainly nice for good formatting and access for
style sheets. Eventually, these might allow browsers to scroll
the table and leave the header rows always visible at the top, for
example. Stay tuned there.) Also, there is
<colgroup> which groups columns so that you can
control them in bulk. And the <caption>
element that makes a caption for your table. And this doesn't
include the ability to control the spacing and padding of the
cells, the cell/row colors, etc.
Back to top of page.
A final few words on tables. Tables are, in my knowledge, almost unique in a rather interesting but useful way. They are block-level elements in HTML. (So don't wrap them in other block-level elements!) That they frequently house other block-level elements. Why would you want to do this? You will sometimes find that you have a large table cell which should house, say, a paragraph of text. Or even several paragraphs. Also, you can put tables inside of tables. (This is sometimes useful for layout purposes. But, again, I encourage you to think very carefully before doing this. Nested tables can become very messy and generally are often used only to control the layout of the page in a way not consistent with the HTML philosophy. Still, I'm sure you can find a case where nested tables are reasonable and useful.)
Incidentally, the HTML standards do not appear to insist that block-level elements not be inside of other block-level elements even in general. In fact, I can think of one other case where you can put a block-level element inside of another block-level element. Can you figure out what it must be? (Hint: we discussed it already.) There are actually some other cases, I think, where you can do this, but most are rather obscure.
Back to top of page.
Here's another nifty concept that's easy to learn. You've probably all seen links that don't just take you to the top of a new page, but they take you to somewhere in the interior of a page. (This might be the same page as you were already reading, or a new page.) These are called internal links.
The way that you create an internal link is to first make the
anchor for it. The anchor is the thing that the link will refer
to. (It's just like a normal link: you need to make sure that the
page that the link refers to exists before creating the link.
Otherwise, the link will be dead and silly-looking.) There are
two ways to do this: the old way using the <a>
tag and the new way using the id attribute that any
tag can take.
So we'll look at the old way first. The <a>
(anchor) tag has another use besides making links, anchoring
locations in a document. The way that you do this is by the
name attribute with the tag. (In this case, you
won't set an href, since the tag isn't supposed to
send anyone anywhere. It's just a landmark of sorts.) So you'll
wrap something (text, a heading, what have you) in the anchor tags
with the name. For example, <h2><a
name="myAnchor">My
Heading</a></h2> makes an anchor that will
eventually bring us to that particular heading. To be strictly
HTML
compliant, make sure that you have something between the anchor
tags. You can generally get away with having nothing in there,
but it's naughty.
The other, newer way is easier. Every tag now allows for an
optional attribute id. This names that tag with the
id you give it. We'll see later that this is handy not only for
linking but also for style sheets and Javascript. But even now, I
imagine that you can see how it would be quite useful to have a
way to refer to one specific tag within your document.
An example of this would be <h2 id="myAnchor">My
Heading</h2>. Same thing as above, but it makes use
of the tag we're already using (simplifying the code) and also
will eventually let us play with the heading itself if we want to.
In fairness, I should note that id used to be called
name so you'll see that around. Also, some older
browsers might not support linking in this way.
So we have the location labeled. Now what? Now we make a
normal link, except that we make small modification to how we
write the URL.
We add a # to the end and then we add the anchor's name. For
example, the URL mydocument.html#myAnchor will
take us to the anchor called "myAnchor" in the local document
called "myDocument.html". You can, of course, specific a
full-absolute URL, here. In addition, there is another
option: no page specified at all, just a URL that starts with the #, such as
href="#myAnchor". What would this do, then? If you
guessed that it'll send us to "myAnchor" in the current
document, you're exactly right. (And you're probably getting a
good intuition for this sort of thing.)
What if the anchor we link to doesn't exist? Then when the user clicks the link, they'll either go nowhere or they'll go to the top of the page in the URL.
Back to top of page.
It's time to talk a bit about good site design and what make web pages better or worse, other than actual content. (Content on the web? Unthinkable...)
One of the most grievous sins committed on the web are poor choices in colors. The results of this error can range from making a page complete unreadable, to inducing nausea in your reader, to just annoyance. The latter is somewhat a matter of taste, of course, so there is somewhat less that you can do about that one than the former.
The first thing that I should mention is that colors don't always render in quite the same way across browsers, monitors, and computers. Part of this has to do with that mysterious parameter called "gamma" that varies across systems. Some of this is operating system funkiness (we've all worked with Suns here, so we all know about that). And there is also the issue of 8-bit versus True Color versus other systems. If you're on a low-color (say 256 colors) system, then clearly some interpolation will have to occur to force a 24-bit color into your system.
Back to top of page.
One key to good web design is to make sure that the text colors you choose contrast with their background colors. I've been to pages that had dark purple text on black backgrounds. (Like this. Bad, isn't it?) The only way I could read the content was to highlight it first. I tend to (personally) go for bright text on dark backgrounds, but the reverse also works. (In fact, white background and black text is the default in most browsers.) Also remember that the font-size and exact color-rendering might vary from machine to machine, so what might be just enough contrast on your machine might be somewhat too little on another. In other words, leave some room for error.
Back to top of page.
Some colors just need to be avoided on principle. For example, this isn't exactly a pleasant color. Imagine it as the background. In general, this is somewhat a matter of taste, so it might help to get a second opinion after you've designed the page. Of course, some colors are pretty safe. Black and white are fairly inoffensive, for example.
Back to top of page.
Background images are a major source of color problems. Why? Because they aren't a uniform color. Most don't even stick with a certain part of the palette, in fact. This makes it difficult to find a font color that doesn't disappear if the text is over the wrong part of the background. What makes this worse is that you pretty much cannot control where the text will appear relative to the background on a given person's browser. So while you might never have any red text on the red part of your background on your screen, someone else might.
What is to be done? Stick with simple backgrounds, for a start. Generally, I like backgrounds that stick to a small area in color-space. For example, my homepage is on a star-field background which is mostly black (with a few stars; being about 1 pixel each, they don't really interfere with the text). You can also imagine that a blue water surface would be alright, since reds and yellows would stand out fairly well in that setting. Really, in the end, backgrounds tend to be more distracting than useful anyway. A simple background can add a bit of personality to a webpage, but the complex ones are just annoying. (Also, they seldom tile nicely, making them look stupid.)
Back to top of page.
Images are another major pain in web pages. A web page without
any images is generally rather dry (like this one), so a few
images can add some color and keep the reader's attention.
However, the pendulum can swing too far the other way, too. Too
many images make the page long to download, particularly if the
images are large. In general, you want to keep your image files
as small as you can (but no smaller). Also remember that the
images should have the alt attribute set, especially
if the image is an important part of the site, such as a navigation
button!
I deferred this discussion from last time, but I should a few
words about types of images on the web. Basically, you get three
choices for image formats: GIFs, JPEGs, and PNGs. Most of you have probably encountered the
first two of these reasonably often. The JPEG format is well-suited to
photographs and pictures with lots of color gradients. The
GIF format,
conversely, works well for images that have a lot of solid colors
and sharp color boundaries. Drawings, cartoons, and other
artificially generated graphics tend to work very well as
The other format option is the PNG (pronounce "ping"). This format is similar to the GIF, except that it was developed as open source in responses to the fact that the GIF was the intellectual property Unisys and that company threatened to start charging for it. (They did, although it did not affect most people. Which is why you still see GIFs around.) At the moment, the PNG may not be universally supported, although all browsers that I've seen handle it. (At least, as far as I can recall.) In the future, more capabilities might be added to this format, but for now they're basically just GIFs. But do stay tuned, especially if you find yourself frustrated with the options available with GIFs. Incidentally, this is the format I generate in IDL when I'm making plots for talks and inclusion in non-LaTeX documents.
Back to top of page.
This is also an appropriate place to discuss image sizes. While some of you might be familiar with dpi (dots per inch) as a way of recording the image resolution, this is really almost irrelevant on the web. Why? Because it's simply number of pixels that matters. (Well, that, and file-size. But that's not what you see, it just sets how long it takes to get the image.) So you can set an image to a billion dpi and save it, but it will be stretched out across the browser for about a million screens. So when you're saving images, save them based on the pixel dimensions. A good rule of thumb is that you shouldn't post images more than 600-650 pixels wide, since the narrowest screens that people are likely to be using are 680 pixels. (The padding is for browser-edges, scroll bars, etc.) Since many image processors will re-size images (shrink or expand) when you work on them, the best way to determine whether the image is OK is to view it with a browser. And do remember that most of us work with monitors which are higher resolution and larger than normal.
In reality, you want to keep images as small as reasonable, but no smaller. Clearly, the image needs to be large enough to do its job. However, if you make it large it will greatly add to the download time, especially on modem connections. This will annoy your readers unduly. Besides cutting down the dimensions, you should also consider cropping your images if there is unneeded space around the edges. A little cropping can greatly reduce file size.
If you're making a photo album and you don't want to force your viewers to download all of the large images (nice, big images are in order when you're trying to show off photographs, after all), one solution is to use thumbnails. A thumbnail is a shrunk-down version of the full image which is generally linked to the big guy. I make thumbnails of almost all of my images and them link them in to the full-sized version for anyone who wants to view them. The thumbnail is typically ¼ to ½ of the size of the big image. Also, I have a bit of Javascript code that I use to make the full-size image page. (Javascript generates the actual page code, so that the pages never really exist as files.) I'd be happy to share it with anyone who wants to use it.
Finally, if you don't already know about the Unix program
xv, you should give it a whirl. It's not a very
complicated editor, but it will let you crop and resize images
without finding a machine with Photoshop or another fancy editor.
Back to top of page.
And now for layout of websites and pages. In general, your pages should be short, since most readers don't want to read many pages of text. There are, as always, exceptions to this rule, though. This page is one example. (Why is it probably OK that this is a long page?) This means that you may want to break up your content into more pages. Just make sure that the breaks are logical and that you don't go too crazy. Having to view too many different pages to get the information that one seeks is just maddening.
Another pointer is to keep lots of easy naviation handy. Provide links back up to the top-level page, for example (notice below?) and internal links in long documents.
There is an old rule in web design that your reader should only need to click three times to get to any given page. Recent studies imply that this glib rule should probably be more like 7 clicks maximum, but the idea is the same: don't make the linking too "deep" that a viewer has to travel through lots of unnecessary pages to get where she wants to.
On the other hand, you don't want to overwelm your readers with too many pages when they first arrive. One solution is to break up your website into parts. (You can visit my website for an example of how I've broken mine up. Ignore the fact that I'm using some style-sheet wizardry to do this. You'll learn it soon enough.) If you're organized, it is probably best to put different sections in subdirectories of your web directory. This makes it easier for you to navigate when editing. (It also eases some fancy navigation tricks. When I helped Keith Gleason recently by creating a script to generate the navigation menu at the top of each page on the SBO site, I was greatly aided by his careful organization.)
Back to top of page.
Finally, I'd like to say a few things about your source code. I'm a big fan of text editors that have HTML packages. (X)emacs, for example, generally has this installed when you get to it. This allows you to engage syntax highlighting (so that the various elements are color-coded; very hand when you forget to close a string or a tag), automatic indentation, and a host of other, smaller features. Using this kind of editor helps you write more effect and easy to read source code. This makes it easier to edit and correct later on. (It is also nice for people who are trying to learn from your successes.)
The bare minimum for good code, in my view, is good use of
white-space within the code. Since HTML ignores returns and multiple
whitespaces, you can use this to make your code more readable.
Above you will see how I set up my table code. Each element is on
a new line (this isn't always the best way to do this, of course)
and the nested elements are indented farther. This makes it a
snap to read the code and find closing tags. (Note that emacs did
the indenting for me. Since it parses the
Lastly, I bring comments to your attention. The proper way to
create a comment in HTML is to start it with <!--
and to end it with -->. (Note that everything
between these bits is commented out. Again, a good editor should
color-code this for you in case you make a mistake.) You probably
want to leave spaces after the starting bit and also before the
closing bit, just to be safe. Comments can be used to comment you
code, generally to make it easy to find things later. For
example, I put some comments in the source code for APS's main
webpage so that I could quickly get to the news and FYI areas to update them.
You can also use comments to note to yourself what you plan to add
or change in a given spot. Also, those who have done a lot of
programming have undoubtedly used comments to "comment out" code.
That is, render a chunk of code inoperative without deleting it.
This is good for both experimenting on your code and for keeping
stuff around in case you might need it down the road.
Back to main workshop page
Back to top of page.