Fill opacity of SVG object nested in transparent div - css

I have a div that has the opacity set to 0.6 to make it a little transparent. Nested in this div, I'm adding lines and shapes using SVG that I want to be opaque. The fiddle shows a simple example:
JSFiddle:
The green circle in the div with the red background is inheriting the opacity of the div with the red background. The green circle below the red div shows it without any transparency - which is how I want to look on the red background.
<div style="width: 160px;height: 140px;background-color: red;opacity: 0.6;">
<svg width="160" height="140">
<circle cx="40" cy="40" r="15" fill="green" fill-opacity="1"> </circle>
</svg>
</div>
<svg width="160" height="140">
<circle cx="40" cy="40" r="15" fill="green" fill-opacity="1"> </circle>
</svg>
How can I make the green circle nested in the red div opaque?

You should use rgba(255,0,0,0.6) colors instead to set only background opacity.
The behavior you experiment is normal, opacity applies all the way through the element , childs & text included .
http://jsfiddle.net/vLV5h/7/

The 0.6 opacity applies to the whole of the div (including it's contents). There is no way for a child element to override the opacity of it's parent.
Your only choice is to move the red background into the SVG.
<div style="width: 160px;height: 140px;">
<svg width="160" height="140">
<rect width="100%" height="100%" fill="red" opacity="0.6"/>
<circle cx="40" cy="40" r="15" fill="green" fill-opacity="1"> </circle>
</svg>
</div>
<svg width="160" height="140">
<circle cx="40" cy="40" r="15" fill="green" fill-opacity="1"> </circle>
</svg>
Demo here

Related

How do I make svg path hover area bigger

What I have:
#poly-1:hover {
stroke: green;
}
<svg width="1000" height="500" id="chart-main-canvas" style="background-color: bisque; z-index:5000;">
<path id="poly-1" d="M 5,10 C 24,88 60.99999999999998,322 100,400 C 139,478 149,470 200,400 C 251,330 295,30.000000000000007 355,50 C 415,70 470.99999999999994,410 500,500" fill="none" stroke="red" style="z-index:6000;"></path>
</svg>
If I hover exactly on path, which is a tricky task, line it will change color to green.
What I want to do is to make hover area of this path bigger, so I could move my cursor somewhere +-5px near the path area and it will still change color.
The only two ways I know I could do is:
Make stroke-width bigger, but I don't want its actual size with red color to increade.
With my main path create invisible duplicating path that has bigger stroke-width and add condition that if I hover on it - my main path will change color.
But there is any simple way to do it?
This answer is practically your second option.
I'm putting the path #poly-1 in the defs and use it first with a wide stroke-width and no stroke. In order to make it sensitive to the mouse I'm using pointer-events="stroke"
<use xlink:href="#poly-1" stroke-width="10" pointer-events="stroke"/>
Next comes another use - the visible one - with a red stroke.
I'm putting both use elements in a group. The stroke of the second use element changes when I'm mousing over the group.
#group .use {
stroke: red
}
#group:hover .use {
stroke: green;
}
<svg width="1000" height="500" id="chart-main-canvas" style="background-color: bisque; z-index:5000;">
<defs>
<path id="poly-1" d="M 5,10 C 24,88 61,322 100,400 C 139,478 149,470 200,400 C 251,330 295,30 355,50 C 415,70 471,410 500,500" fill="none" >
</path>
</defs>
<g id="group">
<use xlink:href="#poly-1" stroke-width="10" pointer-events="stroke"/>
<use class="use" xlink:href="#poly-1" />
</g>
</svg>
I added stroke width for color change to highlight.
please try this..
#poly-1:hover {
stroke: green !important;
stroke-width:2px;
}
<svg width="1000" height="500" id="chart-main-canvas" style="background-color: bisque; z-index:5000;">
<path id="poly-1" d="M 5,10 C 24,88 60.99999999999998,322 100,400 C 139,478 149,470 200,400 C 251,330 295,30.000000000000007 355,50 C 415,70 470.99999999999994,410 500,500" fill="none" stroke="red" style="z-index:6000;"></path>
</svg>

Rotate svg text around central text position using css

