CSS Text-Shadow in Safari, Opera, Firefox and more

29 Sep

The CSS 2 property text-shadow is supported in Safari since version 3 (also available for Windows), Opera since 9.5, Firefox since 3.1, Google Chrome since version 2, Konqueror and iCab. In fact, text-shadow is supported by all browsers that are based on WebKit, the rendering engine behind Safari and Chrome. Internet Explorer 8 does not support such text shadows (except for some DirectX image transform filters).

Animated multiple Shadows (requires JavaScript)

Start/stop animations.

element.style.textShadow = "…";

Text shadows were defined in 1997 and became applicable in 2009

element.style.textShadow = "…";

Text shadows were defined in 1997 and became applicable in 2009

Multiple Shadows

Safari 3 supported one shadow only. Only the first shadow was displayed. Safari 4 supports multiple shadows. Opera 9.5 supported at most six shadows. Later, this limitation was dropped. Please note that Opera painted the shadows in the wrong order. This was fixed in Opera 10.5.

text-shadow: -1px -1px #666, 1px 1px #FFF;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 1px 1px 3px #666, -1px -1px 3px #FFF, 1px 1px #666, -1px -1px #FFF;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 -1px #000, 1px 0 #000, 0 1px #000, -1px 0 #000;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 1px 0 #F33, -1px 0 #33F;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 2px 0 4px #600, -2px 0 4px #006;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 6px 4px #33F, -3px -5px 4px #F00, 3px -5px 4px #0F0;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 24px #C00, 0 0 4px #C00, 1px 1px 2px #333;Text shadows were defined in 1997 and became applicable in 2009

Classical Shadows

text-shadow: 1px 1px 2px #999;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 2px 2px 3px #999;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 8px #000;Text shadows were defined in 1997 and became applicable in 2009

Glowing Borders

text-shadow: 0 0 11px #0F0;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 5px #FF0;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 3px #F90;Text shadows were defined in 1997 and became applicable in 2009

Unusual Effects

text-shadow: 0 7px 11px #390;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0px -15px 0 #F00;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 11px #FF6;Text shadows were defined in 1997 and became applicable in 2009

text-shadow: 0 0 8px #000;Text shadows were defined in 1997 and became applicable in 2009

Text-Shadow Exposed: Make cool and clever text effects with css text-shadow

29 Sep

The aim of this article is to give you a quick introduction of a css property named text-shadow which was first included in CSS2 (but it’s not implemented in all browsers yet). Nevertheless you can make some cool effects with it, which could only be done before by photoshopping text and rendering it as an image.

Because it’s included in Safari since version 1.1(!) Mac users should be aware of various effects done by this property. In fact, most companys and persons with mac users as their main target audience use this effect on their websites.

This article describes how text-shadow works, what you can do with it and which browsers currently support it. At the end of this article I’ve made up some examples and provide a list of useful resources.

 

Here’s an overview of the headlines in this article. As you can see it’s rather complex and long. Be sure to get a delicious fresh cup of coffee or tea before reading on:

  1. What text-shadow is good for
  2. Which browsers support it
  3. Cross-browser compatibility
  4. How does it work and how to use it
  5. Examples with code & demos
  6. Hack: Safari Text Rendering
  7. More articles and resources

1. What text-shadow is good for

kremalicious navbar

subtle glow in my navigation

The main goal of this property is to give designers and css coders a tool to make text effects, which could only be done before by rendering text as images with all the side effects. Text rendered as an image isn’t searchable and therefore very undelicious for search engines. Another side effect is the fact that images can be way more bigger as one small line of code in terms of file size. As you may know most css-files, which contain the whole layout of a website, are smaller than one image on most websites. So it’s really clever to use a css function instead of images for reducing unnecessary traffic.

text-shadow used on apple.com

text-shadow on Apple.com

Utilizing text-shadow to simulate engraved or stenciled text is widely used on websites. Apple did it everywhere in Mac OS X not just since Leopard (just look at the titlebars). So if you design a website for Mac users you can increase the sexyness of your website, because this particular usage of text-shadow integrates very well with the overall look of Mac OS X. I will explain how to achieve this engraved-text-on-metal effect later on in this article.

2. Which browsers support it?

Safari iconOpera icon
Firefox iconGoogle Chrome iconIn fact, text-shadow is not a new property since it was first defined with CSS2 in 1998 but it was just implemented by the KHTML/WebKit-folks. But it’s available in Safari since version 1.1 (2003), in Konqueror since version 3.4 (I believe, not sure) and Opera9.5. Furthermore it’s also supported by Firefox 3.1/3.5 and finallyGoogle Chrome 2 adds full support for the text-shadow property after they had stripped this from the first version of Chrome.

On the Mac platform WebKit is also used in various other programs with a browser included like Coda from Panic, CSSedit from MacRabbit or NetNewsWire from NewsGator. Also every browser which is powered by the WebKit engine is able to render the text-shadow property, like ShiiraOmniWeb or Epiphany which are either for Mac or Linux.

But with Safari 3.1, the beta release of Opera 9.5, Firefox 3.1 and Google Chrome 2 the text-shadow property is finally finding it’s way to the Windows desktop after 10 years of it’s birth and Opera is the first non-WebKit browser which supports text-shadow.

Here’s a list of some browsers and their compatibilty for the text-shadow property to give you an overview:

