How to Pimp Your Power BI Reports with Dynamic CSS in the HTML Content Custom Visual

Microsoft Power BI rose to its leading position in the BI market on the back of its top-shelf PowerQuery self-service ETL and VertiPaq in-memory engine as well as its familiarity and integration for Office and Azure users. On the other hand, its competitive strength has never been on the visualization side, especially compared with Tableau’s polish and advanced controls. That is slowly improving, with additions like Charticulator going in the right direction. But overall, most Power BI reports tend to look the same, and the common way to make them look more dynamic and responsive to user input, like an app would, involves time-consuming and clunky use of bookmarks and images. I’ve done it when I really needed to, but I can’t say I enjoy the authoring experience.

I’ve done some web development years ago and because of that background, I’ve always felt that Power BI should expose more of its inner HTML5, CSS, and JavaScript, including for scripting. I don’t know that this will ever happen, as the product’s ethos is titling more towards the “PowerPoint of data” side than towards a bona fide development environment. In the absence of having that level of control, I’ve been toying with a concept that I haven’t seen discussed much by the Power BI community before, so I thought a post might help.

Namely, the HTML Content custom visual can interpret CSS, including via inline styling. In most cases, when CSS is used to build websites, it’s a best practice to put CSS in a separate file. In our case, inline CSS is preferred as it will let us inject data via PowerQuery or better, DAX. Let’s see what that looks like with a quick proof of concept.

1. Dynamic CSS in Power BI, Step by Step

Oh shiny!

A straightforward way to use HTML Content is to generate your HTML code in PowerQuery, for instance in a disconnected table where you could set up a list of reusable snippets. But things get really interesting thanks to HTML Content’s ability to display not only static columns but also DAX measures. This means that you can inject variables into your CSS, opening a range of possibilities.

For our proof of concept, let’s take this CSS gradient then empty out its angle values to replace them with a DAX calculation, which means that the entire gradient is recomputed based on the most common Power BI user interaction, namely (cross) filtering between visuals:

CSS = 
VAR Angle = [Impact Score Average] *36
"<div style='height: 100vh; background: linear-gradient(" & Angle & "deg, #FFB7B7 0%, #727272 100%), radial-gradient(60.91% 100% at 50% 0%, #FFD1D1 0%, #260000 100%), linear-gradient(" & Angle & "deg, #FFDDDD 0%, #720066 100%), linear-gradient(" & Angle & "deg, #00FFFF 0%, #FF4444 100%), radial-gradient(100.22% 100% at 70.57% 0%, #FF0000 0%, #00FFE0 100%), linear-gradient(127.43deg, #B7D500 0%, #3300FF 100%); background-blend-mode: screen, overlay, hard-light, color-burn, color-dodge, normal;'></div>"

A couple of things to notice in the code above:

  • We’re using double quotes to build our string in DAX, so we want to use single quotes within it in the HTML. This is vastly easier than escaping double quotes.
  • height: 100vh sets your main div (the “box” of HTML content you’re filling in) to use its entire height even if it’s empty.

By putting the HTML Content visual at the bottom of the z-index stack (i.e. select it then “Send to Back”), and playing with partial transparency in your other visuals, you can give your entire report page a “vibe” that users will perceive instantly before reading any specific visual.

Rise and Shine!

Once you have a dynamic background that you like, you’ll want to think through how your overall Power BI theme needs to be lined up with it. Tools to get you started:

  • The Extract Theme functionality in Adobe Color, in case you worked off someone else’s CSS that came with preexisting colors.
  • The Theme Generator at PowerBI.Tips.

You can of course load a completely different stylesheet too, the above is again just a proof of concept. To see this technique in a live report alongside a bunch of other cool visual effects, check my entry on pseudo hierarchies with field parameters.

2. Use Cases: Make it Look More About the Individual Report and Less Like Every Other Power BI Canvas

Now that we’ve established we can do this, should we? What’s the point? Here are some scenarios where I think this technique is worth exploring:

  • Big screen dashboards meant to be consumed from a distance rather than interacted with at your desk. Reports displayed on a big TV hanging in the office can’t be designed like they’re going to be read, the 10-feet-away experience is completely distinct.
  • This instant “mood” that you can convey with smart use of CSS can work well for operational status reports where you want the team to know whether they’re behind, at, or above their goal. Are we killing it or are we getting slaughtered? Is there an emergency to address? Giving that instant visual feedback would also benefit What If scenarios and the new goal scorecard.
  • Reports that have a strong branding requirement. You might see this more in FMCG companies where branding and product packaging are core company values. Of course, this needs to be healthily balanced with usability and accessibility concerns, but some users/customers will want to see their logo and color scheme heavily reflected on their reports, and you’re just not going to change their mind. Roll with it and make it work, or resist it and they’ll get someone else to do it.
  • Organizations where Power BI is already heavily deployed with every report looking the same (“wait, which report am I even looking at again?”), and they’re looking for a bit of a visual makeover. I myself tend to make very utilitarian reports where every pixel needs to matter. But what if the intended audience will actually engage more with a bit of visual glamour? The reality is that people get bored with reports that look like IT designed them.
  • Visual elements that would be time consuming to generate and handle as images or SVG. Because CSS is code, it inherently gives you more dynamic control than having to load static assets like GIFs.

3. Known Limitations: I’ll Admit This is A Bit Cutting Edge

Like most things, this technique comes with its set of tradeoffs, so better walk into it informed of its drawbacks:

  • HTML Content is not and cannot be certified, so all limitations of non-certified custom visuals apply: no print, no export to PDF etc.
  • Power BI’s sandboxing rules can get in the way, read this for details.
  • Support for advanced CSS techniques varies among browsers. If you have to support users stuck with ancient versions of Internet Explorer, things can get pretty hairy.
  • Power BI Desktop may or may not render your CSS the way actual browsers will. You will need to doublecheck how things work in the service.
  • Most Power BI developers and business analysts don’t know CSS, these are different skillsets. Be prepared to learn, leverage online resources, or work with a web designer. Or you can hire me.
  • Expression-based control of partial transparency for visuals doesn’t work, so you need to hardcode that via each visual’s Format panel. I’m mentioning this because the primary appeal of this approach is to stack the HTML Content visual either below or on top of other visuals. We can achieve dynamic partial transparency within the HTML Content visual as it’s something you can control with CSS.

4. Further Resources: CSS Is Its Own Universe

I only scratched the surface with this proof of concept. Here are some pointers for the community to explore, I’d love to hear what you come up with!

Among these advanced techniques, CSS transitions – including on hover – do work, as well as CSS animations:

On the left, a CSS animation. On the right, a smooth color transition in and out of hover (i.e with control of duration) and partial transparency cannot be done programmatically natively in Power BI. Here done with a couple lines of CSS/HTML in a DAX measure.

Power BI tends to feel a bit “flat” and could use more affordance. These techniques might be an acceptable workaround to highlight buttons, add halos to cards when they’re showing extreme or unexpected values, or otherwise provide visual cues whenever warranted.

I focused this entry on creating background textures in a single div, but you could push the envelope much further by generating dynamic HTML as well. Good luck if you fall in that rabbit hole!

I don’t always write about Power BI, but when I do, I tend to research topics fairly extensively. Check out the Power BI category for posts on third-party tools, object level security, dataflows, custom visuals, and more.

4 thoughts on “How to Pimp Your Power BI Reports with Dynamic CSS in the HTML Content Custom Visual

  1. Samuel Martin

    Newbie here 🙂 Can you be more explicit as to how to implement the code snippet, please? I installed the HTML Content, created a card with it and dragged the CSS Measure into the card’s Visual Filter… the bg does not show up. I have no such element as Impact Score average in my PowerBI file, but not matter what modification I try, I get an ‘incorrect DAX syntax’ message. Thank you!

  2. otravers Post author

    Samuel, see the DAX measure example at the beginning of the entry (the statement that starts with “CSS =”). Most likely you have an issue with single vs. double quotes.

  3. Rafael Luvian Fagundes

    Oliver Is it possible create buttons to redirect to another page in powerbi, like native buttons of powerbi?

    I’ve been finding more examples about css with powerbi but I’m not sucessfull in it. Do You have some places with more explanation about this?

    1. otravers Post author

      I’m not exactly sure what you intend to do, but you could try putting a regular Power BI button with a bookmark link on top of the HTML viewer, then make that button transparent.


Leave a Reply

Your email address will not be published. Required fields are marked *