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

Creating counters with Generated Content

I have never used the counter or increment properties since they aren’t supported in IE7 or earlier, nor are the :before pseudo elements, or content property. Since IE8 does support all of these, soon we may be able to include these CSS properties, so I thought I would explain them.


The <ol> start attribute and <li> value element were deprecated in HTML 4.01 and not supported in XHTML strict. The value attribute set the number of a list item, enabling the following list items to increment from that value. While there is no (X)HTML replacement for these elements, CSS 2.1 provides methods for setting and incrementing counters on any element, not just <li>’s. This article focuses on the following CSS pseudo elements and properties:

  • content CSS property
  • :before pseudo-element
  • :after pseudo-element
  • counter-increment CSS property
  • counter-reset CSS property

The content property is used in conjunction with the :before or :after pseudo-elements. The value of the content property is added to the visual layout of your document, but is NOT added to the DOM. If you’re reading this tutorial, you should already know that! We’re discussing :before, :after and content here because without them, the counter is kind of useless: if you’re not going to display the content of a counter before (or perhaps after) an element, why include it?

Overview of content property

To make understanding this tutorial easier, we are going to use the concrete example of adding ” – <hrefValue>” after every link, which is helpful when using print CSS.

<ul id="showlinkafterlink">
  <li><a href="http://www.yahoo.com">Yahoo</a></li>
  <li><a href="http://www.google.com">Google</a></li>
  <li><a href="http://evotech.net/blog">CSS, JavaScript and XHTML explained</a></li>
</ul>

Listing 1: Without any CSS, this is how the code above looks

#showlinkafterlink a:after {
    content: "  - <" attr(href) ">";
    }

Listing 2: If you are using a standards compliant browser (i.e. NOT IE6 or IE7), the above should have the hrefs following the links.

A few things to note about the content rendered via the content property:

  • Generated content does not alter the document tree. The content is rendered only: it doesn’t appear in the DOM tree, altering the presentation only, not the document
  • To control the appearance of the generated content, you can use other CSS properties. All properties in the :after declaration impact the generated content.
  • In case you were wondering, you can only add one pseudo-element per side of your element. element:before:before does not work.
#showlinkafterlink a:after {
    content: "  - <" attr(href) ">";
    color: #ff0000;	 font-style: italic;
    }

Listing 3: Here we’ve defined the color and font-style for the generated content.

While the generated content is NOT added to the DOM, think of it as an added span that inherits everything from it’s parent. The content cannot contain any HTML, just ASCII, escaped and ISO characters. As mentioned, content is used with the :before and :after pseudo-elements to generate content in a document.

Values of the CSS content property

The CSS content property can take as its value none | normal | <string> | url | open-quote | close-quote | no-open-quote | no-close-quote | attr(attribute) | counter(name[, style]). Values have the following meanings:

  • content: none;

    none: The pseudo-element is not generated.

  • content: normal;

    normal: Computes to ‘none’ for the :before and :after pseudo-elements unless the default browser rendering includes content (i.e. <q>) which is handled differently based on the browser – Safari shows the default content, IE8 and FF do not.

  • content: "Estelle: ";content: "\00a3 "; /* includes '£' */

    string: Adds a string before or after the element (depending on which pseudo-element is used). Strings can either be written with double or single quotes. If your string includes a quotation mark, make sure you escape it with a slash-quote or slash-ISO value. If you are going to include any non-ASCII characters or entities, declare the charset in your CSS and XHTML, and/or use the ISO code for the character. Check out my blog post on including named entities in CSS and Javascript

  • content: url(myBullet.gif);

    url: The value is a URI that designates an external resource (such as an image). If the browser can’t display the resource, FF and IE8 omit it, as if it were not specified, but Safari indicates that the resource cannot be displayed with a missing image icon.

  • content: open-quote;

    open-quote and close-quote: These values are replaced by the appropriate string from the ‘quotes’ property. Opera handles this, but does not nest quotes correctly, Safari ignores this completely. IE8 and Firefox get it right.

  • content: open-quote;

    no-open-quote and no-close-quote: Introduces no content, but increments (decrements) the level of nesting for quotes. Safari ignores this completely. Opera, IE8 and Firefox get it right.

  • content: attr(title);

    attr(x): This function returns as a string the value of attribute X for the subject of the selector. The string is not parsed by the CSS processor. If the subject of the selector doesn’t have an attribute X, an empty string is returned. The case-sensitivity of attribute names depends on the document language.

    For uber coolness, or geekiness as the case may be, you can add text dynamically without using javascript.

    a.tooltip {
      position: relative;
    }
    a.tooltip:hover:after {
      content: attr(title);
      position:absolute;
      display:block;
      padding: 5px;
      border: 1px solid #f00;
      background-color: #dedede;
    }
  • content: counter(subtitles, decimal);content: counter(headers) "." counter(subtitles) ": ";


    counter(name)
    or counter(name, style): The counter takes two parameters: the name, which you can reference to increment or reset, and the style, which, if not declared, defaults to “decimal”. While you can name the counter almost anything except ‘none’, ‘inherit’ or ‘initial’, avoid key terms.