Safari 3.1 (Mac/Win) yes, but no multiple shadows
Safari 4 (Mac/Win) yes, full support
Opera 9.5 (Mac/Win/Lin) yes, full support
Firefox 2/3 (Mac/Win/Lin) no
Firefox 3.1/3.5 (Mac/Win/Lin) yes, full support
Google Chrome 1 (Win) no
Google Chrome 2 (Win) yes, full support
IE 7/8 (Win) no
Shiira (Mac) yes, but no multiple shadows
Konqueror (Lin/Mac/Win) yes, full support
iCab (Mac) yes, but no multiple shadows
Epiphany (Lin) yes, since April 2008
Safari on iPhone yes, but no multiple shadows
Nokia Symbian-Smartphones (Series 60) yes
Opera Mini 4.1 yes, no blur radius

But wait, regarding Safari on Mac OS X there’s one more (bad) thing to remember. The Mac OS X 10.5.2 update resulted in minor changes of the WebKit text-shadow rendering. It seems that with this update text-shadow is finally rendered correctly as WebKit added one extra pixel to the shadow offset on 10.4.11 and 10.5.1.

3. Any chance of cross-browser compatibility?

So the major browser Internet Explorer doesn’t support it yet but just don’t count on Internet Explorer. I guess they are happy withcoding their own non-standard version of CSS for IE9 and making shadows with those DXImageTransform.Microsoft.Shadow-stuffwhich in the end just looks horrible. So even IE 9 won’t have it included.

But with Firefox 3.1 including text-shadow all major browsers except Internet Explorer are now supporting it. So you can start using it all around your next projects just with a lot of other techniques which in the end aren’t available in Internet Explorer.

One cross-browser trick would be to use conditional tags and serve Internet Explorer users different stylesheets with either a cross-browser compatible hack or via the old school way with text rendered as images. If you don’t need the blur radius value for your desired effect than there’s a nice idea on Design Meme for this problem which includes producing a shadow with the css pseudo-element :before.

Now that you’re aware of it’s compatibility with the various browsers we can take a look at the syntax of the text-shadow property.

4. How does it work and how to use it

When defined in a css-stylesheet the property syntax should look like this:

p { text-shadow: 1px 1px 1px #000; }

The first two values specify the length of the shadow offset. The first value specifies the horizontal distance and the second specifies the vertical distance of the shadow. The third value specifies the blur radius and the last value describes the color of the shadow:

1. value = The X-ccordinate
2. value = The Y-coordinate
3. value = The blur radius
4. value = The color of the shadow

Using positive numbers as the first two values ends up with placing the shadow to the right of the text horizontically (first value) and placing the shadow below the text vertically (second value).

The third value, the blur radius, is an optional value which can be specified but don’t have to. It’s the amount of pixels the text is stretched which causes a blur effect. If you don’t use the third value it is threated as if you sepcified a blur radius of zero.

Alternatiely, for WebKit-based browsers, you can use rgba values instead of hex code colors as the fourth value. The last number stands for transparency and can be set between 0.0 and 1.0 so you can make the text-shadow more subtle:

p { text-shadow: 1px 1px 1px rgba(255,255,255, .5); }

Of course the effects done by this property often depend on the colors of your text and your background, so let’s take a look at what we can do with all those combinations.

5. Examples with code & demos

I’ve made up some examples to show you the possibilities of this css property. Every example code follows a text example which is rendered by your browser. Below that you’ll find a screenshot of the described effect rendered in Safari 3.1 on Mac OS X 10.5.2 so the non-WebKit and non-Opera Internet Explorer users can see the effect.

5.1 Simple drop shadow

With the following lines of css code you get black text on white background with a smooth black drop shadow.The shadow is placed 2 pixels right and 2 pixels below the text and has a blur radius of 3:

color: #000;
background: #fff;
text-shadow: 2px 2px 3px #000;
I’m a text with a smooth shadow

image

Or you can make it not so smooth but also good looking by ignoring the blur radius and setting a lighter color for the shadow:

color: #000;
background: #fff;
text-shadow: 2px 2px #000;
I’m a text with no smooth shadow

image

Using some negative values you can make the shadow look like it’s lightsource is placed below the text:

color: #000;
background: #fff;
text-shadow: 2px -2px 3px #000;
I’m a text with a smooth shadow

image

Of course you can make it more funky and horrible to read:

color: #33cc33;
background: #fff;
text-shadow: 2px 2px 2px #ff3300;
I’m funky colored text

image

5.2 Apple style (engraved text on metal)

With those lines you get this engraved-text-on-metal effect often used by Apple. You should use a grey background and a very dark text color for this. It’s nothing more than a white or light grey shadow which is placed 1px below the text. You can use a blur of 1 to make it look more round. I’ve used bold text to make the effect more visible:

color: #000;
background: #666;
text-shadow: 0px 1px 1px #fff;
I’m engraved text

image

This even works the other way around on a black background with grey text by adjusting only the color values:

color: #666;
background: #000;
text-shadow: 0px 1px 0px #ccc;
I’m engraved text on black

image

Or you can make this one which looks like the text stands out from the background:

color: #fff;
background: #666;
text-shadow: 0px 1px 1px #000;
I’m on top of the background

image

5.3 Make your text glow

By utilizing the blur radius we can achieve some interesting effects. Here’s some subtle glowing white text on a black background:

color: #fff;
background: #000;
text-shadow: 1px 1px 6px #fff;
I’m subtle glowing text

image

You can also make the whole text blurry by using the same color for text and shadow with no offset:

color: #fff;
background: #666;
text-shadow: 0px 0px 3px #fff;
I’m also glowing but more blurry

image

We can make it quite mysterious by using the same color for text and background and make the text just visible through text-shadow. Remember that the same color for text and background can be bad for usability…:

color: #000;
background: #000;
text-shadow: 1px 1px 4px #fff;
I’m pretty mysterious looking text

image

Or the other way around to make it look light and… milky:

color: #fff;
background: #fff;
text-shadow: 1px 1px 4px#000;
I’m pretty milky looking text

image

5.4 Dublicate your text

With text-shadow you can make pixel-perfect dublicates of any text. Just add some pixels to your font-size and use it as a value for the vertical description of the shadow offset:

color: #000;
background: #fff;
text-shadow: 0px 20px #000;
Which line is text, which is shadow?

image

5.5 Multiple shadows

Sadly Safari 3 isn’t able to render more than one shadow on one element. It just renders the first property description and will ignore all others. But using multiple shadows looks awesome. So currently the following will only work in Opera 9.5 beta or Konqueror. Just have a look at the screenshot below the example if you’re not using these browsers. Due to the lack of support for this in Safari the screenshot below the example is rendered in Opera 9.5 beta on Mac OS X 10.5.2. For no reason Opera 9.5 beta doesn’t render the background color:

color: #000;
background: #000;
text-shadow: 0 0 4px #ccc, 0 -5px 4px #ff3, 2px -10px 6px #fd3, -2px -15px 11px #f80, 2px -18px 18px #f20;
Isn’t this awesome?

image

6. Hack: Avoid jagged light-on-dark text rendering in Safari

sub-pixel rendering

sub-pixel rendering (click to zoom)

More than a hack than an effect but it addresses the poor light-on-dark text rendering in Safari. This is caused by the sub-pixel rendering of OS X’s Quartz 2D layer as a part of the Core Graphics framework. Also Safari 3.1 on Windows uses sub pixel rendering instead of plain anti-aliasing.

anti-alias rendering through text-shadow

anti-alias rendering through text-shadow (click to zoom)

In most situations this improves the legibility and smoothness of all 2D-text rendered throughout the Mac OS X interface which makes everything look so gorgeous. But it has some rough problems with light text on dark backgrounds in Safari This problem doesn’t exist when using anti-aliasing.

And since 24ways’ and Cameron’s discovery we know that Safari renders all text-shadow-styled text with plain anti-aliasing instead of sub-pixels. So we can add a text-shadow with an offset of 0px to the desired text style:

text-shadow: 0 0 0 #000;

This causes Safari 3 to use anti-aliasing and make your text on dark backgrounds more legible with it.

But this won’t work with the new Safari 4 (public beta) as John pointed out in the comments. To just cite him:

Apparently if your shadow has no blur, then the text will be sub-pixel rendered. But more than 1px blurred uses the anti-alias rendering like “usual.”

But fear not. Rogie King already came up with a solution for this which you can read here:

Create a Grid Based Web Design in HTML5 & CSS3

29 Sep

Follow this step by step walkthrough of the making of a sleek website design for an eyewear brand in HTML5 and CSS3. We’ll build the HTML structure with the latest elements then style up the appearance of the site with CSS3 affects to match the original Photoshop concept with minimal use of background images.

 

The design concept

Optik website design concept

The design we’ll be coding up is for a fictional eyewear brand named OPTIK. If you’re interested in seeing how the design concept was created in Photoshop, head over to Blog.SpoonGraphics so see part one of the tutorial. Essentially the page is based on an underlying grid and features a few key focal elements to direct the user towards the various ranges of eyewear.

View the Photoshop design tutorial

Exporting the images

I know I mentioned we’d build the website with minimal background images, but there’s still a few graphics that need pulling out of the Photoshop concept that just can’t be recreated in HTML or CSS (…yet!). The first of those graphics is the patterned background. Copy and export a selection so that the pattern will repeat seamlessly when tiled.

We’ll create the gradients used on the feature area with CSS3, but we’ll need to export the actual photograph. Draw a tight selection around the character and save for web as a JPEG.

In the original concept we saved two versions of the range graphics. Copy both into a new document to create mini sprite images then export as JPEGs.

This design was created according to columns and a baseline grid. Export a copy of the grid image from Photoshop. We’ll add this as a temporary background image so we can easily line up the elements with CSS to replicate the grid based layout.

The HTML structure

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>OPTIK</title>

<link href="style.css" rel="stylesheet" />

</head>

<body>

</body>
</html>

The HTML file begins with a typical document structure of Doctype, page title, link to CSS stylesheet and the opening & closing body tags. The simple HTML5 Doctype really looks great when compared to the long versions of HTML4 and XHTML.

<div id="container">
	<header>
		<h1><a href="#"><img src="images/optik-logo.png" alt="Return to the homepage" /></a></h1>
		
		<nav>
			<ul>
				<li><a href="#">Sun</a></li>
				<li><a href="#">Sport</a></li>
				<li><a href="#">Tech</a></li>
				<li><a href="#">Special</a></li>
			</ul>
		</nav>
	</header>	

A typical container div is added to ‘contain’ the elements to help centre everything up, then we can get stuck in to some fancy HTML5 tags/elements with<header>. As the name suggests, <header> is used to outline an introduction or group of navigation elements and is used in place of the traditional<div id="header"> code we usually use.
<nav> is another new element we can make use of, which identifies a section of navigation. Inside this element a normal unordered list lays out the four navigation links.

	<section id="feature">
		<a href="#"><img src="images/feature-image.jpg" alt="Man wearing Hydrotek sunglasses" /></a>
		<div id="feature-info">
			<a href="#"><h2>Hydrotek</h2></a>
			<p>HYDRO-TEK sports eyewear from OPTIK optimizes the flow of perspiration for an increased aerodynamic advantage over your competition.</p>
			<p><a href="#">Find out more</a></p>
		</div>
	</section>

Where we would previously use divs to create major structural areas of a webpage, in HTML5 we can use the <section> tag. <section> is used along with an ID to identify a clear ‘section’ of the document, such as the feature area at the top of the page. The photo of the guy wearing sunglasses could be added as a background image, but I expect users to naturally try to click it, so adding it as an <img> inside an anchor will allow us to link it up to its relative content.
<h2> and <p> elements semtantically lay out the few lines of content, with a class of ‘btn’ allowing us to style up that particular link as a button graphic later. All these elements will need floating next to the image, so a simple div helps group them all together.

	<section id="content">
		<div>
			<a href="#" id="sun">Sun range of OPTIK eyewear</a>
			
			<p>Enjoy the summer sun in style with OPTIK's range of casual eyewear. Choose from an array of fashionable frames and styles.</p>
			
			<p><a href="#">View the SUN range</a></p>
		</div>
		
		<div>
			<a href="#" id="sport">Sport range of OPTIK eyewear</a>
			
			<p>Protect and enhance your vision with the SPORT range of eyewear from OPTIK to give yourself the edge over your competition.</p>
			
			<p><a href="#">View the SPORT range</a></p>
		</div>
		
		<div>
			<a href="#" id="tech">Technicaly information about OPTIK eyewear</a>
			
			<p>Find out more about the science behind the materials, geometry and coatings that make OPTIK lenses so technologically advanced.</p>
			
			<p><a href="#">View the TECH info</a></p>
		</div>
		
		<div>
			<a href="#" id="special">Special range of OPTIK eyewear</a>
			
			<p>OPTIK also design eyewear for specific industries where eye protection is crucial. Make sure your team has the best optical safety.</p>
			
			<p><a href="#">View the SPECIAL range</a></p>
		</div>
	</section>	

Another <section> tag outlines the main content area, followed by four separate divs with a class of ‘bucket’ to lay out the four boxes seen on the design concept. Inside each of these boxes the images will need adding with CSS to allow the sprite hover effects to work, so they are created in HTML as simple anchors with a descriptive anchor text introducing the section.

</div>

<footer>
	<p id="copyright">&copy; Copyright OPTIK 2011</p>
	<ul>
		<li><a href="#">About</a></li>
		<li><a href="#">Retailers</a></li>
		<li><a href="#">Corporate</a></li>
		<li><a href="#">Warranty</a></li>
		<li><a href="#">News</a></li>
		<li><a href="#">Contact</a></li>
	</ul>
	
	<p id="back-top"><a href="#">Back to top</a></p>
	
</footer>


</body>
</html>

The footer appears below the main content panel in the concept so the container div is closed before the <footer> tag opens. Just like <header>,<footer> is a new structural tag that replaces the old method of <div id="footer">.
The <ul> in the footer isn’t enclosed in a <nav> element because of guidelines in the HTML5 spec:

It is common for footers to have a short list of links to various pages of a site, such as the terms of service, the home page, and a copyright page. The footer element alone is sufficient for such cases.

The complete HTML

View the complete HTML

The CSS styling

body, div, h1, h2, h3, h4, h5, h6, p, ul, ol, li, dl, dt, dd, img, form, fieldset, input, textarea, blockquote {
	margin: 0; padding: 0; border: 0;
}

body {
	font: 14px Helvetica, Sans-Serif; line-height: 24px; color: #a6a6a6;
	background: #000 url(images/bg-pattern.png);
}

#container {
	width: 960px; margin: 0 auto 24px auto; background: #000; /*background: url(images/grid.png) center top no-repeat;*/
	box-shadow: 0px 5px 45px #343434;
	-moz-box-shadow: 0px 5px 45px #343434;
	-webkit-box-shadow: 0px 5px 45px #343434;
}

