Nested Elements


#1

Is there more of an explanation for Nested Elements? I’m having trouble understanding it.

https://www.codecademy.com/courses/learn-css-selectors-visual-rules/lessons/css-setup-selectors/exercises/nested-elements?action=resume_content_item&course_redirect=learn-css


#2

Nested elements in HTML are tags withing tags.
Example:

<div class="container">
    <div class="row">
        <p>This is a paragraph</p>
    </div>
</div>

In this example there are 3 HTML elements. The outer div with 1 child div and that child div with a child paragraph div. This example has 3 layers. (div-ccontainer > div-row > p)

In CSS you can use this nested structure to style specific HTML elements.
Normally you would style the div’s in the following ways:
Example 1:

div {
    color: blue;
}

The above method with style both the div with class container and the div with class row.

Example 2:

.container {
    color: blue;
}
.row {
    color: red;
}

The above method will style the text color of the div with the class container to blue and the div with class row to red.

The same can be done with the paragraph.

p {
    color: blue;
}

This will make all of the paragraphs on the linked HTML page’s text blue.

Usually this is not what we want to do.
Most of the time only certain paragraphs has to be styled.
This can be achieved by giving the paragraphs classes or an id and then using that to style them in CSS.
This can also be done by using the layers in HTML. When we want to style all of the paragraphs that are the child elements of 2 div elements like above.

To achieve this you can either use the class names:

.container .row p {
    color: blue;
}

this will only style <p> elements within an element with class row, within an element with class container.
You can also use the elements:

div div p {
    color: blue;
}

This will style all of the paragraphs within a div element that is within another div element regardless of their classes.


#3

So it’s basically making them more specified?


#4

Not that this is completely wrong, but, the correct term is elements within elements.

<p>        =>  tag, as in, OPENTAG

</p>       =>  tag, as in, ENDTAG

<p></p>    =>  element, as in, text container

Nested elements are children of their parent container. This promotes inheritence where the parent element can give its properties (some) to its children so they don’t have to be assigned those properties directly.

Some elements do not permit nesting of other elements unless they are inline elements. For instance we cannot nest another paragraph inside a paragraph like we can a division within a division. Likewise we cannot nest a list item within another list item.

Nested lists demonstrate this…

<ul>
  <li>unordered list
    <ol>
      <li>ordered list</li>
      <li>ordered list</li>
      <li>ordered list</li>
    </ol>
  </li>
  <li>unordered list</li>
  <li>unordered list</li>
</ul>
  • unordered list
    1. ordered list
    2. ordered list
    3. ordered list
  • unordered list
  • unordered list

Not quite so. Any conflict between this generic rule (specificity 0 0 0 3) and a class (specificity 0 0 1 0) will favor the class. Generic rules are the easiest ones to override, and are encouraged over more specific rules.

It should be noted that,

div div p {
    color: blue;
}

will apply to any P-node that is at least two levels down. This would still apply if it was five levels down the document tree, or ten, so long as the three nodes are DIV, DIV, P.

specific, not necessarily, but yes to some degree.

<div>
  <p>one level</p>
  <div>
    <p>two levels</p>
    <div>
      <p>three levels</p>
      <div>
        <p>four levels</p>
        <div>
          <p>five levels</p>
          <section>
            <p>six levels</p>
          </section>
        </div>
      </div>
    </div>
  </div>
</div>
p {
  color: red;
}
div p {
  color: teal;
}
div div p {
  color: blue;
}

nesting_css

No red paragraphs, only one teal, and all the rest blue. But wait, the last one is in a section, why is it blue? That’s because of inheritance. The p element is still a descendant of a div that is a descendant of another div, only it is a grandchild, not a direct child.

div p

is a descendant selector.

div > p

is a direct child selector.

Let’s add one line to the top of the HTML above,

<p>direct child of body</p>

and impose the direct child selector in the css,

div div > p {
    color: blue;
}

nesting_css_section

https://repl.it/@mtf/Nested-elements-CSS?language=html


#5

There’s div div yet the paragraphs “four levels” and “five levels” are blue as well.
Does that mean that when a div is typed above another div, it’s the parent of the divs under it?


#6

For example,

<div>
  <p>Test<p>
</div>

<div>
  <p>Test2<p>
</div>

and if I add this code in the css,

div p {
  color: teal;
}

both of the divs color will change to teal?


#7

I didn’t add the opening and closing tags because they are removed after the comment is posted.


#8

Use three backticks at the start, and three at the end when posting code samples.

```
<div></div>
```

#9

No. That would make them siblings. To select the second or later of siblings we use,

div + div p  (or)  div + div > p

but, that is another story, unrelated to nesting.

To be children, the elements must be inside their parent element enclosure.

<div>
  <p>child
    <span>grandchild</span>
  </p>
  <p>child</p>
</div>

Notice in the last example how the paragraph in the section now follows the div p rule? That one still applies because of descendant relation.


#10

Yes, they will both be teal.

Earlier we spoke of generic rules. They’re generic because they are general and global. They are type selectors that reach across the entire DOM to all matching node types.


#11

Thanks so much for the help!


#12

You’re welcome. Here’s a little more for you to consider…

specificity is a weighted score table. That’s why we always see it written like 0 0 0 1.

That is one row of a table, where each column has different importance, the leftmost column having the most, and the rightmost the least. Generic selectors fall into the latter column.

Columns add up but never carry over to the adjacent column. The total remains in that column.

When two selector rules conflict, the score on the left is favored and its selector rule will override any other in effect previous. This relates to the cascade, but that too is another story unrelated to nesting.

Clearly, nesting relates to the parent-child relationship, descendants stipulated to any number of levels. The term level should be clear by now, I’m hoping?

It proves vitally important to understand the above and how it is the basis of DOM traversal.

Picture a neuro-chemical designed to fit only one shape of slot in a brain cell, and a few or many or all cells have this slot. There could be a sea of these chemicals attaching themselves on any random cell. Given a sufficient abundance of the chemical all the cells would be guaranteed to have that slot occupied. That’s how CSS works in the DOM. It is declarative and ubiquitous.

p

No matter how many paragraph elements there are in the document, none will escape this selector.

Specificity and the cascade is how we override it.

p:first-child

will override the generic selector most definitely. p has specificity, 0 0 0 1, where the above has, 0 0 1 1.

How do we get that weighted score? Count the pieces in your selector. The type column gets 1 for the p, the class column gets 1 for :first-child. It won’t matter how large the number in the rightmost column, now. The only thing that will override this is a selector with specificity 2 or more in the class column, or a value greater than zero in any column to the left.

nesting_css_pseudo

Notice how none of the generic rules ever stood a chance against this pseudo-class rule?

div p

has specificity, 0 0 0 2 because it has two type selectors. The only thing it has more specificity than is p, but is able to override that selector.

div div p

with specificity, 0 0 0 3, is able to override that. This is still a descendant combinator though and wholly generic, as we’ve seen. Remember, generic selectors are pervasive. They reach everywhere.

Bottom line, and the reason generic selectors are encouraged, keep specificity low at all accounts. Use the least specificity needed to make your rules work. Make this your mantra and CSS will always be your friend. When you get to scripting and using JavaScript to poll and manipulate the DOM it will be a powerful tool moving forward. Know how to write selectors that get to their targets.