Styling Raphael.js Elements With CSS

Recently finished up a project in which one of the major requirements was that everything be re-skinnable. This meant that every interface element needed to be styled through the style sheet. Swap out a single file to completely change the look of the site.

In theory, this shouldn’t be a problem; that is the raison d’etre for Cascading Style Sheets. Where things got ¬†little complicated, however, was in the many, many charts created using Raphael.js. Even the colors used therein needed to be accessible from the .css files.

Raphael produces SVG elements, which are added dynamically to the DOM. I found that the easiest way to style them was to, at the point of creating the individual elements, use Javascript (jQuery, in this case) to add class names. And that simply, everything works! See an example here. Reload the page to re-render the elements. Code follows:

<!doctype html>
<html>
	<head>
		<title>Styling Raphael.js Elements with CSS</title>
		<script type="text/javascript" src="jquery-1.7.1.min_.js"></script>
		<script type="text/javascript" src="raphael-min.js"></script>
		<script type="text/javascript">
			var r1,r2,i
			$(document).ready(function(){
				r1 = new Raphael('raph1',320,320);
				for(i=0;i<50;i++) {
					var s1 = Math.round(Math.random()*300)+10;
					var s2 = Math.round(Math.random()*300)+10;
					var e1 = Math.round(Math.random()*300)+10;
					var e2 = Math.round(Math.random()*300)+10;
					var s = Math.round(Math.random()*5);
					var c = Math.round(Math.random()*5);
					var p = "M"+s1+","+s2+"L"+e1+","+e2;
					var out = r1.path(p).attr({"stroke-width":s});
					$(out.node).attr('class','c'+c);
				}
				r2 = new Raphael('raph2',320,320);
				for(i=0;i<50;i++) {
					var x = Math.round(Math.random()*320);
					var y = Math.round(Math.random()*320);
					var r = Math.round(Math.random()*32);
					var s = Math.round(Math.random()*5);
					var c = Math.round(Math.random()*5);
					var f = Math.round(Math.random()*5);
					var out = r2.circle(x,y,r).attr({"stroke-width":s});
					$(out.node).attr('class','c'+c + ' f'+f);
				}
			});
		</script>
		<style type="text/css">
			* {margin:0;padding:0;}
			h4 {margin:20px 20px 0 20px;}
			.demo {width:320px;height:320px;margin:5px 20px 20px 20px;border:1px solid #cccccc;}
			.c0 {stroke:#ff0000;}
			.c1 {stroke:#00ff00;}
			.c2 {stroke:#0000ff;}
			.c3 {stroke:#ffff00;}
			.c4 {stroke:#ff00ff;}
			.c5 {stroke:#00ffff;}
			
			.f0 {fill:#222222;}
			.f1 {fill:#444444;}
			.f2 {fill:#666666;}
			.f3 {fill:#888888;}
			.f4 {fill:#aaaaaa;}
			.f5 {fill:#cccccc;}
		</style>
	</head>
	<body>
		<h4>Styling stroke color</h4>
		<div class="demo" id="raph1"></div>
		<h4>Styling stroke color and fill color</h4>
		<div class="demo" id="raph2"></div>
	</body>
</html>

and so forth. CSS classes and IDs work the same for SVG elements as they do for HTML elements. The big difference is that SVG styles which mimic HTML styles use different key words. Where you would set a background color on a HTML element using background-color:#cccccc, in SVG you would use fill:#cccccc. Stroke is the SVG version of border.

Here is a short list of helpful links for styling SVG with CSS:

SVG and CSS

Style reference at Mozilla Developer Network

Leave a Reply

Your email address will not be published. Required fields are marked *