demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter.

featured articles

popular favourites

Captioned Images In XHTML

Captioned Image Example ScreenshotWhile there are many possible different methods for captioning an image, the solution I prefer in XHTML is to place the image in a definition list. This makes the most sense semantically – the image is the item we are defining, while the definition term is the caption – and is the most flexible in terms of markup. Note that the approach in HTML5 is very different, the latter language having markup explicitly designed for the purpose of captioning images.

A typical XHTML code example would be:

  1. <dl id=”captioned-image”>
  2. <dt><img src=”khufu-pyramid.jpg” alt=”Great Pyramid of Giza”
  3. title=”Great Pyramid of Giza” style=”width:492px; height: 345px;” /></dt>
  4. <dd>The Great Pyramid of Giza, completed ~ 2560 BCE</dd>
  5. </dl>

While this accomplishes our goal of a captioned image, it doesn’t look terribly good. First, let’s put a border on the definition list:

  1. dl#captioned-image { border: 1px solid black; }

Note that this border makes it clear that our definition list takes up the entire horizontal space of our web page, which makes sense, as <dl> is a block tag. The height of the <dl> is determined by the content inside the list. Now let’s float it:

  1. dl#captioned-image { border: 1px solid black; float: right; }

Note that when we float a block element it essentially collapses: now the width of our definition list is determined by the widest element it contains (the image).

We’ll add a little padding, margin-left and background-color; you could also remove the border at this stage:

  1. dl#captioned-image { border: 1px solid black; float: right; padding: 1em;
  2. margin-left: 1em; background-color: #ffc; }

The <dt> content is indented because that is the default for that element, just as it is for <li> elements, so let’s remove that with a separate style declaration:

  1. dl#captioned-image dd { padding-left: 0; }

At the same time, we’ll improve a few things about the caption:

  1. dl#captioned-image dd { padding-left: 0; text-align: centre; font-style: italic; }

Now the captioned image can have content wrapped around it. However, unlike an image by itself, it cannot be placed inside a paragraph:

  1. <dl id=”captioned-image”>
  2. <dt><img src=”khufu-pyramid.jpg” alt=”Great Pyramid of Giza”
  3. title=”Great Pyramid of Giza” style=”width:492px; height: 345px;” />
  4. </dt>
  5. <dd>The Great Pyramid of Giza, completed ~ 2560 BCE</dd>
  6. </dl>
  7. <p>Common knowledge (and Cecil B deMille films) imagines rows of
  8. sweating, beaten slaves building the pyramids. >Archeologically, there
  9. is no evidence for this; indeed, all the available evidence shows that
  10. the workers were local men, hired to work off taxes owed to the Pharaoh
  11. by completing labour during the Egyptian wet season, when the Nile was
  12. flooded and no farming could take place.</p>
  13. <p>In addition, the gangs of workers were significantly smaller
  14. than those shown in cinematic recreations: it has been estimated that
  15. it would take only 2,000 men working full-time to erect the Great Pyramid
  16. in the 10 years stated for its construction. Even taking into account
  17. support staff and rotation of workers, the entire workforce was probably
  18. no more than 10,000 people at any one time, lower by an order of magnitude
  19. than the 100,000 slaves Herodotus reported in his
  20. <cite>Histories</cite>.</p>

While we have used this list to contain a single example, you could have multiple pairs of images and captions as definition terms and matching declarations in the same list.

Interweaving XHTML and PHP: The XML Prolog Problem

Let's take a simple page and save it as prologtest.php, with the code below:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5. <head>
  6. <title>An XHTML 1.0 Strict standard template</title>
  7. <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  8. </head>
  9. <body>
  10. </body>
  11. </html>

As before, upload this page to your server and use your browser to look at it in that location.

Depending on how your server is set up (error messages shown or repressed) you will see either nothing at all on the page, or an error line similar to the following:

  1. Parse error: syntax error, unexpected T_STRING in
  2. /f2/demosthenes/public/test.php on line 1

This demonstrates two important points:

  1. When PHP doesn't work (almost always due to an error in your code) it really doesn't work: the page stops, and you get an error message, or nothing at all.

  2. The echo statement prints information to the page: that information could be a text string, as we have above, HTML, a variable, or a combination of all three. Anything other than a variable must be enclosed inside quotes; either single quotes ('') or double quotes("").

So what's the problem with our page?