I want to apply a single css rotation transformation to a set of elements in an SVG, such that each element is rotated independently, without having to calculate the centre of each element in the css. For example, I have an SVG that looks like the picture on the left, and want to apply css to achieve the effect on the right
I'm writing the svg myself, and am creating something like this
<svg baseProfile="full" height="200" version="1.1" width="200" xmlns="http://www.w3.org/2000/svg">
<text transform="translate(50 100)" text-anchor="middle">Text 1</text>
<text transform="translate(100 100)" text-anchor="middle">Text 2</text>
</svg>
When I apply a css rotation, e.g. by inserting <style>text {transform: rotate(10deg)}</style>, it seems to overwrite the first transformation, and the rotated text is placed in the top left corner:
I can modify the svg to use `x="X" y="Y" instead of a transform attribute, but that results in the transformation being applied around a different centre instead:
<svg baseProfile="full" height="200" version="1.1" width="200" xmlns="http://www.w3.org/2000/svg">
<style>text {transform: rotate(10deg)}</style>
<text x="50" y="100" text-anchor="middle">Text 1</text>
<text x="100" y="100" text-anchor="middle">Text 2</text>
</svg>
How can I structure the svg so that I can apply a rotation which works independently on each element without overwriting the initial transform?
This is a possible solution:
-The text has x="0" y="0" and is rotated with CSS.
-You put the text in the <defs>.
-You use the text and the <use> element has the x and y values you need.
text{transform:rotate(90deg)}
<svg baseProfile="full" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<text id="a" text-anchor="middle" >Text 1</text>
<text id="b" text-anchor="middle" >Text 2</text>
</defs>
<use xlink:href="#a" x="50" y="50" />
<use xlink:href="#b" x="100" y="50" />
</svg>
Yet another solution (inspired by the comment of Robert Longson) would wrapping the rotated text in a g element and translate the g
text{transform:rotate(90deg)}
<svg baseProfile="full" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(50,50)"><text text-anchor="middle" >Text 1</text></g>
<g transform="translate(100,50)"><text text-anchor="middle" >Text 2</text></g>
</svg>

Image clip to text

How can I clip an image to text? I would prefer a method that is available in any browser. I tried background-clip but it not available in all modern browsers.
Add a clip-path to an image and you'll see a clipped image.
I've made it look more like your example by adding an additional copy of the image with low opacity behind the clipped image.
<svg width="100%" height="100%">
<defs>
<clipPath id="sample" clipPathUnits="userSpaceOnUse">
<text x="85" y="330" font-family="sans-serif" font-size="380" font-weight="bold">I CAM</text>
</clipPath>
</defs>
<image transform="scale(0.4)" xlink:href="http://netghost.narod.ru/gff/sample/images/png/marble24.png" x="20" y="20" width="1419" height="1001" opacity="0.3" />
<image transform="scale(0.4)" xlink:href="http://netghost.narod.ru/gff/sample/images/png/marble24.png" x="20" y="20" width="1419" height="1001" clip-path="url(#sample)" />
</svg>

Is it possible to use a background image on the stroke of an SVG element?

Just as the question asks - I'm trying to figure out whether or not it's possible to use some kind of pattern or repeated background image for the stroke of an SVG path.
Is this doable? Or are you limited to colors only?
TIA!
You can use a <pattern> as a stroke e.g.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="p1" patternUnits="userSpaceOnUse" width="32" height="32">
<image xlink:href="http://phrogz.net/tmp/alphaball-small.png" width="32" height="32" />
</pattern>
</defs>
<rect stroke-width="32" stroke="url(#p1)" width="200" height="200" fill="none"/>
</svg>
The pattern can contain <svg> drawing elements or (as here) an image, or both.
You can use the property stroke-dasharray for "patterns" in the stroke:
<line stroke-dasharray="5, 5" x1="10" y1="10" x2="190" y2="10" />
With this you can specify the length of strokes and gaps between. For some examples have a look at the MDN example page.

Text on a rectangle kills the rectangle's hover effect

I have several svg rectangles with an hover effect, the background-color of the rectangles gets changed when the mouse is over them. The hover effect is set via css:
.myclass:hover {
fill: rgb(255,128,0);
}
Apart from that, text is placed above each of the rectangles. A pair of text and rectangle define a group.
<g>
<rect class="myclass" x="10" y="10" width="40" height="40" />
<text x="30" y="40" font-family="Verdana" font-size="10" fill="blue">ESC</text>
</g>
The hover effect works fine, but only if the cursor is not exactly above the text. If it is exactly above the text, then the hover effect vanishes.
How could I fix that?
Here a screenshot: on the left you can see the hover effect (background is orange), on the right you can see how the effect vanishes if the cursor hits the text on the rectangle:
Thank you
You need to make the text have pointer-events="none" so that it's ignored by the hover.
<g>
<rect class="myclass" x="10" y="10" width="40" height="40" />
<text x="30" y="40" font-family="Verdana" font-size="10" fill="blue" pointer-events="none">ESC</text>
</g>
The problem is the hover is assigned to element that sits behind the text. So when you're hovering over the text, you're technically NOT touching the background anymore.
My suggestion would be to apply the class to the parent element, and assign the hover to that.
<g class="myclass">
<rect x="10" y="10" width="40" height="40" />
<text x="30" y="40" font-family="Verdana" font-size="10" fill="blue">ESC</text>
</g>
Now your CSS would look like this, to target the child "rect" element:
.myclass:hover rect {
fill: rgb(255,128,0);
}

Resources