a {
	color: #abe2ff; text-decoration: none;
}
	a:hover {
		color: #5db5e3;
	}

Onto the CSS! First we clean things up with a simple reset and declarations to the body to set the global styling. Then the container div is centered up and given the outer glow styling from the Photoshop concept with CSS3 box-shadow. Remember that grid used in Photoshop? We can add that as a temporary background image to allow us to align all the page elements exactly into place.

header h1 {
	margin: 54px 0 0 21px; float: left;
}

header nav {
	float: left;
	margin: 79px 0 17px 0;
}
	header nav ul li {
		float: left; list-style: none;
		width: 58px; margin: 0 0 0 98px;
	}
		header nav ul li a {
			text-transform: uppercase;	
		}

Next up the header items are moved into place according to the grid with simple margins. This is where the Firebug plugin for Firefox comes in handy so you can edit the figures live in order to achieve pixel perfection.

#feature {
	clear: both; height: 431px; overflow: hidden; margin: 0 0 48px 0;
	background: #000;
	background: -moz-linear-gradient(top, #000 0%, #191919 5%, #000 5%, #000 94%, #191919 94%, #000 100%);
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#000), color-stop(5%,#191919), color-stop(5%,#000), color-stop(94%,#000), color-stop(94%,#191919), color-stop(100%,#000));
	background: -webkit-linear-gradient(top, #000 0%,#191919 5%,#000 5%,#000 94%,#191919 94%,#000 100%);
	/*opacity: 0.5;*/
}
	#feature h2 {
		width: 216px; height: 30px; margin: 0 0 31px 0;
		background: url(images/hydrotek.png); text-indent: -9999px;
	}
	#feature img {
		float: right; margin: 22px 0 0 0;
	}
	#feature-info {
		float: left; width: 370px; margin: 89px 0 0 100px;
	}
		#feature-info p {
			margin: 0 0 34px 0; font-size: 16px;
		}
		#feature-info p.btn a {
			display: block; width: 170px; height: 35px;
			background: #497389;
			background: -moz-linear-gradient(top, #497389 0%, #151e36 100%);
			background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#497389), color-stop(100%,#151e36), color-stop(100%,#000));
			background: -webkit-linear-gradient(top, #497389 0%,#151e36 100%);
			border: 1px solid #313e52;
			border-radius: 10px;
			-moz-border-radius: 10px;
			-webkit-border-radius: 10px;
			text-transform: uppercase; text-align: center; padding: 12px 0 0 0;
		}

We can really start going to town with CSS3 styling on the feature section. In the concept there’s a gradient glow above and below the feature area. We could replicate this in CSS3 with box-shadow or CSS gradients. Here I’ve gone for the gradient approach with the help of the handy CSS Gradient Generator tool, which makes it easy to match the format from Photoshop.
The <h2> uses a non-web font so a simple CSS image replacement technique switches the default H2 text for an image. The text content and image is moved into place, then the “btn” class is given some styling to convert it into a button style graphic. display:block; converts it into a block element so a width and height can be added, then another CSS gradient is generated to flow from dark to light blue. border-radius then rounds off the corners and the text is set to uppercase and bumped into position vertically using a touch of padding.
Tip: Use opacity: 0.5; as a temporary declaration on the feature section so you can see the underlying grid lines.

#content {
	overflow: hidden; clear: both;
}
	#content .bucket {
		width: 212px; float: left; margin: 0 0 48px 20px;
		border: 1px solid #262626;
		background: #000;
		background: -moz-linear-gradient(top, #000 0%, #000 39%, #191919 39%, #000 100%);
		background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#000), color-stop(39%,#000), color-stop(39%,#191919), color-stop(100%,#000));
		background: -webkit-linear-gradient(top, #000 0%,#000 39%,#191919 39%,#000 100%);
	}
		#content .bucket:first-child {
			margin: 0 0 0 22px;
		}
	
	#content #sun, #content #sport, #content #tech, #content #special {
		display: block; width: 212px; height: 143px;
		margin: 0 0 32px 0; text-indent: -9999px;
	}
		#content #sun { background: url(images/sun.jpg); }
		#content #sport { background: url(images/sport.jpg); }
		#content #tech { background: url(images/tech.jpg); }
		#content #special { background: url(images/special.jpg); }
	
		#content #sun:hover, #content #sport:hover, #content #tech:hover, #content #special:hover {
			background-position: 0 -143px;
		}
		
		#content .bucket p {
			margin: 0 0 24px 0; padding: 0 13px 0 13px;
		}

The four buckets in the content area can then be styled up with a specific width and margin and floated side by side. A simple border and another background gradient help replicate the shadow underneath the header images in the concept. To match the layout to the grid the first bucket’s margin is adjusted using thefirst-child selector.
All the header images can be grouped together for some general CSS such as the width, height and margin. text-indent: -9999px; shifts the default text off screen, then the specific background image for each link is added. These images has a hover state included in the basic sprite, so all anchors are set to move the background position on hover.

footer {
	width: 960px; margin: 0 auto; height: 80px;
	font-size: 12px;
}
	footer #copyright {
		float: left; margin: 0 0 0 22px;
	}
	
	footer ul {
		float: left; margin: 0 0 0 134px; list-style: none; overflow: hidden;
		
	}
		footer li {
			float: left; margin: 0 10px 0 10px;
		}
	
	footer #back-top {
		float: right; margin: 0 22px 0 0;
	}
		footer #back-top a {
			background: url(images/optik-logo-sm.png) left no-repeat; padding: 5px 0 5px 40px;
		}

Finally the footer area can be styled to finish off the page. Because it’s outside the container div it first needs moving into position with the 960px width andmargin: 0 auto; declarations. Then each of the three elements can be floated side by side and moved into place with margins.

The complete CSS

View the complete CSS

Patching up IE

Needless to say, Internet Explorer doesn’t support these fancy new HTML5 and CSS3 goodies. Our CSS will simply degrade back to non CSS3 styling, so there will be no gradients or round corners. The HTML5 tags on the other hand won’t be recognised at all, which will bork the layout altogether. Luckily there’s a snippet of code you can add to the head of your page to render the tags as normal elements:

<!--[if IE]>
<script>
  document.createElement('header');
  document.createElement('footer');
  document.createElement('section');
  document.createElement('nav');