The PHP opening tag is usually <?php ..., but it may also be shortcut to <? .... This latter, optional format for the opening tag confuses the PHP parser, which attempts to interpret our opening XML prolog as PHP. There are several possible solutions to this:

  1. Drop the XML prolog. Doing so sacrifices some flexibility and future-proofing, avoids an issue in IE6 (which also has an issue with the XML prolog), keeps your page valid, and is probably the quickest solution.

  2. Set the PHP parser to only accept the long form of the opening PHP tag and ignore the short version.

  3. Use PHP to echo out the XML prolog. Replace the first line of the page with the following code (note the uses of single quotes):

    1. <?php echo '<?xml version="1.0" encoding="utf-8"?>' ?>

Choose the option that appeals to you, make the appropriate change, save and upload the page, and view it again.

And suckas be thinkin' that they can fake this
But I'm gonna drop it at a higher level...

Creating Alpha-Masked Clouds as PNGs in PhotoShop With CSS3

In previous articles we’ve looked at creating 32-bit PNGs for use in web pages. In this exercise we are going to make a more complex image, working solely in the mask layer. I’ll be using CS5, but the techniques illustrated should be applicable to any version of PhotoShop, and translatable to other image editing programs such as GIMP. We’ll use the result of this tutorial in several articles to come, including PNG Optimisation and CSS3 animation.Clouds Image PhotoShop Setup

Step 1: Setup

Our initial goal is to make a banner for some text that is easily adjustable, with the foreknowledge that we will be animating it later with CSS3. First, you’ll want your canvas in PhotoShop to be a little wider and taller than your final banner to allow for animation: I would suggest around 1000px wide by 250px tall. Make sure that you name the document and make its background transparent before you press OK.

Make sure you have default colours (black foreground, white background) selected in the color picker by pressing D on your keyboard. Ctrl+ click to rename the current layer. After pressing OK, fill the layer with white by pressing SHIFT + F5 and choosing Background Color as the fill option. Immediately create a mask for your layer by clicking on the Add Mask icon in the layers palette. The mask is selected by default. We will be doing all of our work directly on the layer mask:Clouds PhotoShop Layers Palette you’ll be able to tell that you are on the layer mask by the small highlighted frame around the layer mask icon in the Layer palette.

Step 2: Create the clouds

From the menu bar, choose Filter / Render / Clouds.

The result doesn’t look terribly cloud-like yet, but we’ll improve that. Choose Filter / Render / Difference Clouds. Re-apply the Difference Clouds filter twice more by pressing CMD-F twice in succession. (You will be able to see the mask we are creating more clearly by going to the Channels palette and temporarily turning on the visibility of the Clouds Mask while turning off the others by clicking on their eye icons.)

Photoshop Clouds Levels SettingsWe want to tighten up the edges of the clouds a little. Press CMD-L to bring up the Layers window and adjust the sliders to the approximate locations you see in the screenshot to the right.

Finally, apply a little Gaussian blur to the cloud mask (Filter / Blur / Gaussian Blur) to break it up a fraction more, using a value of 1.6.

Step 3: Export the PNG-24

While we could continue to make improvements, let’s leave our clouds in their current state. Again, all of the work has been on the mask: the impression of “clouds” is rendered solely by the transparency information in the alpha mask.

Go ahead and save the image as a PNG-24 from PhotoShop via File / Save for Web and Devices. If you are still unclear as to why we are using PNGs and not GIFs as our export, feel free to preview the difference between the two formats in the export screen that appears. Call the final file clouds.png. It might also be wise to save your original image as clouds.psd, as we will be using it in the next lesson.

Step 4: Create the markup and basic CSS

In the text editor of your choice, create an HTML. Inside the <body>, place something like the following:

  1. <div id=“clouds“>
  2. <q>And suckas be thinking' that they can fake this<br />
  3. But I'm gonna drop it at a higher level…</q>
  4. </div>

Next, apply some CSS. We want the <div> to contain both a CSS3 gradient background and the PNG image. This is possible with CSS3’s support for multiple backgrounds, but we must be careful to specify them in the correct order:

  1. div#clouds {
  2. background-image: url(clouds.png);
  3. background-image: url(clouds.png),
  4. -webkit-gradient(linear, 0 0, 0 100%, from(#3e6caa), to(#76b6f4));
  5. background-image: url(clouds.png),
  6. -moz-linear-gradient(top, #3e6caa, #76b6f4);
  7. background-repeat: no-repeat;
  8. font-family: Highway, Arial, sans-serif;
  9. font-size: 36px; padding: .2em 2em;
  10. }

As you can see, the clouds appear over our gradient “sky”, and are semi-transparent against it, due to the alpha mask we created in the PNG. One advantage is that we can modify and move the clouds and sky backgrounds separately, or animate it using more CSS3, no Flash or movie file required.

TitleJapanese TitleYear of ReleaseRun Time
Rashomon羅生門195088 minutes
IkuruI生きる1952143 minutes
Seven Samurai七人の侍1954207 minutes
Throne of Blood蜘蛛巣城1957105 minutes
The Hidden Fortress隠し砦の三悪人1958139 minutes
Yojimbo用心棒1961110 minutes
Ran1985160 minutes
Hover to highlight rows, click on table headers to highlight columns

Dynamic Customized Tables With CSS3

The demarcation between the appropriate roles for , and in modern web development can be a grey area. Perhaps one of the easiest ways to make this distinction clear is with tables. For example, in the table to the left, we want to accomplish several goals:

  • A background image that automatically resizes as we add and remove table data
  • Alternate appearance of table rows, to make them clearer
  • Highlight the row that the user places their cursor in
  • Make it clear which column our user is interested in.

All of this is just CSS. I've touched on almost all of the techniques I'm about to use in past articles, and will reference them as I go; the parts that are new and interesting are under-utilized and almost unknown tags that we'll use as markup to add more semantic "hooks" for our CSS to modify: <col />, <thead> and <tbody>.

Extended Table Markup

The code for our table looks something like this:

  1. <table summary="The popular films of director Akira Kurosawa" id=kurosawa>
  2. <col /><col /><col />
  3. <caption>The Masterworks of Akira Kurosawa</caption>
  4. <thead>
  5. <tr>
  6. <th>Title</th>
  7. <th>Year of Release</th>
  8. <th>Run Time</th>
  9. </tr>
  10. </thead>
  11. <tbody>
  12. <tr><td>Rashomon</td><td>1950</td><td>88 minutes</td></tr>
  13. <tr><td>Ikuru</td><td>1952</td><td>143 minutes</td></tr>
  14. <tr><td>Seven Samurai</td><td>1954</td><td>207 minutes</td></tr>
  15. </tbody>
  16. </table>

<thead> and <tbody> are fairly straightforward: they make clear what in the table is data versus header sections (<tfooter> is also possible). We've talked about table accessibility previously: that's why we use the summary attribute and caption tag. What's new here is col.

col

When we construct HTML tables, we do so by row, creating table cells each row. Columns are implied, but they are not explicit. <col> is a reference to make that association clear: each <col> tag refers to the column of cells immediately below it when the table is rendered in the browser. Therefore, you would normally have the same number of cols declared as you have <td> cells in each row, as we do here.

(It is possible to have a <col /> take responsibility for multiple columns by using the span attribute: <col span="2" />, for example).

Table Customisation

First, some base CSS:

  1. table#kurosawa { background-image:url(seven-samurai.jpg);
  2. background-size: cover;
  3. border-collapse: collapse; }
  4. table#kurosawa caption { font-size: larger; padding: 1em; }
  5. table#kurosawa td { padding: .5em; }
  6. table#kurosawa thead tr { background: #000; color: #fff; }

We've used a dynamic background image to fill the table and are using <thead> as a parent in a descendant selector to change the header row; aside from that, the CSS is fairly straightforward. Next, we want to zebra-stripe the rows in the table body:

  1. table#kurosawa tbody tr:nth-child(odd) { background: rgba(0,0,0,0.3); }

To highlight the rows on hover:

  1. table#kurosawa tbody tr:hover { background: rgba(0,0,0,0.8); color: #fff;
  2. cursor: pointer; }

Finally, we want to be able to highlight each column. Unfortunately, <col /> supports very few CSS properties, and can't take most pseudo-selectors. Instead, we'll use :target from links in the table header section. To do so, we'll modify the markup slightly:

  1. <table summary="The popular films of director Akira Kurosawa " id=kurosawa">
  2. <col id=filmtitle" />
  3. <col id=releasedate" />
  4. <col id=runtime" />
  5. <caption>The Masterworks of Akira Kurosawa</caption><thead>
  6. <tr>
  7. <th><a href="#filmtitle">Title</a></th>
  8. <th><a href="#releasedate">Year of Release</a></th>
  9. <th><a href="#runtime">Run Time</a></th>
  10. </tr>
  11. </thead>

Now each table header cell has an anchor link to the <col /> it is part of. Next, we customize the links:

  1. table#kurosawa thead tr th a {
  2. text-decoration: none; color: #fff; background: #000;
  3. padding: .5em; display: block; }
  4. table#kurosawa thead tr th a:hover { background: #777; }

And then the neat part: make each column highlight when it is targeted by the appropriate link.

  1. table#kurosawa col:target { background: rgba(255,0,0,0.5); color: white; }

<col /> can be placed almost anywhere in a table: I've put them at the very top in order to minimize "bouncing" of the page when the local anchor link is followed. Because cols are rendered on "top" of the existing content, using rgba colours creates a nice layered effect. It's also possible to "zebra stripe" cols using CSS; for example:

  1. table#kurosawa col:nth-child(odd) { background: rgba(255,0,0,0.3); }

