SpeciFISHity: CSS Specificity

Some people are confused by CSS Specificity, especially with all of the (not-so) new CSS3 Selectors. The image below may help make sense of CSS Specificity.

X-0-0: The number of ID selectors, represented by Sharks
0-Y-0: The number of class selectors, attributes selectors, and pseudo-classes, represented by Fish
0-0-Z: The number of type selectors and pseudo-elements, represented by Plankton a la Spongebob
*: The universal selector has no value

Download the specificity chart and read the rest of the SpeciFISHity article here

Placeholder Attribute Support in ALL browsers

Included along with jQuery, the following code allows you to include the HTML5 placeholder attribute work in older browsers. The idea is to find all the input elements that have a placeholder attribute that the browser is ignoring since it doesn’t understand. Check to see if the input value is empty. If it is empty, include the placeholder value temporarily as the value (preferably making it look like a placeholder). If the user focuses on the input, clear the placeholder value, which is the default behavior in browsers that support the placeholder value. When the user exits the input box, the script checks to see if there is a value. If not, reinstate the value of the placeholder.

The second script is for when the user submits the form: we want to make sure that the form is not alwasy submitting the placeholder value. The main issue with this function is that the user cannot actually enter data that matches the placeholder, so, if you’re going to use this function, make sure that the placeholder value is not one that a user would intentionally submit. For example, use ‘first name’ and ‘last name’ for names, rather than ‘john’ and ‘doe’. Use ‘phone number’ or ‘415.555.1212’ for phone numbers, and other implausible values, etc.

  //make HTML5 placeholders work in non supportive browsers
  $("input[placeholder]").each(function(){
    if($(this).val()==""){
     // $(this).addClass('hasplaceholder');
      $(this).val($(this).attr("placeholder"));
      $(this).focus(function(){
        if($(this).val()==$(this).attr("placeholder")) $(this).val("");
       // $(this).removeClass('hasplaceholder');
      });
      $(this).blur(function(){
        if($(this).val()==""){
	  // $(this).addClass('hasplaceholder');
           $(this).val($(this).attr("placeholder"));
        }
       });
    }
  });

$('form').submit(function(evt){
	$('input[placeholder]').each(function(){
		if($(this).attr("placeholder") == $(this).val()) {$(this).val('');}
	});
});

Here are the lines explained:

Finds and iterates thru each input with a placeholder attribute:
$("input[placeholder]").each(function(){

Checks to see if the value is empty
if($(this).val()==""){

Commented out, you can add this line to add a class to the inputs that currently don’t have a value, so you can stylize them to look like placeholders (in other words, change the color to light grey using CSS):
// $(this).addClass('hasplaceholder');

Find the value of the placeholder attribute and sets it as the value of the value attribute
$(this).val($(this).attr("placeholder"));

Create an onFocus event handler
$(this).focus(function(){

When focused, checks to see if the current value matches the value of the placeholder. If so, it clears the placholder
if($(this).val()==$(this).attr("placeholder")) $(this).val("");

If you included the class to stylize the placeholder look and feel, remove it when the user is focusing on this input
// $(this).removeClass('hasplaceholder');

Close out the onFocus event handler
});

Create an onBlur event handler for when the user exits the input box
$(this).blur(function(){

Check to see if the input box is empty (the user has NOT entered any data)
if($(this).val()==""){

If the value is empty, we’re going to not just put the placeholder in, we should also include a class to be able to stylize it as a placeholder would look:
// $(this).addClass('hasplaceholder');

Put the value of the placeholder in the value — as we did on page load above.
$(this).val($(this).attr("placeholder"));

Close out all the set up stuff
}
});
}
});

We also need to ensure that the element has a legitimate value when the form is sumbitted:

We create an onSubmit event handler:
$('form').submit(function(evt){

We go thru all the inputs that have the placeholder attribute:
$('input[placeholder]').each(function(){

If the current value matches the placeholder value, we clear it before sumbitting:
if($(this).attr("placeholder") == $(this).val()) {$(this).val('');}

We close out the function:
});
});

Note that if the element is ‘required’, the submit function would be different and we would test to see if the browser supports the placeholder attribute before doing any of this, but i am just providing a small snippet to show how easy (and possible) it is to make older browsers support HTML5 form features.

HTML5: Introduction to <canvas>

Canvas: Tutorial of basic canvas functionality, canvas properties and methods

The HTML5 Canvas specification is a JavaScript API for coding drawings. The canvas API allows the definition of a canvas context object as the <canvas> element on your HTML page inside which we can draw.

We can draw in both 2D and 3D (WebGL) context. 2D is available in all the modern Web browsers, IE9, and via excanvas.js in current versions of IE, and will be more thoroughly introduced below. 3D is still nascent, with only experimental implementations.

2D context provides a simple yet powerful API for performing quick drawing operation, on a 2D bitmap surface. There is no file format, and you can only draw using script. You do not have any DOM nodes for the shapes you draw — you’re drawing pixels, not vectors. OK, not true. You are drawing vectors, but once drawn, only the pixels are remembered.

Your first <canvas>

Being a very basic introduction to canvas, we are only going to cover basic shapes and lines. If you are unfamiliar with JavaScript, the syntax may at first seem a bit confusing. If you are familiar, it should make sense.

Step 1 is adding the <canvas> element to your document. In terms of HTML, the only step involved in adding a canvas to your document is adding the <canvas> element to your document:

<canvas id="flag" width="320" height="220">
You don't support Canvas. If you did, you would see a flag
</canvas>

That is it for the HTML part of it. . We could simply have written <canvas></canvas>. However, you should include an id for ease of JavaScript targeting, but you could also target via placement within the DOM. You can also define the width and height of the canvas, though you can define that in the CSS as well. We’ve also included alternative content for users that don’t support or otherwise can’t see your <canvas> content

With that, we’ve created your blank drawing board, or canvas. Everything else takes place in our JavaScript files. Step 2 is drawing on our canvas. From now on, everything is in javascript. We target the canvas node with getElementById(‘flag’) or getElementsByTagName(‘canvas’)[0], initialize a 2D context and start drawing using 2D context API commands. We can draw the Japanese flag:

<script>
var el= document.getElementById("flag");

if (el && el.getContext) {
var context = el.getContext('2d');
if(context){
context.fillStyle = "#ffffff";
context.strokeStyle = "#CCCCCC";
context.lineWidth = 1;
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 4;
context.shadowColor = 'rgba(0, 0, 0, 0.4)';
context.strokeRect(10, 10, 300, 200);
context.fillRect(10, 10, 300, 200);
context.shadowColor='rgba(0,0,0,0)';
context.fillStyle = "#d60818";
context.arc(160, 107, 60, 0, Math.PI*2, false);
context.fill();

}
}
</script>

The first line finds your <canvas> element by matching the element’s id attribute. Before creating the 2D context, we check to make sure that the canvas element has been found AND that the browser supports canvas by checking for the existence of the getContext method.

We have to then create a reference to a context using the getContext(contextId) method of the canvas element –‘2d’ and ‘3d’ are the contextId value choices. If context creation is successful, we are finally free to draw in our canvas.

Before drawing a shape, we must define the look and feel of the shape we want to draw by setting properties on the context object. We define the look of the border (stroke and linewidth) properties and the shadow of our first rectangle, which we draw with the strokeRect() method. We pass the same parameters as our SVG example: (10, 10, 300, 200). The four values are the x-offset, the y-offset, width and height respectively. Once the script executes a command, the script forgets about what it has done, and moves onto the next line of code. Unlike our SVG example, the rectangle we’ve drawn on our canvas is not part of the DOM.

When we draw our second rectangle using the fillRect method, which paints rectangles using the previously set fillStyle property, we need to pass the coordinates again as the DOM does not remember our first rectangle, though it can access pixel information.

Both rectangle method calls have the same parameters — 10, 10, 300, 200 — we’ve drawn our fill rectangle directly on top of our dropshadow rectangle. We could have created an object with those coordinates and passed it to both methods, but we can’t tell the canvas to access the first rectangle’s coordinates and copy to the second after the method call

As mentioned above, once you paint onto the canvas, the DOM has no recollection of what you’ve painted. Yes, the JavaScript remembers the values of the properties you’ve set, but the pixels that are places on the canvas are just pixels of color. As we start the process of drawing the disc or sun on our flag, the DOM has no recollection of which pixels were painted with which colors, but it does remember some properties we set, like our shadowColor. As we don’t want a shadow on the red circle, we can set the shadowColor to transparent.

Next we define our circle. We are not actually drawing the circle yet. context . arc(x-offset of center, y-offset of center, radius, startAngle, endAngle, anticlockwise) adds points to an arced path creating a virtual circumference of a circle described by the arguments, starting at the given start angle, in our case 0, which is on the right horizon, and ending at the given end angle, going in the given direction, which in our case is clockwise. Had our endAngle been less than 2Π, our circle would have been flattened: the start and end points connected by a straight line. Π would have created a half circle. We also re-define the fill color, from white to red. We then paint the circle we created using the fill() method that fills the described arc in the fillStyle color.

We haven’t even touched the surface of what <canvas> can do. http://ie.microsoft.com/testdrive/Graphics/CanvasPad/Default.html is a fun page to learn simple shapes, colors, shadows, text, images, transformation, animation and mouse movement with <canvas>.

Canvas functions and properties

Styles

Set the fillStyle

context.fillStyle="color"

Set the strokeStyle

   context.strokeStyle="color"

Line widths

   context.lineWidth=number

Line join styles

   context.lineJoin="bevel || round || miter"

Line end styles

   context.lineCap="butt || round || square"

Rectangles

Draw a rectangle

   context.strokeRect(left, top, width, height)

Fill a rectangle

   context.fillRect(left, top, width, height)

Erase a rectangle

   context.clearRect(left, top, width, height)

paths

Begin a path

   context.beginPath

Complete a path

   context.closePath

