Deux syntaxes concurrentes ont besoin de votre aide pour déterminer laquelle doit être retenue pour devenir une spécification candidate.
L'imbrication CSS est une syntaxe pratique qui permet d'ajouter du CSS à l'intérieur d'un ensemble de règles. Si vous avez déjà utilisé SCSS, Less ou Stylus, vous avez certainement déjà vu quelques variantes de ce qui suit :
.nesting {
color: hotpink;
> .is {
color: rebeccapurple;
> .awesome {
color: deeppink;
}
}
}
Après avoir été compilé en CSS standard par le préprocesseur, il se transforme en CSS standard comme suit :
.nesting {
color: hotpink;
}
.nesting > .is {
color: rebeccapurple;
}
.nesting > .is > .awesome {
color: deeppink;
}
Une version CSS officielle de cette syntaxe est fortement envisagée. Nous avons une préférence partagée et nous aimerions faire appel à la communauté pour nous aider à trancher. Le reste de cet article présente les options de syntaxe pour que vous puissiez répondre à un sondage à la fin.
Pourquoi l'exemple d'imbrication exacte présenté ci-dessus ne peut-il pas être la syntaxe d'imbrication CSS ?
Il existe plusieurs raisons pour lesquelles la syntaxe d'imbrication la plus courante ne peut pas être utilisée telle quelle :
Analyse ambiguë
Certains sélecteurs imbriqués peuvent ressembler exactement à des propriétés et des préprocesseurs> sont capables de les résoudre et de les gérer au moment de la compilation. Les moteurs de navigateur n'ayant pas les mêmes affordances, les sélecteurs ne doivent jamais être interprétés de manière approximative.Conflits d'analyse du préprocesseur
La façon dont CSS imbrique les éléments ne doit pas interrompre les préprocesseurs ni les workflows d'imbrication des développeurs existants. Cela perturberait et manquerait de respect à ces écosystèmes et communautés.En attente de
:is()
L'imbrication de base ne nécessite pas:is(), mais l'imbrication plus complexe, si. Consultez l'exemple 3 pour une brève présentation des listes de sélecteurs et de l'imbrication. Imaginez que la liste de sélecteurs se trouve au milieu d'un sélecteur au lieu d'être au début. Dans ce cas,:is()est nécessaire pour regrouper les sélecteurs au milieu d'un autre sélecteur.
Présentation des éléments comparés
Nous voulons que l'imbrication CSS soit correcte. C'est pourquoi nous incluons la communauté. Les sections suivantes vous aideront à comprendre les trois versions possibles que nous évaluons. Nous examinerons ensuite quelques exemples d'utilisation à des fins de comparaison. À la fin, nous vous demanderons dans une brève enquête laquelle vous avez préférée.
Option 1 : @nest
Il s'agit de la syntaxe actuellement spécifiée dans CSS Nesting 1. Il offre un moyen pratique d'imbriquer des styles d'ajout en commençant de nouveaux sélecteurs imbriqués par &. Il propose également @nest pour placer le contexte & n'importe où dans un nouveau sélecteur, par exemple lorsque vous n'ajoutez pas simplement des sujets. Il est flexible et minimal, mais vous devez vous souvenir de @nest ou & selon votre cas d'utilisation.
Option 2 : @nest restricted
Il s'agit d'une alternative plus stricte, qui vise à réduire les dépenses liées à la mémorisation de deux méthodes d'imbrication. Cette syntaxe restreinte n'autorise l'imbrication qu'après @nest. Il n'existe donc pas de modèle pratique d'ajout uniquement. Supprime l'ambiguïté du choix, en créant une manière facile à retenir d'imbriquer, mais sacrifie la concision au profit de la convention.
Option 3 : Crochets
Pour éviter la double syntaxe ou l'encombrement supplémentaire impliqués par les propositions @nest, Miriam Suzanne et Elika Etemad ont proposé une syntaxe alternative qui repose plutôt sur des accolades supplémentaires. Cela permet de clarifier la syntaxe, avec seulement deux caractères supplémentaires et sans nouvelles règles @. Il permet également de regrouper les règles imbriquées par type d'imbrication requis, afin de simplifier les sélecteurs imbriqués de manière similaire.
Exemple 1 : Emboîtement direct
@nest
.foo {
color: #111;
& .bar {
color: #eee;
}
}
@nest toujours
.foo {
color: #111;
@nest & .bar {
color: #eee;
}
}
crochets
.foo {
color: #111;
{
& .bar {
color: #eee;
}
}
}
CSS équivalent
.foo {
color: #111;
}
.foo .bar {
color: #eee;
}
Exemple 2 : Imbrication composée
@nest
.foo {
color: blue;
&.bar {
color: red;
}
}
@nest toujours
.foo {
color: blue;
@nest &.bar {
color: red;
}
}
crochets
.foo {
color: blue;
{
&.bar {
color: red;
}
}
}
CSS équivalent
.foo {
color: blue;
}
.foo.bar {
color: red;
}
Exemple 3 : Listes de sélecteurs et imbrication
@nest
.foo, .bar {
color: blue;
& + .baz,
&.qux {
color: red;
}
}
@nest toujours
.foo, .bar {
color: blue;
@nest & + .baz,
&.qux {
color: red;
}
}
crochets
.foo, .bar {
color: blue;
{
& + .baz,
&.qux {
color: red;
}
}
}
CSS équivalent
.foo, .bar {
color: blue;
}
:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
color: red;
}
Exemple 4 : Plusieurs niveaux
@nest
figure {
margin: 0;
& > figcaption {
background: lightgray;
& > p {
font-size: .9rem;
}
}
}
@nest toujours
figure {
margin: 0;
@nest & > figcaption {
background: lightgray;
@nest & > p {
font-size: .9rem;
}
}
}
crochets
figure {
margin: 0;
{
& > figcaption {
background: lightgray;
{
& > p {
font-size: .9rem;
}
}
}
}
}
CSS équivalent
figure {
margin: 0;
}
figure > figcaption {
background: hsl(0 0% 0% / 50%);
}
figure > figcaption > p {
font-size: .9rem;
}
Exemple 5 : Emboîtement de parents ou changement de sujet
@nest
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
@nest toujours
.foo {
color: red;
@nest .parent & {
color: blue;
}
}
crochets
.foo {
color: red;
{
.parent & {
color: blue;
}
}
}
CSS équivalent
.foo {
color: red;
}
.parent .foo {
color: blue;
}
Exemple 6 : Combinaison de l'imbrication directe et de l'imbrication parent
@nest
.foo {
color: blue;
@nest .bar & {
color: red;
&.baz {
color: green;
}
}
}
@nest toujours
.foo {
color: blue;
@nest .bar & {
color: red;
@nest &.baz {
color: green;
}
}
}
crochets
.foo {
color: blue;
{
.bar & {
color: red;
{
&.baz {
color: green;
}
}
}
}
}
CSS équivalent
.foo {
color: blue;
}
.bar .foo {
color: red;
}
.bar .foo.baz {
color: green;
}
Exemple 7 : imbrication de requêtes média
@nest
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
ou explicite / étendu
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
@nest always (toujours explicite)
.foo {
display: grid;
@media (width => 30em) {
@nest & {
grid-auto-flow: column;
}
}
}
crochets
.foo {
display: grid;
@media (width => 30em) {
grid-auto-flow: column;
}
}
ou explicite / étendu
.foo {
display: grid;
@media (width => 30em) {
& {
grid-auto-flow: column;
}
}
}
CSS équivalent
.foo {
display: grid;
}
@media (width => 30em) {
.foo {
grid-auto-flow: column;
}
}
Exemple 8 : Imbriquer des groupes
@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 toujours
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;
}
}
}
crochets
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 équivalent
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;
}
Exemple 9 : Groupe d'imbrication complexe "Kitchen Sink"
@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 toujours
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;
}
}
crochets
dialog {
border: none;
{
&::backdrop {
backdrop-filter: blur(25px);
}
& > form {
display: grid;
{
& > :is(header, footer) {
align-items: flex-start;
}
}
}
}
{
html:has(&[open]) {
overflow: hidden;
}
}
}
CSS équivalent
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;
}
Il est temps de voter
Nous espérons que vous avez trouvé cette comparaison et cet échantillon des options de syntaxe que nous évaluons équitables. Veuillez les examiner attentivement et nous indiquer ci-dessous celui que vous préférez. Merci de nous aider à faire évoluer l'imbrication CSS vers une syntaxe que nous connaîtrons et apprécierons tous !