Browser support for the CSS content property and :before and :after pseudo elements

The CSS content property and possible values
IE6 IE7 IE7 in IE8 IE8 FF3 FF 3.5 Beta Saf 3.2 Saf 4 Beta Opera 9.64
:before
:after
content Since :before and :after is not supported in these browsers, testing is not possible, and moot. It is assumed that IE6 and IE7 does not support the content property, therefore supports none of these values works, except for issues below works, except for issues below works, except for issues below
none n
normal displays quotes on <q> Makes sense, but not the spec.
url() nothing nothing nothing missing image icon missing image icon missing image alt
string
open-quote
close-quote
Does not nest quotes correctly, but does include quotes.
no-open-quote
no-close-quote
attr(x)
counter

counter-increment and counter-reset CSS properties

Counters don’t work on their own! if you just write p:before {content: counter(subtitles, decimal);} every paragraph will have a zero in front of it. To more easily understand this, let’s think of real world examples:

  • footnotes
  • creating numbering for outlines: counting chapters, sections and subsections, restarting the subsection counter for each new section, and resetting the section counter for each new chapter

Using the CSS counter syntax you can define as many counters as you like in your page, increment the counters and reset the counters. While the counter gets physically added to the presentation of the page (not the DOM) using the CSS counter value on the content property as a pseudo element using the :before or :after syntax, the increment happens on an actual element on the page.

<p> With this paragraph, I have included <cite class="footnote">citation to footnote</cite>.</p>

cite.footnote {counter-increment: citations;}

cite.footnote:after {content: counter(citations); vertical-align:text-top;}

In our example above, we would increment the counter on every <cite class="footnote">, then add the footnote numbers using the content property on the :after pseudo element. In order to use a counter, you should give it a name. In the above scenario, the name is “citations”. You can also specify the style. If the style is not declared, the style defaults to decimal. The values include all the list-style-type values, though only <ol> values make sense with a counter. Values include decimal | decimal-leading-zero | lower-alpha | lower-greek | lower-roman | upper-alpha | upper-roman | lower-latin | upper-latin | hebrew | georgian and others.

You can include more than one counter in generated content. For example, in legalese, you often have sections within sections all numbered. This is doable with CSS counters.

<h1>First Header</h1>
<h2>subsection</h2>
<p>text....</p>
<h2>another subsection</h2>
<p>text....</p>
<h2>yet another subsection</h2>
<p>more text....</p>
<h1>Another Header</h1>
<h2>subsection</h2>
<p>text....</p>
<h2>another subsection</h2>
<p>text....</p>
<h2>yet another subsection</h2>
<p>more text....</p>

To add counters in front of every h1, with counters on the h2s that reset after each h1, the CSS would look like:

h1 {
	counter-increment: headers;
	counter-reset: subsections;
	}
h1:before {
	content: counter(headers, upper-roman);
	}
h2 {
	counter-increment:subsections;
}
h2:before {
	content: counter(headers, upper-roman) "." counter(subsections, lower-roman) ":";
	}

Now all <h2>s are preceded by their header number and subsection number.

A few things to note about the code: note that in the h2:before declaration we’ve included two counters: the header counter and the subsection counter. We declared the style in both calls, as style is NOT inherited. Also, we’ve included strings within our declaration. Note that there are quotes delimiting our strings, but not our counters, and there are no concatenation elements without our content value. To combine multiple counter ID’s in the same style attribute, string them together using space delimited counter ID values.

Incrementing of the counter was done through the counter-increment declaration. While the default value is to increment by 1, we can increment by other values. You can also reset counters. It makes sense to reset subsections after every header. To overwrite the default value of 1, and to reset after each <h1> the CSS could be:

h1 {
  counter-increment: headers 10;
  counter-reset: subsections 5;
}
h2 {
  counter-increment:subsections 2;
}

Named, HSL and RGB Colors

CSS3 adds names colors from SVG and well as colors defined by Hue, Saturation and Lighness. Below is a table that lists all named colors along with their hexidecimal, RGB and HSL values.

Also, check out the CSS3 Color Converter

Named Color Hex RGB HSL
aliceblue #F0F8FF rgb(240,248,255) hsl(208, 100%, 97%)
antiquewhite #FAEBD7 rgb(250,235,215) hsl(34, 78%, 91%)
aqua / cyan #00FFFF rgb(0,255,255) hsl(180, 100%, 50%)
aquamarine #7FFFD4 rgb(127,255,212) hsl(160, 100%, 75%)
azure #F0FFFF rgb(240,255,255) hsl(180, 100%, 97%)
beige #F5F5DC rgb(245,245,220) hsl(60, 56%, 91%)
bisque #FFE4C4 rgb(255,228,196) hsl(33, 100%, 88%)
black #000000 rgb(0,0,0) hsl(0, 0%, 0%)
blanchedalmond #FFEBCD rgb(255,235,205) hsl(36, 100%, 90%)
blue #0000FF rgb(0,0,255) hsl(240, 100%, 50%)
blueviolet #8A2BE2 rgb(138,43,226) hsl(271, 76%, 53%)
brown #A52A2A rgb(165,42,42) hsl(0, 59%, 41%)
burlywood #DEB887 rgb(222,184,135) hsl(34, 57%, 70%)
cadetblue #5F9EA0 rgb(95,158,160) hsl(182, 25%, 50%)
chartreuse #7FFF00 rgb(127,255,0) hsl(90, 100%, 50%)
chocolate #D2691E rgb(210,105,30) hsl(25, 75%, 47%)
coral #FF7F50 rgb(255,127,80) hsl(16, 100%, 66%)
cornflowerblue #6495ED rgb(100,149,237) hsl(219, 79%, 66%)
cornsilk #FFF8DC rgb(255,248,220) hsl(48, 100%, 93%)
crimson #DC143C rgb(220,20,60) hsl(348, 83%, 58%)
cyan / aqua #00FFFF rgb(0,255,255) hsl(180, 100%, 50%)
darkblue #00008B rgb(0,0,139) hsl(240, 100%, 27%);
darkcyan #008B8B rgb(0,139,139) hsl(180, 100%, 27%)
darkgoldenrod #B8860B rgb(184,134,11) hsl(43, 89%, 38%)
darkgray / darkgrey #A9A9A9 rgb(169,169,169) hsl(0, 0%, 66%)
darkgreen #006400 rgb(0,100,0) hsl(120, 100%, 20%)
darkkhaki #BDB76B rgb(189,183,107) hsl(56, 38%, 58%)
darkmagenta #8B008B rgb(139,0,139) hsl(300, 100%, 27%)
darkolivegreen #556B2F rgb(85,107,47) hsl(82, 39%, 30%)
darkorange #FF8C00 rgb(255,140,0) hsl(33, 100%, 50%)
darkorchid #9932CC rgb(153,50,204) hsl(280, 61%, 50%)
darkred #8B0000 rgb(139,0,0) hsl(0, 100%, 27%)
darksalmon #E9967A rgb(233,150,122) hsl(15, 72%, 70%)
darkseagreen #8FBC8F rgb(143,188,143) hsl(120, 25%, 65%)
darkslateblue #483D8B rgb(72,61,139) hsl(248, 39%, 39%)
darkslategray / darkslategrey #2F4F4F rgb(47,79,79) hsl(180, 25%, 25%
darkturquoise #00CED1 rgb(0,206,209) hsl(181, 100%, 41%)
darkviolet #9400D3 rgb(148,0,211) hsl(282, 100%, 41%)
deeppink #FF1493 rgb(255,20,147) hsl(328, 100%, 54%)
deepskyblue #00BFFF rgb(0,191,255) hsl(195, 100%, 50%)
dimgray / dimgrey #696969 rgb(105,105,105) hsl(0, 0%, 41%)
dodgerblue #1E90FF rgb(30,144,255) hsl(210, 100%, 56%)
firebrick #B22222 rgb(178,34,34) hsl(0, 68%, 42%)
floralwhite #FFFAF0 rgb(255,250,240) hsl(40, 100%, 97%)
forestgreen #228B22 rgb(34,139,34) hsl(120, 61%, 34%)
fuchsia / magenta #FF00FF rgb(255,0,255) hsl(300, 100%, 50%)
gainsboro #DCDCDC rgb(220,220,220) hsl(0, 0%, 86%)
ghostwhite #F8F8FF rgb(248,248,255) hsl(240, 100%, 99%)
gold #FFD700 rgb(255,215,0) hsl(51, 100%, 50%)
goldenrod #DAA520 rgb(218,165,32) hsl(43, 74%, 49%)
gray / grey #808080 rgb(128,128,128) hsl(0, 0%, 50%)
green #008000 rgb(0,128,0) hsl(120, 100%, 25%)
greenyellow #ADFF2F rgb(173,255,47) hsl(84, 100%, 59%)
honeydew #F0FFF0 rgb(240,255,240) hsl(120, 100%, 97%)
hotpink #FF69B4 rgb(255,105,180) hsl(330, 100%, 71%)
indianred #CD5C5C rgb(205,92,92) hsl(0, 53%, 58%)
indigo #4B0082 rgb(75,0,130) hsl(275, 100%, 25%)
ivory #FFFFF0 rgb(255,255,240) hsl(60, 100%, 97%)
khaki #F0E68C rgb(240,230,140) hsl(54, 77%, 75%)
lavender #E6E6FA rgb(230,230,250) hsl(240, 67%, 94%)
lavenderblush #FFF0F5 rgb(255,240,245) hsl(340, 100%, 97%)
lawngreen #7CFC00 rgb(124,252,0) hsl(90, 100%, 49%)
lemonchiffon #FFFACD rgb(255,250,205) hsl(54, 100%, 90%)
lightblue #ADD8E6 rgb(173,216,230) hsl(195, 53%, 79%)
lightcoral #F08080 rgb(240,128,128) hsl(0, 79%, 72%)
lightcyan #E0FFFF rgb(224,255,255) hsl(180, 100%, 94%)
lightgoldenrodyellow #FAFAD2 rgb(250,250,210) hsl(60, 80%, 90%)
lightgray / lightgrey #D3D3D3 rgb(211,211,211) hsl(0, 0%, 83%)
lightgreen #90EE90 rgb(144,238,144) hsl(120, 73%, 75%)
lightpink #FFB6C1 rgb(255,182,193) hsl(351, 100%, 86%)
lightsalmon #FFA07A rgb(255,160,122) hsl(17, 100%, 74%)
lightseagreen #20B2AA rgb(32,178,170) hsl(177, 70%, 41%)
lightskyblue #87CEFA rgb(135,206,250) hsl(203, 92%, 75%)
lightslategray / lightslategrey #778899 rgb(119,136,153) hsl(210, 14%, 53%)
lightsteelblue #B0C4DE rgb(176,196,222) hsl(214, 41%, 78%)
lightyellow #FFFFE0 rgb(255,255,224) hsl(60, 100%, 94%)
lime #00FF00 rgb(0,255,0) hsl(120, 100%, 50%)
limegreen #32CD32 rgb(50,205,50) hsl(120, 61%, 50%)
linen #FAF0E6 rgb(250,240,230) hsl(30, 67%, 94%)
maroon #800000 rgb(128,0,0) hsl(0, 100%, 25%)
mediumaquamarine #66CDAA rgb(102,205,170) hsl(160, 51%, 60%)
mediumblue #0000CD rgb(0,0,205) hsl(240, 100%, 40%)
mediumorchid #BA55D3 rgb(186,85,211) hsl(288, 59%, 58%)
mediumpurple #9370DB rgb(147,112,219) hsl(260, 60%, 65%)
mediumseagreen #3CB371 rgb(60,179,113) hsl(147, 50%, 47%)
mediumslateblue #7B68EE rgb(123,104,238) hsl(249, 80%, 67%)
mediumspringgreen #00FA9A rgb(0,250,154) hsl(157, 100%, 49%)
mediumturquoise #48D1CC rgb(72,209,204) hsl(178, 60%, 55%)
mediumvioletred #C71585 rgb(199,21,133) hsl(322, 81%, 43%)
midnightblue #191970 rgb(25,25,112) hsl(240, 64%, 27%)
mintcream #F5FFFA rgb(245,255,250) hsl(150, 100%, 98%)
mistyrose #FFE4E1 rgb(255,228,225) hsl(6, 100%, 94%)
moccasin #FFE4B5 rgb(255,228,181) hsl(38, 100%, 85%)
navajowhite #FFDEAD rgb(255,222,173) hsl(36, 100%, 84%)
navy #000080 rgb(0,0,128) hsl(240, 100%, 25%)
oldlace #FDF5E6 rgb(253,245,230) hsl(39, 85%, 95%)
olive #808000 rgb(128,128,0) hsl(60, 100%, 25%)
olivedrab #6B8E23 rgb(107,142,35) hsl(80, 60%, 35%)
orange #FFA500 rgb(255,165,0) hsl(39, 100%, 50%
orangered #FF4500 rgb(255,69,0) hsl(16, 100%, 50%)
orchid #DA70D6 rgb(218,112,214) hsl(302, 59%, 65%)
palegoldenrod #EEE8AA rgb(238,232,170) hsl(55, 67%, 80%)
palegreen #98FB98 rgb(152,251,152) hsl(120, 93%, 79%)
paleturquoise #AFEEEE rgb(175,238,238) hsl(180, 65%, 81%)
palevioletred #DB7093 rgb(219,112,147) hsl(340, 60%, 65%)
papayawhip #FFEFD5 rgb(255,239,213) hsl(37, 100%, 92%)
peachpuff #FFDAB9 rgb(255,218,185) hsl(28, 100%, 86%)
peru #CD853F rgb(205,133,63) hsl(30, 59%, 53%)
pink #FFC0CB rgb(255,192,203) hsl(350, 100%, 88%)
plum #DDA0DD rgb(221,160,221) hsl(300, 47%, 75%)
powderblue #B0E0E6 rgb(176,224,230) hsl(187, 52%, 80%)
purple #800080 rgb(128,0,128) hsl(300, 100%, 25%)
red #FF0000 rgb(255,0,0) hsl(0, 100%, 50%)
rosybrown #BC8F8F rgb(188,143,143) hsl(0, 25%, 65%)
royalblue #4169E1 rgb(65,105,225) hsl(225, 73%, 57%)
saddlebrown #8B4513 rgb(139,69,19) hsl(25, 76%, 31%)
salmon #FA8072 rgb(250,128,114) hsl(6, 93%, 71%)
sandybrown #F4A460 rgb(244,164,96) hsl(28, 87%, 67%)
seagreen #2E8B57 rgb(46,139,87) hsl(146, 50%, 36%)
seashell #FFF5EE rgb(255,245,238) hsl(25, 100%, 97%)
sienna #A0522D rgb(160,82,45) hsl(19, 56%, 40%)
silver #C0C0C0 rgb(192,192,192) hsl(0, 0%, 75%)
skyblue #87CEEB rgb(135,206,235) hsl(197, 71%, 73%)
slateblue #6A5ACD rgb(106,90,205) hsl(248, 53%, 58%)
slategray / slategrey #708090 rgb(112,128,144) hsl(210, 13%, 50%)
snow #FFFAFA rgb(255,250,250) hsl(0, 100%, 99%)
springgreen #00FF7F rgb(0,255,127) hsl(150, 100%, 50%)
steelblue #4682B4 rgb(70,130,180) hsl(207, 44%, 49%)
tan #D2B48C rgb(210,180,140) hsl(34, 44%, 69%)
teal #008080 rgb(0,128,128) hsl(180, 100%, 25%)
thistle #D8BFD8 rgb(216,191,216) hsl(300, 24%, 80%)
tomato #FF6347 rgb(255,99,71) hsl(9, 100%, 64%)
turquoise #40E0D0 rgb(64,224,208) hsl(174, 72%, 56%)
violet #EE82EE rgb(238,130,238) hsl(300, 76%, 72%)
wheat #F5DEB3 rgb(245,222,179) hsl(39, 77%, 83%)
white #FFFFFF rgb(255,255,255) hsl(0, 100%, 100%)
whitesmoke #F5F5F5 rgb(245,245,245) hsl(0, 0%, 96%)
yellow #FFFF00 rgb(255,255,0) hsl(60, 100%, 50%)
yellowgreen #9ACD32 rgb(154,205,50 hsl(80, 61%, 50%);

