Is it appropriate to wrap each navigation element in a div? - css

I'm learning HTML + CSS and working on a website where I need to have a vertical navigation bar on the left side which will have four elements which can be interacted with. Is it standard practice to wrap each of these four elements with a div or is there a more elegant or semantic way to solve this problem? I will want each element to have unique on-click functions associated with them, which is why I thought giving them divs and classes would make the most sense for interacting with them later.
Thanks!

JSFIDDLE DEMO
HTML structure:
There are many ways to achieve a vertical navigation.
The most common would be to use ul and li:
<div id="lnav_container">
<ul id="lnav">
<li class="lnav_item">Item 1</li>
<li class="lnav_item">Item 2</li>
<li class="lnav_item">Item 3</li>
<li class="lnav_item">Item 4</li>
</ul>
</div>
Also very common to have a tags inside li.
Styling:
You can get rid of the bullets by having list-style-type: none; for the ul.
You can give them different style on hover by using :hover selector to make it more interactive.
.lnav_item {
width: 74%;
margin-top: 10px;
}
.lnav_item:first-child {margin-top: 0px;}
.lnav_item.selected {width: 86%;}
.lnav_item a {
display: inline-block;
width: 100%;
line-height: 30px;
padding: 8px 5px 5px 0px;
background-color: yellow;
color: black;
font-weight: bold;
text-decoration: none;
border-radius: 2px 12px 12px 2px;
}
.lnav_item.selected a {
background-color: green;
color: white;
font-size: 18px;
}
.lnav_item:hover a {background-color: orange;}
To get rid of a underline use text-decoration: none; and override its default coloring if you wish.
Javascript (jQuery):
It'll be easy to bind clickListener to the items:
$('.lnav_item a').on('click', function() {
//$(this) item is clicked, do whatever you want
$('.lnav_item').removeClass('selected');
$(this).parent().addClass('selected');
});
EDIT:
If you want to give each of the navigation items a different style, etc, you can achieve it different ways:
jsfiddle DEMO
You can use CSS' nth-child() selector:
.lnav_item:nth-child(2):hover a{background-color: #252F1D;}
.lnav_item:nth-child(3):hover a{background-color: white;}
If you're doing it in jQuery, alternatively you can use the function with parameter (index) and maybe use eq if needed.
$('.lnav_item > a').each(function(index) {
if(index == 0) {
//give it a different onClick, CSS rule, etc
}
//and so on
});
index is zero-based, but nth-child starts from one.

The typical HTML5 markup for a site navigation menu would be a nav element that contains an ul element:
<nav>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</nav>
If you can get your CSS/JS to work with this markup (+ class attributes or whatever you need), great.
If you need more elements, add div and/or span elements: they are meaningless, so they don’t change the semantics of your document.

NAV elements are simply LISTS.
You don't need to wrap them in anything.
Here's an example of my own Navigation Panel (I also placed it on the left-hand side of my screen)
<nav>
<ul style="list-style: none">
<h3>Main Menu</h3>
<li style="font-size: 100%"><b>Article 1</b></li>
<ul style="list-style: none">
<br>
<dt>
<li style="font-size: 100%"><a href="Article 1.1">Article
1.1</a>
</li>
<br>
<li style="font-size: 100%"><a href="Article 1.2">Article
1.2</a>
</li>
<br>
</dt>
</ul>
<br>
</nav>

Related

Bootstrap menu focus background color

I'm trying to build a simple drilldown in Bootstrap. When the user selects a "row", I want the background color to change to indicate what "row" is selected. It only works like I want it on the first level rows.
Here's the basic HTML:
<div class="container">
<ul class="nav nav-drilldown" id="Menu">
<li>
Thing the first
<ul class="collapse" id="a">
<li>child 1</li>
<ul class="collapse" id="a-child-1">
<li>
<div class="row">
<div class="col-md-6">something</div>
<div class="col-md-3">goes</div>
<div class="col-md-3">here</div>
</div>
</li>
</ul>
</ul>
</li>
</ul>
</div>
And the CSS:
.nav-drilldown:focus {
background-color: #eee;
}
.nav-drilldown li li a:focus {
background-color: #FF0000;
}
.nav-drilldown li a:focus {
background-color: #eee;
}
For the second level, on the text part of the anchor changes background color. I get that you can't set selected on a <li>, but i don't understand why the second level doesn't behave like the first level. I can't get the third level to much of anything.
Level 1:
Level 2:
JSFiddle
I believe this is just a matter of the padding on the anchor tag. At the top level, you have 10px top and bottom padding and on the second level anchor tag, you have no padding. So, if you want similar behavior, you could add:
.nav-drilldown li li a {
padding: 10px 15px;
}

Is there a CSS way to make class="active" toggle on menu?

Here is the plunker - http://plnkr.co/edit/WZ6cqCcXaLuOCXnZdCa6?p=preview
Is there a CSS way so that when I click on One or Two, it becomes class="active" for One or Two and removed from Home?
You can highlight each link with CSS alone, but not by using classes. Rather, use the :target pseudo class: http://codepen.io/pageaffairs/pen/kqoma
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
ul, li, div {margin: 0; padding: 0;}
ul {
list-style: none;
overflow: hidden;
padding: 10px;
}
li {
float: left;
margin: 0 20px 0 0;
}
li a {
display: block;
padding: 10px 20px;
text-decoration: none;
color: #08c;
border-radius: 20px;
}
li a:hover, li a:target {
background: #08c;
color: white;
}
</style>
</head>
<body>
<h1>Hello <code>:target</code>!</h1>
<div class="header">
<ul class="nav nav-pills">
<li class="active">
Home
</li>
<li>
One
</li>
<li>
Two
</li>
</ul>
</div>
</body>
</html>
You will need to edit the html somehow, css doens't have the ability to change an elements class. You could write a little function to js to do this on a click event and remove the class from the old menu item and add it to the newly selected menu item.
like this:
http://plnkr.co/edit/6B5v2KrZonuI33dJySS6?p=preview
You can so this with jQuery, following this format:
switch (window.location.pathname) {
case '/THE_URL_HERE':
$('.nav-home').addClass('active');
break;
case '//THE_URL_HERE':
$('.nav-one').addClass('active');
break;
case '//THE_URL_HERE':
$('.nav-two').addClass('active');
break;
}
And add classes to your HTML:
<h1>Hello Plunker!</h1>
<div class="header">
<ul class="nav nav-pills">
<li class="nav-home">
Home
</li>
<li class="nav-one">One</li>
<li class="nav-two">Two</li>
</ul>
</div>
Not using CSS exclusively. Behavioral features, such as linking, and modification of the DOM are outside the scope of CSS.
However, you could construct the links to modify the query string of the URL (e.g. ?item=one) and use the resulting GET values to set classes on your navigation.
Or use javascript.
use :target it's more flexible if it's to make a menu without javascript

<li> problems, links are going on top of each other not side by side

Hopefully you can see what the problem is, I want the links to go side by side not on top of each other?
Can you please see what the problem is on JS Fiddle: http://jsfiddle.net/pky7X/
Thank you for any help
At first, you forgot the <ul></ul>
<style>
ul {
list-style-type: none;
}
li {
float: left;
border: 1px solid #ff9900;
}
</style>
<ul>
<li>Home</li>
<li>About</li>
</ul>
First: You're missing <ul> around your <li> tags (don't think that's valid in HTML5; it wasn't before).
Second: Why even using list items and then removing the list-style and adding float?
Just use <span> or the <a> directly...
HomeAbout
... and then use CSS to set their padding, style, dividers, etc.
Remove the <br /> and place <li> tags inside a <ul> like so:
<ul>
<li>Home</li>
<li>About</li>
</ul>
Remove margin: -35px 220px; from CSS and remove the <br /> from HTML.

CSS: remove separator on the last and first item

I have a menu div which has a dark background. Inside it, I have several menu item divs with 1px margins on the right and the left. This way I've got separators between them. Obviously these appear on the very left and very right side of the menu which I don't want. Is there a way to accomplish this without inserting 1-pixel divs as separators?
Thank you
edit: sorry, I thought it was descriptive enough. Here is the code:
<div id="menu">
<div class="menu_item"><img src="imgs/menu/szabalyzat.png" /></div>
<div class="menu_item"><img src="imgs/menu/profil.png" /></div>
<div class="menu_item"><img src="imgs/menu/zenekarok.png" /></div>
<div class="menu_item"><img src="imgs/menu/jelentkezes.png" /></div>
<div class="menu_item"><img src="imgs/menu/esemenynaptar.png" /></div>
<div class="menu_item"><img src="imgs/menu/mmmk_estek.png" /></div>
</div>
IE6 incompatibility is OK (thankfully).
The following rule will apply to all .menu_item elements that follow another .menu_item element:
.menu_item + .menu_item {
border-left: 2px solid black;
}
The simplest way yo achieve it is to mark your first and last elements with custom classes and remove that margins from them.
<ul class="menu">
<li class="first">One</li>
<li>Two</li>
<li>Three</li>
<li class="last">Four</li>
</ul>
<style>
.menu li { margin: 0 1px; }
.menu .first { margin-left: 0; }
.menu .last { margin-right: 0; }
</style>
You can also try using complex css selectors, like :first-child, but they do not work in older versions of MSIE.
OR, you can use 2px margins on the right side instead and go with only one additional class:
<ul class="menu">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li class="last">Four</li>
</ul>
<style>
.menu li { margin-right: 2px; }
.menu .last { margin-right: 0; }
</style>
If a high percentage of your audience's browsers support CSS3, you can use the :first-child and :last-child pseudo-classes:
div#menu div:first-child {
margin-left: none;
}
div#menu div:last-child {
margin-right: none;
}
Can't you have 2px left-margin instead of 1px on each side and then use the css pseudo class :first-child to remove these margin for the first item ?
EDIT: I agree with the fact that you should use border as separator rather than background but in case you do this that way for some good reasons, my answer's still valid :-)

CSS Accordion/Tree Menu with 100% width dividers

I want to create a CSS/JS accordion menu, with HTML like so:
<ul>
<li>First Link
<ul>
<li>Child One</li>
<li>Child Two</li>
</ul>
</li>
<li>Second Link</li>
<li>Third Link</li>
</ul>
The nav structure can get N levels deep, and each child menu will be indented from its parent. I want there to be a border that spans 100% of the width between all nav elements including the n-th level child elements. Like this:
alt text http://files.getdropbox.com/u/64548/nested-nav.png
I cannot for the life of me figure out an easy way to do this without using JavaScript, but it feels like something that should be possible. (I will be using JS to expand/collapse the nav tree).
You need to have the border and padding on the <a> which also must be set to display:block. This gives an added bonus as it makes the whole <li> region clickable.
There is no extra markup needed in the ul. Just define the max number of sublists in your css.
Example here
a {text-decoration:none;}
ul {width:240px;padding:0;list-style:none;border-top:1px solid #000;}
ul ul, ul ul ul {border-top:0;}
li a {border-bottom:1px solid #000;display:block;padding-left:0px;}
li li a {padding-left:40px;}
li li li a {padding-left:80px;}
<ul>
<li>First Link
<ul>
<li>Child One</li>
<li>Child Two
<ul>
<li>Child Two One</li>
<li>Child Two Two</li>
</ul>
</li>
</ul>
</li>
<li>Second Link</li>
<li>Third Link</li>
</ul>
The tiling background image for the divider rows does not contradict resizing (at least should not, with sane CSS renderers).
This is pretty sloppy for my tastes, but basically it requires text-indent instead of padding or margin to achieve the nesting. But then to use a sprite image as the bullet for the <a>, you have to end up taking the current text-indent for the level and bump the sprite image over that many px, minus the sprite image width.
I've changed it to use padding-left on the anchor instead, but then this requires overflow: hidden on the parent div to hide the extra border that gets pushed to the right with each nesting.
And of course, visualize any of the stuff like .two_deep, .expanded, etc. as being done with jQuery, and NOT hardcoded into the CSS. It should be fairly simple to get a ul's depth in the menu.
<html>
<head>
<style>
body {font: normal 11px Arial;}
a:link, a:visited {color: #888; text-decoration: none;}
a:hover, a:active {color: #000; text-decoration: none;}
div {width: 250px; border-top: 1px solid #888; overflow: hidden;}
ul {
width: 100%;
margin: 0; padding: 0;
list-style-type: none;
}
li {
padding: 5px 0;
border-bottom: 1px solid #888;
}
li a {
display: block;
}
.two_deep li a {
padding-left: 25px;
}
.three_deep li a {
padding-left: 50px;
}
.four_deep li a {
padding-left: 75px;
}
.expanded {
display: block;
width: 100%;
border-bottom: 1px solid #888;
margin: -5px 0 5px;
padding: 5px 0;
}
li > ul {margin: -5px 0 -6px;}
</style>
</head>
<body>
<div>
<ul>
<li><a class="expanded" href="#">First Link</a>
<ul class="two_deep">
<li>Child One</li>
<li>
<a class="expanded" href="#">Child Two</a>
<ul class="three_deep">
<li>
<a class="expanded" href="#">Child One of Child Two</a>
<ul class="four_deep">
<li>Child One of . . .</li>
<li>Child Two of . . .</li>
</ul>
</li>
<li>Child Two of Child Two</li>
</ul>
</li>
</ul>
</li>
<li>Second Link</li>
<li>Third Link</li>
</ul>
</div>
</body>
</html>
But honestly, maybe you would rather just use a background image, and have it look ugly/broken when text is resized. The css is a bit 'hack-y' for my tastes, especially all the padding compensation needed due to the anchor and li having to be siblings.
I've tested this in Firefox 3.5, Safari 4, and Opera 9.6. I don't have access to anything else at the moment, so it's probably not even very pretty.
Needless to say it's probably a complete wreck in all IE versions. Sorry… It was just my own little test to see if I was up to the task!
Edit: It DOES work with page zoom and text resize, but again, IE support (?)…

Resources