I made a simple HTML page with a simple drop-down menu (made with CSS). I have a problem with the drop-down text transparency: it shows the bottom text (as explained in the image below). The text in the menu is a link, so it's included in a tag. I tried to change the text color and opacity property but doesn't solve the problem. Any idea?
.menu {
margin-right: 0px;
margin-left: -40px;
}
li {
display: block;
float: left;
width: 25%;
height: 50px;
line-height: 50px;
font-family: Helvetica, sans-serif;
font-size: 20px;
text-align: center;
color: white;
background-color: #000000;
}
.pat:hover {
color: #EC008C;
}
.l {
width: 100%;
height: 50px;
margin-left: -20px;
}
.sub-menu {
visibility: hidden;
}
.menu .pat:hover .sub-menu {
visibility: visible;
}
<ul class="menu">
<li>Home</li>
<li class="pat">Patenti
<ul class="sub-menu">
<li class="l">Patente A</li>
<li class="l">Patente B</li>
<li class="l">Patenti superiori</li>
</ul>
</li>
<li>News</li>
<li>Contatti</li>
</ul>
Instead of visibility: hidden; and visibility: visible; on hover for submenus, it's better to use display: none and display: block, and use position: absolute on the submenu and position: relative on its parent menu entry.
The reason display: none doesn't take any space (and position: absolute will prevent the visible submenu to change the design of the main menu entries), whereas visibility: hidden; reserves the space for the hidden element and just makes it invisible, which makes it impossible to properly position it independently of objects which it should cover when visible.
Just add position: relative to .menu. It will create a stacking context causing it to appear above body text.
Here is a modified pen. I have rewritten all rules but only the last one is important.
Related
I have a nav containing a list of links. The list has a line-height: 1em. However the links have a height greater than 1em and overlap the preceeding list item, making it hard to click the items.
nav {
height: 100%;
overflow: hidden;
position: absolute;
top: 7.2rem;
left: 0;
right: 0;
font-size: 50px;
line-height: 1em;
}
nav li {
background-color: green;
}
nav a {
background-color: pink;
}
<nav>
<ul>
<li>Projects</li>
<li>About</li>
<li>Services</li>
<li>Ethics</li>
<li>Contact</li>
</ul>
</nav>
This can be seen more easily if I add margin-bottom to the nav li. The links (pink) have greater height than the line-height of the list items (green):
How do I get the links to have the same height as the list items? So that there is no overlapping?
Note. there is no padding on the links, so I don't know why they are larger. It doesn't make any difference if I add height:1em to the nav a. I've tried display:inline-block - which makes the pink background the same height as the green background, but strangely the links are still clickable just above and below the pink background! The clickable area isn't confined to the pink background.
NEW INFO
Links have a greater height than the font-size.
The size of the link is in no way influenced by the line-height.
For example a line of text with font-size: 50px has a height of 50px. Yet the link inside the line of text has a height of 68px (there is no padding or margin on the link).
I presume the clickable area around the link has to take into account all the ascenders and descenders of the typeface. And this is why it has a greater height than the font-size.
Hence if the line-height is set to 1em the links overlap. Using display: inline-block displays the pink background as being the same height as the green background, but, (strangely) the clickable area is still larger than the 50px pink background height.
Unless there is a way to constrain the height of the link to the height of the font-size, then I will have to increase the line-height to account for this difference.
This JS Fiddle shows how the links are bigger than the font-size: https://jsfiddle.net/utqafz61/
... so if the line-height is the same as the font-size (1em) then the links will overlap making it difficult to click the right link. I first noticed this on this website: https://www.hassellstudio.com on the nav menu the links overlap. The mouse pointer can be on one link, but the link below is highlighted!
the weird thing you were doing is to set the font-size of nav which is parent of ul li to 10rem that had made them bigger and also line-height is different from the actual height just se here line-height
example
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
nav {
height: 100%;
overflow: hidden;
position: absolute;
top: 7.2rem;
left: 0;
right: 0;
/* font-size: 10rem;*/
}
nav li {
margin: 10px;
background-color: green;
}
nav a {
background-color: pink;
}
<nav>
<ul>
<li>Projects</li>
<li>About</li>
<li>Services</li>
<li>Ethics</li>
<li>Contact</li>
</ul>
</nav>
Just add display: inline-block to your a elements.
Anchor tags are naturally inlined by user agent stylesheets which is what's causing your overflow.
The problem is with the line-height in your nav, its not giving any space between the lines ()line-height: 1em is only allocating the same as the font-size (50px) so there is no room for the default space around the letters). You can make line-height larger (1.1em will works with your code above):
nav { line-height: 1.1em; }
Or just remove it altogether so it uses the default.
UPDATE:
If you cannot change the line-height from 1em, There are 2 fundamental problems that are causing issues to achieve this:
a tags are inline by default which makes it harder to work with margins & padding etc.
most fonts have extra space above and below so that the ascenders and descenders don't touch - this is down to the font glyphs themselves. Some fonts are "worse" than others.
You could force the link not to overflow outside the li using the following, and it will prevent the effect you see where the mouse looks like its over one link but actually activates another:
nav li {
background-color: green;
overflow: hidden; /* this will crop off anything outside the element */
}
However depending on the font, this could crop a tiny part off the descenders of the letters.
Working snippet:
ul {
margin: 0;
padding: 0;
border: 0;
vertical-align: top;
list-style: none;
}
nav {
height: 100%;
overflow: hidden;
position: absolute;
left: 0;
right: 0;
line-height: 1em;
font-size: 3rem;
font-family: "Times New Roman";
}
nav li {
background-color: green;
overflow: hidden;
}
nav a {
background-color: pink;
}
nav li:hover a{
background-color: yellow;
}
<nav>
<ul>
<li>Projects</li>
<li>About</li>
<li>Services</li>
<li>Ethics</li>
<li>Contact</li>
</ul>
</nav>
There isn't an easy way around this without changing the line-height (even slightly), but I tried various hacks to see if we could move the link text up a couple of pixels without moving the active link.
If it is possible for you to make the a to be display: block, then this seems to work:
nav li {
background-color: green;
overflow: hidden;
}
nav a {
background-color: pink;
display: block;
/* tweak the values below to suit */
margin-top: -2px;
padding-bottom: 2px;
}
Solution: Use overflow:hidden, negative margin and padding as workaround this
The negative margin moves up the top of the link (which has the extra space) and the padding adds a little space for the descender. The òverflow:hidden on the li crops off the extra.
You can see it working below - Note I have greatly exaggerated the margin and padding to ensure that it works with no overlap, and I added a border around the links to make it clear where the link was:
ul {
margin: 0;
padding: 0;
border: 0;
vertical-align: top;
list-style: none;
}
nav {
height: 100%;
overflow: hidden;
position: absolute;
left: 0;
right: 0;
line-height: 1em;
font-size: 3rem;
font-family: "Times New Roman";
}
nav li {
background-color: green;
overflow: hidden;
}
nav a {
background-color: pink;
display: block;
margin-top: -20px;
padding-bottom: 20px;
border:1px solid blue;
}
nav li:hover a{
background-color: yellow;
}
<nav>
<ul>
<li>Projects</li>
<li>About</li>
<li>Services</li>
<li>Ethics</li>
<li>Contact</li>
</ul>
</nav>
That's as good as I can come up with, hope one of those options is suitable!
I have a horizontal scrolling menu with some of the main menu items having a dropdown menu. The problem is if I scroll the main menu the drop down menus do not follow (absolute positioning), or if I make them follow (relative) they push the main menu up.
Absolute:
Relative:
The CSS is:
.navbar {
width:100%;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.dropdown-content {
display: none; //displayed on hover
position: absolute; //or relative
background-color: #f9f9f9;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
Any suggestions as to what I can do to fix this?
What I am looking for is the absolute version - notice the drop down menu drops over the scroll bar, not pushing it down - but with the sub menu properly aligned.
See jsfiddle for example of absolute postioning:
https://jsfiddle.net/9hjgo1qc/7/
Just add vertical-align:top; on .dropdown class style. Fixes your problem.
Test it here
Update 1
Used JQuery to fix the problem.
See here
Update 2
You can achieve same thing for multiple menus with minor change in jquery method.
See here
Like I already said in the comment, you don't actually need any kind of positioning to achieve this. It's just a matter of good HTML code. I have already provided a codepen example, but it was anonymus and someone had rewritten it.
You can achieve exactly what you want in just a few lines of code. I have started editing your jsfiddle, but figured I have already given you all the code needed in my codepen example :)
.navbar {
margin: 200px auto;
display: flex;
width: 800px;
overflow-x: scroll;
}
ul {
min-width: 250px;
list-style: none;
}
li {
display: inline-block;
text-align: center;
height: 40px;
line-height: 40px; /* quick hack to center text vertically (assuming it is just one line), but I wouldn't use it for production - it is just for this quick example */
background: beige;
margin: 0;
border: 1px solid white;
}
ul li:not(:first-child) {
height: 0;
transition: all .3s ease-in;
visibility: hidden;
/* alternatively you can use transform and scaleY
transform: scaleY(0);
transform-origin: 50% 0; */
}
ul:hover li:not(:first-child) {
height: 40px;
visibility: visible;
/* transform: scaleY(1); */
}
<div class="navbar">
<ul>
<li>M1</li>
<li>M1-1</li>
<li>M1-2</li>
</ul>
<ul>
<li>M2</li>
<li>M2-1</li>
<li>M2-2</li>
</ul>
<ul>
<li>M3</li>
<li>M3-1</li>
<li>M3-2</li>
</ul>
<ul>
<li>M4</li>
<li>M4-1</li>
<li>M4-2</li>
</ul>
<ul>
<li>M5</li>
<li>M5-1</li>
<li>M5-2</li>
</ul>
</div>
This is dummy code, but I think you can translate it to your example, easily. Let me know if you need me to explain this further.
My menu is using a series of nested <ul> tags with sub <ul> and <li> within existing <li> calls. This is pretty standard for most menu's are far as I am aware. To make my website work well on mobile devices, I have decided to take a more responsive design approach and use #media query's to show or hide content as the browser is resized.
When my menu is shrunk down, the drop downs are hidden (for now). I will most likely introduce a hamburger type menu later on where you can click on a + icon beside the menu on the mobile version and see it's sub links.
As of right now, when the browser is resized the menu is then ordered as an absolute display and this disables the scrolling on the menu. If a user, say on an iPhone, turns the phone sideways, the menu is then cut off and they cannot scroll down to see the rest of the menu in this orientation. Here is an image to depict the issue:
And here is an example of the nested html code:
<div id="navmenu">
<ul>
<li><div class="home"></div></li>
<li class='storelink dropdown'><a class='dropbtn' href='/store'>Store</a>
<div class='dropdown-content'>
<a href='/store?group=1'>All Items</a>
</div>
</li>
<li class='cartmenu'><a href='/cart'>Cart</a></li>
<li class='accountmenu dropdown'><a class='dropbtn' href='/account'>Account</a>
<div class='dropdown-content'>
<a href='/account'>Customer login</a>
</div>
</li>
<li><a href='/services'>Services</a></li>
</ul>
</div>
and finally the relevant css
#navmenu .dropdown:hover .dropdown-content {
display: block;
position: absolute;
}
#navmenu {
overflow-y: scroll;
display: none;
clear: both;
background: #333;
left: 0;
position: absolute;
float: none;
margin: 0;
padding: 0;
width: 100%;
border-bottom: 2px solid #fff;
}
#navmenu ul {
width: 100%;
text-align: center;
}
#navmenu li {
float: none;
clear: both;
background: #333;
width: 100%;
text-align: center;
}
#navmenu li a {
display: block;
width: 100%;
clear: both;
margin: 0;
padding: 10px 0;
}
Why won't this scroll when resized? Thanks
Try adding this:
#navmenu {
height: 100%;
...
}
Hmm, you can try giving your #navmenu a fixed height.
Alternatively, you can try setting #navmenu to position:fixed (not absolute) and height:100%.
I'm working on making a responsive menu that by default is displayed inline with the site title. However on mobile the menu needs to display as a list below the site title and it's toggled by hitting a + or -. I've achieved all of this except for two small issues.
I can't seem to get the menu to display relative to the document flow so that it overlaps the text on the pages
I need the menu to be the full width of the page.
I'm not sure if I just need to take this menu and put it in its own div outside of the nav or if I'm just forgetting some css rule. It's currently set up as:
<nav>
<div id="nav-div">
<div id="title"></div>
<div id="menu-toggle"></div>
<div id="nav-links">
<ul>
<li>link 1</li>
<li>link 2</li>
<li>link 3</li>
</ul>
</div>
</div>
</nav>
CSS:
#nav-links {
position:absolute;
width:100%;
ul {
}
li {
display:block;
float: none;
border-bottom: 1px solid black;
&:last-child {
border-bottom: none;
}
a {
}
}
}
You need to set top and left properties on #nav-links. And if you set right too, you wont need width: 100%. Also make it position:relative. Like this:
#nav-div {
position: relative;
height: 50px;
}
#nav-links {
position:absolute;
left: 0;
right: 0;
...
}
Change 50px to whatever your navbar height is.
The way I ended up doing this was:
ul {
position: absolute;
width: 100%;
right: 0px;
left: 0px;
li {
width: 100%;
a {
width: #small-width; //defined with my variables
margin: 0px auto;
display: block;
}
}
}
I'm trying to create a horizontal menu with dropdown content boxes. I'm using the same method I'd use for a vertical menu with children that expand on :hover of their parent. It works fine, except that I can't seem to find a method that forces the dropdown content to stick around once the cursor moves from the parent element itself. You can see what I mean at http://asubtleweb.com/clients/kingswood/ ... The dropdown content isn't clickable because it contracts as soon as the mouse moves from its parent element.
Here's my CSS:
#header_menu nav { display: table; width: 30%; float: left; text-align: center; }
#header_menu nav ul, nav#mainmenu ul { list-style-type: none; }
#header_menu nav li { display: inline; margin-right: 2.5%; }
#header_menu nav a, nav#mainmenu a { font: 400 1.25em 'Oswald', sans-serif; color: black; text-transform: uppercase; }
#header_menu li .navhover { display: block; width: 100%; position: absolute; top: 50px; left: 0px; background-color: black; background-color: rgba(0,0,0,0.6); color: white; text-align: left; max-height: 0px; overflow: hidden; transition: all 1s linear; -wekbkit-transition: all 1s linear; }
#header_menu li:hover .navhover { max-height: 300px; min-height: 300px; }
#header_menu li .navhover article { margin: 20px; }
#header_menu li .navhover.news article { width: 30%; margin: 2.5% 0% 2.5% 2.5%; float: left; }
...and my HTML:
<div id="header_menu">
<nav>
<ul>
<li id="mission">
Mission
<div class="navhover">
[[CONTENT]]
</div>
</li>
<li id="news">
News
<div class="navhover news">
[[CONTENT]]
</div>
</li>
<li id="reserve">Reserve</li>
</ul>
</nav>
</div>
I've also tried making each parent element its own absolutely positioned block that expands on :hover, with no luck. I didn't expect to have so much trouble with the concept, but it's stumping me.
Simply add z-index: 1; to #header_menu li .navhover
As Francesco Frapporti pointed out:
Simply add z-index: 1; to #header_menu li .navhover
Edit: There is an error on your website moveWindow is not defined see body element
Simply add this to your css....
#header_menu li .navhover:hover{min-height:0;max-height:0;}
then it should work just fine!
The problem is that the parent element you are using with :hover doesn't actually "touch" the child element. So there is space between the parent and child element and that causes the parent element to lose focus when moving the mouse toward the child.
Choose whichever method you like to eliminate the gap between parent and child. Make the parent larger, move the child closer to the parent, etc.