CSS drop-down menu, link cut in half - css

I'm learning how to build pure CSS drop-down menus, and I'm seeing a weird issue. I've searched and haven't found anything useful.
If you hover over the Blog link, you'll see "Case Studies" split in half with, "Case" on one line and "Studies" on the next line.
I' ve checked my HTML and it looks fine. It's been a long day so maybe I'm missing something obvious. :o
I have this so far:
<nav class="p-nav">
<ul>
<li>About</li>
<li>Showcase</li>
<li>Services</li>
<li>Blog
<ul>
<li>Case Studies</li>
<li>Tutorials
<ul>
<li>CSS</li>
<li>Javascript</li>
<li>Playground</li>
</ul>
</li>
</ul>
</li>
<li>Contact</li>
</ul>
</nav>
#import url(http://fonts.googleapis.com/css?family=Lato:300, 400);
.p-nav li {
position: relative;
}
.p-nav ul ul {
display: none;
position: absolute;
top: 100%;
}
.p-nav ul li {
float: left;
}
.p-nav a {
display: block;
font: 300 100%/70px"Lato", sans-serif;
padding: 0 30px;
}
.p-nav ul li:hover > ul {
display: block;
}
Here is the link to the code: http://jsfiddle.net/6CwYh/20/
Can anyone explain why it's doing that, and how I can fix it?
TIA.

Cause of space "problems" it places those two words on two lines.
If you don't like that you can add white-space:nowrap;to the <li>so it want wrap, have a look at the fiddle: http://jsfiddle.net/6CwYh/21/
.p-nav li {
position: relative;
white-space:nowrap;
}

There is simply not enough space for the text to fit, which is why it is wrapping. Give the 2nd level ul a width, like 350px.
http://jsfiddle.net/6CwYh/24/
Also, make sure you use direct descendant operators (>) I've added some in the above link.
If I target #something ul li That actually will target all uls and all lis in #something even if they're nested.
This was causing the items in the dropdowns to float, which caused further problems.
/* Better selectors */
#something > ul {}
#something > ul > li {}
#something > ul > li > ul {}
#something > ul > li > ul > li {}

make it wider:
nav ul li{
width:200px;
}
and its fixed

Related

How to color specifics parts (letters) of menu?

