Extra pixel in firefox on dropdown hover - html

I'm using top: 100% to push the sub-menu dropdown below the main navigation bar on hover but in Firefox the menu is pushed below the border of the menu causing a 1px gap. In webkit browsers it works the way I'm wanting it to, where it shows the sub-menu with no gap in between. I'm using 100% to avoid hard coding in a value.
I created a codepen for testing. I set the border around the menu to red to make it easier to see the issue. The second nav is just showing the hover state.
update
Without display: table; on the .nav-main element, the 1px gap goes away, but I'm using it so I can add display: table-cell; to the nav list items to spread them out and fill the entire nav. Any ideas on how to get around that?
html
<nav role="navigation">
<ul class="nav-main">
<li>Link One</li>
<li>
Link Two
<ul class="sub-menu">
<li>Dropdown Link One</li>
<li>Dropdown Link Two</li>
<li>Dropdown Link Three</li>
</ul>
</li>
<li>Link Three</li>
<li>Link Four</li>
</ul>
</nav>
scss
$pink: #ed2490;
a {
text-decoration: none;
}
.nav-main {
position: relative;
display: table;
margin: 0;
padding: 0;
width: 100%;
border: 1px solid lighten(black, 22%);
border-radius: 4px;
background: lighten(black, 8%);
#include background(linear-gradient(bottom, lighten(black, 8%), lighten(black, 36%)));
font-weight: 500;
line-height: 1;
> li {
display: table-cell;
text-align: center;
position: relative;
&:hover {
.sub-menu {
top: 100%;
}
a {
background: lighten(black, 18%);
background: rgba(black, 0.25);
}
}
}
a {
display: block;
color: white;
padding: 15px 10px;
&:hover,
&:focus {
background: lighten(black, 18%);
background: rgba(black, 0.25);
}
}
.sub-menu { // dropdown
position: absolute;
top: -999px;
z-index: 10;
margin: 0;
padding: 0;
width: 200px;
background: lighten(black, 4%);
li {
border-top: 1px solid lighten(black, 18%);
&:first-child {
border-top: 0;
}
}
a:hover {
background: $pink;
}
}
}
// For example only
.styleguide-dropdown {
padding: 40px 20px 130px;
}
.nav-main {
border-color: red;
.psuedo-hover {
a {
background: lighten(black, 18%);
background: rgba(black, 0.25);
}
.sub-menu {
top: 100%;
.psuedo-hover {
background: $pink;
}
}
}
}

shudder, anything with display: table-* is inherently going to be very hard to style consistently across browsers.
But, that said, its really not your issue. The following fixes both work:
.submenu { display:none;}
:hover > .submenu { display: block;}
or
.submenu { height: 0; overflow:hidden }
:hover > .submenu { height: auto; }
And either of those should be better for reflow/repaint/re-render than crazy shifts in top. Also they will be more robust in case you ever wanted to re-use that nav lower on a page, without just "hiding" things by sending them up with a negative top.
Cheers.

Removing the 1px border around ul solves the problem; then you can add top and bottom borders to each li. Though the border-radius won't be calculated the same way.
I believe the reason is that the height of ul is more than the height of li with this 2px of border and so 100% of the height of li isn't enough... but I'm really not sure of this one.
Here's a working demo: http://codepen.io/anon/pen/jsBEt

Related

CSS Vertical Menu with submenu callouts overlapping

Its been a while - but I found myself a new exiting hobby in web development, and I am hoping that you can help me overcome the following issue:
I am working on a personal website. Content etc. is all preliminary. My main focus is the vertical menu on the left hand side. While I am pretty happy with the appearance so far, there are still some questions:
1) I had to set the transition as ease out to >0s, so that I have enough time between the main-menu hover and the hover over the sub-menu. Because of this, if I hover between main-menu items, they will briefly overlap due to the phase out. Is there a way to work around this?
(the focus selector might be an option, but that requires to click the menu item, and I prefer the hover)
2) The sub-menu is aligned to the top of the li of the main-menu. Because of that, the last item's sub (Testing) exceeds the boundaries of the page, giving whitespace below the page. Is there a way to make the sub-menu shift up if it presses against the edge of the overall body?
I probably could give it a different tag and design it differently, am I am hoping there is a more general solution.
3) Minor issue: When switching from main-menu hover to sub-menu hover, the main-icon "blinks" very briefly. Is that normal behavior? Certainly isn't pretty.
4) Last but not least: As this is my first time doing a website, I would be more than grateful to get your general feedback on inefficiencies in the code, so I can be more lean in the future.
(see updated fiddle below - full code removed to save space.)
Thanks for your help!
EDIT
THanks for your answers - issue #1 has been solved using the approaches you outlined!
However, the last submenu still gives me a bit a headache.
If I use the "last-child" selector, and the code added below, it will not change anything. However, if I give the last "bubble" a different tag, using the exact same code, the bubble will align to the bottom of the last main-menu item, but the containing UL remains defiant.
As you can see from the original CSS, the last "relative" is the main-menu IL, so shouldn't the submenu and the containing UL both align to the bottom of their respective parent/grandparent?
using a dedicated, different tag for the last-child "bubble_last
Using the last-child selector
and the accompanying new code (updated fiddle with full code: Heres the Fiddle ...use large screen for the result to see the alignment issue):
.navigation ul li:last-child {
border: solid orange;
}
.navigation .bubble_last{
position: absolute;
margin-top: 0%;
padding: 0px;
left: 60px;
bottom: 0px;
width: 400px;
height: 200px;
border: solid red;
}
.navigation .bubble_last ul{
position: absolute;
left: 0;
bottom: : 0px;
margin-top: 0px;
padding: 0px;
width: 20vw;
height: 100px;
font-size: 15px;
font-size: 1.2vw;
font-weight: 400;
border: solid blue;
margin-left: 28%;
display: block;
}
.navigation .bubble_last ul li {
list-style: none;
background-color: none;
border-radius: 3px;
height: 2vw;
line-height: 1.2vw;
width: 20vw;
position: relative;
padding-top: 0px;
margin: 0;
padding: 0;
}
Instead of adding a transition delay on .bubble, you just need to make the .bubble class wide enough (and start behind the main li trigger with a left: 60px) so that the hover will be continuous:
.navigation .bubble {
position: absolute;
margin-top: 0%;
padding: 0px;
left: 60px;
top: 0px;
width: 200px;
height: 100%;
background-color: none;
}
Then just add a margin-left to the submenu:
.navigation ul li ul {
margin-left: 20px;
}
To fix your second issue, simply add the following CSS to make the last submenu positioned relative to the bottom of the nav item:
ul li ul.subm:last-child {
top: auto;
bottom:0px;
}
Updated Demo: JSFiddle
How about this? Adjust your navigation to use the nav element, set it to use flex box, adjust that so it fits the height of your page, and then adjust the transition effects so they transition in and out properly.
I hope this helps.
#import url("http://fonts.googleapis.com/css?family=Roboto");
* {
border: none;
margin: 0;
padding: 0;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
font-family: Roboto Condensed;
box-sizing: border-box;
}
.landing {
display: table;
margin: auto;
width: 100%;
height: 100%;
background: url("https://imageshack.com/i/poXkyeIYj") 50% 50% no-repeat;
background-size: cover;
top: 0;
position: relative;
z-index: 1;
}
.landing .welcome {
margin: 10px;
width: 89%;
color: #FFF;
text-align: center;
display: table-cell;
vertical-align: middle;
position: absolute;
left: 10%;
top: 30%;
}
#mug {
background: url("https://imageshack.com/i/pmJaAuFkj") 50% 50% no-repeat;
background-size: cover;
border: solid 3px #FFF;
/*max-width: 20%;
max-height: 20%; */
width: 150px;
height: 150px;
margin: auto;
border-radius: 100%;
}
nav {
width: 50px;
height: 100%;
flex: 1;
display: flex;
justify-content: center;
flex-direction: column;
}
nav img {
max-width: 50px;
max-height: 50px;
}
.nav ul {
*zoom: 1;
list-style: none;
margin: 0;
padding: 0;
-ms-flex: 0 100px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
justify-content: space-between;
margin-top: 0px;
padding: 0px;
width: 11vw;
height: auto;
font-size: 15px;
font-size: 1.2vw;
font-weight: 400;
border-color: none;
}
nav ul li {
background-color: rgba(222, 225, 229, 0.8);
border-radius: 3px;
width: 100%;
font-size: 15px;
font-size: 1.2vw;
font-weight: 900;
}
.nav ul:before,
.nav ul:after {
content: "";
display: block;
}
.nav ul:after {
clear: both;
}
.nav ul>li {
position: relative;
}
.nav a {
display: block;
padding: 10px 20px;
line-height: 1.2em;
color: #fff;
border-left: 1px solid #595959;
text-decoration: none;
color: #FFF;
}
.nav a:hover {
text-decoration: none;
background-color: rgba(242, 93, 38, 0.8);
}
.nav li ul {
background: #273754;
}
.nav li ul li {
width: 200px;
}
.nav li ul a {
border: none;
}
.nav li ul a:hover {
background: rgba(0, 0, 0, 0.2);
}
.nav li ul {
position: absolute;
left: 11vw;
top: 0;
z-index: 1;
visibility: hidden;
opacity: 0;
filter: alpha(opacity=0);
-webkit-transition: 200ms ease;
-moz-transition: 200ms ease;
-o-transition: 200ms ease;
transition: 200ms ease;
}
.nav ul>li:hover ul {
visibility: visible;
opacity: 1;
filter: alpha(opacity=100);
}
span.caption {
display: none;
}
<body>
<div class="landing">
<div class="welcome">
<div id="mug">
</div>
<h1>Welcome to my personal Website!</h1>
<h2>On this site you will find a information about the person, the profession and other stuff about me. Enjoy!</h2>
</div>
<!-- cleaned up the navigation, nested it within the rest of the page, and adjusted the css -->
<nav class="nav">
<ul>
<li>
<img src="https://imageshack.com/i/potj2pVwp"> <span class="caption">Home</span>
</li>
<li>
<img src="https://imageshack.com/i/pntQ9nVMp"><span class="caption">About Me</span>
<ul>
<li>What I do</li>
<li>Motorcycling</li>
<li>Music</li>
</ul>
</li>
<li>
<img src="https://imageshack.com/i/po4WFq6Yp"><span class="caption">Professional</span>
<ul>
<li>Current Employment</li>
<li>Working Experience</li>
<li>Education</li>
</ul>
</li>
<li>
<img src="https://imageshack.com/i/pmcfm7Kbp"> <span class="caption">Projects</span>
<ul>
<li>Subnav Item</li>
<li>Subnav Item</li>
<li>Subnav Item</li>
</ul>
</li>
<li>
<img src="https://imageshack.com/i/pnM0Fmgrp"> <span class="caption">Misc</span>
<ul>
<li>Subnav Item</li>
<li>Subnav Item</li>
<li>Subnav Item</li>
</ul>
</li>
<li>
<img src="https://imageshack.com/i/poqRnk6ap"> <span class="caption">Testing</span>
<ul>
<li>Subnav Item</li>
<li>Subnav Item</li>
<li>Subnav Item</li>
</ul>
</li>
<li>
<img src="https://imageshack.com/i/pmc8tts9p"> <span class="caption">Contact</span>
</li>
</ul>
</nav>
</div>

