What is the difference between p:nth-child(2) and p:nth-of-type(2)?

前端 未结 8 2032
醉酒成梦
醉酒成梦 2020-12-10 03:37

What is the difference between p:nth-child(2) and p:nth-of-type(2)?

As per W3Schools CSS Selector Reference:

  • p:nth-chil
相关标签:
8条回答
  • 2020-12-10 03:41

    This question may remind you of What is the difference between :first-child and :first-of-type? — and in fact, a lot of parallels can be drawn between the two. Where this question greatly differs from the other is the arbitrary integer argument X, as in :nth-child(X) and :nth-of-type(X). They're similar in principle to their "first" and "last" counterparts, but the potentially matching elements vary greatly based on what's actually in the page.

    But first, some theory. Remember that simple selectors are independent conditions. They remain independent even when combined into compound selectors. That means that the p neither is influenced by, nor influences, how :nth-child() or :nth-of-type() matches. Combining them this way simply means that elements must match all of their conditions simultaneously in order to match.

    Here's where things get interesting. This independent matching means I can get pretty creative in how I express compound (and complex) selectors in terms of plain English, without changing the meaning of the selectors. In fact, I can do so right now in a way that makes the difference between :nth-child(2) and :nth-of-type(2) seem so significant that the pseudo-classes might as well be completely unrelated to each other (except for the "siblings" part anyway):

    • p:nth-child(2): Select the second child among its siblings if and only if it is a p element.

    • p:nth-of-type(2): Select the second p element among its siblings.

    All of a sudden, they sound really different! And this is where a bit of explanation helps.

    Any element may only have a single child element matching :nth-child(X) for any integer X at a time. This is why I've chosen to emphasize "the second child" by mentioning it first. In addition, this child element will only match p:nth-child(X) if it happens to be of type p (remember that "type" refers to the tagname). This is very much in line with :first-child and :last-child (and, similarly, p:first-child and p:last-child).

    There's two aspects to :nth-of-type(X) on the other hand:

    1. Because the "type" in :nth-of-type() is the same concept as the "type" in a type selector, this family of pseudo-classes is designed to be used in conjunction with type selectors (even though they still operate independently). This is why p:nth-of-type(2) can be expressed as succinctly as "Select the second p element among its siblings." It just works!

    2. However, unlike :first-of-type and :last-of-type, the X requires that there actually be that many child elements of the same type within their parent element. For example, if there's only one p element within its parent, p:nth-of-type(2) will match nothing within that parent, even though that p element is guaranteed to match p:first-of-type and p:last-of-type (as well as, by extension, p:only-of-type).

    An illustration:

    <div class="parent">
      <p>Paragraph</p>
      <p>Paragraph</p>          <!-- [1] p:nth-child(2), p:nth-of-type(2) -->
      <p>Paragraph</p>
      <footer>Footer</footer>
    </div>
    
    <div class="parent">
      <header>Header</header>
      <p>Paragraph</p>          <!-- [2] p:nth-child(2) -->
      <p>Paragraph</p>          <!-- [3] p:nth-of-type(2) -->
      <footer>Footer</footer>
    </div>
    
    <div class="parent">
      <header>Header</header>
      <figure>Figure 1</figure>
      <p>Paragraph</p>          <!-- [4] -->
      <footer>Footer</footer>
    </div>
    
    <div class="parent">
      <header>Header</header>
      <p>Paragraph</p>          <!-- [2] p:nth-child(2) -->
      <figure>Figure 1</figure>
      <hr>
      <figure>Figure 2</figure> <!-- [5] .parent > :nth-of-type(2) -->
      <p>Paragraph</p>          <!-- [5] .parent > :nth-of-type(2) -->
      <p>Paragraph</p>
      <footer>Footer</footer>
    </div>
    

    What's selected, what's not, and why?

    1. Selected by both p:nth-child(2) and p:nth-of-type(2)
      The first two children of this element are both p elements, allowing this element to match both pseudo-classes simultaneously for the same integer argument X, because all of these independent conditions are true:

      • it is the second child of its parent;
      • it is a p element; and
      • it is the second p element within its parent.
    2. Selected by p:nth-child(2) only
      This second child is a p element, so it does match p:nth-child(2).

      But it's the first p element (the first child is a header), so it does not match p:nth-of-type(2).

    3. Selected by p:nth-of-type(2) only
      This p element is the second p element after the one above, but it's the third child, allowing it to match p:nth-of-type(2) but not p:nth-child(2). Remember, again, that a parent element can only have one child element matching :nth-child(X) for a specific X at a time — the previous p is already taking up the :nth-child(2) slot in the context of this particular parent element.

    4. Not selected
      This p element is the only one in its parent, and it's not its second child. Therefore it matches neither :nth-child(2) nor :nth-of-type(2) (not even when not qualified by a type selector; see below).

    5. Selected by .parent > :nth-of-type(2)
      This element is the second of its type within its parent. Like :first-of-type and :last-of-type, leaving out the type selector allows the pseudo-class to potentially match more than one element within the same parent. Unlike them, how many it actually matches depends on how many of each element type there actually are.

      Here, there are two figure elements and three p elements, allowing :nth-of-type(2) to match a figure and a p. But there's only one header, one hr, and one footer, so it won't match elements of any of those types.

    In conclusion, :nth-child() and :nth-of-type(), with an integer argument X (i.e. not in the form An+B with a coefficient A of n), function pretty similarly to :first-child/:last-child and :first-of-type/:last-of-type, with the major difference being that the argument, along with the page itself, influences how many different elements may be matched with :nth-of-type().

    Of course, there's a whole lot more to :nth-child() and :nth-of-type() than just a simple integer argument, but needless to say the details and possibilities thereof are outside the scope of this question.

    0 讨论(0)
  • 2020-12-10 03:46

    As MDN says:

    The :nth-child() CSS pseudo-class matches elements based on their position in a group of siblings.


    That means that p:nth-child(2) will only capture <p> elements that are the second child of their parent.

    However, p:nth-of-type(2) will capture <p> elements that are the second element of their parent, regardless of the element's index. This mean's an element can have 100 children and if the last child is the second paragraph element among its siblings, it will be affected by the styles listed.

    Some things to keep in mind (that haven't already been said):

    an element is nth-child(1) and nth-of-type(1)

    This is always true.


    an element is nth-child(2) and nth-of-type(2)

    This is true when an element's first 2 children are of the same type.


    an element is nth-child(3) and nth-of-type(2)

    This is true when an element's 1st and 3rd children are of the same type, but the 2nd child is not.


    an element is nth-child(2) and nth-of-type(3)

    This is always false as an element that is the 3rd of its type can not be the 2nd child of it's parent.


    Example:

    p:nth-child(2)   { color: red; }
    p:nth-of-type(2) { background-color: yellow; }
    <div>
      <p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
      <p>Paragraph 2</p> <!-- p:nth-child(2), p:nth-of-type(2) -->
      <span></span>
    </div>
    
    <hr />
    
    <div>
      <p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
      <span></span>
      <p>Paragraph 2</p> <!-- p:nth-child(3), p:nth-of-type(2) -->
    </div>

    0 讨论(0)
  • 2020-12-10 03:51

    p:nth-child(2): This will select all <p> elements that are the second element inside their parent element. The first element can be any other element. e.g.

    <div>
        <h1>Title</h1>
        <p>Paragraph</p> ** p:nth-child(2)
        <p>Paragraph</p>
    </div>
    
    <div>
        <p>Paragraph</p>
        <p>Paragraph</p> ** p:nth-child(2)
        <p>Paragraph</p>
    </div>
    
    <div>
        <p>Paragraph</p>
        <h1>Text</h1>
        <p>Paragraph</p> ** None are selected
    </div>
    

    p:nth-of-type(2): This will select all <p> elements that are the second occurrence of a <p> element inside their parent element.

    <div>
        <h1>Title</h1>
        <p>Paragraph</p>
        <p>Paragraph</p> ** p:nth-of-type(2)
    </div>
    
    <div>
        <h1>Title</h1>
        <h2>Subtitle</h2>
        <p>Paragraph</p>
        <h2>Subtitle</h2>
        <h2>Subtitle</h2>
        <h2>Subtitle</h2>
        <p>Paragraph</p> ** p:nth-of-type(2)
    </div>
    
    <div>
        <h1>Title</h1>
        <p>Paragraph</p> ** None are selected
    </div>
    
    0 讨论(0)
  • 2020-12-10 03:53

    p:nth-child selector, in "Plain English," means select an element if:

    • It is a paragraph element
    • It is the second child of a parent (if second child of a parent is not <p> css will not effect)

    p:nth-of-type selector, in "Plain English," means:

    • Select the second paragraph <p> child of a parent (care about <p>, just list up all child <p> and take )

    .first p:nth-child(2) {
      background: blue // this css not effect
    }
    
    .first p:nth-of-type(2) {
      background: red
    }
    <div class="first">
      <p>This is 1st paragraph</p>
      <div>This is a div</div>
      <p>This is 2nd paragraph</p>
    </div>

    0 讨论(0)
  • 2020-12-10 03:57

    For p:nth-child(2) it selects the second element of its parent element if it's a paragraph whereas p:nth-of-type(2) will select the second paragraph of its parent element. If you are still confused let's make me clarify it for you. Consider the code snippet below:

    <section>
       <h1>Words</h1>
       <p>Little</p>
       <p>Piggy</p>    <!-- Want this one -->
    </section>
    

    Here, p:nth-child(2) will select <p>Little</p> because it is the second child of its parent and it a paragraph element.

    But, Here, p:nth-of-type(2) will select <p>Piggy</p> because it will select the second paragraph among all the paragraph of its parent.

    Help from: https://css-tricks.com/the-difference-between-nth-child-and-nth-of-type/

    0 讨论(0)
  • 2020-12-10 03:58
    • p:nth-child(1): Means that is the first child of any parent and is of type paragraph.
    • p:nth-of-type (1): Means that is the first appearance of the type paragraph within any parent

    p:nth-child(2){background:#f00;}
    p:nth-of-type(2){background:#0f0;}
    <div>
       <div>first child</div>
       <p>second child and first element of class "p"</p>
       <p>third child and second element of class "p"</p>
       <p>fourth child and third element of class "p"</p>
    </div>

    0 讨论(0)
提交回复
热议问题