Apply effect to Element on Hover of Another without JS - html

I have this code: http://codepen.io/hwg/pen/azZoyp
What I am attempting to do is to apply the blur effect (SVG filter for compatibility) to the other elements on hover of another.
The most important bit of the CSS is as follows
.oi:hover ~ a {color:green;filter: url('#blur');}
This uses the ~ selector in order to effect the siblings of the Link with class of oi. This is fine, but it only affects the elements after the hovered one. Not all of the siblings in the container div.
Is this possible just in CSS?
I've seen that you can use JS as seen here: Using jQuery to Hover over one element and apply the effect in another, and in other questions.
I'd just like to not use JS if possible, would appeciate any help!
Thanks!
Code Embedded:
.btn {
background:lightblue;
padding:1em;
font-family:sans-serif;
margin:0.4em;
display:inline-block;
transition:0.25s all ease-in-out;
border-radius: 5px;
}
.oi ~ a {color:red;}
.oi:hover ~ a {color:green;filter: url('#blur');}
.oi:hover {transform: scale(1.5,1.5);color:red;}
div {margin: 100px auto;display:block;width:100%;}
<div>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn oi">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
</div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>

The CSS general sibling selector will only select siblings after that element. (Source: https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_selectors)
Use the parent element class, or the btn class instead, and then remove the filter effect with filter:none on the selected element. To wit:
.btn {
background:lightblue;
padding:1em;
font-family:sans-serif;
margin:0.4em;
display:inline-block;
transition:0.25s all ease-in-out;
border-radius: 5px;
color: red;
}
.oi {color:black;}
.btn_wrapper {margin: 100px auto;padding:0;display:block;width:100%;}
.btn_wrapper:hover .btn {color:green;filter: url('#blur');}
.btn_wrapper:hover .btn:hover {transform: scale(1.5,1.5);color:red;filter: none;}
<div class="btn_wrapper">
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn oi">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
</div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>

Is this possible just in CSS?
Unfortunately, not in a resilient way.
CSS can only descend (cascade) down the DOM, as such selectors can only identify children of an element or siblings appearing after it, at the same level.
In order to achieve what you want you will likely need to resort to a javascript solution- what you wish to achieve would be trivial in jQuery, e.g:
$('.oi').on('mouseover', function(){
$(this).siblings('a')....
});
Alternatively, as close as you will get in CSS is:
.btn {
background: lightblue;
padding: 1em;
font-family: sans-serif;
margin: 0.4em;
display: inline-block;
transition: 0.25s all ease-in-out;
border-radius: 5px;
}
a {
color: red;
}
div:hover a {
color: green;
filter: url('#blur');
}
.oi:hover {
transform: scale(1.5, 1.5);
color: red;
}
div {
margin: 100px auto;
display: block;
width: 100%;
}
<div>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn oi">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
<a class="btn">Cholla</a>
</div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
</svg>

Related

SVG mouseover show hide on hotspots

