Hide with CSS - SEO friendly

I have used a drop down menu which uses css rather than javascript. What I am worried about is that using visibility: hidden in my css styles may cause a problem with google and SEO in general.

Could anyone shed any light on this and maybe some advice on whaich is the best way to go about it.

An example of my CSS code is;

.menu.top.cat ul ul {
    position: absolute;
    visibility: hidden;
    list-style: none;
    z-index: 9999;
    background: #FFF;
}

Google probably doesn’t take into account external CSS styles affecting the page and most likely will only see markup anyway. So I wouldn’t worry too much with the navigation menu being pure CSS as the content is still on the page and functions without scripting.

Google is clever enough to know whether you are hiding elements for keyword stuffing or for proper use. Use elements as they were intended and you shouldn’t have a problem.

However screenreaders do have a problem with visibility hidden and display none and therefore the best approach is simply to move the element off the the left of the screen outside the viewport and then bring it back when needed.

This will help screenreaders and avoid any possible seo issues.


.menu.top.cat ul ul {
    position: absolute;
[B]    margin-left:-999em;/* hide it*/[/B]
    list-style: none;
    z-index: 9999;
    background: #FFF;
}
.menu.top.cat li:hover ul {
[B] margin-left:0;/* show it*/[/B]
}


Make sure that you also cater for keyboard users with your dropdown as not all users have a mouse.

Thanks for the responses. Great help

Seems I spoke too soon. By using

margin-left:-999em;/* hide it*/ in place of visibility: hidden; when I hover over the link all the previously hidden lists now show.

Here is the complete css for what I’m using


.menu.top {
    height: 30px;
    overflow: hidden;
    color: #000;
	font-weight: bold;
	border-bottom: 1px solid #000;
}
.menu.top.cat {
    overflow: visible;
    text-align:center;/*center inline children*/
	background:#b6cfee;
}
.menu.top.cat ul {
    display:inline-block;/*center the entire ul*/
    text-align:left;
    position: relative;
    list-style: none;
    z-index: 50;
    margin: 0;/*hide the menu off screen*/
    padding: 0;
    white-space: nowrap;
    background:#b6cfee;
}
*+html .menu.top.cat ul {display:inline}/*IE7 tripswitch*/

.menu.top.cat:hover ul{
    margin-left:0px;/*reveal menu on div hover*/
    background:#b6cfee;
}
.menu.top.cat ul li {
    position: relative;
    float: left;
    text-align: left;
}
.menu.top.cat ul ul {
    position: absolute;
    /*visibility: hidden;*/
	margin-left:-999em;/* hide it*/
    list-style: none;
    z-index: 9999;
    background: #FFF;
	border-left: 1px solid #000;
	border-right: 1px solid #000;
	border-bottom: 1px solid #000;
}
.menu.top.cat ul ul li {
    display: block;
    width: 100%;
    clear: both;
}
.menu.top.cat ul a {
    display: block;
    white-space: nowrap;
    color: #000;
    line-height: 30px;
    padding: 0 10px;
	text-decoration: none;
}
.menu.top.cat ul ul ul {
    position: absolute;
    top: 0;
    left: 0;
}
.menu.top.cat ul li:hover ul, 
.menu.top.cat ul a:hover ul, 
.menu.top.cat ul:hover ul:hover ul, 
.menu.top.cat ul:hover ul:hover ul:hover ul {
    /*visibility: visible;*/
	margin-left:0;/* show it*/
}
.menu.top.cat ul:hover ul ul, 
.menu.top.cat ul:hover ul:hover ul ul {
    /*visibility: hidden;*/
	margin-left:-999em;/* hide it*/
}
.menu.top.cat ul a:hover {
    color: #fff;
    text-decoration: none;
}

Anyone got any ideas of how to get it just to show the selected list not all, works fine with visibility: hidden; and visibility: visible; but I don’t want to run the risk of Google says thanks but no thanks.

Hi,

Id need to see your html for the full solution but in subsequent menus you just hide it again.


.menu.top.cat ul ul {
    position: absolute;
[B]    margin-left:-999em;/* hide it*/[/B]
    list-style: none;
    z-index: 9999;
    background: #FFF;
}
.menu.top.cat li:hover ul {
[B] margin-left:0;/* show it*/[/B]
}
[B].menu.top.cat li:hover ul ul {
[/B][B] margin-left:-999em;/* hide it*/
}[/B]



However in your code above you seem to have mixed ul:hover and li:hover into the mix which doesn’t make sense unless I sse the html as well.


.menu.top.cat ul [B]li:hover[/B] ul, 
.menu.top.cat ul a:hover ul, 
.menu.top.cat [B]ul:hover[/B] ul:hover ul, 
.menu.top.cat[B] ul:hover[/B] [B]ul:hover[/B] [B]ul:hover[/B] ul {
    /*visibility: visible;*/
    margin-left:0;/* show it*/
}
.menu.top.cat [B]ul:hover[/B] ul ul, 
.menu.top.cat [B]ul:hover[/B] [B]ul:hover[/B] ul ul {
    /*visibility: hidden;*/
    margin-left:-999em;/* hide it*/
}


It needs to be consistent and the effect is usually carried out on li:hover not ul:hover.

I’d need to see the working example to fix properly :slight_smile:

Hi, this code actually from a previous post which you have helped on before.

here’s the html I’m using:

<html>
<body>
<div class='menu top cat'>
    <ul class='catparent'>
        <li class="cat-item"><a href="#">Menu 1</a>
            <ul class='children'>
                <li class="cat-item"><a href="#">Menu 1 child 1</a> </li>
                <li class="cat-item"><a href="#">Menu 1 child 2</a> </li>
            </ul>
        </li>
        <li class="cat-item"><a href="#">Menu 2</a> </li>
        <li class="cat-item"><a href="#">Menu 3</a>
            <ul class='children'>
                <li class="cat-item"><a href="#">Menu 3 child 1</a> </li>
                <li class="cat-item"><a href="#">Menu 3 child 2</a> </li>
            </ul>
        </li>
    </ul>
</div>
</body>
</html>

Eventually I want to get the lists populated using database data.

Cheers for the advice and help so far

You can CSS this without using the classnames (except of the ul itself).

Loose example:


.catparent, .catparent ul {
  list-style: none; /*hit them all*/
}

.catparent {
  position: relative;
  set a width;
  margin: 0 auto; (use width and automargins to center)
  whatever else styles
  z-index: 50; <--z-index on the parent works on all browsers including IE
}

.catparent li {
  position: relative;
  float: left;
  width: auto; /*or set width, but this stops an Opera bug*/
}

.catparent ul {
  position: absolute;
  set a width... if you want width of its li, set 100%, tho IE6 doesn't work with that
  margin-left: -999em;
  whatever else
  don't bother with z-index here, doesn't work in IE
}

      /*do like Paul says*/
        .catparent li:hover ul {
           margin-left: 0; /*brings onscreen*/
        }
        .catparent li:hover ul ul {
           margin-left:-999em;/* keep sub hidden*/
        }

...
        .catparent ul li:hover ul {
           margin-left: 0; /*bring sub sub onscreen*/
        }

Ignore the wrapping div, since you have a class on the ul. This keeps your code small. Any ul who is a child of your main ul will be .classname ul, and any sub-ul would be .classname ul ul. You can hit the li’s the same way:
main li: .classname li
first submenu li: .classname ul li
second submenu li: .classname ul ul li

etc.

This keeps your CSS simple, and can remove all those classes you have on everything (unless they’re there for something else?).

I have started using px instead of ems for the margins, only because I notice if I want to bring the submenu items onscreen with :focus, px works and em for some reason doesn’t. But whatever: so long as the units and numbers are the same, you’ll move the thing off-screen and back.

Thanks for the suggestion and it does indeed cut down on the amount of code. All these nested ul and li can get confusing however.

If i want to include a style for text link for example how would I go about this. I want to have a rollover effect using css and two colours, red and black.

If i want to include a style for text link for example how would I go about this.

Do you mean just some link on your page, or the links in your menu?

All the links in your menu are available similar to the li’s:
.catparent a will hit all anchors in that menu
if you need the subanchors to be different (which is common), you just make a slightly more specific rule:

.catparent ul a <–all anchors who are inside a ul who is inside someone with “catparent” class

And if the third-level needs to be also different:

.catparent ul ul a

I prefer using id’s for dropdown menus myself, since then there’s no chance at all that someone else with the same id will ever show up on the page. Classes are allowed to be multiple on a page, so I wouldn’t get any validation errors for more than one element with .catparent as a class.

What you call a rollover has two main ways to reach it: with a mouse (using :hover) and with a keyboard (using :focus). In general, wherever you’re doing :hover for something you can click, add :focus too.

For IE6, if you’re supporting that browser, add :active. It (wrongly) believes the :active state is the same as the :focus state.

IE7 will not understand :focus at all.

Thanks for jumping in Mallory and completing this :slight_smile:

Thanks for the comprehensive reply. I’m going to look at trying these out now. Nice to you guys are here to help out us strugglers