Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collapsible navbar #40

Open
ekstroem opened this issue Mar 13, 2016 · 4 comments
Open

Collapsible navbar #40

ekstroem opened this issue Mar 13, 2016 · 4 comments

Comments

@ekstroem
Copy link

This is not a bug but more like a feature/enhancement request. I'm still trying to tweak my pages and have run into this minor issue:

I'd like to have a collapsible navbar.

Currently the navigation bar is created from the site.pages and while the tex size scales with device/media size it is not uncommon to get something that is wider that a single line if there are more than a few pages in the menu.

If the text width becomes too large then I'd like either all the menu items (besides the site name) to collapse or just the ones that there aren't room for.

For starters I moved the navigation part to a separate file _includes/nav.html (shown below)

<header>
<nav id="menu">
<ul>
<li><a href="{{site.baseurl}}/">sitename</a></li>
{% for node in site.pages %}{% unless node.nav_exclude %}{% if page.url == node.url %}
<li><a class="active" href="{{node.url | prepend: site.baseurl}}">{{node.title}}</a> </li>
{% else %}
<li><a href="{{node.url | prepend: site.baseurl}}">{{node.title}}</a></li>
{% endif %}{% endunless %}{% endfor %}
</ul>
</nav>
</header>

where the menu items are items in an unordered list. Now I found some previous code to work as a collapsible navbar. Here's the part of the script that does all the computation with the width of the menu bar entries and moves them back and forth between being hidden (included as part of the footer).

/*--------------------------------------------------
Hidden Nav
--------------------------------------------------*/
hiddenNavBar = {
    $menu: $('#menu'),
    init: function () {
        this.resize();
        $('<div id="on-hidden-menu"><div class="toggle"><span></span></div><ul></ul></div>').hide().insertAfter(this.$menu);
        // toggle
        $('#on-hidden-menu .toggle').click(function () {
                                                  $('#on-hidden-menu').toggleClass('open');
                                              });

        // win load & resize
        $(window).on('load resize', function () {
                         hiddenNavBar.resize();
                     });
    },
    resize: function () {
        setTimeout(function () {
                          var menuWidth = $('ul', this.$menu).width() + 60;
                          var winW = $(window).width();

                          console.log(menuWidth, winW);

                          if (menuWidth > winW) {
                              console.log('init');

                              $('#on-hidden-menu').show();
/*                            $clone = $('li:not(".on-hidden"):last', this.$menu).addClass('on-hidden').clone(); */
                              $clone = $('#menu li:not(".on-hidden"):last', this.$menu).addClass('on-hidden').clone();
                              if ($clone.parent().size() == 0) {
                                  $clone.prependTo($('#on-hidden-menu ul'));
                              }

                              hiddenNavBar.resize();
                              /** this.menu */
                          } else if (menuWidth + $('li.on-hidden:first').width() < winW) {
                              $('li.on-hidden:first').removeClass('on-hidden');
                              $('#on-hidden-menu ul li:first').remove();
                          }

                          if ($('.on-hidden').size() == 0) {
                              $('#on-hidden-menu').removeClass('open').hide();
                          }
                      }, 10);
    }
};


/*--------------------------------------------------
DOC READY
--------------------------------------------------*/
$(function () {
         hiddenNavBar.init();
     })

and then there's the corresponding css file information (included in the header).

/*--------------------------------------------------
Nav
--------------------------------------------------*/

header {
padding: 15px 5px;
position: relative;
z-index: 1;
}

body.full-width > header {
}

#menu {
white-space:nowrap;
position: relative;
z-index: 1;
width: auto;
}

#menu ul {
list-style: none;
list-style-type: none;
margin: 0;
padding: 0;
white-space: nowrap;
display: inline-block;
}

#menu ul li {
display: inline-block;
position: relative;
}

#menu ul li a {
text-decoration: none;
padding: 0.7em;
}

/*--------------------------------------------------
On Hidden Menu
--------------------------------------------------*/


#menu ul li.on-hidden { display: none; }

#on-hidden-menu {
display: block;
position: absolute;
z-index: 10;
right: 0;
margin-top: 15px;
min-width: 280px;
}

#on-hidden-menu ul {
margin: 0;
padding: 0;
list-style: none;
position: relative;
overflow: hidden;
height: 0;
}

#on-hidden-menu li {
background: #30424d;
border-bottom: 1px solid #273640;
opacity: 0;
-moz-transition: all .4s ease-in-out .2s;
-o-transition: all .4s ease-in-out .2s;
-webkit-transition: all .4s ease-in-out .2s;
transition: all .4s ease-in-out .2s;
position: relative;
}

#on-hidden-menu li a {
color: rgba(255,255,255,.9);
text-decoration: none;
padding: 10px 15px;
display: block;
}

#on-hidden-menu li a:hover { background: #354C5A; }

/* on hidden menu open */


#on-hidden-menu.open ul {
display: block;
height: 100%;
}

#on-hidden-menu.open ul li {
    opacity: 1;
}


#on-hidden-menu.open ul li:last-child {
    border-bottom-left-radius: 5px;
}

/* toggle */

#on-hidden-menu .toggle {
width: 32px;
position: absolute;
top: -42px;
right: 10px;
height: 32px;
background-color: #f73a14;
z-index: 1;
cursor: pointer;
border-radius: 2px;
}

#on-hidden-menu .toggle:before, #on-hidden-menu .toggle:after,
#on-hidden-menu .toggle span:before {
content: '';
width: 4px;
height: 4px;
background: #fff;
border-radius: 5px;
position: absolute;
top: 17px;
left: 5px;
-moz-transition: all .4s ease-in-out;
-o-transition: all .4s ease-in-out;
-webkit-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}

#on-hidden-menu .toggle:after {
left: 13px;
-moz-transition-delay: .1s;
-o-transition-delay: .1s;
-webkit-transition-delay: .1s;
transition-delay: .1s;
}

#on-hidden-menu .toggle span:before {
left: 21px;
-moz-transition-delay: .2s;
-o-transition-delay: .2s;
-webkit-transition-delay: .2s;
transition-delay: .2s;
}

/* close */


#on-hidden-menu.open .toggle:before, #on-hidden-menu.open .toggle:after {
width: 20px;
-moz-transform: rotate(225deg);
-ms-transform: rotate(225deg);
-o-transform: rotate(225deg);
-webkit-transform: rotate(225deg);
transform: rotate(225deg);
top: 14px;
height: 3px;
}

#on-hidden-menu.open .toggle:after {
-moz-transform: rotate(-225deg);
-ms-transform: rotate(-225deg);
-o-transform: rotate(-225deg);
-webkit-transform: rotate(-225deg);
transform: rotate(-225deg);
left: 5px;
-moz-transition-delay: .0s;
-o-transition-delay: .0s;
-webkit-transition-delay: .0s;
transition-delay: .0s;
}

#on-hidden-menu.open .toggle span:before {
top: 14px;
left: 13px;
width: 2px;
height: 2px;
-moz-transition-delay: .0s;
-o-transition-delay: .0s;
-webkit-transition-delay: .0s;
transition-delay: .0s;
}

Okay. So far so good. Then I want to fix the nav.html so it matches the collapsible code (forget about the aesthetics here for now - it's not a beauty but that could be fixed). I add the ID's to nav.html

<header>
<nav id="menu">
<ul id="menu">
<li><a href="{{site.baseurl}}/">sandsynlig<b>vis</b>.dk</a></li>
{% for node in site.pages %}{% unless node.nav_exclude %}{% if page.url == node.url %}
<li><a class="active"  id="menu" href="{{node.url | prepend: site.baseurl}}">{{node.title}}</a> </li>
{% else %}
<li><a id="menu" href="{{node.url | prepend: site.baseurl}}">{{node.title}}</a></li>
{% endif %}{% endunless %}{% endfor %}
</ul>
</nav>
</header>

which makes the collapsible navbar function. Sort or anyway. The width calculation is not working perfectly and the menu item pops in and out of existence until there's two items in the hidden part of the menu. Can anyone help with this and/or would help make it blend in with the rest of the Tufte-CSS format?

I can set up a (version) of the page so you can see what is wrong, but I haven't pushed it to the official server since it isn't working.

@ekstroem
Copy link
Author

Okay. I did a bit of tweaking and seems to have it almost working. You can see a working example here. There's still a few corrections to be made to make it blend in completely but it's somewhat acceptable as it is.

I can write it up in case anyone else would be of interest.

@clayh53
Copy link
Owner

clayh53 commented Apr 4, 2016

I haven't had time to look at this, but at first glance this seems like a good idea, particularly for the smaller device width use cases. If it can be easily added I will add it to the repo.

@ekstroem
Copy link
Author

ekstroem commented Apr 4, 2016

Want me to try to extract the necessary bits and put them into a pull request?

@clayh53
Copy link
Owner

clayh53 commented Apr 4, 2016

That would be great if it wont chew up too much of your time.

Thanks

Sent using 100% all-natural biodynamic electrons

On Apr 4, 2016, at 7:17 PM, Claus Ekstrøm [email protected] wrote:

Want me to try to extract the necessary bits and put them into a pull request?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants