Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

              
                <div class="main">
		<h1>Specificity Calculator</h1>
		<p class="intro">A visual way to understand  <a href="http://www.w3.org/TR/css3-selectors/#specificity" target="_blank">CSS-selectors</a> from <a href="http://specificity.keegan.st/">Keegan Street</a>. Change the selectors or paste in your own.</p>
		<div id="items" class="items">
			<div class="item is-small transition-all">
				<textarea type="text" class="input">ul#nav li.active a</textarea>
				<div class="selector"><span class="type-c">ul</span><span class="type-a">#nav</span> <span class="type-c">li</span><span class="type-b">.active</span> <span class="type-c">a</span></div>
				<div class="specificity">
					<span class="type-z">0</span>
					<span class="type-a">1</span>
					<span class="type-b">1</span>
					<span class="type-c">3</span>
				</div>
				<div class="legend">
          <span class="type-z">Inline-styles</span>
					<span class="type-a">IDs</span>
					<span class="type-b">classes, attributes and pseudo-classes</span>
					<span class="type-c">elements and pseudo-elements</span>
				</div>
				<a href="#" class="duplicate button">duplicate</a>
			</div>
		</div>
	</main>
	<div class="menu">
		<a href="#" class="sort button">sort by specificity</a>
	</div>
	
	<div class="offscreen-container"><div id="offscreen"></div></div>


              
            
!

CSS

              
                @import "bourbon";

/*
 * The colour theme for Specificity Calculator is from http://ethanschoonover.com/solarized
 */

body {
	background: #FDF6E3;
	color: #657B83;
}

h1 {
	font-size: 40px;
	line-height: 40px;
	margin: 25px 0 5px;
	color: #CB4B16;
	letter-spacing: -1px;
}

p {
	line-height: 1.5em;
}

a {
	color: #6C71C4;
}

code {
	background-color: transparentize(white,.6);
	border: 1px solid #CCCCCC;
	-webkit-border-radius: 3px;
	border-radius: 3px;
	padding: 0 5px;
}

.intro {
	font-style: italic;
	margin-top: 0;
}

.footer {
	margin-bottom: 60px;
}

.main {
	width: 680px;
	margin: 0 auto;
}

/* Items */

#items {
	width: 680px;
	min-height: 536px;
	position: relative;
}

.item {
	background: #FFF;
	padding: 20px 20px 10px;
	width: 640px;
	margin-bottom: 20px;
	-webkit-box-shadow: 0px 0px 10px 0px #D5CEBB;
	box-shadow: 0px 0px 10px 0px #D5CEBB;
	-webkit-border-radius: 3px;
	border-radius: 3px;
	overflow: hidden;
	position: relative;
	opacity: 1;
}

.transition-all {
	-webkit-transition: all 0.2s ease;
	-moz-transition: all 0.2s ease;
	-ms-transition: all 0.2s ease;
	-o-transition: all 0.2s ease;
	transition: all 0.2s ease;
}

.is-small {
	-webkit-transform: scale(0.6);
	-moz-transform: scale(0.6);
	-ms-transform: scale(0.6);
	-o-transform: scale(0.6);
	transform: scale(0.6);
	opacity: 0;
}

	.input,
	.selector {
		font-size: 28px;
		line-height: 36px;
		font-family: monospace, serif;
		_font-family: 'courier new', monospace;
	}

	.input {
		width: 630px;
		height: 36px;
		position: absolute;
		top: 20px;
		left: 20px;
		padding: 3px 5px;
		border: none;
		background: none;
		color: #FFF;
		resize: none;
		outline: none;
		overflow: hidden;
	}

		.input:focus,
		.input:active {
			-moz-box-shadow: 0 0 10px #00171D;
			-webkit-box-shadow: 0 0 10px #00171D;
			box-shadow: 0 0 10px #00171D;
		}

	.selector {
		width: 630px;
		min-height: 36px;
		padding: 3px 5px;
		background: #002B36;
		white-space: pre-wrap;
	}

	.specificity {
		margin: 20px 0 0;
		color: #FFF;
		font-size: 80px;
		line-height: 80px;
		text-align: center;
		font-weight: bold;
	}

		.specificity > span {
			float: left;
			width: 157px;
			padding: 10px 0 10px 0;
			margin-left: 4px;
			-webkit-border-top-left-radius: 3px;
			border-top-left-radius: 3px;
			-webkit-border-top-right-radius: 3px;
			border-top-right-radius: 3px;
		}
			.specificity > span:first-child {
				margin-left: 0;
			}

	.legend {
		clear: left;
		font-size: 12px;
		text-align: center;
		color: #FFF;
	}

		.legend > span {
			float: left;
			width: 117px;
			height: 40px;
			padding: 0 20px;
			margin-left: 4px;
			-webkit-border-bottom-left-radius: 3px;
			border-bottom-left-radius: 3px;
			-webkit-border-bottom-right-radius: 3px;
			border-bottom-right-radius: 3px;
		}

			.legend > span:first-child {
				margin-left: 0;
			}

.selector .type-z {
	color: #CB4B16;
	background: #CB4B16;
}

.specificity .type-z,
.legend .type-z {
	background: #CB4B16;
}

.selector .type-a {
	color: #D33682;
	background: #D33682;
}

.specificity .type-a,
.legend .type-a {
	background: #D33682;
}

.selector .type-b {
	color: #268BD2;
	background: #268BD2;
}

.specificity .type-b,
.legend .type-b {
	background: #268BD2;
}

.selector .type-c {
	color: #2AA198;
	background: #2AA198;
}

.specificity .type-c,
.legend .type-c {
	background: #2AA198;
}

.button {
	float: right;
	margin-top: 10px;
	font-size: 12px;
	line-height: 12px;
	text-decoration: none;
	background: #B58900;
	color: #FFF;
	padding: 2px 5px;
	-webkit-border-radius: 3px;
	border-radius: 3px;
}

.button:hover {
	background: #CEA62C;
}

.duplicate:before {
	content: "+";
	padding-right: 5px;
}

.menu {
	position: fixed;
	top: 110px;
	left: 20px;
}

.offscreen-container {
	height: 1px;
	width: 1px;
	position: relative;
	overflow: hidden;
}

#offscreen {
	position: absolute;
	left: 10000px;
	top: 10000px;
}
              
            
!

JS

              
                /**
 * Calculates the specificity of CSS selectors
 * http://www.w3.org/TR/css3-selectors/#specificity
 *
 * Returns an array of objects with the following properties:
 *  - selector: the input
 *  - specificity: e.g. 0,1,0,0
 *  - parts: array with details about each part of the selector that counts towards the specificity
 */
var SPECIFICITY = (function() {
	var calculate,
		calculateSingle;

	calculate = function(input) {
		var selectors,
			selector,
			i,
			len,
			results = [];

		// Separate input by commas
		selectors = input.split(',');

		for (i = 0, len = selectors.length; i < len; i += 1) {
			selector = selectors[i];
			if (selector.length > 0) {
				results.push(calculateSingle(selector));
			}
		}

		return results;
	};

	// Calculate the specificity for a selector by dividing it into simple selectors and counting them
	calculateSingle = function(input) {
		var selector = input,
			findMatch,
			typeCount = {
				'a': 0,
				'b': 0,
				'c': 0
			},
			parts = [],
			// The following regular expressions assume that selectors matching the preceding regular expressions have been removed
			attributeRegex = /(\[[^\]]+\])/g,
			idRegex = /(#[^\s\+>~\.\[:]+)/g,
			classRegex = /(\.[^\s\+>~\.\[:]+)/g,
			pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi,
			// A regex for pseudo classes with brackets - :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-type(), :lang()
			pseudoClassWithBracketsRegex = /(:[\w-]+\([^\)]*\))/gi,
			// A regex for other pseudo classes, which don't have brackets
			pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g,
			elementRegex = /([^\s\+>~\.\[:]+)/g;

		// Find matches for a regular expression in a string and push their details to parts
		// Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
		findMatch = function(regex, type) {
			var matches, i, len, match, index, length;
			if (regex.test(selector)) {
				matches = selector.match(regex);
				for (i = 0, len = matches.length; i < len; i += 1) {
					typeCount[type] += 1;
					match = matches[i];
					index = selector.indexOf(match);
					length = match.length;
					parts.push({
						selector: match,
						type: type,
						index: index,
						length: length
					});
					// Replace this simple selector with whitespace so it won't be counted in further simple selectors
					selector = selector.replace(match, Array(length + 1).join(' '));
				}
			}
		};

		// Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
		(function() {
			var regex = /:not\(([^\)]*)\)/g;
			if (regex.test(selector)) {
				selector = selector.replace(regex, '     $1 ');
			}
		}());

		// Remove anything after a left brace in case a user has pasted in a rule, not just a selector
		(function() {
			var regex = /{[^]*/gm,
				matches, i, len, match;
			if (regex.test(selector)) {
				matches = selector.match(regex);
				for (i = 0, len = matches.length; i < len; i += 1) {
					match = matches[i];
					selector = selector.replace(match, Array(match.length + 1).join(' '));
				}
			}
		}());

		// Add attribute selectors to parts collection (type b)
		findMatch(attributeRegex, 'b');

		// Add ID selectors to parts collection (type a)
		findMatch(idRegex, 'a');

		// Add class selectors to parts collection (type b)
		findMatch(classRegex, 'b');

		// Add pseudo-element selectors to parts collection (type c)
		findMatch(pseudoElementRegex, 'c');

		// Add pseudo-class selectors to parts collection (type b)
		findMatch(pseudoClassWithBracketsRegex, 'b');
		findMatch(pseudoClassRegex, 'b');

		// Remove universal selector and separator characters
		selector = selector.replace(/[\*\s\+>~]/g, ' ');

		// Remove any stray dots or hashes which aren't attached to words
		// These may be present if the user is live-editing this selector
		selector = selector.replace(/[#\.]/g, ' ');

		// The only things left should be element selectors (type c)
		findMatch(elementRegex, 'c');

		// Order the parts in the order they appear in the original selector
		// This is neater for external apps to deal with
		parts.sort(function(a, b) {
			return a.index - b.index;
		});

		return {
			selector: input,
			specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(),
			parts: parts
		};
	};

	return {
		calculate: calculate
	};
}());

// Export for Node JS
if (typeof exports !== 'undefined') {
	exports.calculate = SPECIFICITY.calculate;
}






$(document).ready(function() {

	var $items = $('#items'),
		$baseItem = $items.find('.item:eq(0)').clone(),
		$sort = $('.sort'),
		$offscreen = $('#offscreen'),
		update,
		createItem;

	createItem = function(selector, $prev) {
		var $item = $baseItem.clone(),
			$input = $item.find('> .input').val(selector),
			$selector = $item.find('> .selector'),
			$specificityZ = $item.find('> .specificity > .type-z'),
			$specificityA = $item.find('> .specificity > .type-a'),
			$specificityB = $item.find('> .specificity > .type-b'),
			$specificityC = $item.find('> .specificity > .type-c'),
			$duplicate = $item.find('> .duplicate'),
			update;

		update = function(e) {
			var input = $input.val(),
				result,
				specificity,
				highlightedSelector,
				i, len, part, text1, text2, text3;

			// Resize the textarea to fit contents
			(function() {
				var $temp = $('<div class="selector"></div>'),
					lastChar = input.substr(input.length-1),
					height;

				if (lastChar === '\n' || lastChar === '\r') {
					$temp.text(input + ' ');
					console.log('tes');
				} else {
					$temp.text(input);
				}
				$offscreen.append($temp);
				height = $temp.height();
				$temp.remove();
				$input.height(height + 'px');
				$selector.height(height + 'px');
			}());

			result = SPECIFICITY.calculate(input);

			if (result.length === 0) {
				$selector.text(' ');
				$specificityZ.text('0');
				$specificityA.text('0');
				$specificityB.text('0');
				$specificityC.text('0');
				return;
			}

			result = result[0];
			specificity = result.specificity.split(',');
			$specificityZ.text(specificity[0]);
			$specificityA.text(specificity[1]);
			$specificityB.text(specificity[2]);
			$specificityC.text(specificity[3]);

			highlightedSelector = result.selector;
			for (i = result.parts.length - 1; i >= 0; i -= 1) {
				part = result.parts[i];
				text1 = highlightedSelector.substring(0, part.index);
				text2 = highlightedSelector.substring(part.index, part.index + part.length);
				text3 = highlightedSelector.substring(part.index + part.length);
				highlightedSelector = text1 + '<span class="type-' + part.type + '">' + text2 + '</span>' + text3;
			}
			$selector.html(highlightedSelector);
		};

		$duplicate.click(function(e) {
			e.preventDefault();
			createItem($input.val(), $item);
		});

		$input.keyup(update);
		update();
		if ($prev) {
			$prev.after($item);
		} else {
			$items.append($item);
		}
		setTimeout(function() {
			$item.removeClass('is-small');
		}, 100);
	};

	$items.empty();
  if (window.location.hash) { 
     var thehash = window.location.hash;
     thehash = thehash.slice(1);
     //thehash = thehash.replace(/##/g, '');
     //thehash = thehash.replace(/#/g, '');
     thehash = thehash.replace(/-/g, ' ');
     createItem(thehash);
  } else {
	  createItem('li:first-child h2 .title');
	  createItem('#nav .selected > a:hover');    
  }

	$sort.click(function(e) {
		e.preventDefault();

		var $children = $items.children(),
			children = $children.get(),
			yPos = 0;

		$items.height($items.height());
		$children.each(function(index, el) {
			var $this = $(this);
			$this.removeClass('transition-all').css({
				'position': 'absolute',
				'top': yPos + 'px',
				'left': '0'
			});
			yPos += $this.outerHeight(true);
		});

		children.sort(function(sel1, sel2) {
			var spec1 = [],
				spec2 = [],
				i;

			spec1[0] = parseInt($('.specificity .type-z', sel1).text(), 10),
			spec1[1] = parseInt($('.specificity .type-a', sel1).text(), 10),
			spec1[2] = parseInt($('.specificity .type-b', sel1).text(), 10),
			spec1[3] = parseInt($('.specificity .type-c', sel1).text(), 10),
			spec2[0] = parseInt($('.specificity .type-z', sel2).text(), 10),
			spec2[1] = parseInt($('.specificity .type-a', sel2).text(), 10),
			spec2[2] = parseInt($('.specificity .type-b', sel2).text(), 10),
			spec2[3] = parseInt($('.specificity .type-c', sel2).text(), 10);

			for (i = 0; i < 4; i += 1) {
				if (spec1[i] > spec2[i]) {
					return -1;
				} else if (spec2[i] > spec1[i]) {
					return 1;
				}
			}

			return 0;
		});

		setTimeout(function() {
			var yPos = 0;

			$.each(children, function(index, el) {
				var $el = $(el);
				$el.addClass('transition-all').css({
					'top': yPos + 'px'
				});
				yPos += $el.outerHeight(true);
			});

			setTimeout(function() {
				$.each(children, function(index, el) {
					$(el).removeClass('transition-all').css({
						'position': 'relative',
						'top': '0',
						'left': '0'
					});
					$items.append(el);
					$items.height('auto');
				});
			}, 500);
		}, 50);
	});
  


});
              
            
!
999px

Console