http://www.rebelinbl...specificity.php
Find any problems just let me know.
For those who don't know CSS specificity is how the browser knows which rules to apply when multiple rules conflict, the selector with the higher score gets used
Posted 29 June 2005 - 01:04 PM
Posted 29 June 2005 - 01:32 PM
Posted 29 June 2005 - 04:12 PM
Stephen, on Jun 29 2005, 06:32 AM, said:
Posted 30 June 2005 - 04:40 PM

Posted 30 June 2005 - 07:31 PM
<html>
<head>
<title>CSS Specificity Calculator</title>
<script type="text/javascript">
function show(data) {
window.document.getElementById('code').innerHTML = data;
}
function floatdetails() {
var posY = 0;
var netscape = (navigator.appName.indexOf("Netscape") != -1);
function move(id) {
var divpos = document.getElementById ? document.getElementById(id): document.all ? document.all[id] : document.layers[id];
divpos.sP = function(y) {
this.style.top = y + "px";
};
divpos.y = posY;
return divpos;
}
window.floatdiv = function() {
var pY = netscape ? pageYOffset : document.body.scrollTop;
pos.y += (pY + posY - pos.y) / 8;
pos.sP(pos.y);
setTimeout("floatdiv()");
}
pos = move("code");
floatdiv();
}
</script>
</head>
<body>
<div align="center">
<h1>CSS specificity calculator</h1>
<?php
/*
*
* CSS specificity calculator
* Written by Stephen Ball
* [url="http://www.rebelinblue.com"]http://www.rebelinblue.com[/url]
* --------------------------
* If you improve on this script
* please do let me know
*
*/
function cleanup(&$data, $value) {
$data = trim($data);
}
// Pseudo classes
$classes = array(":link", ":visited", ":hover", ":active", ":focus", ":target", ":lang", ":enabled",
":disabled", ":checked", ":indeterminate", ":root", ":nth-child", ":nth-last-child",
":nth-of-type", ":nth-last-of-type", ":first-child", ":last-child", ":first-of-type",
":last-of-type", ":only-child", ":only-of-type", ":empty", ":contains", ":not");
// Pseudo elements
$elements = array(":before", ":after", ":first-line", ":first-letter", ":selection");
// HTML tags
$tags = array("a", "abbr", "acronym", "address", "applet", "area", "b", "base", "basefont", "bgsound",
"bdo", "big", "blink", "blockquote", "body", "br", "button", "caption", "center", "cite",
"code", "col", "colgroup", "comment", "dd", "del", "dfn", "dir", "div", "dl", "dt", "em",
"embed", "fieldset", "font", "form", "frame", "frameset", "h", "h1", "h2", "h3", "h4", "h5",
"h6", "head", "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "label",
"legend", "li", "link", "listing", "map", "marquee", "menu", "meta", "multicol", "nextid",
"nobr", "noframes", "noscript", "object", "ol", "optgroup", "option", "p", "param", "plaintext",
"pre", "q", "s", "samp", "script", "select", "server", "small", "sound", "spacer", "span",
"strike", "strong", "style", "sub", "sup", "table", "tbody", "td", "textarea", "textflow",
"tfoot", "th", "thead", "title", "tr", "tt", "u", "ul", "var", "wbr", "xmp");
// Check if form has been submitted
if (isset($_POST["css"])) {
// Strip slashes
$_POST["css"] = get_magic_quotes_gpc() ? stripslashes($_POST["css"]) : $_POST["css"];
$data = preg_replace("/\/\\*[\\s\\S]*?\\*\//", "", $_POST["css"]); // Strip comments
$data = preg_replace("/\{(.*?)\}/s", ", ", $data); // Strip content and replace with delimiter
$data = str_replace(" ,", ",", $data); // Strip spaces after selectors
$tmp = explode(",", $data); // Get rid of selector groupings
array_walk($tmp, 'cleanup'); // Trim whitespace from end of selectors
?>
<table border="1" width="760" style="margin: auto;">
<tr>
<td>
<table>
<tr align="middle">
<th width="40%">Selector</th>
<th width="5%">Score</th>
<th width="5%">Properties</th>
</tr>
<?php
// Loop through the selector array
foreach ($tmp as $var) {
$score = 0; // Set the score to 0
if (!empty($var)) {
$score += substr_count($var, '#') * 100; // Count the IDs and multiple by 100 (i.e. #itemID)
$score += substr_count($var, '.') * 10; // Count the classes and multiple by 10 (i.e. .classname)
$score += substr_count($var, '[') * 10; // Count the attributes and multiple by 10 (i.e. input[type=text])
foreach ($classes as $test) { // Count the pseudo-classes and multiple by 10
$score += substr_count($var, $test) * 10;
}
foreach ($elements as $test) { // Count the pseudo-elements and multiple by 10
$score += substr_count($var, $test);
}
$cleaned = str_replace(":", " ", $var); // Remove the pseudo selector
$cleaned = str_replace("+", " ", $cleaned); // Remove the adjacent sibling selector
$cleaned = str_replace(">", " ", $cleaned); // Remove the child selector
$cleaned = str_replace("*", " ", $cleaned); // Remove the universal selector
$cleaned = str_replace(".", " ", $cleaned); // Remove the class selector
$cleaned = str_replace("#", " ", $cleaned); // Remove the ID selector
$cleaned = explode(" ", $cleaned); // Explode on space
foreach ($cleaned as $rubbish) { // Count the type selectors (i.e. HTML tags)
if (in_array(strtolower($rubbish), $tags)) {
$score++;
}
}
// Now to find the actually properties
$code = substr($_POST["css"], strpos($_POST["css"], $var)); // Find the position of the current selector
$first = strpos($code, "{") + 1; // Get the position of the first {
$last = strpos($code, "}"); // Get the position of the first }
$code = substr($code, $first, $last - $first); // Get the content between the { and }
$code = preg_replace("/\/\\*[\\s\\S]*?\\*\//", "", $code); // Strip any comments from the properties
// Now make the data safe for javascript
$code = trim($code); // Trim the properties
$code = str_replace("\\", "\\\\", $code); // Escape any slashes
$code = str_replace("'", "\\'", $code); // Escape any apostrophes
$code = str_replace("\r\n", "<br>", $code); // Convert new lines to HTML break (Can't use nl2br as it doesn't remove the newlines)
$code = str_replace("\n", "<br>", $code);
$code = str_replace("\r", "<br>", $code);
$score = str_pad($score, 3, '0', STR_PAD_LEFT); // Pad the final score to 3 characters
$defined = substr_count($code, ":"); // Count the number of properties the selector defines
?>
<tr>
<td onmouseover="show('<?=$code;?>');" onmouseout="show('');" style="cursor: pointer;"><?=$var;?></td>
<td align="center"><?=$score;?></td>
<td align="center"><?=$defined;?></td>
</tr>
<?php
}
}
?>
</table>
</td>
<td width='50%' valign='top' style="padding: 5px;">
<center><strong>Property data</strong></center>
<div id='code' style='position: relative;'></div>
<script type='text/javascript'>floatdetails();</script>
</td>
</tr>
</table>
<p>Note: Inline styles using the HTML "styles" attribute have a score of 1000.</p>
<p><a href="specificity.php">Start over</a></p>
<?php
}
else {
?>
<p>Paste your CSS into the field below, the specificity of your selectors will be calculated for you.</p>
<h2>Current limitations</h2>
<ul>
<li>Your CSS <b>must</b> <a href="http://jigsaw.w3.org/css-validator/" title="Ensure the file is valid CSS">be valid</a> in order for the calculator to work</li>
<li>Currently only HTML elements are counted in the score, custom tags such as XML are not</li>
</ul>
<form method="post" action="specificity.php">
<textarea name="css" rows="25" cols="90"></textarea>
<br /><input type="submit" value="Calculate" />
</form>
<?
}
?>
</div>
</body>
</html>
Posted 30 June 2005 - 11:50 PM

Posted 01 July 2005 - 10:28 AM