css organizational chart lines

Okay, so the other day, Zoë asked me if it was possible to use CSS to make those organizational chart lines in that picture up there, and I said, “Why not?” I typed out a solution, wrote a quick walk-through about my thought process, and I figured I would share it with the rest of the world, too. Below is the simplified solution I created, available for you to download and look at to match with the final product of this tutorial. Disclaimer: This was typed during the evening hours inside Chrome developer tools and was left relatively unedited or fact checked, sorry not sorry.

Organizational-Chart-Lines-CSS-Solution.zip

Cool. So, to begin, this is an outline of how I imagined splitting this graphic into parts:

WE PUT THE RIGHT MESSAGE IN THE RIGHT HANDS AT THE RIGHT TIME

COLUMN ONE

COLUMN TWO

COLUMN THREE

So, in my solution, you will see the above heading and 3 columns, each holding their own piece of the graphic inside. Why did I decide to do it this way? Pretty much, the graphic spans 1 whole column and 2 half columns, so because I had to position the lines based on the center-point of the outside columns, and it is difficult to find the center of an element outside of that element, I decided this was an inside job. Let’s break it down, lose the heading, and just look at the columns, since they will be what we are working inside of:

COLUMN ONE
COLUMN TWO
COLUMN THREE

We Begin Our Journey in a Sunny Glade, Confident that We Will Find The Princess:

Step one: the best place to start. I won’t waste your time, let’s dump some ugly-*** containers inside of there.

COLUMN ONE

COLUMN TWO

COLUMN THREE

Naturally following, you want to put the left graphic piece aligned right inside it’s column and the right one aligned left while leaving the text centered in each of the columns. Now, someone with a simple knowledge of CSS might say, float the left one right, and float the right one left. Set the widths to 50%, turn on the top and side borders you want to see and call it good. And they’d be right! However, watch what happens immediately following this action:

.graphicLeft, .graphicMid, .graphicRight {
    height: 20px;
}

.graphicLeft, .graphicRight {
    border-top: black solid 1px;
}

.graphicLeft {
    border-left: black solid 1px;
    float: right;
    width: 50%;
}

.graphicRight {
    border-right: black solid 1px;
    float: left;
    width: 50%;
}

COLUMN ONE

COLUMN TWO

COLUMN THREE

Holy problem hell! Let’s fix the first, easiest thing: lets get the tops of those columns aligning. This is probably taken care of automatically by Bootstrap for you if you’re working in WordPress like we were here (WordPress column are base solely off of the usage of Twitter’s Bootstrap), but this is an important concept, regardless. The CSS property vertical-align has nothing to do with how stuff lines up vertically inside an element (unless you’re in a table-cell element, but that’s a different story). Rather, this property defines the vertical alignment relationship between elements side-by-side on the same level. Sounds like it’s a good time to put that theory to the test.

.col {
    ...
    vertical-align: top;
    ...
}

COLUMN ONE

COLUMN TWO

COLUMN THREE

Oh, look it’s almost manageable. But see how the blocks float left and right and the text goes around the sides of them? Now you have to do the voodoo. Ever seen that weird class on EVERY SINGLE WEBSITE called “clearfix”? Sometimes it doesn’t do **** if you delete it, but sometimes it does. Well, it’s time to make your own clear fix. Ours will do something because we write good code. Let’s start with a dedicated example:

So Entereth the Clearfix Soapbox:

LOOK AT ME, I FLOAT!
ALL GOOD CONTENT IS IN CONTENT BOX NUMBER ONE

So, the box floats right, over the other box, and you see the borders of that box going through and underneath the floating box, though the text stays to the outside. With trial and error, you’ll most likely find if you put down enough <br /> tags after the floaty-box, you can find your own line for the other box.

LOOK AT ME, I FLOAT!
ALL GOOD CONTENT IS IN CONTENT BOX NUMBER ONE
LOOK AT ME, I FLOAT!

.

ALL GOOD CONTENT IS IN CONTENT BOX NUMBER ONE
LOOK AT ME, I FLOAT!

.
.

ALL GOOD CONTENT IS IN CONTENT BOX NUMBER ONE

But that’s dumb, because it doesn’t do exactly what we want perfectly. The floaty-box is a whopping 50px tall, and the base font-size (1rem) is 16px. Which means 1 line-break = 1 rem ≠ a factor of the bottom of the floaty-box. Plus, if you change the floaty-box height, you have to add or take away line breaks, then deal with the resulting white-space difference. Plus, what happens if the screen size goes down? Try it and see. Now a clearfix is a class definition containing one CSS property: the clear property, and it takes care of our problem nicely.

.clearfix {
    clear: both;
}
<div class="iFloat">...</div>
<div class="clearfix"></div>
<div class="iDontFloat">...</div>

This “clearfix” is just an empty div with the clear property on it. The clear property can be used to clear the side of any right or left float, so that it floats, but it stacks still, too. We’re just going to say clear: both and use one class for all our needs. So scrap the manually entered line breaks, and throw in a clearfix instead:

LOOK AT ME, I FLOAT!
OH MY ******* GOD THIS LOOKS SO MUCH CLEANER

Pent Up Digression:

Okay, where were we… Here.

COLUMN ONE

COLUMN TWO

COLUMN THREE

So let’s smack down a couple clearfixes on that bad-boy right between the text and the graphic boxes.

COLUMN ONE

COLUMN TWO

COLUMN THREE

Oh, wow, I feel like I can do this all of a sudden! Ingrid may let me keep my job! Note that the clearfix is only needed on the right and left; there’s nothing floating in the middle. For the last part, we need a vertical line in the middle and a big line on the top, so we’re essentially missing a big ol’ “T” shape. So, I think I’ll make a box with only one border (either right or left, of course) like the other two, then just put a top border over the entire middle column. I’m usually a fan of going through great lengths to use the text-align property (simple personal preference), but I’m just going to leave the middle piece a block level element and position it using margin since it goes on its own line anyway.

.graphicMid {
    width: 0;
    margin: 0 auto;
    border-left: black solid 1px;
}

.col.center {
    border-top: black solid 1px;
}

COLUMN ONE

COLUMN TWO

COLUMN THREE

And that should do almost exactly what we want. You’ll notice there’s little spaces between the borders. This is no CSS issue, so do not take counsel with the CSS gods! This is most likely because you or your CMS likes your code to be human-readable, so there were probably spaces or returns put in between the code. If you highlight the entire thing, you’ll see the spaces selected!

<!-- Don't do this -->
<div>COLUMN</div> <div>COLUMN</div>

<!-- Or this... -->
<div>COLUMN</div>
<div>COLUMN</div>

<!-- Do this! -->
<div>COLUMN</div><div>COLUMN</div>

COLUMN ONE

COLUMN TWO

COLUMN THREE

Voici! Nous avons fini! Those spaces are still there, because WordPress doesn’t play nicely with people who know what they’re doing; I just put some negative margins on there to make it look like I have to freedom to control what I type in this pain-in-my-*** box. I hope you found some of this useful are able to apply it towards bringing better solutions to real-world problems. Leave me a comment with any questions/suggestions you may have.

Fin.

Leave a Reply

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