Wednesday, January 30, 2008

Detailed Look at Stacking in CSS

Using the z-index to affect stacking order in CSS is a much deeper topic than it may appear at first. The idea seems quite simple, but if we take a look we can see that there is actually quite a bit going on here that warrants a closer examination.

Most of the time, stacking order just kind of works behind the scenes and we don't really pay any attention to it. However, once we use relative or absolute positioning to move an object around the screen, we will end up with several elements occupying the same space. Which element is displayed on top is determined by the elements stacking order. We can adjust an elements stacking order by using the z-index property.

The z-index is so named because it affects an elements position along the z-axis. The z-axis is the axis that goes from front to back from the user. If we think of the x-axis and y-axis as height and width, then z-axis would be the depth. The higher the z-index of an element, the closer it becomes to the user, and the lower the z-index, the further back on the screen it appears.

If we do not specify any z-index values, the default stacking order from closest to the user to furthest back is as follows:

  1. Positioned elements, in order of appearance in source code

  2. Inline elements

  3. Non-positioned floating elements, in order of appearance in source code

  4. All non-positioned, non-floating, block elements in order of source code

  5. Root element backgrounds and borders


Based on the default stacking order above, you can see that any element that has been positioned, whether relative or absolute, will be placed above any element that is not positioned. Both positioned and non-positioned elements are of course, above the background of our root element.

Mixing Things Up A Bit


Now let's say we want to move some of our elements around in the stacking order so different elements appear on top. We can use the z-index property on any positioned elements to adjust there stacking order. The z-index property can accept an integer, the auto value, or an inherit value. When using integers, the higher the positive number, the further up in the stacking order it will appear. You can use negative z-index values to move the element further down in the stacking order. If we do not use a z-index value on an element, it will render at the rendering layer of 0 and will not be moved. The stacking order now looks like this:

  1. Positioned elements with z-index of greater than 0, first in order of z-index from lowest to highest, then in order of appearance in source code

  2. Positioned elements, in order of appearance in source code

  3. Inline elements

  4. Non-positioned floating elements, in order of appearance in source code

  5. All non-positioned, non-floating, block elements in order of source code

  6. Positioned elements with z-index of less than 0, first in order of z-index from highest to lowest, then in order of appearance in source code.

  7. Root element backgrounds and borders


Stacking Context


An interesting thing happens though when we set a z-index value to 0 or auto...we establish a new stacking context. Let's say we set #front to have a z-index of 5. Now, we have just established a new stacking context for any element descending from (contained in) #front. If #middle is contained within #front, and I set its z-index to 2, it should still appear above #front. Why? Because since we set a z-index value to #front, every descendant of #front is now being stacked in relation to #front. It may be helpful to look at this as a multiple number system (as demonstrated by Eric Meyer in CSS: The Definitive Guide):





  1. #front 5.0

  2. #middle 5.2



Since #front is the ancestor that sets the stacking context, it's relative stacking level can be thought of as 0. Now when we set the z-index for middle, we are merely setting it's local stacking value. Of course 2 is higher than 0, and therefore even though in our CSS it looks like #middle should be displayed behind #front, we can see that actually it should be displayed on top.

For an example, consider the following code:





  1. <div id="one">

  2. <div id="two"></div>

  3. </div>

  4. <div id="three"></div>



Now, using CSS we position these elements so that there is some overlap:





  1. #one{

  2. position: absolute;

  3. left: 0px;

  4. top: 20px;

  5. z-index: 10;

  6. }

  7. #two{

  8. position: absolute;

  9. left: 50px;

  10. top: 30px;

  11. z-index: 15;

  12. }

  13. #three{

  14. position: absolute;

  15. left: 100px;

  16. top: 30px;

  17. z-index: 12;

  18. }



Z-Index Example

The result is that #two shows up below #three, even though the z-index value we gave it (line 11) is higher than the z-index value we gave #three (line 17). This is because #two is a descendant of #one, which established a new stacking context. Which means if we use our numbering system, we would get the following stacking order:





  1. #three 12

  2. #two 10.15

  3. #one 10.0



Firefox Gets It Wrong


