nth CSS Selectors
When using nth CSS selectors, we must take certain things into consideration:
Hint #1 - The ancestor element that all of the target elements have in common.
Hint #2 - Each of the target elements' tagName
s and their ancestors as well.
Hint #3 - The nth
point of entry which isn't always the target elements. It could possibly be more than one level depending if the target element and/or ancestor elements have sibling elements or not and how they are positioned.
Hierarchy
The layout is a 5 level hierarchy.
- ROOT ---- tagName:
<html>
- LEVEL 0 - tagName:
<head>
, <body>
- Role: <<<COMMON ANCESTOR>>>
- LEVEL 1 - tagName:
<div>
, <span>
-- Role: <<<POINT OF ENTRY>>>
- LEVEL 2 - tagName:
<div>
-------------- Role: <<<TARGET ELEMENT>>>
- LEVEL 3 - tagName:
<div>
Two nth
's - nth-child
and nth-of-type
nth-child:
If you use nth-child
, ignore hint #2,
So at the point of entry the common ancestor (i.e. <body>
) has 5 children, not 3 children.
The line-up is: <div>
, <span>
, <span>
, <span>
, <div>
So instead of first-child
it should be nth-child(2)
Instead of last-child
, it's nth-child(4)
nth-of-type:
If you use nth-of-type
, Hint #2 is key to understanding how to use nth-of-type
.
At the point of entry the common ancestor has 2 <div>
s and 3 <span>
s.
Now we can specify a <span>
as first, last, etc. because nth-of-type
differentiates between element tagName
s.
[common ancestor]................:body
- {direct descendant(a.k.a. child)}:
>
- [point of entry].................:
span:first-of-type
- [target element].................:
div
body>span:first-of-type div
Of course the selector above can have variations, but the important part is the point of entry span:first-of-type
.
Demo
Click any span and it will revert from display:block
to display:inline
which is what was posted in OP
Hover over any element to see its Level in the hierarchy, its tagName
, and what its role is.
There is a version of nth-child
styles commented out included as well.*
// For demonstration purposes
Array.from(document.querySelectorAll('span')).forEach(function(spn, idx) {
spn.addEventListener('click', function(e) {
spn.classList.toggle('inline');
}, false);
});
:root::before {
content: 'ROOT';
}
html {
height: 111vh;
width: 90vw;
background: rgba(255, 200, 50, 0.2);
font: 600 15px/1 Consolas;
cursor: crosshair;
overflow-y: scroll;
text-align: center;
color: black;
}
body {
height: 101%;
width: 50vw;
padding: 0 10vw;
margin: 2vh auto;
outline: 0.5rem solid rgba(250, 150, 150, 0.9);
background: rgba(50, 255, 0, 0.4);
font-size: 0.8rem;
}
div {
max-height: 15vh;
max-width: 50vw;
padding: 10px;
outline: 2px dashed darkblue;
background: rgba(255, 200, 50, 0.5);
}
span {
/* OP: display:inline */
display: block;
min-height: 10%;
max-width: 50vw;
padding: 0 20px;
margin: 8px auto;
outline: 3px solid blue;
background: rgba(255, 0, 100, 0.7);
}
.inline {
display: inline;
}
/*::..BEGIN DISABLED OP..::
.parent-span .cta-wrapper {background:gray;}
.parent-span:last-child > .cta-wrapper {background:red; }
.parent-span:first-child > .cta-wrapper {background:green}
}
::..END DISABLED OP..::*/
/*::..BEGIN nth-type-of..::*/
body>span>div {
background: gray;
}
body>span:first-of-type>div {
background: red;
}
body>span:last-of-type>div {
background: green;
}
/*::..END nth-of-type..::*/
/*::..BEGIN nth-child..::
body>span>div {
background: gray;
}
body>span:nth-child(2)>div {
background: red;
}
body>span:nth-child(4)>div {
background: green;
}
::..END nth-child..::*/
<html title='ROOT-HTML'>
<head title='L0-HEAD'>
</head>
<body title='L0-BODY [COMMON ANCESTOR]'>L0
<div title='L1-DIV'>[XXXX] L1 [XXXX]</div>
<span class="parent-span" title='L1-SPAN [POINT OF ENTRY]'>L1
<div class="cta-wrapper" title='L2-DIV [TARGET ELEMENT]'>L2
<div title='L3-DIV'>L3 [1]</div>
</div>
</span>
<span class="parent-span" title='L1-SPAN [POINT OF ENTRY]'>L1
<div class="cta-wrapper" title='L2-DIV [TARGET ELEMENT]'>L2
<div title='L3-DIV'>L3 [2]</div>
</div>
</span>
<span class="parent-span" title='L1-SPAN [POINT OF ENTRY]'>L1
<div class="cta-wrapper" title='L2-DIV [TARGET ELEMENT]'>L2
<div title='L3-DIV'>L3 [3]</div>
</div>
</span>
<div title='L1-DIV'>[XXXX] L1 [XXXX]</div>
</body>
</html>
The terms: common ancestor™, point of entry™, role™, and hierarchy™ are not standard terms, they are of my own creation because these rules are never explained very well AFAIK by anyone (myself included).