Why is my UL sub-menu taking the background of it's grandparent?

I'm working on a menu and on small screens I have it using gradients for backgrounds. There are 4 levels to this sub-menu, and each have their own color backgrounds. But for some reason my 4th level sub-menu is taking the background color of the 2nd sub-menu (it's grandparent) instead of the color it should be, which is pure white. It's so weird, this problem skips the 3rd sub-menu. I've tried as many work-arounds as I can think of, and even adding !important to the 4th level css hasn't fixed it. Below is the jsFiddle and the code. Am I missing something?
Here is the jsFiddle
CSS (for small screens)
#navbar {
background-color: #29568F !important;
}
.nav-tabs {
display: inline-block;
position: relative;
width: 98.5%;
background-color: #29568F;
margin: 0px 0px;
padding: 0px;
list-style-type: none;
color: white;
text-decoration: none;
text-shadow: 2px 2px #000000;
font: 18px arial, verdana, sans-serif;
border: 3px solid #29568F;
}
#menu-icon {
width: 200px;
display: block;
float: left;
text-align: left;
border: 0px;
border-bottom: 0px !important;
}
.nav-tabs > li:first-child span { /* This is #menu-icon */
border: 0px !important;
background: #29568F !important;
}
.menu-item {
display: none;
}
.nav-tabs li {
width: 100%;;
border-right: 0px;
clear: both;
list-style-type: none;
}
.nav-tabs li span {
display: block;
border: 0px !important;
padding: 10px 2.5% !important;
width: 95% !important;
position: relative !important;
top: 0px;
left: 0px;
}
.nav-tabs li span {
text-align: left;
border-bottom: 1px solid lightgrey !important;
background: linear-gradient(#29568F, #3399CC);
}
.nav-tabs > li > span:hover,
.nav-tabs > li .open {
background: linear-gradient(#3399CC, #29568F);
}
/* -- Arrows -- */
.nav-tabs .arrow-open {
content: url("/images/arrow-up.png");
}
.nav-tabs li .arrow-closed{
content: url("/images/arrow-down.png") !important;
}
/* --- 2nd level submenu -- */
.sub-menu {
position: relative;
top: 0px;
left: 0px;
width: 100%;
clear: both;
}
.sub-menu > li {
position: relative;
left: 0px;
}
.sub-menu > li span {
left: 0px;
text-align: center;
background: linear-gradient(#99EEFF, #3399CC);
}
.sub-menu > li > span:hover,
.sub-menu > li .open {
background: linear-gradient(#3399CC, #99EEFF);
}
/* -- 3rd level submenu -- */
.drop-menu {
display: none;
clear: both;
width: 100%;
position: relative;
top: 0px;
left: 0px;
}
.drop-menu li span {
border: 0px;
}
.drop-menu > li > span {
border: 0px !important;
left: 0px;
text-align: left;
background: linear-gradient(#C9EAF3, #ffffff);
}
.drop-menu > li > span:hover,
.drop-menu > li .open {
background: linear-gradient(#ffffff, #c9EAF3);
}
/* -- 4th level submenu -- */
.slide-menu {
display: none;
background: #ffffff !important;
border: 0px;
width: 100%;
clear: both;
position: relative;
top: 0px;
left: 0px;
z-index: 300px;
}
.slide-menu li {
position: relative;
left: 0px !important;
width: 98%;
border: 0px !important;
text-align: center;
}
.slide-menu li span {
display: block !important;
position: relative;
left: 0px;
width: 100%;
border: 0px !important;
}
HTML (sample code to view structure)
<div id="navbar">
<ul class="nav-tabs">
<li id="menu-icon"><span><img src="/images/menu-icon.png">Menu</span></li>
<li class="menu-item"><span>Dogs <div class="arrow-closed"></div></span>
<ul class="sub-menu">
<li><span>Meet the Breeds<div class="arrow-closed"></div></span>
<ul class="drop-menu">
<li><span>Sort A - Z <div class="arrow-closed"></div></span>
<ul class="slide-menu">
<li>Breeds A - F</li>
<li>Breeds G - L</li>
<li>Breeds M - R</li>
<li>Breeds S - Z</li>
</ul> <!-- close slide-menu -->
</li> <!-- close Drop-menu item -->
</ul> <!-- close drop-menu -->
</li> <!-- close sub-menu item -->
</ul> <!-- close sub-menu -->
</li> <!-- close main menu item -->
</ul> <!-- close main-menu -->
</div>
NOTE!
While creating the jsFiddle for this question, I realized that when I only included the css for small screens, the 4th level menu's background was white as it was supposed to be. It wasn't until I included the WHOLE CSS code that it stopped working. Which still doesn't make sense because the 4th level background works in it's normal, large screen state. I don't understand why it would be doing this so if someone would be kind enough to comb through this for me I'd be ever so grateful.
UPDATE!
I've been messing with the jsFiddle, and I removed all of the large-screen CSS to try and de-bug it. 4th level menu had a white background. Ok. So I added the 1st level CSS back in, and the 4th level background messed up. Removed it, and added the 2nd level CSS in, and the 4th level background messed up again. But if I added in the 3rd or 4th level CSS for large screens, the 4th level background wasn't affected at all. So the problem is somewhere BOTH in the 1st level and 2nd level CSS. But I don't understand why. I don't have anything inheriting it's parent's css, and none of the code calls for any gradient at all. So weird.
Spent a few minutes looking over your code, and i think i found the problem. In your 2nd and 3rd sub-menu you're applying the background to the span tags. But on your 4th menu ( .slidemenu ) you're applying it directly to the ul.
Remove background from:
Line: 416
.slide-menu
Add background to:
Line: 432
.slide-menu li
Working fiddle: jsfiddle

Navbar li goes to next line upon resize

I have a navbar on my website, which is made up of a ul and some lis inside. The last li, Log Out, has to be right aligned. The problem is, when the screen is resized too small, it goes to a line below to prevent running into the other lis.
Here's the HTML for the navbar:
<div class="navbar">
<ul>
<li>Home</li>
<?php if ($user->logged_in) { ?>
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
<li style="margin-right: 10px; float: right;">Log Out</li>
<?php } ?>
</ul>
and the CSS:
/* Navbar */
.navbar {
background: #DDDDDD;
overflow: hidden;
width: 100%;
}
.navbar ul {
border: solid 1px #BBBBBB;
margin: 0;
min-width: 600px;
overflow: hidden;
}
.navbar ul li {
border: solid transparent;
border-width: 0 1px 0 1px;
cursor: pointer;
display: inline-block;
float: left;
padding: 16px;
}
.navbar ul li:hover {
background-image: url("../images/patterns/background.png");
border-color: #369643;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
color: #FFFFFF;
text-shadow: 0 1px 0 #167F39;
}
.navbar ul li a {
color: inherit;
display: block;
text-decoration: none;
width: 100%;
}
Your question isn't too clear but I'm assuming you don't want the "logout" element to go below the other nav elements. The problem is in your css where your setting a "min-width" to your 'navbar ul' element. Therefore when the screen is reduced below that width it is being hidden.
I say hidden because after executing your code the "logout" element doesnt go below other nav elements it is just completely hidden. (Using Safari).
Deleting the 'min-width' fixed that problem for me. Hope it does for you too.
It works well in jsfiddle as well as in local browser.. Overflow is already added.
/* Navbar */
.navbar {
background: #DDDDDD;
overflow: hidden;
width: 100%;
}
.navbar ul {
border: solid 1px #BBBBBB;
margin: 0;
min-width: 600px;
}

Change css of list item before an after the item that is being hovered over

I've created navigation menu for my website. Here's the html: (you can also view the sidebar menu at belairfinishing.com, its the menu on the left.)
<div><img src="../public/images/skystatic.jpg" id="LinkForBannerImage"></div>
<ul>
<li>Proccess Technology</li>
<li>Equipment</li>
<li>Media & Compounds</li>
<li>Parts Cleaners & Dryers</li>
<li>Waste Water Treatment</li>
<li>Precious Metal Recovery</li>
<li>Consulting</li>
<li>Technical Articles</li>
<li>Press Releases</li>
<li>Toolhoning.com</li>
<li>Distributor Log In </li>
</ul>
</div>
Basically what I would like to happen is that when you hover over one of the items, ONLY the items directly before an after that get a red border. So if someone were to hover over Consulting, then Technical Articles and Precious Metal Recovery will have red borders.
I've been looking this up all morning and haven't found anything that works. So far I've tried to use nth-child(-n) and nth-child(n) to get 1 above an 1 below but I can't get that to actually work. Am I messing up the syntax or is their a better solution for this problem?
Thanks for the help!
Using CSS you could only select the next element using the adjacent sibling selector(+), however CSS doesn't have a previous sibling selector.
This could be achieve using jQuery.
$('li').hover(
function() {
$(this).next().find('a').addClass('highlight');
$(this).prev().find('a').addClass('highlight');
},
function() {
$(this).next().find('a').removeClass('highlight');
$(this).prev().find('a').removeClass('highlight')
})
#cssmenu {
text-align: center;
}
ul {
padding: 0;
list-style: none;
white-space: nowrap;
}
li {
display: inline-block;
vertical-align: top;
}
a {
display: block;
text-decoration: none;
width: 130px;
height: 50px;
line-height: 50px;
color: white;
background: #222;
box-sizing: border-box;
}
a:hover {
color: rosybrown;
}
.highlight {
border-bottom: 4px solid rosybrown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cssmenu">
<ul>
<li class="active">Home</li
><li>About Us</li
><li>Contact Us</li
><li>Trade Shows</li
><li>Vibratory Workshops</li
><li class="last">Directions</li>
</ul>
</div>
Edit
You could also make it work using CSS alone.
The idea is to add a :before :pseudo-element to a on :hover, if the a is not a descendant of first li and :after :pseudo-element, if the a is not a descendant of the last li.
i.e, li:not(:first-child) a:hover:before, li:not(:last-child) a:hover:after.
In simple words, it won't add the line on the left if the li is the first element and won't add the line on the right if the li is the last element.
body {
margin: 0;
}
#cssmenu {
text-align: center;
margin: 0;
}
ul {
padding: 0;
margin: 0;
list-style: none;
white-space: nowrap;
}
li {
display: inline-block;
vertical-align: top;
}
a {
position: relative;
display: block;
text-decoration: none;
width: 130px;
height: 50px;
line-height: 50px;
color: white;
background: #222;
box-sizing: border-box;
}
a:hover {
color: rosybrown;
}
li:not(:first-child) a:hover:before, li:not(:last-child) a:hover:after {
content: '';
position: absolute;
width: 100%;
height: 4px;
left: -100%;
bottom: 0;
border-bottom: 4px solid rosybrown;
box-sizing: border-box;
}
li:not(:last-child) a:hover:after {
left: 100%;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cssmenu">
<ul>
<li class="active">Home</li
><li>About Us</li
><li>Contact Us</li
><li>Trade Shows</li
><li>Vibratory Workshops</li
><li class="last">Directions</li>
</ul>
</div>

Border-bottom issue (expanding downwards on hover)

I'm working on a navigation, and I can't seem to figure out how to make the bottom border increase in size upwards, instead of expanding downwards (which in turn extends my header a few pixels), I could fix the extending header with setting a height, but the the border will still extend downwards instead of upwards.
The CSS:
header {
margin: 0;
padding: 0;
left: 0;
top: 0;
width: 100%;
position: absolute;
background: #000000;
}
ul {
list-style-type: none;
display: block;
margin: 0 0 0 20px;
padding: 0;
}
ul li {
display: inline-block;
padding: 0;
}
ul li a{
display: block;
border-bottom: 1px solid #fff;
font-size: 19px;
}
ul li a:hover{
border-bottom: 2px solid #fff;
background: #333;
font-size: 19px;
}
The HTML:
<header>
<ul id="nav">
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</header>
The JSFiddle:
http://jsfiddle.net/Artsen/EZWvF/
So you want to increase the border-bottom to the top, right?
I've actually had to do this for a website recently. There is no other way than to set specific padding, and border properties.
I edited your jsfiddle here: http://jsfiddle.net/EZWvF/2/ (changed some properties to make the test case more visible)
The principle is: Swap the pixel values from padding-bottom and border-bottom on hover.
These are the key lines to your solution:
ul li a {
border-bottom: 1px solid white;
padding-bottom: 5px;
}
ul li a:hover {
border-bottom: 5px solid white;
padding-bottom: 1px;
}
Note: This only works if you don't add a css-transition. If you unquote the css-transition I put in the fiddle, you'll see that the div still expands to the bottom. If you want a ss-transition you'll need to add a separate div to the li's to mimic a border.
As Tyblitz suggested using extra padding value on :hover works great when you don't need a transition.
If you need transition and don't want to introduce an extra div you can do it using the line-height/height approach for controlling the vertical height.
so instead of doing this:
.nav-element a {
color: gray;
padding: 25px 15px;
transition: all ease-in-out 0.2s;
display: block;
text-decoration: none;
}
do this:
.nav-element a {
color: gray;
padding: 0 15px;
line-height: 70px;
height: 70px;
transition: all ease-in-out 0.2s;
display: block;
text-decoration: none;
}
See example where it doesn't work here
and does work (using the line-height/height) here