I am trying to display the list on button hover, but what happens is, whenever I hover near the button area, text gets displayed.
.header_nav {
width: 800px;
height: 400px;
}
.header_nav ul {
list-style: none;
}
.header_nav ul ul {
display: none;
}
.header_nav ul ul #nav_button:hover>ul {
display: block;
}
.header_nav ul ul li >ul {
display: none;
}
.header_nav ul li:hover >ul {
display: block;
}
<nav class="header_nav">
<ul>
<li>
<input type="button" value="Button 1" name="nav_button" id="nav_button">
<ul>
<li>Locations</li>
<li>
Mumbai
<ul>
<li>Txt 1</li>
<li>Txt 2s</li>
<li>Txt 3</li>
</ul>
</li>
<li>Delhi</li>
<li>Banglore</li>
<li>Nagpur</li>
</ul>
</li>
</ul>
</nav>
JS FIDDLE : https://jsfiddle.net/fhv7drst/
It is because your li element was block element.
I changed it to inline and it started working as per your requirements
HTML:
<li class="parentElement">
<input type="button" value="Button 1" name="nav_button" id="nav_button">
CSS:
li.parentElement{
display: inline;
}
here is the working fiddle
https://jsfiddle.net/m73p8pea/
The reason is that your li element is a block element, which means that it will automatically try to span the entire width available. In your case, this is the 800px provided by the topmost element.
You have two solutions readily available - one is to make the list element an inline-block element (or simply an inline element, though I'd prefer inline-block here, as block is how it started) to prevent it spaning the whole width:
.header_nav ul li {
display: inline-block;
}
You could also trigger the display change on the unordered list when hovering over the button directly, not when hovering over it's parent list item:
.header_nav #nav_button:hover + ul {
display: block;
}
This is likely the better solution, as it doesn't mess with the display types more than you need to, and you more accurately describing what you want to happen - show the list when the button is hovered.
As pointed by #Rahul Arora indeed it is because of li as block element.
But if for some reason you still want to keep it as block element, you can keep it by making it as inline-block. I also recommend removing margin (see your given example by inspect element, it is to the write of ul) and padding which is assigned by browser as default.
Here is the code:
.header_nav
{
width:800px;
height:400px;
}
.header_nav ul
{
list-style:none;
//displaying ul & all its child as inline block until overriden by other rules
display:inline-block;
//removing default margin and padding
margin:0;
padding:0;
}
.header_nav ul ul
{
display:none;
}
.header_nav ul ul #nav_button:hover>ul
{
display:block;
}
.header_nav ul ul li >ul
{
display:none;
}
.header_nav ul li:hover >ul
{
display:block;
}
<nav class="header_nav">
<ul>
<li>
<input type="button" value="Button 1" name="nav_button" id="nav_button">
<ul>
<li>Locations</li>
<li>
Mumbai
<ul>
<li>Txt 1</li>
<li>Txt 2s</li>
<li>Txt 3</li>
</ul>
</li>
<li>Delhi</li>
<li>Banglore</li>
<li>Nagpur</li>
</ul>
</li>
</ul>
</nav>
Related
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>
In the below it's a menu with dropdown submenus.
In Chrome the sub-menus are appearing below the menu, but in Firefox and IE they are always appearing below the first item.
If I change the 'float: none' to 'float: left' it works and they appear below the menu, but all the sub-menu items become inline and flow one after the other.
Is there an easy fix (rather than modifying the html as this is generated from an xml file on the server - but I can modify if need be) in css?
Thanks.
<html>
<head>
<style>
#cat_nav li > ul { display: none; }
#cat_nav ul{list-style-type: none;}
#cat_nav ul li {float: none; position: relative} /*change float to not none and it aligns but items are inline */
#cat_nav ul li:hover > ul {display: block;}
#cat_nav ul ul {min-width: 150px;background-color:#DFDFDF;padding:4px 0 4px 0;position:absolute;}
</style>
</head><body>
<nav id="cat_nav">
<ul class="products_btn">
<li style="display: inline">
PCBS1
<ul class="dropdown">
<li> Fuzz 1-1</li>
<li> Fuzz 1-2</li>
<li> Fuzz 1-3</li>
</ul>
</li>
<li style="display: inline">
PCBS2
<ul class="dropdown">
<li> Fuzz 2-1</li>
<li> Fuzz 2-2</li>
<li> Fuzz 2-3</li>
</ul>
</li>
</ul>
</body></html>
Change the float:none to the float:left on #cat_nav ul li and add this
#cat_nav ul li li {
float:none
}
to un-float the list items within the list items (and thus appear stacked instead of inline).
You need to edit your selecting and positioning. I have made some small edits to your code with a working example tested in firefox. See below.
DEMO http://jsfiddle.net/RDQW8/1/
#cat_nav li > ul {
display: none;
}
#cat_nav ul {
list-style-type: none;
}
#cat_nav ul > li {
position: relative
}
/*change float to not none and it aligns but items are inline */
#cat_nav ul li:hover > ul {
display: inline-block;
}
#cat_nav ul ul {
min-width: 150px;
background-color:#DFDFDF;
padding:4px 0 4px 0;
top:15px;
position:absolute;
}
I'm trying to show a nested (sub) list, but hide the parent ULs and LIs through an "active" class so that the sub list looks like the parent list.
The list with the "active" class isn't visible because it inherits display: none from its parent.
Code:
<ul>
<li>
Hidden
<ul>
<li class="active">Visible</li>
</ul>
</li>
</ul>
CSS:
li {
display: none;
}
li.active {
display: block;
}
Fiddle: http://jsfiddle.net/2C8qs
Any ideas?
If you can add span around the hidden text (http://jsfiddle.net/vittore/2C8qs/3/) :
<ul>
<li>
<span>Hidden</span>
<ul>
<li class="active">Visible</li>
</ul>
</li>
</ul>
li span, li li {
display: none;
}
li li.active {
display: block;
}
display: none hides the element and all of its children, that is final and adding display: block to a child won't make it visible again.
This will hide all children, except for the .active element:
ul.parent > li {
display: none;
}
ul.parent > li.active {
display: block;
}
EDIT: Oops, I misread the question. You can do something similar to the above though, if you wrap the other contents in an element.
An ugly CSS trick : http://jsfiddle.net/2C8qs/4/
Instead of using display none/block, I used text-indent, like that :
li {
text-indent: -99999em
}
li.active {
text-indent: 0
}
Note that can only work on inline / text elements.
I know this is very late to this question, but I've found what I would consider a nice solution and thought I'd post it here for whoever might need it in the future.
First of all, wrap all the <li>'s children with <p> (or <div> or anything, it doesn't matter really), but not any sub-<ul>'s. Then, to the child <ul> you want to be visible, add a class called showing. Example (we only want to show the SubSubThing list):
<ul>
<li>
<p>Item</p>
<ul>
<li>
<p>SubItem</p>
<ul>
<li>
<p>SubSubItem</p>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Thing</p>
<ul>
<li>
<p>SubThing</p>
<ul class="showing">
<li>
<p>SubSubThing1</p>
</li>
<li>
<p>SubSubThing2</p>
</li>
<li>
<p>SubSubThing3</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Then apply this CSS:
ul>li {
list-style:none;
}
ul>li>p {
display: none;
}
ul.showing>li>p {
display:block;
}
/* Without removing padding and margin,
the sublists appear way over to the right */
ul {
margin-left: 0px;
padding-left: 0px;
}
li {
margin-left: 0px;
padding-left: 0px;
}
Now, only the <li>'s who are direct descendants of ul's with a showing class will display at all. The other items in the list will use no space.
To get the sublists to show bullet points would be easy via CSS, and to show different sublists it is simple to just use jQuery to set showing on the appropriate ul.
Hope that helps.
Obligatory JSFiddle
So the reason you can't simply hide the first li and reveal the second is because the second is contained by the first — you can't reveal and element that is contained by a hidden one.
Therefore, if you put the li element within a span that you'd like to hide, it becomes easy. I've created a class-free version for you here: http://jsfiddle.net/rgpnr6mh/3/
<ul>
<li><span>Hidden</span>
<ul>
<li>Visible</li>
</ul>
</li>
</ul>
I'm assuming you don't want to display the bullets:
ul {
list-style-type:none
}
li span{
display: none;
}
li li {
display: block;
}
I have a vertical navigation menu and I want to show different levels of the menu upon hovering of certain elements. The problem is that the method I used is not working and I do not understand why. When I hover over "Product", I expect to see a sub-menu expand, but nothing happens. Why?
HTML:
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Product</li>
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
<li>Contact</li>
</ul>
</nav>
CSS:
nav {
border:1px solid red;
}
nav ul ul {
display:none;
}
nav ul li:hover > ul {
display:block;
}
Your code:
nav ul li:hover > ul {
display:block;
}
Means "Make any ul within a hovered li display:block". Your submenu is not within the LI, it's after it. Here's a working version of what you were trying to do.
Working HTML:
<li>Product
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
</li>
Working CSS:
nav ul li ul {
display:none;
}
nav ul li:hover ul {
display:block;
}
Also
nav ul ul {
display:none;
}
should be
nav ul li ul {
display:none;
}
Try this for your html:
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Product
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
</li>
<li>Contact</li>
</ul>
</nav>
You have two ways of changing this; you can either update the HTML or you can update the CSS.
There are pros and cons to changing code and in a vacuum I can't recommend one approach over the other.
Without changing your HTML you can make the CSS work like this:
nav ul li:hover + ul {
display: block;
}
Note that rather than using the descendant selector this uses the adjacent selector and applies the style to the element that immediately follows the hovered LI.
Alternatively, the HTML change mentioned above does work equally well.
This link http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/ provides a fantastic resource.
this is my html file:-
<div id="load">
<ul>
<li>Activities
<ul>
<li>Physical1
<ul>
<li>Cricket
<ul>
<li>One Day</li>
</ul>
</li>
</ul>
</li>
<li>Test1
<ul>
<li>Test At Abc</li>
</ul>
</li>
<li>Test2
<ul>
<li>Test At Xyz</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
i want to set in to css hover.
i dont konw about css hover much so give me suggestion for this.
this is my output i needed.
hover in Acvivities display
Physical1
Test1
Test2
hover in Physcial1 display Cricket...
thanks...
ul > li > ul {
display: none; // hide all submenus
}
li:hover > ul {
display: block; // show sub menu when parent li is hovered
}
DEMO
ul li ul
{
display:none;
}
ul > li:hover > ul
{
display:block;
}
http://jsfiddle.net/AyLYe/
I won't provide the whole code, but with this base you can adapt the code to display the rest of what you need.
Before we start, see this tutorial I found with a google search: http://line25.com/tutorials/how-to-create-a-pure-css-dropdown-menu I scanned it at a glance and it looks pretty good, it will at least guide you through the concepts and the process.
Here's a JSFiddle:http://jsfiddle.net/Kq7vD/
Heres the CSS that makes it work:
#load ul li ul {
display: none;
}
#load ul li:hover ul {
display: block;
}
Note that by removing #load you can cause this to work across every list in your menu. The downside to this is that the css rules then apply to every list on your site, even if it shouldn't be a menu. It is recommended that you keep your rules relatively specific for this reason.
EDIT to address your comment:
If your HTML structure includes a DIV before each UL, even the nested UL's then your css rules will need to adapt to that new structure. In particular, it's also important to note that you will not set the UL to display: none/block; anymore but the DIVs.
Assuming a structure like:
<div id="load">
<div>
<ul>
<li>
<div>
<ul>
<li></li>
</ul>
</div>
</li>
</ul>
</div>
</div>
Your code would then look like...
#load div ul li div {
display: none;
}
#load div ul li:hover div {
display: block;
}