Overlapping Bar Charts

Read Time:7 Minute, 12 Second

As the name suggests, overlapping charts visualize two different sets of data in a single diagram. The idea is that the overlapping bars allow us to compare data, say, year-over-year. They are also useful for things like tracking progress for a goal where one bar represents the goal and the other shows the current amount.

But they’re beautiful too!

Overlapping Bar Charts

Your mind is probably like mine and is already starting to figure out how you’d go off and code that. Here’s how I tackled it.


We’re going to start with markup because, well, that’s how we know what needs styling.

We will be using description lists (<dl>) as it is a much more semantic approach as compared to standard ordered and unordered lists. Another reason is that we are including a label within each bar. Normal lists do not have a tag within them to add a title or description unlike definition lists. In simple terms, it just makes more sense and is more readable too.

The first description list, .numbers, is the y-axis. The .bars is where the data is visualized and I’ve made a definition list to build the x-axis as well. Each list item contains a .bar and the label as a description term (dt).

And what’s up with the data attribute? The data-percentage is being used to specify the height of the bar, which ultimately represents its value on the y-axis. We could manually set it in CSS for each bar, but that is repetitive and a lot of extra code that can be replaced with a few lines of CSS.

The basic chart styles

We’re working with a lot of two-dimensional directions, so flexbox is going to be our friend for getting everything lined up. We can make the .chart element a flexible container that positions the y-axis labels and the chart beside one another in the row direction.

We don’t even need to specify the direction since flexbox defaults to row. Let’s do that and then add flexbox to the list of labels along the y-axis while we’re at it since we know those will run in the column direction.

Believe it or not, we can use flexbox again for the bars since, they too, are running in a row direction.

I’ve set this up so that the .bars automatically take up whatever space is leftover by the y-axis .numbers.

You probably noticed it in the HTML, but “bar” is actually two bars where one overlaps the other. I wrapped those in a generic <div> that we can use as yet another flexible container that holds the definition term (<dt>) we’re using as a label and the description details (<dd>) that holds both bar values:

Each bar is going to be the same width, hence flex: 1. We’re relatively positioning the element while we’re at it because we’re about to absolutely position each bar and we want to make sure they stay in their containers.

Each bar has a percentage height that corresponds to the values along the vertical y-axis. You may also remember that we gave each bar a data-percentage attribute — we’re going to sprinkle in a little JavaScript that sets the height of each bar using those values.

That’s our basic chart!

We want to get this to where we can see the bars overlapping one another. That’s next!

Overlapping bars

The trick to get one bar to overlap another is funny because we’re often trying to prevent things from overlapping visually in CSS. But in this case, we actually want that to happen.

The bars are already overlapping; it’s just tough to tell. Notice in the HTML that the second .bar in each set has an additional .overlap class. Let’s use that to differentiate the bars. You’re totally free to choose your own styling for this. I’m adding a little padding to the .overlap bars so that they are wider than the other bars. Then I’m tweaking the stacking order using z-index so that the .overlap bars sit below the other bars.

Let’s add a legend

Legend. Such a great word, isn’t it? Packed with all kinds of meaning. In this case, it’s a more than a nice touch because, visually, we’re jamming two bars in spaces that are typically reserved for one bar. A legend provides context that explains what each bar represents.

Using a <figure> feels correct to me. They’re often used to wrap images, but the spec says they’re used “to annotate illustrations, diagrams, photos, code listings, etc.” and we’re working with a diagram. We could probably use an unordered list to hold the items, but I went with an unsemantic <div>. If anyone has an opinion on the best way to mark this up, I’m all ears in the comments!

Once again, styling is totally up to you:

Accessibility considerations

We’ve spent a bunch of our effort on making decisions for the markup and styling of our overlapping bar chart. It’s great so far, but we’re definitely not done because there’s more we can do to make this a more accessible experience. Not everyone is a sighted web surfer, so there’s some additional work to do to convey the content in those contexts.