CSS Value Lengths, Times, Frequencies and Angles

Many of the property values are keywords unique to that property. But for some properties, the values can include length, frequency or time values or units. In this article we go over all the math type units that can be applied as property values in CSS.

CSS Length Values

In terms of lengths, there are both relative and absolute lengths. Here is a quick summary of all of the length value types

unit meaning
em relative to the font size of the parent element.
ex relative to the height of the lowercase ‘x’
gd used in East Asian typography, not relevant to us
rem relative to the root font size
vw relative to the viewport width: the viewport width is 100vw
vh relative to the viewport height: the viewport height is 100vh
vm relative to viewport width or height, whichever is smaller
ch relative to the size of the 0 (zero)
px relative the screen resolution not the viewport size, : generally 1point, or 1/72 or an inch.
in an inch
cm a centimeter
mm millimeter
pt point is 1/72 of an inch
pc pica, or 1/12 of a point
% relative to the parent element, it’s normally defined self or other element defined by the property.

The most common value types in CSS include pixels and percents.

Pixels can be considered both a relative and absolute. Pixels are a relative measurement because the measurement is based on the screen resolution of the monitor or screen, rather than the viewport size. However, pixels are also an absolute size because lengths given in pixels are immutable: they can only be increased via zoom features.

Images, such as jpeg photos and gifs have an absolute width and height, defined in pixels. Increasing or decreasing the size of these image types with CSS or via the width and height attributes of the image tag distort the image.

