Anthony Martin
Anthony Martin

Reputation: 678

Selectively hide background elements when overlayed with transparent div

I've got some transparent elements and some translucent elements on a patterned background.

I want to be able to pick a certain transparent element, and hide one of the translucent elements where the two intersect. Ie so you would end up with something like:

    ==========   ===========   ===========   ===========
    |        |   |         |   |         |   |         |
----|--------|---|         |---|---------|---|---------|---
----|--------|---|---------|---|---------|---|---------|---
    |        |   |         |   |         |   |         |
    ==========   ===========   ===========   ===========

I've put an example codepen below. I'd like to be able to hide the line with class "random-line" (and not hide the line with class "other-random-line"!) behind the div titled "Object 2". Does anyone have any ideas on how I could go about doing this, or whether it is even at all possible?

http://codepen.io/anon/pen/GgzeGP

Thanks!

Upvotes: 2

Views: 2876

Answers (2)

EdenSource
EdenSource

Reputation: 3387

Since you didn't ask to avoid JS/jQuery solution, here is a way to do (that can be refined for a better result).


1 - I've created a mask that contains your duplicated background:

HTML

<div class="maskContainer">
    <div class="mask">
    <div class="background"></div>
    </div>
</div>

CSS

.background {
    position: absolute;
    display: inline-block;
    background: repeating-linear-gradient(
      45deg,
      rgba(0, 0, 0, 0.2),
      rgba(0, 0, 0, 0.2) 10px,
      rgba(0, 0, 0, 0.3) 10px,
      rgba(0, 0, 0, 0.3) 20px
    );
    top:0px;
}
.maskContainer{
    z-index: 2;
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
 }
 .mask{
    position:relative;
    top:200px;
    overflow:hidden;
    padding: 2em;
    border: 1px solid #afa;
    margin: 0 1em;
 }

JS

var containerWidth = $(".container").width();
var containerHeight = $(".container").height();

$(".background").css({
  'width':containerWidth+'px',
  'height':containerHeight+'px',
});

2 - This mask gets the size and position of your desired object with jquery (and some other stuffs to deal with your object padding/margin):

JS

var selectedObjWidth = $(".object.selected").width();
var selectedObjHeight = $(".object.selected").height();
var selectedObjPosX = $(".object.selected").position().left;
var selectedObjPosY = $(".object.selected").position().top;

$(".mask").css({
  'width':selectedObjWidth+'px',
  'height':selectedObjHeight+'px',
  'left':selectedObjPosX+'px',
  'top':selectedObjPosY+'px'
});


var maskMargin = $(".mask").css("margin-left");
maskMargin = maskMargin.split("px");
var realMaskMargin = maskMargin[0];

var maskPosX = $(".mask").position().left+parseInt(realMaskMargin)+1;

$(".background").css({
  'left':'-'+maskPosX+'px'
});

Summary:

The mask takes the position of your Object, hides it with a duplicate of your container background (which is translated left to keep the same position as your original background).

E.G:

  • Object is 150px left

  • Mask is 150px left too

  • Background is also 150px left because it is within the mask, and I want it to be aligned with the main container, so I ask it to be -150px left. This way, the mask try to reproduce your original background, overriding it.

  • We can now play with z-index to hide/show specific random-line


Here is your updated Codepen

Upvotes: 4

vals
vals

Reputation: 64174

You can get working (to some extent) on most modern browsers, except IE.

The trick is not to use transparency, but blending. When you set a blend mode of hard-light, color gray in the overlay results as transparent.

In the following demo, it's just the z-index of the test3 elements that makes the difference.

.test1 {
	width: 200px;
	height: 200px;
	border: solid 1px black;
	background-image: repeating-linear-gradient(45deg, white 0px, lightblue 40px);
	background-color: white;
}

.base {
	position: absolute;
	z-index: 1;
	mix-blend-mode: hard-light;
}

.test2 {
	width: 200px;
	height: 100px;
	top: 50px;
	border: solid 1px red;	
	position: absolute;
	background-color: gray;
	z-index: 10;
}

.test3 {
	width: 40px;
	height: 200px;
	top: 0px;
	border: solid 1px blue;	
	position: absolute;
	mix-blend-mode: hard-light;
	background-color: rgba(255,0,0,0.5);
}

#test31 {
	left: 50px;
	z-index: 15;
}
#test32 {
	left: 120px;
	z-index: 5;
}
<div class="test1">
	<div class="base">
		<div class="test2">
		</div>
		<div class="test3" id="test31">
		</div>
		<div class="test3" id="test32">
		</div>
	</div>
</div>

Upvotes: 2

Related Questions