skip to Main Content

I’m a beginner in javascript and I create a simple project to understand DOM
style but faced with a problem. there is a p tag with a red background color and blue
color hover effect. I put an onclick event on the p that when user clicks on the p,
its background color changes to orange. the problem is when the background color
changes with onclick event, the hover effect will be useless then.
so is there any problem or this is the routine behavior of javascript?

<html>

<head>
  <style>
    #p2 {
      background-color: red;
    }
    
    #p2:hover {
      background-color: blue;
    }
  </style>
</head>

<body>
  <p id="p2" onclick="test()"> text </p>
  <script>
    function test() {
      document.getElementById("p2").style.backgroundColor = "orange";
    }
  </script>
</body>

</html>

I searched in Stackoverflow but unfortunately, these similar questions
1
and 2
didn’t help.

5

Answers


  1. This is routine behavior of JavaScript.

    When you change the background color of an element using JavaScript like: document.getElementById("p2").style.backgroundColor = "orange"
    it directly modifies the inline style of that element which takes precedence over any styles defined in the CSS, including the hover effect.

    Here’s a list if CSS Specificity Hierarchy.

    Login or Signup to reply.
  2. Because inline styles have higher specificity, it will override your css properties. You can counteract this by adding !important to your hover style:

    <html>
    
    <head>
      <style>
        #p2 {
          background-color: red;
        }
        
        #p2:hover {
          background-color: blue !important;
        }
      </style>
    </head>
    
    <body>
      <p id="p2" onclick="test()"> text </p>
      <script>
        function test() {
          document.getElementById("p2").style.backgroundColor = "orange";
        }
      </script>
    </body>
    
    </html>
    Login or Signup to reply.
  3. My recommendation is to define the classes with the same priority to prevent using !important; (that could generate other problems)

    <html>
    
    <head>
      <style>
        #p2.red {
          background-color: red;
        }
    
        #p2.orange {
          background-color: orange;
        }
        
        #p2:hover {
          background-color: blue;
        }
      </style>
    </head>
    
    <body>
      <p id="p2" class="red" onclick="test()"> text </p>
      <script>
        function test() {
          document.getElementById("p2").classList.toggle("orange");
        }
      </script>
    </body>
    
    </html>
    Login or Signup to reply.
  4. You can use CSS variables to change the :hover colour.

    :root{--clr:#0000ff;}
    

    sets the initial colour,

    background-color: var(--clr);
    

    assigns the variable to the background-color style.

    document.querySelector(':root').style.setProperty('--clr','orange');
    

    then changes the variable from JavaScript.

    <html>
    
    <head>
      <style>
    
        :root{
          --clr:#0000ff;
        }
    
        #p2 {
          background-color: red;
        }
        
        #p2:hover {
          background-color: var(--clr);
        }
      </style>
    </head>
    
    <body>
      <p id="p2" onclick="test()"> text </p>
      <script>
        function test() {
         document.querySelector(':root').style.setProperty('--clr','orange');
        }
      </script>
    </body>
    
    </html>
    Login or Signup to reply.
  5. The problem here is due to inline styles having the highest specificity. There are many solutions for this, using !important is generally a bad method of solving it as its difficult to work with the bigger the project gets and various other reasons.

    As a beginner now is the time to get into good habits. So for my answer, I got rid of both your inline onclick and your inline style change.

    I’m using an event listener and querySelector to target your paragraph.

    Then I’m adding a class to that element (you can use toggle to add/remove on click too).

    For the CSS, I target the element via #p2.orange (orange is my class name). And I place it ABOVE the hover in the CSS itself.

    const p = document.querySelector("#p2");
    
    p.addEventListener("click",() => {
      p.classList.add("orange");
    });
    #p2 {
      background-color: red;
    }
    
    #p2.orange{
      background-color:orange;
    }
    
    #p2:hover {
      background-color: blue;
    }
    <p id="p2"> text </p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search