Can't get the tabs right (almost there)

Please, have a look at this webpage which makes use of tabs with java-script.

The colours, borders and layout is all based on css


<style>
#Tabs ul {
padding: 0px;
margin: 0px;
margin-left: 10px;
list-style-type: none;
}

#Tabs ul li {
display: inline-block;
clear: none;
float: left;
height: 24px;
width: 80px;
border-bottom: 0px;
}

#Tabs ul li a {
position: relative;
margin-top: 16px;
display: block;
margin-left: 6px;
line-height: 24px;
padding-left: 10px;
background: #DFF161;
z-index: 9999;
border: 2px solid #ccc;

-moz-border-radius-topleft: 6px;
border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
border-top-right-radius: 6px;

width: 130px;
color: #000000;
text-decoration: none;
font-weight: bold;
}

#Tabs ul li a:hover {
text-decoration: underline;
background-color: #FFFFFF;
border-bottom: none;
}

#Tabs ul li a:selected { color: #000; background-color: #f1f0ee; font-weight: bold; }



#Tabs #Content_Area { // this is the css class for the content displayed in each tab
padding: 15px;
margin: 24px;
clear:both;
line-height:19px;
position: relative;
top: 20px;
z-index: 5;
width: 800px;
height: 800px;
overflow:auto;
border: 2px solid #ccc;
border-top: 0px;
display:block}

</style>

I want to achieve the following layout effects:

  1. I would like the width of tabs are either set individually (not all equally spaced) or have a width according to the text they have, so as for instance the years 2007-2012 have a smaller width while the first tab is wider, therefore all text is visible.

When the tab is hovered, the botom-border goes away (but only part of it goes away). Can’t figure out the problem.

I would like that when a tab is clicked, the background colour changes (even if mouse is not over) so as to show which tab is being read. I tried with a:selected but without success.

These are the main problems; hope I can find your kind help for a solution

Thanks

Stepen

You can try this. There is a slight jog when the longer words are hovered because you change the font style to italic. You might consider a different font that does not change character width or word spacing when italicized.

I was unable to understand whether the presence or absence of the bottom border was the problem, so that remains unchanged (the border goes away).


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width">
    <title>template</title>
<!--
http://www.sitepoint.com/forums/showthread.php?1166029-Can-t-get-the-tabs-right-(almost-there)
Thread: Can't get the tabs right (almost there)
2013.08.25 14:20
SteveMif

You might consider a different font that does not change character width when italicized, or simply not italicize the text on :hover.
-->
    <style type="text/css">

#Tabs ul {
    list-style-type:none;
    padding-left:24px;
    margin:0;
}

#Tabs ul li {
    float:left;
    clear:none;
    border-bottom:0;
}

#Tabs ul li a {
    position:relative;
/*  z-index:1; /* */
    display:block;
    line-height:24px;
    background:#dff161;
    border:2px solid #ccc;
    -moz-border-radius-topleft:6px;
    border-top-left-radius:6px;
    -moz-border-radius-topright:6px;
    border-top-right-radius:6px;
    color:#000;
    font-weight:bold;
    text-decoration:none;
    padding:1px 10px;
    margin-top:16px;
/*  margin-left: 1px; /* */
}

#Tabs ul li a:hover {
    text-decoration: underline;
    background-color: #fff;
    border-bottom: none;
}

#Tabs ul li a:selected {
    color:#000;
    background-color:#f100ee;
    font-weight:bold;
    padding:14px 6px 8px 6px;
}

    </style>
</head>
<body>

<div id="Tabs">
    <ul>
        <li id="li_tab1" onclick="tab('form')"><a href="#">Feedback Form</a></li>
        <li id="li_tab2" onclick="tab('2012')"><a href="#">2012</a></li>
        <li id="li_tab3" onclick="tab('2011')"><a href="#">2011</a></li>
        <li id="li_tab4" onclick="tab('2010')"><a href="#">2010</a></li>
        <li id="li_tab5" onclick="tab('2009')"><a href="#">2009</a></li>
        <li id="li_tab6" onclick="tab('2008')"><a href="#">2008</a></li>
        <li id="li_tab7" onclick="tab('2007')"><a href="#">2007</a></li>
        <li id="li_tab8" onclick="tab('news')"><a href="#"> Newspaper</a></li>
    </ul>
</div>

</body>
</html>

And you may want to set the margin-top of #Content_Area to zero.

Well, first things first. Don’t needlessly inconvenience your users, the copyright protection script you’re running does that in spades since it will block copy and past, bookmarking, etc all because you’re trying to protect html source that anyone that knows what they’re doing can access anyway. You’re basically just making people go through an extra step or throw up their hands and say why even bother or how ridiculous.


#Tabs ul li {
display: inline-block;
clear: none;
float: left;
height: 24px;
[COLOR="#AFEEEE"]width: 80px;[/COLOR]
border-bottom: 0px;
}
#Tabs ul li a {
position: relative;
margin-top: 16px;
display: block;
[COLOR="#FF0000"]margin-left: 6px;[/COLOR]
line-height: 24px;
padding-left: 10px;
background: #DFF161;
z-index: 9999;
border: 2px solid #ccc;
 
-moz-border-radius-topleft: 6px;
border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
border-top-right-radius: 6px;
 
[COLOR="#AFEEEE"]width: 130px;[/COLOR]
color: #000000;
text-decoration: none;
font-weight: bold;
}

Remove the width, one is fixing the width of the text/link area in each tab the other is fixing the width of the tabs themselves. The default width setting for the inner area of each tab is auto in that case and it manually adjusts based on length of text like you want. If you need upper or lower limits just use min-width or max-width. This will also fix your bottom border issue becuase what you’re seeing is the overlapping borders from the other tab elements.

Your margin-left, in the red, will cause spacing in your tabs once you remove the width, it’s not doing anything for you otherwise and for the effect you want should probably be removed. If what you were trying to do is align the tabs with the table replacing it with left:24px should do that, because you’re using positioning top, left, right, or bottom can adjust it’s position offset.

:selected applies to form elements, what you are looking for is most likely :active, make sure you place it below :hover in your style sheet.

and seriously, no one is going to steal your site’s look and feel.

Hi Belsnickie and RonPat, thanks to you, things have improved a lot. I also did more tweaking to have a smoother tab.

Everything is working well now except:

  1. The selected tab (the one the user is reading) changes colour when clicked on (via the active link) but then it goes to the original colour after clcicking and hoverout. I want that the colour remains, like this example but using different tabs:
    http://www.maltawildplants.com/

  2. A minor thing and probably impossible, but the top border of the contents area is missing at the part where there is no tabs. Could it be included?

The script now looks like this:


<style>
#Tabs ul {
    list-style-type:none;
    padding-left:24px;
    margin:0;
}

#Tabs ul li {
    float:left;
    clear:none;
    border-bottom:0;
}

#Tabs ul li a {
    position:relative;
/*  z-index:1; /* */
    display:block;
    line-height:24px;
    background:#E0d040;
    border:2px solid #ccc;
    -moz-border-radius-topleft:6px;
    border-top-left-radius:6px;
    -moz-border-radius-topright:6px;
    border-top-right-radius:6px;
    color:#000;
    font-weight:bold;
    text-decoration:none;
    padding:1px 10px;
    margin-top:16px;
/*  margin-left: 1px; /* */
}

#Tabs ul li a:hover {
    text-decoration: underline;
	 font-style:normal;
    background-color: #FFF090;	
    border-bottom-color: #FFF090;
}

#Tabs ul li a:active {
    color:#000;
    background-color:#fff;
    font-weight:bold;
}

#Tabs #Content_Area { // this is the css class for the content displayed in each tab
		padding: 15px;
		margin: 24px;
		clear:both;
		line-height:19px;
		position: relative;
		z-index: 5;
		width: 700px;
		height: 600px;
		overflow:auto;
		border: 2px solid #ccc;
		border-top: 2px;
		display:block;
		background-color:#FFF090;
}
</style>

I removed the right click deactivation script. It was meant for other webpages on the same style.

The script that controls this isn’ set up properly. It’s meant to set a class of “active” on the tab that’s currently showing. If it wre doing that, you would set a style for the pab with a class of “active”. The script is far from doing that, though, so needs a JS person to fix it. Perhaps @Pullo can help with that.

Seems to me that the styles of the anchors ought to be handled entire with CSS. So far, I can see no advantage to having JavaScript control these styles other than highlighting the current tab. If JavaScript is overriding the CSS, then that’s a different story.

I should be able to offer a CSS solution within a few minutes… maybe… if needless JavaScript doesn’t interfere.

Change the on-page styles to this:


<style>

#Tabs ul {
    list-style:none;
    overflow:hidden;
    padding:16px 0 0 24px;
    margin:0;
}

#Tabs ul li {
    float:left;
}

#Tabs ul li a {
    display:block;
    line-height:24px;
    background:#e0d040;
    border:2px solid #ccc;
    -moz-border-radius-topleft:6px;
    border-top-left-radius:6px;
    -moz-border-radius-topright:6px;
    border-top-right-radius:6px;
    color:#000;
    font-weight:bold;
    text-decoration:none;
    padding:1px 10px;
}

