Lee Jordan

CSS only flowcharts

CSS only flowcharts

Is it possible to generate flowcharts on a web page using only CSS and HTML? The short answer is yes (but only for simple charts).

I've occasionally run into the requirement to display flow charts on the web. I've never been entirely satisfied with any of the solutions I've landed on. I've generated them as flat images, or rendered them on a canvas element. In my efforts to render a more accessible flow chart, I wondered if you can achieve this with just HTML and CSS.

I spent an enjoyable few hours poking away and have produced a few demos which show how it could work, but only for quite simple flow charts.

#Example markup and SCSS

There is far more to discuss that I've outlined here, but this should give you the basic idea before I show a few examples. For a deeper dive, view the full SCSS on github.

For a vertical family tree style flow chart, Take a set of nested unordered lists:

<ul>
  <li>
    Arthur Thucksake
    <ul>
      <li>
        Harry Thucksake
        <ul>
          <li>
            Oswald Thucksake
          </li>
        </ul>
      </li>
      <li>
        Theresa Thucksake
        <ul>
          <li>
            Melinda Pickles
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Use flexbox to setup the lists so that they flow nicely and are horizontally centered:

ul {
  list-style: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-around;
}

Use pseudo elements to create the lines that visually connect each item in the list:

li {
  &:before {
    content: '';
    position: absolute;
    top: 1em;
    width: 100%;
    border-top: 3px solid black;
  }

  &:after {
    content: '';
    position: absolute;
    top: 1em;
    left: 50%;
    height: 1em;
    border-left: 3px solid black;
  }
}

Use descendent selectors to handle direct children of the list (so that we don't add lines where they are not needed)

> li {
    &:before,
    &:after {
      display: none;
    }
  }

#Basic family tree example

  • Arthur Thucksake
    • Harry Thucksake
      • Oswald Thucksake
    • Theresa Thucksake
      • Melinda Pickles
      • Brian Pickles
        • Steve Giblets
        • Vanessa Giblets
        • Wilhelm Giblets
      • Timothy Pickles

This looks like a decent solution at first but it has one important limitation: how do you indicate a link between items in the same row? Take this example of a family tree where you can see links horizontally:

family tree example

How do you express that relationship with only HTML and CSS? In short, I'm not sure you can, at least not with the markup I'm using as an example. Perhaps two spans inside the first list item? We could draw a line between the two with the same pseudo element approach that we use for the vertical lines.

<li>
    <span>Arthur Thucksake</span>
    <span>Gemina Thucksake</span>
</li>

If we could resolve this then our solution would work well for more complex family trees and even organisational charts. But for now it's starting to get more and more complex so I'll think further about this issue in the future. Let's move on to the next example...

#Dendogram example

A dendrogram, among other things, is used to display the evolutionary relationships among various biological groups. This seems ideal for our HTML/CSS solution because we only ever have one ancestor so we don't need to show relationships between nodes at the same level.

#Decision tree example

In a decision tree, we need to visually distinguish the various node types, so we're using <span> elements inside our list items and styling them as required. For example:

.terminator {
  display: flex;
  align-items: center;
  padding: 1em 2em;
  border-radius: 2vw;
  background-color: #c9c9c9;
}

This allows us to build decision trees in a single direction. However, there is one important limitation to this solution which is sometimes a decision tree will want to link back to an earlier node. We can't do that here, but for decision trees without that requirement, this should work.

#Conclusion

It's certainly possible to render simple flow charts in various styles using HTML and CSS only, as long as you are willing to accept the limitations. It would therefore be possible to dynamically render simple charts like this from nested data objects, such as JSON strings.

Check out the code on github if you want, and let me know if you have any suggestions.