Firstly, happy new year to you all! :)
Ok let's get to it. I have 5 items in my menu, and i would like to color "+" part of the word to red, choosing 2nd,3rd and 4th item of menu.
This is what menu looks like right now.
This is how the menu should look like, when its done.
I might have given a bad picture, but i think you can see the red "+" on 2nd,3rd and 4th item of menu.
This is what i've tried so far, but i can't seem to figure out the nth-child method.
#menu li:nth-child(2):first-letter a{color:red;}
Also tried this, but it colors every first letter in all 5 elements :S
#menu .nav > li > a:first-letter{color:red;}
Any help will be appreciated!
Thank you all!
I've managed to find the solution. Not sure if it's the best one, but im posting it below, so that any1 in the future can use it too, if no other solution is found
#menu .nav > li:nth-child(2) > a:first-letter
{
color:red;
}
#menu .nav > li:nth-child(3) > a:first-letter
{
color:red;
}
#menu .nav > li:nth-child(4) > a:first-letter
{
color:red;
}
Use the :not() selector to have all but one selected like this:
#menu{
background: rgb(83,83,83);
width: 100vw;
height: 40px;
}
ul{
text-align: center;
line-height: 40px;
vertical-align: central;
}
ul li{
display: inline-block;
color: white;
list-style: none;
margin-left: 25px;
}
a{
color: white;
display: block;
}
#menu ul li:not(:first-child):not(:last-child) a::first-letter{
color: red;
}
<div id="menu">
<ul>
<li>+option</li>
<li>+option</li>
<li>+option</li>
<li>+option</li>
<li>+option</li>
</ul>
</div>
I know this question already has an accepted answer, but I think there is a semantically better way of doing this. Instead of having the + symbol inside the link's markup, why not add it as a pseudo :before element? Easier to style and not dependent on your markup.
<nav>
<ul>
<li>Domov</li>
<li class="with-symbol">Naravni kamen</li>
<li class="with-symbol">Dekorativni kamen</li>
<li class="with-symbol">Keramika</li>
<li>Kontakt</li>
</ul>
</nav>
And the respective CSS:
.with-symbol:before {
content: '+';
color: red;
}
Then position it with either position: absolute; or negative left margin.
From the docs (https://developer.mozilla.org/en-US/docs/Web/CSS/%3A%3Afirst-letter): A first line has meaning only in a block-container box, therefore the ::first-letter pseudo-element has an effect only on elements with a display value of block, inline-block, table-cell, list-item or table-caption. In all other cases, ::first-letter has no effect. So you will need to add display: block to your anchor tags.
I would also change the selector to:
ul li a:first-letter {
color:red;
}
as you need to select the first letter of the anchor tag, not the list item.
As a side note, it might be a better solution to use a span as suggested above or pseudo elements to insert the plus character and use a class to determine if it should be displayed or no.

Nested padding LESS

I am trying to create indentation for buttons that sit inside of a nested ul li structure.
I can't change the HTML as it is being rendered by a third party system.
The HTML
<ul>
<li><button>Parent</button>
<ul>
<li>
<button> Child</button>
<li><button>Parent</button>
<ul>
<li>
<button> Sibling etc</button>
</li>
</ul>
</li>
</li>
</ul>
</li>
</ul>
The ul and li have no margin or padding so the idea was to simply add padding to the button elements.
The issue is, because of the ul having no margin/padding, the buttons all start from the exact same point and there (no matter how deep they are nested) all have the exact same indentation.
LESS
ul{
li{
button{
padding-left: 25px;
}
ul{
li{
button{
padding-left: 35px;
}
}
}
}
}
I thought of doing something like the above (and account for as many levels as possible) but it would be a nightmare to maintain.
Surely there is a more elegant way to handle this, thoughts?
I don't know why you would want to go as far as to write a mixin for this.
My solution in LESS:
ul ul button {
padding-left: 25px;
}
ul ul ul button {
padding-left: 35px;
}
Would that solve the problem for you?
The resulting CSS would look like this:
ul ul button {
padding-left: 25px;
}
ul ul ul button {
padding-left: 35px;
}
Alright, so I thought of a different solution and looked at the LESS documentation but the underlying problem is that you can't know the number of levels of nesting coming into play beforehand obviously.
Thus you would have to wait for the HTML to be rendered, then read out the level of nesting (e.g. 5 levels) and based on that you could generate the CSS, which I'm afraid wouldn't make much sense and is something to be done in JavaScript.
All of that being said you could use a few variables to ease your writing process in LESS but that's about it. Here for an example:
#padding: 25px;
#addten: 10px;
#selector: ul button;
#selector { #padding; }
ul #selector { #padding + #addten; }
ul ul #selector { #padding + #addten*2; }
ul ul ul #selector { #padding + #addten*3; }
Probably you could also create a mixin for that to add another layer of abstraction but like I said, I wouldn't go thus far.
Hope this helps. =)

Hide/Show submenu items in responsive navigation menu using CSS

I have created a menu that is only visible on mobiles.
Using CSS I've managed to create a SHOW/HIDE NAVIGATION menu. You can see this in action at http://js.co.nz/mobile-test.php (currently only in portrait view on mobiles as that's as far as I've got with development).
I want to be able to show/hide the submenu items too (as the navigation menu is very long!). For example, if the user clicks on "Browse by type" I would like the submenu of: Chairs; Tables; Mirrors etc to appear.
The html currently looks like this:
<nav id="responsivenav" role="navigation">
Show navigation
Hide navigation
<ul>
<li>HOME</li>
<li>BROWSE ALL STOCK</li>
<li>BROWSE BY TYPE
<ul>
<li>Antique chairs</li>
<li>Dining tables</li>
<li>Antique mirrors<li>
</ul>
</li>
<li>BROWSE BY CATEGORY</li>
<li>BROWSE BY ROOM</li>
<li>REDUCED ITEMS</li>
<li>OPENING HOURS</li>
<li>NEWS</li>
<li>FIND US</li>
<li>ABOUT US</li>
<li>BROCHURES</li>
<li>PERIOD STYLES</li>
</ul>
<div class="clear"></div>
</nav>
The css looks like this:
#responsivenav {display:block;}
#responsivenav > a { }
#responsivenav:not( :target ) > a:first-of-type,
#responsivenav:target > a:last-of-type {
display: block;
height:50px;
line-height:50px;
font-size:15px;
margin-bottom:0;
padding:0;
text-indent:100px;
text-decoration:none;
color:#fff;
font-weight:bold;
text-transform:uppercase;
background: #393b3c url(../images/wd/mobile-menu-icon.jpg) no-repeat 40px center; }
/* first level */
#responsivenav > ul {
height: auto;
display: none;
border-bottom:5px solid #fff;}
#responsivenav:target > ul {
display: block;
list-style:none;
padding:0;
margin:0;}
#responsivenav > ul > li {
width: 100%;
float: none;
display:block;
height:60px;
line-height:60px;
font-size:15px;
text-indent:40px;
border-top: 1px solid #eee;}
#responsivenav > ul > li a {
text-decoration:none;
color:#393b3c;}
/* second level */
#responsivenav > ul > li > ul {
display: none;
}
#responsivenav > ul > li:hover > ul {
display:block;
}
It is this second level of the menu that I know I haven't got right. I've tried various ways of doing it e.g. adding classes to the submenus, using left:-9999px instead of display:none; etc but nothing seems to work yet.
Please help! I'm sure this should be so simple!
Just replace the property height: 60px to min-height: 60px of the #responsivenav > ul > li (line 138 in PhonePtest.css file).
Currently, your code makes the submenu appear on hover which in case of mobile works on click. That is why the navigation menu hides on click. To prevent this you can replace
BROWSE BY TYPE
with
BROWSE BY TYPE
You can do the same with the other menu elements.

Style not being applied

I have an html menu, that start like this:
<nav id='main'>
<ul>
and my CSS file goes like this:
nav #main ul {
list-style: none;
}
But for some reason, this does not seem to work...
What am I doing wrong?
Try using
nav#main ul {
list-style: none;
}
ie remove the space between nav and #main - using the space is indicating #main is a descendant of nav instead of saying #main is an id attribute of nav
See the docs here for pattern matching in CSS2
Space is descendant selector.
You are trying to apply this style to:
All the <ul> descendants from an object with id="main" that is descendant of a <nav> object.
You should instead apply the style to:
All the <ul> descendants from a <nav> object with id="main".
It can be done removing the first space:
nav#main ul {
list-style: none;
}
Remove the space
nav#main ul {
list-style: none;
}
it really should be
nav#main ul { }

Pseudo-classes for li list

I'm experimenting here with Pseudo-classes and trying to something I would usually do with a style class. I have a unordered list with multiple sub unordered lists and so on.
I want to only make sure the first level of li tags are been set to float left.
Here is my html
<body>
<div id="MainMenu">
<ul id="nav">
<li>Home</li>
<li>
About
<ul>
<li>The Product</li>
<li>Meet The Team</li>
</ul>
</li>
<li>
Contact
<ul>
<li>
Business Hours
<ul>
<li>Week Days</li>
<li>Weekends</li>
</ul>
</li>
<li>Directions</li>
</ul>
</li>
</ul>
</div>
</body>
I tried a style like this.
body {
font: 13px/160% Trebuchet MS,Arial,Helvetica,Sans-Serif;
margin:0;
padding:0
}
#nav{
list-style:none;
font-weight:bold;
width:100%;
}
#nav li{
float:left;
margin-right:40px;
position:relative;
}
The issue with this is, its saying all li descendants of id nav get set to float left. Now I only want the first level li tags to float to left and all the other level li tags to be ignored. Please don't answer by saying use a class name for all the top level li tags. I already am aware I could approach it like this. What I'm after is to learn some of the Pseudo-classes and how they may help me in this approach.
For example I need something that is like #nav li:first-child{ .... } But this is only going to give me the first li in the top ul list. I want all the top level children of the ul list and ignore the second level li tags and so on. Is there a Pseudo-classes that can accomplish this.
Thanks
you can use #nav > li this matches all elements that are the immediate li children of #nav.
More info here and here.
A demo: http://jsfiddle.net/9M6p2/
A good approach would be:
#nav li { float: left; }
#nav li li { float: none; }
You could use #nav li like you already do and #nav li ul or #nav li ul li to style the second level LI-Elements.

Resources