Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: conditional formatting based on class of adjacent elements

Tags:

css

I have a few adjacent span tags that are styled to be display: inline-block; like so:

span.mark {
  background-color: yellow;
  display: inline-block;
  vertical-align: center;
  border-width: 1px;
  border-color: red;
  border-style: solid;
  border-radius: 3px;
}
<p>Some <span class="mark">standalone</span> test. Some <span class="mark">continuous </span><span class="mark">elements </span><span class="mark">that</span> should be formatted together.</p>

<p>Some <span class="mark">normal </span><b><span class="mark">and strong</span></b> text that should be formatted together.</p>

So currently these span tags all get their own little borders. However, I want them to look like there's just one border around them all together. So, technicall, the outer ones should have border-width-left: 1px; for the first one and border-width-right: 1px; for the last one and the ones in the middle should have border-width: 1px 0px;.

Is there a way to do this in CSS? Basically the rule should be: "If this is a span with a mark class and the elements before and after me are spans with a mark class then apply middle element styling. If this is a span with a mark class and the element before me is not a element with a mark style and the element after me is a span element with a mark style, apply left element styling. Etc..."

I know there is span.mark:before and span.mark:after, but I don't actually want to style the element before or after the current one. I want to style the current one best on what comes before and after it. Also, I need to check for the class of the :before and :after elements.

edit: Maybe my example was too simplistic. There will be more than one string of <span> tags in a given <p>. The whole :first-of-type :last-of-type is looking very promising, I didn't know about those. I'm afraid the solution will be more complicated though, if it works at all...

like image 740
MadMonkey Avatar asked Nov 07 '22 12:11

MadMonkey


1 Answers

With the support of pseudo-elements and a combination of absolute positioning and stacking context the intended behaviour can be achieved.

The snippet embedded below demonstrates how every preceding element's pseudo-element is stacked below the following element; conveying the impression of seamless continuity while still maintaining the visual impression of a full border for stand-alone elements.

Code Snippet Demonstration:

span.mark {
    background-color: yellow;
    display: inline-block;
    border-width: 1px;
    border-color: red;
    border-style: solid;
    padding: 0px 2px;
    border-right: 0px;
    border-left: 0px;
    position: relative;
}

span.mark:after,
span.mark:before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: -1;
    /* for border-radius */
    border-radius: 3px;
    background: yellow;
    width: 5px;
    border-top: 1px solid red;
    border-bottom: 1px solid red;
}

span.mark:after {
    border-right: 1px solid red;
    right: -2px;
}

span.mark:before {
    border-left: 1px solid red;
    left: -2px;
}
<p>Some <span class="mark">standalone</span> test. Some <span class="mark">continuous </span><span class="mark">elements </span><span class="mark">that</span> should be formatted together.</p>

<p>Some <span class="mark">normal </span><b><span class="mark">and strong</span></b> text that should be formatted together.</p>
like image 174
UncaughtTypeError Avatar answered Dec 17 '22 22:12

UncaughtTypeError