Hoverable menu goes out of page - html

I have a hoverable menu as you can see in the code. However, I got a problem when I hover, which the hover content goes out of the page. When I use "position: relative" for the div(content) it is okay but then the text "Example" goes to the left, wonder how to fix.
When I use position: absolute:
When I use position: relative:
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: relative;
width: 200px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>

due to lack of space u'r getting this issue make width:200px; for ul
ul {
float: right;
position: relative;
width: 200px;
}
div {
display: none;
background-color: red;
position: relative;
width: 200px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>

You could use position absolute, and manipulate its positions setting a negative margin...
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: absolute;
width: auto;
margin-left: -26px;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>

Erase the div, apply the width to the ul and apply the display: none and hovering to the ol.
ul {
float: right;
width: 200px;
}
ol {
display: none;
background-color: red;
}
ul:hover ol {
display: block;
}
<ul>
<li>Example</li>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</ul>
Second version: If you want everything to be floated right, apply float: right; to ul and li in the HTML structure as used before:
ul {
float: right;
}
ol {
display: none;
background-color: red;
}
li {
float: right;
clear: right;
}
ul:hover ol {
display: block;
}
<ul>
<li>Example</li>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</ul>

It's natural behavior, it will depend on header text lenght, it will set your max lenght for below text, you'll need to define a fixed width for the header element and not on child one as you did.
Example of dynamic width (natural div property as a flex container):
ul {
float: right;
position: relative;
}
div {
display: none;
background-color: red;
position: relative;
}
ul:hover div {
display: block;
}
<ul>
<li>ExampleOfMagicMenu</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
Second example, setting fixed width to the parent box, letting child/s element/s with auto-width (they will never occupy more width than parent, as they can grow in height, overriding height auto with a fixed one will cause overflow):
ul {
float: right;
position: relative;
width: 100px;
text-align: right;
list-style: none;
}
div {
display: none;
background-color: red;
position: relative;
}
ul:hover div {
display: block;
}
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>

You can do it with the Flexbox without unnecessary floats and positioning.
Solution with the container as you wrote in the comment:
.container {
max-width: 960px;
margin: 0 auto;
border: 1px solid;
}
ul {
display: flex; /* displays children inline by default that's why you need to change its direction */
flex-direction: column; /* stacks children vertically */
align-items: flex-end; /* places them far right */
}
ul > div { /* modified for accuracy */
display: none;
background-color: red;
width: 200px;
}
ul li:hover + div { /* modified for accuracy since the inner div is the next element after the li */
display: block;
}
li + div:hover {display:block} /* needs to be in order to be displayed when hovering over */
<div class="container">
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
</div>
If you don't fancy the above solution then you can simply add right: 0 to the absolutely positioned div:
.container {
max-width: 960px;
margin: 0 auto;
border: 1px solid;
}
.container:after {
content: "";
display: block;
clear: both;
}
ul {
float: right;
position: relative;
}
ul > div {
display: none;
background-color: red;
position: absolute;
right: 0; /* added */
width: 200px;
}
ul:hover div {
display: block;
}
<div class="container">
<ul>
<li>Example</li>
<div>
<ol>
<li>Link 1</li>
<li>Link 2</li>
</ol>
</div>
</ul>
</div>

Related

Center html ul completely in container [duplicate]

This question already has answers here:
Vertically center ul in div
(5 answers)
Closed 3 years ago.
I have this unordered list and I want to display it vertically and also make it completely centered inside the parent container. I've managed to make it display vertically and be centered on the x-axis, but not on the y-axis. "vertical-alignment: middle;" doesn't seem to do what I want.
Consider this html-code:
div {
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
width: 100;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
To vertically align on y-axis add the below given css to ul:
display:flex;
justify-content:center;
align-items:center;
And remove width:100; from ul tag.
Demo
div {
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
padding: 0;
display:flex; /*add this */
justify-content:center; /*add this */
align-items:center; /*add this */
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
You can use display: flex for the div and margin: auto for the ul. And remove height and width rules from ul. here's the working Fiddle
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>
div {
display: flex;
margin: auto;
width: 90%;
height: 200px;
background-color: lightblue;
}
ul {
margin: auto;
list-style: none;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
To align vertically u can use line-height.
use line-height instead of height in div tag.
div {
margin: auto;
width: 90%;
line-height: 200px; /*change this */
background-color: lightblue;
}
div {
margin: auto;
width: 90%;
line-height: 200px;
background-color: lightblue;
}
ul {
list-style: none;
height: 100%;
padding: 0;
text-align: center
}
ul li {
display: inline;
margin-right: 20px;
vertical-align: middle;
}
<div>
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
</div>

Zooming in browser and element sizes

I have menu like this: jsfiddle. If in your browser start zoomin (Firefox ctrl+roller on mouse) elements will be enlarging. But not disproportionately. In some steps of zoom last menu element (my text 3) jumps to another row...
How ensure some scale ratio? (Without javascript)
EDIT:
Now I see in chrome with 100% zoom element (my text 3) is on another row but problem is still the same but reversed - if you will zooming element (my text 3) jumps back to row 1...
HTMl:
<ul>
<li>my text 1</li>
<li>my text 2</li>
<li>my text 3</li>
</ul>
CSS:
ul {
display: inline-block;
background-color: blue;
width: 298px;
padding: 0;
}
ul li {
display: block;
float: left;
margin-right: 20px;
}
ul li a {
display: inline-block;
background-color: red;
padding: 10px;
}
This is not a browser zoom feature issue.
You have limited the space in which your floated <li> can be contained. On my browser the text of each <li> takes up approximately 80px. Each <li> is approximately 100px because you added margin to the right side of each one. So, 100px * 3 = 300px and your container is only 298px.
There are multiple solutions to this problem like flexbox, inline-block, etc. but the easiest for you might be to remove the margin from the last <li>.
ul {
display: inline-block;
background-color: blue;
width: 298px;
padding: 0;
}
ul li {
display: block;
float: left;
margin-right: 20px;
}
ul li:last-child {
margin: 0;
}
ul li a {
display: inline-block;
background-color: red;
padding: 10px;
}
<ul>
<li>my text 1</li>
<li>my text 2</li>
<li>my text 3</li>
</ul>
But then you end up with extra background blue. To fix this don't set a set width on the <ul> and clear the floated elements within the <ul> so you can still see the background blue.
ul {
display: inline-block;
background-color: blue;
padding: 0;
overflow: hidden; /* clearfix: clears floats */
}
ul li {
display: block;
float: left;
margin-right: 20px;
}
ul li:last-child {
margin: 0;
}
ul li a {
display: inline-block;
background-color: red;
padding: 10px;
}
<ul>
<li>my text 1</li>
<li>my text 2</li>
<li>my text 3</li>
</ul>

Assistance with vertical navigation

I am trying to create a vertical navigation in my HTML document, but I cannot seem to get the main menu to line up evenly. Here is my HTML for the vertical navigation:
<div id="navbar">
<ul>
<li>Menu 1</li>
<li>Menu 2
<ul>
<li>Drop 1</li>
<li>Drop 2</li>
<li>Drop 3</li>
</ul></li>
<li>Menu 3</li>
<li>Menu 4
<ul>
<li>Drop 1</li>
<li>Drop 2</li>
</ul></li>
<li>Menu 5</li>
</ul>
</div>
And my CSS:
#navbar {
margin-left: -40px;
}
#navbar li{
list-style: none;
position: relative;
width: 209px;
padding: 6px;
line-height: 20pt;
cursor: pointer;
}
#navbar ul ul{
margin-left: 100px;
margin-top: -28px;
visibility:hidden;
height: 100px;
}
#navbar ul li:hover ul{
visibility:visible;
}
This is my first post ever, so I apologize if I didn't post in the correct format. This code is also from a much larger HTML/CSS file, so I just copy/pasted the only part I'm having an issue with. If I need to post a screenshot of what I'm talking about I can do that.
Thank you in advance!!
demo - http://jsfiddle.net/uab2hr50/2/
if you are looking to align the sub menu below the main menu
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#navbar ul {
border: 1px solid red;
display: inline-block;
padding: 6px;
}
#navbar li {
list-style: none;
position: relative;
width: 209px;
line-height: 20pt;
cursor: pointer;
}
#navbar ul ul {
display: none;
padding: 0;
border: 0;
}
#navbar ul li:hover ul {
display: block;
}
<div id="navbar">
<ul>
<li>Menu 1
</li>
<li>Menu 2
<ul>
<li>Drop 1
</li>
<li>Drop 2
</li>
<li>Drop 3
</li>
</ul>
</li>
<li>Menu 3
</li>
<li>Menu 4
<ul>
<li>Drop 1
</li>
<li>Drop 2
</li>
</ul>
</li>
<li>Menu 5
</li>
</ul>
</div>
There are a few problems here preventing the display you expect:
First: the fiddle
CSS CHANGES
#navbar li{
list-style: none;
position: relative;
/*width: 209px;*/
padding: 6px;
line-height: 20pt;
cursor: pointer;
display: block;
}
#navbar li:after {
content: '';
display: table;
clear: both;
}
#navbar ul a {
display: inline-block;
}
#navbar ul ul{
margin-top: 0;
visibility:hidden;
height: 100px;
padding: 0;
display: inline-block;
vertical-align: top;
margin-bottom: -9000px;
}
#navbar ul ul li:first-child {
padding-top: 0;
}
We removed quite a bit of your padding and margin rules here, and stopped setting a width on the li that you went ahead and broke out of anyway in the original code.
Then, we told both the a and ul elements to display as inline-block, told them they were to vertically align at the top and removed the padding-top off the first child of your sub-nav.
Then, we way over-compensate for the height of your lists by setting a margin-bottom of -9000px to pull your subsequent list items up to where they belong.
No absolute positioning needed, which would probably require some JavaScript to position everything reliably for you given different conditions.
Hope that helps.

Prevent Div from moving

I am working with a website with css drop down menus within the header div. When the drop down menu appears it resizes the header div therefore shoving down the content div.
In the body of my index.php:
<div class="top"></div>
<div class="container">
<?php include_once("header.php"); ?>
<div class="content"></div>
</div>
The header.php
<div class="header">
<div style="display: table-cell; width: 250px; text-align: center;">
LOGO
</div>
<div style="display: table-cell;">
<br><br><br>
<ul>
<li>Link 1
<ul>
<li>Monkey 1</li>
<li>Monkey 2</li>
<li>Monkey 3</li>
<li>Monkey 4</li>
<li>Monkey 5</li>
<li>Monkey 6</li>
<li>Monkey 7</li>
</ul>
</li>
<li>Link 2
<ul>
<li>Monkey 1</li>
<li>Monkey 2</li>
</ul>
</li>
<li>
Link 3
<ul>
<li>Monkey 1</li>
<li>Monkey 2</li>
<li>Monkey 3</li>
</ul>
</li>
<li>Link 4</li>
<li>Link 5</li>
<li>Link 6</li>
</ul>
</div>
</div>
And main.css
ul{
padding: 0;
list-style: none;
}
ul li{
float: left;
width: 100px;
text-align: center;
}
ul li a{
display: block;
padding: 5px 10px;
color: #333;
background: #f2f2f2;
text-decoration: none;
}
ul li a:hover{
color: #fff;
background: #939393;
}
ul li ul{
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
.top{
background: #1b2d3c;
width: 100%;
height: 40px;
}
.container{
width: 1100px;
height: 1000px;
}
.header{
display: table-row;
width: 1100px;
height: 130px;
}
.content{
position: absolute;
background: #fff;
width: 1100px;
height: 500px;
}
* {
background: #87a0b4;
margin: 0px;
padding: 0px;
margin-left: auto ;
margin-right: auto ;
}
I apologize for the lengthy post. How can I prevent the problem I am having? I want to be sure I am doing things correctly before I get too deep into the project.
You need to change position of ul li:hover ul to absolute, and add some other properties like this JSFiddel (Source)
ul li:hover ul {
display: block;
position: absolute;
width: 100px;
z-index: 100;
}
Hope this will help you ..
As was said in the previous answer, you need to set position: absolute. I'd like to add a bit of information as to why.
According to MDN:
Elements that are positioned relatively are still considered to be in the normal flow of elements in the document. In contrast, an element that is positioned absolutely is taken out of the flow and thus takes up no space when placing other elements. The absolutely positioned element is positioned relative to nearest positioned ancestor. If a positioned ancestor doesn't exist, the initial container is used.
Basically, by giving an element absolute positioning, it is no longer being taken into account when positioning the rest of the page. It will take up its alloted space in its set position no matter what.
In your case, the div was moving relative to the elements surrounding it. By using position: absolute, you are ommiting and relativity.

How to expand rows containing floated elements expand to 100% width?

I'm working on a nav bar style. I want the border to expand to 100% width of the area the menu is taking up, but I want the elements in the rows to float to the right of this 100% width area. Unfortunately, if I get everything floated to the right then it doesn't expand to full width.
Here's an image to check out: http://i.imgur.com/EKd3cZY.png
You can see what width it should be and what width things actually are.
Here's my HTML:
<section class="row">
<nav class="top-bar-navigation">
<div class="main-menu-holder">
<ul class="main-menu">
<li><a class="active" href="#">Active</a></li>
<li>Page 2</li>
<li>Page 3</li>
<li>Page 4</li>
<li>Page 5</li>
</ul>
<button>CTA BUTTON</button>
</div>
<ul class="secondary-menu">
<li>Support</li>
<li>Docs</li>
<li>Why</li>
<li>Social</li>
<li>Link</li>
</ul>
</nav>
</section>
Here's the SASS I've created for the nav element. There are some other styles for the default elements like typography but I don't think it's relevant to this issue:
.top-bar-navigation {
width: 100%;
clear: both;
.main-menu-holder {
border-bottom: 2px solid $pale-grey;
overflow: hidden;
}
.main-menu-holder,
.secondary-menu {
float: right;
}
span,
button,
.main-menu {
display: inline-block;
}
li {
display: inline-block;
}
a {
color: black;
font-weight: 300;
}
a.active {
font-weight: 700;
}
}
Here is the Row style:
.row {
width: 90%;
margin: auto;
max-width: 1100px;
margin-bottom: 5px;
}
.row:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Have you tried using a <hr /> or creating a new div with a class on it to style it to create the same effect?