Splitting a border around another element

1 min read
5170 views

This is one of those “Can you do that, no you can’t do that, but can you really do that?” moments. Splitting the border of an element around another element. Although, I should put quotes around “splitting”. You’re not actually splitting a border, but rather creating the appearance of it.

First, what the heck am I talking about?

Okay, that’s kinda clever. “So…a table?” you might ask.

Nope, a single <span>.

“Wuuuuut?”

Let me show you.

The HTML

<div class="heading" role="banner">
  <div class="split-border"><span></span></div>
  <div class="logo">
    <img src="https://upload.wikimedia.org/wikipedia/en/3/34/SFDC_logo.png" alt="Salesforce logo image">
  </div>
  <h1>The World's No. 1<br>CRM Solution</h1>
</div>

Full disclosure: I don’t have “official” permission to use the Salesforce logo in this demo. So anything you don’t like here reflects on my crappy coding and not on Salesforce.

The CSS

Let’s review the styles that help define that border layout:

.heading .logo {
  text-align: center;
}

.split-border {
  text-align: center;
}

.split-border span {
  position: relative;  
}

.split-border span::before,
.split-border span::after {
  border-top: 1px solid #fff;
  content: "";
  position: absolute;
  width: 5.625em;
}

.split-border span::before {
  margin-right: 3.75em;
  right: 100%;
}

.split-border span::after {
  margin-left: 3.75em;
}

For starters, the logo image is center-aligned inside the parent <div> container:

.heading .logo {
  text-align: center;
}

The .split-border class also centers the <span> inside the parent container:

.split-border {
  text-align: center;
}

Now for the fun part…

The <span> element’s pseudo-elements each have a top border and a specified width:

.split-border span::before,
.split-border span::after {
  border-top: 1px solid #fff;
  content: "";
  position: absolute;
  width: 5.625em;
}

That width value corresponds to the overall width of the container element, minus the width of the logo image. When we apply a margin to each pseudo-element (either margin-left or margin-right, respectively), the “split” effect is created:

.split-border span::before {
  margin-right: 3.75em;
  right: 100%;
}

.split-border span::after {
  margin-left: 3.75em;
}

And voila

There you have it

This is a trick I’d never done before until another developer asked how I might go about implementing that kind of design. There may be traditional methods (<table>) or even more creative solutions (text-shadow, maybe?) that will also work for your needs. But it’s still a fun exercise. Feel free to play around with it and see what ideas you come up with.