I have been a Tableau Desktop user for about 18 months, using a free copy of the software I received as a member of Investigative Reporters and Editors (Thanks Tableau!). The software truly impresses with how quickly even a novice user can make good-looking, powerful data visualizations. I've used it for several projects, including LoHud School Security, SBALoans and Fugitives.

Issue: How to make Tableau dashboards responsive?

But an ongoing issue for me has been how to make a Tableau viz responsive. As extensible as it is, Tableau isn't entirely mobile-friendly, meaning visualizations can not be easily reformatted by a browser to fit varying screen sizes. Visualizations will retain the size in which they were created no matter the size of the screen viewing it. That is not an ideal experience for users, who end up seeing a desktop-sized chart on a phone and have to zoom in and out or scroll around to see the full viz.

Reviewing those links I posted, you might notice a trend. In our mobile-first world, I sized them small to ensure they work on phones. In the news business, it is critical that the content we create work for all screen sizes since half or more of our daily web traffic comes mobile devices (smartphones and tablets). But this is a compromise. While doing this ensures users on all devices can see the full viz, desktop and tablet users would rightly be annoyed that half or more of their screens are empty. This is also not ideal since it greatly limits the real estate you have to play with.

Cue the late-night infomercial guy: What if there was a way to make a single Tableau project display differently on devices of all sizes?

Solution: CSS

I found the answer - well, one answer - with 20-year-old web tech: Cascading Style Sheets, or CSS.

How to implement my CSS solution

Open that link on your smartphone. Then on your tablet and on your desktop. You will notice it is a different presentation, formatted differently for varying screen sizes. There's no wizardry involved. Basic CSS is all you need.

Step 1: Create multiple dashboards

The key is in how Tableau works. Every Tableau project, once uploaded to the company's servers, gives users an embed link for that project’s dashboard. You can drop that link on a webpage and the dashboard project will appear in a browser at whatever size it was in your project. What had not occurred to me until lightning struck was that you can create multiple dashboards with a project - each can be a different layout and each has its own embed link!

I decided to experiment. I created a viz using school test scores. I imported my data into Tableau and created three dashboards, one sized for desktop, one for tablet and one for mobile phones.

My desktop dashboard takes up the most space and has dropdowns lined up side by side.

My tablet dashboard is sized at 764 by 655. I am now dealing with smaller tablet screens so I keep the full-sized dropdowns but I stack them on top of each other instead of placing them side by side.

This next step is where my intermediate Tableau skills might have hindered me. I attempted to make a third dashboard in this project with even smaller fields for mobile but for some reason going that small affected the display of my other dashboards. They must share some global settings where changes are mirrored among them. Rather than hammer out this issue, I took the easier, more cumbersome, route. I imported my data into a separate Tableau project and made a mobile-sized dashboard, sizing it at 320 by 520, shrinking the size of the fields and using smaller dropdowns.

Step 2: Grab the embed code for all your dashboards

Once done, I uploaded both projects to Tableau and grabbed the embed links for each dashboard. From there, you can begin making your web page. Add in whatever markup you'll need (banners, title, introductory text, etc.) then place each of the embed scripts for your dashboards on the page.

Wrap each embed link inside of its own div tag and give each a name. At this stage, my page body looked like this:

(Desktop)

(Tablet)

(Phone)

Step 3: Write the CSS

I then wrote the CSS rules. I'm assuming you're familiar with CSS but basically it's the web language that applies styles and formatting to plain HTML. CSS is also able to show and hide different elements on a page based on rules you set (screen size, user interaction, etc). We'll focus on screen size.

Be sure to include a viewport meta tag, which is necessary to optimize the page for a mobile display.

Running through it quickly, this basically grabs the width of a device for the browser, loads the content at its full responsive display size and does not let the user zoom in and out. That last part is not a hard and fast rule. Sometimes you will want the user to be able to zoom.

I then set the rules to tell the browser when to display each div. All three embed scripts are on the page so these rules are essential. Without them, all three embeds will always be displayed. Here's the CSS I used:

You may need to fine-tune the pixel counts for your needs.

How it all works

That’s pretty much all it takes but let me explain what is happening. When a visitor loads your page the browser is told the size of their screen. The HTML loads containing all of the scripts but only one embed (i.e. dashboard) will be shown based on the rules you set while the other two are hidden. On a screen between 320 and 763 pixels the browser will hide the tablet and desktop embeds. Since the rule doesn't hide the mobile embed, it will be the only one shown.

Note: 320 pixels is typically the smallest size you'll have to worry about. It's the size of older iPhones. Below that and you're in dumbphone/flip phone territory, which probably wouldn't be able to display any of this.

The next rule says if a device screen is between 764 to 999 pixels, hide the phone and desktop embeds. The tablet embed will then be displayed.

Lastly, for device screens of 1000 pixels or above, the rule will hide phone and tablet displays only showing the desktop version.

There it is, responsive Tableau. Very cool, right?

See the dashboard in action!

Click on the image below to see the solution in action (try it out on your desktop, tablet and phone!)

I hope this helps some of you with what can be a vexing problem If you have any questions, you can reach me on Twitter at @DwightsNews or on my website, dwightworley.net.

Keep in mind that using this method means that all three dashboards are loaded by the web browser even though only one of them is rendered at a time. For large data sets or complicated visualizations, this could cause significant performance issues.

Also consider that each dashboard could be designed to fill up 100% width it's breakpoint. For example, your "phone" dashboard's size could be set to a range between 764x655 and 999x655. Then replace all the width references in the embed code generated by Tableau to be "100%." The dashboard would then perfectly fit the size of any screen within that range.

This is really interesting for me, we're trying to make our dashboards tablet and mobile-friendly.

Perhaps I need to reread it a few times, but I'm wondering does this mean that I can't implement this solution if I am just using regular Tableau Server links. Our dashboards aren't sucked into a separate webpage which I can 'edit'.

I use a method that definitely isn't fool proof. I set the size to fit in a tablet (we don't support mobiles), and then for desktop I scale the iframe tableau appears in. It's not perfect, but I does the job and saves us having to manage multiple instances of the same dashboard.

So, this issue is my nemesis. But, I am coming at it from a slightly different angle.

I want to embed the dashboard using Tableau's JS API not the generated embed code. It also means the dashboard can be stripped down to the bare minimum, making it easier to conform to different screen sizes (i.e., fewer dashboard objects). I then add custom filters and controls to my site that use API scripts to interact with the dashboard.

I just can't figure out how to make the lonely viz div object responsive using CSS - when the embedded dashboard is of a pre-defined or automatic size. (I know just enough JS to embed the viz and interact with it, and enough HTML to add a viz div to the page; I know nothing about CSS.)