Ok...that felt weird to say. We are all used to Firefox getting most CSS things right, but this is one area it gets wrong. According to CSS 2.1, no element can be stacked below the background of the stacking context (the root element for that particular context). What this means is if we adjust the CSS above to give our #two element a negative z-index, the content of #one should overlap over the content of #two, but the background color should not. The way IE renders this is correct. Both results are shown below:

Z-Index Example

You can see that in IE, while the content of #one is still set above the content of #two, the background color remains behind it, as specified in CSS 2.1. Firefox on the other hand, shoves the entire #two element, background color and all, behind #one. Until this is fixed, be careful about using negative numbers for the z-index of an element.

Go Forth and Experiment


Definetely take this and play around with it. This is a topic that is best understood by setting up some positioned and non-positioned elements and experimenting with different z-index values. If you are feeling bold, check out the W3C's really detailed breakdown of the stacking order of not just elements, but their background colors, background images, and borders. As with most topics in CSS, there is more here to understand than we first realize.

Monday, January 28, 2008

Develop for the Next Guy

All developers at one point or another will have to work with code that they didn't develop. Whether we are replacing the person who created the application, or simply trying to work on a project developed by someone else in house, this is always a bit of an interesting experience. It becomes necessary to familiarize ourselves with the existing coding techniques used on the project so that we can quickly edit and maintain it for our purposes.

Unfortunately, this is often a total mess of a job. The code we have to work with is often quite long, poorly documented, looks like ancient Greek, and leaves us angrily spewing silent (perhaps in some cases not so silent) insults at whoever the poor person was who created this mess. Not only does this leave us frustrated, but it also can frustrate our employers, as projects that should've been easily taken care of now require much more time and effort.

Here then, are a few practices you can start using now to ensure that the next guy working on your application isn't hoping for your demise.

Start Commenting


This is one practice that should be ingrained in your head from your early on in your development career. In addition to making the code easier for you to navigate in a month or two, effective commenting can also make it much easier for a new developer working with your code to understand what is going on. Any section of code that may require more explanation (functions in particular), should have a comment explaining what is going on there.

It can also be useful in some cases to explain why a particular solution was used instead of another one. If when developing, you found that one solution resulted in better performance than another, comment about it. A person just trying to understand your code may not realize that there is a performance benefit to your code, and ditch it in favor of something he/she is more familiar with.

Use Descriptive Names


Few things are more frustrating to someone trying to work with your code than coming across blocks like this:





  1. var j = 0;

  2. var a = getData();

  3. for (var i=0; i < a.length; i++) {

  4. var x = a[i].getName();

  5. if (x === 'John') {

  6. j++;

  7. }

  8. }



Granted, a simple for loop like above is not to difficult to follow, but what exactly are the variables, a, j, and x? This may seem to save you some typing initially, but coming back to this in a few months will drive you crazy. Variable names should make some sense.





  1. var counter = 0;

  2. var employees = getData();

  3. for (var i=0; i < employees.length; i++){

  4. var firstName = employes.getName();

  5. if (firstName === 'John'){

  6. counter++;

  7. }

  8. }



Just by using better variable names, we have made the code much easier to understand. Even to someone completely unfamiliar with your application, it is easy to tell that we are looping through a bunch of employees, and counting how many of them have a first name of 'John'. Not so easy to tell in our first example.

Be Consistent


This goes for naming conventions as well as formatting. Come up with a set way of naming variables and stick to it. Don't have my_variable on one line, and then otherVariable on the next. If you are going to use underscores, stick to underscores. If you want to use camel casing, then use camel casing on each of your variables. It makes it much easier to tell at a glance what values are variables in your code.

When you are declaring functions, decide how you want to display them. Some people like to use the following format:





  1. function getName()

  2. {

  3. ...

  4. }



Others will use stick the opening bracket of a function on the same line as the initial declaration.





  1. function getName(){

  2. ...

  3. }



It doesn't really matter which method you use, just so long as you continue using it throughout your code.

Utilize Common Design Patterns


Design patterns are solutions to specific programming problems that have been documented and allows developers not to have to solve the problem again and again. They provide us with a way of quickly communicating the method used to resolve a problem. Common design patterns, like the factory pattern or the singleton pattern, have the added benefit of being used by programmers of various different languages. Now anyone who recognizes the pattern used can tell right away what is being done, it's just a matter of figuring out the exact syntax of the specific language being used.

