Change :hover CSS properties with JavaScript
Asked Answered
E

18

161

How can JavaScript change CSS :hover properties?

For example:

HTML

<table>
  <tr>
    <td>Hover 1</td>
    <td>Hover 2</td>
  </tr>
</table>

CSS

table td:hover {
background:#ff0000;
}

How can the td :hover properties be modified to, say, background:#00ff00, with JavaScript? I know I could access the style background property using JavaScript with:

document.getElementsByTagName("td").style.background="#00ff00";

But I don't know of a .style JavaScript equivalent for :hover.

Etesian answered 7/7, 2012 at 1:27 Comment(0)
L
159

Pseudo classes like :hover never refer to an element, but to any element that satisfies the conditions of the stylesheet rule. You need to edit the stylesheet rule, append a new rule, or add a new stylesheet that includes the new :hover rule.

var css = 'table td:hover{ background-color: #00ff00 }';
var style = document.createElement('style');

if (style.styleSheet) {
    style.styleSheet.cssText = css;
} else {
    style.appendChild(document.createTextNode(css));
}

document.getElementsByTagName('head')[0].appendChild(style);
Livia answered 7/7, 2012 at 1:37 Comment(7)
If you're taking this route, this article may help in the future as well.Antimony
If looking to append the stylesheet, would it not be style.styleSheet.cssText += css;?Helicograph
@Helicograph No, because style variable in kennebec's answer is a new element created in the code and doesn't point to an existing <style> tag in the HTML.Centrifugal
Why is it unknown whether the new style element already has a styleSheet or not?Essence
How would you find and edit a current stylesheet rule, to change it? This shows adding a new rule, but what if there already is a rule, and it's just a value being changed?Essence
@JGallardo what would be better variable names in your opinion?Eudo
your solution worked fine and this one did not: #8209586 (Dabolus) -- i will figure that one out in a different lifetime.Torsion
A
58

You can't change or alter the actual :hover selector through Javascript. You can, however, use mouseenter to change the style, and revert back on mouseleave (thanks, @Bryan).

Antimony answered 7/7, 2012 at 1:30 Comment(3)
There really is NO way to change the :hover selector with JavaScript?Etesian
Note that you are also going to need to bind mouseleave in order to reverse the effects.Drabbet
I've been using this on past projects and even tried the accepted answer recently, but this one always prevails when it comes to using hover/active elements with colored buttons. Just want to say thanks for posting this as an option.Alyshaalysia
A
31

Pretty old question so I figured I'll add a more modern answer. Now that CSS variables are widely supported they can be used to achieve this without the need for JS events or !important.

Taking the OP's example:

<table>
  <tr>
    <td>Hover 1</td>
    <td>Hover 2</td>
  </tr>
</table>

We can now do this in the CSS:

table td:hover {
  // fallback in case we need to support older/non-supported browsers (IE, Opera mini)
  background: #ff0000;
  background: var(--td-background-color);
}

And add the hover state using javascript like so:

const tds = document.querySelectorAll('td');
tds.forEach((td) => {
  td.style.setProperty('--td-background-color', '#00ff00');
});

Here's a working example https://codepen.io/ybentz/pen/RwPoeqb

Aguste answered 22/2, 2020 at 23:8 Comment(3)
so you first define a css var and then change the var in js?Landman
Yes! There's still no way on JS to target the :hover state but CSS variables allows you to "bypass" it by changing the value of the variable via JS while the CSS code doesn't change.Aguste
This is def the best answer now! Worked super for meFrayne
V
16

What you can do is change the class of your object and define two classes with different hover properties. For example:

.stategood_enabled:hover  { background-color:green}
.stategood_enabled        { background-color:black}
.stategood_disabled:hover { background-color:red}
.stategood_disabled       { background-color:black}

And this I found on: Change an element's class with JavaScript

function changeClass(object,oldClass,newClass)
{
    // remove:
    //object.className = object.className.replace( /(?:^|\s)oldClass(?!\S)/g , '' );
    // replace:
    var regExp = new RegExp('(?:^|\\s)' + oldClass + '(?!\\S)', 'g');
    object.className = object.className.replace( regExp , newClass );
    // add
    //object.className += " "+newClass;
}

changeClass(myInput.submit,"stategood_disabled"," stategood_enabled");
Vivianne answered 18/5, 2013 at 15:42 Comment(0)
P
16

Sorry to find this page 7 years too late, but here is a much simpler way to solve this problem (changing hover styles arbitrarily):

HTML:

<button id=Button>Button Title</button>

CSS:

.HoverClass1:hover {color: blue !important; background-color: green !important;}
.HoverClass2:hover {color: red !important; background-color: yellow !important;}

JavaScript:

var Button=document.getElementById('Button');
/* Clear all previous hover classes */
Button.classList.remove('HoverClass1','HoverClass2');
/* Set the desired hover class */
Button.classList.add('HoverClass1');
Pecoraro answered 18/8, 2019 at 12:58 Comment(2)
This is only for one button right ? What if i want to add this effect to all the buttonsSeptuplet
JavaScript provides several ways to handle multiple operations, including using arrays.Pecoraro
C
13

If it fits your purpose you can add the hover functionality without using css and using the onmouseover event in javascript

Here is a code snippet

<div id="mydiv">foo</div>

<script>
document.getElementById("mydiv").onmouseover = function() 
{
    this.style.backgroundColor = "blue";
}
</script>
Consuetudinary answered 21/5, 2016 at 17:49 Comment(3)
This will persist the new style and won't go back to its previous one!Allie
@Allie - You can revert this color back on mouse out event.Erythrite
Mouse events are not reliable, as people can switch tabs/applications without moving the mouseWaziristan
A
12

You can use mouse events to control like hover. For example, the following code is making visible when you hover that element.

var foo = document.getElementById("foo");
foo.addEventListener('mouseover',function(){
   foo.style.display="block";
})
foo.addEventListener('mouseleave',function(){
   foo.style.display="none";
})
Amylaceous answered 19/10, 2020 at 14:8 Comment(1)
You better use this.style.display="block"; | this.style.display="none";Mandal
G
4

I'd recommend to replace all :hover properties to :active when you detect that device supports touch. Just call this function when you do so as touch()

   function touch() {
      if ('ontouchstart' in document.documentElement) {
        for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
          var sheet = document.styleSheets[sheetI];
          if (sheet.cssRules) {
            for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
              var rule = sheet.cssRules[ruleI];

              if (rule.selectorText) {
                rule.selectorText = rule.selectorText.replace(':hover', ':active');
              }
            }
          }
        }
      }
    }
Gnotobiotics answered 4/7, 2017 at 12:6 Comment(0)
O
3

This is not actually adding the CSS to the cell, but gives the same effect. While providing the same result as others above, this version is a little more intuitive to me, but I'm a novice, so take it for what it's worth:

$(".hoverCell").bind('mouseover', function() {
    var old_color = $(this).css("background-color");
    $(this)[0].style.backgroundColor = '#ffff00';

    $(".hoverCell").bind('mouseout', function () {
        $(this)[0].style.backgroundColor = old_color;
    });
});

This requires setting the Class for each of the cells you want to highlight to "hoverCell".

Orangutan answered 5/6, 2016 at 19:57 Comment(0)
D
3

You can make a CSS variable, and then change it in JS.

:root {
  --variableName: (variableValue);
}

to change it in JS, I made these handy little functions:

var cssVarGet = function(name) {
  return getComputedStyle(document.documentElement).getPropertyValue(name);
};

and

var cssVarSet = function(name, val) {
  document.documentElement.style.setProperty(name, val);
};

You can make as many CSS variables as you want, and I haven't found any bugs in the functions; After that, all you have to do is embed it in your CSS:

table td:hover {
  background: var(--variableName);
}

And then bam, a solution that just requires some CSS and 2 JS functions!

Dicky answered 21/5, 2020 at 23:28 Comment(0)
L
2

I had this need once and created a small library for, which maintains the CSS documents

https://github.com/terotests/css

With that you can state

css().bind("TD:hover", {
        "background" : "00ff00"
    });

It uses the techniques mentioned above and also tries to take care of the cross-browser issues. If there for some reason exists an old browser like IE9 it will limit the number of STYLE tags, because the older IE browser had this strange limit for number of STYLE tags available on the page.