I've created a map image with overlaying hotspots. It was created in inkscape and exported as an SVG.
The map is a test sketch only. http://wilsonvisuals.art/zenmapillo/imagemap_responsive2.html
I have pasted the SVG code into an html page with css.
I am now trying to add mouse over functionality to the hotspots.
When the user mouses over a hotspot it shows a tooltip or other card. And hides again when moused off.
I've tried several methods of inserting html/css code into the svg code but never works. The one below is simple html css.
I's this method workable? and how would I fix it?
Is Javascript a better approach to this? I got it working this way but the sample code I used performed a different function than what I want. Is there some sample code specific to show/hide on mouseover? (I am Javascript illiterate).
Any ideas on this would be greatly appreciated.
<!DOCTYPE html>
<html>
<title>Zen Maps - Courtney & Comox, Vancouver Island</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="css/custom.css">
<style>
#myBtn {
margin: auto;
z-index: 99;
font-size: 18px;
border: none;
outline: none;
background-color: #4a178bff;
color: white;
cursor: pointer;
padding: 15px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
div {
text-align: center;
}
h2 {
color: #4287f5;
}
.hide {
display: none;
border: 5px double #b4b8bf;
}
.hide2 {
display: none;
border: 5px double #b4b8bf;
}
.hide3 {
display: none;
border: 5px double #b4b8bf;
}
a {
display: block;
margin-top: 15px;
cursor: pointer;
text-decoration: none;
}
a:hover + span {
display: block;
color: #4287f5;
font-size: 20px;
}
a.two {
display: block;
margin-top: 15px;
cursor: pointer;
text-decoration: none;
}
a.two:hover + span {
display: block;
color: #4287f5;
font-size: 20px;
}
a.three {
display: block;
margin-top: 15px;
cursor: pointer;
text-decoration: none;
}
a.three:hover + span {
display: block;
color: #4287f5;
font-size: 20px;
}
</style>
<body>
<div class="mapdiv">
<!----to make svg responsive change fixed width to percentage and remove height property in the svg tag---->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg366"
width="3272.7273"
height="2029.0909"
viewBox="0 0 3272.7273 2029.0909"
sodipodi:docname="Comox3hotspot.svg"
inkscape:version="1.2 (dc2aeda, 2022-05-15)"
inkscape:export-filename="Comox1hotspot.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs370" />
<sodipodi:namedview
id="namedview368"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="0.38072222"
inkscape:cx="1086.0937"
inkscape:cy="1016.4891"
inkscape:window-width="1732"
inkscape:window-height="1290"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="g372" />
<g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g372">
<image
width="3272.7273"
height="2029.0909"
preserveAspectRatio="none"
xlink:href="maps/Comox12.jpg"
id="image374" />
<a xlink:href="http://travelalberta.com/">
<clipPath id="alberta-clipper">
<path id="CA-AB" d="M1932…"/>
</clipPath>
<image clip-path="url(#alberta-clipper)"
width="1024" height="768"
xlink:href="crowsnest-pass.jpg" x="1300" y="150">
</image>
</a>
<a xlink:href="http://travelalberta.com/">
<path
style="opacity:1;fill:#310000"
d="m 853.64075,499.05151 c -152.34204,-2.62658 -152.34204,-2.62658 -152.34204,-2.62658 l 2.62658,168.10156 212.75354,31.51904 76.17102,-110.31665 z"
id="path562" />
</a>
<foreignObject x="20" y="20" width="160" height="160">
<span class="hide">
First Card
</span>
</foreignObject>
<a xlink:href="http://travelalberta.com/">
<path
style="opacity:1;fill:#333"
d="m 1452.5026,590.98206 -154.9687,186.48767 383.4817,84.05078 291.5512,7.87976 -112.9433,-309.93726 z"
id="path6362" />
</a>
<foreignObject x="20" y="20" width="160" height="160">
<span class="hide2">
Second Card
</span>
</foreignObject>
<a xlink:href="http://travelalberta.com/">
<path
style="opacity:1;fill:#777"
d="m 1329.053,1625.8573 57.7849,344.0829 643.5138,36.7722 -139.2091,-378.2285 z"
id="path6364"
inkscape:export-filename="path6364.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
</a>
<foreignObject x="20" y="20" width="160" height="160">
<span class="hide3">
Third Card
</span>
</foreignObject>
</g>
</svg>
</div>
</body>
</html>
I would put the card outside the svg element. The card can be a div with position absolute (so that you can position it where you need it to be) and display none that you make visible only when passing over the path.
For clarity i've simplified the code.
let paths = document.querySelectorAll("path");
paths.forEach((p) => {
p.addEventListener("mouseleave", (evt) => {
card.style.display = "none";
});
p.addEventListener("mousemove", (evt) => {
let pos = oMousePos(svg, evt);
let text = p.dataset.text;
card.style.display = "block";
card.style.top = pos.y + "px";
card.style.left = pos.x + "px";
card.innerHTML = text;
});
});
function oMousePos(element, evt) {
let ClientRect = element.getBoundingClientRect();
return {
//objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
};
}
#card {
position: absolute;
width: 100px;
height: auto;
display: none;
border: solid;
background: white;
pointer-events: none;
color:red;
padding:1em;
}
<svg viewBox="0 0 3272.7273 2029.0909" id="svg" >
<g id="g372">
<image width="3272.7273" height="2029.0909" preserveAspectRatio="none" xlink:href="maps/Comox12.jpg" id="image374" />
<a xlink:href="http://travelalberta.com/">
<path style="opacity:1;fill:#310000" d="m 853.64075,499.05151 c -152.34204,-2.62658 -152.34204,-2.62658 -152.34204,-2.62658 l 2.62658,168.10156 212.75354,31.51904 76.17102,-110.31665 z" id="path562" data-text="first Card" />
</a>
<a xlink:href="http://travelalberta.com/">
<path style="opacity:1;fill:#333" d="m 1452.5026,590.98206 -154.9687,186.48767 383.4817,84.05078 291.5512,7.87976 -112.9433,-309.93726 z" id="path6362" data-text="Second Card" />
</a>
<a xlink:href="http://travelalberta.com/">
<path style="opacity:1;fill:#777" d="m 1329.053,1625.8573 57.7849,344.0829 643.5138,36.7722 -139.2091,-378.2285 z" id="path6364" data-text="third Card" />
</a>
</g>
</svg>
<div id="card"></div>

How do I set different size SVGs same height?

I use a RestAPI, it's giving me different size SVG. Some images are fit but some images don't fit.
Example: If you look at the border and image, you gonna understand.
The main problem is that; I don't know all pictures sizes, How can ı set this case? (İf it's given 100% height change the card height and ı don't want this.)
<div className="countries__card card">
<div className="card__flag">
<LazyLoad
height={windowWidth >= 614 ? "210px" : '173px"'}
once
>
<img
width={windowWidth >= 614 ? "320px" : "100%"}
height={windowWidth >= 614 ? "210px" : '100%"'}
src="https://restcountries.eu/data/afg.svg"
alt="flag"
/>
</LazyLoad>
</div>
<div className="card__body">
<div className="card__body-name">
<h5>Lorem</h5>
</div>
<div className="card__body-infos">
<span className="country-capital">Capital: Lorem</span>
<span className="country-currencies">Currency: Lorem</span>
<span className="country-region">Region: Lorem</span>
</div>
</div>
<footer className="card__footer">
Go to detailed information.
</footer>
</div>
<div className="countries__card card">
<div className="card__flag">
<LazyLoad
height={windowWidth >= 614 ? "210px" : '173px"'}
once
>
<img
width={windowWidth >= 614 ? "320px" : "100%"}
height={windowWidth >= 614 ? "210px" : '100%"'}
src="https://restcountries.eu/data/blr.svg"
alt="flag"
/>
</LazyLoad>
</div>
<div className="card__body">
<div className="card__body-name">
<h5>Lorem</h5>
</div>
<div className="card__body-infos">
<span className="country-capital">Capital: Lorem</span>
<span className="country-currencies">Currency: Lorem</span>
<span className="country-region">Region: Lorem</span>
</div>
</div>
<footer className="card__footer">
Go to detailed information.
</footer>
</div>
.card {
border: 2px solid black;
text-align: center;
margin-bottom: rem(50px);
width: 320px;
overflow: hidden;
animation: showCard 0.7s ease-out forwards;
img {
vertical-align: middle;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
&__body,
&__footer {
background: $skyblue;
}
&__body {
&-name {
color: $text-navy;
padding: rem(10px) 0;
font-size: rem(20px);
font-weight: $font-bold;
font-weight: normal;
border-bottom: 4px solid $text-navy;
}
&-infos {
padding: rem(15px) 0;
display: flex;
justify-content: center;
color: $text-navy;
span {
white-space: nowrap;
font-size: rem(14.3px);
}
span:not(:last-child) {
padding-right: rem(5px);
border-right: 3px solid $text-navy;
}
span:not(:first-child) {
padding-left: rem(5px);
}
}
}
&__footer {
border-top: 3px solid $text-navy;
padding: rem(15px) 0;
background: $text-navy;
cursor: pointer;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
There is no standard for flag dimensions. RestCountries provides flags in their true dimensions.
I created a 29 kB Single File Web Component that does all SVG flags in fixed dimensions (like most SVG flag Repos do).
And can use RestCountries (or any other SVG flag Repo) as alternative source:
https://flagmeister.github.io/
Alas, I did not create all crests, you picked the exact two I failed to complete: Afghanistan and Andorra for your screenshots. Those flags FlagMeister will default to RestCountries unless prevented with the detail setting.
<script src="https://flagmeister.github.io/elements.flagmeister.min.js"></script>
<style>
div {
display:grid;
grid-template-columns:repeat(6,100px);
gap:10px;
}
[nodetail] {
--flagmeisterdetail:99999;
}
</style>
<h3>RestCountries & FlagMeister (forced to no-detail)</h3>
<div>
<flag-af></flag-af>
<flag-af nodetail></flag-af>
<flag-by></flag-by>
<flag-by nodetail></flag-by>
<flag-ad></flag-ad>
<flag-ad nodetail></flag-ad>
</div>
If you can live with making local copies of all the flags. Then, if you add the following attribute to all SVGs, they will stretch to fit your <img> width and height.
preserveAspectRatio="none"
For instance, the Belarus flag becomes:
svg {
width: 300px;
height: 300px;
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="450" viewBox="0 0 1098 549" preserveAspectRatio="none">
<title>Flag of Belarus</title>
<rect fill="#C8313E" width="1098" height="549"/>
<rect y="366" fill="#4AA657" width="1098" height="183"/>
<rect fill="#FFF" width="122" height="549"/>
<g id="h">
<g id="q" fill="#C8313E" fill-rule="evenodd" transform="scale(5.304347826,9)">
<path d="M4,0h3v1h1v1h1v1h1v1h1v1h-1v1h-1v1h-1v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h-1v-1h-1v-1h-1v-1h1v-1h1v-1h1v-1h1zM5,2h1v1h1v1h1v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h1v-1h1zM5,4h1v1h-1zM0,1h1v1h-1zM0,7h1v1h-1zM11,0h0.6v2h-.6zM11,7h.6v2h-.6zM2,9h1v1h1v1h1v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h1v-1h1zM2,11h1v1h-1zM8,9h1v1h1v1h1v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h1v-1h1zM8,11h1v1h-1zM0,15h1v1h-1zM11,14h.6v2h-.6z"/>
<path d="M0,18h1v-1h1v-1h1v-1h1v-1h1v-1h1v1h1v1h1v1h1v1h1v1h1v1h.6v4h-.6v1h-1v1h-1v1h-1v1h-1v1h-1v2.6h-2v-0.6h-1v-1h-1v-1h-1v-1h-1 v-3h1v1h1v1h1v1h1v-1h1v-1h1v-1h1v-1h1v-1h1v-1h-1v-1h-1v-1h-3v1h2v1h-1v1h-1v1h-1v-1h-1v-1h-1v-1h-1zM0,22h1v1h-1zM11,25h.6v1h-.6zM9,27h1v1h1v1h.6v1.6h-.6v-.6h-1v-1h-1zM7,30h1v.6h-1z"/>
</g>
<use xlink:href="#q" transform="translate(122,0) scale(-1,1)"/>
</g>
<use xlink:href="#h" transform="translate(0,549) scale(1,-1)"/>
</svg>

SVG oversized on load until CSS kicks in

I have a SVG inside a fixed-size div (width: 350px; height: 400px;) and everything is fine once the page loads, but during the loading, the SVG is oversized and mangled up until CSS kicks in:
Here is the code, HTML first:
<div class="dashboard-tasks-completed">
<figure>
<svg width="100%" height="100%" viewBox="0 0 42 42" class="donut">
<circle class="donut-hole" cx="21" cy="21" r="15.91549430918954" fill="#fff"></circle>
<circle class="donut-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#19222a" stroke-width="5"></circle>
<circle id="active" class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#206996" stroke-width="5" stroke-dasharray="66.66666666666666 33.33333333333333" stroke-dashoffset="25"></circle>
<circle id="completed" class="donut-segment" cx="21" cy="21" r="15.91549430918954" fill="transparent" stroke="#B8E1FA" stroke-width="5" stroke-dasharray="33.33333333333333 66.66666666666666" stroke-dashoffset="58.33333333333334"></circle>
<g class="chart-text">
<text x="50%" y="50%" class="chart-number">3</text>
<text x="50%" y="50%" class="chart-label"> Tasks </text>
</g>
</svg>
<figcaption class="figure-key">
<ul class="figure-key-list" aria-hidden="true" role="presentation">
<li>
<span class="shape-circle shape-blue"></span>2 Active (66.67%)
</li>
<li>
<span class="shape-circle shape-lightblue"></span>1 Completed (33.33%)
</li>
</ul>
</figcaption>
</figure>
</div>
CSS:
.dashboard-tasks-completed {
width: 350px;
height: 400px;
}
.chart-text {
font: 16px/1.4em "Montserrat", Arial, sans-serif;
fill: #000;
transform: translateY(0.25em);
}
.chart-number {
font-size: 0.6em;
line-height: 1;
text-anchor: middle;
transform: translateY(-0.25em);
}
.chart-label {
font-size: 0.2em;
font-weight: bold;
text-transform: uppercase;
text-anchor: middle;
transform: translateY(0.7em);
}
.figure-key-list {
list-style: none;
}
.figure-key-list li {
margin: 0 0 8px;
font-size: 14px;
}
.shape-circle {
display: inline-block;
vertical-align: middle;
width: 32px;
height: 32px;
border-radius: 50%;
margin-right: 10px;
}
.shape-blue { background-color: #206996; }
.shape-lightblue { background-color: #B8E1FA }
I have created a minimal example, unfortunately it is not reproducible in neither JSFiddle or Codepen, but here is the demo in any case.
How can I overcome the issue?
As others have said, you are letting the SVG fill the page until the CSS loads and it becomes the correct size.
If you know your SVG is going to be width: 350px; height: 400px;, then you could set those dimensions on the SVG instead.
<svg width="350px" height="400px" ...>
Then put it back to what you want in the CSS.
.dashboard-tasks-completed svg {
width: 100%;
height: 100%;
}
Or you could inline some basic styling in your document, that would set up some important sizes until the rest of the SVG loads.
<head>
<style>
.dashboard-tasks-completed {
width: 350px;
height: 400px;
}
.chart-text {
font: 16px/1.4em "Montserrat", Arial, sans-serif;
fill: #000;
transform: translateY(0.25em);
}
</style>
...
And if your font size never changes, then why not just set those attributes on your <text> element instead of using CSS?
<g class="chart-text" style="font: 16px/1.4em "Montserrat", Arial, sans-serif; fill: #000; transform: translateY(0.25em);">
One option is to hide the div (or other elements within) initially and then reveal it after the page finishes loading.
For example, modify your div thusly:
<div id="showme" class="dashboard-tasks-completed" style="display:none;">
And then add the following javascript:
window.onload = function () {
document.getElementById("showme").style.display = "block";
};
The inline CSS display:none; lets the browser know not to display it, even before external CSS is loaded. Once everything is loaded, your onload event will fire, and the javascript above will display the previously-hidden elements.
The viewBox attribute defines the position and dimension, in user space, of an SVG viewport.
The value of the viewBox attribute is a list of four numbers min-x, min-y, width and height, separated by whitespace and/or a comma, which specify a rectangle in user space which is mapped to the bounds of the viewport established for the associated SVG element (not the browser viewport).
Taken from MDN.
The viewbox property defines the region of an svg element which should be zoomed in on to fit inside it's container. However, the element will keep it's aspect ratio and not stretch to fit inside the container.
So in your case, this means that the svg element will fill all it's parents space while maintaining it's aspect ratio, until css arrives and tells it to size it self inside a 350px by 400px space.

css on focus change another div's styling

I want the svg to change the fill color when a user have focus on the input.
But I don't understand how to write the css to make it happen.
Added Html and css for you to check out! I'm using scss for the css.
<div class="search">
<svg width="20px" height="20px" viewBox="0 0 88 88" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Symbols" stroke="none" stroke-width="1" fill-rule="evenodd">
<g id="Icon-Search" fill="#b3b3b3" fill-rule="nonzero">
<path d="M86.829,81.172 L64.128,58.471 C69.055,52.312 72,44.5 72,36 C72,16.118 55.883,0 36,0 C16.118,0 0,16.118 0,36 C0,55.882 16.118,72 36,72 C44.5,72 52.312,69.054 58.471,64.127 L81.172,86.828 C81.953,87.609 82.977,88 84,88 C85.024,88 86.048,87.609 86.829,86.828 C88.391,85.267 88.391,82.733 86.829,81.172 Z M36,64 C20.536,64 8,51.464 8,36 C8,20.536 20.536,8 36,8 C51.465,8 64,20.536 64,36 C64,51.464 51.465,64 36,64 Z" id="Shape"></path>
</g>
</g>
</svg>
<input class="input inputSearchField" type="text" placeholder="Search...">
</div>
.input{
width: 250px;
height: 35px;
padding-left: 16px;
font-weight: 700;
background-color: $white-color;
border-radius: 4px;
border: 1px solid $lighter-gray;
font-size: 16px;
outline:none;
transition: all 0.30s ease-in-out;
&::placeholder {
color: $light-gray;
}
&:focus {
box-shadow: 0 0 5px #64e469;
border: 1px solid #64e469;
}
}
.search {
position: relative;
margin: 0 auto;
text-align: center;
width: 270px;
margin-bottom: 30px;
}
.search svg {
position: absolute;
top: 7px;
right: 22px;
fill: $lighter-gray;
}
Check out this CodePen Demo. You'll need to move your input before your SVG, otherwise you'll have to use some JavaScript to do this, because CSS doesn't have a "look behind" selector of any kind. Even the General Sibling Combinator only looks ahead of the current selector target.
If you move the input first, you can just do:
.input:focus + svg #Icon-Search {
fill: #64e469;
}
If you do want to keep the current structure, the JavaScript would look something like on this Demo
let search = document.getElementsByClassName('inputSearchField');
let svgFill = document.getElementById('Icon-Search');
search[0].onfocus = function(){ svgFill.style.fill = '#64e469'; }
search[0].onblur = function(){ svgFill.style.fill = '#b3b3b3'; }
You can see it's a fair bit more tedious!
I'm wondering that you have a html like it:
<div class="search">
<input class="input" />
<svg />
</div>
Your css can be something like this:
.input:focus + svg { ... }
If svg comes before input, then you can use ~ instead +

How to affect other elements if SVG is hovered over?

I have this issue here where I have an svg as a logo next to my .brand-name class. What I have done so far is to make sure the svg looks like it's a part of the .brand-name class, meaning that whenever I hover over the .brand-name class, the svg also appears as if it was hovered over. However, I could not find any material as to how to get the opposite effect; meaning that when I hover over the svg, the .brand-name class also appears like it's been hovered over. I have been researching this topic using this thread, but I couldn't come up with a solution that could fit the svg to .brand-name class issue.
HTML
<ul class="brand">
<li><a href="#" class="logo-container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="40px" height="35px" viewBox="0 0 363.818 363.818" style="enable-background:new 0 0 363.818 363.818;" xml:space="preserve">
<path class="logo" d="M358.872,0.841c-3.196-1.538-7.014-0.931-9.572,1.526c-19.515,18.728-53.141,46.415-102.511,71.961 c-2.159,1.118-3.737,3.106-4.333,5.463c-4.028,15.908-11.933,33.271-23.492,51.607l-4.705,7.462l8.772-38.205 c0.715-3.115-0.378-6.368-2.828-8.42c-2.451-2.052-5.846-2.556-8.786-1.303l-1.015,0.428 C110.79,133.291,81.352,198.24,72.67,233.22c-3.013,12.141-4.516,24.163-4.465,35.738c0.02,4.466,0.272,8.722,0.75,12.705 l-66.39,67.703c-3.211,3.273-3.246,8.505-0.078,11.822c1.667,1.745,3.904,2.629,6.149,2.629c2.02,0,4.045-0.717,5.664-2.164 l182.428-163.851c0.896,0.059-103.874,109.806-102.925,109.806c14.22,0,33.863-6.555,56.804-18.95 c30.935-16.717,65.508-42.37,99.979-74.185c2.832-2.612,3.551-6.805,1.753-10.213c-1.798-3.407-5.662-5.181-9.42-4.315 l-21.363,4.904l7.465-4.706c20.835-13.136,40.313-21.511,57.891-24.897c1.901-0.367,3.622-1.372,4.875-2.849 c41.348-48.75,58.853-96.919,66.256-128.743c2.69-11.567,4.579-23.134,5.607-34.38C363.972,5.742,362.069,2.379,358.872,0.841z" fill="#FFFFFF"/>
</svg>
</a></li>
<li>Company Name</li>
</ul>
CSS
.header ul.brand .logo {
transition: 0.2s ease-in-out fill;
}
.header ul.brand:hover .logo {
fill: #fbabab;
color: #fbabab;
}
.header ul.brand .logo:hover {
fill: #fbabab;
color: #fbabab;
}
I've already created the motion where the svg appears to be hovered over when the user hovers over the .brand-name anchor class.
Additionally, if more information is required to aid me on this issue, I'd be more than grateful to help out to provide such. Please comment down below if such clarification is necessary. Many thanks!
You can add hover to both at the same time:
.header ul.brand:hover .logo,
.header ul.brand:hover .brand-name {
fill: #fbabab;
color: #fbabab;
}
Or
.header ul.brand:hover .logo {
fill: #fbabab;
}
.header ul.brand:hover .brand-name {
color: #fbabab;
}
However, I would simplify the HTML to:
<header>
<a href="#">
<svg>...</svg>
<span>Company Name</span>
</a>
</header>
And use this as an example:
header a:hover svg {
...
}
header a:hover span {
...
}