This question already has answers here:
Understanding CSS selector priority / specificity
(4 answers)
Closed 3 years ago.
https://jsfiddle.net/dr1vfymn/
I have an svg element with two boxes and I'm trying to change the fill color of one when the mouse hovers over it:
#room1:hover {
fill: #ffcccb;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<rect id="room1" x="0.5" y="0.5" width="93" height="99" style="fill:#fff"/>
<path d="M128,44v98H36V44h92m1-1H35V143h94V43Z" transform="translate(-35 -43)"/>
<rect id="room2" x="93.5" y="0.5" width="56" height="99" style="fill:#fff"/>
<path d="M184,44v98H129V44h55m1-1H128V143h57V43Z" transform="translate(-35 -43)"/>
</svg>
However it is not working at all. What could be the reason?
Because your inline CSS is overriding it. One way to overcome that is to use !important
#room1:hover {
fill: #ffcccb !important;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<rect id="room1" x="0.5" y="0.5" width="93" height="99" style="fill:#fff"/>
<path d="M128,44v98H36V44h92m1-1H35V143h94V43Z" transform="translate(-35 -43)"/>
<rect id="room2" x="93.5" y="0.5" width="56" height="99" style="fill:#fff"/>
<path d="M184,44v98H129V44h55m1-1H128V143h57V43Z" transform="translate(-35 -43)"/>
</svg>
Note that using !important is typically frowned upon so don't rely on inline styling:
#room1:hover {
fill: #ffcccb;
}
#room1,
#room2 {
fill: #fff;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<rect id="room1" x="0.5" y="0.5" width="93" height="99" />
<path d="M128,44v98H36V44h92m1-1H35V143h94V43Z" transform="translate(-35 -43)"/>
<rect id="room2" x="93.5" y="0.5" width="56" height="99"/>
<path d="M184,44v98H129V44h55m1-1H128V143h57V43Z" transform="translate(-35 -43)"/>
</svg>
Related
everyone!
I have some SVG image with mask (for expamle):
<svg width="173" height="173" viewBox="0 0 173 173" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="mask0_42_56" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="61" y="65" width="50" height="43">
<rect x="61" y="65" width="50" height="43" rx="12" fill="#C4C4C4"/>
</mask>
</defs>
<rect width="173" height="173" rx="16" fill="#F2F3F7"/>
<g opacity="0.5">
<g mask="url(#mask0_42_56)">
<rect x="61" y="65" width="50" height="43" rx="0" fill="#C4C4C4"/>
<path d="M100.062 80.3574C102.651 80.3574 104.75 78.2947 104.75 75.7502C104.75 73.2058 102.651 71.1431 100.062 71.1431C97.4736 71.1431 95.3749 73.2058 95.3749 75.7502C95.3749 78.2947 97.4736 80.3574 100.062 80.3574Z"
fill="#6C6C6C"/>
<path d="M99.3574 90.5753C98.0109 89.2622 95.8359 89.2336 94.4531 90.5101L82.875 101.207V111.071H108.656C109.951 111.071 111 110.048 111 108.786V101.929L99.3574 90.5753Z"
fill="#6C6C6C"/>
<path d="M104.75 111.071L78.0929 84.4931C76.6965 83.1008 74.441 83.0706 73.0069 84.424L61 95.7654V108.648C61 109.987 62.0877 111.071 63.4306 111.071H104.75Z"
fill="#6C6C6C"/>
</g>
</g>
</svg>
I wanna bundle all of svg images on my project in one svg-sprite. I use simple gulp script for this, a lot of images displayed correctly. But images who contain mask displayed without mask. Mask id and attributes with using mask id match. The root of the incorrect display just in than symbol doesn't see mask with this id.
I have solution for Firefox. Move mask tag with chilren from symbol tag in parent svg tag.
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<mask id="ara" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="61" y="65" width="50" height="43">
<rect x="61" y="65" width="50" height="43" rx="12" fill="#C4C4C4"/>
</mask>
</defs>
<symbol fill="none" viewBox="0 0 173 173" id="empty-cover" xmlns="http://www.w3.org/2000/svg">
<rect width="173" height="173" rx="16" fill="#F2F3F7"/>
<g mask="url(#ara)" opacity="0.5">
<rect x="61" y="65" width="50" height="43" rx="0" fill="#C4C4C4"/>
<path d="M100.062 80.357c2.589 0 4.688-2.062 4.688-4.607 0-2.544-2.099-4.607-4.688-4.607-2.588 0-4.687 2.063-4.687 4.607 0 2.545 2.099 4.607 4.687 4.607zM99.357 90.575a3.582 3.582 0 00-4.904-.065l-11.578 10.697v9.864h25.781c1.295 0 2.344-1.023 2.344-2.285v-6.857L99.357 90.575z"
fill="#6C6C6C"/>
<path d="M104.75 111.071L78.093 84.493a3.656 3.656 0 00-5.086-.069L61 95.765v12.883a2.426 2.426 0 002.43 2.423h41.32z"
fill="#6C6C6C"/>
</g>
</symbol>
This solution doesn't work for Chrome.
I tried to move mask to parent tag like in Firefox solution.
And I tried put mask to both places: root svg tag and symbol.
I am trying to change the mobile hamburger menu icon to fit the color of my logo when the mouse is over -
.menu-hamburger:hover {
fill: #FFB400!important;
}
<a href="#">
<svg class="menu-hamburger">
<use xlink:href="#menu-hamburger"></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="menu-hamburger" class="menu-hamburger" viewBox="0 0 16 16" style="width: 16px; height: 16px; color:#FFF;">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
</a>
but still no luck
When using <use xlink:href="#" , the SVG content falls into the DOM shadow and the styling result depends on the style hierarchy of the external, internal CSS style sheet, SVG presentation styles
What will be the result of the struggle of these styles is not always easy to foresee..
Therefore, in the adjacent answer, the rule fill: #FFB400!important;
But this is a very bad practice that can break the rest of the layout.
The style hierarchy can be seen in the image below from the article: By Sara Soueidan Styling SVG Content with CSS
Computed Styles has the biggest weight.
Therefore, it is most reliable to use CSS variables for CSS styling.
.menu-hamburger {
margin:1em;
}
#u1,#u2 {
fill:black;
}
#u1:hover {
--primary-color: red;
cursor:pointer;
}
#u2:hover {
--primary-color: green;
}
<a href="#">
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u1" xlink:href="#menu-hamburger" ></use>
</svg>
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u2" xlink:href="#menu-hamburger" ></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0" viewBox="0 0 16 16">
<symbol class="menu-hamburger">
<g id="menu-hamburger" style="fill: var(--primary-color, black)">
<rect width="100%" height="100%" fill="transparent" />
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</g>
</symbol>
</svg>
UPDATE
By applying CSS variables you can implement multi-color icons
.menu-hamburger {
margin:1em;
}
#u1,#u2 {
fill:black;
}
#u1:hover {
--primary-color: green;
--second-color: gold;
--third-color: red;
cursor:pointer;
}
#u2:hover {
--primary-color: purple;
--second-color: greenyellow;
--third-color: dodgerblue;
}
<a href="#">
<svg class="menu-hamburger" width="96" height="96" viewBox="0 0 16 16">
<use id="u1" xlink:href="#menu-hamburger" ></use>
</svg>
</a>
<a href="#">
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u2" xlink:href="#menu-hamburger" ></use>
</svg>
</a>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0" viewBox="0 0 16 16">
<defs>
<symbol class="menu-hamburger">
<g id="menu-hamburger" style="fill: var(--primary-color, black)">
<rect width="100%" height="100%" fill="transparent" />
<rect y="1" width="16" height="2" style="fill: var(--primary-color)"></rect>
<rect y="7" width="16" height="2" style="fill: var(--second-color)"></rect>
<rect y="13" width="16" height="2" style="fill: var(--third-color)"></rect>
</g>
</symbol>
</defs>
</svg>
Try this.
svg.menu-hamburger :hover {
fill: #FFB400!important;
}
<a href="#">
<svg class="menu-hamburger">
<use xlink:href="#menu-hamburger"></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="menu-hamburger" class="menu-hamburger" viewBox="0 0 16 16" style="width: 16px; height: 16px; color:#FFF;">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
</a>
In this example I changed the <a> to a <button> because the action of clicking it is not navigating somewhere but opening a menu. It has the same properties. Controlling the width and the height of the menu is done using the button#menu-hamburger svg selector together with the fill color. So, now using a similar selector (button#menu-hamburger:hover svg) for hover the menu changes color without problem. I added the hover to the button so that you also "hover" when the pointer is in between the bars in the hamburger menu.
button#menu-hamburger {
display: block;
border: none;
background: transparent;
}
button#menu-hamburger svg {
fill: #000;
width: 16px;
height: 16px;
}
button#menu-hamburger:hover svg {
fill: #FFB400;
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" display="none">
<defs>
<symbol id="menu-hamburger" viewBox="0 0 16 16">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
<button id="menu-hamburger">
<svg xmlns="http://www.w3.org/2000/svg">
<use href="#menu-hamburger"/>
</svg>
</button>
I have a image, and i have cordinates (x1,y1),(x2,y2),(x3,y3),(x4,y4) to draw a svg/rectagle on image, how to draw?
I have tried using svg tag in img tag, but it does not work, the main thing is how to set width and height of svg(rect svg) using those cordinates.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
</svg>
If I understand correctly OP then so and look at the comments in the code.
<style>
.container {
width:100vw;
height:100vh;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/ORJ3b.jpg" width="100%" height="100%" />
<!-- Add a red rectangle over the image. -->
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
<!-- Add text -->
<text x="550" y="200" font-size="48px" font-family="sans-serif" font-weight="700" fill="white" >TEST </text>
</svg>
</div>
UPDATE
If a square over the image is needed to focus on one or more fragments of the image, then
you can use it repeatedly but add individual tooltips <tooltip>
A tooltip pops up when you hover and hold the cursor on the red square
.container {
width:100vw;
height:100vh;
}
.rect {
fill:transparent;
stroke:red;
stroke-width:2;
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1024 768" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/uOg10.jpg" width="100%" height="100%" />
<!-- Add a red rectangles over the image. -->
<g>
<!-- Tooltip pops up on hover -->
<title> Young lioness </title>
<rect class="rect" x="160" y="220" width="170" height="170" rx="15" />
</g>
<g>
<title> Young lion </title>
<rect class="rect" x="475" y="200" width="200" height="220" rx="15"/>
</g>
</svg>
</div>
You can consider using calc() and some CSS variables to find the width/height:
:root {
--x1:200;
--x2:100;
--x3:150;
--x4:200;
}
rect {
x:calc(var(--x1)*1px);
y:calc(var(--x2)*1px);
width:calc((var(--x1) + var(--x2))*1px);
height:calc((var(--x3) + var(--x4))*1px);
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect fill="none" stroke="red" stroke-width="2" />
</svg>
I want to attach an svg to an img tag like so
<img src="./img/home.svg" class="svg home-img" alt="Image of home">
From looking around the forums and guides I found out that you can use javascript to convert this img tag into an inline svg tag and then you'll be able to alter it like that.
I can not have javascript in my project. How can I go about doing this? This is the svg file I am working with.
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 48 48" enable-background="new 0 0 48 48" xml:space="preserve">
<polygon fill="#E8EAF6" points="42,39 6,39 6,23 24,6 42,23 "/>
<g>
<polygon fill="#C5CAE9" points="39,21 34,16 34,9 39,9 "/>
<rect x="6" y="39" fill="#C5CAE9" width="36" height="5"/>
</g>
<polygon fill="#B71C1C" points="24,4.3 4,22.9 6,25.1 24,8.4 42,25.1 44,22.9 "/>
<rect x="18" y="28" fill="#D84315" width="12" height="16"/>
<rect x="21" y="17" fill="#01579B" width="6" height="6"/>
<path fill="#FF8A65" d="M27.5,35.5c-0.3,0-0.5,0.2-0.5,0.5v2c0,0.3,0.2,0.5,0.5,0.5S28,38.3,28,38v-2C28,35.7,27.8,35.5,27.5,35.5z"
/>
</svg>
Is it possible to have a multiple different views into single SVG, or even just simulate that sort of effect with some clever use of groups? I wish to show different parts of a potentially very large SVG, but I'd rather avoid rendering it multiple times. Is there some sort of simple way of doing this?
for standalone SVGs there is the <view/> element which you can use to show only portions of your graphics. try this in a standalone file.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="100" height="100">
<view id="circleView" viewBox="0 0 100 100"/>
<view id="rectView" viewBox="100 0 100 100"/>
<a xlink:href="#rectView">
<circle cx="50" cy="50" r="45" fill="blue"/>
</a>
<a xlink:href="#rectView">
<rect x="105" y="5" width="90" height="90" fill="royalblue" stroke="#53c"></rect>
</a>
</svg>
just click on the cirlce to see the rect and on the rect to see the circle.
this also works if you reference your svg via <img>
<img src="your.svg#circleView"/>
<img src="your.svg#rectView"/>
i found this to be not working for inlined SVG. Here you can use a similar aproach. You can just change the viewBox of your SVG. In contrast to the above, viewBoxes can even be animated!
<svg viewBox="0 0 460 360" width="200" height="200">
<polygon id="triangle" points="100,10,450,350,10,350" fill="#52c" />
<circle id="circle" cx="50" cy="50" r="45" fill="#c52" />
<rect id="rect" x="255" y="155" width="200" height="200" fill="#5c2" />
<animate attributeName="viewBox" to="250 150 210 210" dur="0.5s" begin="circle.click" fill="freeze" />
<animate attributeName="viewBox" to="0 0 100 100" dur="0.5s" begin="triangle.click" fill="freeze" />
<animate attributeName="viewBox" to="0 0 460 360" dur="0.5s" begin="rect.click" fill="freeze" />
</svg>
<br/>click on any of he shapes!
of course you can also just set the viewBox by script...
if you want to reference different parts of your SVG, you might use the <use> - Element as suggested in the other answers.
It's pretty simple to do. You just use the <use> element as Robert suggests. Here is a working example.
svg {
border: solid 1px black;
}
svg#original {
width: 450px;
}
<svg viewBox="0 0 450 300" id="original">
<circle cx="225" cy="150" r="150" fill="orange"/>
<circle cx="175" cy="110" r="25" fill="black"/>
<circle cx="275" cy="110" r="25" fill="black"/>
<circle cx="225" cy="70" r="150" fill="none" stroke="black" stroke-width="20" stroke-dasharray="0 145 180 1000"/>
</svg>
<br/>
<!-- part of the original at the same scale -->
<svg width="150" height="150">
<use xlink:href="#original" x="-50" y="0" width="450" height="300"/>
</svg>
<!-- part of the original at 0.5x scale -->
<svg width="150" height="150">
<use xlink:href="#original" x="0" y="0" width="450" height="300" transform="scale(0.5)"/>
</svg>
<!-- part of the original at 3x scale (and using a different method to achieve the scaling) -->
<svg width="150" height="150">
<use xlink:href="#original" x="-450" y="-255" width="1350" height="900"/>
</svg>