4

I have a navigation menu which changes color when you have the mouse over one of the links/elements in the menu. Each link / list item runs a javascript function when you click on it which will hide som content and some other content will be displayed on the page. At the same time, the background color changes for the page / link which you are visiting. It works as it should but the problem is that once you have clicked on one of the links, the css code ul.nav li:hover does not work anymore.

Here is my code so far:

    function show_page1() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: none";
        page1.style = "display: block";

        page1_Link.style = "background-color: #008CBA";
        page2_Link.style = "background-color: #f3f3f3";
    }

    function show_page2() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: block";
        page1.style = "display: none";

        page1_Link.style = "background-color: #f3f3f3";
        page2_Link.style = "background-color: #008CBA";
    }
       ul.nav {
            list-style-type: none;
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f3f3f3;;
            line-height: 1.5;
        }

        ul.nav li {
            float: left;
            display: inline-block;
            text-align: center;
            padding: 14px 16px;
            text-decoration: none;
        }

        ul.nav li:hover {
            background-color: lightgrey;
            cursor: pointer;
        }

        #page1_link {
            background-color: #008CBA;
        }

        #page2 {
            display:none;
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <nav>
        <ul class="nav">
            <li id="page1_link" onclick="show_page1()">page 1</li>
            <li id="page2_link" onclick="show_page2()">page 2</li>
        </ul>
    </nav>

    <div id="page1">
        Page 1
    </div>

    <div id="page2">
        Page 2
    </div>
</body>
</html>
user3740970
  • 389
  • 1
  • 3
  • 16

1 Answers1

2

It's a matter of specificity.

When you use :hover, the style is applied when the mouse is over the element. But the new style is just applied as it was just plain CSS, it won't substitute the current style.

In this case, you have your hover style in the following selector:

ul.nav li

They are 2 tagname selectors + 1 class selector, its sepcificity is 0 1 2

But the background color is given by the following selector:

#page1_link

It is just an id, its specificity is 1 0 0, which is higher.

So even if the two styles are applied together on hover, the second one "wins" and you don't see the effect.

To solve the problem, you need to give a higher specificity to your element, or (not advised) use !important.

I show you both examples:

Example with higher specificity:

function show_page1() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: none";
        page1.style = "display: block";

        page1_Link.style = "background-color: #008CBA";
        page2_Link.style = "background-color: #f3f3f3";
    }

    function show_page2() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: block";
        page1.style = "display: none";

        page1_Link.style = "background-color: #f3f3f3";
        page2_Link.style = "background-color: #008CBA";
    }
ul.nav {
            list-style-type: none;
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f3f3f3;;
            line-height: 1.5;
        }

        ul.nav li {
            float: left;
            display: inline-block;
            text-align: center;
            padding: 14px 16px;
            text-decoration: none;
        }
        /* example with higher specificity: id in place of class */
        #page1_link:hover {
            background-color: lightgrey;
            cursor: pointer;
        }

        #page1_link {
            background-color: #008CBA;
        }

        #page2 {
            display:none;
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <nav>
        <ul class="nav">
            <li id="page1_link" onclick="show_page1()">page 1</li>
            <li id="page2_link" onclick="show_page2()">page 2</li>
        </ul>
    </nav>

    <div id="page1">
        Page 1
    </div>

    <div id="page2">
        Page 2
    </div>
</body>
</html>

Example with !important:

function show_page1() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: none";
        page1.style = "display: block";

        page1_Link.style = "background-color: #008CBA";
        page2_Link.style = "background-color: #f3f3f3";
    }

    function show_page2() {
        let page1 = document.querySelector("#page1");
        let page2 = document.querySelector("#page2");
        let page1_Link = document.querySelector("#page1_link");
        let page2_Link = document.querySelector("#page2_link");

        page2.style = "display: block";
        page1.style = "display: none";

        page1_Link.style = "background-color: #f3f3f3";
        page2_Link.style = "background-color: #008CBA";
    }
ul.nav {
            list-style-type: none;
            margin: 0;
            padding: 0;
            overflow: hidden;
            background-color: #f3f3f3;;
            line-height: 1.5;
        }

        ul.nav li {
            float: left;
            display: inline-block;
            text-align: center;
            padding: 14px 16px;
            text-decoration: none;
        }

        /* example with !important */
        ul.nav li:hover {
            background-color: lightgrey !important;
            cursor: pointer;
        }

        #page1_link {
            background-color: #008CBA;
        }

        #page2 {
            display:none;
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <nav>
        <ul class="nav">
            <li id="page1_link" onclick="show_page1()">page 1</li>
            <li id="page2_link" onclick="show_page2()">page 2</li>
        </ul>
    </nav>

    <div id="page1">
        Page 1
    </div>

    <div id="page2">
        Page 2
    </div>
</body>
</html>
  • but I have still have the same problem – user3740970 Apr 07 '19 at 21:32
  • I've put two working snippets where the `:hover` style is applied - even after a click – Christian Vincenzo Traina Apr 07 '19 at 21:34
  • @user3740970 I'm sorry but the first snippet isn't actually working. That happens because you set the style via the `style` property in js, which is equivalent to `
    ` and this has the highest specificity, only `!important` has higher specificity. I advise you to don't use `style.backgroundColor` but just apply class through js
    – Christian Vincenzo Traina Apr 08 '19 at 07:30