Angles, Times and Frequencies:

With some of the new CSS3, such as transforms and animations, length units do not suffice. We also need to learn and understand angles, times and frequencies. These measurements have been around and used in aural style sheets, but now with browser support for transitions, transforms and animations, angles and times have become relevant to the screen as well. The units of angles, times and frequencies are shown and described in greater detail below.

unit meaning
deg degrees
grad grads
rad radians
turn turns
ms milliseconds
s seconds
Hz Hertz
kHz kilohertz

Originally, all of the above units, frequencies and times, other than the new ‘turn’ unit, were introduced as aural values. The units used for aural style sheets are angles, specified in rad (radians), deg (degrees), or grad (gradians). Frequencies are specified in Hz (Hertz) or kHz (kilohertz).

Times are specified in ms (milliseconds), or s (seconds). The default unit for all of the length, angle, time and frequency values is zero, and all the values are interpreted as floats.

CSS Angle Measurement

Angle measurement types include degrees, grads, rads and turns.

Degrees

Degrees range from 0 to 360deg, with those two being equal. Positive degrees go clockwise, negative degrees go counter clock wise. For example, -90deg is one quarter of the way around counter clock-wise, turning it on its left side. 90deg will turn it clockwise 90 degrees.
The CSS for the the image below reads (in part):

 .image1, image5 { 
                        -webkit-transform: rotate(-5deg);
                        -ms-transform: rotate(-5deg); 
                       transform: rotate(-5deg);
              }
  .image2, image4 {
                        -webkit-transform: rotate(7deg);
                        -ms-transform: rotate(7deg);
                      transform: rotate(7deg);
              }

