Skip to content

Instantly share code, notes, and snippets.

@Integralist
Created August 16, 2011 07:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Integralist/1148624 to your computer and use it in GitHub Desktop.
Save Integralist/1148624 to your computer and use it in GitHub Desktop.
Using JavaScript to detect support for CSS pseudo-element selectors :before & :after (judges the width of the element)
body {
font: normal small Helvetica, Arial, Verdana, sans-serif;
}
h1 {
border-bottom: 1px solid #C00;
color: #666;
font-weight: bold;
margin-bottom: 10px;
}
div {
border: 1px dashed #333;
padding: 10px;
}
div,
div p {
margin-bottom: 10px;
}
code {
color: blue;
}
ul {
list-style: disc;
margin-left: 10px;
padding-left: 10px;
}
.before #apply:before {
color: red;
content: "before";
display: inline-block;
margin: 0 5px 5px 0;
}
.after #apply:after {
color: green;
content: "after";
display: inline-block;
margin: 0 0 0 55px;
}
<h1>Detection script for CSS :before and :after support</h1>
<div>
<p>This script detects support of the CSS selectors <code>:before</code> and <code>:after</code> by:</p>
<ul>
<li>Adding two empty paragraph elements to the page (effectively their width each is zero).</li>
<li>Adding a style element to the page (+inserting the relevant <code>:before</code>/<code>:after</code> code).</li>
<li>Checking the width of the element (we need to set them to <code>display:inline-block</code>).</li>
<li>If the width is greater than zero then we know the content was added so support is detected.</li>
<li>Much like <a href="http://www.modernizr.com/">Modernizr</a> we add relevant class names to the main <code>html</code> element</li>
<li>Had to go back and make changes for Internet Explorer (see code comments)</li>
</ul>
</div>
<p id="apply">Paragraph 1</p>
<p>Paragraph 2</p>
// Get a style property (name) of a specific element (elem)
function getStyle(elem, name) {
// If the property exists in style[], then it's been set recently (and is current)
if (elem.style[name]) {
return elem.style[name];
}
// Otherwise, try to use IE's method
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
// Or the W3C's method, if it exists
else if (document.defaultView && document.defaultView.getComputedStyle) {
// It uses the traditional 'text-align' style of rule writing, instead of textAlign
name = name.replace(/([A-Z])/g, '-$1');
name = name.toLowerCase();
// Get the style object and get the value of the property (if it exists)
var s = document.defaultView.getComputedStyle(elem, '');
return s && s.getPropertyValue(name);
}
// Otherwise, we're using some other browser
else {
return null;
}
}
window.onload = function() {
var doc = document,
html = doc.documentElement,
body = doc.body,
paraBefore = doc.createElement('p'),
paraAfter = doc.createElement('p'),
styleBefore = doc.createElement('style'),
styleAfter = doc.createElement('style'),
widthBefore, widthAfter, selectorsBefore = '#testbefore { display:inline-block; } #testbefore:before { content: "before"; }',
selectorsAfter = '#testafter { display:inline-block; } #testafter:after { content: "after"; }';
// Internet Explorer seems to need a type attribute to recognise a stylesheet?
styleBefore.type = 'text\/css';
styleAfter.type = 'text\/css';
paraBefore.id = 'testbefore';
paraAfter.id = 'testafter';
// For Internet Explorer...
if (styleBefore.styleSheet) {
styleBefore.styleSheet.cssText = selectorsBefore;
styleAfter.styleSheet.cssText = selectorsAfter;
} else {
styleBefore.appendChild(doc.createTextNode(selectorsBefore));
styleAfter.appendChild(doc.createTextNode(selectorsAfter));
}
body.appendChild(styleBefore);
body.appendChild(styleAfter);
body.appendChild(paraBefore);
body.appendChild(paraAfter);
// Internet Explorer doesn't always play ball…
widthBefore = (getStyle(document.getElementById('testbefore'), 'width') === 'auto') ? document.getElementById('testbefore').offsetWidth : parseInt(getStyle(document.getElementById('testbefore'), 'width'));
widthAfter = (getStyle(document.getElementById('testafter'), 'width') === 'auto') ? document.getElementById('testafter').offsetWidth : parseInt(getStyle(document.getElementById('testafter'), 'width'));
if (widthBefore > 0) {
html.className += ' before';
body.removeChild(styleBefore);
body.removeChild(paraBefore);
} else {
console.log('before failed');
}
if (widthAfter > 0) {
html.className += ' after';
body.removeChild(styleAfter);
body.removeChild(paraAfter);
} else {
console.log('after failed');
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment