This question already has answers here:
CSS multiple selectors without comma
(2 answers)
CSS Sibling Selector w/ Hover
(4 answers)
What does the "+" (plus sign) CSS selector mean?
(9 answers)
Closed 4 years ago.
I m trying to get my head around CSS.
I found a navigation menu that I would like to use but some things aren't working yet and there are a lot of things that confuse me.
is there a reason why li is two times in this part of the code ?
/*Make dropdown links vertical*/
li ul li {
display: block;
float: none;
}
and this part I don't understand at all.
does this mean hover state for only a selector or does it mean hover state for ul, li and a selectors ?
ul li a:hover + .hidden, .hidden:hover {
display: block;
}
I have been following the css tutorial from w3schools but I didn't see anything that explains the things I don't understand.
Full code is here
/*horizontal navigation style*/
/*Strip the ul of padding and list styling*/
ul {
list-style-type:none;
margin:0;
padding:0;
position: absolute;
}
/*Create a horizontal list with spacing*/
li {
display:inline-block;
float: left;
margin-right: 1px;
}
/*Style for menu links*/
li a {
display:block;
min-width:140px;
height: 50px;
text-align: center;
line-height: 50px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #fff;
background: #2f3036;
text-decoration: none;
}
/*Hover state for top level links*/
li:hover a {
background: #19c589;
}
/*Style for dropdown links*/
li:hover ul a {
background: #f3f3f3;
color: #2f3036;
height: 40px;
line-height: 40px;
}
/*Hover state for dropdown links*/
li:hover ul a:hover {
background: #19c589;
color: #fff;
}
/*Hide dropdown links until they are needed*/
li ul {
display: none;
}
/*Make dropdown links vertical*/
li ul li {
display: block;
float: none;
}
/*Prevent text wrapping*/
li ul li a {
width: auto;
min-width: 100px;
padding: 0 20px;
}
/*Display the dropdown on hover*/
ul li a:hover + .hidden, .hidden:hover {
display: block;
}
/*Style 'show menu' label button and hide it by default*/
.show-menu {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
text-decoration: none;
color: #fff;
background: #19c589;
text-align: center;
padding: 10px 0;
display: none;
}
/*Hide checkbox*/
input[type=checkbox]{
display: none;
}
/*Show menu when invisible checkbox is checked*/
input[type=checkbox]:checked ~ #menu{
display: block;
}
/*Responsive Styles*/
#media screen and (max-width : 760px){
/*Make dropdown links appear inline*/
ul {
position: static;
display: none;
}
/*Create vertical spacing*/
li {
margin-bottom: 1px;
}
/*Make all menu links full width*/
ul li, li a {
width: 100%;
}
/*Display 'show menu' link*/
.show-menu {
display:block;
}
}
li ul li {
display: block;
float: none;
}
It means it will target all the <li> elements which are inside li ul..The css are always applied to the last selector in the expression. See example below
Stack Snippet
li {
color: blue;
}
li ul li {
color: red;
}
<ul>
<li>Menu
<ul>
<li>Submenu</li>
<li>Submenu</li>
<li>Submenu</li>
</ul>
</li>
</ul>
ul li a:hover + .hidden,
.hidden:hover {
display: block;
}
Here you are applying same styling to two elements using ,(comma) separator...
1: using + i.e adjacent sibling selector...it separates two selectors and matches the second element only if it immediately follows the first element, means here <a> and .hidden sholud be both adjacent elements.
2: is .hidden:hover means it will work only when you hover only .hidden element.
.hidden {
display: none;
}
ul li a:hover+.hidden {
display: inline-block;
background: red;
}
<ul>
<li><a>Hover Here</a><span class="hidden">hidden</span></li>
</ul>
Isn't that hard to understand, just see it as 'items' that are separated by white spaces ' ', it means, that each word separated by a space, it's an item. Then, see that the first item is the 'parent' item, and it's immediately right item is it's child (or inner item), and so on.
So, in your first example:
li ul li {
display: block;
float: none;
}
you have li, then ul, and then li again, it means that it is looking for all li tags inside an ul tag, which it is inside an il tag itself (reading from right to left). It would be something like:
<li>
<ul>
<li>this is the selected item</li>
<li>this is the selected item</li>
<li>this is the selected item</li>
</ul>
</li>
For the later case, it's the same, the only difference is the use of subclasses selectors (like hover), and the comma. When using the comma it means that you're going to add a new group of selectors, it means that the selectors separated by comma aren't in any way related between them. So you have two groups:
ul li a:hover + .hidden
and
.hidden:hover
the first one means "select all the items with .hidden class, that are immediately children(+) of an 'a' tag which is being hovered, and this 'a' tag must be inside a li tag, and this later inside a ul tag"
it would be something like:
<ul>
<li>
<a>
<span class="hidden" >this part is selected if mouse hovers</span>
<span class="hidden" >this don't cause it's not an immediate child </span>
<a>
</li>
</ul>
And finally the second case it's simpler, it says (remember, read from right to left) "select all items being hovered by mouse and with hidden class". If we use the above example:
<ul>
<li>
<a>
<span class="hidden" >this part is selected if mouse hovers</span>
<span class="hidden" >this part is selected TOO if mouse hovers </span>
<a>
</li>
<li class="hidden">
this part is selected TOO if mouse hovers
</li>
</ul>
Hope I explained well myself
li ul li {
display: block;
float: none;
}
this code means there is two list one of them includes the other
first, li is the parent and the term 'ul li' is the sublist from it
the first li is the basic menu and the other is the dropdown
ul li a:hover + .hidden, .hidden:hover {
display: block;
}
this code means there are two cases of hover
once when hovering on "ul li a" which is part of a list
and other on his siblings '.hidden' which refer to it here by using "+" assignment
Related
I have a dropdown menu on my site's top navigation bar. I'd like the items in this menu to expand horizontally to fit their contents. For some reason they won't expand to be wider than their parent.
I've recreated the issue in CodePen here: http://codepen.io/YM_Industries/pen/GgJBQv
In my actual website I don't have control over this section of the DOM, so I'm a little constrained there.
Here's the code for my recreation in case CodePen is unavailable:
HTML:
<ul class="nav">
<li>
Home
</li>
<li>
v Test1 v
<ul class="submenu">
<li>
Submenu 1
</li>
<li>
Long text wraps and is ugly :/
</li>
</ul>
</li>
<li>
Test2
</li>
</ul>
CSS:
* {
font-family: sans-serif;
}
ul.nav,
ul.nav li,
ul.nav ul {
display: block;
padding: 0;
}
ul.nav li {
position: relative;
}
/* Style each link */
ul.nav li > a {
display: block;
padding: 10px 15px;
line-height: 20px;
height: 20px;
background: rgba(254, 197, 46, 1);
border: none;
}
/* Bring back the first level links */
ul.nav > li {
float: left;
margin-right: 1px;
}
/* Selected/Hover effect */
ul.nav li > a:hover {
color: #004d85;
background: rgb(255, 213, 102);
}
/* Display dropdown in the correct location */
ul.nav li ul.submenu {
position: absolute;
top: 40px !important;
left: 0px !important;
display: none;
}
ul.nav li:hover ul.submenu {
display: block;
}
/* Set font+colour for site links */
ul.nav li a,
ul.nav li a:link,
ul.nav li a:visited {
color: black;
font-size: medium;
text-decoration: none;
}
ul.nav li a:hover,
ul.nav li a:active {
color: blue;
}
If I explicitly set a width on my submenu items (400px for example) they will expand correctly, but for some reason the content isn't making them get wider. I'd really rather not have to hardcode the width.
Thanks,
YM
The solution is rather easy. You just have to add
ul.submenu a {
white-space: nowrap;
}
which prevents the text from wrapping and therefore doesn't stick to the parent container size.
You can check it out here http://codepen.io/anon/pen/QwbYvG
just fixed your pen - upgrade your css classes:
ul.nav li ul.submenu
{
position: absolute;
top: 40px !important;
left: 0px !important;
width:auto;
display: none;
background: rgb(254, 197, 4);
}
ul.nav li ul.submenu > li
{
display:inline-block;
white-space: nowrap;
}
AND IT USES CSS 2 :)
I have a nav that holds a ul with several ils. The problem is that im unable to get rid of the ul's first and last child's divider.
here's a demo: http://jsfiddle.net/Rvs3C/1/
i've added this code to my CSS file but seems like it makes no difference:
nav ul a li:first-child{
content: none;
}
nav ul a li:last-child{
content: none;
}
You markup is wrong. The corret way is <a> tag being the children of tag <li>.
The way you made the correct selector would:
nav ul a:first-child li{
content: none;
}
nav ul a:last-child li{
content: none;
}
But remembering, this is not the right way to do.
The correct is change you html to:
<ul class="showing">
<li>home</li>
...
As mentioned elsewhere your HTML structure is off, li must me a direct child of ul, no other element as a child is valid. With this said, you also need to change your selectors per the below.
Updated Fiddle
HTML
<nav>
<ul class="showing">
<li>home
</li>
<li>about me
</li>
<li>content
</li>
<li>browse
</li>
<li>rate
</li>
<li class="nav_arr"><img src="http://www.irvinewelsh.net/images/arrow-left.png" />
</li>
</ul>
</nav>
CSS
nav {
margin-right: 150px;
}
nav ul {
background-color: #494A4C;
overflow: hidden;
text-align: right;
}
nav li img {
margin-left: 20px;
vertical-align: top;
}
nav ul li a {
color: white;
text-decoration: none;
font-family:arial;
font-size: 14px;
padding: 0px;
font-weight: bold;
}
nav ul li:first-child:before {
content: none;
}
nav ul li:last-child:before {
content: none;
}
nav li:before {
content:"|";
padding: 5px;
font-weight: bold;
color:lightblue;
font-size: 20px;
}
nav ul li {
display: inline-block;
}
I'm a relative newbie and I'm having trouble following the css for my nav. I need to do 2 things:
1) run my sub menu inline
2) hide my sub-sub nav, and show it inline as well.
Here is the test site: http://gbetza.mydomain.com/webservice2/test/Basso56/test/home.html
Here is the CSS: http://gbetza.mydomain.com/webservice2/test/Basso56/test/css/style%20-%20Copy.css
I'm having trouble understanding which class I need to adjust as well as how.
Thank you
Copy + Paste from a similar answer of mine.
I have created a really simple implementation of this. It is barebones so that you can get a real easy look at the basic concept.
In the fiddle here: http://jsfiddle.net/WS3QQ/2/
HTML - Note how the sub-menus are nested
<div id="nav">
<ul>
<li>Top Menu
<ul>
<li>Sub-Menu</li>
<li>Sub-Menu</li>
<li>Sub-Menu</li>
</ul>
</li>
<li>Top Menu</li>
<li>Top Menu</li>
<li>Top Menu</li>
</ul>
</div>
CSS - note how you can easily target the sub-menus (#nav li li). By default the sub-menu li is hidden (display:none). When the li is hovered over, the sub menu li is shown (display:block).
#nav ul { list-style-type: none; margin: 0; padding: 0; }
#nav li { float: left; }
#nav li li { clear: left; display: none; }
#nav li:hover li { display: block; }
#nav li:hover a { background: #111; }
#nav li a { background: #333; padding: 10px; display: block; color: #FFF; font-weight: bold; text-decoration: none; }
#nav li a:hover { background: #3914AF; }
I'm having a design issue with my css vertical menu.
It's working but it does not have the effect i would like to have when I do a mouse hover on a category
Below, you will see a simple vertical menu which appears when you hover your mouse over the main category
However I would like to have a small effect :
When the mouse is hover a category, i would like to add a background color (black).
It's working but I would like that the height and the width of the background to stick exactly to the same height and width of the text. Currently, I dont know why; the height of the background is more than the height of my text.
Here is some pictures of how it's right now and how i would like to be be.
How it 's now:
How I would like it to be:
Here is my code Html code
<div id="menu">
<ul id="MenuDeroulant">
<li style="margin-left:-10px;">Main categorie
<ul>
<li><a href="" >Subcat 1</a></li>
<li><a href="" >Subcat 2</a></li>
</ul>
</li>
</ul>
Here is my css code:
#MenuDeroulant
{
margin: 0;
padding: 0
}
#MenuDeroulant li
{
float: left;
list-style: none;
}
#MenuDeroulant li a
{
display: block;
padding: 0px 0px;
text-decoration: none;
color: #000;
white-space: nowrap;
text-align:center;
}
#MenuDeroulant li a:hover
{
background: #000;
color: #FFF;
}
#MenuDeroulant li ul
{ visibility: hidden;
padding: 0px 0px;
}
#MenuDeroulant li ul li
{
float: none;
display: inline;
}
#MenuDeroulant li ul li a
{
width: auto;
padding: 0px 0px;
}
#MenuDeroulant li ul li a:hover
{
background: #0000;
padding: 0px 0px;
}
Thanks in advance for your help and I wish you a very nice day,
Anselme
Use width:100% to all your <li> or li a elements and a fixed width to your <ul>. This will solve your issue.
With that CSS your nested ul is permanently hidden. You'll need something like
#MenuDeroulant li:hover ul {
visibility:visible;
}
to show the nested menu items then maybe display: inline on the #MenuDeroulant li ul li a
You can add a class to your menu hyperlinks giving them a margin-bottom:3px and it should bump up the links in the container.
Ref this tutorial: https://www.servage.net/blog/2009/03/20/create-a-cool-css-based-drop-down-menu/
I used an external stylesheet, and simply put #menu before each CSS item, like this:
#menu ul{
font-family: Arial, Verdana;
font-size: 14px;
margin: 0;
padding: 0;
list-style: none;}
or:
#menu ul li{
display: block;
position: relative;
float: left;}
But, when i reference with #menu, the menu doesn't render properly. It leaves the parent 'li' untouched by CSS.
http://jsfiddle.net/UGW2L/
Any ideas?
Thx,
Dave
Your HTML is this:
<ul id="menu">
Which means your CSS needs to be this:
ul#menu
Your current CSS is looking for an 'LI inside of a UL that is inside of some other element with an ID of MENU'
#menu ul targets this (any ul inside of an element with id='menu')...
<div id="menu">
<ul> <!-- <<-- this element is the target -->
...
</ul>
</div>
(div is just an example, any element with id="menu" can be used above)
ul#menu targets this (the ul with id='menu')...
<ul id="menu"> <!-- <<-- this element is the target -->
...
</ul>
Edit as per comments:
Quote: "...i am missing the 'box' around the parent node."
I think the node to which you refer is the <li>, just inside the parent <ul id='menu'>, and you have not targeted it anyplace at all.
Just add ul#menu li a to your box styling. (Note the comma. It separates two totally unique selectors sharing the same styling.)
ul#menu li a,
ul#menu ul li a {
display: block;
text-decoration: none;
color: #ffffff;
border-top: 1px solid #ffffff;
padding: 5px 15px 5px 15px;
background: #2C5463;
margin-left: 1px;
white-space: nowrap;
}
http://jsfiddle.net/cWpEg/1/
See the difference?
ul#menu is the parent.
ul#menu li is the first item inside the parent.
ul#menu li a is the link inside the first child of the parent.
Since ul#menu li targets any & all <li>'s that are children of the ul#menu parent, you would only need the one selector...
ul#menu li a {
display: block;
text-decoration: none;
color: #ffffff;
border-top: 1px solid #ffffff;
padding: 5px 15px 5px 15px;
background: #2C5463;
margin-left: 1px;
white-space: nowrap;
}
http://jsfiddle.net/cWpEg/2/
Also note how it's the full width of the screen.
To target & style just the parent, add something like this.
ul#menu {
display: block;
position: relative;
float: left;
list-style: none;
}
http://jsfiddle.net/cWpEg/6/