Recently I have noticed that when you are styling menu item on:hover, some properties like text-shadow, color, background and and many others are applied to the menu item that is currently be hovered over.
However, it seems that the padding property is applied to all the menu items, not just the menu item being hovered over.
Here's an example: http://codepen.io/Bizzet/pen/LEvopq
.main-navigation a {
display: block;
text-decoration: none;
color: #fff;
font-size: 1.1em;
transition: 1s;
margin-bottom: -7px;
}
.main-navigation a:hover {
margin-bottom: 0;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
}
As you can see in Codepen, the text-shadow is applied to a single menu item while the padding is applied to all the elements.
What can I do to prevent this?
I only want one menu item to hover at once.
The padding is not being applied to all menu items. What's happening is that the height of the parent container is being expanded by the hover effect, and since the other menu items are top-aligned, they raise as well.
Try this:
.main-navigation a:hover {
...
margin-bottom: 0;
margin-top: -7px;
}
Demo
Problem
Your ul li a's have a negative margin-bottom initially.
When you hover over an a, though, you reset the margin-bottom to 0. This causes the box to grow in size and push the whole nav-bar upwards.
Insight
The padding is not being applied to all list items. One of the links in your nav boxes is pushing the whole navigation bar up, which gives the appearance of applying the padding to all list items.
Demo
Run this snippet for a demo. The menu-items are black.
header {
min-height: 10em;
background: rgba(0, 0, 0, 0.25);
position: relative;
}
h1 {
text-align: center;
}
.container {
background: green;
list-style: none;
position: absolute;
padding: 0;
margin: 0;
bottom: 0;
}
.container:after {
display: block;
content: '';
clear: both;
}
li {
float: left;
margin-right: 0.5em;
display: inline-block;
background: black;
position: relative;
}
span {
color: red;
margin-bottom: -0.75em;
display: block;
transition: all 3s;
}
span:hover {
margin-bottom: 0;
}
<header>
<h1>Title</h1>
<ul class="container">
<li class="item">
<span>Hello</span>
</li>
<li class="item">
<span>there</span>
</li>
<li class="item">
<span>friend</span>
</li>
</ul>
</header>
Solution
It should be noted that negative margins are usually not encouraged, unless you want element overlap. If it is necessary, it can be better to set a negative margin on 1 parent element than each individual child.
To hack this particular problem together, just replace this:
a:hover { margin: 0; }
with this:
a:hover { transform: translateY(-70%); }
Keep in mind that you might have to add -browser- prefixes to the transform rule. Browser support here
Related
This question already has answers here:
Image inside div has extra space below the image
(10 answers)
Closed 6 years ago.
I can't figure out how to remove this space from my navbar and the picture..
The CSS code I have for the navbar and the image is:
a {
text-decoration: none;
color: white;
padding-right: 5px;
padding-left: 5px;
padding-top: 0;
}
a:hover {
color: black;
}
header {
background-color: #C0C0C0;
margin: 3px 60px 0;
}
li {
display: inline;
border-right: 1px solid black;
border-left: 1px solid black;
border-bottom: 1px solid black;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
nav {
position: relative;
text-align: center;
}
ul {
list-style-type: none;
}
#bikebanner {
position: relative;
left: 65px;
}
#bikebanner is the image id.
And the html goes like so:
<header>
<img src="images/bicyclebanner.jpg" id="bikebanner" alt="People riding bikes." title="Biking">
<h1 id="pagetitle">Cycling Tours</h1>
<nav>
<ul>
<li>About Us</li>
<li>Ask Us</li>
<li>Destinations</li>
<li>FAQ</li>
<li>Reviews</li>
<li>Seminars</li>
<li>Trip Prep</li>
</ul>
</nav>
</header>
Looking for a universal fit as I have other things with white space between them as well.
Thanks.
Try adding this to your css:
img{
display:block;
}
img is of type inline-block which adds a little space which is hard to find.
setting it to block should fix it.
what space you are talking about ?
Keep in mind h1 by default has white space around it
every h1-h6 tag has a margin top and bottom by default. i think if you overwrite this in your css you have what you want.
h1 {
margin: 0;
padding: 0;
}
look at this jsfiddle https://jsfiddle.net/zn7wtdLp/
This drives a lot of people crazy initially and the solution is not obvious, but images, lists and list items end up with a small space like this due to the font size inherited by or set on the img or ul. If you do nothing, the img and ul inherit the body font size (often 14px - 16px) with results in this 0.25rem (or 3.5px - 4px) space issue.
Nav Items
There are two popular solutions:
Float your list items left and make sure that you add a clearfix to your ul or its container, or
My preferred solution: Set the font-size on the ul to 0 and then the font-size on the li to 1rem (or whatever).
So my CSS would look something like this:
ul {
font-size: 0;
list-style: none;
margin: 0;
padding: 0;
}
li {
display: inline-block;
font-size: 1rem;
}
Images
If you set the image to display: block, this would kill the space below the image. This comes with its own caveats as well. For example, if you want it centered after you switch it to display: block;, you'll need to set the side margins to auto. Something like this:
header img {
display: block;
margin: 0 auto;
}
The problem is display:inline. This treats the elements like text, so if you have
<li>...</li>
<li>...</li>
you have the problem you mentioned, because the linebreaks cause a space.
Try to put your list elements like this:
<li>...</li><li>...</li>
For other solutions see here
I already tried "width: 100%;" but the dropdown element then gets the same width as the whole page. I'm working with floats so maybe that needs a different approach?
I swear I've looked at similar questions but none of the solutions there worked for me. Can anyone see what I'm doing wrong? You can find the jsfiddle with all of the code here. I currently "solved" the problem with a fixed width.
Here is the HTML for the navi:
<nav role="navigation" class="navi">
<ul class="nav-elements">
<li>Home</li>
<li>Ongoing Stories
<ul>
<li>Sublink</li>
<li>Another Sublink with a long text</li>
</ul>
</li>
<li>Sleeping Stories
<ul>
<li>Sublink</li>
<li>Another Sublink</li>
</ul>
</li>
<li>News</li>
<li>About/FAQ</li>
</ul>
</nav>
And the CSS:
.navi {
float: left;
margin-bottom: 0.5em;
}
.navi ul {
padding-left: 0; /* Navi aligned left */
margin: 0;
}
.navi li {
background: #808080;
float: left;
padding: 0.2em 0.8em 0.2em 0.8em;
border: 1px solid black;
margin: 0 0.4em 0.4em 0;
list-style: none;
font-size: 1.2em;
border-radius: 10px;
}
/* nav-elements for dropdown-menus */
.nav-elements ul {
margin-top: 0.2em;
padding: 7px 10px 0 0;
}
.nav-elements li ul {
position: absolute;
left:-9999px; /* Hide off-screen when not needed (this is more accessible than display:none;) */
z-index: 1000;
width: 9.25em;
margin-left: -0.85em; /* to counter the padding in .navi li */
}
.nav-elements li:focus,
.nav-elements li:hover { /* main navi gets shadow while dropdown is active */
text-shadow: 0 0 7px rgba(255,255,255,.5); /* kind of a glow effect */
}
.nav-elements li:focus ul, /* show the submenu when user focues (e.g. via tab) the parent li [doesn't work?]*/
.nav-elements li:hover ul { /* show the submenu when user hovers over the parent li */
left:auto; /* Bring back on-screen when needed */
text-shadow: none; /* dropdown doesn't inherit shadow from main-navi*/
}
.nav-elements ul li {
float: none;
font-size: .9em;
}
According to your issue that you don't want to use fixed width then please check my Updted fiddle
I have used width:100% so it will change according to parent ul. What you need is to change width:100% and position:relative or parent li(.navi li) and then i removed margin-right as it was extra and you got the result.
Updated
As i have used position:relative so width:100 is taking width inside the border so you are missing 2px gap so just for workaround i have used width:101%. Please check my updated fiddle.
let me know if its what you need. Thank you :)
your second ul element can just be wide as the li element around it. try this:
#subMenuFoo {
display: none;
}
#foo:hover ~ #subMenuFoo {
display: block;
}
<div class="nav-elements">
foo
<div id="subMenuFoo">
bar
</div>
</div>
--
please mind the gap
When I hover mouse over menu items they don't always fit perfectly within the navigation bar, I am also unable to fix that tiny gap between border and last navigation item and the gap changes when I zoom in/out the page, when I zoom in/out on google chrome and hover over menu items the hovered item gets taller than the rest of the bar. I've been trying to figure this out for quite some time now. Thank you for your help in advance.
Main objectives: getting rid of the gap next to "contact", making hovered items fit into the navbar, fixing google chrome navbar zooming issue.
Here's my codepen: http://codepen.io/anon/pen/QbBgKR
<nav class="menu">
<ul class="clearfix">
<li>HOME </li>
<li>PROFILE</li>
<li>STUFF</li>
<li>STUFF</li>
<li id="long"> PRODUCTS<span class="arrow">▼</span>
<ul class="sub-menu">
<li>STUFF1</li>
<li>STUFF2</li>
<li>STUFF3</li>
</ul>
</li>
<li>CONTACT</li>
</ul>
</nav><!-- menu -->
.clearfix:after {
display: block;
clear: both;
}
.clearfix {
margin-left: -37px;
}
nav {
font-size: 1em;
width: 700px;
background-color: #3A5199;
font-family: Verdana;
}
#current {
background-color: #6082ec;
}
.menu li {
display: inline-block;
list-style: none;
position: relative;
width: 15.2%;
text-align: center;
margin-left: -0.4%;
margin-right: -0.4%;
}
.menu li:hover {
background-color: #6082ec;
}
.menu a {
text-decoration: none;
color: white;
display: block;
padding-top: 10px;
padding-bottom: 10px;
}
#long {
width: 24%;
}
.menu .arrow {
font-size: 12px;
line-height: 0%;
}
.sub-menu {
width: 128px;
position: absolute;
z-index: -1;
opacity: 0;
transition: opacity linear 0.15s;
background-color : #6082ec;
}
.menu li:hover .sub-menu {
z-index:1;
opacity:1;
}
.sub-menu li:hover {
background-color: #3A5199;
}
.sub-menu li {
width: 131%;
display: block;
right: 39.2px;
}
.sub-menu a {
position: relative;
text-align: center;
}
Using a reset stylesheet or something like normalize.css will go a long way in fighting various margin, padding and display inconsistencies across browsers and you won't have to do negative margin "hacks" like you did for .clearfix.
Although you have calculated your percentages correctly for your li to add up to 100%, the gap to the right of Contact arises with the pixel rounding of the percentage width you've applied.
15.2% of 700px = 106.4px
The browser will likely round down to 106px. The change in the gap when zooming is also likely related to the percentage widths. At one zoom level the value gets rounded differently.
106px * 5 = 530px + 24% of 700px (168px) = 698px
Since you're using a fixed with on your <nav> element, why not use fixed widths on the li also? Or change up the percentage values a bit. 15.2% for the home link creates more padding between the text Home and the left and right edges of the li than it does for Profile.
Fixed Width Solution
/* default width for all li */
.menu li {
width: 108px;
}
/* Home */
.menu li:nth-child(1) {
width: 100px;
}
/* Products */
.menu li:nth-child(5) {
width: 168px;
}
As far as zooming in Chrome and getting a height change when hovering, I cannot replicate that issue.
Negative margin for UL is working.
.clearfix {
margin-left: -37px;
margin-right:-0.4%;
}
It's strange math her - imho.
I'm trying to do something like file tree. The structure is like that:
<ul class="tree">
<li class="directory">
dir1
<ul>
<li class="file">file1</li>
<li class="file">file2</li>
</ul>
</li>
<li class="file">file3</li>
<li class="file">file4</li>
</ul>
I also used some CSS:
ul.tree li {
list-style: none;
padding: 0px;
padding-left: 20px;
margin: 0px;
white-space: nowrap;
}
ul.tree a {
color: #111;
text-decoration: none;
display: block;
padding: 0px 2px;
}
.tree li.directory {
background: url(/images/directory.png) left top no-repeat;
}
.tree li.file {
background: url(/images/file.png) left top no-repeat;
}
It gives me fine effect - I need tree more digged in with every inner directory, and <a> with width from given position to the end of line (tree area has specified width, but it can be scrolled if path or filename is longer then tree area's width). Well, it was ok until now.
But now I have to change it a little and put a "delete" option at the end of line. With it, <a> should end before "delete", so
display:block;
is probably no longer correct. I tried
display: inline-block;
but then, the <a> area ends with the end of file name - and I still need it until the "delete", which should be at the end of line.
The new structure should be like this:
<ul class="tree">
<li class="directory">
dir1Delete
<ul>
<li class="file">file1Delete</li>
<li class="file">file2Delete</li>
</ul>
</li>
<li class="file">file3Delete</li>
<li class="file">file4Delete</li>
</ul>
I don't know what styles or what else should I use to do it the way, I want to. So, could you help me, please?
I had to read your post multiple times to try to get what you were looking for. If I'm reading you correctly, what you want is the first <a> tag to act as a display:block so that when you hover over it the entire width is clickable, but you want the second <a> tag to float to the right on the same line.
I believe that this demo will accomplish what you wish. I changed the order of the anchor links to make it as easy as possible. Also added background colors so you could see what's going on.
<li class="file">DeleteLong Link Name
The CSS required would be:
ul.tree li {
list-style: none;
padding: 0px;
padding-left: 20px;
margin: 0px;
white-space: nowrap;
}
ul.tree a {
color: #111;
text-decoration: none;
display: block;
padding: 0px 2px;
background-color: gold; //so you can see what's happening
}
ul.tree .delete {
background-color: lightgreen; //so you can see what's happening
margin: 0 0 0 5px;
display: inline;
float: right;
}
ul.tree a:hover {
background-color: lightblue; //so you can see what's happening
}
.tree li.directory {
background: url(/images/directory.png) left top no-repeat;
}
.tree li.file {
background: url(/images/file.png) left top no-repeat;
}
If changing the order of the anchors is out of the question, I could muck around with some more elaborate CSS, but as the complexity of the CSS increases, so do your chances of it breaking in one browser or the other.
EDIT: Based on your reply, I've created some CSS to add an ellipsis (…) when the link text is too long. It requires setting a width on the main <ul>, but from your initial question it sounds like you're doing that anyway. You can see the updated JSFiddle here, and here's the updated CSS:
ul {
width: 333px;
}
ul ul {
width: inherit;
}
a {
overflow: hidden;
text-overflow: ellipsis;
}
ul.tree li {
list-style: none;
padding: 0px;
padding-left: 20px;
margin: 0px;
white-space: nowrap;
}
ul.tree a {
color: #111;
text-decoration: none;
display: block;
padding: 0px 2px;
background-color: gold; //so you can see what's happening
}
ul.tree .delete {
background-color: lightgreen; //so you can see what's happening
margin: 0 0 0 5px;
display: inline;
float: right;
}
ul.tree a:hover {
background-color: lightblue; //so you can see what's happening
}
.tree li.directory {
background: url(/images/directory.png) left top no-repeat;
}
.tree li.file {
background: url(/images/file.png) left top no-repeat;
}
Original Fiddle | Fiddle with long links
Change the anchor tags to inline block and then float the second one to the right
ul.tree a {
display: inline-block;
}
ul.tree li a:last:child {
float: right;
}
JSfiddle Demo
Have you considered using jQuery Javascript ?
You could use the append() function to add the <a> tags specifically where you need them to appear.
http://www.w3schools.com/jquery/html_append.asp
Adding some float and overflow to css:
ul.tree li {
...
clear: both;
overflow: auto;
}
.delete {
float: right;
}
.tree li a:first-child {
float: left;
}
http://jsfiddle.net/9rxeu/
I'm trying to create a submenu that stretches across an entire page on http://jobcreatr.com
The problem is that the submenu is only stretching from the top menu item all the way to the right. I want it to go all the way across. Also, there's some weird padding on the submenu items, which I think is related to the border bottom on hover - which I don't even want on the submenu items.
How do I get the submenu to stretch across the entire page, and also get rid of that weird padding/border-bottom.
Here's the css I have:
.sf-menu.sf-horizontal.sf-shadow ul, .sf-menu.sf-vertical.sf-shadow ul, .sf-menu.sf-navbar.sf-shadow ul ul {
width: 100%;
background-color: #F6F6F6;
background: none;
list-style-type: none;
text-align: center;
margin-top:22px;
overflow: none;
display: none;
}
.sf-menu.sf-horizontal.sf-shadow ul a, .sf-menu.sf-vertical.sf-shadow ul a, .sf-menu.sf-navbar.sf-shadow ul ul a {
background-color: #000/*#F6F6F6*/;
width: 9999px;
}
.sf-menu.sf-style-whiteshadow li {
overflow: visible;
}
.sf-menu.sf-style-whiteshadow li:hover {
border-bottom: 4px solid #000;
}
.sf-menu.sf-style-whiteshadow .sf-depth-2 {
border-bottom: none;
}
Here's the HTML:
<ul id="superfish-2" class="menu sf-menu sf-main-menu sf-horizontal sf-style-whiteshadow sf-total-items-3 sf-parent-items-1 sf-single-items-2 superfish-processed sf-js-enabled sf-shadow">
<li id="menu-1299-2" class="first odd sf-item-1 sf-depth-1 sf-no-children">
<li id="menu-1300-2" class="middle even sf-item-2 sf-depth-1 sf-no-children">
<li id="menu-1301-2" class="last odd sf-item-3 sf-depth-1 sf-total-children-1 sf-parent-children-0 sf-single-children-1 menuparent">
<a class="sf-depth-1 menuparent sf-with-ul" title="" href="http://jobcreatr.com/products">
<ul class="sf-hidden" style="float: none; width: 12em; display: block;">
<li id="menu-1632-2" class="firstandlast odd sf-item-1 sf-depth-2 sf-no-children" style="white-space: normal; width: 9999px; position: absolute; float: left;">
<a class="sf-depth-2" title="" href="http://www.google.com" style="float: none; width: auto;">test</a>
</li>
</ul>
</li>
</ul>
Ideally if you want to make an element take up the whole width you should have it on the same level as your uppermost element which also takes up the whole width (for example body, if your body does not have any width set) and then position this element absolutely with a width of 100%.
However in your case you could use fixed position, try changing your css rules where you have defined width of 9999px to this:
.sf-menu.sf-horizontal.sf-shadow ul a, .sf-menu.sf-vertical.sf-shadow ul a, .sf-menu.sf-navbar.sf-shadow ul ul a {
background-color: #000/*#F6F6F6*/;
width: 100%!important;
position: fixed;
left: 0;
}
The reason why you have to add the !important to your width is because currently the width is being overwritten by javascript responsible for making the menu work. Using !important isn't best practice and if you want to do it properly you should change your javascript so that the width does not get set by it: then you do not need to use the !important rule.
As mentioned in my comment above, change this
.sf-menu.sf-style-whiteshadow li:hover {
border-bottom: 4px solid #000;
}
to this:
.sf-menu.sf-style-whiteshadow > li:hover {
border-bottom: 4px solid #000;
}
to get rid of the bottom border of your submenu item.