Also, it limits the traffic to the tags by updating tags only periodically. There is also a limited support for creating animation classes.

Lorrianelorrie answered 3/9, 2016 at 10:52 Comment(0)
S
2

Declare a global var:

var td

Then select your guiena pig <td> getting it by its id, if you want to change all of them then

window.onload = function () {
  td = document.getElementsByTagName("td"); 
}

Make a function to be triggered and a loop to change all of your desired td's

function trigger() {
    for(var x = 0; x < td.length; x++) { 
      td[x].className = "yournewclass"; 
    }
}

Go to your CSS Sheet:

.yournewclass:hover { background-color: #00ff00; }

And that is it, with this you are able to to make all your <td> tags get a background-color: #00ff00; when hovered by changing its css propriety directly (switching between css classes).

Skillern answered 23/10, 2017 at 21:45 Comment(1)
I just applied this model on my SoloLearn playrground website, check by yourself and see how it works: code.sololearn.com/WEtMpJ0mwFAD/#jsSkillern
R
2

For myself, I found the following option: from https://mcmap.net/q/152016/-how-to-set-input-focus-style-programatically-using-javascript

const el = document.getElementById('elementId');
el.style.setProperty('--focusHeight', newFocusHeight);
el.style.setProperty('--focusWidth', newFocusWidth);
.my-class {
  --focusHeight: 32px;
  --focusWidth: 256px;
}

.my-class:focus {
  height: var(--focusHeight);
  width: var(--focusWidth);
}
Rampageous answered 4/5, 2022 at 7:49 Comment(0)
R
1

Had some same problems, used addEventListener for events "mousenter", "mouseleave":

let DOMelement = document.querySelector('CSS selector for your HTML element');

// if you want to change e.g color: 
let origColorStyle = DOMelement.style.color;

DOMelement.addEventListener("mouseenter", (event) => { event.target.style.color = "red" });

DOMelement.addEventListener("mouseleave", (event) => { event.target.style.color = origColorStyle })

Or something else for style when cursor is above the DOMelement. DOMElement can be chosen by various ways.

Roebuck answered 20/2, 2021 at 21:21 Comment(1)
Sorry, did not think it over first. You should also add an other event, when mouse leaves, and if you want to revert back the orig stly, one way, to save it in a variableRoebuck
A
1

I was researching about hover, to be able to implement them in the button label and make the hover effect

<button type="submit"
        style=" background-color:cornflowerblue; padding:7px; border-radius:6px"
        onmouseover="this.style.cssText ='background-color:#a8ff78; padding:7px; border-radius:6px;'"
        onmouseout="this.style.cssText='background-color:cornflowerblue; padding:7px; border-radius:6px'"
        @click="form1()">
        Login
</button>
Altair answered 20/2, 2022 at 21:56 Comment(0)
W
1
    const tds = document.querySelectorAll('td');
    tds.forEach((td,index) => {
      td.addEventListener("mouseover", ()=>hover(index))
      td.addEventListener("mouseout", ()=>normal(index))
    });
    function hover(index){
      tds[index].style.background="red";
    }
    function normal(index){
      tds[index].style.background="yellow";
    }

Try this code it will work fine .

Workshop answered 21/12, 2022 at 2:6 Comment(1)
While this answer probably has a similar effect, it does not answer the OP's Q. The Q is how to change the property of the :hover pseudo class. Your code changes the background color of the "un-pseudoed" element.Spinneret
I
0

You can create a class in css

.hover:hover {
    background: #ff0000;
}

and then add it dynamically

const columns = document.querySelectorAll('table td');

for (let i = 0; i < columns.length; i++) {
   columns[i].classList.add('hover');
}

But your css and js files should be connected in index.html

Insurrection answered 23/2, 2022 at 10:0 Comment(0)
V
-1

If you use lightweight html ux lang, check here an example, write:

div root
 .onmouseover = ev => {root.style.backgroundColor='red'}
 .onmouseleave = ev => {root.style.backgroundColor='initial'}

The code above performes the css :hover metatag.

Valarievalda answered 9/7, 2020 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.