Is this the best way?

Hi all

I hava a simple header with two sets of horizontal navigation. Both the navigations are in div’s and I’m using padding on top of the divs to push the navigation into the place I want.

It all works fine but it doesn’t seem like the correct way to do it. Is there a better way to do this.

http://www.ttmt.org.uk/forum/nav/


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
   
   <title>untitled</title>
   <style type="text/css" media="screen">
    *{
      margin:0;
      padding:0;
      list-style:none;
      text-decoration:none;
    }
    
    #wrapper{
      width:800px;
      margin:auto;
    }
    #header{
      position:relative;
      background:gray;
      height:190px;
      font-weight:bold;
    }
    #header #headNav_1,
    #header #headNav_2{
      margin:0 25px;
      float:left;
      clear:both;
    }
    #header #headNav_1{
      padding-top:70px;
    }
    #header #headNav_2{
      padding-top:50px;
    }
    #header #headNav_1 li,
    #header #headNav_2 li{
      display:inline;
    }
    #header #headNav_1 li a,
    #header #headNav_2 li a{
      display:block;
      float:left;
      color:#fff;
      padding:.6em .9em;
    }
    #header #headNav_1 li a:hover,
    #header #headNav_2 li a:hover{
      background:#aaa;
      color:gold;
    }  
   </style>
</head>

<body>
  <div id="wrapper">
    <div id="header">

      <div id="headNav_1">
        <ul>
          <li><a href="contact.html">Contact</a></li>
          <li><a href="areas.html">Areas Covered</a></li>
        </ul>  
      </div>
      
      <div id="headNav_2">
        <ul>
          <li><a href="index.html" class="select">Home</a></li>
          <li><a href="services.html" >Services</a></li>
          <li><a href="consult/consult.html">Consultancy</a></li>
          <li><a href="company/company.html">Company</a></li>
          <li><a href="faq.html">FAQs</a></li>
        </ul>   
      </div>

    </div><!--header-->   
  </div>     
      
</body>
</html>

I personally would never use padding to positioning divs. I think margins are way more appropriate to use

Hi,

Your header is a fixed height and therefore you are relying on padding + font-size + line-height + margin to get your second nav to sit on the bottom of the header. If any of these differ or the user resizes the text then the bottom nav is going to be misplaced.

You could either not use a height at all for the header and then any differences will not be noticed cross browser. You’d just need to make sure you clear the floats so the header background extends around them.

If the header must be that fixed height then a better alternative would be to place the second nav absolutely on the bottom and then it will be exact cross browser (apart from Ie6 which is one pixel out when bottom is used and the distance covered is an odd number of pixels - but that won’t really notice.)

It also means if text is resized the text rises upwards and doesn’t break out of the header.

Something roughly like this:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>untitled</title>
<style type="text/css" media="screen">
html, body, h1, h2, h3, h4, h5, h6, ol, ul, form {
    margin:0;
    padding:0;
}
ul, ol {list-style:none}
a {text-decoration:none}
#wrapper {
    width:800px;
    margin:auto;
}
#header {
    position:relative;
    background:gray;
    font-weight:bold;
    height:190px;
}
.headNav {
    margin:0 25px;
    float:left;
    clear:both;
    display:inline;
    padding-top:70px;
}
.headNav2 {
    position:absolute;
    left:25px;
    bottom:-.5em;
    padding:0;
    margin:0;
}
.headNav li {display:inline}
.headNav li a {
    float:left;
    color:#fff;
    padding:0 .9em;
    line-height:2.4em;
    height:2.4em;
}
.headNav li a:hover {
    background:#aaa;
    color:gold;
}
</style>
</head>
<body>
<div id="wrapper">
    <div id="header">
        <ul class="headNav">
            <li><a href="contact.html">Contact</a></li>
            <li><a href="areas.html">Areas Covered</a></li>
        </ul>
        <ul class="headNav headNav2">
            <li><a href="index.html" class="select">Home</a></li>
            <li><a href="services.html" >Services</a></li>
            <li><a href="consult/consult.html">Consultancy</a></li>
            <li><a href="company/company.html">Company</a></li>
            <li><a href="faq.html">FAQs</a></li>
        </ul>
    </div>
    <!--header-->
</div>
</body>
</html>


There was no need to wrap divs around the uls unless you had good reason. Also use classes instead of duplicating ids all the time when most of the styles could be re-used.

Don’t use the global reset (* margin:0;padding:0) and especially don’t apply things like list-style:none to it either as that is a waste of time as only uls and ols have that style. Indeed, I believe some old IE versions crash if you do things like that.:slight_smile:

I generally agree with donboe here, mostly because padding shows the moment a background colour, image, or border is added. Margins stay invisible.

What I would do is empty the navs (so it’s just ul, which is illegal but this is just for testing) and get them positioned where you want based on then default document flow… then use margins from there.

Keep in mind that with floated children like you have (which is fine) means unless you trigger both Haslayout in IE and something like overflow: hidden for float-wrapping in Modern Browsers, you won’t see or affect the positioning much of the children.

If you’ve never heard what I’m talking about, let us know. It’s common but a great cause of trouble to those new to CSS.

u have to THINK abouit what your desired effect is. ASK the following questions.

  1. is the size of my header fixed AND independent of the size of the navigation ( lets ay in the case where you have a header that needs to show a 900 x 200px image… , for example)… in this case you are better off setting height + width… and using either or ABSOLUTE positioning

  2. BUT if you want the nav to determine the size of your header, you COULD use RELATIVE POSITIONING and MARGIN. The size of the document will me based on your content, but you can offset the position in which it’s displayed.

I should clarify that margins and padding are different things although at times they can accomplish the same task.

Margin is the space outside the element and padding is the space inside the element. Margins collapse in certain circumstances but padding never collapses.

For the first statically placed element inside a container the top margin would collapse with the parent and instead of the inner element being moved the parent would be moved instead and the inner element would remain stuck to the top of the parent. In cases like this top padding would be more suitable (assuming that the element in question does not have a specific height that needs to be maintained).

In most normal cases though margins are the preferred method to move things around. It does depend on situation and whether margin collapse is an issue but margin and padding are different things although as mentioned above they can accomplish similar things in the right situation.

Thanks for all you help and advise with this - i knew the way I did it didn’t seem right.

Paul O’B, in your first post you used this code - why have you used line-height and height, would the padding on it’s own not do the job?


.headNav li a {
    float:left;
    color:#fff;
    padding:0 .9em;
    line-height:2.4em;
    height:2.4em;
}

If you have “non-wrapping” text then you can set the line-height to the same as the height for that element and the text will automatically be vertically centred within that element.

This has a number of good benefits over using padding top and bottom and they are as follows:

  1. If you use padding top and padding bottom the you have to calculate font-size + padding top + padding bottom + line-height to arrive at a final height. With the line-height method you have no calculations.

  2. If you haven’t worked these measurements out exactly then your dimensions will be inaccurate. The issue is also compounded by the fact that you may have rounding issues to arrive at a final size and the fact that browsers will vary on the font-size anyway.

  3. If the user resizes the text then the element grows in height because the padding top and bottom push out and if the background was a fixed height image then the layout breaks. using line-height the image can resize and still stay vertically centred and not break the layout for quite a few resizes.

  4. It’s just a simpler and more robust way to vertically centre text within an element.

If you have text that wraps to two lines then you would need to use the padding method but for most menus which don’t have wrapping text then the line-height method is simpler and more robust.