Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore margin for pseudo-elements :before or :after

Tags:

I am trying to mark borders for the given set of general HTML elements (their CSS is not under my control) in a way that the borders are visible, and they are highlighted on hover.

I am currently using pseudo-elements :before and :after to achieve this, but I am struggling with the margins. I need to use CSS for that, not JS.

The desired behavior is to only have a single line between any two elements, but because of the margins, the borders are duplicated between paragraph "Some content" and heading "World".

I am able to apply marker classes either to wrapping divs or directly to class elements as shown in the below snippet, both is OK for me.

.mark-borders:before,
.mark-borders:after
{
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  display: block;
  height: 1px;
  border-bottom: dashed 1px #ccc;
}

.mark-borders:hover:before,
.mark-borders:hover:after
{
  border-bottom: solid 1px red;
  z-index: 1;
}
<div class="mark-borders">
  <h1>
    Hello
  </h1>
</div>
<div class="mark-borders">
  <p>
   Some content
  </p>
</div>
<div class="mark-borders">
  <h1>
    World
  </h1>
</div>
<br />
<hr />
<div class="mark-borders">
  <h1>
    Hello
  </h1>
</div>
<p class="mark-borders">
 Some content
</p>
<h1 class="mark-borders">
  World
</h1>

Is there some way how to "merge" the borders between to a single one while preserving the hover highlight effect without using JS to place the border lines?

I have tried using :after for all, and :before only for the very first element, but in that case I am either loosing the hover effect for the top border, or it displays in wrong location (same problem as with original borders).


UPDATE:

I was able to put together almost working solution with the following concept:

  • Each element displays its :before border
  • The last element displays also its :after border
  • hover activates :before border of current element and :before border of its next sibling

But ... even that it works better than original, the "margin" area is dead, not responding to :hover, any ideas how it could be fixed?

Updated code:

.mark-borders:before,
.mark-borders:last-child:after
{
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  display: block;
  height: 1px;
  border-bottom: dashed 1px #ccc;
}

.mark-borders:hover:before,
.mark-borders:hover:last-child:after,
.mark-borders:hover + *:before
{
  border-bottom: solid 1px red;
  z-index: 1;
}
<div>
  <div class="mark-borders">
    <h1>
      Hello
    </h1>
  </div>
  <div class="mark-borders">
    <p>
      Some content
    </p>
  </div>
  <div class="mark-borders">
    <h1>
      World
    </h1>
  </div>
</div>
like image 585
martinh_kentico Avatar asked Nov 02 '16 00:11

martinh_kentico


1 Answers

Ive edited your code and came up with this: https://jsfiddle.net/7g31c5rp/4/

.mark-borders:nth-of-type(2):after,
  p.mark-borders:after{
  display: none;
}
.mark-borders:hover + .mark-borders:before{
   border-bottom: solid 1px red;
   z-index: 1;
}

removing the some-content after and targeting the WORLD before on hover.

like image 187
Ron.Basco Avatar answered Sep 26 '22 16:09

Ron.Basco