Playing with CSS rules

ven. 12 août 2016 by Rémi Duraffort

While working on improving the log viewer in LAVA I ran into an issue.

The issue is really simple: how to add display: block or display: none to a list of nodes while another JS script is adding more of theses nodes to the page.

The classical approach is to select the right nodes and apply the CSS rule. When the second script is adding nodes, you have to redo the selection. As you have many nodes (one per line of log) the update will be really slow.

Something like this would work:

// Update the page
$.ajax()({
  ...
});
// Update the css rule for the new blocks
$("my_selector").css('display', 'block');

Creating a Style Sheet

Instead of adding a CSS rule to every nodes, we can mark theses nodes with a class and change the CSS rules for this class whenever needed.

I discovered in the Mozilla documentation that it's possible (in JavaScript) to create a Style Sheet and to add or remove rules in it.

To create a new Style sheet, you just have to add a style section in the head with:

var sheet = (function() {
    var style = document.createElement("style");
    document.head.appendChild(style);
    return style.sheet;
}

It's then possible to insert rules into the Style Sheet with insertRule:

// Insert at the top of the Style Sheet
sheet.insertRule(".mylabel { display: block }", 0);

// Or better, at the end
sheet.insertRule(".mylabel { display: none}", sheet.cssRules.length);

It's also possible to remove rules from the Style Sheet by using their indexes with deleteRule:

// Remove the first rule
sheet.deleteRule(0);
// Remove the last one added
sheet.deleteRule(sheet.cssRules.length - 1);

With theses two function, you have everything you need to create a specific rule and update it whenever needed. You just have to keep track of his index.