Move the pen to a location

   context.moveTo(horizontal, vertical)

Draw a straight line from current point to a new location

   context.lineTo(horizontal, vertical)

Stroke the current path

   context.Stroke()

Fill the current path

   context.fill()

Shadows

Shadow color

   context.shadowColor="color"

Shadow horizontal offset

   context.shadowOffsetX=number

Shadow vertical offset

   context.shadowOffsetY=number

Shadow blur

   context.shadowBlur=number

Canvas versus SVG

HTML5 Canvas and SVG may seem similar, in that they are both web technologies that allow you to create rich graphics inside the browser, but they are fundamentally different. In SVG, you ‘draw’ with XML. For canvas, you draw with JavaScript. Canvas is the painting of pixels onto a canvas, once painted, each pixel is forgotten. SVG, on the other hand, creates DOM nodes, accessible until deleted or until navigation away from the page. They both have their advantages and disadvantages.

SVG is resolution independent, making SVG an excellent choice for user interfaces of all sizes as it allows scaling for all screen resolutions. SVG is an XML file format enabling easy accessibility. SVG can be animated using a declarative syntax, or via JavaScript. Each element becomes part of and is accessible via the SVG DOM API in JavaScript. However, anything that accesses the DOM repeatedly slows the page down.

Canvas is all drawn in pixels. Zooming can lead to pixilation. Canvas is inherently less accsessible: accessibility is limited mainly to including fallback content should canvas not render. Interactivity requires redrawing of each pixel. There are no DOM nodes for anything you draw. There’s no animation API, instead timers are generally used for updating the canvas at quick intervals. Canvas gives you a surface to draw onto with the API of the context you choose. Canvas, however, is very well suited for editing of images, generating raster graphics such as for games or fractals, and operations requiring pixel-level manipulation. Canvas can also be exported to gif or jpeg.

CSS3 Implementable Features

There are several features of CSS3 that are implementable today. In this presentation we discuss CSS3 Selectors, Text Shadows, Box Shadow, Rounded Corners (prefixed), @font-face, Alpha Transparency, Opacity, Rotation. Mostly, there are links to my sandboxing of those features.

If it’s not successfully embedded, you can see it here css3 implementable features

Content covered in the PPT presentaion

I do not have a podcast, but here is a summary of what was presented in case you missed it, or incase the flash above isn’t enough

CSS3: Si se puede

CSS2.1

has been around since 1999, but only fully supported in IE8. We obviously didn’t wait to implement CSS2 until all the browsers fully supported it. CSS3, while not yet finalized, has a lot of features that are supported in many browsers. Like CSS 2.1, there is no reason not to use these features just because not all browsers support all the features equally: if that were our logic, we would still be on CSS1.

Your site does not need to be identical in all browsers

In developing with CSS3 think about graceful degradation. Not all browsers need to implement your site identically. Yes, your site should look good in all browsers, but no, if your body is a few pixels different in one browser to the next, who cares? You’re the only one who is going to be looking at your website in multiple browsers at the same time. 99.99% of the site user base (that number is pulled out of my ass) have one favorite browser on their desktop, and that’s what they’ll use to look at your site.

Twitter uses rounded corners for non IE browsers only

Example: Twitter uses native rounded corners for supporting browsers.

IE does not support rounded corners. Twitter believes that rounded corners make their site look nicer, but lack of them doesn’t break the site. So, the experience is a little different in the IE’s than in modern browsers. But if I hadn’t shown you this example, you may never have known!

Twitter would have had a difficult time creating rounded corners with images since the background color of the right hand nav bar on twitter is user selectable. They could have created rounded corners on the left and square angles on the right, but likely going all square for IE looked better.

For the rest of the examples, I’ll be explaining how to make CSS3 work in IE. I just want to spread the gospel that it doesn’t have to look identical anyway.

Features that are implementable and discussed below:

  • CSS3 Selectors
  • Text Shadow (2.0).
  • Box Shadow (prefixed)
  • Rounded Corners (prefixed).
  • @font-face
  • Alpha Transparency.
  • Opacity.
  • Rotation.

Features that are implementable, but not discussed in this talk

  • Multi-column layout
  • Video (HTML5)
  • Animations
  • Transitions
  • Border-image
  • Multiple background images
  • Linear Gradients

CSS3 Selectors

If you look at the grid of CSS3 Selectors and Browser Support, you’ll note that, at this point, only the three IEs don’t understand CSS3 selectors. That doesn’t mean you can’t use them.

To see all the selectors, and what you can and cant use, check out CSS3 Selectors and Browser Support

Alpha Tranparency

color: rgba(0,0,0,0.4);
color: hsla(300, 100%, 50%, 0.4);

HSL stands for hue, saturation and lightness. The HSL format simplifies color palette creation as you can pick a hue as the base, then manipulate the lightness/darkness and saturation of the hue selected.

HSL is a new color type added in CSS3, stading for hue, saturation and lightness. The syntax is similar to rgb(), but instead of including the values for red, green and blue, the color value accepts values in degrees from 0 to 359 for hue, and percentages for saturation and lightness, with 50% being the norm for lightness and 100% being the norm for saturation. Lightness of 0% will be white, 50% will be the actual hue, and 100% will be black. Saturation of 100% will be the hue, and saturation of 0 will give you a shade of grey from white to #808080 to black depending on the lightness.

Values for hues include: 0 = red, 60 = yellow, 120 = green, 180 = cyan, 240 = blue, 300 = magenta, and everything in between.

Similar to rgb() with rgba(), hsl() also has an alpha transparent call, hsla(). the syntax is hsla, followed by hue in degrees, saturation in percentage, lightness in percentage and alphavalue from 0-1, encompassed in parenthesis.

For example: hsla(300, 100%, 50%, 0.5) is magenta at 50% opacity.

Opacity

Opacity likely doesn’t have the impact you intended. The element made less that fully opaque is not the only element impacted. All the element with a z-index higher than the one made opaque inherit the same level of transparency. Generally, you’ll want to use alpha transparency on a background rather than opacity.

  .halfthere {
       opacity: 0.4;
       filter: alpha(opacity=0.4)
   }

Opacity Example

Rounded Corners

.rounded {
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;
   }

The order is topleft, topright, bottomright, bottomleft.

Safari has some issues with rounded corners.

IE6, IE7 and IE8 don’t support native CSS rounded corners, and never will. For those browsers, if I really don’t want my page to look different in the IEs than in modern browsers, I add the rounded corners with a little bit of JavaScript and CSS magic, and a single background image:

$('.rounded').append('<b class="tr"></b><b class="tl"></b><b class="br"></b> <b class="bl"></b>');

Text Shadow

.shadowed {
  text-shadow: 3px 3px 3px rgba(0,0,0,0.4);
  }

In the above, the order of values is

leftOffset rightOffset blur Color

If you’re going to use text shadow, which is not supported in IE, this is a good time to use the Hack for CSS3 Supporting Browsers. As I mention in that article, you don’t want to end up with white text on white background.

Rotation

Transforms are supported in all browsers, just with different syntax.

    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    transform: rotate(90deg);
    filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);

Note that for IE, the values are 1=90, 2=180, 3=270. Check out my

sandbox, or just look at the header of this blog.

I’ve been told that IE supports more than just the 90degree angles, but haven’t tested yet. The syntax is:

     filter:  progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',
                     M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17); /* for IE6 and IE7 */
         -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand',
                     M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17)"; /* for IE8 */

and make sure that the element hasLayout.

Gradients

I didn’t actually go over gradients in my presentation, but linear gradients are  supported in one way or another in all browsers except opera, so you can use them. Radial gradients …. not yet.

