PHP include menu & class active CSS

Hi Folks,

Just a quick question, hopefully somebody can clear this up for me please.

I have my navigation menu in a php include file being expressed in each page.

<?php include("includes/menu.php"); ?>

I also have my menu styled in my CSS sheet. However, the problem lies on the link being ‘active’. Meaning, when I’m at the ‘Home’ page then the ‘Home’ button should be highlighted and so on etc.

Now, how can this be done using CSS so that the current page corresponds with the certain button, and thus highlight that button?..

I think I know one way, but I failed doing it as I’m not quite sure / certain how to lay it in the stylesheet.

— Give the body tag of each individual PHP page a unique ID, for example: [SUB]body id=“home”[/SUB] for the home page. Furthermore, give each li anchor link in the php include file add the appropriate unique ID [SUB]<li><a href=“home.php” id=“home”>Home</a></li>[/SUB]. Then, when it comes to the CSS I’m a little sticky ??

That way, each page / body will have it’s own unique id and thus each link will have it’s own unique id for the current page to correspond with the CSS, and each active link can be altered and differ if wanted.

Thanks.

You have the right thought there. tho IDs maybe a but heavy handed and classes would do as well. Plus it’s not valid to have two of the same ID in the same document so lets say you give each LI a class instead. Let’s assume you wanted to have the current page link highlighted the same way as your hover states. You would to the markup as you described CSS, am also using a class=“nav” in the UL for good measure, and then your would be as follows:

.nav li{grenaral styling here. }
#home li.home, #about li.about, #page li.page, #other li.other,    .nav li:hover {hover and current styling here }

That should be sufficient but if it’s not try this

#home .nav li.home, #about .nav li.about, #page .nav li.page, #other .nav li.other,    .nav li:hover {hover and current styling here }

Hope that helps

Thanks for your reply dresden,

Do you mean an ID in each body tag and a Class in each anchor link? - Like below…

For index page…

<body ID="Home">

menu.php Include…

<div class="menu">
<ul>
	<li><a class="homelink" href="index.php">Home</a></li>
        <li><a class="portfoliolink" href="portfolio.php">Portfolio</a></li>
        <li><a class="aboutlink" href="about.php">About Us</a></li>
	<li><a class="bloglink" href="blog.php">Our Blog</a></li>
        <li><a class="contactlink" href="contact.php">Contact Us</a></li>
</ul>
</div>

And here is my current CSS menu, where the menu changes on hover and the hover stays static on active page.

