I have a menu with submenu working fine, however I am trying to add css transition on sub menu, If I mouseover on second nav item, the submenu which appear should have slide from top to bottom transition but its not working, can anybody please suggest?
Here is the working JSfiddle
.header_right {
float: right;
width: 100%;
min-height: 80px;
line-height: 80px;
}
.header_right > ul {
list-style: none;
margin: 0;
padding: 0;
font-size: 0;
text-align: right;
}
.header_right > ul > li {
list-style: none;
display: inline-block;
background: #3275a6;
padding: 8px 16px;
color: #fff;
-webkit-border-radius: 4px;
border-radius: 4px;
font-family: 'Montserrat', sans-serif;
font-size: 15px;
font-weight: 400;
line-height: normal;
vertical-align: middle;
transition: all 0.3s ease 0s;
cursor: pointer;
position: relative;
}
.header_right > ul > li > a {
color: #fff;
text-decoration: none;
}
.header_right > ul > li:nth-child(1) {
margin-right: 15px;
cursor: default;
}
.header_right > ul > li:nth-child(1) > a {
cursor: default;
}
.header_right > ul > li:hover {
background: #14507d;
}
.header_right > ul > li.actbtn {
background: #14507d;
}
.navigation-third {
background: #14507d;
border-radius: 0 0 4px 4px;
display: none;
list-style: outside none none;
margin: 0;
padding: 0;
position: absolute;
right: 0;
top: 33px;
width: 100%;
-moz-transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
-webkit-transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
}
.navigation-third > li {
list-style: outside none none;
}
.navigation-third > li > a {
color: #fff;
font-size: 14px;
padding: 10px 12px;
display: block;
text-align: left;
text-decoration: none;
}
.navigation-third > li > a:hover {
background-color: #0076AA;
}
.navigation-third > li:nth-child(2) > a:hover {
border-radius: 0 0 4px 4px;
}
.header_right > ul > li:nth-child(2):hover .navigation-third {
display: block;
}
<div class="header_right">
<ul>
<li href="javascript:;"><i class="ico ico_location"></i> Delhi/NCR </li>
<li> <a class="sub-3"><i class="fa fa-sign-in"></i> Welcome, User</a>
<ul class="navigation-third">
<li><i class="fa fa-cog" aria-hidden="true"></i> User Account</li>
<li><i class="fa fa-sign-out"></i> Logout</li>
</ul>
</li>
</ul>
</div>
You can't use display: none to do this. Use CSS's visibility property instead. Also, since you're using transition for top (plus a few more) property, you also have to use a varying top value.
That being said, your CSS should look like this:
.navigation-third {
background: #14507d;
border-radius: 0 0 4px 4px;
visibility: hidden; <-- Changed
list-style: outside none none;
margin: 0;
padding: 0;
position: absolute;
right: 0;
top: 0; <-- Changed
width: 100%;
-moz-transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
-webkit-transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
transition: top 0.7s, right 0.7s, bottom 0.7s, left 0.7s;
}
.header_right > ul > li:nth-child(2):hover .navigation-third {
visibility: visible; <-- Changed
top: 33px; <-- Added
}
Note: You still have to play a bit with z-index I guess, since this snippet places the dropdown in front of your nav item (doesn't look smooth). You may also play with the sliding transition. Just change your top values accordingly.
Demo
If I understand you correctly you want your CSS to transition between your positioning attributes on .navigation-third when hovering on its parent element?
If so, it doesn't work because the only thing happening right now on hover is that the display property is changed. There's no other position for it to transition between.
A solution is to add your "default" position when the list is hidden and then your "correct" positioning values when hovering.
Also, in this scenario (if you want to avoid JavaScript) you want to transition between the element's opacity value rather than its display value when you want to show/hide it, since CSS cannot transition between display properties. An important thing to add to this implementation is pointer-events: none when the element is hidden to avoid accidental clicks or hovers.
You cant use transition on display property. You can simply achieve this by using jquery. here is example fiddle.
$('#sec').hover( function(){
$('.navigation-third').stop().slideToggle('slow');
});
Hope this helps you.
Related
Consider the following nested list:
<div >
<ul class="main">
<li>Fist item<ul class="ab"><li>a1</li><li>a2</li><li>a3</li><li>a4</li></ul>
</li>
<li>Second item<ul class="ab"><li>b1</li><li>b2</li><li>b3</li><li>b4</li></ul></li>
<li>Third item<ul class="ab"><li>c1</li><li>c2</li><li>c3</li><li>c4</li></ul>
</li>
</ul>
</div>
I want the outer level displayed horizontally, and the inner level displayed just below the outer one. To this aim I've used relative and absolute position for outer and inner lists in the css style:
#container {width:300px}
main {width:200px;position:relative;}
body > div > ul > li {display:block;float:left;padding:5px;}
body > div > ul > li > a:hover + .ab {display:block;}
.ab {display:none;clear:both;position:absolute;left:0px}
It works fine unless you resize container width to 200px (as you can try on JSfiddle) (I have to achieve a solution working with different widths). In this case the inner level container overlaps the outer one. I wonder if it is possible to force the inner container to be displayed after the outer container through css or solve this issue in another way.
Edit: I need to make my question clearer because given answers so far show the same proposal I have already made. So i've made a little addition in the css styles declaring a box for the inner container (here the update JSfiddle snippet). The key issue is that my toy example simulates the left column in a more complicated web page. I do not know in advance the exact width of such a column (maybe 150px, maybe 200px or something similar) and I do not know in adcance the length of the titles for the outer list elements. I need a solution that works for whichever width the outer container could have.
This is a screenshot of what I obtain in the default case:
This is what I obtain narrowing the outer container to 200px (try yourself on JSfiddle):
and this is instead what I want to obtain:
I hope to have been my question clear now.
U need to make outer level positioned to relative and inner level as absolute, like this:
#container {width:300px}
.ab {
display:none;
clear:both;
position:absolute;
left:0px
}
body > div > ul > li {
display:block;
float:left;
padding:5px;
position:relative;
}
body > div > ul > li > a:hover + .ab {
display:block;
position:absolute;
left:0; /* So it aligns to the left edge of outer level */
top:100%; /* So inner level isn't overlaping outer */
}
main {width:200px;position:relative;}
Example here: https://jsfiddle.net/d9fsff69/2/
To ensure flexibility, make sure your widths are not fixed. And the rest is a matter of margin. I added some background coloring for visual aid:
Use this CSS:
#container {
width: 100%
}
main {
width: 200px;
position: relative;
}
body > div > ul > li {
display: block;
float: left;
padding: 5px;
background:#999;
}
body > div > ul > li > a:hover + .ab {
display: block;
background:#ddd;
margin-top: 5px;
}
.ab {
display: none;
clear: both;
position: absolute;
left: 0px
}
Here is the DEMO
I would just give you similar example:
body {
margin: 0px;
font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 13px;
text-align: center;
background: #E3CAA1;
}
ul {
width: 100%;
text-align: center;
display: inline-block;
margin: 0px;
list-style: none;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
background: #000;
color: #fff;
}
ul li {
font: 12px/18px sans-serif;
display: inline-block;
margin-right: -4px;
position: relative;
padding: 20px 20px;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
ul li:hover {
color: #71b51e;
background: #161616;
}
ul li ul {
padding: 0;
position: absolute;
left: 0;
top: 57px;
width: 140px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
ul li ul li {
background: #161616;
display: block;
color: #fff;
text-align: left;
padding: 5px 15px;
height: 25px;
}
ul li ul li:hover {
background: #111;
color: #71b51e;
}
ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
<ul>
<li>OPTION
<ul>
<li>SUB-1</li>
<li>SUB-2</li>
<li>SUB-3</li>
<li>SUB-3</li>
</ul>
</li>
<li>OPTION</li>
<li>
OPTION
<ul>
<li>SUB-1</li>
<li>SUB-2</li>
<li>SUB-3</li>
<li>SUB-3</li>
</ul>
</li>
<li>OPTION</li>
</ul>
I have created a fiddle for this: http://jsfiddle.net/Lux0ztyt/
When hovering over the SPAN (A,B,C,D, etc.), I need it to change the background to the same as when hovering the rest of the bar however I can't work out how to do it.
I know the problem is because the SPAN is at the END of all the elements but I am not able to change the positioning of this. How can it work with the positions staying as they are?
I have tried:
#my-list li span:hover ~ div {
/* background stuff */
}
And also:
#my-list li span:hover div {
/* background stuff */
}
And also:
#my-list li span:hover + div {
/* background stuff */
}
Any suggestions?
HTML:
<ul id="my-list">
<li class="100"><div style="width: 100%;"><label>100%</label></div><span>A</span></li>
<li class="85"><div style="width: 85%;"><label>85%</label></div><span>B</span></li>
<li class="95"><div style="width: 95%;"><label>95%</label></div><span>C</span></li>
<li class="85"><div style="width: 85%;"><label>85%</label></div><span>D</span></li>
<li class="95"><div style="width: 95%;"><label>95%</label></div><span>E</span></li>
<li class="80"><div style="width: 80%;"><label>80%</label></div><span>F</span></li>
<li class="90"><div style="width: 90%;"><label>90%</label></div><span>G</span></li>
<li class="95"><div style="width: 95%;"><label>95%</label></div><span>H</span></li>
</ul>
CSS:
#my-list {
list-style-type: none;
margin: 0px;
padding: 0px;
}
#my-list li {
display: block;
width: auto;
text-align: left;
position: relative;
margin: 2px 0px;
}
#my-list li span {
position: absolute;
left: 5px;
top: 0px;
color: #fff;
text-shadow: 1px 1px 1px #555;
font-size: 0.85em;
}
#my-list li div, #my-list li label, #my-list li span, #my-list li {
height: 30px;
line-height: 30px;
}
#my-list li div {
position: absolute;
background: #b02976;
left: 0px;
top: 0px;
width: 0px;
border-radius: 7px;
transition: width 1s, background-color 0.4s ease;
}
#my-list li div:hover {
background: #009e77;
transition: all 0.4s ease;
}
#my-list li div:hover > label {
display: block;
opacity: 1.0;
transition: all 0.4s ease;
}
#my-list li div label {
position: absolute;
right: 5px;
color: #fff;
font-weight: bold;
font-size: 0.7em;
opacity: 0;
transition: all 0.4s ease;
text-shadow: 1px 1px 1px #555;
}
Your code is almost working. The only thing you should change:
Handle the :hover on li rather than the div - then you have no problem:
change
#my-list li div:hover
to
#my-list li:hover div
and
#my-list li div:hover > label
to
#my-list li:hover div > label
The span element will send its :hover to the li - which then will colorize its div child as defined in the css.
http://jsfiddle.net/taqveyjs/1/
TimeDead's answer is correct in that you can't target a parent in CSS. I took a different approach though:
http://jsfiddle.net/austinthedeveloper/Lux0ztyt/2/
#my-list li div {
position: absolute;
background: #b02976;
left: 0px;
top: 0px;
width: 0px;
border-radius: 7px;
transition: width 1s, background-color 0.4s ease;
z-index:-1;
}
#my-list li:hover div {
background: #009e77;
transition: all 0.4s ease;
}
#my-list li:hover div > label {
display: block;
opacity: 1.0;
transition: all 0.4s ease;
}
The trick is to z-index the div so it is behind the li, masking your span. After that, you just update your hover classes to target the li instead of the div and everything works.
Sadly what your asking to do I'm not sure can be done strictly in CSS since in CSS you cannot select and change the parents background in this case the span is the child of the div there for cannot modify it's attributes.
my problem is that when I hover over the area where the hidden list is, it shows the hidden list. I only want it to show the hidden list when hovered over the 'Language' link on the dropdown menu. Why is it doing this, it's probably something blindingly obvious that I can't spot.
Cheers :)
EDIT: I've already tried using a fixed height for the #lang_bar. I also need the transitions to still work. I've already tried using the display:none and display:block; but that didn't work so I used visibility instead.
Any ideas?
HTML:
<div id="lang_bar">
<ul>
<li><strong>Language</strong>
<ul>
<li><strong>Maori</strong></li>
<li><strong>Tongan</strong></li>
<li><strong>Chinese</strong></li>
<li><strong>Japanese</strong></li>
<li><strong>Korean</strong></li>
</ul>
</ul>
</div>
#lang_bar {
font-family: 'Open Sans', sans-serif;
color: white;
padding-left: 152px;
text-transform: uppercase;
z-index: 40;
position: absolute;
padding-top: 2px;
top: 0;
}
#lang_bar ul ul li a {
padding-top: 3px;
padding-left:5px;
}
#lang_bar ul li ul li a:before {
content: '';
display:block;
right: 0px;
height: 2px;
bottom:117px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.2);
}
#lang_bar ul li ul li a:after {
content: '';
display:block;
right: 1px;
height: 2px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.6);
}
#lang_bar li, #lang_bar li ul {
text-decoration: none;
list-style-type: none;
}
#lang_bar ul {
list-style: none;
padding-left: 0px;
}
#lang_bar ul li {
float: left;
width: 100px;
text-align: left;
line-height: 21px;
}
#lang_bar ul li a {
display: block;
color: #FFF;
background: transparent;
text-decoration: none;
text-align: center;
}
#lang_bar ul li ul {
visibility: hidden;
font-size:12px;
opacity: 0;
}
#lang_bar ul li:hover ul {
opacity: 1;
visibility: visible; /* display the dropdown */
-webkit-transition: all .25s ease;
-moz-transition: all .25s ease;
-ms-transition: all .25s ease;
-o-transition: all .25s ease;
transition: all .25s ease;
}
#lang_bar ul li ul a:hover{
transition-duration: 0.6s;
background-color: rgba(255, 0, 0, 0.23);
}
I changed your css a little bit and here is the result
I used display:none and display: block in place of visibility, and everything is working as it should be.
http://jsfiddle.net/sy3qowxs/5/enter link description here
And here is your final CSS:
#lang_bar {
font-family: 'Open Sans', sans-serif;
color: #123111;
padding-left: 152px;
text-transform: uppercase;
z-index: 40;
position: absolute;
padding-top: 2px;
top: 0;
}
#lang_bar a:link{color:#333333;}
#lang_bar ul ul li a {
padding-top: 3px;
padding-left:5px;
}
#lang_bar ul li ul li a:before {
content: '';
display:block;
right: 0px;
height: 2px;
bottom:117px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.2);
}
#lang_bar ul li ul li a:after {
content: '';
display:block;
right: 1px;
height: 2px;
width: 100px;
position: absolute;
background: rgba(255, 255, 255, 0.6);
}
#lang_bar li, #lang_bar li ul {
text-decoration: none;
list-style-type: none;
}
#lang_bar ul {
list-style: none;
padding-left: 0px;
}
#lang_bar ul li {
float: left;
width: 100px;
text-align: left;
line-height: 21px;
}
#lang_bar ul li a {
display: block;
color: #FFF;
background: transparent;
text-decoration: none;
text-align: center;
}
#lang_bar ul li ul {
display: none;
font-size:12px;
opacity: 0;
}
#lang_bar ul li:hover ul {
opacity: 1;
display: block; /* display the dropdown */
-webkit-transition: all .25s ease;
-moz-transition: all .25s ease;
-ms-transition: all .25s ease;
-o-transition: all .25s ease;
transition: all .25s ease;
}
#lang_bar ul li ul a:hover{
transition-duration: 0.6s;
background-color: rgba(255, 0, 0, 0.23);
}
As an alternative to the display: none solution, for accessibility reasons you can use position:absolute and then move the hidden element off screen:
ul li ul {
position:absolute;
top:-1000px;
}
ul li:hover ul {
top:auto;
}
It should work with visibility, since it hides the element (like display: none) but doesn't remove it from the DOM
Here is a working example: Dropdown Menu
HTML
<ul class="menu">
<li class="menu-item"> Dropdown Menu
<ul class="submenu">
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
<li class="submenu-item">Link</li>
</ul>
</li>
</ul>
CSS
.menu-item {
position: relative;
}
.menu-item:hover .submenu {
visibility: visible;
opacity: 1;
}
.submenu {
position: absolute;
visibility: hidden;
transition: all .2s ease;
opacity: 0;
top: 100%;
}
.submenu-item {
padding: .4em;
}
What about just using the adjacent sibling combinator:
Change: #lang_bar ul li:hover ul
To: #lang_bar ul li a:hover + ul
To add to the previous answer, the reason this works when you use the display property instead of visibility is because display removes the element from the document flow, and other elements reflow in its place. Visibility, on the other hand, hides the element, but leaves the empty space as if it were still there. So when you used visibility: hidden, your list item looked like it just contained the text "Language" and the link, but the hidden ul was still there, and still hoverable. That's why when you hovered over where the list item should have been, it reappeared; technically, you were hovering over that first list item, because the sub menu was a child of it.
In general, I use display:block/display:none to toggle hiding and showing of items, rather than visibility. Typically the use case is that you want the element completely hidden from the page, and elements around it to reflow, and the display property will do that for you.
I'm very new to making websites, mostly I do this as a hobby and now I'm working on a website for a friend of mine.
Everything went fine so far but I'm struggling with the menu. (It is also a wordpress website.)
You can preview it at http://www.decapeerwerken.be
The design is quite alright but the problem persists when you come underneath the dropdown menu. There is a sort of range where you can hover where it is not acceptable that the menu drops down, only when you hover on the parent link.
I can see myself that the height of ul.submenu is too high but I can't find it. Already been looking for days after this little issue...
Thank you guys in advance for helping me out!
CODE:
.menu {
text-transform: uppercase;
font-weight: bold;
background: -webkit-linear-gradient(#FEF9CD, #FCE1BC);
background: -o-linear-gradient(#FEF9CD, #FCE1BC);
background: -moz-linear-gradient(#FEF9CD, #FCE1BC);
background: linear-gradient(#FCE3BC, #FEF9CD, #FCE1BC);
border: 1px solid #FCE1BC;
border-radius: 3px;
box-shadow: 1px 1px 10px #A4743d;
}
ul.nav-menu li a {
color: #604443;
font-family:'Oregano', cursive;
}
.nav-menu {
list-style-type: none;
height: 40px;
margin: 0;
}
.nav-menu li {
float: left;
position: relative;
padding: 0;
line-height: 40px;
}
.nav-menu li a {
display: block;
padding: 0 15px;
color: #fff;
text-decoration: none;
}
.nav-menu li:hover {
color: #965A3E;
transition: color 0.8s, box-shadow 0.3s;
background: linear-gradient(#FCE3BC, #FFFCE3, #FCE1BC);
box-shadow: 1px 1px 10px #A4743d;
margin-top: -1px;
background-position: 0 -40px;
}
.nav-menu li ul {
opacity: 0;
position: absolute;
left: 0;
list-style-type: none;
padding: 0;
margin: 0;
}
.nav-menu li:hover ul {
padding-top: 5px;
opacity: 1;
transition: opacity 0.8s;
}
.nav-menu li:hover ul li {
float: none;
position: static;
height: 30px;
line-height: 30px;
background: linear-gradient(#FCE3BC, #FEF9CD, #FCE1BC);
transition: background-color 1.4s, color 0.8s, box-shadow 0.5s;
color: #965A3E;
margin-bottom: 5px;
width: 200px;
}
Replace "opacity:1" (opacity:0) with "display:block;" ("display:none")
Your problem is that hover changes the layout (the contents occupy more space, even though they are hidden, when the parent is not hovered), but also that because you are only changing opacity, the user can still hover the contents when they are hidden.
I managed to fix the issue by transitioning visibility as well as opacity, which means you can no longer hover over the contents when they are invisible:
.nav-menu li ul {
opacity: 0;
visibility: hidden;
position: absolute;
left: 0;
list-style-type: none;
padding: 0;
margin: 0;
}
.nav-menu li:hover ul {
padding-top: 5px;
opacity: 1;
visibility: visible;
transition: opacity 0.8s, visibility 0.8s;
}
I would like a topbar navigation, similar to one that you see with Foundation. The problem i'm having is that i've set margins for the page and dont know how to override them?
So for most of page (body) I need these margins but for the top bar i'd like it extending the full width of the browser.
Here's the code:
body {
font-family: 'Droid Sans', sans-serif;
font-size: 1.2em;
color: #000000;
background-color: white;
margin: 0em 6.5em 3.5em;
#nav ul {
width: 100%;
background-color: #212121;
font-size: 12px;
font-weight: bold;
color: white;
text-align: left;
display: block;
margin: 0;
padding: 15px 4px 17px 0;
list-style: none;
}
#nav ul li {
display: inline-block;
margin-right: -4px;
height: inherit;
margin-left: 20px;
position: relative;
padding: 15px 20px;
background: #212121;
cursor: pointer;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#nav ul li:hover {
background: #212121;
color: #fff;
}
#nav ul li ul {
padding: 0;
position: absolute;
top: 48px;
left: 0;
width: 150px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
display: none;
opacity: 0;
visibility: hidden;
-webkit-transiton: opacity 0.2s;
-moz-transition: opacity 0.2s;
-ms-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
-transition: opacity 0.2s;
}
#nav ul li ul li {
background: #212121;
display: block;
color: #fff;
}
#nav ul li ul li:hover { background: #212121; }
#nav ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
Html:
<body>
<div id="nav">
<ul>
<li>Home</li>
<li>Venue</li>
<li>Events</li>
<li>Stalls
<ul>
<li>Food</li>
<li>Arts & Crafts</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
Besides using absolute positioning, you can just use negative margins for the #nav like this:
#nav {
margin-left:-6.5em;
margin-right:-6.5em;
}
Demo
Apply the following css for the header,
#nav{
position:absolute;
left:0;
right:0;
}
It's take the nav out of normal flow and stretch it from left to right.
Check this JSFiddle
If you set position:fixed; width:100%; then the header will be taken out of the normal flow and will be positioned relative to the window. It'll stay where it is even if the user scrolls down the page.
Use fixed positioning for the navigation bar you want at the top of your page.
#nav {
min-width:100%;
position:fixed;
top:0;
left:0;
}
Adding a min-width of 100% should ensure the navigation bar stretches across the width of your page. Setting top and left to zero, in conjunction with position:fixed, would anchor the nav div to the top-left.