#Tabs ul li a:hover {
    font-style:normal;
    text-decoration:underline;
    background-color:#fff090;
    border-bottom:2px solid transparent;    /* add me */
}

#Tabs ul li a:active {
    background-color:#fff;
 }

#Tabs #Content_Area {  // this is the css class for the content displayed in each tab
    width:700px;
    height:600px;
    line-height:19px;
    overflow:auto;
    border:2px solid #ccc;
    background-color:#fff090;
    padding:15px;
    margin:-2px 24px 24px;    /* add me */
}
 
</style>

Please NOTE:
The comments page shows 50 HTML validation errors.
The ecology page shows 106 HTML validation errors.
Both could use some serious TLC. :slight_smile:

This is probably because he’s using old old outdated table formatting, etc.

I disagree. Outdated, old table code can and should be essentially error free. Unfortunately, these days, many new coders underestimate the value of writing good HTML code, then wonder why their equally squirrely CSS doesn’t work. :sigh: It’s a learning curve. :slight_smile:

The problem is though that depending on your validator settings it will flag is as invalid code even if it’s functionally not an issue. Particularly if you have it set to HTML 5 or HTML. It also has a tendency to flag valid encoding as invalid depending on the HTML setting it’s validating as and on what looks to be a largely html3 codding conventions site I’d imagine you’d get more than a fair bit of those.

Keep in mind I haven’t actually looked at it in the validator yet.

Edit: in his case there’s a bit of that, like absmiddles and margin’s on those elements but most of it is typos and invalid chars and such so yeah, plenty of TLC needed

The validators are tools. They flag as invalid the things that they have been programmed to flag. Part of the learning curve is learning how to use the tools that make your code better. One can write perfectly valid code that totally fails to render as desired. One can also write pages that are marginally invalid that render just fine… New technologies sometimes use techniques that validators do not recognize. Nevertheless, one cannot lose by validating his code. Squeaky clean valid code is not necessarily a sign of success; but understanding exactly why the code is not valid is very important to writing stable, durable, cross-browser compatible code. The validators are just tools to help a coder reach that goal.

Old table code can be perfectly valid and stable.

With a bad doctype, though, all bets are off :eek:

This poster’s code is a learning lab of errors. :slight_smile: Good stuff.

Hey Ralph,

This bit of JS is setting a class of “selected” on the link that is currently selected:

if ( id == selectedId ) {
  tabLinks[id].className = 'selected';
  contentDivs[id].className = 'tabContent';
} else {
  tabLinks[id].className = '';
  contentDivs[id].className = 'tabContent hide';
}

So the markup looks like:

<ul id="tabs">
  ...
  <li><a href="#endemics" class="selected">Endemics</a></li>
  ...
</ul>

If you wanted an additional class name of “active” to be added to the <li> elements, you’d just do this:

if ( id == selectedId ) {
  tabLinks[id].className = 'selected';
  tabLinks[id].parentNode.className = 'active';
  contentDivs[id].className = 'tabContent';
} else {
  tabLinks[id].className = '';
  tabLinks[id].parentNode.className = '';
  contentDivs[id].className = 'tabContent hide';
}

Then the markup would be:

<ul id="tabs">
  ...
  <li class="active"><a href="#endemics" class="selected">Endemics</a></li>
  ...
</ul>

Does that help?

I know, I have created this website in 2006-7 and I am not a coder by profession. When I started to make my first html website in 1999 (I remember the prog was called hotdog) , the way at that time was table design and I kept that mentality all over this time. I know coders say it is outdated/old, but it is easy and works most of the time. Is there a link discussing the disadvantages of table-design. Nevertheless, I thought about the possibility of nested tables might be a problem here and I have tried the tabs & content out of any table and still it did not work.

Hi Pullo, thanks for your time. I see that you are optimizing the code for [noparse]www.maltawildplants.com[/noparse] (MWP) which at present I am happy about as it does the job, but the code in question is that on [noparse]www.MaltaNatureTours.com/comments.php[/noparse] (MNT) where I wish to have the selected tab to stand out by being coloured differently or the same as the content area. Some suggested it can be done via java-script, some said it can be solved via css. (probably it’s both!)

Thanks Pullo. Blimey, that’s not happening in my browser. There are no classes on any tab when it’s selected.

Hi, Ralph,

The page, http://www.maltawildplants.com/ , for which Pullo wrote the JavaScript, seems to be working just fine in my browser.

The first page, http://www.maltanaturetours.com/comments.php#tp, doesn’t have the CSS to support the class, yet. (Actually, I think the class was coded as a pseudoclass and the OP removed it.)

Oh dear. Sorry about that!
I’ll sort that out now. Hang fire!

Yes, it’s both. The CSS that I posted in #7 should fix the top border on #Content_Area and allow the bottom of the active tab to flow through to #Content_Area. You will need to write a similar JavaScript for the comments page and set a CSS class for .selected and describe it.


#Tabs ul li a.selected {
    font-style:normal;
    text-decoration:underline;
    background-color:#fff090;
    border-bottom:2px solid transparent;
}

So, this’ll work for the page: http://www.maltanaturetours.com/comments.php

Replace this:

<ul>
  <li id="li_tab1" onclick="tab('form')"><a href="#tp">Feedback Form</a></li>
  <li id="li_tab2" onclick="tab('2012')"><a href="#tp">2012</a></li>
  <li id="li_tab3" onclick="tab('2011')"><a href="#tp">2011</a></li>
  <li id="li_tab4" onclick="tab('2010')"><a href="#tp">2010</a></li>
  <li id="li_tab5" onclick="tab('2009')"><a href="#tp">2009</a></li>
  <li id="li_tab6" onclick="tab('2008')"><a href="#tp">2008</a></li>
  <li id="li_tab7" onclick="tab('2007')"><a href="#tp">2007</a></li>
  <li id="li_tab8" onclick="tab('news')"><a href="#tp">Newspaper</a></li>
</ul>

With this:

<ul id="tab-nav">
  <li class="active"><a href="#form">Feedback Form</a></li>
   <li><a href="#2012">2012</a></li>
   <li><a href="#2011">2011</a></li>
   <li><a href="#2010">2010</a></li>
   <li><a href="#2009">2009</a></li>
   <li><a href="#2008">2008</a></li>
   <li><a href="#2007">2007</a></li>
   <li><a href="#news">Newspaper</a></li>
</ul>

And this:

function tab(tab) {
  document.getElementById('form').style.display = 'none';  
  document.getElementById('2012').style.display = 'none';
  document.getElementById('2011').style.display = 'none';
  document.getElementById('2010').style.display = 'none';
  document.getElementById('2009').style.display = 'none';
  document.getElementById('2008').style.display = 'none';
  document.getElementById('2007').style.display = 'none';
  document.getElementById('news').style.display = 'none';
  document.getElementById('li_tab1').setAttribute("class", "");
  document.getElementById('li_tab2').setAttribute("class", "");
  document.getElementById('li_tab3').setAttribute("class", "");
  document.getElementById('li_tab4').setAttribute("class", "");
  document.getElementById('li_tab5').setAttribute("class", "");
  document.getElementById('li_tab6').setAttribute("class", "");
  document.getElementById('li_tab7').setAttribute("class", "");
  document.getElementById('li_tab8').setAttribute("class", "");
  document.getElementById(tab).style.display = 'block';
  document.getElementById('li_'+tab).setAttribute("class", "active");
}

With this:

var tabList = document.getElementById("tab-nav"),
    tabs = tabList.getElementsByTagName("li");

for (var i=0, l = tabs.length; i < l; i++){
  tabs[i].onclick = function(e){
    handleTabClick(e, this);
  }
}

function handleTabClick(e, tab){
  var activeTab = document.getElementsByClassName("active")[0],
      activeContentId = activeTab.childNodes[0].getAttribute("href").replace(/#/, ""),
      activeContent = document.getElementById(activeContentId),
      contentId = tab.childNodes[0].getAttribute("href").replace(/#/, ""),
      contentDiv = document.getElementById(contentId);
      
  activeContent.style.display = "none";
  contentDiv.style.display = "block";
  activeTab.className = '';
  tab.className = 'active';
  e.preventDefault();
}

It’s a bit clunky, but’ll work.
Let me know if you decide to go with this and I’ll look at tidying things up a little.

Here’s a demo.

I am soon off to the library, but have enough time to reply RonPat about the border.

The content area css at #7 did not work well for me. Apparently the Clear:both was essential. Anyway, your code generated a grey line border below the tabs which was permanent. I want that the colour of the tab and the content area background be the same and merge as one body. Since I am not good to explain in words, here I attach an image example. However the bottom pic lacks the grey border were there are no tabs. I think the border has to stay (the way you suggested) but the selected tab (at the moment working on hoover) has to get 2pix larger so as to overlay and cover the top border of the content area.

The image below was taken with the mouse over the tab. I want to stay like that when selected (Just to remove any doubts of what I wish to achieve)

A big thank you to all