Be careful with this one though. Don't just use a design pattern to be using design patterns. If you make sure your code can benefit from the use of a design pattern, then go ahead and implement one. Otherwise, you will just end up with over-engineered code that is more complicated than it may need to be.

Make it Flexible


Make sure your methods are flexible and can be used in a variety of different ways. You never know the different uses that may be required of your application in the future. Make sure your methods are built in a way that the data returned is then able to be used in various solutions. For example, let's look at some very simple Javascript that involves getting an employee's name and outputting it to a div.





  1. function getName(employee){

  2. var myDiv = document.getElementById("divName");

  3. var employeeName = employee.name;

  4. myDiv.innerHTML = employeeName;

  5. }



This works perfectly fine for our solution. What happens though if in 3 months, we decide that we actually want to use the name in an alert instead? Now we have to go back, find our getName function and rework it. Instead, if we make the getName function more flexible, we can allow future developers to use it however they choose.





  1. function getName(employee){

  2. return employee[i].name;

  3. }



Separate the retrieval of information from the usage of it. It makes the code more flexible, and much easier to adjust in the future.

These are just five simple techniques you can use to ensure that your code is easier both to understand and to adapt for the next guy who comes along and has to modify it. It also has the added benefit of making your life a little easier when several months down the road, your boss tells you to change some of the functionality. It is now easy to both understand what the code is doing, and how to make it do what you want.

Tuesday, January 22, 2008

IE's Questionable Version Targeting

There has been an awful lot of talk around the web community about Microsoft's new feature in IE8 - version targeting. Initially, I hated the idea. However, instead of jumping in blindly, I thought it deserved a more detailed look on my part.

What Is It?


Version targeting, as proposed by Microsoft, will use a X-UA-Compatible declaration, either via a META tag or as a HTTP header on the server, to determine which rendering engine the page will be displayed in. For example, the META tag below will tell IE to use the IE8 rendering engine to display the page:

If IE8 comes across a site that doesn't have this declaration either in a META tag or as a HTTP header, than it will render the page using IE7's rendering engine. This idea is not entirely new. DOCTYPE declarations have been switching IE browsers from 'quirks mode' to Web Standards mode since, I believe, IE6. There were some limitations with this. While using a DOCTYPE ensured standards mode, there is a definite difference in what standards mode is in IE6 versus in IE7.

The X-UA-Compatible declaration is meant to be more robust. Here, we can tell the browser exactly which version of IE to render the page in, thereby alleviating us from the headaches that may be caused by a different rendering engine in IE8 than in IE7 for example. We can also use the 'edge' keyword (which is apparently not recommended) instead of declaring a specific version. The 'edge' keyword is used below:

By using the 'edge' keyword, we are telling IE to always use the most current rendering engine available. This basically gives us the option of ignoring IE's new feature. However, this seems like a flawed idea, because as Jeremy Keith said "...even if you want to opt out, you have to opt in."

Some Problems


I agree with Keith in thinking that the idea was implemented wrong. The X-UA-Compatible declaration should be a tool to use, not a required feature. If I want my site rendered in the newest version of IE, I shouldn't have to tell it that. It should assume that unless I tell it otherwise, I want my site rendered with the most current rendering engine, not the other way around. I guess I understand how from a business perspective this makes sense, this way everything works at least as well as before. However, for a community that puts so much emphasis on progressive enhancement, this doesn't seem to fit the mold.

I am also not so sure that this is any better than using conditional comments. If I can develop for standards supporting browsers and then use conditional comments to "fix" the other ones, than what benefit do I really get from using the X-UA-Compatible declaration? Also, what happens years down the road, after IE9 and IE10 are released? If I am one of those people still using IE8 at that time, and I come across a site that declares it should render in IE10, how will IE8 handle that? I would like to assume it would just render it using the highest version it knows (IE8 can only render IE8 or lower so an IE9 declaration results in IE8). Of course that just brings us back to using hacks again to ensure the older browsers still show our site reasonably well, and then we're back at the beginning.

I would also be interested to see if this is going to result in substantial code bloat for IE. If IE10 is potentially supporting four different rendering engines (quirks mode, standards mode in IE7, IE8, IE9) how is this going to affect the size of the browser code? I could see this potentially resulting in a pretty hefty amount of disk space being required in the future as more and more engines are being supported.

Not All Bad


