Due sintassi in competizione hanno bisogno del tuo aiuto per determinare quale deve essere promossa come candidato alla specifica.
L'annidamento CSS è un'aggiunta di sintassi conveniente che consente di aggiungere CSS all'interno di un insieme di regole. Se hai utilizzato SCSS, Less o Stylus, allora avrai sicuramente visto alcune varianti di questo:
.nesting {
color: hotpink;
> .is {
color: rebeccapurple;
> .awesome {
color: deeppink;
}
}
}
che, dopo essere stato compilato in CSS normale dal preprocessor, si trasforma in CSS normale come questo:
.nesting {
color: hotpink;
}
.nesting > .is {
color: rebeccapurple;
}
.nesting > .is > .awesome {
color: deeppink;
}
Stiamo prendendo in seria considerazione una versione CSS ufficiale di questa sintassi e abbiamo una preferenza divisa che vorremmo risolvere con l'aiuto della community. Il resto di questo post introdurrà le opzioni di sintassi, così potrai rispondere a un sondaggio alla fine.
Perché l'esempio di nidificazione esatto mostrato sopra non può essere la sintassi per la nidificazione CSS?
Esistono alcuni motivi per cui la sintassi di nidificazione più comune non può essere utilizzata così com'è:
Analisi ambigua
Alcuni selettori nidificati possono avere l'aspetto esatto di proprietà e preprocessor sono in grado di risolverli e gestirli in fase di compilazione. I motori del browser non avranno le stesse funzionalità, i selettori non devono mai essere interpretati in modo approssimativo.Conflitti di analisi del preprocessor
Il modo di nidificare il CSS non deve interrompere i preprocessor o i flussi di lavoro di nidificazione esistenti degli sviluppatori. Questo comportamento sarebbe distruttivo e scortese nei confronti di questi ecosistemi e community.In attesa di
:is()
L'annidamento di base non richiede:is(), ma quello più complesso sì. Consulta l'esempio n. 3 per una breve introduzione agli elenchi di selettori e all'annidamento. Immagina che l'elenco dei selettori si trovi al centro di un selettore anziché all'inizio. In questi casi,:is()è obbligatorio per raggruppare i selettori al centro di un altro selettore.
Panoramica di ciò che stiamo confrontando
Vogliamo implementare correttamente l'annidamento CSS e, in questo spirito, includiamo la community. Le sezioni seguenti descrivono le tre possibili versioni che stiamo valutando. Poi esamineremo alcuni esempi di utilizzo per il confronto e alla fine ci sarà un breve sondaggio in cui ti verrà chiesto quale preferisci in generale.
Opzione 1: @nest
Questa è la sintassi specificata attualmente in CSS Nesting 1. Offre un modo pratico per nidificare
gli stili di aggiunta iniziando nuovi selettori nidificati con &. Offre anche
@nest come modo per inserire il contesto & ovunque all'interno di un nuovo selettore, ad esempio
quando non stai solo aggiungendo soggetti. È flessibile e minimale, ma a scapito della necessità di ricordare @nest o & a seconda del caso d'uso.
Opzione 2: @nest restricted
Si tratta di un'alternativa più rigorosa, nel tentativo di ridurre la spesa menzionata per ricordare due metodi di nidificazione. Questa sintassi limitata consente l'annidamento solo dopo @nest, quindi non esiste un pattern di convenienza di sola aggiunta. Rimozione
dell'ambiguità della scelta, creazione di un modo facile da ricordare per nidificare, ma sacrifici
la concisione a favore della convenzione.
Opzione 3: parentesi
Per evitare la doppia sintassi o l'ingombro aggiuntivo delle proposte @nest, Miriam Suzanne ed Elika Etemad hanno proposto una sintassi alternativa che si basa invece su parentesi graffe aggiuntive. In questo modo la sintassi è più chiara,
con solo due caratteri aggiuntivi e nessuna nuova regola @. Consente inoltre di raggruppare le regole nidificate in base al tipo di nidificazione richiesto, in modo da semplificare più selettori nidificati in modo simile.
Esempio 1 - Nidificazione diretta
@nest
.foo {
color: #111;
& .bar {
color: #eee;
}
}
@nest always
.foo {
color: #111;
@nest & .bar {
color: #eee;
}
}
parentesi
.foo {
color: #111;
{
& .bar {
color: #eee;
}
}
}
CSS equivalente
.foo {
color: #111;
}
.foo .bar {
color: #eee;
}
Esempio 2 - Nidificazione composta
@nest
.foo {
color: blue;
&.bar {
color: red;
}
}
@nest always
.foo {
color: blue;
@nest &.bar {
color: red;
}
}
parentesi
.foo {
color: blue;
{
&.bar {
color: red;
}
}
}
CSS equivalente
.foo {
color: blue;
}
.foo.bar {
color: red;
}
Esempio 3: elenchi di selettori e nidificazione
@nest
.foo, .bar {
color: blue;
& + .baz,
&.qux {
color: red;
}
}
@nest always
.foo, .bar {
color: blue;
@nest & + .baz,
&.qux {
color: red;
}
}
parentesi
.foo, .bar {
color: blue;
{
& + .baz,
&.qux {
color: red;
}
}
}
CSS equivalente
.foo, .bar {
color: blue;
}
:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
color: red;
}
Esempio 4: più livelli
@nest
figure {
margin: 0;
& > figcaption {
background: lightgray;
& > p {
font-size: .9rem;
}
}
}
@nest always
figure {
margin: 0;
@nest & > figcaption {
background: lightgray;
@nest & > p {
font-size: .9rem;
}
}
}
parentesi
figure {
margin: 0;
{
& > figcaption {
background: lightgray;
{
& > p {
font-size: .9rem;
}
}
}
}
}
CSS equivalente
figure {
margin: 0;
}
figure > figcaption {
background: hsl(0 0% 0% / 50%);
}
figure > figcaption > p {
font-size: .9rem;
}
Esempio 5: nidificazione dei genitori o modifica dell'oggetto
@nest
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
@nest always
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
parentesi
.foo {
color: red;
{
.parent & {
color: blue;
}
}
}
CSS equivalente
.foo {
color: red;
}
.parent .foo {
color: blue;
}
Esempio 6: combinazione di nidificazione diretta e nidificazione principale
@nest
.foo {
color: blue;
@nest .bar & {
color: red;
&.baz {
color: green;
}
}
}
@nest always
.foo {
color: blue;
@nest .bar & {
color: red;
@nest &.baz {
color: green;
}
}
}
parentesi
.foo {
color: blue;
{
.bar & {
color: red;
{
&.baz {
color: green;
}
}
}
}
}
CSS equivalente
.foo {
color: blue;
}
.bar .foo {
color: red;
}
.bar .foo.baz {
color: green;
}
Esempio 7: nidificazione delle media query
@nest
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
o esplicito / esteso
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
@nest always (is always explicit)
.foo {
display: grid;
@media (width => 30em) {
@nest & {
grid-auto-flow: column;
}
}
}
parentesi
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
o esplicito / esteso
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
CSS equivalente
.foo {
display: grid;
}
@media (width => 30em) {
.foo {
grid-auto-flow: column;
}
}
Esempio 8: gruppi nidificati
@nest
fieldset {
border-radius: 10px;
&:focus-within {
border-color: hotpink;
}
& > legend {
font-size: .9em;
}
& > div {
& + div {
margin-block-start: 2ch;
}
& > label {
line-height: 1.5;
}
}
}
@nest always
fieldset {
border-radius: 10px;
@nest &:focus-within {
border-color: hotpink;
}
@nest & > legend {
font-size: .9em;
}
@nest & > div {
@nest & + div {
margin-block-start: 2ch;
}
@nest & > label {
line-height: 1.5;
}
}
}
parentesi
fieldset {
border-radius: 10px;
{
&:focus-within {
border-color: hotpink;
}
}
> {
legend {
font-size: .9em;
}
div {
+ div {
margin-block-start: 2ch;
}
> label {
line-height: 1.5;
}
}}
}
}
CSS equivalente
fieldset {
border-radius: 10px;
}
fieldset:focus-within {
border-color: hotpink;
}
fieldset > legend {
font-size: .9em;
}
fieldset > div + div {
margin-block-start: 2ch;
}
fieldset > div > label {
line-height: 1.5;
}
Esempio 9: gruppo di nidificazione complesso "Lavello"
@nest
dialog {
border: none;
&::backdrop {
backdrop-filter: blur(25px);
}
& > form {
display: grid;
& > :is(header, footer) {
align-items: flex-start;
}
}
@nest html:has(&[open]) {
overflow: hidden;
}
}
@nest always
dialog {
border: none;
@nest &::backdrop {
backdrop-filter: blur(25px);
}
@nest & > form {
display: grid;
@nest & > :is(header, footer) {
align-items: flex-start;
}
}
@nest html:has(&[open]) {
overflow: hidden;
}
}
parentesi
dialog {
border: none;
{
&::backdrop {
backdrop-filter: blur(25px);
}
& > form {
display: grid;
{
& > :is(header, footer) {
align-items: flex-start;
}
}
}
}
{
html:has(&[open]) {
overflow: hidden;
}
}
}
CSS equivalente
dialog {
border: none;
}
dialog::backdrop {
backdrop-filter: blur(25px);
}
dialog > form {
display: grid;
}
dialog > form > :is(header, footer) {
align-items: flex-start;
}
html:has(dialog[open]) {
overflow: hidden;
}
È ora di votare
Ci auguriamo che tu ritenga che questo sia un confronto equo e un assaggio delle opzioni di sintassi che stiamo valutando. Esaminali attentamente e facci sapere quale preferisci qui sotto. Ti ringraziamo per averci aiutato a far progredire il nesting CSS verso una sintassi che tutti impareremo a conoscere e ad amare.