I have a page that's divided into 3 sections. A top bar with several buttons, a large middle section and a bottom bar with more buttons. And on top of everything several floating windows that will open and close depending on the buttons clicked (ignorable for this problem).
The requested structure is the middle section must be an empty div that will load several other pages through jquery. Some of those pages have interactive elements, so it must accept mouse events, despite the div having the lowest z-index of all the page elements.
The buttons on the top and bottom bars must all be svg elements, both because of the vectorial properties and the occasional odd shapes. And they must have a higher z-index than the middle div at all times.
My problem is the svg is covering the middle div and blocking all interactions (in this case a simple alert when you click on the div), although none of the visual elements overlap.
I've tried to call 2 different svgs, one for each bar, but the 2nd never shows up. I've also tried calling the 2 svgs inside a main svg and include the div inside as well, but it didn't work too.
This is an example of how it currently looks (the absolute positions, z-indexes and styles are defined in a css):
<div id="middleDiv" class="middleDiv" onClick="alert(1)">< /div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<svg id="topBar" class="topBar" x="0" y="0">
<rect id="btn_1" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_2" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
<svg id="bottomBar" class="bottomBar" x="0" y="500">
<rect id="btn_3" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_4" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
</svg>
This was the 1st solution attempt:
<div id="middleDiv" class="middleDiv" onClick="alert(1)">< /div>
<svg id="topBar" class="topBar" x="0" y="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect id="btn_1" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_2" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
<svg id="bottomBar" class="bottomBar" x="0" y="500" xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect id="btn_1" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_2" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
And this was the 2nd solution attempt:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<svg id="topBar" class="topBar" x="0" y="0">
<rect id="btn_1" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_2" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
<div id="middleDiv" class="middleDiv" onClick="alert(1)">< /div>
<svg id="bottomBar" class="bottomBar" x="0" y="500">
<rect id="btn_3" class="topBtn" x="0" y="0" height="30" width="100"/>
<rect id="btn_4" class="topBtn" x="100" y="0" height="30" width="100"/>
</svg>
</svg>
Firstly you should specify width and height attributes for the <svg> elements. If you're using Chrome it incorrectly makes them the size of the page if you omit such attributes and this may be your entire issue.
If that doesn't work then add pointer-events="none" to prevent the <svg> elements intercepting mouse clicks.
Related
So I've created a page with some colorful SVG images in it, and I want them to be grayed at hormal state, and shows color while hovered.
svg {
width: 200px;
margin: 50px;
}
svg * {
transition: fill 1s;
}
svg:not(:hover) * {
fill: gray !important;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 1">
<rect x="0" y="0" width="1" height="1" style="fill: red" />
<rect x="1" y="0" width="1" height="1" style="fill: green" />
<rect x="2" y="0" width="1" height="1" style="fill: blue" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 1">
<g>
<rect x="0" y="0" width="1" height="1" style="fill: red" />
<rect x="1" y="0" width="1" height="1" style="fill: green" />
<rect x="2" y="0" width="1" height="1" style="fill: blue" />
</g>
</svg>
As one can see, SVGs have different colored elements, also some elements are grouped. This is pretty simplified example, but the real images are much more complex, with massive transform-s so I can't easily remove grouping.
Both images work perfect and changes colors while hovered, but the first image does it instantly while the the second has 1 second delay before animation starts.
Searching for the solution I've found that if an elemend is wrapped with a single <g> tag it has the animation delay, but if there no <g> or two of them, no delay occurs.
Firefox animates both images with no animation delay.
By the moment I ungrouped elements by hands, but obviously it's not a good solution, so the question is how it can be solved without changing files at all ?
A pretty sneaky bug, but easily solved: just restrict the child selector to non-g elements:
svg {
width: 200px;
margin: 50px;
}
svg :not(g) {
transition: fill 1s;
}
svg:not(:hover) * {
fill: gray !important;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 1">
<rect x="0" y="0" width="1" height="1" style="fill: red" />
<rect x="1" y="0" width="1" height="1" style="fill: green" />
<rect x="2" y="0" width="1" height="1" style="fill: blue" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 1">
<g>
<rect x="0" y="0" width="1" height="1" style="fill: red" />
<rect x="1" y="0" width="1" height="1" style="fill: green" />
<rect x="2" y="0" width="1" height="1" style="fill: blue" />
</g>
</svg>
I have an SVG with nested SVGs inside of it that are wrapped inside various <a> tags. I would like the entire nested SVG to activate the link (i.e. be clickable), but it seems I cannot use the CSS property pointer-events: bounding-box as that value isn't supported by Safari & Firefox. (This works great in Chrome, however).
What other approach could I use to simulate this behavior in these browsers?
Cover each SVG with a transparent <rect> and wrap that with the link element.
<svg width="300" height="200">
<a xlink:href="http://www.google.com">
<svg x="50" y="50" width="200" height="100">
<ellipse cx="100" cy="50" rx="100" ry="50" fill="red"/>
</svg>
</a>
</svg>
<svg width="300" height="200">
<svg x="50" y="50" width="200" height="100">
<ellipse cx="100" cy="50" rx="100" ry="50" fill="green"/>
</svg>
<a xlink:href="http://www.google.com">
<rect x="50" y="50" width="200" height="100" fill="transparent"/>
</a>
</svg>
I have an svg rect chart like:
<div style="width:300px;height:300px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width:100%;height:100%" viewBox="0 0 300 300">
<g>
<rect width="14.55" height="40%" x="0" y="0" fill="black"></rect>
<rect width="14.55" height="20%" x="50" y="0" fill="green"></rect>
<rect width="14.55" height="80%" x="100" y="0" fill="red"></rect>
<rect width="14.55" height="90%" x="150" y="0" fill="yellow"></rect>
<rect width="14.55" height="10%" x="200" y="0" fill="pink"></rect>
<rect width="14.55" height="60%" x="250" y="0" fill="orange"></rect>
</g>
</svg>
</div>
What I want to do is to display it upside down.
The code and a given solution, are coming from http://jsfiddle.net/rhvP8/5/
Although, I want to keep each bar in the same X place. So, rotation approach is not that useful in this case.
Any help is welcome.
Rotation of the x-axis only seems be be what you require.
svg {
border: 1px solid green;
transform: rotateX(180deg);
}
<div style="width:300px;height:300px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width:100%;height:100%" viewBox="0 0 300 300">
<g>
<rect width="14.55" height="40%" x="0" y="0" fill="black"></rect>
<rect width="14.55" height="20%" x="50" y="0" fill="green"></rect>
<rect width="14.55" height="80%" x="100" y="0" fill="red"></rect>
<rect width="14.55" height="90%" x="150" y="0" fill="yellow"></rect>
<rect width="14.55" height="10%" x="200" y="0" fill="pink"></rect>
<rect width="14.55" height="60%" x="250" y="0" fill="orange"></rect>
</g>
</svg>
</div>
<clipPath id="clip1">
<rect x="10" y="222" height="30" width="50" rx="5" />
</clipPath>
<image .... clip-path="url(#clip1)" />
It cuts the outer space of the image. But I want to cut a hole into the image. How can I achieve it?
For your purposes, you can use a mask
<svg width="200" height="200" viewBox="0 0 200 200">
<defs>
<mask id="hole">
<rect width="100%" height="100%" fill="white"/>
<rect x="50" y="50" height="50" width="100" rx="5" fill="black" />
</mask>
</defs>
<image x="0" y="0" width="200" height="200"
xlink:href="http://placeimg.com/200/200/any"
mask="url(#hole)" >
</image>
</svg>
My SVG pattern Shown below
<pattern id="img1" patternUnits="userSpaceOnUse" width="10" height="10">
<image xlink:href="Buzz.jpg" x="0" y="0" width="10" height="10" />
</pattern>
<pattern id="img2" patternUnits="userSpaceOnUse" width="10" height="10">
<image xlink:href="Tank-icon2.png" x="0" y="0" width="10" height="10" />
</pattern>
Now, I want to change xlink:href="Buzz.jpg" to xlink:href="Buzz2.jpg". Can I just do it by CSS?
No, you cannot use CSS to change HTML tag attributes.