Eaten by a Grue
Eaten by a Grue

Reputation: 22931

Create visual borders between elements on the same line

I'd like the have a visual border, pipe or some other separator between the <span> elements in the following snippet. The trouble is that when they flow into a new line I end up with a border at the beginning of the line. How can i apply some kind of border between elements only when they are on the same line? I am completely open to changing the markup or taking another approach, however I've tried a number of things from flexbox to floats so far without success.

Stipulations:

Is this even possible? I've already looked at this similar question but the answers there either use js or media queries.

The snippet below is a basic example and I've put the spans in a resizeable div only to demonstrate the flow problem at smaller widths.

.resizable {
  resize: horizontal;
  overflow: scroll;
  border: 1px solid black;
  height: 95vh;
  box-sizing: border-box;
  min-width: 120px;
  max-width: 100%;
  padding: 10px;
}

span {
  font-size: 18px;
  font-family: sans-serif;
}

span+span {
  margin-left: 10px;
  border-left: 2px solid #aaa;
  padding-left: 10px;
  display: inline-block;
}
<div class="resizable">
  <span>dog</span><span>cat</span><span>elephant</span><span>potato</span><span>boston clam chowder</span>
</div>

Upvotes: 3

Views: 592

Answers (2)

mdsimmo
mdsimmo

Reputation: 619

Here's a pure CSS method that also works for elements that are centered.

The ::before and ::after of adjacent tiles are used to create a dark strip between the elements, then, the ::before of the container clips the lighter stuff out of existence.

Downsides - Getting the perfect color can be tricky as there's lots of maths involved.

section {
  text-align: center;
  position: relative;
}

section::before {
  
  /* Clip light areas to pure white, leaving only boarders*/
  mix-blend-mode: color-dodge;
  background: #bbb;
  z-index: -1000;
  
  /* Fill Parent */
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  content: "";
}

span {
  position: relative;
  display: inline-block;
  
  box-sizing: border-box;
  padding: 10px;
}

/* Spans slightly overlap creating darker lines between elements*/
span::before {
  left: -1px;
}
span::after {
  right: -1px;
}
span::before, span::after {
  position: absolute;
  content: "";
  display: block;
  width: 10px;
  height: 100%;
  background: #555;
  top: 0;
  z-index: -1001;
  mix-blend-mode: multiply;
}
<section>
  <span>Hello</span><span>Cats</span><span>Fish</span><span>Dogs</span><span>Hello</span><span>Cats</span><span>Fish</span><span>Dogs</span><span>Hello</span><span>Cats</span><span>Fish</span><span>Dogs</span>
</section>

For some reason, this code does not work in Stackoverflow's JSFiddle. Here's a link to JSFiddle where it does work:

https://jsfiddle.net/mdsimmo/vwu7xbjp/2/

Upvotes: 0

C3roe
C3roe

Reputation: 96226

You can fix this by using a container with the overflow hidden, and a negative margin to “drag” the elements at the beginning of the line outside of that overflow area.

(In this particular example the overflow:hidden is not really necessary, the outer scrolling element already takes care of that, but in different scenarios it might be needed.)

The 1.5em value used here is a bit of a magic number; you might want to replace it with a pixel value, since you’re using pixels for the border and its spacing from the text already - but in general, you should be able to find “working” values with a little bit of experimentation.

.resizable {
  resize: horizontal;
  overflow: scroll;
  border: 1px solid black;
  height: 95vh;
  box-sizing: border-box;
  min-width: 120px;
  max-width: 100%;
  padding: 10px;
}
.container {
  margin-left: -1.5em;
  width: calc(100% + 1.5em);
}
span {
  font-size: 18px;
  font-family: sans-serif;
  margin-left: 10px;
  border-left: 2px solid #aaa;
  padding-left: 10px;
  display: inline-block;
}
<div class="resizable">
  <div class="container">
  <span>dog</span><span>cat</span><span>elephant</span><span>potato</span><span>boston clam chowder</span><span>dog</span><span>cat</span><span>elephant</span><span>potato</span><span>boston clam chowder</span><span>dog</span><span>cat</span><span>elephant</span><span>potato</span><span>boston clam chowder</span>
  </div>
</div>

Upvotes: 5

Related Questions