Microdata: Metadata For Content

In most tags are semantic: that is, they carry meaning. This structure of semantic tags is embraced and extended in through elements like <time>.

Even with the dozens of new tags in HTML5, there is no way to provide meaning for every piece of content. This impoverishes the web: machine-readable tags that provide context make for a richer, more semantic internet, better and more accurate searches, and more powerful data aggregators. But short of an XML utopia, covering every possibility of meaning is a near-infinite task.

Instead, there are several measures that add to, or extend, the semantics of web pages:

  • Dublin Core meta tags, and their progenitors, attempt to summarize the context of the entire page, adding information such as authorship and revision date. However, they can only describe the page as a whole: as meta tags are written in the <head> section, it is impossible for such tags to drill down and specify the individual content of the page.

  • Microformats extend tags via special values for class and id attributes. Microformats have strong support by Google, Facebook and YouTube through schemas like hcard (to represent people, companies, organizations, and places), calendar (for events), recipe, and XFN (to diagram relationships between people).

  • RDFa is another means of providing context to tags via values added to del and class attributes, currently used to indicate Creative Commons licenses, amongst other purposes.

  • To this, HTML5 adds microdata, a way of extending the meaning of tags through a shared vocabulary. Unlike meta tags, microdata is written in the body of an HTML document; unlike microformats and RDFa, it does not abuse class or del, instead using new attributes that are built into HTML5 such as itemscope and item type, with established, central schemas such as schema.org and data-vocabulary.org. Google and Microsoft are both supporters of microdata, with more adopters being added.

“Which system should I use?”

Which system you use depends on what you are trying to do:

Are you making an XHTML page?

In that case, use Dublin Core and microformats

Want to add a Creative Commons license?

Use RDFa

Making an HTML5 page?

Use microdata, adding meta tags and RDFa as they are supported with namespaces.

The doctype

Specifying the correct doctype of your web page is very important. Without it, the client (the web browser, iPhone, etc) will have no idea which version of HTML you are using to write the document, and will default to guessing how the HTML should be rendered. In many browsers, this is known as “Quirks” mode, and can result in pages displaying oddly. By specifying the doctype, we tell the client “try to render this document according to the standards of this specification”. That information is added at the very start of the page, as follows:

For :

  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
  3. “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

For :

  1. <!DOCTYPE html>

The first part of the specification for – the xml prolog – shows the close relationship between XHTML and XML. A strictly coded XHTML document can be parsed as XML, if we ever wanted to do so. That first line tells the browser what version of XML the XHTML can be translated to (1.0) and the character set used on the page (utf-8, a version of Unicode). This line acts to “future proof” our work, and means that it will be readable for many, many years to come. That being said, the xml prolog is optional: you can drop it if you wish to (and if you want the page to render correctly in , you have to).

The next line for XHTML, and the only line for HTML5 – the doctype – tells the browser which version of HTML we are using (XHTML 1.0 Strict and HTML5), what language it is written in (English), and where to find the defining document for the specification.

Note that neither the doctype nor the XML prolog are, strictly speaking, part of HTML, and they largely ignore the rules that I lay out so carefully in subsequent articles. You may wish to think of the doctype and xml prolog as a negotiation or an exchange of information between the web page and the browser, much as you might, upon meeting a stranger in Switzerland, attempt words in several different languages before both parties settle on speaking English. In our case, our web page is saying “Hi. I can give you the information that follows as XML or XHTML, whichever you prefer. Oh, and I'm going to speak in English, formating my characters this way (UTF-8), just so you know.”

The doctype is also required to validate our code, to check that we have written our web page in the right way. Without a doctype, the validator has no idea what version of HTML you are using, or what rules to check your code against.

Beginning Web Development - Overview

This entry attempts to summarize, in point form, the various topics I have covered in the last two years related to basic web development, including links to relevant entries where appropriate. If you were using this blog for the purposes of study or to make a web page from scratch, this would probably be the place to start. It will be followed by "Beginning CSS Web Development".

Create a basic HTML document:
Add lists, tables and links to a web page.
Manipulate and insert bitmap images into web pages.
Add an accessible form to a web page:
Host a web site under a domain name.
Register a site with search engines and optimize page rank.

web developer guide

featured comment

by Aisling Brock in New Business Card Design

what i'm reading

A Feast for Crows: A Song of Ice and Fire: Book Four
A Feast for Crows: A Song of Ice and Fire: Book Four

what i'm watching

Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]
Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]

what i'm playing

Borderlands
Borderlands

what i'm hearing

Planets
Planets

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.