SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,401
    Mentioned
    147 Post(s)
    Tagged
    4 Thread(s)

    Responsive design problem - showing hiding with media query

    I'm posting this in the CSS forum, but I'm actually not sure if that's right. It might be CSS, or CSS and HTML, or javascript, no idea.

    I'm working on a responsive design, and the media queries work great. I can change styles and layout as needed.
    But now I'm trying to make the top menu bar become a button for mobile screens, and use javascript to toggle the div with the menu options between hidden and visible.
    Works fine also.

    The problem is when resizing the window.
    1) As long as I don't click the button, when I go from "big" to "small" the menu bar disappears and the button appears, and when I go from "small" to "big" the button disappears and the menubar appears. Fine.
    2) As long as I stay "small" and click the button, the menu bar appears/disappears. Perfect.
    3) But when I'm "small" and start clicking the button, and then resize the window back to "big", if the menu bar is hidden, it doesn't reappear! Oops.

    It seems like changing the display style with javascript messes up the changing of display style with media queries.

    I've searched, but didn't find any working solutions. This stuff (JS) seems to work only in FF.

    Is there a CSS solution? Or do I have to move the question to the JS forum?

    Here is the code:
    Code HTML4Strict:
    <div class="navbar">
     
      <a class="brand" href="#">
        <img src="img/logo.png" />
      </a>
     
      <a class="btn btn-navbar" href="javascript:togglediv('navigation');">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
     
      <div id="navigation" class="nav-collapse collapse">
        <ul class="nav-list">
          <li><a href="#home">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#updates">Updates</a></li>
          <li><a href="#screenshots">Screenshots</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </div>
     
      <div class="clear"></div>
    </div>
    main css
    Code CSS:
    .navbar .btn-navbar {
      display:none;
    }
    media query
    Code CSS:
    @media screen and (max-width: 700px) {
     
    .navbar .btn-navbar {
      display:inherit!important;
    }
     
    .navbar .nav-collapse {
      display:none;
    }
     
    }
    Code JavaScript:
      function togglediv(divname) {
        var mydiv = document.getElementById(divname);   
        if(mydiv.style.display == "block") {
          mydiv.style.display = "none";
        } else {
          mydiv.style.display = "block";
        }
      }

  2. #2
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,809
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    Hi,

    The js writes an inline style into the element (style="display:block" or style="display:none") which means that your css will be over-ridden.

    You could instead add a class to the element with js to determine the state.

    e.g.
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Untitled Document</title>
    <style>
    .navbar .btn-navbar { display:none; }
    .nav-off{display:block!important}
    
    @media screen and (max-width: 700px) {
    .navbar .btn-navbar {display:block;}
    .navbar .nav-collapse { display:none; }
    .nav-off{display:none!important}
    }
    </style>
    </head>
    
    
    <body>
    <div class="navbar"> <a class="brand" href="#"> <img src="img/logo.png" /> </a> <a class="btn btn-navbar" href="javascript:togglediv('navigation');">hello <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a>
    		<div id="navigation" class="nav-collapse" >
    				<ul class="nav-list">
    						<li><a href="#home">Home</a></li>
    						<li><a href="#about">About</a></li>
    						<li><a href="#updates">Updates</a></li>
    						<li><a href="#screenshots">Screenshots</a></li>
    						<li><a href="#contact">Contact</a></li>
    				</ul>
    		</div>
    </div>
    <script type="text/javascript">
      function togglediv(divname) {
        var mydiv = document.getElementById(divname);   
        if(mydiv.style.display == "block") {
          mydiv.style.display = "none";
    						mydiv.className+=" nav-off";
        } else {
          mydiv.className=mydiv.className.replace(new RegExp(" nav-off\\b"), "");
    						mydiv.style.display = "block";
        }
      }	
    	
    </script>
    </body>
    </html>
    Does that do what you wanted?

  3. #3
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,401
    Mentioned
    147 Post(s)
    Tagged
    4 Thread(s)
    Thanks a lot Paul. I had to tweak it a bit, but your explanation pointed me in the right direction, and I got it to work.

  4. #4
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,233
    Mentioned
    47 Post(s)
    Tagged
    1 Thread(s)
    Just keep your sanity by realising that, unless by large and small you are getting hit by phones or tablets changing orientation, most small devices won't start getting larger to trigger the problem (except for web developers, who like squishing and growing responsive pages for testing etc).

  5. #5
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,401
    Mentioned
    147 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    Just keep your sanity by realising that, unless by large and small you are getting hit by phones or tablets changing orientation, most small devices won't start getting larger to trigger the problem (except for web developers, who like squishing and growing responsive pages for testing etc).
    I know.
    But if for some reason someone squishes his browser window for a moment, and then when he re-expands it the menu doesn't show up anymore, that would be bad publicity
    It just has to work. And now it does.

  6. #6
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    23,598
    Mentioned
    411 Post(s)
    Tagged
    7 Thread(s)
    Off Topic:

    Quote Originally Posted by guido2004 View Post
    Thanks a lot Paul. I had to tweak it a bit, but your explanation pointed me in the right direction, and I got it to work.
    It would be interesting to see your solution, if it can be reduced to a simple example.

  7. #7
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,401
    Mentioned
    147 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by ralph.m View Post
    It would be interesting to see your solution, if it can be reduced to a simple example.
    Of course

    Code HTML4Strict:
    <div class="navbar">
     
      <a class="brand" href="#">
        <img src="img/logo.png" />
      </a>
     
      <a class="btn btn-navbar" href="javascript:togglediv('navigation');">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>
     
      <div id="navigation" class="nav-collapse">
        <ul class="nav-list">
          <li><a href="#home">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#updates">Updates</a></li>
          <li><a href="#screenshots">Screenshots</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </div>
     
      <div class="clear"></div>
    </div>
    main CSS
    Code CSS:
    .navbar .btn-navbar {
    	display:none;
    }
    media query
    Code CSS:
    @media screen and (max-width: 700px) {
     
    .navbar .btn-navbar {
      display:inherit!important;
    }
     
    .navbar .nav-collapse {
      display:none;
    }
     
    .nav-on {
      display:block!important;
    }
     
    }
    javascript
    Code JavaScript:
      function togglediv(divname) {
        var mydiv = document.getElementById(divname);   
        var pattern = new RegExp("(^| )" + 'nav-on' + "( |$)");
        if(pattern.test(mydiv.className)) {
          mydiv.className=mydiv.className.replace(new RegExp(" nav-on\\b"), "");
        } else {
          mydiv.className+=" nav-on";
        }
      }

  8. #8
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,233
    Mentioned
    47 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Guido
    <a class="btn btn-navbar" href="javascript:togglediv('navigation');">
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    </a>
    Since without hitting this toggle button, the whole ul remains unavailable to screen readers and other AT, I would put some text in that anchor stating what it does ("toggle menu" or similar) to make this whole setup work a little better.
    Some tweets from Marco Zehe (Mozilla a11y developer):
    Anchors
    nowadays
    suck

    And Twitter Bootstrap not only encourages bad code (the examples on the http://twitter.github.com/bootstrap/ site) but seems to even be going out of its way to make sure stuff is broken and inaccessible by default (when I used Bootstrap, I rewrote large parts of it to make it actually work with keyboard and give clickable areas access points and actual text... le sigh).

    I actually don't mind the display: none/block setup for large menus (instead of the usual pulling offscreen or clipping), since when it's display: none you can very easily skip over it, especially nice when sighted and using the keyboard, but then the CSS can't be display: none by default (if the JS breaks or isn't there, stuff's not available by default), and the toggle has to work everywhere for everyone.

    So for example for a dropdown I made it display normally by default, and had JS add in the class with the display: none styles and also add in the anchor (no point in having an anchor who does nothing, unless there's already Javascript working).

  9. #9
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    23,598
    Mentioned
    411 Post(s)
    Tagged
    7 Thread(s)
    Thanks, Guido ... and interesting followup, poes.

  10. #10
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,233
    Mentioned
    47 Post(s)
    Tagged
    1 Thread(s)

  11. #11
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    23,598
    Mentioned
    411 Post(s)
    Tagged
    7 Thread(s)
    Pugh ... I always drag from the bottom right corner.

  12. #12
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    39,809
    Mentioned
    158 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    lol - It's easy to make it responsive when there's no content in the page

  13. #13
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,233
    Mentioned
    47 Post(s)
    Tagged
    1 Thread(s)
    low-content pages ftw


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •