0

So I have a map composed by tiles that are svg elements. tiles

In the image, the tile itself is the blue area, but it has a buffer area to allow geometries that span outside the tile to render whole. The problem is that this buffer area (in green), is covering the geometries from other tiles that are below it. This buffer zone is set in CSS as the following:

padding: 128px;
margin: -128px;

Is there a way to hover/click "through" the buffer area, or is there a better approach in CSS to achieve this?

fdansv
  • 87
  • 2
  • 8
  • Can you explain the orange buffer part, seems I cant see it, do you mean on orange circles? – Zlatko Vujicic Jan 08 '16 at 14:41
  • Generally there is not, if one element ovelaps the other, you won't reach the one underneath. Which elements are you trying to reach? And is the orange zone you mentioned the padding? Or what are you talking about? – Clemens Himmer Jan 08 '16 at 14:45
  • @ZlatkoVujicic Sorry, it must be because my brain mixed it with the rest of the colours, I meant the green area around the tile :) – fdansv Jan 08 '16 at 14:46
  • Ok and what is actually inside of that blue span you are talking about. DevTools colors are blue element, green padding, orange margin :D cheers – Zlatko Vujicic Jan 08 '16 at 14:59
  • @ZlatkoVujicic I need to get hover and click events for the circles that are within the padding area, but that belong to different tiles. – fdansv Jan 08 '16 at 15:05
  • You can't make tiles of a size of a circle? Or similar approach. Do you have link so we can inspect it, this is somehow strange to answer – Zlatko Vujicic Jan 08 '16 at 15:14
  • Just add a block level child element that covers the entirety of the tile contents excluding padding (i.e. position: static with 100% width and height) and have it handle your hover/click event. – Joseph Marikle Jan 08 '16 at 15:31

3 Answers3

0

Padding is part of a element, therefore will react like it was content of your tag.

See here. If you absolutely need to have that spacing to be padding, you can't click anything behind neither content nor padding.

You might consider changing your layering, using z-index, but for further advise on this, you'll have to provide further code, your HTML Markup and CSS code.

Community
  • 1
  • 1
Clemens Himmer
  • 1,340
  • 2
  • 13
  • 26
0

If that blue thingy is the only element that needs this treatment, then I suggest creating a key bind to move that element to the back with z-index, and be done with it.

If you require this functionality on all of these red balls, the thing to do would probably be to move, the one you click on, to the back with z-index ( again ).

Both of these require you to use JavaScript most likely, unless you want to move that big blue element to the back on hover.

To always move the clicked element to the back you could just keep track of what was the last assigned z-index, and decrease it by one every time you assign it to a new object.

Something like this would probably do:

#box1 { position: absolute; background-color: #123; width: 100px; height: 100px; top: 200px; left: 300px; opacity: 0.9; }
#box2 { position: absolute; background-color: #ABC; width: 100px; height: 100px; top: 250px; left: 350px; opacity: 0.8; }

<div class="box" id="box1"></div>
<div class="box" id="box2"></div>

<script type="text/javascript">
var boxes = document.getElementsByClassName("box");

var length = boxes.length;

var index = 0;

function moveToBack(event)
{
    var element = this;

    this.style.zIndex = index;
    index--;

    return false;
}

for(var i = 0; i < length; i++)
{
    var box = boxes[i];

    box.addEventListener("click", moveToBack, false);
}
</scirpt>

Does that do the job ? or did you mean something else entirely ?

0

Only way I can seem to get it to work is to add a child inner element and give pointer-events:none to the wrapper and pointer-events:auto to the inner child element. It's not ideal as support for pointer-events is limited and there's no telling if all browsers will respect a child of pointer-events:none element having a different value than its parent. It will need tested. Well, in any case, here is the code:

$('.tile').on('mouseenter', function(){
  $('.info', this).find('.tile-info').remove();
  var ts = new Date().getTime();
  $('.info', this).append('<div class="tile-info">mouseenter tile '+ts+'</div>');
});
$('.tile').on('mouseleave', function(){
  $('.info', this).find('.tile-info').remove();
  var ts = new Date().getTime();
  $('.info', this).append('<div class="tile-info">mouseleave tile '+ts+'</div>');
});

$('.inner').on('mouseenter', function(){
  $('.info', this).find('.inner-info').remove();
  var ts = new Date().getTime();
  $('.info', this).append('<div class="inner-info">mouseenter inner '+ts+'</div>');
});
$('.inner').on('mouseleave', function(){
  $('.info', this).find('.inner-info').remove();
  var ts = new Date().getTime();
  $('.info', this).append('<div class="inner-info">mouseleave inner '+ts+'</div>');
});
.tile {
  width: 200px;
  height: 200px;
  background: rgba(100,100,200,0.2);
  padding: 50px;
  margin: -50px;
  position: absolute;
  pointer-events:none;
}

.tile:nth-of-type(1) {left: 300px;top: 20px;}
.tile:nth-of-type(2) {left: 90px;top: 210px;}
.tile:nth-of-type(3) {left: 0px;top: 0px;}
.tile:nth-of-type(4) {left: 360px;top: 240px;}

.tile .inner {
  width: 100%;
  height: 100%;
  background: rgba(200,100,100,0.2);
  pointer-events:auto;
  overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tile">
  <div class="inner">
    <div class="info"></div>
  </div>
</div>
<div class="tile">
  <div class="inner">
    <div class="info"></div>
  </div>
</div>
<div class="tile">
  <div class="inner">
    <div class="info"></div>
  </div>
</div>
<div class="tile">
  <div class="inner">
    <div class="info"></div>
  </div>
</div>
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129