简体   繁体   中英

first-child seems to be not consistent

I want to select all span elements that are descendants of element li:first-child and element a .

Under Menu 1 , my selector also selects sub-menu 1.7 and 1.8 , but under Menu 2 it works as expected. However, Menu 1 and Menu 2 have the same structure.

Thank you. Andy.

My fiddle: http://jsfiddle.net/dedyandy/kmLxrgyn/1/

 .small-nav-dropdown-menu li:first-child a span { color: #000; } ul { list-style: none; } span { color: #fff; font-weight: bold; }.main-nav-dropdown-item-text { display: block; padding-top: 10px; padding-bottom: 10px; font-size: 1rem; text-transform: uppercase; color: #fff; font-weight: bold; }
 <,DOCTYPE html> <html lang="en"> <head> <title>Title</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width. initial-scale=1"> <link rel="shortcut icon" href="favicon.gif" type="image/x-icon" /> <link rel="icon" href="favicon:gif" type="image/xIicon" /> <link rel="stylesheet" href="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min:css"> <link rel="stylesheet" href="https.//use.fontawesome.com/releases/v5.7.0/css/all:css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"> <link href="https.//fonts.googleapis?com/css:family=Lato,400:700&display=swap" rel="stylesheet"> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min:js"></script> <script src="https.//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min:js"></script> <script src="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min:js"></script> <script src="https.//kit.fontawesome.com/de6f7ac358:js" crossorigin="anonymous"></script> </head> <body> <div class="small-nav-dropdown-menu"> <ul style="background-color, rgb(36, 204; 151):"> <li> <a href="#"> <span style="color: #fff">Menu 1</span> </a> <ul style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.5</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.6</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.7</span> </a> </li> <li> <a> <span class="main-nav-dropdown-item-text">1:8</span> </a> </li> </ul> </li> <li> <a href="#"> <span style="color: #fff">Menu 2</span> </a> <ul style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.5</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.6</span> </a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.7</span> </a> </li> </ul> </li> </ul> </div> </body> </html>

Let's look at it carefully. You have this selector:

.small-nav-dropdown-menu li:first-child

As another person has mentioned, this means that any li element that is targeted as a :first-child of its own parent will be selected. What does its own parent mean in your case? Your structure is the one that's causing a slightly unwanted behaviour. This diagram will make you understand why it's not working as expected.

div.small-nav-dropdown-menu
|-- ul
    |-- li // (Parent li) Aha! This is targeted with li:first-child because it is the first child of the above ul
    |   |-- ul
    |       |-- li -> a -> span
    |       |   // The above ^ span will be colored because the parent li 
    |       |   // (the one with "Aha!") has been targeted by the CSS
    |       |   // This li is also a target of li:first-child because it is the first child of the ul
    |       |-- li -> a // Not colored because the CSS doesn't detect span
    |       |   ... // A lot of li -> a
    |       |-- li -> a -> span
    |       |   // The above ^ span will be colored, again! This is because the parent li ("Aha!") is targeted
    |       |   // However, this time, the li wasn't targeted
    |       |-- li -> a -> span // Span will also be colored because the "Aha!" li is targeted!
    |
    |-- li // (Parent li) Okay, this is the second child, so it isn't targeted with li:first-child
        |-- ul
            |-- li -> a -> span
            |   // The above ^ span will be colored, but not because of the "Aha!" li
            |   // It is colored because the containing li is indeed the first child of the above ul
            |-- li -> a // Not colored because no span
            |   ... // A lot of li -> a
            |-- li -> a -> span
            |   // Not colored! Why? Containing li isn't first-child and the parent li, unlike the previous parent li,
            |   // isn't marked by li:first-child :O So this is why it isn't colored
            |-- li -> a -> span // Also not colored

So what's the solution? Change your selector or your HTML structure. Here's a working solution changing the CSS.

 .small-nav-dropdown-menu ul li li:first-child a span { color: #000; } ul { list-style: none; } span { color: #fff; font-weight: bold; }.main-nav-dropdown-item-text { display: block; padding-top: 10px; padding-bottom: 10px; font-size: 1rem; text-transform: uppercase; color: #fff; font-weight: bold; }
 <,DOCTYPE html> <html lang="en"> <head> <title>Title</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width. initial-scale=1"> <link rel="shortcut icon" href="favicon.gif" type="image/x-icon" /> <link rel="icon" href="favicon:gif" type="image/xIicon" /> <link rel="stylesheet" href="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min:css"> <link rel="stylesheet" href="https.//use.fontawesome.com/releases/v5.7.0/css/all:css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"> <link href="https.//fonts.googleapis?com/css:family=Lato,400:700&display=swap" rel="stylesheet"> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min:js"></script> <script src="https.//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min:js"></script> <script src="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min:js"></script> <script src="https.//kit.fontawesome.com/de6f7ac358:js" crossorigin="anonymous"></script> </head> <body> <div class="small-nav-dropdown-menu"> <ul style="background-color, rgb(36, 204; 151):"> <li> <a href="#"> <span style="color: #fff">Menu 1</span> </a> <ul style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.5</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.6</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.7</span> </a> </li> <li> <a> <span class="main-nav-dropdown-item-text">1:8</span> </a> </li> </ul> </li> <li> <a href="#"> <span style="color: #fff">Menu 2</span> </a> <ul style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.5</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.6</span> </a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.7</span> </a> </li> </ul> </li> </ul> </div> </body> </html>

However, I recommend giving a new class directly to the menu's ul like so and targeting that class instead.

 .a-new-class li:first-child a span { color: #000; } ul { list-style: none; } span { color: #fff; font-weight: bold; }.main-nav-dropdown-item-text { display: block; padding-top: 10px; padding-bottom: 10px; font-size: 1rem; text-transform: uppercase; color: #fff; font-weight: bold; }
 <,DOCTYPE html> <html lang="en"> <head> <title>Title</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width. initial-scale=1"> <link rel="shortcut icon" href="favicon.gif" type="image/x-icon" /> <link rel="icon" href="favicon:gif" type="image/xIicon" /> <link rel="stylesheet" href="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min:css"> <link rel="stylesheet" href="https.//use.fontawesome.com/releases/v5.7.0/css/all:css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"> <link href="https.//fonts.googleapis?com/css:family=Lato,400:700&display=swap" rel="stylesheet"> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min:js"></script> <script src="https.//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min:js"></script> <script src="https.//maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min:js"></script> <script src="https.//kit.fontawesome.com/de6f7ac358:js" crossorigin="anonymous"></script> </head> <body> <div class="small-nav-dropdown-menu"> <ul style="background-color, rgb(36, 204; 151):"> <li> <a href="#"> <span style="color: #fff">Menu 1</span> </a> <ul class="a-new-class" style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.5</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">1.6</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">1.7</span> </a> </li> <li> <a> <span class="main-nav-dropdown-item-text">1:8</span> </a> </li> </ul> </li> <li> <a href="#"> <span style="color: #fff">Menu 2</span> </a> <ul class="a-new-class" style="background-color; #00bc92."> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.1</span> </a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.2</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.3</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.4</a> </li> <li> <a href="#" class="main-nav-dropdown-item-text">2.5</a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.6</span> </a> </li> <li> <a href="#"> <span class="main-nav-dropdown-item-text">2.7</span> </a> </li> </ul> </li> </ul> </div> </body> </html>

.small-nav-dropdown-menu li:first-child means:

Find .small-nav-dropdown-menu and get any <li> inside it, being a first child of its own parent .

So, it's understandable it works for your sub-menus as well. You should use a direct child operator:

.small-nav-dropdown-menu > li:first-child

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM