Off-screen sliding dropdown list over on-screen menu

Hi
Some time back PauolOB helped me with a menu, now I would need to take it a step further, and I am not able to do it.
As of now it is a straight navigation with no sub-links, and I am wondering if it is possible to have dropdowns added to it, with the dropdown to be off-screen, and slide in when hovering the dropdown link.
I have set up a test page here:
ttri dot biz/fz_test/03/
and the following image is what I’d like to achieve:
ttri dot biz/fz_test/03/on-off-screen-menu.jpg
Thank you.

Hi,

I haven’t had time to look at this yet but 2 things strike me immediately. One is that overflow:hidden is being used on each row which means that a dropdown will not show outside of each coloured bar. I will have to look deeper into the code and see if the overflow:hidden is an integral part of the effect or not.

The second issue is that you are placing the dropdown menu inside an anchor and you can’t do that if the dropdown is going to have menu items that need navigation as anchors cannot be nested.

I’m not back at my desk for a couple of hours but I;ll have a closer look them.

Also you need to clarify what triggers the dropdown exactly? Does the coloured bar slide out when you click link 3 and then you want to click the dropdown again to make it slide down? Or do you want the bar to slide out on the one click and then for the dropdown to slide down automatically once the bar has slid out?

This is just rough as I don’t know the exact requirements but it should get the menu showing ok so that you can tweak it as you wish.

.fz-intro-link {
	/*overflow: hidden;*/
	position: relative;
}
.fz-intro-link.with-dropdown {
	z-index:99;
}
#fz-hover-slide-1 {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	/*
	use image instead of color for background
	background: url(../images/image-name.jpg);
	*/
    background: #db0072;
	opacity: 0.7;
	transition: 1s;
}
#fz-hover-slide-2 {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	background: #722ba9;
	opacity: 0.7;
	transition: 1s;
}
#fz-hover-slide-3 {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	background: #541999;
	opacity: 0.7;
	transition: 1s;
}
#fz-hover-slide-4 {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	background: #3f3cad;
	opacity: 0.7;
	transition: 1s;
}
#fz-hover-slide-5 {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	background: #005b9a;
	opacity: 0.7;
	transition: 1s;
}
.fz-hover-slide {
	position: absolute;
	left: -100%;
	width: 100%;
	height: 100%;
	background: #999;
	opacity: 0.5;
	transition: 1s;
}
.fz-intro-link:hover #fz-hover-slide-1, .fz-intro-link:hover #fz-hover-slide-2, .fz-intro-link:hover #fz-hover-slide-3, .fz-intro-link:hover #fz-hover-slide-4, .fz-intro-link:hover #fz-hover-slide-5, .fz-intro-link:hover .fz-hover-slide {
	transition: 1s;
	left: 0;
}
#fz-hover-slide-1, #fz-hover-slide-2, #fz-hover-slide-3, #fz-hover-slide-4, #fz-hover-slide-5 {
	bottom:0;/* was 5px */
	top:0;
	height:auto;
	margin:0;
	padding-top: 9px;
	padding-left: 38px;
}
.navbar-header {
	float: none;
}
.navbar-collapse .navbar-nav.navbar-right:last-child {
	margin-right: 0;
}
.navbar-nav > li {
	float: none;
}
.navbar-nav {
	float: left;
	margin: 0;
	width: 100%;
}
.navbar-collapse {
	max-height: 450px;
	overflow-x: visible;
	padding-left: 0;
	padding-right: 0;
}
.navbar-collapse, .navbar-form {
	border: medium none;
}
.navbar-toggle {
	background-color: #d9d9d9;
	border: 1px solid transparent;
	border-radius: 4px;
	float: right;
	margin-bottom: 9px;
	margin-right: 45px;
	margin-top: 9px;
	padding: 9px;
	position: relative;
	width: 63px;
}
.fz-top-nav .fz-intro-link > a, .fz-top-nav .sidebar-links .link-03 {
	display: block;
	text-decoration: none;
	margin: 0 auto 5px auto;
	padding: 9px 0 9px 19px;
	background-color: #ddd;
	/*text-align: center;*/
	color:  #959595;
	font-size: 12px;
	font-weight: bold;
	border-left-width: 2px;
	border-left-style: solid;
}
.fz-top-nav .sidebar-links a.link-01 {
	border-left: 18px solid #db0078;
}
.fz-top-nav .sidebar-links a.link-02 {
	border-left: 18px solid #722ba8;
}
.fz-top-nav .sidebar-links .link-03 {
	border-left: 18px solid #532099;
	z-index:99;
}
.fz-top-nav .sidebar-links a.link-04 {
	border-left: 18px solid #3f3cad;
}
.fz-top-nav .sidebar-links a.link-05 {
	border-left: 18px solid #005b9a;
}
.drop {
}
.dropdown-menu-fz {
	position:absolute;
	right:0;
	left:50%;
	background-color: #f00;
	top:0;
	opacity:0;
	box-shadow:5px 5px 5px rgba(0,0,0,0.4);
	transition:opacity 1s ease .5s, top 1s ease 1s;
}
.fz-intro-link:hover .dropdown-menu-fz {
	top:100%;
	opacity:1;
	transition:opacity 1s ease .5s, top 1s ease 1s;
}
.dropdown-menu-fz a {
	display:block;
	color:#fff;
	padding:10px;
	text-decoration:none;
}
.dropdown-menu-fz {
	margin:0;
	padding:0;
	list-style:none;
}

Html Changes also:

<div class="container-fluid">
  <div class="row">
    <div class="col-xs-12 col-md-3 fz-nav-column">
      <div class="row fz-logo-language-wrap">
        <div class="col-xs-9 fz-logo"> LOGO image </div>
        <!-- .col-xs-9 .fz-logo -->
        <div class="col-xs-3 fz-lang"> Lang-1
          Lang-2 </div>
        <!-- .col-xs-3 .fz-lang --> 
      </div>
      <!-- .row .fz-logo-language-wrap -->
      <div class="row fz-top-nav">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar toggle-1"></span> <span class="icon-bar toggle-2"></span> <span class="icon-bar toggle-3"></span> <span class="icon-bar toggle-4"></span> <span class="icon-bar toggle-5"></span> </button>
          <a class="navbar-brand" href="index.php">Title</a> </div>
        <!-- .navbar-header -->
        <div class="navbar-collapse collapse">
          <div class="sidebar-links">
            <ul class="nav navbar-nav">
              <li>
                <div class="fz-intro-link"> <a class="link-01 fz-nav-link fz-first-link" href="#">
                  <div id="fz-hover-slide-1"> Link 1 </div>
                  Link 1 </a> </div>
              </li>
              <li>
                <div class="fz-intro-link"> <a class="link-02 fz-nav-link" href="#">
                  <div id="fz-hover-slide-2"> Link 2 </div>
                  Link 2 </a> </div>
              </li>
              <li>
                <div class="fz-intro-link with-dropdown">
                  <div class="link-03 fz-nav-link">
                    <div id="fz-hover-slide-3">
                      <ul class="dropdown-menu-fz" role="menu">
                        <li class="drop"><a href="#">First drop</a></li>
                        <li class="drop"><a href="#">Second drop</a></li>
                        <li class="drop"><a href="#">Third drop</a></li>
                      </ul>
                    </div>
                    Link 3 - Dropdown Menu </div>
                </div>
              </li>
              <li>
                <div class="fz-intro-link"> <a class="link-04 fz-nav-link" href="#">
                  <div id="fz-hover-slide-4"> Link 4 </div>
                  Link 4 </a> </div>
              </li>
              <li>
                <div class="fz-intro-link"> <a class="link-05 fz-nav-link" href="#">
                  <div id="fz-hover-slide-5"> Link 5 </div>
                  Link 5 </a> </div>
              </li>
            </ul>
            <!-- .nav .navbar-nav --> 
          </div>
          <!-- .sidebar-links --> 
        </div>
        <!-- .navbar-collapse .collapse --> 
      </div>
      <!-- .row .fz-top-nav --> 
    </div>
    <!-- .col-xs-12 .col-md-3 .fz-nav-column --> 
    
  </div>
  <!-- .row --> 
</div>
<!-- .container-fluid -->

Requires your bootstrap min css of course.

I didn’t like the duplicate content you were using for the link text when it hovers (and neither will google) so I re-wrote a simpler menu using text-shadow to automatically reproduce the text content.

The html is clean with no extra elements although if you need more function then you may need to use an extra empty nested element or 2 instead the :before and afters that I used.

It should give you some ideas but remember not everything is possible in css alone so you may need to compromise or add a script if the function you want can’t be made to work… :slight_smile:

Thank you.
Excellent, not that I had doubts.
From quick look I think you basically nailed it.

While you were improving the code, I was playing with the former.

I was aware of the anchor issue, and that has been a barrier I could not go over to even try, I had put it so that the (your) original work was clear.

Regarding duplicate link text, how about just removing the text? i.e.

<li>
<div class="fz-intro-link"> <a class="link-01 fz-nav-link fz-first-link" href="#">
<div id="fz-hover-slide-1"></div>
Link 1 </a> </div>
</li>

First version (post #3)
The triggering you decided is just fine, I notice a kind of “you go first, no you go first” situation when you have your cursor over the “link 3”, and go over to lower links (“link 4” and “link 5”), not a “standard” user behaviour, and not an issue, just thought to mention it.
An issue is if I add a second dropdown, the higher dropdown would go behind the lower one please see:
ttri dot biz/fz_test/04/

Second version (post #4)
It seems that the higher (just link 2), and the lower ones (link 4 and 5) would show the dropdown list (sub-menu), when hovering over where the sub-menu is supposed to be hidden (half right of the block, you can see it both at the codepen sample, and here:
ttri dot biz/fz_test/05/

I think I see what you mean and the issue is that the dropdown can’t be on top and beneath the trigger at the same time. If the menu overlaps the items below (or above as in the transition effect) then it would need to disappear as soon as the rows above and below are triggered and you would lose the transition effect when it disappears.

I’ve updated my example to show this in action. (I also tidied up the trigger link for the dropdown so that it stays active while the dropdown is showing. It meant adding a span as :before wouldn’t work here.)

I’m out for the afternoon now but at least it will leave you something to play with :slight_smile:

Thank you.
Indeed I’ll play, and report.

I played with it, and while getting some of it, there is one that I am missing, and that is the slide-out color of each link.
Test page ttri dot biz/fz_test/06/
I removed the background color from the selectors

.slidenav > li > a:before,
.slidenav > li:nth-child(3) > a > span {background:rgba(219, 0 114, 0.3;)}

and put it on two separate ones like

.slidenav > li > a:before {background:rgba(190, 190, 190, 0.7);}
.slidenav > li:nth-child(3) > a > span {background:rgba(83, 32, 153, 0.7);}

I can’t figure out how to differentiate the color for each given link, I tried adding to all the anchors, and also tried different combinations, but no joy.

I think I confused you by trying to make it easier with the span :slight_smile:

I’ve simplified the example and got rid of the span altogether and now they all work with the pseudo elements in the same way so you can easily set up default colours for the sliding blocks and indeed you can change the colour as it slides if you wanted (but I’m guessing you want it to stay the same).

The colours for the sliding background are set up here.

/* default sliding colours*/
.slidenav > li:nth-child(1) > a:before{background:rgba(219, 0, 114, 0.3);}
.slidenav > li:nth-child(2) > a:before{background:rgba(114, 43, 168, 0.3);}
.slidenav > li:nth-child(3) > a:before{background:rgba(83, 32, 153, 0.3)}
.slidenav > li:nth-child(4) > a:before{background:rgba(63, 60, 173, 0.3);}
.slidenav > li:nth-child(5) > a:before{background:rgba(0, 91, 154, 0.3);}

Of course the blocks are invisible (off screen) ro start with so adding a hover colour would not make much sense as the color would start with the hovered colour and then transition back to the other colour on its way out. However the code is commented out and iin place in the demo and you would just need to set the different colour you needed.

The simplified format should make it easier for you to change and colour as you see fit :slight_smile:

1 Like

Thank you.
One last question, when reducing the screen size to trigger the toggle menu, and opening it based on the content of the dropdown (number of subs) a scroll bar displays, I tried to set height:auto for the selectors I thought would work, but apparently I am not getting it.
Is there a way to not have the scroll bar, and in case would that display a long grey area till the dropdown is triggered, 'cause in that case I’d say scroll bar is better?

That seems to be something that is implemented in the bootstrap navbar menu. You can negate it but you need to check whether it has detrimental affects.

.fz-nav-column .navbar-collapse.in{overflow-y:visible}

Paul, If you hover on the bottom right corner, outside of the main UL, the sub-menu opens.

It looks like top:-100% is not quite enough to pull it up out of hover range
If you set the .sub to opacity:1; you can see where it is hanging out enough to trigger the sub ul without even being inside the menu

It looks like top:-200%; gets it back in the main ul when it is hidden

.sub {
	position:absolute;
	right:0;
	left:50%;
	top:-200%; /*pulls it up just enough for 5 sub items*/
	opacity:1;/*reset to '1' to see the problem with -100%*/
	background-color: #f00;
	z-index:-1;
	box-shadow:5px 5px 5px rgba(0,0,0,0.4);
	/* comment the next line out if you want the submenu to disappear quickly */
  transition:opacity 1s ease .1s, top .1s ease .5s;
}

Thank you.
Actually I hadn’t noticed that, probability of hovering just in that spot!
Good to solve it nevertheless.

Anyhow I was referring to this:

Actually, now that I look at it further, I see that top:-200%; will not solve it.
Something like top:-100em; would solve it but it changes the transition behavior.

If your last list-item (Link 5) has a sub-list in it then it will still hang out even further (though un-visible)

That fix I gave was only for Link 3 with 5 sub-links , I wasn’t looking ahead :neutral_face:

I’m afraid I won’t be of any help with the scrollbar as Paul mentioned that was a bootstrap issue, I’m not experienced with bootstrap.

Thank you all.
Sorry I missed Paul’s comment, I did think it was bootstrap related, just wanted to have a confirmation.
Will look into it further.

Okay, It looks like a negative margin-top can fix this without interfering with Paul’s nice transition effect.

I like that effect that top:-100%; gives, It looks like the dropdown slides in through a letter slot.

It needs to get a little more specificity in there to over-ride the ul resets at the top of the stylesheet. So instead of .sub you’d need to go with ul.sub

ul.sub { /*=== Added ul.sub  ===*/
    position:absolute;
    right:0;
    left:50%;
    top:-100%;
    opacity:0;
    z-index:-1;
    margin-top:-200em;    /*=== Added This ===*/
    background-color: #f00;
    box-shadow:5px 5px 5px rgba(0,0,0,0.4);
    /* comment the next line out if you want the submenu to disappear quickly */
    transition:opacity 1s ease .1s, top .1s ease .5s, margin-top .5s ease 1s;
                                                    /*=== Added This ===*/   
}
.dropdown:hover ul.sub { /*=== Added ul.sub  ===*/
    top:0;
    opacity:1;
    z-index:99;
    margin-top:0;   /*=== Added This ===*/
    transition:opacity 1s ease .5s, top .5s ease .5s;
}
2 Likes

Hi Ray, thanks for spotting that the menu was being triggered at the bottom and that was something I should have spotted.

I didn’t notice it because originally the sub menu was part of the coloured sliding block which was hidden off left and thus the submenu was off left also and out of the way. When I added the pseudo element instead of the extra html element I moved the submenu’s position and forgot it would be on screen.

Rather than move it off top to hide it I would just move it off left instead and just bring it back on hover (although margin top should work just as well I prefer to go left and not worry about how tall the menu may be). As long as only top and opacity are animated it will not spoil the effect. That’s actually how the menu was originally working as I took the method from one of my drop down code pen demos.

The top -100% was not a magic number as such but a nice starting point for the transition and was not meant to hide the menu at all.

I’ll update the codepen when I get back to the computer :slight_smile: ( on a mobile at the moment)

1 Like

I’ve updated the codepen to get rid of the bug.

I changed the rules here:

ul.sub {
	position:absolute;
	width:50%;
	left:50%;
  margin-left:-999em;/* fallback*/
  margin-left:-100vw;
	top:-100%;
	opacity:0;
	background-color: #f00;
	z-index:-1;
	box-shadow:5px 5px 5px rgba(0,0,0,0.4);
	/* comment the next line out if you want the submenu to disappear quickly */
  transition:opacity 1s ease .1s, top .1s ease .5s, margin 0s  1s;
}
.dropdown:hover .sub {
	top:0;
        margin-left:0;
	opacity:1;
	transition:opacity 1s ease .5s, top .5s ease .5s;
  	z-index:99;
}

I changed a couple of things to keep the animation as I wanted but feel free to tweak as required. I like the menu to fade away when finished rather than just disappear.

The menu is hidden off to the left of the screen and to avoid the menu transitioning left and right I’ve added a 0s transition so that it happens immediately but with a transition delay so that the slide up and down takes place first. It’s a good method for allowing a transition to take place and then applying other rules to make sure the menu is hidden off screen without animating to that off screen point.

I think that squashes all bugs but as they say in computer programs “There is always one more bug…”.

1 Like

Thank you both.

Maybe I’ll create it when playing, and messing it up :laughing:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.