skip to Main Content

I am building a Dash web app with two tabs, a map and a FAQ tab. It looks like this:
dash app image

As you see I have defined a navbar to navigate through the tabs, it works as expected. It is defined as follows:

dbc.Navbar(
    dbc.Container(
        children=[
            dbc.NavbarToggler(id='navbar-toggler', n_clicks=0),
            dbc.Collapse(
                dbc.Nav(
                    [
                        dbc.NavItem(
                            dbc.NavLink(
                                'Map',
                                href='/',
                                class_name='map-navlink',
                                id='map-navlink'
                            )
                        ),
                        dbc.NavItem(
                            dbc.NavLink(
                                'FAQ',
                                href='/faq',
                                class_name='faq-navlink',
                                id='faq-navlink'
                            )
                        )
                    ]
                ),
                id='navbar-collapse',
                navbar=True
            ),
        ],
        fluid=True,
        class_name='navbar'
    ),
    color='dark',
    dark=True
)

What I want to achieve now is to change the style of the tab the user is looking. I have already achieved through CSS that the styles are changed when the user clicks the navbar item. The CSS I used is as follows.

.map-navlink {
    color: white;
    margin-left: 0.5vw;
}
.map-navlink:focus {
    color: #26BF64;
    background-color: grey;
}
.map-navlink:hover {
    color: #26BF64;
}


.faq-navlink {
    color: white;
    margin-left: 0.5vw;
}
.faq-navlink:focus {
    color: #26BF64;
    background-color: grey;
}
.faq-navlink:hover {
    color: #26BF64;
}

With this CSS, when a user clicks the Map navlink or the FAQ navlink the styles are correctly changed. However, when they click anywhere else the styles are reverted to their original state. Apart from that, I would also like that when the dash app is first loaded the style of the Map navlink is also changed.

I have already found this 3 SO questions:

Keep style of button after click

How to keep focuse css style after clicking a button (the style disappears after clicking anywhere)

keep focus of css style even if other button clicked

But I can’t seem to make it work.

Can anyone help me?

This is my first posted question here so I apologize in advance if I have made any mistakes. If more information is needed please ask for it and I will happily provide it.

Thank you very much in advance 🙂

2

Answers


  1. Chosen as BEST ANSWER

    I have finally achieved what I wanted and it was much simpler than what I thought. I have just added the parameter active='exact' in both Navlinks as follows:

    dbc.NavItem(
        dbc.NavLink(
            'Mapa',
            href='/',
            class_name='map-navlink',
            id='map-navlink',
            active='exact' # This is new
        )
    ),
    dbc.NavItem(
        dbc.NavLink(
            'FAQ',
            href='/faq',
            class_name='faq-navlink',
            id='faq-navlink',
            active='exact' # This is new
        )
    )
    

    And once that is done I changed my CSS styles as follows:

    .map-navlink.active {
        color: #26BF64 !important;
        background-color: grey;
    }
    
    .faq-navlink.active {
        color: #26BF64 !important;
        background-color: grey;
    }
    

    I needed to add the !important because Dash adds some parent classes to the Navlink and it inherits attributes from them (color being one of them), thus my styles were not being correctly applied.

    With that changes my dash web-app works as expected.


  2. You could use javascript to toggle a css class

    Example:

    const navLinks = document.querySelectorAll("nav > a[data-class]");
    const sections = document.querySelectorAll("main > section[class]");
    
    navLinks.forEach(navLink =>
      navLink.addEventListener("click", () => {
        sections.forEach(sec => sec.classList.toggle("active", sec.classList.contains(navLink.dataset.class)));
        navLinks.forEach(link => link.classList.toggle("active", navLink == link));
      })
    );
    main > section{
      background-color: #ddd;
      box-sizing: border-box;
      padding: 1rem;
    }
    main > section:not(.active){
      display: none;
    }
    nav > a{
      padding: .5rem;
      display: inline-block;
      cursor: pointer;
    }
    nav > a.active{
        background-color: lightblue;
    }
    <nav>
      <a data-class="home" class="active">Home</a>
      <a data-class="about">About</a>
    </nav>
    <main>
      <section class="home active">
        Home content
      </section>
      <section class="about">
        About content
      </section>
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search