HTML Basics: Hyperlink Syntax – Absolute, Relative and Root-relative
My new book Sams Teach Yourself Microsoft Expression Web 3 in 24 Hours is nearing completion (just finished final review of the first 10 chapters last night). The book is a revision of the original for the new version of Expression Web and in the rewriting process I also added some new content to help the readers better understand the sometimes confusing and mysterious world of web code. These additions were mostly brought forth by questions and comments from readers as is the case with the excerpt below about hyperlink syntax.
I chose this excerpt because it is relevant not only to people who use Expression Web 3 but to anyone who does anything on the web. When I started out in this field I was often confused about why there were three different types of hyperlinks and how and when to use them. Well, here is a straight forward explanation with examples:
Absolute, Relative and Root-relative Hyperlinks – an explanation
As you are creating hyperlinks in Expression Web 3, you will notice that the syntax of the link address in the Code view changes depending on what you link to. There are actually three different ways of writing a hyperlink address, all of which are used for different purposes:
Absolute Hyperlinks
Absolute hyperlinks are complete addresses that contain all the elements of a URL. They always start with some version of http:// followed by the domain name (for example, www.designisphilosophy.com) and optionally a page/folder. Absolute hyperlinks are used when linking to pages outside of the current site that have a different domain name.
Relative Hyperlinks
Relative hyperlinks are addresses that are relative to the current domain or location. They only contain the name of the target page prefixed with any necessary folder moves (for example, default.html). The browser sees that this is a relative hyperlink and adds the domain and folder location of the current page to the beginning of the link to complete it. If you use relative hyperlinks and you want to navigate from a page stored in one folder to a page stored in a different folder you add the folder prefixes to the hyperlink. For instance, a relative link from a page in Folder 1 to a page in Folder 2 would be ../Folder 2/page.html, where the ../ tells the browser you want to go out of the current folder and into a new one. When you create hyperlinks between pages in Expression Web 3, they are always inserted as relative links so that the application can easily update them if you choose to move files around. However, if you move the files around on your computer outside of the Expression Web program, the hyperlinks break.
Root-relative Hyperlinks
Root-relative hyperlinks are a subset of relative hyperlinks in which all the links are assumed to start from the root folder (domain name) of the site. They differ from the relative hyperlinks in that the address is prefixed by a forward slash (for example, /default.html). The browser applies only the domain to the beginning of this link. Root-relative hyperlinks are used in place of relative ones in large sites in which there is a chance the files will be moved around without using an application such as Expression Web 3 to update them. Because they refer to the root of the site rather than the current location of the page they are placed in, they work regardless of where the file is placed as long as they remain under the right domain.
Why a CSS Reset should be at the core of your stylesheet
The CSS Reset is a little known and often overlooked tool in web design that makes cross-browser and cross-platform compatibility a lot easier. It also ensures that you start with a clean sheet when building CSS-based web sites, whether they be single pages, static sites, WordPress sites or anything else. In my view the CSS reset is so important that web designers, even those just starting out, should use it at all times and make it the foundation of any and all style sheets they create. In fact the employment of the CSS Reset is a main tenant in both my books on Expression Web 2 and Expression Web 3 and is the basis of all my own design projects including the free WordPress theme Typograph.
Why do I need a CSS Reset?
If you’ve never worked with a CSS Reset before I can pretty much guarantee that the question you are itching to ask is “why do I need a CSS Reset”. After all, you’ve designed or worked with numerous CSS-based sites in the past and even though they didn’t have a CSS Reset they work just fine. Right? Well, let me ask you this: If you’ve ever tried to design a site from scratch using CSS, and you’ve tried to make it cross-browser compatible, you’ve probably noticed that your styles don’t always look the same in different browsers even though they should. In most cases this has been a Internet Explorer vs. the rest type of battle and you’ve probably written it off as such and just picked a side. But that’s not the only, or right for that matter, solution. If you run into a browser incompatibility issue where CSS is concerned, it’s more often than not due to the fact you haven’t properly defined your styles leaving it up to the respective browser to make guesses as to what you want the site to look like.
To put it in simpler terms: If you don’t define all the default CSS parameters in your style sheet, the browser will use its default parameters instead. And since different browsers have different parameters your site will end up looking different depending on what browser you use.
What does the CSS Reset do?
As the name suggests, the CSS Reset resets all the default CSS parameters to a neutral position thus overriding any predefined assumptions at the hands of the browser. That’s a bit of a vague explanation so I’ve made a visual example that illustrates it perfectly:

