I met a traveller from an antique land
Who said: Two vast and trunkless legs of stone
Stand in the desert. Near them, on the sand,
Half sunk, a shattered visage lies, whose frown,
And wrinkled lip, and sneer of cold command,
Tell that its sculptor well those passions read
Which yet survive, stamped on these lifeless things,
The hand that mocked them and the heart that fed:
And on the pedestal these words appear:
"My name is Ozymandias, king of kings:
Look on my works, ye Mighty, and despair!"
Nothing beside remains. Round the decay
Of that colossal wreck, boundless and bare
The lone and level sands stretch far away.

As I explained in a previous article, one of the benefits of JavaScript is that it can randomly traverse the DOM, making it easy for an element anywhere on a web page to respond to a click in another, unrelated of the document. The appearance of HTML content is still under the purview of CSS, meaning that we must integrate the technologies together to create a cohesive whole. As we’ll see in future articles, this extends to using JavaScript to initiate CSS animations on HTML content.

Adding A CSS Property & Value To An Element With JavaScript

We’ll start with a simple example: let’s say we wanted to add a border on an element after clicking on a button. The markup is as follows:

<blockquote id="ozymandius">
	I met a traveller from an antique land…
</blockquote>
<button>Ozymandius</button>

We want a click on the button to change the color of the text in the blockquote. I’ve already styled the page using CSS.

blockquote#ozymandius {
	background: #000 url(ozymandius.jpg) no-repeat top right;
	background-size: contain;
	padding: 3rem 3rem 3rem 4rem;
	color: #fff;
	font-family: Papyrus, fantasy;
	border-radius: 5px;
	margin: 0; font-size: 1.3rem;
	text-shadow: 2px 2px 2px rgba(0,0,0,0.8);
}

(Not shown: an @media query to modify the presentation of the blockquote at smaller screen sizes, and my CSS technique for fading background images).

As I’ve discussed, we can’t work “backwards” through the DOM with CSS as it is currently written: that’s the role of JavaScript. Neither should we try to write the JavaScript inline: it’s much more efficient to call a function.

<button onclick="highlight()">
	Ozymandius
</button>

The function will be written earlier in the page: preferably in the <head> of the document, just after the embedded stylesheet.

function highlight() {
	var ozy = document.querySelector("#ozymandius");
	ozy.style.color = "red";
}

As you can see, changing the style of an element with JavaScript is simple: identify the part of the document you want to with document.querySelector or some other method, add both the style and css properties, and set it to the value you wish.

JavaScript Equivalents To CSS Can Be Tricky

If a CSS property consists of a single word, the JavaScript reference is the same. Things get more complex if the CSS property contains hyphens or multiple words: the equivalent JavaScript reference is concatenated and camelCased. For example:

CSS PropertyEquivalent JavaScript Reference
font-stylefontStyle
margin-bottommarginBottom
list-style-typelistStyleType

JavaScript CSS Prioritization

Taking this idea a step further, we’ll add a border to the element:

function highlight() {
var ozy = document.querySelector("#ozymandius");
ozy.style.border = "2px solid red";
}

Note that the style imposed by JavaScript merges with the established CSS of the document: our JavaScript-infused style respects the fact that we set a border-radius in the embedded stylesheet but no actual border, and combines the two presentational rules together.

Every CSS property you know is applicable after .style. While it is the fastest and most efficient method in JavaScript of adding styles to elements from the perspective of browser performance, writing a sequence of .style code lines can become a little overwhelming when you want to add more than one property at a time. To get around this, you have a few options.

Adding Bulk Presentational Rules With cssText

You can use cssText to add a block of CSS in one shot:

function highlight() {
var ozy = document.querySelector("#ozymandius");
ozy.style.cssText = "border: 2px solid red; color: red;";
}

(I’ve referenced the #ozymandius element as a variable to gain a little more room per line, not because it is required by cssText).

Note that CSS added to an element by JavaScript takes priority over any established CSS rules:

ozy.style.cssText = "border: 2px solid red; color: red; border-radius: 40px";

After the button was clicked, the <blockquote> element would have a 2px thick red border with a corner radius of 40 pixels and red text. You can think of this in exactly the same way as ordinary CSS rules: a declaration coming later in a stylesheet affecting the same element takes precedence over previous style rules, all other things being equal.

Adding classes With JavaScript

For complex CSS changes, it’s usually easiest to add a CSS class that’s already present in the stylesheet:

.highlight {
	border: 2px solid red;
	color: red;
}

Then add className to the element reference:

function highlight() {
var ozy = document.querySelector("#ozymandius");
ozy.className = "highlight";
}

Note that this will replace any classes already applied to the element. Like most JavaScript references, className can be used to both read and write to the DOM, so if you want to retain classes that were previously applied to the element, you need to concatenate the new class to any existing ones:

function highlight() {
var ozy = document.querySelector("#ozymandius");
ozy.className = ozy.className + " highlight";
}

(Note the space before the word highlight, necessary because multiple classes applied to an element are space-separated).

It's also possible to add, remove and toggle classes with JavaScript using classList, which I discuss in the next article.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.