I've been delivered some navigation code to implement in Matrix, and I've come up against an issue. The code requires link tags for menu items which have children to have a particular class. I can't figure out how to implement this in Matrix. Alternatively, I can't figure out how to amend the CSS by selecting such elements with CSS selectors other than an explicit class. Can anyone help?
Menu_normal
Can you post the HTML that you are trying to create? Not sure I am following what you are needing.
It's a whopper:
<ul> <li class="mobile-only"> <a href="/" class="clearfix active"> Home </a> </li> <li> <a href="/Visiting/" class="clearfix has-children"> Visiting <span class="arrow-green-right"></span> </a> <div class="children mobile-only"> <a href="#" class="back-to-main"> <span class="icon-back">Back</span> </a> <ul> <li><a href="/Visiting/Attractions/">Attractions</a></li> <li> <a href="#" class="has-children">See and do <span class="arrow-grey-right"></span></a> <div class="children mobile-only"> <a href="#" class="back-to-main"> <span class="icon-back">Back</span> </a> <ul> <li><a href="#">Towns & Villages</a></li> <li><a href="#">Landmarks</a></li> <li><a href="#">Amazing Views</a></li> <li><a href="#">Forest & Woodland</a></li> <li><a href="#">Coast</a></li> <li><a href="#">Trails</a></li> <li><a href="#">Museums</a></li> <li><a href="#">Farm Attractions</a></li> <li><a href="#">Galleries</a></li> <li> <a href="#" class="has-children">NP Centres<span class="arrow-grey-right"></span></a> <div class="children mobile-only"> <a href="#" class="back-to-main"> <span class="icon-back">Back</span> </a> <ul> <li><a href="#">Sutton bank</a></li> <li><a href="#">The Moorrs Centre</a></li> </ul> </div> </li> <li><a href="#">Events</a></li> <li><a href="#">Film</a></li> </ul></div>
</li>
<li>
<a href="/Visiting/Enjoy-outdoors/" class=“has-children”>Enjoy outdoors<span class=“arrow-grey-right”></span></a>
<div class=“children mobile-only”>
<a href="#" class=“back-to-main”>
<span class=“icon-back”>Back</span>
</a>
<ul>
<li>
<a class=“has-children” href="/Visiting/Enjoy-outdoors/Walking/">Walking <span class=“arrow-grey-right”></span></a>
<div class=“children mobile-only”>
<a href="#" class=“back-to-main”>
<span class=“icon-back”>Back</span>
</a>
<ul>
<li><a href="/Visiting/Enjoy-outdoors/Walking/Walking-routes/">Walking routes</a></li>
<li><a href="/Visiting/Enjoy-outdoors/Walking/Walking-essentials/">Walking essentials</a></li>
<li><a href="#">Long-distance walks</a></li>
<li><a href="#">Classic walks</a></li>
<li><a href="#">Guided walks</a></li>
<li><a href="#">Walking with dogs</a></li>
<li><a href="#">Staying safe</a></li>
<li><a href="#">The Moors message</a></li>
<li><a href="#">Rights of way and open acccess</a></li>
<li><a href="#">Recent changes to rights of way</a></li>
</ul>
</div>
</li>
<li><a href="#">Horse riding</a></li>
<li><a href="#">Activity Centres</a></li>
<li><a href="#">Sports Centres</a></li>
<li><a href="#">Air Sports</a></li>
<li><a href="#">Birdwatching</a></li>
<li><a href="#">Fishing</a></li>
<li><a href="#">Flat green bowling</a></li>
<li><a href="#">Geo-caching</a></li>
<li><a href="#">Go Ape</a></li>
<li><a href="#">Golf</a></li>
<li><a href="#">Motor Sports</a></li>
<li><a href="#">Off-road driving</a></li>
<li><a href="#">Rock Climbing</a></li>
<li><a href="#">Running</a></li>
<li><a href="#">Shooting</a></li>
<li><a href="#">Swimming</a></li>
<li><a href="#">Watersports</a></li>
<li><a href="#">Cycling</a></li>
</ul>
</div>
</li>
<li><a href="#">Seasons</a></li>
<li>
<a class=“has-children” href="/Visiting/Whats-on/">What’s on <span class=“arrow-grey-right”></span></a>
<div class=“children mobile-only”>
<a href="#" class=“back-to-main”>
<span class=“icon-back”>Back</span>
</a>
<ul>
<li><a href="/Visiting/Whats-on/Upcoming-events/">Upcoming Events</a></li>
<li><a href="#">Festivals</a></li>
<li><a href="#">Country shows</a></li>
<li><a href="#">Walk/cycle/event of month</a></li>
<li><a href="#">Seasons</a></li>
</ul>
</div>
</li>
<li><a href="#">While you’re here</a></li>
</ul>
</div>
</li>
<li>
<a href="/Discover/" class=“clearfix has-children”>
Discover <span class=“arrow-green-right”></span>
</a>
<div class=“children mobile-only”>
<a href="#" class=“back-to-main”>
<span class=“icon-back”>Back</span>
</a>
<ul>
<li>
<a href="/Discover/Celebrating-the-North-York-Moors/" class=“has-children”>Celebrating the North York Moors <span class=“arrow-grey-right”></span></a>
<div class=“children mobile-only”>
<a href="#" class=“back-to-main”>
<span class=“icon-back”>Back</span>
</a>
<ul>
<li><a href="/Discover/Celebrating-the-North-York-Moors/60-things-that-make-it-special/">60 things that make it special</a></li>
</ul>
</div>
</li>
<li><a href="#">What makes the North York Moors special?</a></li>
</ul>
</div>
</li>
<li>
<a href="#" class=“clearfix”>
Looking after
</a>
</li>
<li>
<a href="#" class=“clearfix”>
Planning
</a>
</li><li>
<a href="#" class=“clearfix”>
About us
</a>
</li>
</ul>
So, for instance, see line 8:
<a href="/Visiting/" class="clearfix has-children">
<a href="/Visiting/" class="clearfix has-children">How can I apply .has-children only to menu items which have child pages?
I don't think you can do that natively. I would use JS, which would be super easy, but I know you are sometimes opposed to this.
Are you not able to solve the layout issues just using CSS?
No, I hadn't found a way to get Matrix to do this. Maybe I'll have to alter things to get it to work. The problem is that these designs are delivered by third parties to the client, and signed off. Timescales mean that the ideal solution is for Matrix to serve precisely the HTML of the delivered design.
JS is an option, I guess (though as you say I am reluctant). CSS would be better. Any way of selecting a previous sibling in CSS? I don't think I know one. The A tag in question precedes div.children, so this would be my in. It would just be nice to do it in CSS, rather than JS.
There actually is a has_children design area: http://manuals.matrix.squizsuite.net/designs/chapters/show-if-design-area#has_children But it is only on 4.18.x, and not sure if it would help here.
You shouldn't be scared of javascript. Do you have stats showing that a high number of your users have javascript turned off?
Not sure if it will be helpful or not, but take a look at asset #388551 for a Design that I built which has child menu items and had to conform to a designers set markup.
We're due an upgrade in the next couple of months, but that will probably be too late for this one. I don't have stats for this particular client, so might well try the script method. jQuery already used in the site, so might see if I can figure that out. Hang on:
$('a+div.children').prev().addClass('has-children');
Will that do it?
We're due an upgrade in the next couple of months, but that will probably be too late for this one. I don't have stats for this particular client, so might well try the script method. jQuery already used in the site, so might see if I can figure that out. Hang on:
$('a+div.children').prev().addClass('has-children');Will that do it?
Yep, looks like that will do the trick: http://jsfiddle.net/JsRzN/
Yup, though you need to remove the hard-coded .has-children from the HTML to ensure that's working. Seems to be, though. Many thanks for the help. Again.
Yup, though you need to remove the hard-coded .has-children from the HTML to ensure that's working. Seems to be, though. Many thanks for the help. Again.
Looks like I missed a few when removing them and testing it. :)
Another trick I've used in the past if you just want to use CSS, is to add an empty span tag or something inside the <dib> child tag.
<li style="position:relative;"> <div class="children mobile-only"> <span style="position:absolute;" class="child-indicator"></span>
Then just put position absolute on it and position it relatively to the <li> tag.
Another option would be to just use the :after pseudo css selector on the div and position that absolutely and relatively to the parent li.
div.children:before{ content: 'V'; position: absolute; display: block; etc... }
That way, the children indicator will only get printed relatively to the <li> if the child div tag exists.
Thanks, both. As I say, I could obviously start making major changes to the way the menu code works, but it has been signed off by the client, so I really want to make as minimal changes as possible. If I were building it from scratch, my code would look nothing like this, but that's not where we are in the process. The script approach is the simplest, I think, so I'll run with that and see how it goes.