The image above shows the same piece of basic HTML displayed when no CSS is defined and when the CSS Reset is applied. It is pretty obvious what happens: When you create a HTML page with some basic tags like <h1>, <p>, <blockquote> and <ul> without defining the styles of these tags with CSS, the browser applies its default stylesheet to these tags. But like I said earlier, different browsers have different standard stylesheets and as a result the page won’t look the same across all browser. And although this isn’t really a big problem when we’re talking super-basic stuff like what is displayed above, it becomes a serious pain in the neck when you create complicated CSS layouts.
So all I’m doing is creating more work for myself?
Unfortunately the gut reaction from a lot of people when they see the image above is “Oh crap! Why would I ever do that? I just create tons of work for myself.” Well, that’s partly true: With a CSS Reset applied you do have to manually define all your styles unless you like the reset look (I don’t). But on the bright side that also means you are now in complete control of every aspect of your site and nothing is left to chance any more. And in my book the former far outweighs the latter.
If that doesn’t convince you, consider this: Before I startet using the CSS Reset in all my projects, I spent a lot of time trying to jury rig my code into playing nice in all browsers. This often included using IE hacks and JavaScript. After emplying the CSS Reset I only rarely encounter these problems, and when I do it’s usually because I made a mistake somewhere.
Alright, I’m sold. How do I start using the CSS Reset?
There are several CSS Resets available out there. The one I use is CSS guru Eric A. Meyer’s Reset Reloaded. It seems to be the most comprehensive reset and it is constantly being updated. To employ it I simply copy the code from the site and paste it in at the very top of my stylesheet. When it comes time to work on my own styles I make new ones leaving the CSS Reset intact. Cascading Style Sheets work as a cascade from the top down which means with the CSS Reset on top the browser will first read all the reset styles and then whatever styles I define below and apply them in order. That way the layout is guaranteed to be clean of browser junk and only shows my style code.
That really is all there is to it. So employ the CSS Reset and go forth and code.
Using WordPress in Alternate Configurations – My WordCamp Whistler 09 Presentation
Finally, after a full week of catching up, here is the video tutorial version of my presentation at WordCamp Whistler 09 for those who were there and those who couldn’t come. The video is also available on WordPress.tv if you’d rather watch it there. I recorded the video over the weekend and it contains the entire presentation including all my fancy slides as well as the code examples and demos. The only thing you won’t see is me waving my hands around and messing up the code like I did at the actual event ;o)
Code Snippets
The last half of the presentation centers around creating Custom Page Templates and Custom Fields for layout purposes. To help you along in your own WordPress site development, here are those code snippets ready to be cut and pasted into your templates:
Custom Page Templates in 5 lines of code
This block of code is inserted at the very top of the Custom Page Template file. To get started, simply open the page.php file, save it under a different name, paste these 5 lines of code at the top of the document, save and upload to your server. To activate the new Custom Page Template just select it from the Template menu under Attributes in the Page Editor within WordPress.
<?php /* Template Name: Whatever */ ?>
Custom Fields in one line of code
This code can be used in any template file including but not limited to page.php, any Custom Page Templates, index.php, archives.php, single.php etc etc. The code returns a string of text that matches the text inserted in the custom field. Remember to replace $key with the actual name of the custom field. You can read more about Custom Fields and how to use them in the WordPress Codex.
<?php echo get_post_meta($post->ID, '$key', true); ?>Custom Field that parses PHP code
This code is used to parse (interpret) PHP code inserted into custom fields. It is a bit wonky – for instance it terminates any other custom field code placed directly after it in a page – so use it with caution. Otherwise it works exactly as the code above.
<?php $boxContent = get_post_meta($post->ID, 'centerBox', true); ?> <?php eval('?'.'>'.$boxContent); ?>
Applications Used in the Presentation
After the presentation several people came up to me and asked what applications I used, so here is a short list:
BitNami WordPress Stack
The demo site I used in the presentation was actually installed and running locally within Windows 7. To achieve this I used an ingenious application named BitNami WordPress Stack. Once installed this application will run a fully functional version of WordPress with database entry, plug-ins, custom themes and everything else you want to throw at it right inside Windows (XP, Vista and Windows 7 supported) so you don’t have to keep uploading your files to a server or hassle through complicated XAMP installs to play around with WordPress while offline. You can even install several different WordPress and other open source CMS stacks on your computer simultaneously to further increase your productivity. I have no idea exactly how it works but BitNami works incredibly well. Just remember to set the IP address to “localhost” when you install it.
You can download the BitNami WordPress Stack here. For Mac users there is a similar application called MAMP but I know nothing about it.
Web Developer Add-On for FireFox
FireFox is my absolute favourite browser and I use it for browsing as well as in the design process. One of the main advantages of FireFox is the myriad of add-ons you can install that make web site development a lot easier. The one I use the most is the Web Developer Add-On. This small application within an application lets you see and mess with CSS, turn styles and JavaScript on and off and do tons of other stuff that makes it easier to dissect and troubleshoot buggy web pages. Combine it with the HTML Validator add-on and you have a true powerhouse in a small browser window.
Microsoft Expression Web 2
My web development platform of choice is Microsoft Expression Web 2. This new offering from Microsoft is what enables me to build custom WordPress themes and web sites like AnnyChih.com from scratch in less than 24 hours. There are many great things you can talk about with Expression Web 2 but for WordPress theme development the two main features is full PHP support, unrivaled CSS integration and Standards Based CSS generation right out of the box. If you want to know more about Expression Web 2 or want to learn how to use it you can read more on this blog or pick up a copy of my book Sams Teach Yourself Microsoft Expression Web 2 in 24 Hours. It’s a good read, I promise.
Code snippets from my WordCamp presentation
Here are some code snippets from my WordCamp Whistler presentation. This article will be expanded in the coming week but in the meantime here they are for anyone wanting to play around with them:
Custom Page Templates in 5 lines of code
<?php /* Template Name: Whatever */ ?>
Custom Fields in one line of code
<?php echo get_post_meta($post->ID, '$key', true); ?>Custom Field that parses PHP code
<?php $boxContent = get_post_meta($post->ID, 'centerBox', true); ?> <?php eval('?'.'>'.$boxContent); ?>
Using Conditional Custom Fields for Advanced Layouts
An often overlooked function in the WordPress arsenal is Custom Fields. Overlooked because to most it makes no sense: What do you use a custom field for? And how do you use it? The answers to these questions differ depending on how the WordPress theme has been set up: Custom fields can be used for everything from passing information to plug-ins like Next Gen Gallery to feeding custom areas in the template with information. But it goes way beyond that. Custom Fields can also be used to create advanced layouts and design variances that can be triggered on a page by page or post by post basis. And this tehcnique can be edhanced further by adding conditions to the scripts so that the changes only appear when the field is actually activated.
Understanding custom fields
You can add custom fields to any WordPress post or page through the custom fields interface found right underneath the main text area. The custom field contains two elements; a name and a value. These are pretty self explanatory: When the template asks the server for the name, the value is returned. But this also means that unless the template actually asks for the field by name, nothing is returned. An example to show how this works in real life:
A web site for an art gallery requires each artist page to have a series of sub-pages containing an artists statement, bio, CV and image gallery. Although adding an unordered list directly to the text body of the page would work, it would require the addition of style elements and tags – something WordPress doesn’t like very much. Not to mention it’s also cumbersome and messy. A better solution is to place all the style tags in the template and then just feed the menu in the form of a standard unordered list from a custom field, in this case with the name “artistMenu”. Then all that’s left is to get the template to call for the info in the custom field like this:
<div id="artistMenu"> <?php echo get_post_meta($post->ID, "artistMenu", true); ?> </div>
When the template is opened, the content of the custom field named “artistMenu” is placed as a string inside the artistMenu div. (To understand exactly how the php code works you can read about the get_post_meta template tag in the WordPress Codex.)
Making the custom fields conditional
The problem with the example above is that even if there is no custom field defined, the div is still placed in the page taking up space. Not a big problem when it’s just a horizontal menu but if you use a custom field to populate something larger, like an image gallery or a text box, it will look weird if the box is left empty. One way of avoiding this is to make two separate templates, one with the custom field code and one without, but that can quickly become complicated. And the whole idea here is to make things simpler, not more complicated. A better way is to make the code and the call for the custom field conditional on whether the custom field has been defined in the first place. This can be done with a simple if statement:
<?php if((get_post_meta($post->ID, "artistMenu", true))) { ?> <div id="artistMenu"> <?php echo get_post_meta($post->ID, "artistMenu", true); ?> </div> <?php } ?>
Using conditional custom fields as design elements
Now for the really cool stuff: Because we can make custom fields conditional, and because we can populate them with pretty much anything, we can use them not only to add images or text but also to add all new design and layout elements. In the site I built for Sablok & Salbok Notaries Public I used this technique to create a header element that only appears if the custom field is populated by an image or text. The actual appearance of the element is controlled by standard CSS. You can see this layout element as the blue horizontal area in the image and on the front page of the site.
In this particular example the custom field can be populated by an image. Rather than forcing the user to input all the image code in the custom field manually I added some extra code in the template that gathers the width and height of the image and creates the proper element code. As a result all the user has to do is provide the URL for the image. There is also an or condition in the if statement so that the custom field code in the template is triggered either when an image field or a text field is defined:
<?php if((get_post_meta($post->ID, "image", true)) || (get_post_meta($post->ID, "text", true))) { ?> <div id="subheader"> <?php if(get_post_meta($post->ID, "image", true)) { $size = getimagesize(get_post_meta($post->ID, "image", true)); ?> <img src="<?php echo get_post_meta($post->ID, "image", true); ?>" alt="" width="<?php echo $size[0]; ?>" height="<?php echo $size[1]; ?>" /> <?php } ?> <?php if(get_post_meta($post->ID, "text", true)) {?> <?php echo get_post_meta($post->ID, "text", true); ?> <?php } ?> </div> <!-- END SUBHEADER --> <?php } ?>