.menu {width:500px; margin:109px 0 0 0; padding:0; float:right; font: 12px Georgia, "Times New Roman", Times, serif;}
.menu ul {float:right; margin:0; padding:0; list-style:none;}
.menu li {float:left; margin:0 1px; padding:0; font:bold 12px Arial, Helvetica, sans-serif; color:#fff; float:left;}
.menu a {line-height:16px; float:left; font: normal 12px Georgia, "Times New Roman", Times, serif; color:#fff; padding:10px; margin:0; text-decoration:none;}
.menu a:hover {color:#fff; background: #212121 url(images/corner/menu_left.gif) top left no-repeat;}
.menu a:hover div {background: #212121 url(images/corner/menu_rigth.gif) top right no-repeat;}
.menu a.active {color:#fff; background: #212121  url(images/corner/menu_left.gif) top left no-repeat;}
.menu a.active div {background: #212121 url(images/corner/menu_rigth.gif) top right no-repeat;} 

So where do I put the following and what ?

#home .menu li.homelink, #portfolio .menu li.aboutlink, #about .menu li.aboulink, #blog .menu li.bloglink, #contact .menu li.contactlink {
}

Thanks.

Basically you have a hover/active state for your links, and you want that to stay in place on the selected page, so it is the <a> element that you need to target. So in your style sheet, you’d have:

#home .homelink a, #portfolio .aboutlink a {background: #212121} 

and so on.

As an aside, you don’t need the div around the <ul> as the <ul> itself is a block leve element, so you might as well lost the div and put the class on the <ul> itself. Also, don’t know if you meant to write this:

.menu a.active [COLOR="#FF0000"]div[/COLOR] {

but a block element (in this case a div) should not be inside an inline element (in this case, an <a>).

Thanks for the heads up on that.

However, now that I have removed the DIV and placed the class=“menu” in the UL and altered the CSS. The menu is now not against the right hand side of the header the way it was before. The menu is set inside a header Div inside the includes file, and the header is set to a fixed 1024px width. The menu before was floated right against the right hand side with 0px margin, however now that it’s been altered its sitting out about 50px for some odd reason.

.menu { float:right; width:500px; margin:109px 0 0 0; list-style:none; padding:0; font: 12px Georgia, "Times New Roman", Times, serif;}
.menu li { float:left; margin:0 2px; padding:0; font:bold 12px Arial, Helvetica, sans-serif; color:#fff;}
.menu a { line-height:16px; float:left; font: normal 12px Georgia, "Times New Roman", Times, serif; color:#fff; padding:10px; margin:0; text-decoration:none;	}
.menu a:hover  {color:#fff; background: #212121;  }
.menu a.active {color:#fff; background: #212121; }

Does this look ok now? - without the current page CSS of course.

Thanks!

Well to diagnose that problem we will really need a link to see hte issue. Or at minimum the full rendered HTML and CSS.

We would really prefer the link though :). It sitting out 50px or so is likely easy to fix.

It’s called ‘start using variables’. (and while at it lose the pointless DIV for nothing around the UL)… even easier if you start using functions, because then all your ‘common’ elements that appear on every page can go into a SINGLE include file. You may also wish to consider using single quotes in your PHP, so when it comes time to start using echo you’re not reversing them – and single quotes are faster/more predictable in behavior.

your document:


<?php
	include('includes/theme.php');
	theme_header('','Site Title','home');
?>
Your content here
<?php
	theme_footer();
?>

theme.php


<?php
function theme_header($pageTitle='',$siteTitle,$pageShortName) {
	echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<link
	type="text/css"
	rel="stylesheet"
	href="screen.css"
	media="screen,projection,tv"
/>

<title>
	',(isempty($pageTitle) ? '' : $pageTitle.' - '),$siteTitle,'
</title>

</head><body>

<div id="pageWrapper">

	<h1>',$pageTitle,'</h1>
	
	<ul id="mainMenu">
		<li>
			<a',(
				$pageShortName=='home' ? ' class="current"' : ''
			),' href="index.php">Home</a>
		</li><li>
			<a',(
				$pageShortName=='portfolio' ? ' class="current"' : ''
			),' href="portfolio.php">Portfolio</a>
		</li><li>
			<a',(
				$pageShortName=='about' ? ' class="current"' : ''
			),' href="about.php">About Us</a>
		</li><li>
			<a',(
				$pageShortName=='blog' ? ' class="current"' : ''
			),' href="blog.php">Our Blog</a>
		</li><li>
			<a',(
				$pageShortName=='contact' ? ' class="current"' : ''
			),' href="contact.php">Contact Us</a>
		</li>
	</ul>
	
	<div id="content">';
}

function theme_footer() {
	echo '
	<!-- #content --></div>
	
	<div id="footer">
		Site disclaimer here
	<!-- #footer --></div>
	
<!-- #pageWrapper --></div>

</body></html>';
}

?>

Then you only need one class to say which one is ‘current’, just by changing what you feed it for values… and you can make a second function like ‘theme_footer’ in the same file containing your <div id=“footer”></div></body></html> or whatever else goes at the end. One less include means one less OS file request – always a good thing.

Looking at the code you presented, I think the extra div for nothing is a hefty part of your issues, since you’re sending list-style to it when a DIV doesn’t take list-style…

Personally I hate the id on body trick because it results in massive CSS (declaring each and every single one) and bloated markup (classes on each and every single one regardless of it’s state)… a little simple PHP fixes it right up making things clearer and using just a wee bit less bandwidth.

The site is running locally at the moment. I know for sure that the problem lies with the CSS styling. I’ve always known to put a Div around the Ul and I’ve seen it done many times so never thought anything of it. Thus, I’m a little confused with the CSS layout, by putting the class in the UL, do you keep both .menu and .menu ul in the CSS or do you just use either .menu or .menu ul ? The CSS code is in above post.

Also, in relation to my original post / question, I have some good news, more so for those looking to do the same. I have done what I was looking to do by using PHP to detect the current page that is open in the browser and then conditionally class the menu styling.

Firstly, put the following php syntax at the top of each page.

<?php $page = 'PAGE NAME'; ?>

Secondly, edit the anchor links in the menu includes file to include an if / else command to conditionally class=“active” the menu.


<ul>
<?php if ($page == 'home') { ?><li><a href="index.php" class="active">Home</a></li>
<?php } else { ?><li><a href="index.php">Home</a><?php } ?>

<?php if ($page == 'blog') { ?><li><a href="blog.php" class="active">Blog</a></li>
<?php } else { ?><li><a href="blog.php">Blog</a><?php } ?>

<?php if ($page == 'about') { ?><li><a href="about.php" class="active">About</a></li>
<?php } else { ?><li><a href="about.php">About</a><?php } ?>

<?php if ($page == 'contact') { ?><li><a href="contact.php" class="active">Contact</a></li>
<?php } else { ?><li><a href="contact.php">Contact</a><?php } ?>
</ul>

There is simply no need for that div, because a div is a block level element just like the UL, so the UL doesn’t need and help, as it were. If you remove the div and shift the menu class to the UL, you do need to change the CSS a bit, though. For example, the .menu ul would need to change to ul.manu or just .menu.

Regarding the PHP you posted, this isn’t my area, but I’d say it could be a lot simpler. For example, the first LI code could be reduced from


<?php if ($page == 'home') { ?><li><a href="index.php" class="active">Home</a></li>
<?php } else { ?><li><a href="index.php">Home</a><?php } ?>

to


<li><a href="index.php" <?php if ($page == 'home') {class="active"} ?>>Home</a></li>

And I’m not even sure you need to open and close PHP more than once for all those LIs.

Deathshadow’s past show a completely different way to go about all this, and much more efficient … but maybe consider that for next time. :slight_smile:

Opening and closing php like that is grossly inefficient, and it’s why my code doesn’t do that and uses just ONE echo statement to handle all of it…

Where you’re thinking this: (which I’ve always considered bad – part of why I think <?php ?> should be REMOVED from PHP altogether…)


<?php if ($page == 'home') { ?><li><a href="index.php" class="active">Home</a></li>
<?php } else { ?><li><a href="index.php">Home</a><?php } ?>

I can do that in a fraction the code with just one echo.


echo '
		<li>
			<a',(
				$page=='home' ? ' class="current"' : ''
			),' href="index.php">Home</a>
		</li><li>


it just uses an inline evaluation

(condition ? ’ result if true’ : ’ result if false’)

Examples:


echo '<h1>Some simple tests</h1>
  1 = 1 ',(1==1) ? 'true' : 'false','<br />
  1 = 2 ',(1==2) ? 'true' : 'false','<br />';

So you aren’t wasting large amounts of code on opening/closing php, you can set the results as a comma delimited list to echo, and you don’t need all that extra stuff around the if statement.

I’d really like to know where/why people keep doing that – as literally there is NO reason for it… I’ve seen even alleged “experts” doing it in articles on line and can’t help but end up screaming “WHY” at the display… along with nonsense like declaring border:none and border:0 at the same time on a UL, an element that has no default border in anything… Articles that suck in the nubes and does nothing but make them dumber for having read them – and yet SOMEHOW get featured on [url=http://www.sitepoint.com/css-menu-design-multiple-backgrounds-and-more/]sites like… well…

Your example CSS doesn’t HAVE a “.menu ul” in it either… at least not that I’m seeing. Hard to tell with everything crammed onto single lines like that… In the majority of cases though ANYTHING you could apply to a div you could apply to the UL… so you don’t need “.menu ul” since that wouldn’t target anything…

Well, unless you put a UL inside UL.menu, like when making a drop-down menu.

It’s in the second line of the CSS block in post #3.

Must have looked at it like four times, STILL didn’t see it until you said where it was – but I do that whenever things are stuffed onto single lines like that – can’t tell where one property begins and another one ends.

Just reformatted that CSS into something legible – and REALLY so many things re-declared over and over for no good reason – like font-size… I can see now that there could be a reason for the DIV… you’ve got the menu to the right and wanted to keep them in order. If you were putting a full width background on that div, THEN it might make sense… even so I doubt it. For the HTML+CSS we were shown, not so much.

looking closer at it now, declaring such an absurdly narrow fixed width leaves me wondering just what the devil is going on in the rest of the layout. I think you may be over-thinking the solution to your problem here… and really… 12px in a serif font? Illegible.

Also seems to be declaring DIV inside Anchors, which is invalid unless jumping on the idiotic HTML 5 bandwagon, and on the whole serves no real purpose.

… and what on earth is a “rigth”? … also why all the hover states that DON’T declare any values?!?

I think I’d really have to see it running live with what it’s supposed to look like – or at the very least the images being used as this is… pointlessly redundant. So far I can condense the CSS down to:


.menu {
	float:right;
	width:500px;
	margin:109px 0 0 0;
}

.menu li {
	display:inline; /* make IE7 behave by just not bothering to use LI for anything */
}

.menu a {
	float:left;
	display:inline; /* prevent legacy IE margin doubling on floats */
	padding:10px;
	margin:0 1px;
	text-decoration:none;
	font:normal 14px/16px arial,helvetica,sans-serif;
	color:#fff;
}

The hover states have me scratching my head, though I’m pretty sure that’s supposed to be spans, not DIV, right? I suspect whatever it is you are trying to do there I’d probably be handling with just a single image file. That’s the problem with snippets – is it’s like doing brain surgery over a time-phone to 1889.

In any case, remember the biggest rule of CSS – it’s called “cascading” for a reason… which means if you declare certain values on a wrapper, like FONT or COLOR on the A, it inherits to all psuedo-states so you don’t need to say them again. That CSS keeps redeclaring values that are already set – which is pretty much pointless.

Whooaw… Thanks!!!

I can certainly say, in such cases it’s just a matter of bad preaching by some and bad practice by most. Like I say, I have always done the UL inside the DIV. Just by considering the UL as an unordered list and never a block element, and by seeing it done elsewhere, I’ve never thought about it twice as bad practice.

Making no excuses. I fully understand the change now, and I appreciate your guidance in the matter. As of now, the class remains in UL, defined as .menu with the exception of ul.menu for a drop down. Thanks to you.

Moreover, key noted and appreciated again. I make no excuses for the poor CSS line format and I will carry out this cleaner more legible formation from here onwards.

Yes I gotta agree that Deathshadow code and method posted, is a lot more cleaner and far far more efficient. However, I feel it’s a rather daunting step upwards to what I’m used to, that’s using includes for header / footer etc on each page.

As much as I’d love to have this site using that more efficient method, I think I’d be jumping ship in open waters. Best to perhaps finish what I’ve started and venture into that method for next time or convert it when or if possible. For reason being to be perfectly honest with you I don’t fully understand the layout / format of it, what’s going where etc. Again perhaps if I had the files to view and a preview, instead of just code tags, then it’d make thins more clear for me too.

I do though, appropriate your help and guidance and thank you for that.

True enough. Between web rot and people writing books/tutorials who never took the time to understand the POINT of HTML, there’s SO MUCH bad advice out there… and things people consider ‘normal’ without taking the time to rub a few brain cells together over. Complacency being the enemy of progress and so forth.

There’s a lot of ‘standard practice’ out there right now that’s actually bad practice – and it seems to be getting worse and worse year by year and now month by month. I’m seeing code so bad right now coming from alleged “experts” they’d have been laughed off the Internet a decade ago. Just take a look at the average wordpress skin for proof enough of that… or many of the ‘tutorials’ cropping up on doing the simplest of things.

A lot of what I presented can be thought of as hurdles – and there’s no sense jumping a hurdle until you are ready… many developers I think never quite jump the hurdles, but each time you get over one it’s like the fog is lifted and things become clearer and clearer. When you’re ready it’s there – and most of us will be here to guide you along.

Trust me, after some three and a half decades of writing software in one form or another, there’s ALWAYS something new to learn… be a really boring world if there wasn’t.

Indeed, and thanks for posting it, as I’ve been wondering about that method of templating myself, so it’s interesting to study it in detail. :slight_smile: