I\'m looking for a way to change the CSS rules for pseudo-class selectors (such as :link, :hover, etc.) from JavaScript.
So an analogue of the CSS code: a:hove
In jquery you can easily set hover pseudo classes.
$("p").hover(function(){
$(this).css("background-color", "yellow");
}, function(){
$(this).css("background-color", "pink");
});
Just place the css in a template string.
const cssTemplateString = `.foo:[psuedoSelector]{prop: value}`;
Then create a style element and place the string in the style tag and attach it to the document.
const styleTag = document.createElement("style");
styleTag.innerHTML = cssTemplateString;
document.head.insertAdjacentElement('beforeend', styleTag);
Specificity will take care of the rest. Then you can remove and add style tags dynamically. This is a simple alternative to libraries and messing with the stylesheet array in the DOM. Happy Coding!
Instead of directly setting pseudo-class rules with javascript, you can set the rules differently in different CSS files, and then use Javascript to switch one stylesheet off and to switch another on. A method is described at A List Apart (qv. for more detail).
Set up the CSS files as,
<link rel="stylesheet" href="always_on.css">
<link rel="stylesheet" title="usual" href="preferred.css"> <!-- on by default -->
<link rel="alternate stylesheet" title="strange" href="alternate.css"> <!-- off by default -->
And then switch between them using javascript:
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")<i>); i++) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
Switching stylesheets in and out is the way to do it. Here is a library to build stylesheets dynamically, so you can set styles on the fly:
http://www.4pmp.com/2009/11/dynamic-css-pseudo-class-styles-with-jquery/
My trick is using an attribute selector. Attributes are easier to set up by javascript.
css
.class{ /*normal css... */}
.class[special]:after{ content: 'what you want'}
javascript
function setSpecial(id){ document.getElementById(id).setAttribute('special', '1'); }
html
<element id='x' onclick="setSpecial(this.id)"> ...
here is a solution including two functions: addCSSclass adds a new css class to the document, and toggleClass turns it on
The example shows adding a custom scrollbar to a div
// If newState is provided add/remove theClass accordingly, otherwise toggle theClass
function toggleClass(elem, theClass, newState) {
var matchRegExp = new RegExp('(?:^|\\s)' + theClass + '(?!\\S)', 'g');
var add = (arguments.length > 2 ? newState : (elem.className.match(matchRegExp) === null));
elem.className = elem.className.replace(matchRegExp, ''); // clear all
if (add) elem.className += ' ' + theClass;
}
function addCSSclass(rules) {
var style = document.createElement("style");
style.appendChild(document.createTextNode("")); // WebKit hack :(
document.head.appendChild(style);
var sheet = style.sheet;
rules.forEach((rule, index) => {
try {
if ("insertRule" in sheet) {
sheet.insertRule(rule.selector + "{" + rule.rule + "}", index);
} else if ("addRule" in sheet) {
sheet.addRule(rule.selector, rule.rule, index);
}
} catch (e) {
// firefox can break here
}
})
}
let div = document.getElementById('mydiv');
addCSSclass([{
selector: '.narrowScrollbar::-webkit-scrollbar',
rule: 'width: 5px'
},
{
selector: '.narrowScrollbar::-webkit-scrollbar-thumb',
rule: 'background-color:#808080;border-radius:100px'
}
]);
toggleClass(div, 'narrowScrollbar', true);
<div id="mydiv" style="height:300px;width:300px;border:solid;overflow-y:scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus
a diam volutpat, ullamcorper justo eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit
nec sodales sodales. Etiam eget dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Sed a eros metus. Nunc dui felis, accumsan nec aliquam quis, fringilla quis tellus. Nulla cursus mauris nibh, at faucibus justo tincidunt eget. Sed sodales eget erat consectetur consectetur. Vivamus a diam volutpat, ullamcorper justo
eu, dignissim ante. Aenean turpis tortor, fringilla quis efficitur eleifend, iaculis id quam. Quisque non turpis in lacus finibus auctor. Morbi ullamcorper felis ut nulla venenatis fringilla. Praesent imperdiet velit nec sodales sodales. Etiam eget
dui sollicitudin, tempus tortor non, porta nibh. Quisque eu efficitur velit. Nulla facilisi. Sed varius a erat ac volutpat. Sed accumsan maximus feugiat. Mauris id malesuada dui.
</div>