Specifically, we need to:

  1. check that our colors have plenty of contrast between them,
  2. allow keyboard users to tab to each overlapping bar, and
  3. make sure screen readers announce the content.

Color contrasts

We need enough contrast between:

  • the overlapping bars
  • the bars and the chart background
  • the label text and background

I did a little homework in advance on the colors I used in the examples we’ve look at so far, making sure that there is enough contrast between the foregrounds and backgrounds to achieve WCAG AA compliance.

Here’s what I’m using:

  • Overlapping bars: (#25DEAA and #696969: 3.16:1 ratio)
  • Bars and chart background (#696969 and #111: 3.43:1 ratio)
  • Y-axis label text and background (#fff and #333: 12.63: 1 ratio)

Tabbing between bars

To get this where keyboard users can select each individual bar with the Tab key, we can reach for the HTML tabindex attribute. We can use the following JavaScript inside the for-each function to add this property to each bar (both of them). We will set the tab index to 0:

We can also add some CSS to improve the outline when the bar is selected while we’re at it:

Announcing content on screen readers

Another important aspect of accessibility is making sure screen readers can announce the bars and their percentages.

We’re working with two different charts in one: a chart that shows “Estimated” values and another that shows “Actual” values. It’d be great if the user knew which bar was being announced, so let’s label them with the aria-label attribute:

Notice that we have the bar’s value directly in the HTML as well. That will get announced, but we still want to visually hide it. We could use transparent text for that, but another way is to use the classic .visually-hidden trick by wrapping the value in span:

While we’re talking about announcing content, we can probably prevent the y-axis labels from being read. It’s not like the user is missing information, as the actual percentages for each bar are already available and announced. We can use the aria-hidden attribute for that:

I also think it’s OK for screen readers to ignore the legend since it’s a visual aid:

The final demo

That’s a wrap!

There we go, a chart with overlapping bars! It’s a nice way to compare data and I hope you can find a use for it on some project.

Are there other ways we could have approached this? Of course! Everything we covered here is merely walking you through my thought process. I imagine some of you would have taken a different approach — if that’s you, please share! It’d be great to see other CSS layout techniques and perspectives on nailing the accessibility.

Source: https://css-tricks.com/overlapping-bar-charts/

WP Ad Inserter plugin for WordPress

Tag Cloud

Java Java Logical Programs OTP Generation in Java python Recursion youtube video ASCII Upper and Lower Case blockchain javascript graph learn to code software development Successful Software Engineers breadth first search Java Array Programs Java Programs Uncategorized android ios programming kotlin web-development django data sql cybersecurity database swiftui serverless aws swift rust react background-position gradients loader mask grid nth-child pseudo elements indieweb WordPress Print Array without brackets C++ factorial Java String Programs Final Keyword Static Variable Axie Infinity Cryptokitties NFT games tool inserting MISC Tips Codes python code python projects python3 system info python project Bigginers How to Do Integrations Payment Gateways PHP checkout page in php Implement stripe payment gateway in Step by step in PHP integrate stripe gatway in php mysql payment gateway integration in php step by step payment gateway integration in php step by step with source code payment gateway integration in website PHP Integrate Stripe Payment Gateway Tutorial PHP shopping cart checkout code shopping cart in php stripe php checkout PHP/MySQL/JSON best international payment gateway does google pay accept international payments how to accept international payments in india paytm payment gateway razorpay codeigniter github razorpay custom checkout github razorpay get payment details razorpay integration in codeigniter github razorpay international payments Razorpay payment gateway integration in CodeIgniter razorpay payment gateway integration in php code Razorpay payment gateway integration with PHP and CodeIgniter Razorpay payment gateway setup in CodeIgniter Library & Frameworks Tips & Tricks UI/UX & Front-end coding birds online html code for google sign in login with google account in PHP login with google account using javascript login with google account using javascript codeigniter login with google account using php login with google account using php source code
Hacking CSS Animation State and Playback Time Previous post Hacking CSS Animation State and Playback Time
Next post Introducing PyMultiAuth – The ultimate Python Authentication Toolkit

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.