There's a few ways of styling elements in JavaScript.
document.getElementById('header1').style.border = '1px solid red';
*click the boxes
document.getElementById('header1').style.textTransform = 'uppercase';
This is very common. It's easy to use, descriptive, and it's the proper use of the style method.
This way of controling styles is very easy to overlook, harder to debug and can make big impacts in performance.
Reflows
We can't avoid reflows, but we can reduce them.
When we make changes to the DOM, those changes need to recalcuate the styles and other attributes associated with each affected element.
These changes are lightning fast but if not managed can bog down your application.
var container = document.getElementById('example2'); var new_header = document.createElement('h4'); // Append the header to the container element container.appendChild(new_header); // Header Information - Each of these will cause a reflow new_header.innerHTML = 'This will trigger 4 more reflows then it needs to.'; new_header.style.padding = '5px 10px'; new_header.style.background = 'red'; new_header.style.color = 'white';
This is a subtle but important difference.
var container = document.getElementById('example3'); var new_header = document.createElement('h4'); // Header Information - Only 1 reflow from appending the element new_header.innerHTML = 'This header is only appended after all the styles are set.'; new_header.style.background = 'green'; new_header.style.padding = '5px 10px'; new_header.style.color = 'white'; // Append the header to the container element AFTER all the styles are set container.appendChild(new_header);
Before the element exists, it will not trigger reflows. Adding all of the styles and attributes before appending the element is a big optimization.
The fastest way to style elements in JavaScript is leveraging the power of CSS, and only appending a class to manage all those styles.
var container = document.getElementById('example4'); var new_header = document.createElement('h4'); // Header Information new_header.setAttribute('class', 'cool-header'); new_header.innerHTML = 'This header has styles from CSS.'; // Append the header to the container element container.appendChild(new_header);
Great, but I don't want to have to serve a CSS file with my JavaScript.
We don't have to. And we can organize the styles a lot better.
You're going to thank yourself later for this, and so will your developer friends
// Create a style element we can append to the head var module_styles = document.createElement('style'); // Using an array, we can write our styles much like we would in a CSS file var styles_config = [ '#example5{', 'background: green;', '}', '.COOLER-header{', 'padding: 5px 10px;', 'color: #222;', 'background: orange;', '}' ].join(''); // Turns the array into a string // Populate and append style tag module_styles.innerHTML = styles_config; document.getElementsByTagName('head')[0].appendChild(module_styles); // Now let's continue our application like normal. var container = document.getElementById('example5'); var new_header = document.createElement('h4'); // Header Information new_header.setAttribute('class', 'COOLER-header'); new_header.innerHTML = 'This header has styles from an inline style tag appended to the head.'; // Append the header to the container element container.appendChild(new_header);
For this example in particular, it seems like a lot of code but it's worth the setup.
In larger applications the benefits of this pattern are more obvious.
One important note
Inline JavaScript and CSS cannot be cached by the browser. Depending on the scale of your application, loading CSS dynamically like this could be less performant than a one time http request that is then cached.