Changing Z-Order in SVG

Hello everyone. I'm switching from a 'homemade' map of Germany to an SVG version. Everything works fine - the only problem: When hovering with the mouse, I change the color of the outlines. To ensure that this is clearly visible and not possibly obscured by other federal states, I change the Z-order in the SVG and bring the active state to the front. However, this results in the 'landlocked' states Bremen and Berlin being inaccessible, as they are located within the shapes of Brandenburg and Lower Saxony, respectively, and are effectively surrounded by them. I'd like to solve this problem without using additional Hype elements or the like - just within the code/SVG. You can find the corresponding function in dpa_initMap() in the mouseover event listener definition. Many thanks in advance! (87.1 KB)

Theoretical solutions…

Solution #1 β€” Don't use borders. Change the background color of the state. The borders might be easier to do with inner stroke, but that seems to be a problem with SVG shapes on the web…

Solution #2 β€” Double your graphic. On a second overlaying SVG image, that ignores mouse events, only borders could be displayed. (Downside: more HTML!)

Solution #3 β€” Tiered Z-order β€” The inner states could have an !important inline z-index value, like 100. Then, on mouse over, change the z-index to 50. The inner states merely laugh at the feeble attempt to change the z-index.

Hi, thanks a lot for your quick response.

  • #1 is not an option as the use of color and thickness changes of outlines is a requirement from our editorial team.
  • #2 I've thought about that as well, it would work but it's not very elegant... :wink:
  • #3 I don't understand that... :thinking: Could you explain it in more detail?

Best regards, Kalle

It's not very elegant code-wise, but would the viewer even notice?

This is not my preferred solution, but apparently you're hitting a problem with web design.

β€”β€”β€”β€”β€”β€”β€”β€”β€” Tiny "Landlocked" state β€”β€”β€”β€” z-index 100 !important
β€”β€”β€”β€”β€”β€” Selected State β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€” z-index 50
β€”β€”β€” Other States β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€” z-index 1

Since the center states don't block view of the larger states, those β€œlandlocked” state can always be on top…

style="z-index: 100;"

You might not even need… !important

Basically, you're having to change the z-index because the states overlap each other on the borders. However, those landlocked states are in the middle. They have no such overlap. They can be at a higher z-index all the time β€” yes / no? :thinking:

SVG elementscan have classes too. β€œpath” mentioned here… …so maybe using "landlocked" class is an alternative to inline styles.

Maybe all you need to do is add this after line 63

	    	function bringToTopofSVG(targetElement){
  				let parent = targetElement.ownerSVGElement;
			if (elmClass == "Berlin" || elmClass =="Bremen"){

credit : javascript - How to use z-index in svg elements? - Stack Overflow

Also maybe change

elm.setAttribute('stroke', strokeOverColor);


 if (elmClass == "Berlin") {
elm.setAttribute('stroke', "#76D6FF");
} else {
	elm.setAttribute('stroke', strokeOverColor);

Although on that last bit you could just simply change the stroke colour when mouse over to something not the same as the fill colour?

Above seems to work well,

But I noticed a lot of artefacts with the tooltip.

This on my M1 Mac, so I suspected that the the dpa_startTooltip() mouse move code and looked for an alternative to get your tooltip to follower the cursor.

This does it by replacing the cursor with the tooltip element.

The one thing about using a custom element it seems is the element scales down.
After a lot of trying in code it to get the scale back I finally managed to increase the size of the tooltip element and font size using the normal hype ways in the inspector. go figure?.

Also increased the padding in the css.

The newCursor() function runs on scene load.
The dpa_startTooltip() is not used.

This works really well and no artefacts and much crisper.

I got you left/right offset working also.
example with the changes.. (89.9 KB)

The new code for the tooltip/cursor

//Credit :

const cursorPointed = document.querySelector('.toolTip');

const moveCursor = (e)=> {
const mouseY = e.clientY;
const mouseX = e.clientX;
cursorPointedWidth  = cursorPointed.getBoundingClientRect();
cursorPointedWidth  = cursorPointedWidth.width;
cursorPointedHeight = cursorPointed.getBoundingClientRect();
cursorPointedHeight = cursorPointedHeight.height;

if (window.direction == 'li'){

	offX = (cursorPointedWidth)*-1.05;
	offY = (cursorPointedHeight)*-0.1;

} else {
	offX = (cursorPointedWidth)*0.05;
	offY = (cursorPointedHeight)*0.1;
} = `translate3d(${mouseX + offX}px, ${mouseY + offY }px, 0)`;

window.addEventListener('mousemove', moveCursor)
1 Like

Wow! That's really great. Thanks a million Mark for your help! Simply invaluable!! The map works like a charm now!

Maybe all you need to do is add this after line 63

ThatΒ΄s exactly, what I was looking for.

But I noticed a lot of artefacts with the tooltip.

Yes, that's an effect that apparently only occurs in Safari. I experienced something similar on the iPhone - in that case it happened when symbols were moved that contained elements with shadows. I was able to fix this by adjusting the bounding-box of the symbol which was apparently to small...

The newCursor() function runs on scene load.
The dpa_startTooltip() is not used

And - wow! again!! That's a really clear, well-organized code. I've always struggled with the MouseOver...

Here you can see the preliminary version, including the mobile variant.

1 Like