A jQuery Tool That Generates External Stylesheets From Your HTML Structure

HTML to CSS Tool

My HTML to CSS tool will parse through your HTML structure, pull out IDs, classes and any inline CSS and create a basic stylesheet for you. To see this article in action, feel free to skip right to the live demo >>

I find myself converting Photoshop files to HTML & CSS quite frequently. Whenever I find myself repeating a task I look for ways to make that task more efficient and therefore waste less of my time. One way my time is wasted during this process is when I rip out all of my inline CSS into an external stylesheet (or most likely an embedded stylesheet in the HTML document temporarily). Usually this involves identifying the IDs and class names of all my HTML elements as well as any inline styles I may have applied in the short-term.

Because of this, I set out to write some javascript that would parse my HTML, look for any elements with and ID or class name. The code also pulls out the inline styles and sorts them by property name. Finally, it also builds unordered list's CSS because whenever I have a unordered list within my template, it almost always needs further styling (think, navbar, footer etc.)

Import jQuery

As with any project, I import Google's hosted jQuery library. This will hopefully be cached in a users browser already:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

jQuery Pseudo Code

Below is a quick overview of the jQuery:

//Dim variables //Check in DOM is ready to be used //Select elements with an ID or CLASS //Select unique CLASSES //Create UL-LI placeholder CSS //Extract inline style CSS //Push results to TEXTAREA


Below are globally scoped variables which are outside the $(document).ready function. output is used for the final CSS. selector is really just a helper variable which can used to narrow the search for IDs and classes. This means you could look for elements only within another element i.e #content [id], #content [class]. Finally tclasses is used to store the names of classes so there are not duplicate class names in the stylesheet.

var output = ""; var selector = ""; var tclasses = new Array();

The rest of the code is wrapped within the $(document).ready function below. This basically checks to see if the DOM is loaded. Next it loops through elements that have an ID or class and finally sends the output to a textarea.

$(document).ready(function(){ $(selector + " [id]," + selector + "[class]").each(function(i){ }); //Code here $("body").append("<textarea id='output'>"+output+"<\/textarea>"); $("#output").css({height: 400, width: 800}); });

Weed Out Duplicate Classes

Next up, the ID/class names are pulled from the element list being looped through. Class names are then added to a global array. Finally since I find myself styling UL and LI elements frequently, I added some code in to create placeholder CSS for these i.e:

#parent ul { } #parent li { }

Here's the code that creates that:

var tmp = "", childOutput = ""; var tid = $(this).attr("id"); var tclass = $(this).attr("class"); var tstyle = $(this).attr("style"); //Avoids adding duplicate CLASSES to stylesheet if(jQuery.inArray(tclass, tclasses) == -1) { //Adds current CLASS to array if(tclass) tclasses.push(tclass); //Adds UL and LI placeholder styles if they are children of a CLASS or ID $(this).children("ul").each(function() { if(tid) { childOutput = "#" + tid; } else { childOutput = "." + tclass; } childOutput = childOutput + " ul\n{\n}\n\n" + childOutput + " li\n{\n}\n\n"; });

Extracting Inline CSS

Next, the inline CSS is extracted from the elements. I'll explain later why this is tricky between different browsers:

if(typeof(tstyle) != "undefined") { properties = new Array(); properties = tstyle.toLowerCase().split(";"); //Raw input for testing //$("#test").html($("textarea").html() + "\n\n" + properties) //Loops through style attribute properties and trims them for ( var i=0, len=properties.length; i<len; ++i ) { if(properties[i] != "") properties[i] = jQuery.trim(properties[i]); } //Sorts array and finally merges it into a string with a seperator tmp = properties.sort().join(";\n") + ";"; //First branch is for non-ie browsers, second is for IE if(tmp.substring(0,1) == ";") { tstyle = tmp.substring(1,tmp.length); } else { if(tmp != "") tstyle = "\n" + tmp; } } else { tstyle = ""; }

Sending the Results to a Textarea

Finally the results of the above code is dropped in a textarea:

//Creates output depending on if current element is a CLASS or an ID if(tid) { output = output + "#" + tid + "\n{" + tstyle + "\n}\n\n" + childOutput; } else { output = output + "." + tclass + "\n{" + tstyle + "\n}\n\n" + childOutput; }

Browser Variances

I found the inline CSS returned from Javascript could vary by browser, especially when working with CSS shorthand notation. Internet Explorer prefers to seperate out border: 1px solid #000; to the following:

border-bottom: black 1px #000; border-left: black 1px #000; border-right: black 1px #000; border-top: black 1px #000;

While Firefox does the following:

border: 1px solid rgb(0, 0, 0);

Webkit based browsers such as Safari & Google Chrome seem to be more web developer friendly by leaving the original CSS intact:

border: 1px solid #000;

Other Browser Variances

This gets further complicated when using the background property especially in Firefox:

-moz-background-clip: border; -moz-background-inline-policy: continuous; -moz-background-origin: padding; background: rgb(221, 221, 221) none repeat scroll 0% 0%;

Fortunately, Safari and Google Chrome again, keep the original CSS intact:

background-color: #f1f1f1;

Because of this, you may consider using my tool in Google Chrome or Safari as they seem to keep the original code the same.

Check out the final results >>

A Bookmarklet

Finally, I created a Bookmarklet that can be used on any webpage or website on the internet. This means you can add this as a bookmark/favorite and run it on any website.


So what do you think? Does this look like something that could help you speed up your development time? Leave your thoughts below >