Home > other >  Hide first li of specific class
Hide first li of specific class

Time:12-28

Suppose the following HTML code:

<ul >
    <li  data-cart-key="0">aaaaa</li>
    <li >bbbb</li>
    <li >cccc</li>
    <li >dddd</li>
    <li >eeee</li>
    <li >fff</li>
    <li >gggg</li>
</ul>

As you can notice there are two occurrences of .cart_item.subtotal and .cart_item.delivery_fee. What I want is to hide the first occurrences of each of them. So I want to hide bbbb and cccc li's.

I tried with

li.cart_item.subtotal:nth-of-type(1),
li.cart_item.delivery_fee:nth-of-type(1) {
    display: none;
}

which doesn't work. What am I doing wrong?

CodePudding user response:

The :nth-of-type() CSS pseudo-class matches elements based on their position among siblings of the same type (tag name). See docs.

Since the second li is the one you want to hide, this pseudo-class will not help you.

Here is one way to do it that takes two steps:

  • Hide all occurrences of the given selector
  • Show all occurrences that are preceded by a matching selector as a sibling (the ~ can be used to mark "sibling of" - see docs)

/* Hide all li.cart_item.subtotal and li.cart_item.delivery_fee */
li.cart_item.subtotal,
li.cart_item.delivery_fee {
    display: none;
}
/* Show ones that have a previous sibling of the same classes */
li.cart_item.subtotal ~ li.cart_item.subtotal,
li.cart_item.delivery_fee ~ li.cart_item.delivery_fee {
    display: list-item;
}
<ul >
    <li  data-cart-key="0">aaaaa</li>
    <li >bbbb</li>
    <li >cccc</li>
    <li >dddd</li>
    <li >eeee</li>
    <li >fff</li>
    <li >gggg</li>
</ul>


A more concise way that another user posted and deleted (not sure who) can involve combining the two steps:

  • Select occurrences to hide that do not also match the preceding sibling selector

/*
 * Hide all li.cart_item.subtotal and li.cart_item.delivery_fee
 * that are not preceded by a sibling of the same selector.
 */
li.cart_item.subtotal:not(li.cart_item.subtotal ~ li.cart_item.subtotal),
li.cart_item.delivery_fee:not(li.cart_item.delivery_fee ~ li.cart_item.delivery_fee) {
    display: none;
}
<ul >
    <li  data-cart-key="0">aaaaa</li>
    <li >bbbb</li>
    <li >cccc</li>
    <li >dddd</li>
    <li >eeee</li>
    <li >fff</li>
    <li >gggg</li>
</ul>


With CSS Level 4 selectors, you can use the :nth-child(x of y) selector, but it does not have good browser support yet.

/* This will not work in most browsers, may work in Safari */
:nth-child(1 of .cart_item.subtotal) {
    display: none;
}

CodePudding user response:

I like the DenverCoder1's solution but i'd like to add that you can also achieve this with the help of :has pseudo-class, Firefox support is still behind a flag so probably it's better not to use this in production yet

.subtotal:has(~ .subtotal){
  display: none
}

.delivery_fee:has(~ .delivery_fee) {
  display: none
}
<ul >
  <li  data-cart-key="0">aaaaa</li>
  <li >bbbb</li>
  <li >cccc</li>
  <li >dddd</li>
  <li >eeee</li>
  <li >fff</li>
  <li >gggg</li>
</ul>

CodePudding user response:

The :nth-of-type(1) pseudo-class selects the first element of the specified type among its siblings. In your code, it selects the first li element with class cart_item subtotal and the first li element with class cart_item delivery_fee among their siblings.

Since both of these elements are the first occurrence of their respective classes, they will both be selected and hidden.

To hide only the first occurrence of each class, you can use the :first-of-type pseudo-class instead:

li.cart_item.subtotal:first-of-type,
li.cart_item.delivery_fee:first-of-type {
  display: none;
}

Alternatively, you can use the :nth-of-type(2) pseudo-class to select the second occurrence of each class and hide it:

li.cart_item.subtotal:nth-of-type(2),
li.cart_item.delivery_fee:nth-of-type(2) {
  display: none;
}
  •  Tags:  
  • css
  • Related