The idea is not totally off base. It offers a nice feature, we don't have to scramble to make sure our sites don't break in the newest version of IE. I just think that it should be an optional feature...I either use the declaration and therefore ensure that my code will be rendered as always, or I don't use it and allow progressive enhancement to work it's magic.

I still say kudos to IE for trying a new idea out. If nothing else, this has gotten the community discussing the advantages and disadvantages of Microsoft's proposed solution, as well as talking about other routes we could take. Even after looking at it in more detail though, I just don't think this is going to help solve much of anything. I don't know that there is that big of an advantage offered by it, and I just don't think that other browser vendors will think it is worth their time. Who knows though? Maybe in five years, people will be looking at this post and remarking about how short-sighted I was. I guess time will tell.

Don't Take My Word For It


This is a very opinionated topic that has generated some great discussion already across the web. I encourage you to check out some of the varying opinions and arguments presented in the posts below:

Monday, January 21, 2008

Display a Link's Href When Printing

Using print stylesheets are a nice way to enhance a user's experience of a site. Our screen stylesheets don't necessarily turn out that nicely when printed out, so using a few different CSS rules on our print stylesheet we can increase readability and usability.

One of those nice features we can add is to display a link's href directly after the link on our print-outs. This will allow someone who has printed out the page to still be able to know where the links on the page are pointing to. We can do this with CSS by using the :after psuedo-class and some generated content.





  1. a[href]:after{

  2. content: " [" attr(href) "] ";

  3. }



There are really four important parts of the statement above:

  1. a[href]: Here, we use an attribute selector to select all links in our page with an href attribute.

  2. :after: The :after pseudo-class allows us to insert some content after the links and style it if necessary.

  3. content: This is what actually generates the content. We could just insert, for example, the letter "a" with a style call like content: "a".

  4. attr(href): This gets the href attribute of the link currently being styled. This way, each link will display it's own href.


