Jump to content

Simple menu using text links - style question


Bert Coules

Recommended Posts

I've been arranging my menu as a list, so I could try Jonathanks suggestion. Here is the stylesheet entry:

ul#menu li {    display: inline;        font-size: 0.8em;    color: #CCCCCC; /* very light grey */    word-spacing: 2em;}

And this is the HTML:

<ul id="menu">                                    <li> <a href="index.php" title="Bert Coules">home</a> </li>                            <li> <a href="biog.php" title="Bert Coules"><span class="normal_spacing">about me</span></a> </li>                            <li> <a href="appearances.php" title="Appearances">appearances</a> </li>                            <li> <a href="credits.php" title="Credits">credits</a> </li>                            <li> <a href="holmes.php" title="BBC audio complete Sherlock Holmes">            <span class="normal_spacing">Sherlock Holmes</span></a> </li>                            <li> <a href="publications.php" title="Publications">publications</a> </li>                            <li> <a href="contact.php" title="Contact me">contact</a> </li>                            </ul>

This gives me a horizontal list, spaced as I want, (though my efforts to centre it haven't so far been successful). But when I add Jonathanks' code as a separate stylesheet item:

ul.menu a:active {    color:white;}

it doesn't have the desired effect: the selected menu item does not become white. Dsonesuk, I saw your amendment, place active class on list item, not anchor, but I'm not clear on precisely how to do what you suggest. I tried changing the above to

ul.menu li:active {    color:white;}

but that also has no effect and neither does using ul#menu . I must be missing something fundamental.

Edited by Bert Coules
Link to comment
Share on other sites

The :active pseudo class only works as you press down the mouse button on the link, its not reliable to use to highlight current page link, that is why you should use a class instead.

 

if the current page link is to blog page add class 'active'.

<ul id="menu">                                    <li> <a href="index.php" title="Bert Coules">home</a> </li>                            <li class="active"> <a href="biog.php" title="Bert Coules"><span class="normal_spacing">about me</span></a> </li>                            <li> <a href="appearances.php" title="Appearances">appearances</a> </li>                            <li> <a href="credits.php" title="Credits">credits</a> </li>                            <li> <a href="holmes.php" title="BBC audio complete Sherlock Holmes">            <span class="normal_spacing">Sherlock Holmes</span></a> </li>                            <li> <a href="publications.php" title="Publications">publications</a> </li>                            <li> <a href="contact.php" title="Contact me">contact</a> </li>                            </ul>
#menu li a { /*set default styling for menu link*/color: black;background-color: yellow;padding:10px;}#menu li.active a, #menu li a:hover { /*only add the styling that changes, nothing else*/color:white;background-color: red;}
Link to comment
Share on other sites

Dsonesuk,

 

Thanks. I can see how that would work for the one item which had the class="active" tag, but wouldn't I still need individual menu files, each with its own particular highlighted entry? And if that is the case, then wouldn't my original solution, which also uses multiple menus, be just as good?

Link to comment
Share on other sites

I honestly don't which version you are using, the example i produced is the end result you should have when reading link from database table or array, where the class="active" will be added dynamically when the link and current page match, if you are adding manually then yes you would set the active class manually also for each page, unless you alternatively use javascript/jquery to do this instead.

 

Its just an example how the active class is used with css to apply specific styling.

Edited by dsonesuk
Link to comment
Share on other sites

First off the pusedo class element a:active is not designed to show the current page because it is only active on click, and returns to the normal state (a:link or a:visited) when you release the mouse button. Second thing is that a:hover has to come after a:link and a:visited, and a:active has to come after a:hover for it all to work. I did a lot of research on this last night, and it is a very popular question with all kinds of complex and crazy solutions. I did find an elegant jave script solution, but it is not as clean as my suggested solutions above using php. I don't know if I'll have time today, but as soon as I can I will set it up and get it working on one of my working dev sites then post it back here.

Link to comment
Share on other sites

you just need to use a version of count_zero code but amended for ul li menu

 <?php            include("connect.php");            $result = mysql_query("SELECT * FROM link_table");            echo '<ul>';            while ($row = mysql_fetch_array($result)) {                $class = '';                $link = $row['link'];                $title = $row['title'];                $name = $row['name'];                if ($link === $_SERVER['PHP_SELF']) {                    $class = 'class="active"';                }                echo '<li class="' . $class . '"><a  href="' . $link . '" title="' . $title . '">' . $name . '</a></li>';                ///$row++; what is this?            }            echo '</ul>';            mysql_close($con);            ?>
Edited by dsonesuk
Link to comment
Share on other sites

I just found out that using CSS alone would cause some pain with cross-browser compatibility which can be avoided using JS or PHP which is your chosen server-side language. I suggest you use PHP since JavaScript may be disabled on the client side. I'm glad we found the weakness in other methods like mine. Try out those suggestions there. I may find time to come back.@Count_Zero, Bert Coules and all that find time to season this forum, making it a place to be:It's a good thing to be with you. I love forums like this.

Link to comment
Share on other sites

///$row++; what is this?

 

 

Oops that got copy - pasted in there by because I was quickly assembling the demo form other bits and pieces of code without having to type it all out, I tend to be lazy in my old age. Of course you don't need that in a while statement. My bad. :crazy:

 

Anyhow yea that looks clean, and I just got an email from a bud over at stackoverflow who tried my method and say it works like a charm.

 

There is a CSS solution that does work pretty well, and that is to give each page, a unique to that page, ID in the body tag, and the css for that tag has the current page style. You then add an ID to each a tag in the list corresponding to that page's body ID. That way that ID does not become active until you’re on that page, and the ID in the a tag in the menu will use this style. Give me a moment and I will do a demo.

 

One interesting style idea I found used css to style the menu bar to look like JQuery tabs. The menu bar and main content box touched each other (no margin or padding), and the top border for the content box was the same as the box background, with a black border around each menu link. When on the active page it restyled that menu link to have the same background color as the content box and removed the bottom border therefore giving it a tabs appearance.

Link to comment
Share on other sites

This discussion is definitely getting out of my depth now. I'm doing my best to keep up and I think I'm taking most of it in, but my head's reeling a bit. I'm going to take some time to work through the posts slowly, try a few alternatives and make sure I know what's going on - what I definitely do not want to do is put in some coding which works but which I don't completely understand.

 

In the meantime, I do at least have my (to me) ultra-simple solution, with seven separate menu files each of which differs in a slightly different way. It not only works, I know how and why it works! And - as far as I can see - it's not doing any harm or causing any ill-effects.

 

Many, many thanks to everyone for the replies, the patience and the work you've done.

Edited by Bert Coules
Link to comment
Share on other sites

@Bert

 

This discussion is definitely getting out of my depth now. I'm doing my best to keep up and I think I'm taking most of it in, but my head's reeling a bit.

 

 

It means your learning new things, and we all are learning at the same time as you because forums are the greatest tool for learning by colabritively sharing knowledge with other like minded people while working together to solve problems. I learned a lot by trying to help you as did others because I (we) had to do a lot of research, and poring over my own code to produce a demo so you might better understand. I didn't even know this forum existed, but have been using w3schools as a reference for years, and in my opinion it's the best out there. I am no stranger to forums, and run battlefieldsingleplayer.com where our forum has been up and running since 2003, and now has just south of 9000 members globally. Every game AI coder worth his salt cut their teeth on our forums, and still do today.

 

That being said, please keep asking questions, and the only dumb thing about any question is why you didn't ask it in the first place. This is a problem that I want to solve myself for my own menu systems, and I bet there are many others with the same interest. I plan to set it up and make it work on my tutorial development site since I already have everything in place. and run the menus via links srored in a db table. Once I have it working how I like, I will post the results here.

 

In the meantime, I do at least have my (to me) ultra-simple solution, with seven separate menu files each of which differs in a slightly different way.

 

 

LoL, I'm funning with you here so don't get your feathers up, but I have to chuckle at the "ultra-simple solution" with the "seven separate menu files each of which differs in a slightly different way" part of that statement. :rolleyes:

 

Me thinks we need to help you with a little basic php and sql, and then I think you will get your head around the concept.

Link to comment
Share on other sites

Count_Zero, I don't know, it seems to me that is a simple solution. I grant you, it takes up a little more space, but in terms of coding it's about as simple as you can get.

 

The main drawback to it as far as I can see is that if I ever need to change the menu I'll have to do it seven times. But even that's not too bad, is it? I change it once, copy-and-paste the new version into the other files and then make any minor changes necessary to make each one individual again.

 

I think another relevant point is this: I designed the original version of this site almost three years ago, and apart from some very minor revisions to the textual content, I hadn't done anything to it since, or - crucially - done any other HTML coding elsewhere. When I decided to redo the whole thing and looked in detail at the files, I discovered that I'd forgotten almost everything I'd taught myself first time round: I had to relearn it all, basic as it was.

 

Once I get things to my satisfaction this time, there's a good chance that it will once again be years before I have to think about changing stuff. So doesn't it make sense for me not to learn things that are totally new but rather to rely on what I've already managed to get my head around?

 

Great to hear that you're learning by helping me.

Edited by Bert Coules
Link to comment
Share on other sites

This is another simple solution that just uses your html code as it is, no database tables, no array you just add your menu code as a text string, search for opening li tag anchor link and address

<li> <a href="biog.php" where biog.php is current page and replace with <li class="active"> <a href="biog.php", As long as spacing match, and you avoid apostrophes within your html menu code, it should work for your basic menu.

 

menuInclude.php

<?php// assign plain html menu code to variable $menu as text string$menu = '<ul id="menu">            <li> <a href="index.php" title="Bert Coules">home</a> </li>            <li> <a href="biog.php" title="Bert Coules"><span class="normal_spacing">about me</span></a> </li>            <li> <a href="appearances.php" title="Appearances">appearances</a> </li>            <li> <a href="credits.php" title="Credits">credits</a> </li>            <li> <a href="holmes.php" title="BBC audio complete Sherlock Holmes">            <span class="normal_spacing">Sherlock Holmes</span></a> </li>            <li> <a href="publications.php" title="Publications">publications</a> </li>            <li> <a href="contact.php" title="Contact me">contact</a> </li>            </ul>';//search   for <li> <a href="withcurrentpage.php" in text and replace with <li class="active"> <a href="withcurrentpage.php"$menu = str_ireplace('<li> <a href="' . basename($_SERVER['SCRIPT_NAME']) . '"', '<li class="active"> <a href="' . basename($_SERVER['SCRIPT_NAME']) . '"', trim($menu));echo $menu;

biog.php (note i originally named this blog.php and wondered why it was not working, until i noticed it was biog.php with a 'i')

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css">            nav.top-menu {text-align: center; font-size: 0;}            #menu, #menu ul, #menu li {list-style-type: none; text-indent: 0; padding: 0; margin: 0;}            #menu li, #menu li a {display: inline-block;}            #menu li a { /*set default styling for menu link*/                font-size: 14px;                color: black;                background-color: yellow;                padding:10px;            }            #menu li.active a, #menu li a:hover { /*only add the styling that changes, nothing else*/                color:white;                background-color: red;}            </style>        </head>        <body>            <nav class="top-menu">                <?php                include 'menuInclude.php';                ?>            </nav>        </body>    </html>
Edited by dsonesuk
Link to comment
Share on other sites

@dsonesuk

 

LMAO! Now that is clever! Store the menu as a text string in one $var, and use a simple str_ireplace conditional. Eligant, simple, and in a word, brilliant. My hat's off to you. :good:

 

The power of the forum! From one question many have learned, and might be inspired to try something new, therefore increasing their overall knowledge.

 

 

To be honest, and I'm going to go out on a limb here in assuming dsonsuk might have come to the same conclusion, I learn more from helping others solve issues such as this on forums than by any other means. I am by no means a professional programmer, I am totally self-taught as probably most of you are, and because of the way I am, teaching myself while asking questions is just how I learn things. That being said, there is no way you will encounter all the scenarios, or problems you can encounter as a programmer-web developer by yourself in a life time, and that is where helping solve interesting problems posted in forums comes in. It’s a perfect place-medium to gain not only knowledge, but the experience of having applied that knowledge to solve a problem, and that’s knowledge that sticks with you.

 

@Bert

 

The main drawback to it as far as I can see is that if I ever need to change the menu I'll have to do it seven times.

 

 

That and adding an additional page, and it is the reason for the include file. Make a change in one file and every page is updated. I include the header, menu, footer, and even create a new page with a template.php include file.

 

I see your point, that being it's a static site rarely changed, but in your reasoning, you almost contradict yourself (well you are actually). By this I mean you mention that you started redoing your site, you discovered you had to relearn all the basics again, and now you have a fresh, new, and better site, so why stop at the menu. Don't get me wrong, I'm not riding you about it, rather I'm trying to push-inspire you into learning something new, that when you next update, it will be much easier to do, as well as maintain until then. Of course your tried and true method will work, and if you’re comfortable with that, by all means use it. I guess my point would be, if Edison was satisfied with the coal oil lamp, would we have the light bulb?

 

Link to comment
Share on other sites

First a correction for my solution, dsonesuk, and Bert's, and that being we are changing the class on the a:active selector, and it has nothing to do with wither you're on the current page or not. All a:active does is act as a style attribute for onclick, and what needs to be changed for the current page are the a:link, and a:visited selectors because they show the default static condition of the element. Another thing to remember is that a:hover has to come AFTER a:link and a:visited to work, and a:active has to come AFTER a:hover to work.

 

There is a simple all css solution I just tried (and modified) that is not only simple, and easy to setup, but also allows for a menu include file. I will create a demo that matches Bert's situation when I get the chance.

Link to comment
Share on other sites

OK Bert, this will work perfect for you, and it's simple css. All your styles for the menu work as normal and this only becomes active to the menu item for the current page, when on that page.

 

Add a ID to the body tag of each of the pages which will be linked to from the menu bar like so.

<body id="home"><body id="about"><body id="appear"><body id="credits"><body id="holmes"><body id="pub"><body id="contact">

Now in your menu.php include file add a unique ID to each anchor tag (<a>) linke so.

<ul id="menu">                            <li> <a id="m_home" href="index.php" title="Bert Coules">home</a> </li>            <li> <a id="m_about" href="biog.php" title="Bert Coules"><span class="normal_spacing">about me</span></a> </li>    <!-- What is this span-class thing for? -->        <li> <a id="m_appear" href="appearances.php" title="Appearances">appearances</a> </li>            <li> <a id="m_cerdits" href="credits.php" title="Credits">credits</a> </li>            <li> <a id="m_holmes" href="holmes.php" title="BBC audio complete Sherlock Holmes">    <span class="normal_spacing">Sherlock Holmes</span></a> </li>  <!-- What is this span-class thing for? -->            <li> <a id="m_pub" href="publications.php" title="Publications">publications</a> </li>        <li> <a id="m_contact" href="contact.php" title="Contact me">contact</a> </li>                </ul>

Now either in the head, or your external style sheet (preferred) add your selector styles like so.

body#home a#m_home,body#about a#m_about,body#appear a#m_appear,body#credits a#m_credits,body#holmes a#m_holmes,body#pub a#m_pub,body#contact a#m_contact    {    color:rgb(204,204,204);    /* This is the RGB value for #cccccc*/    background-color: rgb(0,0,0);   /* This is the RGB value for black, set it for what you want the bg to be.*/    }

Now I tested this on my dev site, and it works like a charm. If you add the css selectors to an external style sheet along with a menu include file you can manage the menu for all pages from those two files. You could probably copy-paste this just like I have it and it will work.

Edited by Count_Zero
Link to comment
Share on other sites

OR automate it just to head styling and body tag.

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css"><?phpinclude "active-menucss.php";?>            nav.top-menu {text-align: center; font-size: 0;}            #menu, #menu ul, #menu li {list-style-type: none; text-indent: 0; padding: 0; margin: 0;}            #menu li, #menu li a {display: inline-block;}            #menu li a { /*set default styling for menu link*/                font-size: 14px;                color: black;                background-color: yellow;                padding:10px;                text-transform: uppercase;                text-decoration: none;                border-left: 1px #333 solid;                border-top: 1px #333 solid;                border-bottom: 1px #333 solid;            }            #menu li:first-child a {border-radius: 10px 0 0 10px;}            #menu li:last-child a {border-right: 1px #333 solid; border-radius: 0 10px 10px 0}            #menu li a:hover { /*only add the styling that changes, nothing else*/                text-decoration: underline;                color:white;                background-color: red;            }                    </style>    </head>    <body <?php echo 'id="' . $identifier . '"'; ?>>        <nav class="top-menu">            <ul id="menu">                <li> <a href="index.php" title="Bert Coules">home</a> </li>                <li> <a href="biog.php" title="Bert Coules"><span class="normal_spacing">about me</span></a> </li>                <li> <a href="appearances.php" title="Appearances">appearances</a> </li>                <li> <a href="credits.php" title="Credits">credits</a> </li>                <li> <a href="holmes.php" title="BBC audio complete Sherlock Holmes">                        <span class="normal_spacing">Sherlock Holmes</span></a> </li>                <li> <a href="publications.php" title="Publications">publications</a> </li>                <li> <a href="contact.php" title="Contact me">contact</a> </li>            </ul>        </nav>    </body></html>

active-menucss.php

<?php$link = basename($_SERVER['SCRIPT_NAME']);$identifier = basename($_SERVER['SCRIPT_NAME']);$identifier = 'active-' . substr($identifier, 0, strlen($identifier) - 4);echo '#' . $identifier . ' #menu a[href="' . $link . '"]            {            text-decoration: underline;                color:white;                background-color: red;            }' . "n";
Edited by dsonesuk
Link to comment
Share on other sites

Count_Zero, your simple CSS version works perfectly: I had to make a couple of tiny changes, mostly to do with names, but that made no difference. I now have one menu file instead of seven and a better understanding of the coding involved. Thank you so much.

 

Dsonesuk, when Count_Zero's solution not only worked but worked in a way I could follow, I decided to leave well alone. But thanks again for your thoughts and efforts.

 

Incidentally, you mentioned the biog / blog mixup: the menu item was originally "biog" too, but several people pointed out the potential for confusion. I'm not too fond of "about me" but I've yet to come up with anything better.

 

I want to turn my attention next to building a separate mobile-friendly version of the site. There will probably be more questions, I'm afraid.

Edited by Bert Coules
Link to comment
Share on other sites

Well that's great Bert, glad you have something your happy with up and running, and it has made for a very productive thread. After all we now have what 3, or 4 very interesting solutions to this common problem, and anyone who comes across this tread while searching this issue certanly has a choice of solutions to meet their skill level, what ever that may be. I know I learned seome new things whilist looking up information, and at the same time found not only some flaws in some of my own code, but learned some new ways to do things.

 

@dsonesuk

 

I like that last solution, though still getting my head around it all, but it was the string replace idea you posited as a solution in a previous post that has given me some ideas on some interesting (well maybe kind of wild) menu - link solutions. That’s a can I want to keep kicking down the road when I get the chance. It just might be part of a solution to some things I am trying to do on a large project I have been working on for awhile now. I also need to improve my knowledge of string functions, and it would be like killng two birds with one stone.

Edited by Count_Zero
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...