</script>
<![endif]-->

Then you can simply create a conditional stylesheet to fix up the mess IE makes of your standard CSS. With this tutorial being a HTML5/CSS3 demonstration, I’ll leave those exciting fixes for another time…

The final website design

View the demo

Our final coded website matches the original Photoshop concept identically with the help of a few CSS3 features and looks cool under the hood with the new HTML5 tags. Check out the demo in the latest Firefox, Safari or Chrome browsers.

Happy 10th Birthday Firefox!

29 Sep

On September 23, 2012 Mozilla Firefox celebrated its tenth birthday. Or, more specifically, the browser project which ultimately became Firefox was released on September 23, 2002.

Phoenix, as it was then known, was an experimental browser developed by Blake Ross, Dave Hyatt, Pierre Chanial and Joe Hewitt. The amusing version 1.0 (Pescadero) release page remains live today and you can even download the installation (extract and run — no user-friendly installers here).

Mozilla Phoenix

There have been a few obvious interface changes in the past decade, but features such as tabs, preferences and the JavaScript console remain recognizable.

The 2002 Browser Market

In 2002, Internet Explorer 6.0 reigned supreme with a 90%+ market share. Microsoft’s business tactics may have been questionable, but IE had little competition:

  • Opera was good and had a passionate following, but the commercial software was more expensive than the alternatives.
  • Netscape 4.x was an abomination. It’s few remaining users were ditching the old browser.
  • The Netscape 6+ and Mozilla 1+ suites used the same code base and were slow, buggy and bloated. Few people needed a multi-megabyte installation which contained a browser, email client, newsgroup reader, address book, chat client, web page editor, developer tools and Palm Pilot synchronization.

Despite the hassle IE6 caused in later years, the browser’s success was largely deserved.

Phoenix Rises From the Ashes

Phoenix evolved because the developers believed Netscape’s commercial requirements and Mozilla’s scope creep compromised the browser’s future. They wrapped the Gecko rendering engine in a lightweight shell, removed unnecessary features and introduced the concept of add-ons.

If you think Firefox releases appear rapidly today, Phoenix 0.2 was released within one week. Version 0.3 appeared on October 16 2002, 0.4 on October 31 and 0.5 on December 7. The browser had started to gain momentum in the developer community. Like many, I had it installed although still used IE6 as my default.

Following trademark issues with Phoenix Technologies, the browser was renamed “Firebird” and version 0.6 appeared on May 16, 2003 for Windows, Mac and Linux. Versions 0.6.1 and 0.7 appeared in July and October 2003 respectively. These editions changed everything:

  • the browser had overtaken IE6 in terms of standards support, stability, speed and functionality
  • a thriving set of add-ons also provided developers with tools that had been sorely lacking
  • while it was still a beta release, developers spread the word and non-technical users began to install the application
  • many people adopted it as their default browser
  • Mozilla scrapped their browser suite to concentrate on Firefox and the Thunderbird email client (originally named Minotaur).

Fox Eats Bird

The Firebird name didn’t last long, particularly as it clashed with the open source Firebird database server. Following delays in the trademarking process, the browser was re-branded “Firefox” on February 10, 2004. Reactions were mixed — partly because it shared its name with the dire 1982 Clint Eastwood movie — but it stuck and Firefox 1.0 was launched on November 9, 2004.

The Legacy Continues

Today, Firefox usage accounts for 23% of the browser market — down from its peak of 33% in November 2009. But, without Firefox, the web would not be the same. Would Google and Apple challenged Microsoft’s domination if it were not for Mozilla’s success? Would IE6 still have a stranglehold on the web? Even if you prefer another browser, that application may not have existed had Firefox failed.

Firefox usage is slowly dropping but it still provides two major benefits:

  1. It is the best development browser. The competition has caught up, but the quantity and quality of add-ons created by web developers for web developers remains unsurpassed.
  2. Mozilla is an independent, open-source organization. No one can buy Mozilla or shut it down. Firefox is the only browser not influenced by commercial requirements or shareholder demands.

Congratulations to Mozilla and the Firefox development team for reaching double-figures. I’m sure the browser will still be around in another ten years. Are you?

How to Create Facebook FBML Template

15 Feb

Everyone knows a social network called FaceBook. It’s the place where lots of people are constantly spending lots of time. It didn’t take a long time for brands and local businesses to join FaceBook too. So when the amount of non-human accounts started to grow, FaceBook guys have decided to add an ability to create separate pages for businesses and brands.

Today FaceBook pages can be equipped and customized with a lot of different widgets and applications. However the most important of all is the FBML box – it lets you create awesome landing pages, using HTML, CSS, FBML, FBJS, iframes and even Flash.

In this tutorial we will show you how to design a photographers FaceBook FBML page. Follow carefully what we say and you will get a nice layout like this:

 

1. Let’s start with creating a new document 520 * 800 pixels. That’s because FaceBook has recently announced that the page width will be shortened from 760 to 520 pixels.

2. To create a fancy bubbles background we have used this great tutorial.

3. Now take the Rounded RectangleTool (U) and create a rectangle, which will contain our logo. The radius that I’ve used is 15px.

To enhance the rectangle let’s set a Opacity to 70%

and add a tiny shadow to it:

4. Fill in the rectangle with the name of your company using the Type Tool (T). To make it look more like a logo we can play with the fonts a bit. “John” is written with a thin font FuturaBTLight of #f5634a color, while “Marley” is black (#000000) FuturaBTBold. I have also added a tiny slogan at the bottom. It’s a Visitor TT1 BRK font with 10px height.

5. Adding some effects to the texts as shown on screenshots:

Gradient:

Outer Glow:

6. There’s some free space to the right from our logo – a perfect place to insert some photographers attribute. The most obvious one is undoubtedly a camera :)

7. The title of our page is “Welcome to my FaceBook page” which is also made of two above fonts of different colors.

8. Fill the page with some text content and add a bit styling to it by making some phrases bold and some underlined. I’ve used Tahoma font in this part:

9. As far as we’re creating a photographer layout, we need to add a tiny photo gallery to a page. Insert some photos and resize them to 210 * 115 pixels. Order in a line with a 10px distance between them. The third picture will not fit to a page, so we’ll have to cut it with Marquee Tool (M).

10. Add a Stroke effect on the layer with pictures – this will create a nice border:

Adding effect:

Stroke settings:

11. We obviously need a scrollbar under the pictures, so take a RectangleTool (U) and draw it. Then add DropShadow, GradientOverlay and Stroke effects as per screenshots:

Stroke:

Drop Shadow:

Gradient Overlay:

12. Pick a Pencil Tool (B) and draw 3 white and 3 black lines in the center of the scroller.

13. To finish the scroll box we need a scroll holder. Pick a Rectangle tool and make a black rectangle of the same height as the scroll. The width should be adjusted in accordance to the photo thumbs. Set the Opacity of the layer to 10%. The scroll box is all set:

14. Using a Text Tool add 2 more boxes in the footer – “Latest News” and “Contacts”. At the very bottom add the copyrights:

15. You can also add the icons of your social profiles to the header. And don’t forget to ask people to become a “Fan” of your page. Add a “Like” button with a supporting text to engage them to join:

Finally our FaceBook page is ready:

Autoloading in PHP and the PSR-0 Standard

14 Feb

Let’s say you have the file Rectangle.php which contains the definition for a Rectangle class. Before you can create an instance of the object elsewhere in your code, you first need to pull in the Rectangle.php file, perhaps by writing something like this:

1 <?php
2 require "Rectangle.php";
3 $rect = new Rectangle(42, 25);

Normally we put each class’ definition in its own file for better organization, and so you need to require/include each of the class files you want to use. If there are only a few files then it isn’t too much of a problem, but oftentimes that’s not the case. It can be very cumbersome to load a large library including all of its dependencies like this.

In this article I’ll walk you through the “history of autoloading,” from the older to the current PSR-0 standard autoloader approach found in many PHP frameworks such as Lithium, Symfony, Zend, etc. Then I will introduce you to the ClassLoader component from the Symfony2 project for PHP 5.3 which follows the PSR-0 standard.

Warning: Most of the code samples in the beginning of this article demonstrate deprecated approaches. It would be unwise to use them in production. I recommend you use one of the PSR-0 standard autoloaders instead.

Autoloading in the “Olden Days”

PHP 5 introduced the magic function __autoload() which is automatically called when your code references a class or interface that hasn’t been loaded yet. This provides the runtime one last chance to load the definition before PHP fails with an error.

Here’s an example of an extremely basic __autoload() implementation:

1 <?php
2 function __autoload($className) {
3     $filename = $className . ".php";
4     if (is_readable($filename)) {
5         require $filename;
6     }
7 }

It’s a good idea to make sure a file exists before you try to include it, but sometimes the file may be there but will not have sufficient read permissions so it’s better to use is_readable() over file_exists() which will for test both conditions.

The major drawback to the __autoload() function is that you can only provide one autoloader with it. PHP 5.1.2 introduced spl_autoload() which allows you to register multiple autoloader functions, and in the future the __autoload() function will be deprecated.

The introduction of spl_autoload_register() gave programmers the ability to create an autoload chain, a series of functions that can be called to try and load a class or interface. For example:

01 <?php
02 function autoloadModel($className) {
03     $filename = "models/" . $className . ".php";
04     if (is_readable($filename)) {
05         require $filename;
06     }
07 }
08
09 function autoloadController($className) {
10     $filename = "controllers/" . $className . ".php";
11     if (is_readable($filename)) {
12         require $filename;
13     }
14 }
15
16 spl_autoload_register("autoloadModel");
17 spl_autoload_register("autoloadController");

Generally the functions are called in the order they’re registered, but the order can also be affected by additional arguments passed to spl_autoload_register().

It’s important to remember that once a function has been registered with spl_autoload_register(), the __autoload() function will no longer be called. If you have an __autoload() function you want to run as part of your autoloader chain, then you’ll have to register it with spl_autoload_register().

Of course, the implementations of the autoloading functions I’ve shown this far have been rather simple. Real-world autoloaders are more complex.

Before real namespace support was introduced in PHP 5.3, developers devised their own approaches to prevent naming collisions. The PEAR Coding Standard used underscores to prefix class names with their directory path; the class Zend_Translate for example would be defined in the file Zend/Translate.php. The autoloader needed to replace the underscores with directory separators to locate the definition.

Also, different developers adopted different conventions when it came to naming their class files, for example the files might end in .php, .class.php, .inc, etc. Some libraries may be installed in different paths as well. The loader needed to look in various places for them, so now the loader begins to look like this:

01 <?php
02 function __autoload($className) {
03     $extensions = array(".php", ".class.php", ".inc");
04     $paths = explode(PATH_SEPARATOR, get_include_path());
05     $className = str_replace("_" , DIRECTORY_SEPARATOR, $className);
06     foreach ($paths as $path) {
07         $filename = $path . DIRECTORY_SEPARATOR . $className;
08         foreach ($extensions as $ext) {
09             if (is_readable($filename . $ext)) {
10                 require_once $filename . $ext;
11                 break;
12            }
13        }
14     }
15 }

Autoloading is a useful idea, but was an idea that desperately needed some standardization.

PSR-0 Standard

After PHP 5.3′s introduction of true namespace support, a group of people from the PHP community decided to create the PHP Standards Working Group in 2009 (later renamed to the Framework Interoperatability Group) and establish the PSR-0 standard which outlines various practices and constraints that must be followed for autoloader interoperability. Below are the requirements for PSR-0 compliance:

  • A fully-qualified namespace and class must have the following structure \<Vendor Name>\(<Namespace>)*\<Class Name>.
  • Each namespace must have a top-level namespace (“Vendor Name”).
  • Each namespace can have as many sub-namespaces as it wishes.
  • Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system.
  • Each underscore in the class name is converted to a DIRECTORY_SEPARATOR. The underscore has no special meaning in the namespace.
  • The fully-qualified namespace and class is suffixed with .php when loading from the file system.
  • Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lower case and upper case.

According to the PSR-0 standard, there should be a top level directory with the vendor’s name and then the package name, so the directory tree will look like this:

example component path

The classes would then be namespaced accordingly:

1 <?php
2 namespace Vendor\Package;
3 class Example
4 {
5 }

Thus, the class definition for \Doctrine\Common\Connections would be found at /path/to/project/lib/Doctrine/Common/Connections.php, and \Symfony\Core\Request at /path/to/project/lib/Symfony/Core/Request.php. The PSR-0 standard does not mandate what the base /path/to/project/lib portion of the path is, and conforming autoloaders offer different methods for its resolution. Some will allow you to register the directory, some will search PHP’s include_path, and some offer you both.

You can use any one of the PSR-0 compliant autoloaders from frameworks such as Symfony, Pear2, AuraPHP (which is for PHP 5.4+), etc. and adhere to the rules above with your own code to take advantage of autoloading without the uncertainties I discussed previously.

Using Symfony’s Autoloader

The Symfony2 project is a component-based framework for PHP 5.3 and greater which you can use as a component library or as a full-stack framework. You can download Symfony’s Autoloader, the ClassLoader component, via different means — pear.symfony.com, packagist, or from GitHub.

Here’s the directory structure of Symfony’s ClassLoader component:

Symfony ClassLoader Component

Using the component then looks like this:

1 <?php
2 require_once "/path/to/Symfony/Component/ClassLoader/UniversalClassLoader.php";
3 use Symfony\Component\ClassLoader\UniversalClassLoader;
4
5 $loader = new UniversalClassLoader();
6 $loader->registerNamespace("Symfony\Component" => "/path/to/symfony/components");
7 $loader->registerNamespace("Monolog" => "path/to/monolog/src/");
8 $loader->registerPrefix("Zend_", "path/to/zend/library");
9 $loader->register();

The registerNamespace() method is used to inform the autoloader where the given namespace’s base directory maps to on the file system and accepts a namespace as its first argument and path as its second value. You can also register multiple namespaces in a single call with the registerNamespaces() method.

1 <?php
2 $loader->registerNamespaces(array(
3     "Symfony\Component" => "/path/to/symfony/components",
4     "Monolog' => "path/to/monolog/src"));

The registerPrefix() method is used to register pseudo-namespaces which was used by Pear, Zend, and other libraries and frameworks before real namespace support was implemented in PHP as we have already covered above. You can also register mulitple ones with the registerPrefixes() method and passing it as an associative array.

1 <?php
2 $loader->registerPrefixes(array(
3     "Zend_" => "/path/to/zend/library",
4     "Twig_" => "path/to/twig/library"));

If you are using the Alternative PHP Cache (APC), a free and open source opcode cache for PHP, then you can may want to consider using the ApcUniversalClassLoader class. The ApcUniversalClassLoader extends the UniversalClassLoader but uses apc_store() and apc_fetch() to store lookup information in APC’s cache. The standard UniversalClassLoader will of course work with APC, but the additional behavior offered by the ApcUniversalClassLoader class afford extra performance benefit.

1 <?php
2 require_once "path/to/Symfony/Component/ClassLoader/UniversalClassLoader.php";
3 require_once "path/to/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php";
4 use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
5 $loader = new ApcUniversalClassLoader("apc.prefix.");

The ApcUniversalClassLoader accepts a prefix with its constructor. For more information on APC, I suggest reading the APC documentation.

Summary

In this article we have discussed autoloading, from its early days to the current PSR-0 standard which has become widely adopted across many PHP frameworks. Recently, David Coallier tried to push the SplClassloader class into PHP 5.4 to offer native PSR-0 compliant autoloading functionality, but for various reasons it didn’t happen. Maybe in the future we will see it added.

Now the current hot discussion in the working group is focused on caching. If it’s something you’d like to be part of, feel free to join the discussion!

%d bloggers like this: