Placing sub-items in the CSS3 menu

Asked

Viewed 68 times

0

I’m creating a drop'n down menu in CSS3, but I’m not managing to style the third level.

The CSS is like this:

*{margin: 0; padding:0;}
.menu{width: 100%; height: 50px; background-color:#222; font-family:Arial, Helvetica, sans-serif;}
.menu ul{list-style:none; position:relative;}
.menu ul li{width: 150px; float:left;}
.menu a{padding: 15px; display:block; text-decoration:none; text-align:center; background-color:#222; color:#fff;}
.menu ul ul{position: absolute; visibility:hidden;}
.menu ul li:hover ul{visibility: visible;}
.menu ul ul li:hover ul{visibility: visible;}
.menu a:hover{background-color:#f4f4f4; color:#555;}
.menu ul ul li{float: none; border-bottom: 1px solid #ccc;}
.menu ul ul li a{background-color: #999;}
label[for="bt_menu"]{padding: 5px; background-color: #222; color: #FFFFFF; font-family:Arial, Helvetica, sans-serif; font-size:30px; cursor: pointer; width: 50px; height:50px;}

The HTML is like this:

<nav class="menu">
    <ul>
        <li><a href="#">Dashboard</a></li>
        <li><a href="#">Ve&iacute;culos</a>
            <ul>
                <li><a href="#">Novos</a></li>
                <li><a href="#">Seminovos</a></li>
                <li><a href="#">F&amp;I</a></li>
            </ul>
        </li>
        <li><a href="#">Peças</a>
            <ul>
                <li><a href="#">Balc&atilde;o</a></li>
                <li><a href="#">Oficina</a>
                    <ul>
                        <li><a href="#">Mec&acirc;nica</a></li>
                        <li><a href="#">Funilaria</a></li>
                        <li><a href="#">Acessórios</a></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</nav>

Even the second level is good, but I guess I didn’t know how to set up the third level :/

The result of the code in the browser looks like this: inserir a descrição da imagem aqui

Since it would be desirable for it to remain so: inserir a descrição da imagem aqui

2 answers

2


I think you were almost there.

The problem is that you don’t know the levels from the elements.

When you follow two selectors using space, CSS selects all subelements at any level.

a b {} /* qualquer b em qualquer nível dentro de a */

What I think you’d like to use is the operator >, which means: the immediate child, rather than anyone in any sublevel.

a > b {} /* seleciona "b" que é filho imediato de "a"

Note the lines I commented on from your CSS, with the necessary changes (I made a summary of the changes, with explanations, just below the code snippet below):

*{margin: 0; padding:0;}
.menu{width: 100%; height: 50px; background-color:#222; font-family:Arial, Helvetica, sans-serif;}
.menu ul{list-style:none; position:relative;}
.menu ul li{width: 150px; float:left;}
.menu a{padding: 15px; display:block; text-decoration:none; text-align:center; background-color:#222; color:#fff;}
.menu ul ul{position: absolute; visibility:hidden;}

/*.menu ul li:hover ul{visibility: visible;}*/
.menu ul li:hover > ul{visibility: visible;}

/*.menu ul ul li:hover ul{visibility: visible;}*/

.menu a:hover{background-color:#f4f4f4; color:#555;}
.menu ul ul li{float: none; border-bottom: 1px solid #ccc;}
.menu ul ul li > a{background-color: #999;}
label[for="bt_menu"]{padding: 5px; background-color: #222; color: #FFFFFF; font-family:Arial, Helvetica, sans-serif; font-size:30px; cursor: pointer; width: 50px; height:50px;}

/* adicionados */
.menu ul li ul li { white-space: nowrap; }
.menu ul li ul li > a { display: inline-block; width: 100%; box-sizing: border-box; }
.menu ul li ul li > ul { display: inline-block; }
<nav class="menu">
    <ul>
        <li><a href="#">Dashboard</a></li>
        <li><a href="#">Ve&iacute;culos</a>
            <ul>
                <li><a href="#">Novos</a></li>
                <li><a href="#">Seminovos</a></li>
                <li><a href="#">F&amp;I</a></li>
            </ul>
        </li>
        <li><a href="#">Peças</a>
            <ul>
                <li><a href="#">Balc&atilde;o</a></li>
                <li><a href="#">Oficina</a>
                    <ul>
                        <li><a href="#">Mec&acirc;nica</a></li>
                        <li><a href="#">Funilaria</a></li>
                        <li><a href="#">Acessórios</a></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</nav>

Amendments:

  • Replaces:

    .menu ul li:hover ul{visibility: visible;}
    

    With:

    .menu ul li:hover > ul{visibility: visible;}
    

    This rule means that when the user gives :hover in a li, all the ul who are the immediate children of this li will become visible. Before, what was happening is that all the ul, children or grandchildren, or at any level within the li:hover were becoming visible, revealing all levels at the same time.

  • I erased:

    menu ul ul li:hover ul{visibility: visible;}
    

    This rule was redundant with the previous one, because that rule specifies any li:hover with your son ul undeserved.

  • Additions to the end:

    I also added a few more details to make the third level appear on the side instead of below:

    .menu ul li ul li { white-space: nowrap; }
    .menu ul li ul li > a { display: inline-block; width: 100%; box-sizing: border-box; }
    .menu ul li ul li > ul { display: inline-block; }
    

Note that without this last part added the CSS would already work, but would appear below.

  • Thank you very much for the reply Miguel. It worked.

  • Ok. Unfortunately, CSS does not provide a way to specify all even or odd levels. So if you want to do a 4th level, where the menu goes down, you have to repeat rules, using ul > li > ul > li > ul > li level by level until you reach the desired item. And pro 5th level, the same.

0

i made some adjustments to your css: I informed you that any read that has a ul and that is with focus, I make ul visible:

.menu ul li:hover > ul{visibility: visible;}

and to leave aligned I go in last ul and step the following values and attributes:

.menu ul ul ul {position: absolute; top: 50%; left: 100%;}
  • Thanks for the reply Natan. It was almost good. When the sub-item is in the third line. But when it is further down, it misaligns the text. I am editing the question to attach the unwanted result.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.