background-image: -moz-linear-gradient(top, #56abf3, #ffffff, #ffffff, #ffffff); /* FF3.6+ */
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #56abf3),color-stop(25%, #ffffff));

IE has

Filter: progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#FF56abf3, endColorstr=#FFFFFFFF)

There are two types of Gradients – 0 gives a gradient running from top to bottom. 1 from left to right.
startColorstr —  The start color of the gradient. The first 2 characters in the 8 digit HEX color number are the Alpha values ( 00 being transparent,  FF is opaque). Default is blue
endColorstr= —   The color of the bottom or right  end of the gradient, depending on what GradientType you use. The default color is black  #FF000000 if omitted.

There are no colorstops in IE as far as i can tell

CSS Background Properties: possible values, default values, browser support and DOM

Everything you could possibly want to know about CSS Background Properties: Interpreting the w3c specifications with browser support and links to examples and test cases.

Last Major Update: May 26, 2011

There are 8 attributes controlling background images. The CSS3 background properties are very well supported in modern browsers, but a few values are not. Also, there are some properties and values that have not yet made it into the specifications, but are already supported in all browsers except Firefox.. This blog post goes over all the existing and future attributes, targeting them with the DOM, and lets you know of bugs you may find when implementing backgrounds.

  • background-attachment
  • background-color
  • background-image
  • background-position
  • background-repeat
  • background-clip
  • background-origin
  • background-size
  • background-inline-policy – (not in the specifications)
  • shorthand: background, which includes the above attributes that are in the specifications.
  • Each property has a list of possible values. Many developers use the “background:” shorthand. I advocate against using the shorthand, as I spend a lot of time correcting other people’s code when they forget to declare all the possible values, and therefore inadvertently set some of the attributes to their default values, when that was not their intention. For example, in th CSS reset script I recommend, the reset sets background-repeat: no-repeat;. When this reset value is included, if a coder writes background: url(myImg.gif); the background-repeat value gets reset to the default value of repeat — repeating along the x and y axis — which is almost never the intended value. Note that none of the background properties are inherited by default, though several do have “inherited” as a value option. See below for more information on the background shorthand.

    default IE6 IE7 IE8 IE9 IE10 FF 3.6 FF 4 FF 5 Safari Chrome Opera
    background-attachement CSS2.1 Χ Χ
    fixed   Χ Χ
    scroll default
    inherit
    local CSS3 Χ Χ Χ Χ 5
    background-color CSS2.1 Δ Δ Δ
    transparent default Δ
    rgb(r, g, b)  
    #fff
    #ffffff
    rgba(r, g, b, a) CSS3 Χ Χ Χ
    hsla() CSS3 Χ Χ Χ
    140+ named colors
    CSS3                      
    background-image  
    none default     1 1 1 1
    url  
    url, url CSS3 Χ Χ Χ 3.6
    background-position  
    left/top default
    right/bottom
    center default when only one declaration
    inherit
    center
    px
    %
    multiple 
    CSS3 Χ Χ Χ 3.6
    4 Values
    CSS3 Χ Χ Χ Χ Χ Χ Χ Χ Χ Χ
    background-position-x not in the spec Χ Χ Χ Χ
    background-position-y not in the spec Χ Χ Χ Χ
    background-repeat  
    inherit
    no-repeat
    repeat
    repeat-x / repeat-y
    multiple images Χ Χ Χ
    space Χ Χ Χ Χ Χ Χ
    round Χ Χ Χ Χ Χ Χ
    x / y values separate Χ Χ Χ Χ Χ Χ
    background-clip CSS3 Χ Χ Χ Δ -webkit-
    border-box Χ Χ Χ Δ
    padding-box Χ Χ Δ
    content-box Χ Χ Χ Δ
    background-origin CSS3 Χ Χ Χ Δ
    border-box Χ Χ Δ
    padding-box default Χ Χ Δ
    content-box Χ Χ Χ Δ
    background-size CSS3 Χ Χ Χ -moz-
    auto default -moz-
    contain Χ Χ Χ -moz-
    cover Χ Χ Χ -moz-
    (length) Χ Χ Χ -moz-

    background-attachment

    The background-attachment attributes sets whether the background-image scrolls with the the document or remains fixed at the same location within the viewport. For example, if you include a “fixed” background image in a div, as the div scrolls up the page, the background image will stay in the same spot relative to the viewport, and will exit off the bottom edge of the div, disappearing from view, as the div moves up the screen. The default value is scroll. IE6 is the only browser that fails to support it correctly.

    Property Values for background-attachment

    background-attachment: fixed | scroll  | local;
    

    Browser support for background-attachment

    Internet
    Explorer 6
    Internet
    Explorer 7
    Internet
    Explorer 8
    Internet Explorer 9 Firefox Opera Chrome Safari
    fixed behaves as “scroll” behaves as “scroll” works, but the placement of the image is off.
    scroll behaves as “local” behaves as “local”
    local Works because it inherits scroll, which erroneously renders as local. Works because it inherits scroll, which erroneously renders as local. 10.5 5

    background-attachment:fixed;

    In elements with background images that are background-attachment:fixed; the position of the fixed image is relative to the viewport (the browser), not the element that it is in. In other words, if you declare a fixed background image, the image is positioned relative to the document window rather than relative to the element. Because of this, as you scroll thru the page, and your element with the background image that is fixed moves thru the viewport, the background image will come into view as it passes over the location of the otherwise hidden background image.

    Note: background-attachment: local is a new value added in CSS3. “Local” is basically how “scroll” has been acting on scrolling elements in IE6 and IE7. An example is a div with "overflow: scroll.” Generally, as you scroll thru to div, the background image stays exactly where it was initially in the scrolling div’s viewport. Using local, the div’s background image scrolls with the element’s content. In the case of ’scroll’, the background does not scroll with the element’s content, except in non-compliant IE6 and IE7. In the case of ‘local’, the background scrolls along with the element’s content.

    Mobile Note: Mobile webkit does support fixed, but it doesn’t behave as you might expect. Smart phones show websites thru a viewport, displaying just a portion of the webpage. As you scroll, you are moving the viewport, not the actual page. So, the fixed background image is doing what it should, but it doesn’t look like you would expect.

    Bugs:

    • IE8 does suppord fixed and not local, but get’s the positioning of the background image wrong.
    • IE6 and IE7 mistakingly renders fixed as scroll and scroll as local. Since scroll is the default, scroll renders as local, and the browser ignores the keyterm local, you can actually use local in these browsers as it will render local correctly.

    DOM

    document.getElementById("myID").style.backgroundAttachment

    background-color

    The background-color property sets the background color of the element. This attribute, like all other background attributes, is NOT inherited. If you set a background image that is a transparent gif, transparent PNG, or gradient with transparency,, the declared background color will show thru the transparent pixels.

    All browsers support background colors.

    The default value is “transparent”. In using RGB instead of Hex values, you can either use integer range 0 – 255 or percent values of 0-100%. If you go over (for example, 300 or 110%), the browsers will reduce the value to the maximum allowable value (either 255 or 100%).

    Note that if you mix RGB between integer and percents, some browsers will fail. If you include the wrong number of characters in a hex value, some browsers will ignore the declaration. If you misspell a named color, the browser will ignore the declaration.

    CSS3 provided us with new colors. Any valid value for color is valid for the value of background-color. For example, you can set the opacity or transparency level of the background color using background-color: rgba(255, 255, 255, 1);, where 255 is an integer between 0 and 255 or a percent value, and the 1 is any value between 0 and 1, with 0 being completely transparent and 1 being completely opaque. test page

    Property Values for background-color

    background-color: transparent | rgb(255, 255, 255) / rgb(r%, g%, b%) | rgba(255, 255, 255, 1) /  rgba(r%, g%, b%, 1)  | #fff | #123456 | magenta;

    Browser support for background-attachment

    IE6 IE 7 IE 8 IE 9 IE10 FireFox Safari Chrome Opera
    transparent
    rgb(r, g, b) Renders with mixed values Renders with mixed values
    #fff
    #ffffff
    rgba(r, g, b, a) ignores the entire call ignores the entire call ignores the entire call  
    hsl(h, s, l) ignores the entire call ignores the entire call ignores the entire call  
    hsla(h, s, l, a) ignores the entire call ignores the entire call ignores the entire call  
    named colors didn’t test      

    Note:

    • Do not using mixed values (percents and integers) in RGB. This is against the specifications, and will fail in all modern browsers.
    • IE6 and IE7 get “partially compliant” for RGB, since they erroneously display color if integers and percents are mixed. This may be a good thing, but it’s not in the specifications. test page
    • Do not use RGBA without browser targeting: color will fail in non-supporting browsers.
    • Bug: IE6 sometimes completely chokes on background-color: transparent. For example, if you declare background-color: transparent on pop-out in a suckerfish menu, the links in that menu will not be clickable and it will display as black.
    • Named colors have been expanded to include many new colors. Check out my list of named, hsl, hex and rgb colors.

      DOM

      document.getElementById("myID").style.backgroundColor
      

    background-image

    The background-image property allows us to define none, one or more background images for an element. This property only declares what image or gradient, if any, should be used. Other properties on this page can be used to define the position, movement, size, etc., or your declared images.

    In CSS3, an element can have multiple background images or layers. Separate each layer/image background image with a comma. When more than one image/layer/gradient is defined, the last image is drawn below all other layers and the first one is drawn on top, with each layer displayed in front to back order in between.

    Note that background images are not limited to jpegs, gifs and pngs. Browsers support data URIS, and (almost) all supporting gradients and some are supporting inline SVG.

    Property Values for background-image

    background-image: inherit | none | url(relative to CSS) | [gradients];
    background-image: url(relative to css), url(second image); // CSS3 allows for multiple background images.

    Browser support for background-image

    IE 6 IE 7 IE 8 IE 9 IE 10 FireFox Safari Chrome

    Opera

    inherit if url doesn’t work, neither does inherit if the background image on parent doesn’t work, neither does inherit if the background image on parent doesn’t work, neither does inherit      
    none      
    url needs to have adequate size to work IE7 zoom function does not increase the size of background images IE7 zoom function does not increase the size of background images      
    url, url 3.6     10.5
    gradient -ms- -moz- -webkit- -webkit

    -o-

    background-image browser bugs

    IE6 has several bugs with background images that are worth noting.

    1. The area of an element with a background-image must be at least 2500 pixels, or the image may not display. Fix by giving area or hasLayout=true.
    2. The repeated background image position starts and ends at the inside of the border and is therefore not seen thru a dashed or dotted border. Compliant browsers start the image at 0 0, but repeat it thru the border on all sides.
    3. For background images on links, IE6 fetches the image from the server for every “hover”, causing flickering.
    4. IE6 does not handle transparency of PNGs. Use proprietary filter to get around this bug
    5. If the background-image of a link is a transparent PNG, the link will not work in IE6.
    6. Using background images on <li>, <dd> and <dt> the background image may not render, especially if the list is placed within a floated, relatively-positioned parent.

    IE7 and IE8 has bugs too:

    1. The IE7 zoom function does not increase the size of background images.
    2. Same as IE6, in IE7 and IE8 the repeated background image position starts and ends at the inside of the border and is therefore not seen thru a dashed or dotted border. Compliant browsers start the image at 0 0, but repeat it thru the border on all sides.

    Gradients

    Browsers are beginning to support gradients as background image values. See my CSS Gradients Library and Library of World Flags in CSS Gradients as examples. The syntax differs in Safari 5 (and slightly in FF 3.6) from the standard, and all browsers that support gradients support gradients only as a prefixed value.

    I’ll be posting a tutorial on gradients shortly, so am not including details here.

    SVG as Background image

    There are two ways to include SVG as background images. Either point to an svg file as you would to any jpg file: Old Example of SVG as bgimage

    or you can include the SVG directly in the background image call.

    background-image: 
     url("data:image/svg+xml;utf8,
       <svg xmlns='http://www.w3.org/2000/svg'>
       <linearGradient id='gradient'>
       <stop offset='1%' stop-color='#F00'/>
       <stop offset='90%' stop-color='#C33'/>
       </linearGradient>
       <rect fill='url(#gradient)' x='0' y='0' 
       		width='100%' height='100%'/>
       </svg>"); }

    Note that spacing was added for legibility. All spacing must be removed for SVG to work. example of svg as background URI

    DOM

    document.getElementById("myID").style.backgroundImage
    

    background-position

    In CSS2.1 background position takes two: left and top (in that order!) of the background image. If you only declare one attribute, the outcome depends on the type of value used (percent, measurement or keyword). The default value is “top left”, well, actually, “0 0″.

    NOTE: If you are using anything other than the keyterms, make sure the order is LEFT and TOP in that order.

    Property Values for background-position

    background-position: bottom | center | inherit | left | right | top | 10px 10px | 50%  50%;
    background-position: 0 0, 50% 50%, 100% 100%; /* multiple placements */

    In CSS3 we can have up to 4 values for a single image’s background-position!!!

    If only one value is specified, the second value is assumed to be ‘center’. For example, background-position: bottom; will position the image centered at the bottom of the element. When using lengths instead of keyterms, the value refers to the horizontal positioning, so background-position: -20px; will position the background image centered veritally, with 20px of the background image being cut off the left hand side of the element.

    If two values are given and they’re not both keywords, the first value represents the horizontal position and the second represents the vertical position as an offselt from the top left corner of the element (background origin determines is its the top left corner of the outside of the border, inside of the border or inside the padding.

    New to CSS3, we can include three or four values for background-position, enabling us to position a background image relative to the bottom right of the element.

    Let’s start by explaining the four value property value, since the 3-value value is insanely confusing. The default of background-position is to offset your background image from the top left corner. Use four values to set your own offset corner. the syntax with an example:

    background-position: [bottom | center  | left | right ][length][bottom | center  | left | right ][length];
    background-position: bottom 40px right 20px;

    Pick one side, then list the offset from that edge, then include a perpendicular side and the offset from that second edge.In our example, the background image will be positioned 40px from the bottom and 20px from the right toward the bottom right of our element.

     

    If three values are given, 2 values must be keyterms and the missing offset is assumed to be zero. Currently only Opera supports 3 and 4 value background position. And, if you get any part of the syntax wrong (like try to offset from center which is not allowed), the entire declaration will be ignored. Because the 3-value syntax is confusing and prone to error, I recommend defining the 4 value whenever offsetting from any corner other than the top left corner. JS Fiddle Example

    Browser support for background-position

    IE 6 IE7 IE 8 IE 9 !E 10 Firefox Opera Chrome Safari iPhone
    left/top
    right/bottom
    center
    inherit
    center
    px
    %
    mulitple     since 3.6 10.5
    4-value offset 11

    Note that background position with percent values can be confusing! A background-position of X% will place the pixel that is X% from the left of the image at the pixel that is X% of the way in from the left of the element in which it is placed.

    • For 0, the 0%, or left/top most pixel, will be placed at 0%, or the left/top.
    • For 100%, the 100%, or right/bottom most pixel of the bg image, will be placed at 100%, or bottom/right of the element.
    • For 50%, the middle of the image will be placed in the center of the element.

    Any other percentage value is a bit more confusing:

    A background-position of 25% will place the pixel that is 25% from the left of the image at the pixel that is 25% of the way in from the left of the element in which it is placed. If your image is 1000px wide, the pixel at 750px will be placed 75% in. In an element that is 1000px wide, it will be placed at 0,0. If your parent is 2000px, the pixel at 75% is 1500, so the 1000px background image will go from px 750 to 1750. Likely, that’s not what you want.

    Because of this, know the width of the image and the width of the element before using percent (other than 0, 50% and 100%) when creating liquid layouts. If you have a content area that is 80% of the viewport, to put a faux column background image for a 25% width column, create a background image with a ratio of 1:3 that is wide enough to cover a wide scree browser., and place the background-position-x: 20%; (80% * 25% = 20%).

    DOM

    document.getElementById("myID").style.backgroundPosition
    

    Background-position-x

    Although not part of the W3C specifications, backgroundPositionX and backgroundPositionY are part of the DOM and supported by some browsers. Colors are different in the following table, since green means the browser follows the W3C specifications and red means it fails, and these values are not in the specifications.. This property was added by MS for IE5.5, made it into the CSS3 specifications for a while, but was removed in 2009. Test case

     

    Property Values for background-position-x

    background-position-x: center | inherit | left | right | px/em | %;

    Browser support for background-position-x

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox Chrome Safari Opera
    % Supported Supported Supported Supported Supported Supported
    px (length) Supported Supported Supported Supported Supported Supported
    left / center /right Supported Supported Supported Supported Supported Supported

    DOM

    document.getElementById("myID").style.backgroundPositionX
    

    background-position-y

    Property Values for background-position-y

    background-position: bottom | center | inherit | top | 10px | 2em | 50%;

    Browser support for background-position-y

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox Chrome Safari Opera
    % Supported Supported Supported Supported Supported Supported
    px (length) Supported Supported Supported Supported Supported Supported
    left / center /right Supported Supported Supported Supported Supported Supported

    DOM

    document.getElementById("myID").style.backgroundPositionY
    

    Background-repeat

    The backround-repeat property specifies whether the background image is repeated or tiled. And, if so, how that image is tiled. The default value is repeat, which repeats the image along both the x and y axis. Since this is generally NOT the effect I go for, i include background-repeat: no-repeat in my CSS reset.

    There are two new values for background-repeat: space and round. Space means the image is repeated as many times as can fully fit, separated by white space if repeating does not create an exact fit. Round means the image is repeated as often as will fit. If it doesn’t fit a whole number of times, the background images are rescaled so they do.

    You can also declare different values for the x and y axis. While this new feature is in the specifications, it is not supported yet in Firefox.

     

    Property Values for background-repeat

    background-repeat: inherit | no-repeat | repeat | repeat-x | repeat-y;
    IE 6 IE 7 IE 8 IE 9 IE 10 Firefox Chrome Safari Opera
    inherit
    no-repeat
    repeat
    repeat-x / repeat-y
    multiple comma separated values
    space
    round
    separate x/y values

    DOM

    document.getElementById("myID").style.backgroundRepeat
    

    background-clip

    With possible values of border-box | padding-box, the background-clip property determines whether the background position is relative to the border or the padding, specifying whether an element’s background extends underneath its border. This only has any visual effect when the border has transparent regions (because of border-style) or partially opaque regions; otherwise the border covers up the difference. The default value is “border”, which is the effective default of all current browsers. Firefox 3 supports -moz-background-clip. Safari’s implementation is -webkit-background-clip.
    Supporting browsers also support content-box, which is not in the CSS3 specifications at this time. Border box is the default. Webkit uses both -webkit-border and -webkit-border-box. Firefox uses -moz-background-clip, and does not include the term ‘box’ in the value. The syntax may change.

    Property Values for background-clip

    background-clip: [border-box | padding-box ] [ , [border-box | padding-box ] ]* ;
    -moz-background-clip: border;
    -webkit-background-clip: border-box;

    Browser support for background-clip

    IE 6 IE 7 IE 8 IE9 IE 10 Firefox 3.6 Firefox 4 Chrome Safari 4/5 Opera
    border-box     -moz-: border   -webkit- -webkit-
    padding-box     -moz-: padding   -webkit- -webkit-
    content-box         -webkit- -webkit-

    Notes:

    IE 7 (in yellow) behaves like background-clip:padding if overflow property is set to hidden, auto or scroll.

    FF 3.6 is both prefixed, and supports values of border and padding (not border-box | padding-box)

    Safari 4 is both prefixed, and supports values of border, padding and content (not border-box | padding-box | content-box)

    DOM

    document.getElementById("myID").style.backgroundClip
    

    background-origin

    The background-origin property determines how the ‘background-position’ is calculated. Takes one or two parameters: border-box | padding-box | content-box. With a value of ‘padding-box’, the position is relative to the padding edge (‘0 0′ is the upper left corner of the padding edge, ‘100% 100%’ is the lower right corner). ‘Border-box’ means the position is relative to the border edge, and ‘content-box’ means relative to the content edge.

    Each comma-separated value applies to one image of ‘background-image’. This is useful only in safari at this point… but haven’t tested to see if supported. Safari’s current implementation is -webkit-background-origin. Mozilla is supporting -moz-background-origin. Has no impact when background attachement is set to fixed.

    Unlike clip, the value of content-box is in the proposed specifications.

    Note that the spec has changed. Mozilla and webkit have support, but use the original value terms of border | padding | content instead of the currect proposed specifications border-box | padding-box | content-box.

    Property Values for background-origin

    background-origin: [border-box | padding-box | content-box ] [ , [border-box | padding-box  | content-box] ]* ;
    -moz-background-origin: border; /* does not yet support multiple images, so no support for multiple values */
    -webkit-background-origin: border-box, padding-box, border-box;

    Browser support for background-origin

    IE 6 IE 7 IE 8 IE9 IE 10 Firefox 3.6
    -moz-
    Firefox 4 Safari 3
    -webkit-
    Safari 4 Safari 5 Chrome Opera
    border-box     border   border -webkit-      
    padding-box     padding   padding -webkit-      
    content-box     content   content -webkit-      

    Sandbox: Background-clip in action

    DOM

    document.getElementById("myID").style.backgroundOrigin
    

    background-size

    Supported by Opera, Safari and Chrome, and Firefox , the background-size property specifies the size of the background images. The ‘contain’ values scales the image, while preserving its aspect ratio (if any), which may leave uncovered space. The ‘cover’ scales the image so that it covers the whole area, completely covering the element, but perhaps not showing part of the image if the element and the image did not have the same aspect ratio.
    see background-size specifications at the W3C

    Note that you still need to use the -moz- prefix if you’re supporting FF3.6 and the -webkit- prefix if for some unexplainable reason you’re still supporting Safari 4.

    Internet Explorer 6 Internet Explorer 7 Internet Explorer 8 Internet Explorer 9 Firefox 3.6 Firefox 4 Chrome Safari Opera
    auto -moz-
    contain -moz-
    cover -moz-
    (length) -moz-

    DOM

    document.getElementById("myID").style.backgroundSize
    

    The background shorthand.

    The background shorthand (or shortcut) attribute enables the declaration of all five background attributes in one statement. Before CSS3, the values could be in any order, but were generally in the color, image, attachment, position and repeat order. If an attribute value is not specified, the value gets reset to the default value, which is why I recommend against using the shorthand.

    If you use the background shorthand and fail to declare any of the individual properties that make up the shorthand, those properties will revert to their default values listed below:

     

    	background-color: transparent;
    	background-position: 0% 0%;
    	background-size: auto auto;
    	background-repeat: repeat repeat;
    	background-clip: border-box;
    	background-origin: padding-box;
    	background-attachment: scroll;
    	background-image: none

    If you are declaring several background images using the shorthand property, the background color, if declared, should be declared as part of the shorthand of the final image only.

    Since they have the same value syntaz, if one <box> value is declared, then both the ‘background-origin’ and ‘background-clip’ are set to that value. If two values are present, then the first sets ‘background-origin’ and the second defines the ‘background-clip’ property.

    Property Values and order for the background shorthand

    background: background-image | background-position / background-size | background-repeat  | background-attachment | backgroun-origin | background-clip | background-color 
    background: url(myImg.jpg) bottom 20px right 20px / 200px 100px no-repeat fixed red;
    background: url(myImg.gif) 0 0 /  200px 100px no-repeat fixed border-box padding-box blue;  /*in action*/

    Default Values for background when values aren’t explicitly declared

    Property IE 6 IE 7 IE 8 IE 9 Firefox Safari Chrome Opera
    background-color transparent transparent transparent transparent transparent transparent transparent transparent
    background-image none none none none none none none none
    background-attachment “local” “local” scroll scroll scroll scroll scroll scroll
    background-position 0 0 0 0 0 0 0 0
    background-repeat repeat repeat repeat repeat repeat repeat repeat repeat
    background-size       auto auto auto auto auto
    background-clip       border-box border-box border-box border-box border-box
    background-origin       padding-box padding-box padding-box padding-box padding-box

    DOM

    document.getElementById("myID").style.background
    

    background-inline-policy

    Mozilla only, pecifies how the coordinate system for the background-position of an inline element is chosen when the content of the inline element wraps onto multiple lines. -moz-background-inline-policy values include bounding-box | continuous | each-box, with a default of continuous. Property has no effect when background-attachment is fixed.

    Alternative Text for Images: the ALT attribute


    For a webpage to validate and be accessible, all images must have a value for the alt attribute, even if that value is empty. The XHTML DTD requires only two atttributes for the img element: src and alt. The XHTML DTD tells you it needs to be there. WCAG tells you a bit more about what it needs to look like. Unfortunately, W3C writings are is not always understandable. This entry will explain, in human terms, how to write the values for your alt attributes.

    Section 508/WCAG alt attribute Guidelines:

    The first Section 508 guidelines states, “A text equivalent for every non-text element shall be provided (e.g., via “alt”, “longdesc”, or in element content)”. Checkpoint 1.1, the first priority of priority 1 of the WCAG guidelines states the same thing: Provide a text equivalent for every non-text element (e.g., via “alt”, “longdesc”, or in element content). This includes: images, graphical representations of text (including symbols), image map regions, animations (e.g., animated GIFs), applets… (I shortened it. the W3C tends to be loquacious.)

    Decorative Images

    Decorative images include background images, bullets, <hr /> equivalents, spacer images, etc. These types of images make the page prettier but have no semantic value for a webpage. The alt attribute for decorative images should be empty: <img src=”path/image.gif” alt=”” />.

    Notes:

    • If you’ve read any of my other blog entries, or other articles on web standards, you likely will never have an empty alt attribute, since you are separating the content layer from the presentation layer; and therefore not including decorative images in your XHTML; opting instead for the use of CSS.
    • If you include an empty alt attribute, screen readers will skip over the image. If you fail to put an alt attibute in, the screen reader will read the entire URL of the image. Can you imagine listening to a robot say “spacer gif spacer gif spacer gif” repeatedly, or, worse, going letter bu letter thru the underscores and extensions of a filename generated by ImageReady.

    Icons

    The alt attribute of an icon should describe the intention of the icon, since an icon can have differing meanings depending on the context, and someone who has never seen the icon wouldn’t understand whatit emant if only visually described.

    icon possible relevant values for alt useless alt
    “correct”, “open”, “start”, “completed”, “asset”, “” circle with check mark
    “stop”, “wrong”, “delete”, “close window”, “”, “remove module”, “delete email” red cross
    “RSS Feed”, “add RSS feed to reader, “” orange square with 3 lines.
    “answer”, “enter password”, “”, “primary key”, “security feature”, “” gold key
    “security feature”, “blocked”, “password protected” closed lock

    The desription of the appearance of the icon is almost alwasys a useless alt attribute value. Unless you are writing a manual on graphic design or on understanging iconography, don’t include a description of the icon as the value of the alt attribute.

    An empty string is a possible relevant value for all icon alt attributes. When an icon appears directly before an equivalent definition of the function of that icon, then the value of the alt attribute should be empty. The two most common examples of this are the print and email icons:

    icon possible relevant values for alt useless alt
    “open email”, “email messages”, “go to inbox”, “send an email, “” letter
    print, “” printer

    When an icon describes the text immediately preceding or following it, it is redundant to include a value for the alt attribute of the icon. The screen reader will read “print print”, or “email email”.

    Sample alt attribute encoding for icons:

    Wrong:

    <a href="inbox.html"><img src="icon/email.gif" /> inbox</a> //missing alt attribute

    Will validate, but not really good: Screenreader will say “go to inbox inbox”

    <a href="inbox.html"><img src="icon/email.gif" alt="go to inbox" /> inbox</a> //redundant alt attribute

    Better, and correct:

    <a href="inbox.html"><img src="icon/email.gif" alt="" /> inbox</a>

    Best: seperates content from presentation

    <a href="inbox.html" class="email">inbox</a>

    with the css of

    a.email {
        padding-left: 18px;
        background: tranparent url(icon/email.gif) no-repeat 0 0;
        }

    Notes:

    • Although it is generally best to use CSS background images (including sprites) if you are going to use an icon
    • If you use a sprite, the alt altribute should describe the relevant section of the sprite. Don’t write “sprite of icons”. Instead, follow the recommendations above (all those images are actually one transparent .gif — a sprite.

    Buttons, navigation and other images with text

    If you are still using images for the elements in your navigation bar (shame on you!), the general rule is that the value of the alt attribute must match the text of the image. If your image says only “about”, the value of the alt attribute should also read about. Then include more detail about the destination in the title attribute of the parent anchor tag.

    <a href="about/index.html" title="About the Author"><img src="img/nav_about.jpg" alt="about" /></a>.

    Include the text that appears within your image as the value of the image’s alt attribute.

    If you are using mystery meat navigation, you should describe relevant text in the alt, not the an explanation of the iconography of the tab. This may go against standards guidelines, but since mystery meat navigation goes against web standards, at least make your website accessible to the visually impaired, even if it isn’t accessible to sighted users.

    Instead of using an <img> for navigation, use text, and make your link attractive, including using your image, via CSS using image replacement. I will include a blog entry on image replacement in the near future, since i use it a lot. In the meantime, you can look it up on any search engine.

    Images, without text, that link to somewhere

    Sometimes it makes sense to actually use images, without image replacement, to link to a page. For example, on Facebook, Yahoo, and maybe on your company’s about page, thumbnail images of people or avatars may link to the person’s profile. If the image is within the same link as a text link, the alt attribute should be left empty. If not, however, the link should describe the purpose of the link: <a href="bios/jane.html"><img src="img/thmb_jane.jpg" alt="Jane Smith's profile" /></a>.

    This is similar to the explanation on icons above. Let’s say you do use just the email icon (from the icon example above). The correct presentation would be:

    <a href="inbox.html"><img src="icon/email.gif" alt="go to inbox" /></a>

    Complex, detailed images that “convey 1000 words”

    Sometimes images are worth a thousand words. Maps, Graphs and Charts are examples of images that contain information necessary to understanding the message of a page but too complex to be described in under 255 characters. If the complex image is followed by text explaining or detailing the content of the image, like you might find in a journal article, then a simple alt attribute value suffices.If there is information conveyed in the image that is not explained in the text following the image and is too complex to describe in 2 sentences, like you might find in a powerpoint presentation, then you need an alternative method of explaining the content of the image to those unable to view the image. In other words, if all the data presented in your image is reiterated as text, then an alt attribute value of “graph of blood pressure by age group” suffices. If there is information that is conveyed in the image that is not reiterated as text for all of your visitors to read (and search engines to find), then you should include a longer description of the image in the form of a longdesc attribute linking to content describing in full detail the contents of your image.

    The longdesc attribute

    longdesc is an optional attribute of the <img> and <frame> elements. The longdesc property specifies a url for a longer description of the contents of the current frame. The longdesc attribute is coded like this::

    <img src="graph.gif" alt="graph of blood pressure by age group(long description available)" longdesc="supportfiles/graphdescribed.html" />


    You then need to create a separate page for your longdescription. This page should include the description and a link back the current page. The longdesc attribute’s purpose is to provide a link to a separate page where a long description is available. This link is invisible to the sighted user but available to those using screen readers.

    The longdesc functionality is rarely implemented in websites despite it’s being the recommendation of the WC3 and Section 508 guidelines. For this reason, you should:

    • Include the fact that a long description is available in the alt attribute value of the image: it’s used so infrequently that even those using screen readers may not otherwise notice you included it. alt="graph of blood pressure by age group(long description available)"
    • It’s better to not use the longdesc attribute, opting instead to fully describe the contents of the image in the text for all readers. This method provides more fodder for search engines, and explains the content of your graph that even sighted users may not have otherwise noticed or derived.
    • To test whether it’s necessary, turn off images and see if all the information conveyed in the image is presented in the text in the page. If yes, longdesc is not necessary. If not, either include more descriptive text, or include a longdesc.
    • When I receive data graphs, I usually include a datatable with the data conveyed in the graph. Most charts are created using MS Excel (open MS Excel, select “Insert” > “Chart”). Ask whoever created your chart image for the original Excel file, and present the data from the spreadsheet in a data table. If you don’t have the original spreadsheet, if the chart is detailed enough to require a longdesc, then it’s detailed enough to be able to cull the data.
    • WebAIM provides more information on the longdesc attribute.

    Other images

    This is for all other images! If you included a picture of yourself standing with Britney Spears, your alt attribute value should minimally read “Britney Spears and me”. You can, of course, add a few more details to better describe the image if there is other relevant information presented in the image that the visitor should know.

    16 Common JavaScript Gotchas

    We all know that JavaScript can trip you up. Here are a 16 common traps that can trip you up when coding javascript. You likely know most of the code on the page, but if you keep these 16 gotchas in your mind, coding and debugging will be less of a headache:

    1. Case sensitivity: Variable names, properties and methods are all case sensitive
    2. Mismatching quotes, parenthesis or curly braces will throw an error
    3. Conditional Statments:3 common gotchas
    4. Line breaks: Always end statements in semi-colons to avoid common line break issues
    5. Punctuation:Trailing commas in object declarations will trip you up
    6. HTML id conflicts
    7. Variable Scope: global versus local scope
    8. string replace function isn’t global
    9. parseInt should include two arguments
    10. ‘this’ and binding issues
    11. Function overloading: Overwriting functions, as overloading doesn’t exist
    12. Setting default values for parameters in case you omit them
    13. For each loops are for objects, not arrays
    14. switch statements are a little tricky
    15. Always check for Undefined before checking for null
    16. Function location may matter
    Case Sensitivity
    Variables and function names are case sensitive. Like mismatched quotes, you already know this. But, since the error may be silent, here is the reminder. Pick a naming convention for yourself, and stick with it. And, remember that native javascript function and CSS properties in javascript are camelCase.

    getElementById('myId') != getElementByID('myId'); // it should be "Id" not "ID"
    getElementById('myId') != getElementById('myID'); // "Id" again does not equal"ID"
    document.getElementById('myId').style.Color; // returns "undefined"
    
    Mismatching quotes, parenthesis and curly brace
    The best way to avoid falling into the trap of mismatched quotes, parentheses and curly brackets is to always code your opening and closing element at the same time, then step into the element to add your code. Start with:

    var myString = ""; //code the quotes before entering your string value
    function myFunction(){
         if(){   //close out every bracket when you open one.
    
    	 }
    }
    
    //count all the left parens and right parens and make sure they're equal
    alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //close every parenthesis when a parenthesis is open
    

    Every time you open an element, close it. Put the arguments for a function into the parenthesis after you’ve added the closing parenthesis. If you have a bunch of parenthesis, count the opening parenthesis and then the closing parenthesis, and make sure those two numbers are equal.

    Conditional statements (3 gotchas)
    1. All conditional comments must be within parentheses (duh!)
      if(var1 == var2){}
    2. Don’t get tripped up by accidentally using the assignment operator: assigning your second argument’s value to your first argument. Since it’s a logic issue, it will always return true and won’t throw an error.
      if(var1 = var2){} // returns true. Assigns var2 to var1
    3. Javascript is loosely typed, except in switch statements. JavaScript is NOT loosely typed when it comes to case comparisons.
      var myVar = 5;
      if(myVar == '5'){ // returns true since Javascript is loosely typed
        alert("hi");  //this alert will show since JS doesn't usually care about data type.
      }
      switch(myVar){
        case '5':
        alert("hi"); // this alert will not show since the data types don't match
      }
    Line Breaks
    • Beware of hard line breaks in JavaScript. Line breaks are interpreted as line-ending semicolons. Even in a string,if you include a hard line break in between quotes you’ll get a parse error (unterminated string).
          var bad  = '<ul id="myId">
                         <li>some text</li>
                         <li>more text</li>
                      </ul>'; // unterminated string error
      
          var good = '<ul id="myId">' +
                         '<li>some text</li>' +
                         '<li>more text</li>' +
                     '</ul>'; //correct
    • The line break being interpreted as a semi-colon rule, discussed above, does not hold true in the case of control structures: line breaks after the closing parenthesis of a conditional statement is NOT given a semi-colon.

    Always use semi-colons and parenthesis so you don’t get tripped up by breaking lines, so your code is easier to read, and, less thought of but a source of quirks for those who don’t use semicolons: so when you move code around and end up with two statements on one line, you don’t have to worry that your first statement is correctly closed.

    Extra commas
    The last property in any JavaScript object definition must never end with a comma. Firefox won’t barf on the trailing, unnecessary commas, but IE will.

    HTML id conflicts
    The JavaScript DOM bindings allow indexing by HTML id. Functions and properties share the same namespace in JavaScript. So, when an id in your HTML has the same name as one of your functions or properties, you can get logic errors that are hard to track down. While this is more of a CSS best practice issue, it’s important to remember when you can’t solve your javascript issue.

    var listitems = document.getElementsByTagName('li');
    
    var liCount = listitems.length; // if you have <li id="length">, returns that <li> instead of a count.

    If you’re marking up (X)HTML, never use a javascript method or property name as the value for an ID. And, when you’re coding the javascript, avoid giving variables names that are ID values in the (X)HTML.

    variable scope
    Many problems in javascript come from variable scope: either thinking that a local variable is global, or overwriting a global variable unwittingly with what should be a local variable in a function. To avoid issues, it’s best to basically not have any global variables. But, if you have a bunch, you should know the “gotchas”.

    Variables that are not declared with the var keyword are global. Remember to declare variables with the var keyterm to keep variables from having global scope. In this example, a variable that is declared within a function has global scope because the var ke

    anonymousFuntion1 = function(){
    	globalvar = 'global scope'; // globally declared because "var" is missing.
    	return localvar;
    }();
    
    alert(globalvar); // alerts 'global scope' because variable within the function is declared globally
    
    anonymousFuntion2 = function(){
    	var localvar = 'local scope'; //locally declared with "var"
    	return localvar;
    }();
    
    alert(localvar); // error "localvar is not defined". there is no globally defined localvar
    

    Variable names that are introduced as parameter names are local to the function. There is no conflict if your parameter name is also the name of a global variable as the parameter variable has local scope. If you want to change the global variable from within a function that has a parameter duplicating the global variable’s name, remember that global variables are properties of the window object.

    var myscope = "global";
    
    function showScope(myscope){
      return myscope; // local scope even though there is a global var with same name
    }
    alert(showScope('local'));
    
    function globalScope(myscope){
      myscope = window.myscope; // global scope
      return myscope;
    }
    alert(globalScope('local'));
    

    You should even declare variables within loops

    for(var i = 0; i < myarray.length; i++){}
    string replace
    A common mistake is assuming the behavior of the string replace method will impact all possible matches. Infact, the javascript string replace method only changes the first occurrence. To replace all occurrences, you need to set the global modifier.

      var myString = "this is my string";
      myString = myString.replace(/ /,"%20"); // "this%20is my string"
      myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
    
    parseInt
    The most common error with parding integers in javascript is the assumption that parseInt returns the integer to base 10. Don’t forget the second argument, the radix or base, which can be anything from 2 to 36. To ensure you don’t screw up, always include the second parameter.

    parseInt('09/10/08'); //0parseInt('09/10/08',10); //9, which is most likely what you want from a date.
    ‘this’
    Another common mistake is forgetting to use ‘this‘. Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the ‘this’ reference identifier. For example, the following is incorrect:

    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {
    		alert(objProperty);
    		}
         };
      myObject.objMethod();
    } 
    
    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {
    		alert(this.objProperty);
    		}
         };
      myObject.objMethod();
    }

    There’s an A List Apart article that puts this binding issue into plain English

    Overwriting functions / overloading functions
    When you declare a function more than once, the last declaration of that function will overwrite all previous version of that function throwing no errors or warnings. This is different from other programming languages, like java, where you can have multiple functions with the same name as long as they take different arguments: called function overloading. There is no overloading in javascript. This makes it vitally important to not use the names of core javascript functions in your code. Also, beware of including multiple javascript files, as an included script may overwrite a function in another script. Use anonymous functions and namespaces.

    (function(){
    	// creation of my namespace
        // if namespace doesn't exist, create it.	if(!window.MYNAMESPACE) {		window['MYNAMESPACE'] = {}; 		}
    
        // this function only accessible within the anonymous function
        function myFunction(var1, var2){
    		//local function code goes here
        }
    
        /* attaches the local function to the namespace
           making it accessible outside of the anoymous function with use of namespace */
        window['MYNAMESPACE']['myFunction'] = myFunction; 
    
     })();// the parenthesis = immediate execution	  // parenthesis encompassing all the code make the function anonymous
    Missing Parameters
    A common error is forgetting to update all the function calls when you add a parameter to a function. If you need to add a parameter to handle a special case call in your function that you’ve already been calling, set a default value for that parameter in your function, just in case you missed updating one of the calls in one of your scripts.

    function addressFunction(address, city, state, country){
          country = country || "US"; // if country is not passed, assume USA
          //rest of code
        }

    You can also get the length of the argument array. But we’re focusing on “gotchas” in this post.

    For each
    The “for” loop in javascript will iterate it over all object attributes, both methods and properties, looping thru all of the property names in an object. The enumeration will include all of the properties—including functions and prototype properties that you might not be interested in—so filter out the values you don’t want using hasOwnProperty method and typeof to exclude functions. Never use for each to iterate thru an array: only use for each when needing to iterated thru object properties and methods.

    • for each (var myVar in myObject) iterates a specified variable over all values of object’s properties.
    • for (var myVar in myObject) iterates a specified variable over all the properties of an object, in arbitrary order. The for...in loop does not iterate over built-in properties. For each distinct property the code is executed
    • for (var 1=0; i < myArray.length; i++) iterates thru all the elements of an array.

    To fix the problem, generally you’ll want to opt for for ... in for objects and use the for loop for arrays:

    listItems = document.getElementsByTagName('li');
    
    for each (var listitem in listItems){
        // this goes thru all the properties and methods of the object,
        // including native methods and properties, but doesn't go thru the array: throws error!
       }
    
    //since you have an array of objects that you are looping thru, use the for loop
    for ( var i = 0; i < listItems.length; i++) {
        // this is what you really wanted
       }
    Switch statements
    I wrote a whole blog post on switch statement quirks, but the gist is:

    • there is no data type conversion
    • once there is a match, all expressions will be executed until the next break or return statement is executed, and
    • you can include multiple cases for a single block of code
    Undefined ≠ null
    Null is for an object, undefined is for a property, method or variable. To be null, your object has to be defined. If your object is not defined, and you test to see whether it’s null, since it’s not defined, it can’t test, and will throw an error.

    if(myObject !== null  && typeof(myObject) !== 'undefined') {
    	//if myObject is undefined, it can't test for null, and will throw an error
    }
    
    if(typeof(myObject) !== 'undefined' && myObject !== null) {
    	//code handling myObject
    }

    Harish Mallipeddi has an explanation of undefined versus null

    Function location can matter
    There are two ways to declare function: When declaring a function in the form of a variable assignment, location does matter:

    var myFunction = function(arg1, arg2){
      // do something here
    };

    A function declared with

    function myFunction (arg1, arg2){}

    can by used by any code in the file no matter its location (before or after the function declaration). A function declared with the variable assignment syntax can only be used by code that executes after the assignment statement that declares the function.

    jQuery Tutorial: DOM Manipulation and sorting

    JQuery is a lightweight JavaScript library that helps you quickly develop events, animations, and AJAX interactions.

    In this tutorial we go over the following:

    Note that the test javascript files associated with each section go with the same XHTML file.

    Setting up your environment for this tutorial:


    • Download the JQuery library Generally you will want the minified version, but for today, download the uncompressed version so you can read some of the code if you so choose.
    • Save it locally in a directory (let’s call it “js” for this tutorial)
    • Create a new HTML page (Sample file)
    • Link to the JQuery file – <script type="text/javascript" src="js/jquery-1.2.6.js"></script>
      You may need to change the 1.2.6 part to whatever the current release number is.
    • Create a new javascript file, and call it “myCode.js”
    • Link to your javascript file – <script type="text/javascript" src="js/myCode.js"></script>
    • Add some HTML to your page (this is what we’re going to manipulate).
    • You can also add some CSS.

    ready method in anonymous function

    The first step is to create an anonymous function withing your myCode.js file to encompass all of your javascript. If you take a look at your JQuery file, you’ll note that the entire file is in an anonymous function:

    (function(){
     // code here
    
    })();

    All of your the code that you create should be included in it’s own anonymous function. This ensures that the jQuery variables are local: your variable declarations will not break the jQuery library, and the jQuery library will not overwrite your variables, methods and properties.

    For our own javascript, we are going to encapsulate all our code in an anonymous function. However, since we are accessing elements of the DOM, we need to ensure that the DOM is loaded. We can’t use the parenthesis at the end as in the code above, which executes the anonymous function immediately, since our DOM isn’t loaded yet. We should only execute our anonymous function once we have the DOM. Without jQuery, and without much Javascript skill, the usual route is to include a document.onLoad event. Instead of using onLoad, which makes us wait until all the images are loaded, we’re going to use jQuery’s ready function — $(document).ready() — which executes when the DOM is ready.

    The $(document).ready() function has advantages over other load time event handlers. Everything inside it will load as soon as the DOM is loaded, without having to wait for the page contents to be completely loaded. Ready is fired as soon as the DOM is registered by the browser, which allows for hiding and showing effects and other effects as soon as the user sees the page elements. Unlike the onLoad method, which is limited to only one function, the jQuery ready method allows for multiple functions to be loaded within it.

    $(document).ready(function() {
     // code here
     });

    Add the code above to your myCode.js file.jQuery

    Targeting elements in the DOM with CSS and XPath

    jQuery enables selecting elements with the same syntax that you would use to target that element with CSS. For example, we can target the first <h2> in our html file these two ways among others: (test js)

    • $("h2:first")
    • $("#mainContent > h2")

    Take a look at the official jQuery Selectors page to get a better understanding of how you can use CSS syntax to target elements.

    DOM Manipulation

    The following are explanations and examples of the DOM manipulation methods provided by the jQuery core. The jQuery domentation for the DOM manipulation methods can be found at http://docs.jquery.com/Manipulation

    jQuery’s version of innerHTML and textNodes

    jQuery replaces innerHTML with the html() method to both return and set innerHTML with (and without) HTML elements. To return or set text, similar to retrieving and setting textNodes, use jQuery’s text() method. The main difference between the two involves the returning and rendering of HTML elements. (test js)

    • html()
      returns the HTML content of an element. This is directly equivalent to the innerHTML property commonly used by JavaScripters.
      var myHTMLContent = $("#mainContent").html(); // "<h2>My jQuery te.... (to) ...functionality</p>
    • html(myString)
      Sets the innerHTML for an element to myString.
      $("h2:first").html('This is new <em>header</em> content'); // changes the h2, and adds some emphasis
    • text()
      returns the text content, or text nodes, of an element without any markup as one string
      var myTextContent = $("#mainContent").text(); // returns same as html(), but without tags;
    • text(myString)
      Resets the text node value for an element to myString.
      $("h2:first").text('Ugly <em>header</em>); // escapes '>' and '<' instead of rendering italics

    Child & Sibling nodes

    append() and prepend() methods: similar to appendChild, except jQuery accepts a string, a DOM element, or a jQuery object as valid arguments. jQuery converts the argument into a text node or element depending on what is passed. (test js)

    1. $("#leftNav ul").append("<li>after the last &lt;li&gt;</li>"); // adds <li> at the end of <ul>
    2. $("#leftNav ul").prepend("<li>before the first &lt;li&gt;</li>"); // adds <li> at the start of <ul>
    3. $("#leftNav ul").append($("#mainContent h2")); // moves headers from the mainContent to the leftNav

    4. $("#leftNav ul").append($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav

    There are two similar methods — appendTo() and prependTo() — which are basically inververted verstions of append() and prepend(). A.append(B) is about equal to B.appendTo(A)

    Note: As shown in example 3, if you try to append an element that already exists in the DOM, that element will first be removed from DOM before being reinserted, or appended, in the new location.

    before() and after() methods: similar to insertBefore() method (and the non-existant, but found in many javascript libraries, includeing this one, insertAfter()). The after() method inserts a node after a selected one. The before() method inserts a node before a selected one, like the javascript standard method of insertBefore().

    1. $("#leftNav ul").before("<h2>Left Navigation</h2>"); // adds header before the <ul>
    2. $("#leftNav ul").after("<h4>New Header</h4>"); // adds header after the <ul>
    3. $("#leftNav h4").before($("#mainContent h2").html()); //copies text of the first h2, adds it to leftNav before our new <h4>

    There are two similar methods — insertBefore() and insertAfter() — which are basically inververted versions of before() and after(). A.before(B) is about equal to B.insertBefore(A)

    Parent nodes

    wrap(), wrapAll() and wrapInner() methods: wrap selected element or elements in another element. The argument can be an XHTML or DOM element as a string. If the element has child nodes, the element being wrapped will be put in the deepest child node of the first element. (test js)


    1. $("#leftNav ul").wrap("<div class=\"red\"></div>"); // the <ul> gets wrapped in a <div>
    2. $("#mainContent h2").wrap("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>'s get wrapped in a two separate <blockquote>s
    3. $("#mainContent h2").wrapAll("<blockquote class=\"blue\"></blockquote>"); // the 2 <h2>'s get wrapped in a single <blockquote>, moving the second <h2> up to be the nextSibling to the first <h2>
    4. $("#mainContent h2").wrap('<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>'); // puts the H2s in two "blue" divs, the LIs will be empty.
    5. $("#mainContent h2").wrapAll('<div class="shell"><div class="blue"></div><ul class="red"><li></li></ul></div>'); // puts the H2s in ONE "blue" div, the LI will be empty.
    6. $("#mainContent p").wrapInner("<a href=\"#\"></a>"); // puts an <a> between the <p> and the <p>'s first child.
    7. $("#mainContent").wrapInner("<blockquote class=\"blue\"></blockquote>"); // wraps all the children of #mainContent into one parent <blockquote>

    remove() and empty()

    remove(), empty() and replace() methods: similar to the native javascript removeChild() method, use remove() to remove element(s) from the DOM. Use the empty() method to keep the element, but remove the element’s children.
    Note that remove() can take a parameter, but empty() does not. (test js)

    1. $("#leftNav li:first").remove(); // removes the first LI
    2. $("#leftNav li").remove(); // removes all the LIs from the #leftNav
    3. $("#leftNav li").remove(":contains('Second')"); //remove the LI containing the term.
      Note that the string is case-sensitive
    4. $("#mainContent h2:first").empty(); //removes the text in the first H2, but the h2 is not removed from the DOM
    5. $("#mainContent h2:contains('second')").empty(); //removes the text node child of the H2 containing the letters "second"

    replaceWith(), replaceAll() and clone()

    replaceWith() and clone() methods: Cloning creates copies of the DOM elements copied, including the new elements in the DOM, but does not append them to the page. To append the clone to the page, use one of the methods above.

    1. $("#leftNav li:first").replaceWith("<li>new first <em>LI</em></li>"); //text changed, LI is emphasized

    2. $("#leftNav li:first").text().replaceWith("new first <em>LI</em>");// grabs text, and replaces it. No <li> needed
    3. var navCopy = $("#leftNav").clone(); //copies it
      $("#mainContent").append(navCopy); //apends it

      The problem with cloning is that IDs are copied too, and ID’s need to be unique!


    Effects with JQuery

    The above was an overview of all the DOM manipulation functions. If you’re doing a simple site, those are likely all the javascript helpers you need. But, if that was all you could do with JavaScript, then you really wouldn’t need javascript libraries. The power of the libraries is in everything else they do for you. With jQuery you can create drag and drop, autocomplete, sorting, etc., the is unobtrusive and works cross browser in less than 10 lines of javscript. Proof? Here are two examples:

    Sorting a table with javascript:

    1. Create a table in plain old XHTML, and populate that table with data. Give your data table the class of sort with: (sampleFile)
      <table class="sort">
    2. Download the jquery libary and the jquery.tablesorter.js file.
    3. Attach the two jQuery files and your own JavaScript file to your XHTML file by including the following in the header of your XHTML file:
      <script type="text/javascript" src="jquery-1.2.6.js"></script>
      <script type="text/javascript" src="jquery.tablesorter.js"></script>
      <script type="text/javascript" src="myTableCode.js"></script>
    4. In your JavaScript file (called myTableCode.js above) include the simple script:
      $(document).ready(function() {
          $("table.sort").tablesorter();
       });
    5. Literally, the previous step is all there is to sorting tables bu column content in However, that just sorts it based on the content of the HTML. So, if you have an <em> or <p> in one table cell and not in another, it may not sort the way you want. To sort based on a portion of your code inside a cell, use the textExtraction utility provided by jQuery:
      $(document).ready(function() {
      
       $("table.sort").tablesorter({
              // define a custom text extraction function
             textExtraction: function(node) {
                  // if there is a link, return the content of the link
      		if(node.getElementsByTagName('a')[0]){
      				return node.getElementsByTagName('a')[0].innerHTML;
          			}
              return node.innerHTML;
              }
          });
       });

    See my example

    Making a list sortable

    Similar to the sortable table, you can make a make a list that is sortable by dragging list items around. (example)

    1. Create a list, give it the class of “sortable”.
      <ul class="sortable">
        <li>This is my first list item</li>
        <li>second list item</li>
        <li>Brief 3</li>
        <li>Long 4</li>
      </ul>
    2. Go to the jQuery Download Builder and select “sortable”. You’ll note that the other required library elements are automatically selected.
    3. Attach the three javascript files downloaded from the builder, and your own javascript file, to your page with the list.
      $(document).ready(function() {
           $("ul.sortable").sortable();
         });

    Userful Links

    JavaScript Objects

    Javascript: Things you should know

    Note: This is part III of a "Javascript: Things you should know" series. I assume readers have an understanding of the core language. This section goes over objects at a very basic level. Most books cover objects in a confusing manner. Below are really simple examples which, if you have been confused, will hopefully make things make sense. The previous entry was JavaScript Switch Statement Quirks.

    JavaScript Objects Demystified

    Everything in JavaScript is an object except core types. true, false, null, undefined and numeric values are not objects. Strings, with the length property and numerous methods, are objects.

    Most JavaScript objects are collections of name-value pairs. I think of objects as associative arrays. The "name" or key of an object is a string except for in the array object where it can be a string or a incremental integer. The value can be any JavaScript value, including an array or other object.

    Creating a JavaScript Object

    There are two basic ways to create an object which are semantically equal. You can declare an object using an object function and instantiate the object by using the "new" keyword or you can use the object literal method:

    • var obj = new Object();
    • var obj = {}; // object literal method

    Assigning properties to an object

    An object’s properties can be assigned with the dot operator or like an associative array::

    obj.name = "Estelle";
    obj["name"] = "Estelle";

    the property values can be retrieved in a similar fashion

    var myname = obj.name;

    var myname = obj["name"];

    The difference between using the dot operator versus the array method is that since the key value is a string, you can use reserved words for the "name". If you plan on creating property names based on user input, this can be aspirin for what otherwise would be a headache. Otherwise, the dot syntax is easier, and reserved words should not be used. Using a reserved word is a bad idea. Both the object name and property name are case sensitive.

    obj.for = "Estelle"; // produces an error
    obj["for"] = "Estelle"; // allowed

    Object Literals

    Object literal syntax can be used to initialize the entire object.:

    var obj = {
      name: "Estelle",
      gender: "Female",
      outfit: {
         top: "t-shirt",
         bottom: "jeans",
         shoes: "hiking boots"
         }
    }

    You can chain it together:

    obj.outfit.shoes; // hiking boots
    obj["outfit"]["bottom"]; // jeans

    Even though outfit in the example above seems like it is a newly created object within obj, it isn’t:

    outfit.shoes; // error, since outfit is not defined
    obj.shoes; // undefined, not an error, since obj is defined, but the property shoes has not been assigned a value

    Assigning methods to an object

    Methods are simply functions tied to objects. For example, toUpperCase is a method of the string object. The simplest way to attach a method to an object is to use an anonymous function:

    var greeting = {
      name: "Estelle",
      message: "this was written by ",
      welcome: function(){
         alert("Objects now make sense");
         },
      sayhi: function(){
         alert(this.message + this.name);
        }
    }
    

    welcome is a method of the greeting object. Calling greeting.welcome();, with the parenthesis, will cause the alert.

    sayhi is also a method of the greeting object. Calling sayhi.welcome();, with the parenthesis, will cause the alert. The this keyword refers to the object that is calling the function, and will be discussed in further detail in a future entry.

    Method names are also case sensitive.

    the Window object.

    All variables that are not assigned as properties of other objects become properties of the window object.

    var animal = {};
    var myCat = animal.pet = "Sassafrass";

    In this case, animal is an object, pet is a property of the animal object and myCat is a property of the window object.

    The following all work and return "Sassafrass":

    • animal.pet;
    • window.animal.pet;
    • myCat;
    • window.myCat;

    The following may not return what you expected:

    • pet; // throws an error as pet is a property of the animal object, not the window object
    • window.pet; // undefined
    • window.animal // evaluates to object.

    Note: JSON, or JavaScript Object Notation, is a subset of JavaScript’s oject literal notation.

    JavaScript Object Properties and Methods

    All objects in javascript inherit from the Object object, and therefore inherit the properties and methods of Object, including:

    • constructor property
    • prototype property
      used to assign new properties and methods to future instances of the object type.
    • hasOwnProperty() method
    • isPrototypeOf() method
    • propertyIsEnumerable() method
    • toString() method
    • toLocaleString() method
    • valueOf() method

    Extending Objects

    It is fairly simple, though not always necessary, to extend objects with new methods and properties. Use the protoype property, inherited from the Object object to add methods to an object. Here are some examples of String, Array and Date object methods.

    String.prototype.capFirst = function(){
       return this.charAt(0).toUpperCase() + this.substr(1);
    }
    
    String.prototype.trim = function () {
      return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
    };
    
    Array.prototype.sortCaseInsensitive = function(){
        return this.sort(function(a,b){ return (String(a).toLowerCase() > String(b).toLowerCase())? 1: -1;}
    }
    
    
    Date.prototype.customFormat = function(formatString){
      //The code for this is in the javascript date object article.
    }

    JavaScript Object Literals Simplified

    Instantiating Objects

    You are likely familiar with instantiating strings and arrays in javascript:

    var myString = new String();
    var myArray = new Array();

    Array and String are both objects, extended from the Object object. String and Array are objects inheriting all the properties of the Object object, and adding new properties and methods that are specific to the Array and String objects respectively. In these cases, the new keyword creates a new instance of the String and Array objects respectively.

    There are several ways to declare an object in Javascript, including:

    var myObject = new Object();
    
    var myObject = {};

    JavaScript Dot Notation

    If you are on this site, you have likely used javascript dot notation for properties and methods of objects. The following hopefully looks familiar to you:

    var myFirstLink = document.getElementById('myDiv').getElementsByTagName('a')[0]; 
    //returns the first link in the parent element with ID of "myDiv"
    
    myFirstLink.className = "myClass" 
    // or, not as good, but still valid, myFirstLink.style.color = "#ff0000"

    and if you have used any javascript libraries, or have coded more advanced javascript, you have likely used javascript dot notation in creating new methods, such as

    myObject.somemethod = function(){
        // code here
    }

    Declaring methods and properties with Dot notation

    Using dot notation your code may look something like this:

    var myObject = new Object();
    	myObject.myProperty = value;
    	myObject.yourProperty = value;
    	myObject.myMethod = function(){
    	  //code here
    	}
    	myObject.yourMethod = function(){
    	  //more code
    	}
    

    Note: remember that undefined properties of objects return undefined. Unlike undeclared variables, they do “exist”, so they don’t throw an error. If we us the examples above, (myString.typoed_property == undefined) returns true.

    Declaring methods and properties using Object Literal syntax

    You could declare the properties and methods listed above using cleaner Object Literal syntax:

    var myObject ={
    	myProperty : value,
    	yourProperty : value,
    	myMethod : function(){
    	  //code here
    	},
    	yourMethod : function(){
    	  //more code
    	}
    }

    A few things to note:

    1. The Object literal notation is basically an array of key:value pairs, with a colon separating the keys and values, and a comma after every key:value pair, except for the last, just like a regular array. Values created with anonymous functions are methods of your object. Simple values are properties.
    2. if you are mixing code sources, using libraries or sharing code, you want to use static methods and properties rather than public methods and properties, to safeguard against overwriting functions or variables / methods or properties declared outside your current javascript file.
    3. Unlike public functions, which can appear anywhere in your code, including after lines using your function, methods declared using object literal notation do not exist until execution of that section of the script.
    4. This method instantiates a new object, so don’t try to create a instance using the new keyword