polaroids_sm.jpg

Grads

A grad, or gradian, is equivalent to 1⁄400 of a full circle. Similar to degrees, a positive grad value will go clockwise, a negative value goes counter clockwise 100grad will be at a 90% angle. (see figure 4.4)

Rads

A rad, or radian, is equal to 180/π degrees, or about 57.3 degrees. An angle of 1 radian on a circumference of a circle creates an arc with an equal length to the radius of the circle. 1.570796326794897rad is the same value as 100grad and as 90deg.
angles.gif
90deg is the same as 100grad is the same as 1.508rad

Turns

Turns, are new in CSS3, and mean a rotation. One turn is equal to 360deg. For example, 2turn = 720deg. Note that turn is singular, and there is no space between the number and its unit..
rotate(900deg) is equivalent to rotate(2.5turn)

Times

Time units are much easier to explain than grads! There are two units of measurement: seconds (ms) and milliseconds (s). There are 1,000 milliseconds in a second. The format of a time value is a number followed by ‘s’ for seconds or ‘ms’ for milliseconds.
0.5s = 500ms

Frequencies

Frequency values are used with aural (or spoken) cascading style sheets. There are two value units: ‘Hz’, or Hertz and ‘kHz’ or kilohertz, 1,000Hz = 1kHz (case-insensitive). Frequencies can be used to change the pitch of a voice reading text. A low frequency is a bass sound, a high frequency is a treble. When CSS like the following snippet is used, a low-pitched voice, such

p.low { pitch: 105Hz; }
q.squeal {pitch: 135Hz;}

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 Transform Property and the various transform functions

The transform property

Supported in Firefox 3.5+. Opera 10.5 and Webkit since 3.1, the transform CSS property lets you modify the coordinate space of the CSS visual formatting model. Using it, elements can be translated, rotated, scaled, and skewed. We manipulate an elements appearance using transform functions. The value of the transform property is a list of space-separated transform functions applied in the order provided. The transform functions include:

translate()

The translate(x, y) function is similar to relative positioning, translating, or relocating, an element by x from the left, and y from the top.

  -webkit-transform: translate(15px, -15px); 
  -moz-transform: translate(15px, -15px);
  -o-transform: translate(15px, -15px); 
  transform: translate(15px, -15px);

 

translateX()

The translateX(x) function is similar to the translate() function above, but only the left/right value is specified

  -webkit-transform: translatex(15px);
  -moz-transform: translatex(15px);
  -o-transform: translatex(15px);
  transform: translatex(15px);

 

translateY()

The translateY(y) function is similar to the translate() function above, but only the top/bottom value is specified

  -webkit-transform: translatey(-15px); 
  -moz-transform: translatey(-15px); 
  -o-transform: translatey(-15px); 
  transform: translatey(-15px);

scale()

The scale(w, h) property scales an element by w width and h height. If only one value is declared, the scaling will be proportional. Since you likely don’t want to distort an element, you’ll generally see only one parameter in this transform function

  -webkit-transform: scale(1.5, 2);
  -moz-transform: scale(1.5, 2);
  -o-transform: scale(1.5, 2);
  transform: scale(1.5, 2);

scaleX()

The scalex(w) function is similar to the scale() function above, but only the width value is specified. It is the same as declaring scale(w, 1)

  -webkit-transform: scalex(0.5); 
  -moz-transform: scalex(0.5); 
  -o-transform: scalex(0.5); 
  transform: scalex(0.5);

