2

Objective: Change the properties of CSS Stylesheet instead of HTML CSS using Javascript.

Current Issue: using document.getElementById("foo").style.display = "none" causes changes in HTML document that removes Media Query functionality

My website has a button that changes the display of a sidenav bar on smaller screens. This button is not available on screen sizes greater than 768px. The website is dynamic, so the button shows up when the screen is small enough. When the button is clicked, the sidenav (initially set to display:none), is set to display:block, which can then be closed again.

Once the sidenav is closed in a screensize < 768px, and the screen is increased to a size > 768px, the media query no longer changes the display to block because the Javascript changes the HTML, which overwrites the CSS media query.

Below is the code and changes the Javascript does to the HTML.

HTML Before:

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

<!-- button to change sidenav -->
<div id="menu-button" onclick="openCloseNav(this)"></div>

Javascript

function openCloseNav(x){
    if(x.classList != "change"){
        document.getElementById("sidenav").style.display = "none";
    }
    else{
        document.getElementById("sidenav").style.display = "block";
    }
}

CSS

#sidenav{
    display:none;
}
@media only screen and (min-width: 768px){
    #sidenav{
        display:block
    }
}

HTML After div id="menu-button" is clicked twice

<div id="sidenav" style="display:none">foo</div>

<!-- button to change sidenav -->
<div id="menu-button" onclick="openCloseNav(this)"></div>

I have tried a few different things such as attempting to detect screenwidth in Javascript like this:

var currentWidth = window.screen.availWidth;

function showSideNav(){
    if (currentWidth >= "768"){
        document.getElementById("sidenav").style.display = "block";
    }
}

to no avail. If the snippet above does work, I don't know where to place it in my HTML.

Question: What can I do to make it so that the sidenav will show even after the menu-button div is clicked on screen sizes > 768px?

3
  • 4
    Instead of using JS to set the display = none, have JS add a class to your element document.getElementById('foo').classList.add('hide') (or whatever you choose to name it), which then answers to the CSS. Allowing you to set media query parameters on that class in accordance to what you want to accomplish. Commented Apr 4, 2018 at 19:36
  • And if you need to affect multiple elements using different rules, then place that class on an element further up, and make according use of descendant selectors in your stylesheet ... body.sidenavShown foo { ... } Commented Apr 4, 2018 at 19:41
  • Thanks @Doug, that worked perfectly. I had to remove display:none from the main #sidenav in my CSS stylesheet and made a .hide-nav class. I suppose I could change this to just .hide if I need to hide other things, as well, and just apply for reduced bloat @Scott Marcus suggested. Commented Apr 4, 2018 at 19:51

2 Answers 2

1

Whenever possible, change styling via the addition/removal of CSS classes, rather than affecting the element.style object. This not only makes the code cleaner and reduces code duplication, but it eliminates the issue you are having with the CSS being added directly to the HTML element as an inline style, which is the most specific way to add CSS and difficult to override.

You can easily add/remove/toggle and more with CSS classes with the element.classList API.

Here's a simplified example:

document.querySelector("button").addEventListener("click", function(){
  document.getElementById("element1").classList.add("hidden");
  document.getElementById("element2").classList.remove("special"); 
  
  // Just to show that classList modifications don't alter the inline HTML style
  console.log(document.getElementById("element1"), document.getElementById("element2"));
});
.hidden { display:none; }
.special { background-color:#ff0; color:#800080; }
<div id="element1">Now you see me...</div>
<div id="element2" class="special">Something else</div>
<button>Click to change styles</button>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this worked perfectly, and is a neat trick to reduce bloat and keep my CSS clean.
0

You could use an extra attribute that controls your navbar, so you can use you JavaScript independent of you CSS. I am not sure that the css I put here is correct but I think you get the idea.

EDIT I just noticed thanks to @Doug that you can just use a class instead.

function openCloseNav(x) {
  if (x.classList != "change") {
    document.getElementById("sidenav").setAttribute("hideme", true);
  } else {
    document.getElementById("sidenav").setAttribute("hideme", false);
  }
}
#sidenav[hideme=true] {
  display: none;
}

@media only screen and (min-width: 768px) {
  #sidenav {
    display: block
  }
}
<div id="sidenav">foo</div>

<!-- button to change sidenav -->
<div id="menu-button" onclick="openCloseNav(this)"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.