Using Bootstrap 4 Theme Colors in JavaScript

Jun 2018

I'm leading the front end design on a project where we use Google Charts to visualize data for a Java web application. The web app's front end is built on Bootstrap 4. Anyone familiar with Bootstrap and Material Design (Google's design language) will immediately recognize the disparities between the two in terms of look and feel. One challenge that presented itself while integrating Google Charts with the Bootstrap framework was how to keep the colors in sync between the two systems. In this post, I'll cover how I worked Bootstrap 4 theme colors into Google Charts via JavaScript to create integrated-looking data visualizations.

Setting the Stage

Admittedly, I'm a Bootstrap fan boy. I started with Bootstrap 3 and have followed development of Bootstrap 4 from its inception. I'm active on Bootstrap's Slack channel. I think the Bootstrap community is fantastic. I think the Bootstrap 4 framework itself is wonderfully designed. I find it very easy to work with, customize, extend. I've also worked with Sass for a number of years, and appreciate its core integration in Bootstrap 4. I'm not so strong with JavaScript, but understand it's growing popularity. I'm also not a Google Charts expert. I work with it because it's the library chosen by our backend developers to display data. With all this in mind, the following should be taken with a grain of salt. And keep in mind, this is but one way out of many to achieve the desired result.

Exploration

Looking at the _ root.scss partial in Bootstrap's scss directory, we find color, theme color, breakpoint and font variables added to the :root pseudo class as custom properties. This is what the Sass code looks like:

:root {
  ...

  @each $color, $value in $theme-colors {
    --#{$color}: #{$value};
  }

  ...
}

And the CSS output looks like this:

:root {
  --blue: #007bff;
  --indigo: #6610f2;
  --purple: #6f42c1;

  ...

  --primary: #007bff;
  --secondary: #6c757d;
  --success: #28a745;

  ...
}

Looking at the CSS from the developer console in a web browser, we see something like this:

Bootstrap 4 :root variables in developer console
Browser support for custom properties is pretty solid, aside from IE, meaning these variables are accessible on most modern browsers.

And since Bootstrap includes these values on the :root pseudo element, which is essentially the same as the <html> element, it means these values will be accessible on every page that loads the Bootstrap CSS.

Now let's look at the Google Charts library. At a high level, to display a chart you have to do the following:

  • Load a Google Charts package
  • Provide data
  • Specify options
  • Set a location for display
  • Draw the chart

Here's an example of what the JavaScript code might look like:

google.charts.load("current", { packages: ["corechart"] });
google.charts.setOnLoadCallback(drawChart);

function drawChart() {
    var data = google.visualization.arrayToDataTable([
        ["Item", "Amount"],
        ["Give You Up", 27],
        ["Make You Cry", 7],
        ["Run Around and Desert You", 8],
        ["Make You Cry", 15],
        ["Say Goodbye", 20],
        ["Tell a Lie and Hurt You", 23]
    ]);

	var style = window.getComputedStyle(document.documentElement),
		item1 = style.getPropertyValue('--red').trim(),
		item2 = style.getPropertyValue('--orange').trim(),
		item3 = style.getPropertyValue('--yellow').trim(),
		item4 = style.getPropertyValue('--green').trim(),
		item5 = style.getPropertyValue('--blue').trim(),
		item6 = style.getPropertyValue('--purple').trim();

	var options = {
		width: $(window).width(),
        height: $(window).height(),
		title: "Rick Astley Would Never",
		titleTextStyle: {
			color: item1,
			fontSize: 50,
			bold: true
		},
		pieHole: 0.2,
		pieStartAngle: 0,
		pieSliceText: "none",
		slices: {
			0: { color: item1 },
			1: { color: item2 },
			2: { color: item3 },
			3: { color: item4 },
			4: { color: item5 },
			5: { color: item6 }
		}
	};

	var chart = new google.visualization.PieChart(
		document.getElementById("donut")
	);

	chart.draw(data, options);
}

This example draws a donut chart. See a working demo of this code on CodePen. The parts of the JavaScript we're most interested in are the style and item variables and the slices property of the options object.

Solution

We have our Bootstrap theme colors stored in custom properties on the :root pseudo element in our CSS. We know we can color the slices of our donut chart by specifying a color for each slice in the slices property of our Google Charts options object. All we have to do to extend our Bootstrap theme to Google Charts is access the theme colors in the CSS with JavaScript and plug them into slices options as color values. Here's one way to do it:

First, set a variable in the JavaScript to hold the CSS property values (var style). Next, using the getComputedStyle method on the window, we'll return an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain. The element we're interested in is the documentElement of the document, which returns the root element of the document (the <html> element). From there, we'll use the getPropertyValue method to get the value of each theme color property, and assign that to a variable (e.g. item1).

The trim() method should be used to trim whitespaces returned with the property value. You may find this necessary to include if you like to put a space between your property and value in your Sass/CSS (e.g. --blue: #007bff;). The getPropertyValue method will return the string " #007bff" if the trim() method is not called — note the leading space in the string — and Google Charts may complain about the whitespace in there when trying to draw the chart.

We now have our Bootstrap theme colors stored in variables in our JavaScript. All we have to do to complete the task is assign our desired Bootstrap theme color to the slices of our chart (e.g. 0: { color: item1 }).

Mission accomplished!

The cool thing about storing off the custom properties from the :root pseudo element as variables in the JavaScript is that if you change the color values of your Bootstrap theme, those changes will propagate to your chart after you recompile your CSS without having to edit any of the JavaScript code (assuming only the values change, not the property names). In this way we're dynamically translating Bootstrap theme colors from our stylesheet to our JavaScript.

In Conclusion

Integrating third party libraries and frameworks into your web application's front end can be a tough task to accomplish. Getting code that you didn't write running is a difficult task alone. But then, to integrate seemlessly, it can take a lot of effort. Fortunately, modern libraries make this task possible by taking advantage of newer CSS features and harnessing the power of JavaScript to build components quickly and dynamically.

There are, of course, other ways this challenge could have been completed. For instance, nmax reported using the NPM package gulp-sass-json to build Bootstrap theme variables into a JavaScript variable.

Likewise, the method for accessing CSS properties in JavaScript put forth here can be applied to a variety of problems, not just customizing colors in a charting library. You can store and access all kinds of data in custom properties. Bootstrap 4, for example, also has values for breakpoints and fonts you can access via :root variables.

But as with any technical decision, tradeoffs have to be considered. The solution above may run slower than other solutions; in nmax's solution, the setting of values is not as dynamic; both come with caveats during interpretation, when the code traverses the CSS/JavaScript border.

If you work with Bootstrap, I encourage you to say hi to the community on the Slack channel. The community there is very helpful and welcoming.

If you haven't worked with Bootstrap 4 yet, I highly recommend checking it out. It has come a long way since Version 3. I'd buy all the contributors and maintainers a beer if I could. What a job they've done with the framework.

And if you've found other solutions to the problem of accessing Bootstrap variables in JavaScript, I'd love to hear what you've come up with.

👋 Hi, I'm Chase
profile picture

I work at Verilogue, a medical marketing research company, as part of a rock star development team.

I enjoy writing about web design, and throughout this site share my experience as a front end developer working at the intersection of Big Data and Big Pharma.

In my spare time I like to compose music, which I link to from the playground along with all of my other side projects. I also spend a lot of time reading, mostly about web design and user experience with the occasional book on string theory or building time machines. Beyond that, I enjoy traveling, cooking, and playing World of Warcraft, where I main a Fire Mage named Wildford.

I grew up in Harrisburg, PA and graduated from Temple University in 2007 with a bachelor’s degree in Advertising and a minor in Sociology.

To learn more about me, check out my resume or let's talk on X.