If we put this style in our print stylesheet, all of our links that actually have an href will print out like this: TimKadlec.com [http://www.timkadlec.com]

Obviously, this is a pretty handy enhancement to our print stylesheets. Now, the links printed out actually have some meaning to them. The problem is, Internet Explorer doesn't support the :after pseudo class, nor does it support the content style. So if a user is using Internet Explorer and tries to print our page out, they still won't see any href's displayed.

Javascript to the Rescue


We can use a little bit of browser specific Javascript to fix this problem. Internet Explorer (version 5.0 and up) has a little known proprietary event called onbeforeprint. Just like it sounds, this event fires right before printing a page or viewing a print preview of the page. Since IE is the only major browser that doesn't create the effect using CSS, a proprietary event is the perfect fix. Now, we can draw up a simple function like so:





  1. window.onbeforeprint = function(){

  2. var links = document.getElementsByTagName("a");

  3. for (var i=0; i< links.length; i++){

  4. var theContent = links[i].getAttribute("href");

  5. if (!theContent == ""){

  6. links[i].newContent = " [" + theContent + "] ";

  7. links[i].innerHTML = links[i].innerHTML + links[i].newContent;

  8. }

  9. }

  10. }



Our function simply gets all the links on a page, and appends their respective href's immediately after them, creating the same effect that we were able to do using CSS in other browsers. You might be wondering why we set the new content we created to be a property of each link. That's because right after printing or canceling out of the print preview screen, we are now seeing the href on our actual web site. We obviously don't want this, and it's simple enough to get rid of with another IE proprietary function, onafterprint.





  1. window.onafterprint = function(){

  2. var links = document.getElementsByTagName("a");

  3. for (var i=0; i< links.length; i++){

  4. var theContent = links[i].innerHTML;

  5. if (!theContent == ""){

  6. var theBracket = theContent.indexOf(links[i].newContent);

  7. var newContent = theContent.substring(0, theBracket);

  8. links[i].innerHTML = newContent;

  9. }

  10. }

  11. }



Here we just again, loop through all the links, find the position of the new content we added, and remove it from the link. This returns the appearance of our site to the original view before trying to print.

Obviously, it would be ideal if we could simply use CSS to manage this. However, as we've seen, there is no need to wait for IE to support this feature before we implement it. Some proprietary Javascript events allow us to replicate the effect until it is supported later on.

The script/css effect has been tested in IE7, Opera, Firefox, and Safari. If you are interested, the complete Javascript to create the effect in IE is here: printlinks.js

Thursday, January 17, 2008

Branching Out

Utilizing branching in Javascript can allow us to create more efficient code. Branching essentially allows us to create "conditional" functions at run-time so we don't have to keep running the same verifications each time a function is called. That last sentence is probably as clear as mud, so let's take a look at an example.

A very common check to perform is whether a browser supports the getElementById() method, like so:





  1. if (!document.getElementById) return;

  2. var myContainer = document.getElementById('container');



That is just a very simple verification. We check to see if the browser recognizes the getElementById() method. If it doesn't, we quit what we are doing and don't go any further. If it does, we continue on with our code. It can be quite annoying to have to type out document.getElementById each time you have to use it, so let's create a shorter helper function.





  1. var id = function(attr){

  2. if (!document.getElementById) return undefined;

  3. return document.getElementById(attr);

  4. }

  5. var myContainer = id('container');



Above, we create an id function that checks to see if the browser supports the getElementById() method, and if it does, it returns the value for us. There are two major benefits here. First, our function does the check for us to ensure the method is supported. Secondly, it's less typing; instead of having to type document.getElementById() each time we want to get an element, we can just type id().

However, let's say that we have a pretty intensive script here and we have to use the id method let's say 20 times. That means that 20 times over the course of our script, we are running a check to see if the browser supports the method, when we already know the answer after the first time we ran the check. Obviously, that isn't very ideal.

Using branching, we can make the check once on runtime, and then return a function that doesn't require checking anymore.





  1. var id = function(){

  2. if (!document.getElementById){

  3. return function(){

  4. return undefined;

  5. };

  6. } else {

  7. return function(attr){

  8. return document.getElementById(attr);

  9. };

  10. }

  11. }();



The key here is the parentheses after our function declaration (line 11). This makes the function run right away as soon as the browser sees it.

So while loading the page, the browser comes across this function and runs it. If the getElementById method is supported, it assigns a function that returns the element to the id variable. If the browser does not support the getElementById method, than it assigns a function that returns an undefined value to the id variable.

It may help to look at it this way. By using branching in our function above, we have essentially applied one of two functions to our id variable:





  1. // if getElementById is not supported

  2. id = function(){

  3. return null;

  4. }

  5. // if getElementById is supported

  6. id = function(attr){

  7. return document.getElementById(attr);

  8. }

  9. //Example usage

  10. var myContainer = id('container');



So now, when we are getting the element using the id function, it doesn't run the check to see if it is supported, because it doesn't need to. If we use our id function 20 times, the browser support check is only performed once: initially as the script is being loaded.

It is important to note that branching is not always going to provide a performance increase. Using branching results in higher memory usage because we are creating multiple objects. So whenever you consider using branching, you need to be able to compare the benefits you will get from not having to run the comparison over and over versus the higher memory usage that branching requires. However, when used properly, branching can be a very handy tool for optimizing your Javascript performance.

Friday, January 11, 2008

Don't Be Ashamed of Your Code

I came across a post the other day by Guy Davis about 3 Levels of Programmers. In it, he stated that programmers fall into one of 3 Levels, the Good, the Lazy, and the Bad. According to his post, the bad are those that say "I can do that myself!", and then create a solution that is rather messy. The lazy are those that don't build from scratch and instead find existing solutions. The good are those who are the ones creating the frameworks and libraries.

While he admits in his comments that he was mainly venting against as he calls them "weak build-it-yourselfers" I thought it brought up an unfortunate opinion that at times seems to rise up in this industry. Now please note, I am not trying to pick on Guy Davis at all. There are some very valid points raised in his post, and as I stated before, he does admit he was mainly venting. I am sure all of us have vented about such things before.

Developers sometimes give a cold shoulder to developers whose code is not up to par. This is an unfair judgment though. Particularly in an industry as fast moving as the web development industry is, you cannot afford to wait until you are an "expert" to code. You have to code using the best ways you know how, and continue to learn. This means that there are undoubtedly some projects you wish you could pretend you never touched. I know I have them.

I think that a better classification is to broaden it out a bit and say there are two kinds of developers. The first kind are those that are content just getting the job done. They are not particularly concerned with how it is taken care of, so long as it functions relatively well. If they have to use inline Javascript to create an effect, then so be it. They don't push themselves to learn more and find better ways of doing things, they just accept that what they do works well enough and why would they ever need to progress further.

The second type of developer, however, is never satisfied with where they are at. Yes, they will use the knowledge they have to get the job done, which results in some unseemly coding at times. But they know that they have more to learn, and are constantly pushing themselves to find a better method of doing it. These are the types of developers that push the industry forward. They will take their bumps and bruises along the way, but they will continue to further their understanding and knowledge of whatever skill it is they are using.

This doesn't mean that they always develop the solution themselves, or never use libraries or frameworks. Sometimes the best solutions are libraries. It simply means that this kind of developer is always wondering, is there a better way to accomplish this.

Therefore, I say if you are new to a language, be it CSS, Javascript, PHP, or whatever else, don't be ashamed of the code you produce. As long as you are trying to learn more and come up with more fool-proof and efficient ways of developing, there is nothing to be embarrassed about.

If you asked some of the biggest names in web development today if they had ever done a project using coding methods they aren't exactly proud of, I am sure the answer would be "yes". If everyone thought that someone smarter out there would develop a better solution, the industry would become quite stagnant.

Sunday, January 6, 2008

Getting Specific With CSS

One very fundamental and integral part of CSS is understanding specificity. Understanding this basic concept can help to make your CSS development, and more specifically (no pun intended) your troubleshooting go more smoothly.

Every rule in CSS has a specificity value that is calculated by the user agent (the web browser for most web development purposes), and assigned to the declaration. The user agent uses this value to determine which styles should be assigned to an element when there are more than one rule for that particular element.

This is a basic concept most of us have at least a general understanding of. For example, most developers can tell you that the second declaration below carries more weight than the first:


  1. h1{color: blue;}

  2. h1#title{color: red;}



If both styles are defined in the same stylesheet, any h1 with an id of 'title' will of course be red. But just how is this determined?

Calculating Specificity


Specificity in CSS is determined by using four number parts. Each type of value in the style declaration receives some sort of specificity rate:

  • Each id attribute value is assigned a specificity of 0,1,0,0.

  • Each class, attribute, or pseudo-class value is assigned a specificity of 0,0,1,0.

  • Each element or pseudo-element is assigned a specificity of 0,0,0,1.

  • Universal selectors are assigned a specificity of 0,0,0,0 and therefore add nothing to the specificity value of a rule.

  • Combinator selectors have no specificity. You will see how this differs from having a zero specificity later.


So going back to our previous example, the first rule has one element value, so its specificity is 0,0,0,1. The second rule has one element value and an id attribute, so its specificity is 0,1,0,1. Looking at their respective specificity values, it becomes quite clear why the second rule carries more weight.

Just so we are clear on how specificity is calculated, here are some more examples, listed in order of increasing specificity:


  1. h1{color: blue;} //0,0,0,1

  2. body h1{color: silver;} //0,0,0,2

  3. h1.title{color: purple;} //0,0,1,1

  4. h1#title{color: pink;} //0,1,0,1

  5. #wrap h1 em{color: red;} //0,1,0,2



You should also note that the numbers go from left to right in order of importance. So a specificity of 0,0,1,0 wins over a specificity of 0,0,0,13.

At this point, you may be wondering where the fourth value comes into play. Actually, prior to CSS 2.1, there was no fourth value. However, now the value furthest to the left is reserved for inline styles, which carry a specificity of 1,0,0,0. So, obviously, inline styles carry more weight than styles defined elsewhere.

It's Important


This can be changed, however, by the !important declaration. Important declarations always win out over standard declarations. In fact, they are considered separately from your standard declarations. To use the !important declaration, you simply insert !important directly in front of the semicolon. For example:


  1. h1.title{color:purple !important;}



Now any h1 with a class of 'title' will be purple, regardless of what any inline styles may say.

No Specificity


As promised, I said I would explain the difference between no specificity and zero specificity. To see the difference, you need a basic understanding of inheritance in CSS. CSS allows us to define styles on an element, and have that style be picked up by the element's descendants. For example:


  1. h1.title{color: purple;}


  2. <h1 class="title">This is <em>purple</em></h1>




The em element above is a descendant of the h1 element, so it inherits the purple font color. Inherited values have no specificity, not even a zero specificity. That means that a zero specificity would overrule an inherited property:


  1. *{color: gray} //0,0,0,0

  2. h1.title{color: purple;}


  3. <h1 class="title">This is <em>purple</em></h1>



The em element inherits the purple font color as it is a descendant of h1. But remember, inherited values have no specificity. So even though our universal declaration has a specificity of 0,0,0,0, it will still overrule the inherited property. The result is the text inside of the em element is gray, and the rest of the text is purple.

Hopefully this introduction to specificity will help make your development process go smoother. It is not a new concept, or a terribly difficult one to learn, but understanding it can be very helpful.

Wednesday, January 2, 2008

Using Prototypes in Javascript

As mentioned in my previous post, I think using prototypes is powerful enough to deserve a more detailed explanation. To start off, let me say we are talking about the prototype method here, not the JavaScript library.

Prototypes allow you to easily define methods to all instances of a particular object. The beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it. Let's use the Pet object that we created in the previous post. In case you don't remember it or didn't read the article (please do) here is the object again:





  1. function Pet(name, species){

  2. this.name = name;

  3. this.species = species;

  4. }

  5. function view(){

  6. return this.name + " is a " + this.species + "!";

  7. }

  8. Pet.prototype.view = view;

  9. var pet1 = new Pet('Gabriella', 'Dog');

  10. alert(pet1.view()); //Outputs "Gabriella is a Dog!"



As you can see, by using simply using prototype when we attached the view method, we have ensured that all Pet objects have access to the view method. You can use the prototype method to create much more robust effects. For example, let's say we want to have a Dog object. The Dog object should inherit each of the methods and properties utilized in the Pet object and we also want a special function that only our Dog objects have access to. Prototype makes this possible.





  1. function Pet(name, species){

  2. this.name = name;

  3. this.species = species;

  4. }

  5. function view(){

  6. return this.name + " is a " + this.species + "!";

  7. }

  8. Pet.prototype.view = view;

  9. function Dog(name){

  10. Pet.call(this, name, "dog");

  11. }

  12. Dog.prototype = new Pet();

  13. Dog.prototype.bark = function(){

  14. alert("Woof!");

  15. }



We set up the Dog object, and have it call the Pet function using the call() method. The call method allows us to call a specific target function within an object by passing in the object we want to run the function on (referenced by 'this' on line 10) followed by the arguments. Theoretically, we don't need to do this. We could just create a 'name' and 'species' property inside of the Dog object instead of calling the Pet function. Our Dog object would still inherit from the Pet object because of line 12. However that would be a little redundant. Why recreate these properties when we already have access to identical properties inside of the Pet object?

Moving on, we then give Dog a custom method called bark that only Dog objects have access to. Keeping this in mind consider the following:





  1. var pet1 = new Pet('Trudy', 'Bird');

  2. var pet2 = new Dog('Gabriella');

  3. alert(pet2.view()); // Outputs "Gabriella is a Dog!"

  4. pet2.bark(); // Outputs "Woof!"

  5. pet1.bark(); // Error



As you can see, the Dog object has inherited the view method from the Pet object, and it has a custom bark method that only Dog objects have access to. Since pet1 is just a Pet, not a Dog, it doesn't have a bark method and when we try to call it we get an error.

It is important to understand that prototype follows a chain. When we called pet2.view(), it first checked the Dog object (since that is the type of object pet2 is) to see if the Dog object has a view method. In this case it doesn't, so it moves up a step. Dog inherits from Pet, so it next checks to see if the Pet object has a view method. It does, so that is what runs. The bottom most layer of inheritance is actually from the Object.prototype itself. Every object inherits from that. So, in theory we could do this:





  1. Object.prototype.whoAmI = function(){

  2. alert("I am an object!");

  3. }

  4. pet1.whoAmI(); //Outputs 'I am an object!'

  5. pet2.whoAmI(); //Outputs 'I am an object!'



Since all objects inherit from the Object.prototype, pet1 and pet2 both can run the whoAmI method. In short, prototype is an immensely powerful tool you can use in your coding. Once you understand how prototype inherits, and the chain of objects it inherits from, you can start to create some really advanced and powerful object combinations. Use the code examples used in this post to play around with and see the different ways you can use prototype to create more robust objects. With something like this, hands-on is definitely the best approach (at least I think so!).