CSS :nth-child(), Le sélecteur par position
Introduction Introduction
Voici la suite de l’article sur les possibilités avec le :has()
, pour voir la première partie, vous pouvez cliquer le lien de la partie 1 de l’article
La sélection par quantité La sélection par quantité
Ciblage par index Ciblage par index
En CSS, il existe un sélecteur qui permet de cibler un enfant en fonction de son index, autrement dit selon sa position en tant qu’enfant. Par exemple, si je souhaite cibler le troisième enfant, on peut faire un simple :
span:nth-child(3) {
}
<article>
<span>🕳</span>
<span>🕳</span>
<span>🎯</span>
<span>🕳</span>
<span>🕳</span>
</article>
article {
padding: 2rem clamp(1rem, 4vw, 4rem);
font-size: clamp(2rem, 4vw, 4rem);
border-radius: 20px;
display: flex;
place-content: space-between;
}
span {
--color-shadow:360deg;
text-shadow: 0 0 25px hsla(var(--color-shadow), 100%, 50%, 100%);
&:nth-child(3) {
--color-shadow:150deg;
}
}
Ciblage à partir d’un index Ciblage à partir d’un index
On peut également cibler tous les éléments à partir d’un index :
span:nth-child(n + 3) {
}
<article>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
</article>
article {
padding: 2rem clamp(1rem, 4vw, 4rem);
font-size: clamp(2rem, 4vw, 4rem);
border-radius: 20px;
display: flex;
place-content: space-between;
font-family: sans-serif;
}
span {
--filter: 1;
filter: grayscale(var(--filter));
&:nth-child(n + 3) {
--filter: 0;
}
}
Ou en partant de la fin :
span:nth-last-child(n + 3) {
}
<article>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
<span>🚀</span>
</article>
article {
padding: 2rem clamp(1rem, 4vw, 4rem);
font-size: clamp(2rem, 4vw, 4rem);
border-radius: 20px;
display: flex;
place-content: space-between;
font-family: sans-serif;
}
span {
--filter: 1;
filter: grayscale(var(--filter));
&:nth-last-child(n + 3) {
--filter: 0;
}
}
Ciblage en fonction du nombre d’éléments Ciblage en fonction du nombre d’éléments
Imaginons que nous ayons un conteneur d’éléments qui doit passer au orange dès que le nombre de burgers est supérieur à 3 puis au rouge dès que l’on dépasse 6 burgers. On va aussi dynamiser l’affichage d’un message en fonction de ces dépassements.
<article>
<span class="message"></span>
<section><span>🍔</span></section>
<button class="small danger" onclick="deleteBurger(this)">Delete</button>
<button class="small" onclick="addBurger(this)">Add</button>
</article>
article {
--state-color: green;
--text: "C'est ok 😀";
border: var(--state-color) 3px solid;
background-color: #000;
padding: 2rem clamp(1rem, 4vw, 4rem);
font-size: clamp(2rem, 4vw, 4rem);
border-radius: 20px;
text-align: center;
section {
padding:0;
}
.message {
font-size: 2rem;
color: var(--state-color);
&::before {
content: var(--text);
}
}
&:has(section > span:nth-child(3n)) {
--state-color: orange;
--text: "Trop de burgers 😧";
}
&:has(section > span:nth-child(6n)) {
--state-color: red;
--text: "là c'est abusé 😱";
}
}
La sélection par attribut La sélection par attribut
Les sélecteurs d’attributs sont également très utiles pour cibler certains de nos éléments. On peut aller assez loin dans les patterns de sélection avec un peu d’expressions régulières.
Appliquer du style selon la valeur de l’attribut Appliquer du style selon la valeur de l’attribut
Par exemple, on peut appliquer un certain style sur un lien qui serait externe au site :
a[href^="https://"]
{
color: green;
}
Imaginons maintenant que nous souhaitions personnaliser un encart contenant un lien de téléchargement en fonction du type fichier.
En combinant le :has()
et un sélecteur d’attribut, c’est tout à fait possible :
<div class="links">
<a id="top" href="https://www.samuelgomez.fr">https personal Website</a>
<a href="http://www.wooweb.fr">No https external website</a>
<a href="#top">My anchor link</a>
</div>
<div class="links">
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="text.txt">Download</a>
</div>
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="myfile.jpg">Download</a>
</div>
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="myfile.wave">Download</a>
</div>
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="myfile.pdf">Download</a>
</div>
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="myfile.docx">Download</a>
</div>
<div class="link-box">
<p>Télécharger votre fichier</p>
<a href="myfile.xslx">Download</a>
</div>
</div>
.links {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
margin-block-end: 2rem;
a:after {
content: var(--icon-link, "");
}
a[href^="#"] {
--icon-link: " 🔗";
&:after {
font-size: 0.8em;
}
}
a:is([href^="https://"],[href^="http://"]){
--icon-link: " ↗";
}
.link-box {
--theme-color: #333;
--theme-icon: "📄";
--theme-file: "";
border: 1px solid var(--theme-color);
padding: 1rem 1rem 2rem 1rem;
border-radius: 15px;
text-align: center;
position: relative;
background: color-mix(in srgb, var(--theme-color) 15%, white);
transition: background-color 0.5s linear;
&::before {
border-radius: 5px;
position: absolute;
height: 20px;
background: color-mix(in srgb, var(--theme-color) 70%, white);
top: 0;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 0.8rem;
padding: 0.1rem 0.5rem;
line-height: 1;
display: flex;
place-items: center;
z-index: 2;
content: var(--theme-icon);
}
&:hover,
&:focus-within {
background: color-mix(in srgb, var(--theme-color) 5%, white);
transition: background-color 0.5s linear;
}
a {
all: revert;
&::before {
content: none;
}
color: var(--theme-color);
border-radius: 15px;
position: absolute;
display: grid;
height: calc(100% - 0.5rem);
padding-bottom: 0.5rem;
width: 100%;
top: 0;
left: 0;
justify-content: center;
align-content: end;
&:hover,
&:focus {
outline: 2px solid color-mix(in srgb, var(--theme-color) 5%, white);
outline-offset: 2px;
}
}
p {
color: var(--g8);
margin: 0;
&::after {
position: relative;
content: var(--theme-file);
}
}
&:has(a[href$=".wave"]) {
--theme-color: purple;
--theme-icon: "🔈";
--theme-file: " Audio";
}
&:has(a[href$=".jpg"]) {
--theme-color: sienna;
--theme-icon: "🏞";
--theme-file: " Image";
}
&:has(a[href$=".pdf"]) {
--theme-color: darkred;
--theme-icon: "PDF";
--theme-file: " PDF";
}
&:has(a[href$=".docx"]) {
--theme-color: blue;
--theme-icon: "DOCX";
--theme-file: " DOCX";
}
&:has(a[href$=".xslx"]) {
--theme-color: darkgreen;
--theme-icon: "XLSX";
--theme-file: " XLSX";
}
}
}
Autre cas :
https://www.bram.us/2023/01/12/sibling-scopes-in-css-thanks-to-has/