Style the last link in an autonav?
Permalink 1 user found helpful
Hi all
It's easy enough to style the first link in an autonav by defining the 'first' CSS class, but what about the last link?
I've got some borders between my horizontal menu items, but I don't want them on the left of the first item or the right of the last item. I managed it fine with the first item but I can't see a way in the header_menu autonav template to apply a class to the last menu item.
Any help would be much appreciated! :)
It's easy enough to style the first link in an autonav by defining the 'first' CSS class, but what about the last link?
I've got some borders between my horizontal menu items, but I don't want them on the left of the first item or the right of the last item. I managed it fine with the first item but I can't see a way in the header_menu autonav template to apply a class to the last menu item.
Any help would be much appreciated! :)
Thanks for your suggestion.
It didn't quite work for me, but I tweaked the code to get this, which does work:
:)
It didn't quite work for me, but I tweaked the code to get this, which does work:
<?php defined('C5_EXECUTE') or die(_("Access Denied.")); $aBlocks = $controller->generateNav(); $c = Page::getCurrentPage(); echo("<ul class=\"nav-header\">"); $nh = Loader::helper('navigation'); $isFirst = true; $count = count($aBlocks); $i = 1; foreach($aBlocks as $ni) { $_c = $ni->getCollectionObject(); if (!$_c->getCollectionAttributeValue('exclude_nav')) { if ($ni->isActive($c) || strpos($c->getCollectionPath(), $_c->getCollectionPath()) === 0) { $navSelected='nav-selected'; } else {
Viewing 15 lines of 43 lines. View entire code block.
:)
Thought I would post for reference and people who come across this via search.
The above solution doesn't quite work.
$count = count($aBlocks);
Counts all pages, including those that are excluded from the navigation. So if you have 4 pages and 3 excluded pages the count will be 7. This means the last page will not be detected correctly and the class won't be applied as desired.
To get around this you need to subtract the exlcuded pages from your count as follows:
The above solution doesn't quite work.
$count = count($aBlocks);
Counts all pages, including those that are excluded from the navigation. So if you have 4 pages and 3 excluded pages the count will be 7. This means the last page will not be detected correctly and the class won't be applied as desired.
To get around this you need to subtract the exlcuded pages from your count as follows:
foreach($aBlocks as $ni) { $_c = $ni->getCollectionObject(); if ($_c->getCollectionAttributeValue('exclude_nav')) { $count--; } }
Hello,
This is exactly what I am looking for but it would seem that there is still a slight bug.
The script is placing the "last" class on the last but one.
I think this may have something to do with my "Home" link being in the autonav.
Is there a way to take this into consideration?
Thanks so much in advance :)
D!!
p.s I have zero PHP knowledge
This is exactly what I am looking for but it would seem that there is still a slight bug.
The script is placing the "last" class on the last but one.
I think this may have something to do with my "Home" link being in the autonav.
Is there a way to take this into consideration?
Thanks so much in advance :)
D!!
p.s I have zero PHP knowledge
<?php defined('C5_EXECUTE') or die(_("Access Denied.")); $aBlocks = $controller->generateNav(); $c = Page::getCurrentPage(); echo("<ul class=\"nav-header\">"); $nh = Loader::helper('navigation'); $isFirst = true; $count = count($aBlocks); $i = 1; foreach($aBlocks as $ni) { $_c = $ni->getCollectionObject(); if ($_c->getCollectionAttributeValue('exclude_nav')) { $count--;
Viewing 15 lines of 51 lines. View entire code block.
Try this (as requested by Biscutty on the forums):
Basically, you filter out any excluded pages first, then you'll have an array with no fear of skipping elements thus you can use the current iteration's key to check against the last key of the array.
<?php defined('C5_EXECUTE') or die("Access Denied."); $aBlocks = $controller->generateNav(); $c = Page::getCurrentPage(); echo("<ul class=\"nav-header\">"); $nh = Loader::helper('navigation'); // Filter out any excluded pages $aBlocks = array_filter($aBlocks, create_function('$v', ' $c = $v->getCollectionObject(); return !$c->getAttribute("exclude_nav") ? TRUE : FALSE; ') ); // Determine last element key end($aBlocks);
Viewing 15 lines of 54 lines. View entire code block.
Basically, you filter out any excluded pages first, then you'll have an array with no fear of skipping elements thus you can use the current iteration's key to check against the last key of the array.
Silly PHP devs, this can be done with CSS 2.1:
Just put :last-child on whatever you want to style and you'll be good. ;-)
#myelement a:last-child { your stuff goes here }
Just put :last-child on whatever you want to style and you'll be good. ;-)
True, but while :first-child has wide support among legacy browsers, :last-child does not thus the need to programatically tag the last child element.
Very true. Sometimes you gotta' accommodate for IE. I usually use :last-child in combination with IE9.js in a conditional comment to get everything tip top:
http://code.google.com/p/ie7-js/...
http://code.google.com/p/ie7-js/...
Wow, I never saw that script before -- looks really handy. How does it compare to other similar things (in your experience)? I've used CSSPIE before to limited effect, but I think that's more for getting things like rounded corners and drop-shadows to work in IE, whereas this seems to be more for smoothing out differences in CSS?
Yeah, IE9.js does different things in comparison to CSS3Pie. The demo page has a full list of what it adds support for:
http://ie7-js.googlecode.com/svn/test/index.html...
The IE9 flavor includes support for HTML5 elements. I'm making almost exclusively HTML5 sites these days; therefor, I figure it's better to include IE9.js as one file versus an HTML5 shim and whatever else (Selectivizr, CSS3Pie, [your IE shim here]). Overall, I've been very pleased with it and have found it to be a good solution in solving CSS differences.
http://ie7-js.googlecode.com/svn/test/index.html...
The IE9 flavor includes support for HTML5 elements. I'm making almost exclusively HTML5 sites these days; therefor, I figure it's better to include IE9.js as one file versus an HTML5 shim and whatever else (Selectivizr, CSS3Pie, [your IE shim here]). Overall, I've been very pleased with it and have found it to be a good solution in solving CSS differences.
A JS shimmy can help fix it, but it can be turned off. While the earth probably won't implode if a :last-child element isn't parsed properly, using JS to accommodate IE7 bugs that can easily be addressed in server-side languages can a be a bit overkill.
(Or, try to make the first child the exception and treat the rest with the general styling)
(Or, try to make the first child the exception and treat the rest with the general styling)
Silly non-real-world designers, using CSS that doesn't work for FORTY PERCENT of people's browsers!
(last-child selector is not supported by IE6-8)
All in good fun, btw -- much respect to Adam (riotaj), he does really great things for the community here!
(last-child selector is not supported by IE6-8)
All in good fun, btw -- much respect to Adam (riotaj), he does really great things for the community here!
Haha! So good.
You can do this with just css. All you need to do is add a border-left to the list items and then use the first-child selector to not show it on the first item in nav like this:
ul li { border-left:1px solid #000; } ul li:first-child { border-left:none; }
I like this solution - pure CSS, fast with no overrides to the core. Thanks c5mix!
Hi,
I know it's a bit of an old thread by now but in autonav, the first li has a class of first by default as appears in the code quoted here.
so probably this would work:
which is exactly the same as c5mix solution above but using the class name instead of the first-child selector.
I know, I know, stating the obvious :)
I know it's a bit of an old thread by now but in autonav, the first li has a class of first by default as appears in the code quoted here.
so probably this would work:
ul li { border-left:1px solid #000; } ul li.first { border-left:none; }
which is exactly the same as c5mix solution above but using the class name instead of the first-child selector.
I know, I know, stating the obvious :)
Copy the "header_menu.php" file from this directory:
YOURSITE/concrete/blocks/autonav/templates/
to a new directory that you create here:
YOURSITE/blocks/autonav/templates/
Then edit that file. Find this line:
$isFirst = true;
and add these new lines below that one (but above the "foreach" line):
$count = count($aBlocks);
$i = 1;
Then, find this line:
echo '<li class="'.$navSelected.' '.$isFirstClass.'">';
and directly ABOVE it (but under the "else $isFirstClass..." line), add this:
$isFirstClass .= ($i++ == $count) ? ' last' : '';
Now when you place the autonav block on a page, click it and choose "Custom Template", and then choose the "Header Menu" from the list. In your stylesheet, you can identify this last item like so:
ul.nav-header li.last { ... }
-Jordan