Reputation: 3253
I'm displaying a simple box over an image, I want it to highlight when hovered over and change colour when clicked.
I've got it to highlight when hovered over and change colour when clicked.The problem is that after changing colour the first time it no longer highlights when hovered over. It seems when the JS changes the styles it disables the CSS hover selector.
How can I keep the hover highlighting working?
const box = document.getElementsByClassName("box")[0];
box.addEventListener("click", (e) => {
// console.log(e);
if (e.target.style.backgroundColor == "rgba(255, 0, 0, 0.1)") {
e.target.style.backgroundColor = "rgba(0, 255, 0, 0.1)";
e.target.style.borderColor = "rgba(0, 255, 0, 0.4)";
} else {
e.target.style.backgroundColor = "rgba(255, 0, 0, 0.1)";
e.target.style.borderColor = "rgba(255, 0, 0, 0.4)";
}
});
.container {
position: relative;
}
.box {
width: 40px;
height: 40px;
background-color: rgba(0, 255, 0, 0.1);
border-style: solid;
border-color: rgb(0, 255, 0);
position: absolute;
top: 20px;
left: 50px;
}
.box:hover {
background-color: rgba(32, 58, 58, 0.4);
}
<div class="container" style="display: inline-block">
<img src="https://pixeljoint.com/files/icons/full/tree__r1090291261.gif"></img>
<div class="box"></div>
</div>
Upvotes: 1
Views: 108
Reputation: 18619
CSS rules set by JS are inline CSS declarations in the element's style
attribute.
According to the CSS' cascading rules, they take priority over any <style>
elements and <link>
ed stylesheets.
So, to change styles from JS, you should always either:
In this case, it's much easier to implement the first way:
const box = document.getElementsByClassName("box")[0];
box.addEventListener("click", () => {
/*
vvv--- Changed to `box` from `event.target`, so it works even if a child is clicked. This is equivalent to `event.currentTarget`. */
box.classList.toggle("red");
});
.container {
position: relative;
}
.box {
width: 40px;
height: 40px;
background-color: rgba(0, 255, 0, 0.1);
border-style: solid;
border-color: rgb(0, 255, 0);
position: absolute;
top: 20px;
left: 50px;
}
/*
vvvv--- The style applies only to `.box` elements, allowing the `.red` class to have different meanings in different contexts. */
.box.red{
background-color: rgba(255, 0, 0, 0.1);
border-color: rgba(255, 0, 0, 0.4);
}
/*
vvvvvvvvvv--- This selector should be always of greater specificity than the previous. Currently, they are equal, but this is placed later, so takes a higher priority. */
.box:hover {
background-color: rgba(32, 58, 58, 0.4);
}
<div class="container" style="display: inline-block">
<img src="https://pixeljoint.com/files/icons/full/tree__r1090291261.gif"></img>
<div class="box"></div>
</div>
Upvotes: 1
Reputation: 8610
Why not set a class for the borders element in CSS and then toggle the class on click?
The reason your hover element set in CSS is not working is because the inline css you are setting using JS is over riding the psuedo elements styling in the internal CSS. See the second example below.
const box = document.getElementsByClassName("box")[0];
box.addEventListener("click", (e) => {
e.target.classList.toggle('toggle')
});
.container {
position: relative;
}
.box {
width: 40px;
height: 40px;
background-color: rgba(0, 255, 0, 0.1);
border-style: solid;
border-color: rgb(0, 255, 0);
position: absolute;
top: 20px;
left: 50px;
}
.box:hover {
background-color: rgba(32, 58, 58, 0.4);
}
.toggle {
background-color: rgba(0, 255, 0, 0.1);
border-color: rgba(255 ,0, 0, 0.4);
}
<div class="container" style="display: inline-block">
<img src="https://pixeljoint.com/files/icons/full/tree__r1090291261.gif"></img>
<div class="box"></div>
</div>
const changed = document.getElementById('changed')
changed.addEventListener('click', () => {
changed.style.backgroundColor = 'green';
changed.textContent = 'This elements inline style will now over ride the CSS style rendering the hover psuedo rule useless'
})
#changed {
background-color: yellow;
display: inline-block;
}
#changed:hover {
background-color: red;
}
<div title="right click me and select the browser inspector to view inline style" id="changed">hover over me to change the background-color style</div>
<div>Click the element above to add JS inline style to it then hover to see behavior.</div>
Upvotes: 2
Reputation: 1804
In CSS there are several rules for a priorities in case of conflicting styles.
In this case, the inline CSS that you insert takes priority.
you can either set the changed background in a new class and toggle it when clicking, or add !important
to the end of the hover selector.
background-color: rgba(32, 58, 58, 0.4) !important;
Upvotes: -2