mizech mizech - 15 days ago 7
CSS Question

"div p" VS "div * p"? Are they same or different?

I've known about the existence of a so-called "grandchild" selector in CSS until I've seen this article. I've played around with it. It seems to me as being just the universal selector (which selects all elements).

Consider the following demo:



.wrap {
width: 400px;
height: 300px;
margin: 50px auto;
}

.wrap * p {
width: 400px;
height: 100px;
background-color: green;
margin: 10px;
color: red;
}

<div class="wrap">
<div class="item1">
<p>First</p>
<div class="item2">
<p>Second</p>
<div class="item3">
<p>Third</p>
</div>
</div>
</div>
</div>





If we remove the
*
from the
.wrap * p
nothing changes.

It's basically the same as
.wrap p
(parent blank child).

So therefore my question:

Does the grandchild selector
*
make any sense?


How
div * p
is different from
div p
notation?

Answer

Yes, there is a difference.

Descendants of a parent element can be of 2 types:

  1. Direct Descendants.
  2. Indirect Descendants.

For example consider the following markup:

<div>
  <em>This is direct descendant</span>
  <p>
    p is also a direct descendant.

    <span>This is indirect descendant</span>
  </p>
</div>

In the above code <em> and <p> are direct while <span> is indirect descendants of <div>.

Descendant Selector:

In css a space workds as a descendant selector. For example:

div p { ... }

The above selector will select all <p> elements appearing inside <div> (Both direct and Indirect).

In the snippet below all p elements will inherit styles.

.wrap p {
  background: green;
  color: white;
}
<div class="wrap">
  <p>Direct p of wrap</p>
  <div class="item1">
    <p>Indirect p of wrap</p>
    <div class="item2">
      <p>Indirect p of wrap</p>
    </div>
  </div>
</div>

Direct Descendant Selector:

> is a direct descendant selector. For example:

div > p { ... }

The above selector will select all <p> elements that are direct descendants of <div>. This selector will search for the elements only one level down in DOM.

In the snippet below only direct p descendants will inherit styles.

.wrap > p {
  background: green;
  color: white;
}
<div class="wrap">
  <p>Direct p of wrap</p>
  <div class="item1">
    <p>Indirect p of wrap</p>
    <div class="item2">
      <p>Indirect p of wrap</p>
    </div>
  </div>
</div>

Now, What is * selector?

* is a universal selector which can match any element.

Indirect Descendants Selectors:

We can add * operator in between any two selectors to select only indirect descendants. For example:

div * p { ... }

The above selector will select all <p> elements inside <div> that are indirect descendants (not direct). The * selector between div and p will select will pick <p> only when there is some other element (because * is a universal selector) between <div> and <p>.

In the snippet below only indirect p descendants will inherit styles.

.wrap * p {
  background: green;
  color: white;
}
<div class="wrap">
  <p>Direct p of wrap</p>
  <div class="item1">
    <p>Indirect p of wrap</p>
    <div class="item2">
      <p>Indirect p of wrap</p>
    </div>
  </div>
</div>

Comments