scaleY()

The scaley(y) function is similar to the scale() function above, but only the height value is specified. It is the same as declaring scale(1, h)

  -webkit-transform: scaley(2);
  -moz-transform: scaley(2);
  -o-transform: scaley(2);
  transform: scaley(2);

rotate()

The rotate(angle) function with rotate an element about the point of origin (described below) but the angle value specified.

  -webkit-transform: rotate(15deg); 
  -moz-transform: rotate(15deg); 
  -o-transform: rotate(15deg); 
  transform: rotate(15deg)

skew()

The skew(x,y) function specifies a skew along the X and Y axes. The x specifies the skew on the x-axis, the y specifies the skew on the y-axis. If there is only one parameter, then it’s the same as skew(x, 0), or skewX(x) . The values are angles: degrees, turns or grads.

  -webkit-transform: skew(15deg,  4deg);
  -moz-transform: skew(15deg,  4deg);
  -o-transform: skew(15deg,  4deg);
  transform: skew(15deg,  4deg);

skewX()

The skewx(x) function is similar to the skew() value above, but only the x-axis value is specified. It is the same as declaring skew(x,0)

  -webkit-transform: skewx(15deg);
  -moz-transform: skewx(15deg);
  -o-transform: skewx(15deg);
  transform: skewx(15deg);

skewY()

The skewy(y) function is similar to the skew() value above, but only the y-axis value is specified. It is the same as declaring skew(0,y).

  -webkit-transform: skewy(-6deg); 
  -moz-transform: skewy(-6deg); 
  -o-transform: skewy(-6deg); 
  transform: skewy(-6deg);

Multiple transforms

The above show single transforms, but you can include more than one transform on an element. To include more than one transform, simply separate them the tranform functions with spaces.

  .enlargen:hover {
  	-webkit-transform: translate(-50%, -50%) scale(2) rotate(0); 
  	-moz-transform: translate(-50%, -50%) scale(2) rotate(0);
  	-o-transform: translate(-50%, -50%) scale(2) rotate(0);
  	transform: translate(-50%, -50%) scale(2) rotate(0);
  }

The above makes the element twice and tall and twice as wide. By translating the element 50% up and to the left, the bottom right corner should remain in the exact same location. The rotate(0) removes any possible rotation on the element.

This ‘enlargen’ class may be something you would want to add to an image gallery, hilighting an image that is hovered by making it four times larget (twice as wide and twice as tall) and remove any tilt that might have been interesting as a thumbnail but tacky in full size.

Introduction to GeoLocation

Geolocation allows users to share their physical location with your application if they choose to. Especially useful in social networking, geo tagging, and mapping, but applicable to any type of application, geolocation enables developers to enhance the user experience, making content, social graphs and advertisements more relevant to the location of the user.

The browser will request the permission of the user before accessing geolocation information. Geolocation is an opt in feature: when your web application requests Geolocation information, mobile browsers create an alert, and the desktop browser asks via banner that pops up at the top of the browser window asking permission to access location information. The user can grant permission or deny it, and optionally remember the choice on that site. If permission is granted, the Geolocation information will be accessible to your scripts and any third party scripts included in the page, letting your application determine the location of the user, and maintain location as the user moves around.

Location information is approximate, not exact, being garnered from IP addresses, cell towers, Wi-Fi networks, GPS, or even getting the information through manual data entry by the user.  The geolocation API does not care how the client determines location as long as the data is received in a staddard way. Because determining location can take time, the geolocation API is asynchronous.

To determing browser support for geolocation use:

if(navigator.geolocation) {
   //geolocation is supported
}

The geolocation object provides for the getCurrentPosition() method that asynchronously returns the user’s current location.

if(navigator.geolocation) {
   navigator.geolocation.getCurrentPosition(handle_success, handle_errors);
}

If successful, the callback function will return the current position with the coords property contains the more common latitude and longitude properties as well as the altitude, accuracy, altitudeAccuracy, heading and speed properties. The following script will return the alert the current latitude and longitude, and is available in the chapter files:

if(navigator.geolocation) {
 navigator.geolocation.getCurrentPosition(handle_success,handle_errors); 
 
function handle_success(position){ 
 alert('Latitude: ' + position.coords.latitude + '\n Longitude: ' + position.coords.latitude); 
 }
 
 function handle_errors(err) { 
 switch(err.code) 
    { 
   case err.PERMISSION_DENIED: alert("User refused to share geolocation data"); 
   break; 
 
   case err.POSITION_UNAVAILABLE: alert("Current position is unavailable"); 
   break; 
 
   case err.TIMEOUT: alert("Timed out"); 
   break; 
 
   default: alert("Unknown error"); 
   break; 
  }
 } 

 

}

The draft specification can be found at http://dev.w3.org/geo/api/spec-source.html#geolocation_interface. Geolocation is support in Firefox, Webkit and Opera, but not IE. It is anticipated that it will be supported in IE9.

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 Transform Property and the various transform functions

The transform property

Supported in Firefox 3.5+. Opera 10.5 and Webkit since 3.1, the transform CSS property lets you modify the coordinate space of the CSS visual formatting model. Using it, elements can be translated, rotated, scaled, and skewed. We manipulate an elements appearance using transform functions. The value of the transform property is a list of space-separated transform functions applied in the order provided. The transform functions include:

translate()

The translate(x, y) function is similar to relative positioning, translating, or relocating, an element by x from the left, and y from the top.

  -webkit-transform: translate(15px, -15px); 
  -moz-transform: translate(15px, -15px);
  -o-transform: translate(15px, -15px); 
  transform: translate(15px, -15px);

 

translateX()

The translateX(x) function is similar to the translate() function above, but only the left/right value is specified

  -webkit-transform: translatex(15px);
  -moz-transform: translatex(15px);
  -o-transform: translatex(15px);
  transform: translatex(15px);

 

translateY()

The translateY(y) function is similar to the translate() function above, but only the top/bottom value is specified

  -webkit-transform: translatey(-15px); 
  -moz-transform: translatey(-15px); 
  -o-transform: translatey(-15px); 
  transform: translatey(-15px);

scale()

The scale(w, h) property scales an element by w width and h height. If only one value is declared, the scaling will be proportional. Since you likely don’t want to distort an element, you’ll generally see only one parameter in this transform function

  -webkit-transform: scale(1.5, 2);
  -moz-transform: scale(1.5, 2);
  -o-transform: scale(1.5, 2);
  transform: scale(1.5, 2);

scaleX()

The scalex(w) function is similar to the scale() function above, but only the width value is specified. It is the same as declaring scale(w, 1)

  -webkit-transform: scalex(0.5); 
  -moz-transform: scalex(0.5); 
  -o-transform: scalex(0.5); 
  transform: scalex(0.5);

scaleY()

The scaley(y) function is similar to the scale() function above, but only the height value is specified. It is the same as declaring scale(1, h)

  -webkit-transform: scaley(2);
  -moz-transform: scaley(2);
  -o-transform: scaley(2);
  transform: scaley(2);

rotate()

The rotate(angle) function with rotate an element about the point of origin (described below) but the angle value specified.

  -webkit-transform: rotate(15deg); 
  -moz-transform: rotate(15deg); 
  -o-transform: rotate(15deg); 
  transform: rotate(15deg)

skew()

The skew(x,y) function specifies a skew along the X and Y axes. The x specifies the skew on the x-axis, the y specifies the skew on the y-axis. If there is only one parameter, then it’s the same as skew(x, 0), or skewX(x) . The values are angles: degrees, turns or grads.

  -webkit-transform: skew(15deg,  4deg);
  -moz-transform: skew(15deg,  4deg);
  -o-transform: skew(15deg,  4deg);
  transform: skew(15deg,  4deg);

skewX()

The skewx(x) function is similar to the skew() value above, but only the x-axis value is specified. It is the same as declaring skew(x,0)

  -webkit-transform: skewx(15deg);
  -moz-transform: skewx(15deg);
  -o-transform: skewx(15deg);
  transform: skewx(15deg);

skewY()

The skewy(y) function is similar to the skew() value above, but only the y-axis value is specified. It is the same as declaring skew(0,y).

  -webkit-transform: skewy(-6deg); 
  -moz-transform: skewy(-6deg); 
  -o-transform: skewy(-6deg); 
  transform: skewy(-6deg);

Multiple transforms

The above show single transforms, but you can include more than one transform on an element. To include more than one transform, simply separate them the tranform functions with spaces.

  .enlargen:hover {
  	-webkit-transform: translate(-50%, -50%) scale(2) rotate(0); 
  	-moz-transform: translate(-50%, -50%) scale(2) rotate(0);
  	-o-transform: translate(-50%, -50%) scale(2) rotate(0);
  	transform: translate(-50%, -50%) scale(2) rotate(0);
  }

The above makes the element twice and tall and twice as wide. By translating the element 50% up and to the left, the bottom right corner should remain in the exact same location. The rotate(0) removes any possible rotation on the element.

This ‘enlargen’ class may be something you would want to add to an image gallery, hilighting an image that is hovered by making it four times larget (twice as wide and twice as tall) and remove any tilt that might have been interesting as a thumbnail but tacky in full size.