div height: 0; without any floating child elements? - html

Here's some HTML I have
<nav class="navlist">
<span class="left">
<li><a class="active" href="#">Home</a></li>
<li>Work</li>
<li>Services</li>
</span>
<span class="right">
<li>About</li>
<li>Blog</li>
<li>Contact</li>
</span>
</nav>
Relevant CSS:
.navlist {
position: fixed;
top: 0;
width: 100%;
list-style: none;
background-color: rgba(255,255,255,0.4);
}
.navlist span {
position: absolute;
margin: 10px 0;
}
.navlist .left {
right: 0px;
margin-right: 50%;
padding-right: 75px;
}
.navlist .left li {
margin-left: 75px;
}
.navlist .right {
left: 0px;
margin-left: 50%;
padding-left: 75px;
}
.navlist .right li {
margin-right: 75px;
}
.navlist li{
display: inline;
}
.navlist li a {
font-family: "Futura Thin", sans-serif;
font-size: 1.2em;
color: black;
text-decoration: none;
}
Why is the height of the <nav> element 0 instead of wrapping the height around the child elements? I've tried absolutely everything, adding overflow: auto; etc. and nothing works without simply defining the height manually, which is definitely not what I want. Any help?

<span> should be <ul> or <li> should be <span> or any inline-elements to make a valid code. best is to use <ul><li><a> for a list of links.
position:absolute;(or fixed) takes element out of the natural flow of the page, so <nav> have no content to make it grow.

this is caused by your
position:absolute
rule on the span elements.
Absolutely positioned elements don't fill the parent container, causing it to have a height of 0px.
Try making the same layout without using absolute positioning, and you should be fine.
Also, the <li> elements should be in a <ul> parent, not a <span>

You have taken <li> without <ul> or <ol> it is not a best practice.
absolute: The element is positioned relative to its first positioned (not static) ancestor element, So its container doesnt have specific value.
<ul>
<li><a class="active" href="#">Home</a></li>
<li>Work</li>
<li>Services</li>
</ul>
Need to wrap as above and need to give style to remove its default bullets.

Your child elements are positioned as absolute, thus also taking them out of the flow. Because of this, the .navlist element doesn't know how to expand.
Use floats to position your navigation lists and then user the overflow:hidden fix on the .navlist to have it expand to fit the child elements.

As others have said, positioning a child element as absolute will pull it out of the layout, its parent will then always have a height of 0 as it technically has no layout inside of it.
It completely depends on what your end result should look like so its hard to advise but a little reduced case of what you may want ( with a red background colour to make it obvious height is set on the nav is here:
http://jsbin.com/osobor/1/
.navlist {
position: fixed;
top: 0;
width: 100%;
list-style: none;
background: red;
}
.navlist ul {
float: left;
width:50%;
padding:0;
margin: 0;
list-style: none;
}
.navlist .right {
float:right;
}
.navlist li a {
font-family: "Futura Thin", sans-serif;
font-size: 1.2em;
color: black;
text-decoration: none;
}
Edit: Also your spans should be UL ( or OL ) elements if you're nesting LI's within them ( I've added this to the jsbin example )

Related

Links inside list items have a height greater than the list element - what's going on?

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!

How to make sub menu span full width of the browser window?

I want my sub menu to span the full width of the browser window like the below image:
I am using Bootstrap, also my main menu is floated to the right.
I have created a demo on what I have done so far. How do I achieve this result?
http://codepen.io/ifusion/pen/oLVVXj
First of all, bootstrap makes you really unflexible. So if you want to use it I suggest to move the submenu out of the menu's elements, because the width:100%; is dependent on the parent. So everything that should be wider than the parent, shouldn't be the child of this parent element. In addition position:absolute is dependent on the next parent with position:absolute or position:relative. So there are many things that don't make it easy. To move the submenu would make it a lot easier. There you can just use width:100%; and position:absolute with left:0.
Alternatively to get the submenu out of the flow of the page, you could use position:fixed. And width:100%. Check out the Codepen for this solution. I like the first one more, even if it's more work. However, fixed positioning has some side effects, but maybe it's not important for you.
The position absolute child will position with respect to the closest position relative parent, so removing the position relative for main-menu li will solve this issue. Also remove the padding and margin from the body and html.
body, html{
margin: 0;
padding: 0;
}
.main-menu {
list-style-type: none;
padding: 0;
margin: 0;
float: right;
}
.main-menu li {
float: left;
}
.main-menu li a {
display: block;
background: #c2c2c2;
padding: 20px;
color: #337ab7;
text-decoration: none;
}
.main-menu-dropdown {
position: absolute;
left: 0;
right: 0;
display: block;
padding: 0;
list-style-type: none;
background-color: black;
text-align: center;
}
.main-menu-dropdown li {
float: none;
display: inline-block;
margin-left: -4px;
}
.main-menu-dropdown li a {
background: black;
display: inline-block;
}
<div class="container">
<div class="col-md-12">
<ul class="main-menu">
<li>First item</li>
<li>
<a class="has-dropdown" href="#">Second Item</a>
<ul class="main-menu-dropdown clearfix">
<li>Sub item 1</li>
<li>Sub item 2</li>
<li>Sub item 3</li>
</ul>
</li>
<li>Third Item</li>
<li>Fourth Item</li>
</ul>
<div class="col-md-12">
I need the sub menu to span the width of the browser
</div>
</div>
</div>
First off, the width of the submenu is being restricted because it's parent element has position: relative.
Once that is removed the submenu becomes full width, however the items are still aligned left.
In the example below I made .main-menu-dropdown use display: flex and then centered the items within it.
http://codepen.io/adrianlynch/pen/RRddjk
.main-menu-dropdown {
position: absolute;
left: -15px;
right: -15px;
display: flex;
justify-content: center;
margin: 0;
padding: 0;
list-style-type: none;
background: black;
}

Whenever I use absolute positioning to vertically center, the entire nav disappears

ul {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333333;
position: relative;
li {
height: auto;
width: 20%;
position: absolute;
top: 50%;
transform: translateY(-50%);
a {
display: block;
color: white;
text-align: center;
padding: 16px;
text-decoration: none;
}
}
.float-left {
float: left;
font: 2em bold sans-serif;
}
}
Here is my html for context. I added another div just to test out vertical centering on a different element and it works fine. But I couldn't keep the li's on the nav from disappearing whenever I give them absolute positioning. Sorry it's in sass.
<ul>
<li class="float-left">Michael Thomas</li>
<li>About</li>
<li>Résumé</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
When the "li"s are inline/relative, they force the parent "ul" to take the dimensions of the child elements. But when you change the "li"s to position absolute, the "li"s no longer force the parent "ul" to take encompass the shape of its content, so the parent "ul" has a height and width of zero. If you removed the "overflow:hidden" on the parent I think you'd still see its contents. I think you need to give your nav/ul a height and width.

How to position a ul element over a background link-image?

I want to position the <ul> element over the background link-image (black square).
To the right of the words "ABOUT" and "CONTACTS", I cannot click on the link image.
I need to be be able to click on the background link-image every where outside of the
link texts.
Here is what I have tried: Jsfiddle
HTML:
<div class="weekend">
<a href="/all">
<img src="http://cdn.allfun.md/2014/01/23/10/52e0cd02e892f.jpg">
</a>
<ul class="all">
<li class="about">About</li>
<li class="contacts">Contacts</li>
</ul>
CSS:
.all{
position: absolute;
width: 290px;
top: 15px;
left: 15px;
}
.about{
display: block;
font-size: 20px;
font-weight: 700;
text-transform: uppercase;
}
.contacts{
display: block;
font-size: 20px;
font-weight: 400;
text-transform: uppercase;
}
Here is one way of doing it without having to absolutely positioning each link.
Start with your HTML:
<div class="weekend">
<a href="/all">
<img src="http://cdn.allfun.md/2014/01/23/10/52e0cd02e892f.jpg">
</a>
<ul class="all">
<li class="about">About</li>
<li class="contacts">Contacts</li>
</ul>
</div>
And modify your CSS as follows:
.weekend {
position: relative;
}
.all {
display: inline-block;
position: absolute;
width: 10px; /* Set to a small value, 0 will also work */
top: 15px;
left: 15px;
margin: 0;
padding: 0;
border: 1px dashed yellow;
}
.all li {
display: inline-block;
font-size: 20px;
text-transform: uppercase;
border: 1px dotted yellow;
}
.about{
font-weight: 700;
}
.contacts{
font-weight: 400;
}
First: set position: relative to .weekend, that way ul.all is positioned with respect
to its parent block container.
For ul.all, zero out the margin and padding to reset any unwanted whitespace, and
then set display: inline-block to get a shrink-to-fit width.
For the link link elements, ul.all li, use display: inline-block which will
give you better control over padding and margins if needed.
The key point now is to set the width of ul.all to a small value, 10px for example,
(0 also works). This shrinks the edges of ul.all so that they no longer extend
beyond the edges of the li link elements, so you can then click on the background
element outside of the edges of the inline boxes containing the link text.
Essentially, the ul.all li elements are overflowing outside the edges of the parent
ul.all container, which is a bit odd but in this case, exactly what is needed.
See demo at: http://jsfiddle.net/audetwebdesign/91ea4tfw/
Note that you can add top/bottom margins to ul.all li and the resulting whitespace
will also allow you to click on background link-image. In this case, be sure to
set width: 0 to ul.all and remove the yellow border (for demo only).

How to make horizontal dropdown content area stick around?

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.