If you're new here, you may want to subscribe to my RSS feed. So that you can read the latest updates about Web2.0 tools, Making Money Online, Tips in SEO, Ajax and many more. Thanks for visiting ProgramimiCOM!
I thought I’d share a little bit of what I’ve learned from noodling around with stylesheets these past few years. Here are some basic organizational practices I try to follow. ( Much of this might be old hat for you, and if so, just think of it as a refresher. I run into enough messy stylesheets that I thought this might be of some interest. )
Group your styles into categories (ex. layout, typography, forms, so on) and visually seperate them in your css file. A title and table of contents doesn’t hurt either:
/*
HuddleTogether.com Screen Styles
Table of Contents:
layout
typography
forms
*/
/* layout
----------------------------------------------- */
/* typography
----------------------------------------------- */
/* forms
----------------------------------------------- */
Even though I do have some common practices, I don’t have a ‘template’ for how to breakdown styles into categories.
For starters, I almost always have layout and typography categories. With typography defining the sitewide look and feel. Depending on the complexity, I may break out the table and form styles into their own categories.
Next, I address the physical sections of the page with their own categories: header, sidebar, content, and footer for example. Lastly, I collect the page and content section specific styles and place them in their own category (and sometimes subcategories).
Another method is to categorize the styles and place them in seperate CSS files which are all imported by one main CSS file. I find this method good in theory but it can lead to overlapping styles, specification issues, and general confusion if you’re not very careful:
@import url("layout.css");
@import url("typography.css");
@import url("forms.css");
When styling multiple tags, ids, or classes with common attributes, display each on its own line. Also, indent closing braces. Both these actions keep the left column clean so you can quickly skim your stylesheet:
h2,
h3,
h4 {
font-weight: bold;
padding-bottom: 1.5em;
}
h5 {
font-weight: normal;
font-size: 1.5em;
padding-bottom: 0;
}
Use descendant selectors generously and consistently to keep your styles grouped neatly and CSS specificity in check:
#header {}
#header .logo {}
#header .logo img {}
A trick I use all the time to temporarily disable a style attribute involves simply adding an ‘x’ in front of the attribute name. It’s safer then cutting and quicker then commenting out:
#footer{
border-top: 1px solid #e5e5e5;
xborder-bottom: 1px solid #e5e5e5;
}
Quick HTML pointer. For div tags that stay open for a number of lines, add a small comment after the closing tag about the opening div’s id or class:
<div id="content">
<h2></h2>
<p></p>
<p></p>
<p></p>
<p></p>
</div><!-- end #content-->
If you have two (or more) conflicting CSS rules that point to the same element, there are some basic rules that a browser follows to determine which one is most specific and therefore wins out.It may not seem like something that important, and in most cases you won’t come across any conflicts at all, but the larger and more complex your CSS files become, or the more CSS files you start to juggle with, the greater likelihood there is of conflicts turning up.
If the selectors are the same then the latest one will always take precedence. For example, if you had:
p { color: red; }
p { color: blue; }
p elements would be coloured blue because that rule came last.
However, you won’t usually have identical selectors with conflicting declarations on purpose (because there’s not much point). Conflicts quite legitimately come up, however, when you have nested selectors. In the following example:
div p { color: red; }
p { color: blue; }
It might seem that p elements within a div element would be coloured blue, seeing as a rule to colour p elements blue comes last, but they would actually be coloured red due to the specificity of the first selector. Basically, the more specific a selector, the more preference it will be given when it comes to conflicting styles.The actual specificity of a group of nested selectors takes some calculating. Basically, you give every id selector (”#whatever”) a value of 100, every class selector (”.whatever”) a value of 10 and every HTML selector (”whatever”) a value of 1. Then you add them all up and hey presto, you have the specificity value.
p has a specificity of 1 (1 HTML selector)div p has a specificity of 2 (2 HTML selectors; 1+1).tree has a specificity of 10 (1 class selector)div p.tree has a specificity of 12 (2 HTML selectors and a class selector; 1+1+10)#baobab has a specificity of 100 (1 id selector)body #content .alternative p has a specificity of 112 (HTML selector, id selector, class selector, HTML selector; 1+100+10+1)So if all of these examples were used, div p.tree (with a specificity of 12) would win out over div p (with a specificity of 2) and body #content .alternative p would win out over all of them, regardless of the order.
20 Jul
Posted by ProCOM
on July 20, 2007 – 9:40 pm - 226 views
Hopefully you’ve played around with some HTML when you were building your custom 404 error page, as explained in our tutorial on creating your custom 404 error page , in which case this will be a breeze.
If not, it’s time to roll up your sleeves and get ready to do some coding!
The first step is to figure out which page is your custom 404 error page.
Most likely you’ve just built it, so that’s a very simple step, but if not, identify your httpd.conf file, then find the line therein that looks like this:
ErrorDocument 404 /errordoc-404.shtml
That’ll tell you what file is your 404 error page.
There are dozens of different Web page and HTML editors on the market, so your process will likely be different to what we use, but hopefully you have a tool like Homesite, BBEdit, or even vi or EMACS to edit the file and can do so directly. If not, you might need to download the HTML file from your server to your local computer then open it with a simple editor like NotePad (on Windows) or TextEdit (on the Macintosh) to proceed.
Now the fun part: copy the following lines of HTML and paste them directly into your custom 404 error page:
<form action=”http://www.google.com/search” name=”searchbox”
method=”get” style=”margin-left: 2em;” />
<input type=”hidden” name=”hl” value=”en” />
<input type=”hidden” name=”ie” value=”ISO-8859-1″ />
<input type=”hidden” name=”sitesearch” value=”programimi.com” />
<input maxlength=”256″ size=”40″ name=”q” value=”" />
<input type=”submit” value=”find it” name=”btnG”
style=”font-size:75%;” />
</form>
You need to change the domain name from programimi.com to your own domain, but that’s the only customization required. Save the changes and upload the new version of the file if needed.
Once you’ve saved your new custom 404 error page, generate a page by hitting a link like http://www.example.com/badpage and looking for the form.
That’s all there is to it. You now have a lovely Google search engine that constraints itself automatically to a search of your pages only. Now you should ensure that Google knows about your site and you might also want to fix spelling problems too. :-)
18 Jan
Posted by ProCOM
on January 18, 2007 – 10:31 pm - 202 views
Now that MSN has removed the wraps on its new search engine (beta.search.msn.com), intended to compete with both Google and Yahoo, the obvious question on the minds of SEO people everywhere is: what algorithm is MSN going to use for their pagerank calculations?
Microsoft is being predictably coy: their FAQ states: “The MSN Search ranking algorithm analyzes factors such as page contents, the number and quality of sites that link to your pages, and the relevance of your site’s content to keywords. The algorithm is complex and never human-mediated.”
Nonetheless, there are some useful tips that give you a little bit of insight into how MSN is approaching search. This is all quoted from their site, and broken into three categories.
Dave’s comment: In case MSN didn’t notice, the majority of traffic to a site are from search results, so the complexity of a URL doesn’t matter as much as they are saying here. It’s an interesting insight into their ranking criteria, imo.
You can learn more at the MSN Search Site Owner Help. Competition is always good, so it’ll be interesting to see what theories arise about how they’re ranking and ordering search results!
Forms, probably the one thing that made the internet popular among the business people. Thanks to this addition to HTML, users are able to interact with a website. Unfortunately, after web forms were first introduced, not a lot has been changed to them. However, with XForms and Web Forms 2.0 on the rise, this is probably going to change. But what are they? What are their new features? And more importantly, which one is going to be superior?
Lets start with the oldest technology: XForms. XForms 1.0 became a recommendation in late 2003 and an update, XForms 1.1, is already in development. One of the biggest advantages is that XForms is an XML namespace and can therefore be used in a lot of ways as a completely device-independant application. To understand what this means, take a look and/or read the introduction on XForms.
Now that I did my duty to give you a short introduction to XForms, lets take a look at its interesting parts: its features. XForms are always seperated into two 2 parts:
The XForm Model is used to describe the form’s data and how to submit it, while the XForm UI is used to make the form available to the user. How the XForms UI should look is not described by the XForms specification in any way, so it’s up to the user agent to render the form in the most usable way. Because of this, it makes XForms very flexible and usable for the user.
First, lets take a look at the XForm Model. This is always defined in the model element. The model can take 3 different child elements:
instance;submittion;bind.The instance element describes all the data which is to be gathered. Every piece of data gets its own element inside the instance.
The submittion element(s) describe(s) how and where to submit the data. Multiple submittion elements can be added to the model which make it possible to submit data to different servers, or using a different HTTP method. For instance, you can have 2 buttons in your form. One to save the data as a file on the server, and one to submit the data to a form which saves it in a database.
The bind element is where the actual fun begins. Using this element you can create a relation between elements. For instance, using a bind element you can specify that a certain element may only be enabled if the value of another element matches a predefined value. So if you have a form that can be used to pay for something, you can ask the user how he/she would like to pay. This could be either by Paypal, cash or credit card. In this case you can specify only to enable the input field where the user can enter the expiration date if the user selects credit card to be the payment method.
But bind also has other features. Take the type attribute for example. This attribute tells the user agent what data is allowed. Combine this with XML Schema, and you have a very powerful way of specifying what kind of data is allowed. This can vary between strings or integers, but also dates or URIs. If these are not enough, you can of course create your own schema with XML Schema for total control.
Another feature of bind is to calculate an outcome. For instance the combined value of two numbers that the user has entered, or an average, etc. The outcome of this calculation can be displayed on the page without even submitting the form data or using scripting.
Below is a small example of how a model could look like:
<model xmlns="http://www.w3.org/2002/xforms"
xsd:xmlns="http://www.w3.org/2001/XMLSchema"
my:xmlns="http://jero.net/lab/xml/ns">
<instance>
<my:to/>
<my:amount/>
<my:details/>
</instance>
<submittion action="pay-me-now.php" method="post" id="pay"/>
<bind nodeset="to" type="xsd:string"/>
<bind nodeset="amount" type="xsd:integer"/>
</model>
Because there’s no such thing as stand-alone XForm documents, the model element in the example above would normally be placed inside the xhtml:head element.
Now that we have taken a quick look at the XForm Model, lets take a look at the UI. As I said earlier in this article, XForms does not, unlike HTML, specify how the form controls should look, but what they do. That’s a major difference here, so make sure you understand that. Once you’ve got that pumped into your brain, let’s take a look at XForm’s form control elements. I will compare them with HTML’s controls to make it as easy a possible for you to understand them (isn’t that nice?). But to avoid confusion, I will refer to XForm elements as xform:element and html:element for HTML elements. If no namespace is present, you can asume that the element is part of the XForms namespace.
input element html:input element, you do not need to specify the kind of form control (input field, password, radio button etc.) because xform:input is only suitable for text. So xform:input will probably render as <html:input type="text">. All other purposes that html:input has are divided into other element which are described below. secret element <html:input type="hidden">, but instead it is the equavalent of <html:input type="password">. textarea element html:textarea. However, the cols and rows attributes are not required in XForms (as a matter of fact, they don’t even exist). For visual user agents, you can specify the dimension using CSS. output element bind element in the XForm Model to calculate something and display it on the page. Together with the ref element we can refer to a bind element to show the outcome of the bind’s calculation. upload element <html:input type="file">. range element xform:input element to let the user type the number in for himself. But with the range element you can make it the user easier to select the correct value in the range specified by the min and max attributes.. Accessibility++! However, this is of course nothing new. Just take a look at your volume control. trigger element <html:button> and <html:input type="button">. submit element <html:input type="submit"> and <html:button type="submit">. select and select1 element xform:select and select1 are pretty darn useful. These two elements are not only the equivalents of html:select, but also for checkboxes and radio buttons. All you need to do is put the available options inside the xform:select or select1 and let the user agent decide how it should look. This can be a list of checkboxes/radio buttons, drop-down list, or whatever the user agent think it’s best for the user.The difference between the two elements is that with select1 the user can only choose one value, while the user can select multiple options from xform:select elements. To give you an example of how an XForm UI may look like, take a look at the possible UI for the model we created earlier:
<group xmlns="http://www.w3.org/2002/xforms"> <label>Transfer Money</label> <input ref="to"> <label>Receiver</label> </input> <input ref="amount"> <label>Amount</label> </input> <textarea ref="details"> <label>Additional details</label> </textarea> <submit submission="pay"> <label>Transfer!</label> </submit> </group>
As you see, the group element is used to group all the payment controls. In HTML we’d normally use fieldset for this. The xform:label inside the group can be compared with html:legend as they both act as a title for the group/fieldset. The xform:labels inside the xform:input elements are used as text to describe the xform:input element. This is comparable to the function of html:label. The xform:label inside the submit element will probably be rendered as text on a button, just how <html:button>Submit!</html:button> would be rendered.
Now that I gave you some info about XForms (yes, only some as there is a lot more), lets take a look at XForms’s younger stepbrother: Web Forms 2.0 (WF2). WF2 is developed by the WHATWG which is the same group who’s developing the Web Applications 1.0 specification, aimed at extending current markup languages (HTML 4.01 and XHTML 1.0). The same applies to WF2. Unlike XForms, WF2 does not want to replace current web forms. Intead, WF2 aims at extending current web forms which has one very important advantage: backwards compatibility.
When you’d read the Web Forms 2.0 specification, you’d be delighted with the fact that because of WF2’s backwards compatibility it is very easy to pick up, especially compared to XForms which is basically a pain the ass to learn. Just take a look at the INPUT element. Yes! Exactly the same as HTML 4.01’s INPUT element, although with new values for the type attribute:
datetime, datetime-local, date, month, week and time 1996-01-01T00:00Z). When a WF2 confirming user agent would see an INPUT with either of these values for the type attribute, it could make it the user easy and display the input field as
. This way the user agent can make sure that the submitted date will always confirm to ISO 8601 and the user will have less problems with entering the date (some sites require a specific scheme like MM-DD-YYYY which would cause trouble for European users because they’re used to DD-MM-YYYY). number INPUT will only allow numbers. No explanation needed I hope… range xform:range, the html:input with the value range for type will allow the user to select a value in the range of the numbers specified by the min and max attributes. email url If you still don’t like the new values for type, you can write your own regular expression that should be used to validate the user input. This regex can be included in the pattern attribute which will be used to validate the user’s input upon submission.
Of course, the additions to WF2 do not limit themselves to input types. Take the required attribute for example. If there is a form control forgotten that has the required attribute, the user agent should not submit the data. The same applies to the type and pattern attributes if a value is submitted that does not meet its field type.
Another new element we see in WF2 is the DATALIST element. This element allows the author to specify a list of default values for, for instance, a text field which will have a somewhat similar effect as your browser’s address bar. Once you click on the arrow at the right of it, a list of IRIs which you previously visited appear. You can think of the DATALIST element to contain such a list of options which can be selected by the user in the INPUT is he wishes to do so.
And I could go on and on and on about all the new features in both specifications. I didn’t even talk about Web Forms 2.0’s repetition model, XForms’s Repeat Module and the new events! However, doing all this research on these two forms did made me understand the two a lot more. Not only did I learn about the new stuff they bring, but also that it’s not 100% fair to compare the two with each other. First of all, the Web Forms 2.0 is still a Working Draft while XForms 1.0 is already a W3C Recommendation since October 2003. The WF2 specification also says that Web Forms 2.0 aims to simplify the task of transforming XForms 1.0 systems into documents that can be rendered on HTML Web browsers that do not support XForms.
Therefore we can’t really talk about two competing standards.
However, I think it’s clear that both are at least much, much better than the forms we have now. XForms of course being the more powerful of the two. Its power is incredible thanks to the powerful XML functions that allow the use of multiple namespaces in the same document. However, due to the lack of native support for XForms (only Firefox 1.5+) and XML in general (Internet Explorer), it’s going to take a long time until we can use this awesome namespace.
And that’s the sole reason why WF2 was born: because we have to wait for such a damn long time. Thanks to WF2’s backwards compatibility, we can use most of XForms’ features without discriminating legacy browsers like Internet Explorer because WF2 support is not needed to complete the form. The only advantage that WF2 adds is the fact that forms become a lot more usable for the user when the user’s browser supports WF2. Hopefully modern browsers like Firefox, Opera and Safari can use WF2 to win more users.
However, in the long run, I don’t see WF2 surviving. I still think XForms is a lot better, and once it gets proper support, I’m sure we can say goodbye to WF2. Now don’t get me wrong on this. I still think that WF2 is a great extension to current web forms until the browsers ship with native XForms support and I can’t wait for Firefox to support it.
As we all know, the table element shouldn’t be used for styling your document. The div element should be used instead, together with the id and class attribute to style it with CSS, just like the HTML 4.01 and XHTML 1.0 specs tells us to do. But aren’t we polluting our markup with these div elements, because we’re only using them for presentational purposes?
First, let’s take a look at an example. Here’s the HTML code of the top of previous layout:
<div id="logo">
<h1>Programimi.com</h1>
<hr>
</div>
As you see, I wrapped the site name and a hr element inside a div element. But the div element has absolutely no purpose in my document instead of having the id attribute and using CSS to style it. So by using divs, you don’t separate presentation from structure at all, nor does it have any semantic value, just like the font and center elements.
One might argue that the div element can be used to divide the document into sections. If this were true, the div would have a real purpose. Unfortunately, it isn’t. Just take a look at what the HTML 4.01 specification says about the element:
The
divandspanelements, in conjunction with theidandclassattributes, offer a generic mechanism for adding structure to documents. These elements define content to be inline (span) or block-level (div) but impose no other presentational idioms on the content. Thus, authors may use these elements in conjunction with style sheets, thelangattribute,etc., to tailor HTML to their own needs and tastes.
Ok, the spec does talk about adding structure, but that’s actually quite vague, don’t you think? What kind of structure do they mean!? Because the W3C didn’t give any real information on how the div element can give structure to a document that can also be understood by user agents, “adding structure” is actually not possible because no-one understands how it is structurized. The only possible way to do so is by using the id attrubute, but the value of this attribute can only be understood by humans, not user agents. Therefore, it’s still impossible to give structure to a document by using the div element so the only reason to use the element is to group certain elements together in order to style them (or give it a lang like the quoted piece from the HTML 4.01 spec says, but who uses the attribute anyway!?).
So should we just ditch the div element? I guess not. You should, but it would be impossible to make a decent layout at the moment. Which I, as a web designer, enjoy looking at. Another reason would be because we don’t have any alternatives. Well, not yet. Just take a look at the header element, introduced by HTML, or XHTML 2’s role attribute. By using either one of the methods instead of the div element from my previous example at the beginning of this article, that section will actually have a meaning. In other words, the document will become semantically richer.
If you have a website, it is most likely that your server is using Apache as its web server software. Apache has a nice feature that provides the ability to customize configuration directives defined in the main configuration file using a file called .htaccess. In this article I’d like to discuss how you can use the .htaccess file to pimp up your website.
Lets start with my personal favorite: mod_rewrite. It’s an extension module that allows you to mask URIs. An example: I have the URI http://domain.com/contact to point to my contact form, but there’s no file called contact. The URI to my contact form points to an ugly WordPress generated URI with some PHP variables. This can be done with the following configuration:
RewriteEngine On
RewriteRule ^contact/?$ /wordpress/index.php?name=$1
Many also use mod_rewrite to redirect anyone who accesses their website with the www subdomain to the bare domain name, because the www subdomain is just pointless as described on no-www.org. Here’s the configuration for .htaccess to achieve this effect (this code can also be found at no-www.org):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
If you’d like to learn more about this module, do to Apache’s documentation about mod_rewrite.
Using this is absolutely a must. You can allow the server to compress the HTML using gzip and send it to the browser (if it supports gzip, unlike IE). The browser receives it, decompresses it and shows the page like it would normally do. This will definitely reduce your bandwidth. The front page of this website was around the 10KB before I used gzip to compress my pages, and now it is around 3,50KB. mozilla.org has a nice page for a more detailed description about gzip compression. Here???s the configuration to use gzip compression for your HTML files: (Yes, it’s just one line.)
php_value output_handler ob_gzhandler
AddDefaultCharset directiveHow does a user agent know which character encoding has been used? The server should provide this information. The most straightforward way for a server to inform the user agent about the character encoding of the document is to use the “charset” parameter of the “Content-Type” header field of the HTTP protocol ([RFC2616], sections 3.4 and 14.17).
That’s what the HTML 4.01 Specification tells us about defining the character encoding. Yet, many people still use the meta element for this purpose. The meta element also sends an HTTP header, but when the browser parses the document, it has to guess character encoding to parse the beginning of the document because the character encoding is only defined later on, in the head element. So it\ s much better to configure your server to send the HTTP header before the file is being parsed. You can use the .htaccess file for this as well, with the AddDefaultCharset directive. The configuration below configures the server to send all documents with the UTF-8 encoding:
AddDefaultCharset utf-8
Learn more about the AddDefaultCharset directive.
ErrorDocument directiveI guess this is probably the most well known directive, but I’d like to put it in this article anyway. With this directive you can specify what file should be shown when a certain HTTP Status Code has been sent. So if a user agent tries to access a file on a server that does not exist, the server responds with the 404 Status Code. You can use the ErrorDocument directive to show a custom error page instead of Apache’s boring default page. Here’s an example configuration to define a custom error page for when a 404 error code has been sent:
ErrorDocument 404 /error-docs/404.html
Get more info about the ErrorDocument directive.
Those were the directives I currently use in my .htaccess file. But of course, there are a lot more. Most of them are explained at the page Apache Core Features. If you have any other .htaccess tricks that you find very useful, feel free to post them.