Search code examples
csskendo-asp.net-mvc

Why does this code of CSS not work without the >


In the following JSFiddle I have an example of attempting to not apply a style on an object that is inside a div with the class .k-grid.

In the given example the following line of code does not work as I expected. As far as I understand CSS i'm saying: Every P object, that doesn't have the "fancy" class, and are not somewhere inside a div object with a .k-grid.

Since my given p object is inside a div with .k-grid, I dont expect it to turn green.. but it does.

<style>
form.editform div:not(.k-grid) p:not(.fancy) {
  color: green;
}
</style>
<form class="editform">
  <div>
    <div class="k-grid">
      <p>I am a paragraph.</p>
      <p class="fancy">
      <span class="notfancy">I am so very fancy!</span></p>
      <div class="fancy">I am NOT a paragraph.</div>
    </div>
  </div>
</form>

When I change form.editform div:not(.k-grid) p:not(.fancy) to form.editform div:not(.k-grid)>p:not(.fancy) it does properly exclude the p fancy from becoming green.

Can someone explain to me why a space does not work in removing the class from the object, while the > does work? As well as explain what the difference is between "descendents" and "children".


Solution

  • Descendents are children, and descendents of children (e.g. grandchildren, grand-grandchildren, etc). Your <span> is a descendant of <form>, but not a child of it.

    In no case is <div class="k-grid"> getting matched to div:not(.k-grid).

    Your selector is picking up <form class="editform"> as its form.editform, its descendant (and incidentally a child) <div> for div:not(.k-grid), and its descendant (more precisely, grandchild) <p> for p:not(.fancy). You can check that this is what is going on by changing <div> to e.g. <article>, and seeing the CSS rule stop having an effect.

    When you change the last part of your selector to child selector, <p> cannot match because it is a grandchild of <div>.