Css display - Width menu when hover on li - html

I have css width problem with my menu and submenu
My menu is horizontaly like -
<ul>
<li> Menu <div style="diplay:none"> Submenu </li>
<li> Menu <div style="diplay:none"> Submenu </li>
</ul>
The width of <li> is auto, when hover on <li> the display but when the div width is bigger than the<li> ,there is a gap
I want that the <li> width doesn't move whenever I hover
Do you have a solution to keep <li> width fixed when I hover ?
Thanks

Typically dropdown menus are positioned absolutely within their relatively positioned parent element so they do not take up any space.
Here is a basic example. Modify to your needs.
ul, li {
margin: 0;
padding: 0;
}
.menu li {
display: inline-block;
background-color: rgba( 123, 123, 123, 1 );
cursor: pointer;
}
.menu li:hover {
background-color: rgba( 123, 123, 123, 0.5 );
}
.has-submenu {
position: relative;
}
.has-submenu li {
display: block;
}
.has-submenu > ul {
display: none;
position: absolute;
width: 100%;
}
.has-submenu:hover > ul {
display: block;
}
<ul class="menu">
<li>Item</li>
<li class="has-submenu">
Item with submenu
<ul>
<li>Item</li>
<li>Item</li>
</ul>
</li>
<li>Item</li>
</ul>

Related

Mouse Hover Highlight Customisation via CSS

The following is a TOC I have implemented on an instance of Confluence.
It's look has been customized so that when hovering over a menu item with the mouse, the corresponding menu item is highlighted as in the case of the 2. Navigation Bar menu item in the above image.
The hover effect is achieved via the following CSS code:
.toc-link:hover {
background-color: #e5e5e5;
text-decoration: none;
}
I'd like for the hover effect to span the entire width of the box though, similar to the image below:
What property would I have to insert into my CSS code to achieve the desired effect?
Thank you.
This can be achieved by setting display:block on your <a> element. The hover styles should be on your anchor tag, not on your <li>, for example:
a {
display: block;
text-decoration: none;
}
a:hover {
background-color: #e5e5e5;
}
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
If your list items do not have an anchor tag inside, you can achieve it like so:
li {
display: block;
}
li:hover {
background-color: #e5e5e5;
}
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
You can try this:
#content {
border: 1px solid #DDDDDD;
background-color: #F6F6F6;
padding-right: 25px;
}
li{
padding: 5px;
list-style: none;
}
li:before {
content: "• ";
color: #ABADBB;
}
li:hover {
background-color: #DDDDDD;
}
<div id="content">
<ul>
<li>
Opening the Asset Browser
</li>
<ul>
<li>1. Menu</li>
<li>2. Navigation Bar</li>
<li>3. Folder Tree</li>
<li>4. Search Result Pane</li>
</ul>
<li>
Live Updates for Asset Resources Selectors
</li>
<li>
Texture Tool-tips
</li>
</ul>
</div>

CSS3 show a division on hover of another element

I have the following code to show a division on hover. It is initially hidden and i'm trying to show one division on hover of another element.
.topNav {
padding: 1px 15%;
background: #006cb4;
color: white;
}
.mainMenu {
list-style-type: none;
}
.mainMenu li {
display: inline-block;
padding: 3px 15px;
font-size: 20px;
}
.mainMenu li a {
text-decoration: none;
color: white;
}
#item1 {
display: block;
}
#item1:hover #item1detail {
background: #444;
visibility: visible;
}
#item1detail {
position: absolute;
top: 152px;
left: 250px;
background: #ccc;
width: 750px;
height: 400px;
border: solid 1px black;
border-radius: 0 0 10px 10px;
visibility: hidden;
}
<div class="topNav">
<ul class="mainMenu">
<li><a id="item1" href=""> item 1</a>
</li>
<li> item 3
</li>
<li> item 4
</li>
<li> item 5
</li>
<li> item 6
</li>
<li> item 7
</li>
<li> item 8
</li>
<li> item 9
</li>
</ul>
<div id="item1detail">
Some random content
</div>
</div>
on hover of the list item item1 i want to show the division itemdetail. The above code is not working. What am i doing wrong?
As I see it the only solution to display the given div without touching the HTML would be Javascript... As the others suggested already...
BUT... there's a solution with one slight change to your HTML and CSS each.
The main problem is this CSS-selector:
#item1:hover #item1detail
which would translate to "id item1detail INSIDE of an hovered id item1".
You can fix this by placing the div inside of the li and change the selector to:
#item1:hover + #item1detail
Since the div is positioned absolute anyway it doesn't make a visual difference... at least for your snippet...
Updated version of your snippet:
.topNav
{
padding: 1px 15%;
background: #006cb4;
color: white;
}
.mainMenu
{
list-style-type: none;
}
.mainMenu li
{
display: inline-block;
padding: 3px 15px;
font-size: 20px;
}
.mainMenu li a
{
text-decoration: none;
color: white;
}
#item1
{
display: block;
}
#item1:hover + #item1detail
{
background: #444;
visibility: visible;
}
#item1detail
{
position: absolute;
top: 152px;
left: 250px;background: #ccc;
width: 750px;
height: 400px;
border:solid 1px black;
border-radius: 0 0 10px 10px;
visibility: hidden;
}
<div class="topNav">
<ul class="mainMenu">
<li >
<a id="item1" href=""> item 1</a>
<div id="item1detail">
Some random content
</div>
</li>
<li> item 3</li>
<li> item 4</li>
<li> item 5</li>
<li> item 6</li>
<li> item 7</li>
<li> item 8</li>
<li> item 9</li>
</ul>
</div>
You'll have to use javascript
<script>
function myFunction() {
if (document.getElementById("item1detail").hidden==false){
document.getElementById("item1detail").hidden = true;
}else{
document.getElementById("item1detail").hidden = false;
}
}
</script>
and
<div class="topNav">
<ul class="mainMenu">
<li><a id="item1" onhover="myFunction()" href=""> item 1</a>
</li>
<li> item 3
</li>
<li> item 4
</li>
<li> item 5
</li>
<li> item 6
</li>
<li> item 7
</li>
<li> item 8
</li>
<li> item 9
</li>
</ul>
<div id="item1detail">
Some random content
</div>
</div>
I would do that using jQuery.
$('#item1').hover(function(){
$('#item1detail').show();
}, function(){
$('#item1detail').hide();
});
The reason your CSS isn't working is because you're using this selector:
#item1:hover #item1detail
Which selects the element with id #item1detail occurring within the element with id #item1, if the #item1 element is hovered.
In your current markup, #item1detail is outside #item1, and so does not match the selector. Moving #item1detail should get you the behavior you want. (And there will probably be some layout work to do from that point.)
The #item1detail element is not a sibling of the #item1 element, so that is why the #item1:hover #item1detail CSS rule does not apply as you expect it to.
I believe if this is to work with CSS only (not JavaScript), then you will have to make #item1detail a sibling of #item1.

I want my dropdown menu to have a max-width, but my CSS isn't working as expected

I want my dropdown menus to be no more than 250px wide, and the text to wrap to the next line. I set a max-width but they are not expanding.
http://jsfiddle.net/wtpvejjh/1/
<nav>
<ul>
<li>First
<ul>
<li>I want this to wrap to the next line at 250px</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Second
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Third
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
</ul>
</nav>
To restrict the specific LI (as per OP's original question):
Set the nav ul {width:250px} and clear the floated li's. They'll then sit below eachother and will only be as wide as their content up until they are as wide as the parent (250px) and are forced to wrap.
nav li {
list-style: none;
float:left;
position: relative;
padding: 10px;
background: #eee;
}
nav li a {
display:inline-block; /* Make these inline or inline block so their width is collapsed. */
}
nav li ul {
display: none;
position: absolute;
top: 100%;
left: 0;
padding: 0;
width: 250px; /* Set width. This will 'contain' the children. */
}
nav li ul li {
clear:both; /* Clear these so they stack. */
}
nav li ul li a {
padding: 5px;
color: red;
text-decoration: none;
}
li:hover ul {
display: block;
}
<nav>
<ul>
<li>First
<ul>
<li>I want this to wrap to the next line at 250px</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Second
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Third
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
</ul>
</nav>
To restrict the child UL to a max-width (as per OP's comment):
It feels a bit 'hacky' and your mileage may vary but the following works for me...
Use inline-block rather than floating the parent li's. Set the child ul to the desired max width and present the child lis as table-rows. This should mean that the 'table-row' will be collapsed and held open by the content up until it reaches its parent's bounds - at which point the content will wrap.
nav {
font-size:0; /* set font size to avoid the natural margin that exists between inline-block elements */
}
nav li {
font-size:16px; /* undo font size change to avoid the natural margin that exists between inline-block elements */
list-style: none;
display:inline-block; /* display inline (rather than float) */
position: relative;
background: #eee;
padding: 10px;
}
nav li:hover {
background: #ddd;
}
nav li a {
display:block;
}
nav li ul {
display: none;
position: absolute;
top: 100%;
left: 0;
padding: 0;
width:250px; /* fix at your desired max width */
}
nav li ul li {
display:table-row; /* display like a table-row */
}
nav li ul li a {
padding: 10px;
color: red;
text-decoration: none;
}
li:hover ul {
display: block;
}
<nav>
<ul>
<li>First
<ul>
<li>I want this to wrap to the next line at 250px</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Second
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
<li>Third
<ul>
<li>Something</li>
<li>Something</li>
<li>Something</li>
</ul>
</li>
</ul>
</nav>
Update (as per OP's comment regarding the need for a box-shadow)
Assuming you're able to edit the HTML, you'll need to wrap the child ULs in an extra element.
See: http://jsfiddle.net/wtpvejjh/49/
FIDDLE HERE http://jsfiddle.net/wtpvejjh/30/
.Check this i just played around with your bit of code and the solution was easy , actually you need to give max width to the nav li ul li not the nav li ul as you did.
NOTE - Sometimes when you give max width and if a single word occupies greater width than the word comes out of the item, therefore use word-wrap:break-word; it will break the word and make it adjust the width.
Simply, you just need to add the width property of your second level li to your css as follows:
nav ul li ul li{
width: 250px;
}
Checkout this DEMO
for a smooth look pseudo-elements are the answer
Giving the nav ul a fixed width and clearing it's elements float is correct.
Furthermore using :before and :after pseudo elements you'll give visual width coherency to the nav li ul li elements,
check out the fiddle.

h3 and list dropdown menu CSS3

got an html list working as a dropdown menu with CSS when you hover through a < li > element like "Products" in my example. But what I want is the same effect when hover through < h3 > like "Contact" from my example. Is it possible?
Here's the html:
<h3>Contact</h3>
<ul>
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul>
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
And the CSS code:
ul li ul {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
Thank you very much in advance.
On hover you can only control the CSS of the element you hover over, or the CSS of elements within the element you hover over (one of its children).
So you can not make the ul change styles when you hover over the h3 because they 1) are not the same object and 2) do not have a parent-child relationship (they are siblings).
To show the menu when hovering over the h3, you can wrap both of them inside another object (div) and use this for the hover event. To distinguish between the two hovers you can add classnames to both the uls.
See this JSfiddle, or the code below:
<div class="container">
<h3>Contact</h3>
<ul class="menu">
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul class="submenu">
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
</div>
.container ul{
display: none;
}
.container:hover ul.menu{
display: block;
}
ul li ul.submenu {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
In short - you should nest ul inside the h3
<h3>
Contact
<ul>
<li>Home</li>
<li>About</li>
<li>
Products ▾
<ul>
<li>Laptops</li>
<li>Monitors</li>
<li>Printers</li>
</ul>
</li>
<li>Contact</li>
</ul>
</h3>
And in your css:
ul li ul {
display: none;
}
ul li:hover ul{
display: block; /* display the dropdown */
}
h3 > ul {
display: none;
}
h3:hover > ul {
display: block;
}
Here's the demo: https://jsfiddle.net/mscehjLf/1/

Horizontal CSS dropdown menu

I am trying to make a horizontal drop down menu in CSS. However, it appears vertically:
I want the two topmost menu items to be horizontal. What can I do, besides making a table with one row?
ul ul {
display: none;
}
ul li:hover > ul {
display: block;
}
<ul>
<li>
abc
<ul>
<li>abc</li>
<li>abc</li>
</ul>
</li>
<li>
abc
<ul>
<li>abc</li>
<li>abc</li>
</ul>
</li>
</ul>
You can try floating the list items:
.root {
overflow: hidden; /* clear float */
}
.root > li {
float: left;
}
<ul class="root">
<li>
abc
<ul>
<li>abc</li>
<li>abc</li>
</ul>
</li>
<li>
abc
<ul>
<li>abc</li>
<li>abc</li>
</ul>
</li>
</ul>
You can add submenu a class/id with
.inline-menu{
display: inline;
}
http://jsfiddle.net/dyaskur/fby9fan6/
The gist of your question is actually this: what is the difference between inline and block elements? This is a fundamental question that is important to understanding the basics of layout in CSS/HTML. There is a good write-up on this topic and some of the trade-offs of the various approaches at:
http://designshack.net/articles/css/whats-the-deal-with-display-inline-block/
Basically, <li> is block-level tag, meaning that it displays as its own "block" element: receives a layout (settable dimensions), by default takes the entire width of the parent element, and has a forced break after the rendered element (is on a line to itself).
So, that leaves us with a number of approaches for having your menu items sit side-by-side:
Use inline-level elements for your menu items
Use block-level elements and float them
Use block-level elements and style them as inline-block
All of these approaches are detailed in the above link. Personally, I prefer to use floated block elements. I have a fiddle with some rough css to give you an idea. Note that there are some considerations in how to display your submenus as well. You'll note that I've implemented these as having display: block, with no float, because we want them to stack vertically.
HTML
<ul class="menu">
<li>
foo
<ul class="submenu">
<li>subfoo1</li>
<li>subfoo2</li>
</ul>
</li>
<li>
bar
<ul class="submenu">
<li>subbar1</li>
<li>subbar2</li>
</ul>
</li>
</ul>
CSS
ul.menu {
list-style: none;
}
ul.menu > li{
float: left;
position: relative;
}
ul.menu li {
background-color: #cccccc;
padding: 5px 20px;
}
ul.menu > li + li {
border-left: solid black 2px;
}
ul.menu li:hover > ul {
display: block;
}
ul.menu li a,ul.menu li a:link, ul.menu li a:hover, ul.menu li a:visited {
color: black;
text-decoration: none;
}
ul.submenu{
display: none;
list-style: none;
position:absolute;
left: 0;
padding: 0;
}
ul.submenu li {
float:none;
display: block;
}
ul.submenu > li + li {
border-top: solid black 1px;
}
You can just remove some <li> tags:
<ul>
<li>
abc
<ul>
abc
abc
</ul>
</li>
<li>
abc
<ul>
abc
abc
</ul>
</li>
</ul>