Using Data URIs


After reading Nicolas Zakas article, Data URIs make CSS sprites obsolete, I was inspired to see how easy it would be to put into practice. His CSSEmbed JAR uses Base64 encoding for data URIs and MHTML to be backwards compatible with IE 6 and 7. So the logical step was to create a build script that runs CSSEmbed against all my CSS files.

Getting ready

You will need to install a copy of ant and ant-contrib to use these build scripts. To include ant-contrib into your ant build script, use:

<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="pathToJar/ant-contrib-1.0b3.jar"/>

Additionally, you will need the CSSEmbed JAR.

How to do it…

First setup some properties to be used by the ant target:

<property name="datauri.jar" value="pathToCSSEmbed/cssembed-0.3.3.jar"/>
<property name="datauri.charset" value="UTF-8"/>
<property name="datauri.inputdir" value="inputDirectory"/>
<property name="datauri.mhtmlroot" value="URLofCSSorDomain"/>
<property name="datauri.outputdir" value="outputDirectory"/>
<property name="datauri.root" value="URLofCSSorDomain"/>

Next create your ant target:

<target name="create.css.datauri">
	<for param="file">
		<fileset dir="${datauri.inputdir}" id="css.datauri.files">
			<include name="*.css"/>
		</fileset>
		<sequential>
			<propertyregex property="datauri.filename" input="@{file}" regexp="(\w+\.css)" select="\1" override="true"/>
			<echo message="converting ${datauri.filename} to datauri"/>
			<java jar="${datauri.jar}" fork="true" failonerror="true">
				<arg value="-o" />
				<arg value="${datauri.outputdir}/${datauri.filename}" />
				<arg value="--charset" />
				<arg value="${datauri.charset}" />
				<arg value="--root" />
				<arg value="${datauri.root}" />
				<arg value="@{file}" />
			</java>
			<java jar="${datauri.jar}" fork="true" failonerror="true">
				<arg value="-o" />
				<arg value="${datauri.outputdir}/ie-${datauri.filename}" />
				<arg value="--mhtml" />
				<arg value="--mhtmlroot" />
				<arg value="${datauri.mhtmlroot}" />
				<arg value="--charset" />
				<arg value="${datauri.charset}" />
				<arg value="@{file}" />
			</java>
		</sequential>
	</for>
</target>

How it works…

The trickiest part when using CSSEmbed is the root and mhtmlroot properties. These URLs are not the location of the files on your computer, but on the web, and varies depending on how you reference the images in your CSS. If the images are relative to your CSS, then the values should be set to the URL of your CSS directory. If the images are relative to the root of your domain, then these values should be your URL of your root domain. CSSEmbed will make JAVA net calls when generating the URIs.

The ant-contrib project was necessary, because basic ant does not have a way to iterate on a fileset. I tried to simulate this using macros, but couldn't get it working correctly, so I settled on using ant-contrib.

In the build target, the for iterates on the fileset of CSS files in your CSS directory, storing the value as the param @{file}. As written, it will only search that immediate directory, and not subdirectories. To search subdirectories as well, change *.css to **/*.css.

The propertyregex task finds the filename of the file, by removing the absolute path from @{file}. The CSSEmbed JAR is executed twice: once to create the non-IE CSS and a second time to create the IE 6 & 7 CSS. Your code will need to branch serving a different file depending on the browser. You can do this client-side using conditional comments:

<link type="text/css" href="/build/css/dataUriTest.css" rel="stylesheet"/>
<!--[if lt IE 8]>
	<link type="text/css" href="pathToCSS/ie-dataUriTest.css" rel="stylesheet"/>
<![endif]-->

However, this is less efficient than branching server-side, because the IE version contains all the same CSS as the non-IE version (only the URIs vary).

What's next?

I ran out of time while writing this article, but I would have liked to write a build step that strips out all CSS rules from the IE version, except those that contain data URIs. This would reduce the overhead of client-side branching, using conditional comments. However, the most efficient way of branching would still be server-side, as the data URIs would be duplicated in any client-side branching system.

Simple JavaScript Function To Include CSS


This article explains how to write a simple JavaScript function to include CSS files and notify when the loading of the file is complete. The issue is that most browsers do not fire a load event when the link element finishes processing the included CSS rules. And while many libraries have mechanisms for notifying when the CSS is included, I believe this technique is lighter and more elegant. A special thanks goes out to the UX team at Facebook.com who first described this technique to me.

continue reading article…

Dynamically Updating Content Of FireFox Ellipsis Hack


Some time ago, Justin Maxwell wrote an article (String Truncation With Ellipsis) explaining a CSS-only solution for applying ellipsis to the text inside of an HTML element. Unfortunately, to this day, FireFox does not support an ellipsis CSS rule natively; an XML hack is required for it to work in FireFox. However, this hack prevents you from being able to update the content of the node in JavaScript using the innerHTML property. The value changes, but the UI does not update. Today's article will explain a technique for working around this problem.

continue reading article…

CSS Targeted Only to the IPhone


One of this blogs readers, Dan Humphrey, was helpful enough to let me know that the footer position in the new design, was not behaving correctly on the iPhone. Sure enough, when scrolling in Safari on the iPhone a position:fixed element behaves like an absolutely positioned element in other browsers. I like the fixed header and footer, and do not want to remove them, but at the same time, I don't want my site looking bad on the iPhone. The solution then is to figure out a way to target a CSS file just for the iPhone. While, you could attempt to browser sniff on the client- or server-side, using conditional comments is a better practice:

continue reading article…

CSS String Truncation with Ellipsis


Today's article is brought to us by guest writer, Justin Maxwell. Justin will explain the technique he fine tuned for Mint.com to ellipses text using just CSS. For more information about Justin see the end of this article.

---

continue reading article…