Fermer

mai 24, 2021

Cas d'utilisation et stratégies de migration


À propos de l'auteur

Adrian Bece est un développeur web fullstack polyvalent avec une vaste expérience du commerce électronique qui travaille actuellement chez PROTOTYP en tant que responsable technique. Il apprécie …
En savoir plus sur
Adrian

Les requêtes de conteneur ont été récemment ajoutées à Chrome Canary et la communauté des développeurs est enthousiasmée par les améliorations de style potentielles. Cette fonctionnalité révolutionnaire rapproche les requêtes multimédias des éléments cibles eux-mêmes et leur permet de s'adapter à pratiquement n'importe quel conteneur ou disposition donné, ce qui se traduit par des styles de composants plus robustes, réutilisables et maintenables. Dans cet article, nous allons aborder les bases des requêtes de conteneur et comment les utiliser aujourd'hui avec une amélioration progressive ou des polyfills.

Lorsque nous écrivons des requêtes multimédias pour un élément d'interface utilisateur, nous décrivons toujours comment cet élément est stylisé en fonction des dimensions de l'écran. Cette approche fonctionne bien lorsque la réactivité de la requête multimédia de l'élément cible ne doit dépendre que de la taille de la fenêtre. Jetons un coup d'œil à l'exemple de mise en page responsive suivant.

 Exemple de mise en page responsive. L'image de gauche montre la disposition du bureau à une largeur de fenêtre de 1280px et l'image de droite montre la disposition mobile à une largeur de fenêtre de 568px.
Exemple de mise en page adaptative. L'image de gauche montre la disposition du bureau à une largeur de fenêtre de 1 280 pixels et l'image de droite montre la disposition mobile à une largeur de fenêtre de 568 pixels. ( Grand aperçu )

Cependant, la conception Web réactive (RWD) ne se limite pas à une mise en page – les composants individuels de l'interface utilisateur ont généralement des requêtes multimédias qui peuvent changer de style en fonction des dimensions de la fenêtre. [19659009] Exemple de composant de carte produit responsive. L'image de gauche montre un composant à une largeur de fenêtre de 720 px et l'image de droite montre une disposition de composant à une largeur de fenêtre de 568 px. « />

Exemple de composant de carte de produit réactif. L'image de gauche montre un composant à une largeur de fenêtre de 720 px et l'image de droite montre une disposition de composant à une largeur de fenêtre de 568 px. ( Grand aperçu )

Vous avez peut-être déjà remarqué un problème avec l'instruction précédente – la disposition individuelle des composants de l'interface utilisateur ne dépend souvent pas exclusivement des dimensions de la fenêtre. Alors que la mise en page est un élément étroitement lié aux dimensions de la fenêtre d'affichage et est l'un des éléments les plus hauts en HTML, les composants d'interface utilisateur peuvent être utilisés dans différents contextes et conteneurs. Si vous y réfléchissez bien, la fenêtre n'est qu'un conteneur et les composants de l'interface utilisateur peuvent être imbriqués dans d'autres conteneurs avec des styles qui affectent les dimensions et la mise en page du composant.

 Exemple de mise en page avec le même composant d'interface utilisateur de fiche produit dans la section supérieure Grille à 3 colonnes et liste de la section inférieure.
Exemple de mise en page avec le même composant d'interface utilisateur de la fiche produit dans la grille à 3 colonnes de la section supérieure et la liste de la section inférieure. ( Grand aperçu )

Même si le même composant de la fiche produit est utilisé dans les sections supérieure et inférieure, les styles de composant dépendent non seulement des dimensions de la fenêtre, mais aussi du contexte et des propriétés CSS du conteneur (comme la grille dans l'exemple) où il est placé.

Bien sûr, nous pouvons structurer notre CSS afin que nous prenions en charge les variations de style pour différents contextes et conteneurs afin de résoudre manuellement le problème de mise en page. Dans le pire des cas, cette variation serait ajoutée avec un remplacement de style qui entraînerait des problèmes de duplication de code et de spécificité.

 .product-card {
    / * Style de carte par défaut * /
}

.product-card - étroit {
   / * Variation de style pour la fenêtre étroite et les conteneurs * /
}

@ écran multimédia et (largeur min: 569px) {
 .product-card - large {
     / * Variation de style pour une fenêtre et des conteneurs plus larges * /
  }
} 

Cependant, il s'agit plus d'une solution de contournement pour les limitations des requêtes multimédias plutôt que d'une solution appropriée. Lors de l'écriture de requêtes multimédias pour les éléments de l'interface utilisateur, nous essayons de trouver une valeur de fenêtre «magique» pour un point d'arrêt lorsque l'élément cible a des dimensions minimales où la mise en page ne se rompt pas. En bref, nous lions une valeur de dimension de fenêtre «magique» à une valeur de dimensions d'élément . Cette valeur est généralement différente de celle de la dimension de la fenêtre et est sujette à des bogues lorsque les dimensions ou la disposition du conteneur interne changent.

 Exemple de la façon dont la requête multimédia ne peut pas être liée de manière fiable aux dimensions des éléments. Diverses propriétés CSS peuvent affecter les dimensions des éléments dans un conteneur. Dans cet exemple, le remplissage du conteneur est différent entre les deux images.
Exemple de la façon dont la requête multimédia ne peut pas être liée de manière fiable aux dimensions des éléments. Diverses propriétés CSS peuvent affecter les dimensions des éléments dans un conteneur. Dans cet exemple, le remplissage du conteneur est différent entre les deux images. ( Grand aperçu )

L'exemple suivant présente exactement ce problème – même si un élément de carte produit réactif a été implémenté et qu'il semble bon dans un cas d'utilisation standard, il semble cassé s'il est déplacé vers un conteneur différent avec des propriétés CSS qui affectent les dimensions des éléments. Chaque cas d'utilisation supplémentaire nécessite l'ajout d'un code CSS supplémentaire ce qui peut entraîner une duplication de code, une surcharge de code et un code difficile à maintenir.

See the Pen [Product cards – various containers] (https: // codepen.io/smashingmag/pen/abJpgvj) par Adrian Bece .

See the Pen Fiches produits – divers contenants par Adrian Bece .

C'est l'un des problèmes que les requêtes de conteneur tentent de résoudre. Les requêtes de conteneur étendent la fonctionnalité des requêtes multimédias existantes avec des requêtes qui dépendent des dimensions de l'élément cible. Il y a trois avantages majeurs à utiliser cette approche:

  • Les styles de requête de conteneur sont appliqués en fonction des dimensions de l'élément cible lui-même. Les composants de l'interface utilisateur pourront s'adapter à n'importe quel contexte ou conteneur donné.
  • Les développeurs n'auront pas besoin de rechercher une valeur de dimension de fenêtre «nombre magique» qui lie une requête multimédia de fenêtre à une dimension cible du composant d'interface utilisateur dans un conteneur spécifique ou un contexte spécifique.
  • Inutile d'ajouter des classes CSS ou des requêtes multimédias supplémentaires pour différents contextes et cas d'utilisation.

«Le site Web réactif idéal est un système de composants flexibles et modulaires qui peuvent être réutilisés pour servir dans plusieurs contextes. »

Container Queries: Once More Unto the Breach »Mat Marquis

Avant de plonger dans les requêtes de conteneurs, nous devons vérifier le support du navigateur et voir comment nous pouvons activez la fonction expérimentale dans notre navigateur.

Support du navigateur

Les requêtes de conteneur sont une fonctionnalité expérimentale actuellement disponible dans la version Chrome Canary au moment de la rédaction de cet article. Si vous souhaitez suivre et exécuter les exemples CodePen de cet article, vous devrez activer les requêtes de conteneur dans l'URL de paramètres suivante.

 chrome: // flags / # enable-container-queries 
 Requêtes de conteneur
] ( Grand aperçu )

Si vous utilisez un navigateur qui ne prend pas en charge les requêtes de conteneur, une image présentant l'exemple de travail prévu sera fournie avec la démo CodePen.

Working With Container Requêtes

Les requêtes de conteneur ne sont pas aussi simples que les requêtes de média classiques. Nous devrons ajouter une ligne supplémentaire de code CSS à notre élément d'interface utilisateur pour que les requêtes de conteneur fonctionnent, mais il y a une raison à cela et nous en parlerons ensuite.

Propriété de confinement

CSS contient a été ajoutée à la majorité des navigateurs modernes et a une prise en charge décente de 75% du navigateur au moment de la rédaction de cet article. La propriété contain est principalement utilisée pour l'optimisation des performances en indiquant au navigateur quelles parties (sous-arborescences) de la page peuvent être traitées comme indépendantes et n'affecteront pas les modifications apportées aux autres éléments d'une arborescence. De cette façon, si un changement se produit dans un seul élément, le navigateur ne restituera que cette partie (sous-arbre) au lieu de la page entière. Avec contiennent les valeurs de propriété nous pouvons spécifier les types de confinement que nous voulons utiliser – layout size ou paint .

.

] Il existe de nombreux excellents articles sur la propriété contenant qui décrivent les options disponibles et les cas d'utilisation de manière beaucoup plus détaillée. Je vais donc me concentrer uniquement sur les propriétés liées aux requêtes de conteneur.

Qu'est-ce que la propriété de contentement CSS utilisée pour l'optimisation a à voir avec les requêtes de conteneur? Pour que les requêtes de conteneur fonctionnent, le navigateur a besoin de savoir si une modification se produit dans la mise en page enfants de l'élément afin de ne restituer que ce composant. Le navigateur saura appliquer le code de la requête de conteneur au composant correspondant lorsque le composant est rendu ou que la dimension du composant change.

Nous utiliserons la valeur layout pour le contiennent mais nous aurons également besoin d'une valeur supplémentaire qui signale au navigateur l'axe dans lequel le changement se produira.

  • inline-size
    Confinement sur l'axe en ligne . On s'attend à ce que cette valeur ait beaucoup plus de cas d'utilisation, elle est donc mise en œuvre en premier.
  • block-size
    Confinement sur l'axe des blocs. Il est toujours en développement et n'est pas disponible actuellement.

Un inconvénient mineur de la propriété contain est que notre élément de mise en page doit être un enfant d'un élément contain ce qui signifie que nous ajoutent un niveau d'imbrication supplémentaire.

 .card {
   contiennent: mise en page taille en ligne;
}

.card__wrapper {
  affichage: grille;
  écart de grille: 1,5em;
  grid-template-rows: auto auto;
  / * ... * /
} 

Remarquez comment nous n'ajoutons pas cette valeur à une section parentale plus éloignée et gardons le conteneur aussi près que possible de l'élément affecté.

«La performance est l'art d'éviter le travail et rendre tout travail que vous faites aussi efficace que possible. Dans de nombreux cas, il s'agit de travailler avec le navigateur, pas contre lui. »

Rendering Performance »Paul Lewis

C'est pourquoi nous devons signaler correctement le changement au navigateur. L'habillage d'un élément parent distant avec une propriété contient peut être contre-productif et affecter négativement les performances de la page. Dans les pires scénarios d'utilisation abusive de la propriété contain la mise en page peut même être interrompue et le navigateur ne l'affiche pas correctement.

Container Query

Après la propriété contain a été ajouté au wrapper d'élément de carte, nous pouvons écrire une requête de conteneur. Nous avons ajouté une propriété contain à un élément avec la classe card nous pouvons donc maintenant inclure n'importe lequel de ses éléments enfants dans une requête de conteneur.

Tout comme avec les requêtes média régulières , nous devons définir une requête en utilisant les propriétés min-width ou max-width et imbriquer tous les sélecteurs dans le bloc. Cependant, nous utiliserons le mot clé @container au lieu de @media pour définir une requête de conteneur.

 @container (min-width: 568px) {
  .card__wrapper {
    align-items: centre;
    écart de grille: 1,5em;
    lignes de modèle de grille: auto;
    grille-modèle-colonnes: 150px auto;
  }

  .card__image {
    largeur min: auto;
    hauteur: auto;
  }
} 

Les éléments card__wrapper et card__image sont des enfants de l'élément card dont la propriété contient définie. Lorsque nous remplaçons les requêtes multimédias régulières par des requêtes de conteneur, supprimons les classes CSS supplémentaires pour les conteneurs étroits et exécutons l'exemple CodePen dans un navigateur qui prend en charge les requêtes de conteneur, nous obtenons le résultat suivant.

<img src = "https: / /cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/a5cb077f-164a-42fb-87c5-f77c9f1db99d/6-introduction-to-container-queries.gif "width =" 800 "height =" 410 " "alt =" Dans cet exemple, nous ne redimensionnons pas la fenêtre, mais l'élément conteneur
lui-même auquel la propriété CSS redimensionner est appliquée. Le composant bascule automatiquement entre les présentations en fonction des dimensions du conteneur. « />
Dans cet exemple, nous ne redimensionnons pas la fenêtre, mais l'élément conteneur
lui-même auquel la propriété CSS redimensionner est appliquée. Le composant bascule automatiquement entre les présentations en fonction des dimensions du conteneur. ( Grand aperçu )

Voir le Stylo [Product cards – container queries] (https://codepen.io/smashingmag/pen/VwpPJm O) de Adrian Bece .

Voir le stylo Fiches produit – requêtes de conteneurs de Adrian Bece .

Veuillez noter que requêtes de conteneurs actuellement n'apparaissent pas dans les outils de développement Chrome ce qui rend le débogage des requêtes de conteneur un peu difficile. On s'attend à ce que la prise en charge du débogage appropriée soit ajoutée au navigateur à l'avenir.

Vous pouvez voir comment les requêtes de conteneur nous permettent de créer des composants d'interface utilisateur plus robustes et réutilisables qui peuvent s'adapter à pratiquement tous les conteneurs et mises en page. Cependant, la prise en charge appropriée du navigateur pour les requêtes de conteneur est encore loin dans la fonctionnalité. Essayons de voir si nous pouvons implémenter des requêtes de conteneur à l'aide de l'amélioration progressive.

Progressive Enhancement & Polyfills

Voyons si nous pouvons ajouter une solution de secours à la variation de classe CSS et aux requêtes multimédias. Nous pouvons utiliser requêtes de fonctionnalités CSS avec la règle @supports pour détecter les fonctionnalités disponibles du navigateur. Cependant, nous ne pouvons pas vérifier d'autres requêtes nous devons donc ajouter une vérification pour une valeur contient: layout inline-size . Nous devrons supposer que les navigateurs qui prennent en charge la propriété inline-size prennent également en charge les requêtes de conteneur.

 / * Vérifiez si la valeur de taille en ligne est prise en charge * /
@supports (contient: inline-size) {
  .carte {
    contiennent: mise en page taille en ligne;
  }
}

/ * Si la valeur de taille en ligne n'est pas prise en charge, utilisez la fonction de secours de requête multimédia * /
@supports not (contiennent: inline-size) {
    @media (largeur min: 568px) {
       / * ... * /
  }
}

/ * Le navigateur ignore @container s'il n'est pas pris en charge * /
@container (largeur min: 568px) {
  / * Styles de requête de conteneur * /
} 

Cependant, cette approche peut conduire à des styles dupliqués car les mêmes styles sont appliqués à la fois par la requête conteneur et la requête multimédia. Si vous décidez d'implémenter des requêtes de conteneur avec une amélioration progressive, vous voudrez utiliser un pré-processeur CSS comme SASS ou un post-processeur comme PostCSS pour éviter de dupliquer des blocs de code et utiliser des mixins CSS ou une autre approche à la place.

Voir the Pen [Product cards – container queries with progressive enhancement] (https://codepen.io/smashingmag/pen/MWpJMpr) par Adrian Bece .

See the Pen Fiches produit – requêtes de conteneurs avec amélioration progressive par Adrian Bece .

Puisque cette spécification de requête de conteneur est encore en phase expérimentale, il est important de garder à l'esprit que la spécification ou l'implémentation est susceptible de changer dans les versions futures.

Alternativement, vous peut utiliser des polyfills pour fournir une solution de secours fiable. Je voudrais mettre en évidence deux polyfills JavaScript, qui semblent actuellement être activement maintenus et fournissent les fonctionnalités de requête de conteneur nécessaires:

Migration des requêtes multimédias vers les requêtes conteneur

Si vous décidez d'implémenter des requêtes conteneur sur un projet existant qui utilise des requêtes multimédias, vous devrez refactoriser le code HTML et CSS. J'ai trouvé que c'était le moyen le plus rapide et le plus simple d'ajouter des requêtes de conteneur tout en offrant une solution de secours fiable aux requêtes multimédias. Jetons un œil à l'exemple de carte précédent.

/ * ... * /
 .card__wrapper {
  affichage: grille;
  écart de grille: 1,5em;
  grid-template-rows: auto auto;
  / * ... * /
}

.card__image {
  / * ... * /
}

@ écran multimédia et (largeur min: 568px) {
  .card__wrapper - large {
    align-items: centre;
    écart de grille: 1,5em;
    lignes de modèle de grille: auto;
    grille-modèle-colonnes: 150px auto;
  }

  .card__image {
    / * ... * /
  }
}

Tout d'abord, encapsulez l'élément HTML racine auquel une requête multimédia est appliquée avec un élément dont la propriété contient .

 @supports (contain: inline-size) {
  .carte {
    contiennent: mise en page taille en ligne;
  }
} 

Ensuite, encapsulez une requête multimédia dans une requête de fonctionnalité et ajoutez une requête conteneur.

 @supports not (contain: inline-size) {
    @media (largeur min: 568px) {
    .card__wrapper - large {
       / * ... * /
    }

    .card__image {
       / * ... * /
    }
  }
}


@container (largeur min: 568px) {
  .card__wrapper {
     / * Même code que .card__wrapper - à l'échelle de la requête multimédia * /
  }

  .card__image {
    / * Même code que .card__image dans la requête multimédia * /
  }
} 

Bien que cette méthode entraîne une surcharge de code et du code dupliqué, en utilisant SASS ou PostCSS, vous pouvez éviter de dupliquer le code de développement, de sorte que le code source CSS reste maintenable.

Une fois que les requêtes de conteneur reçoivent une prise en charge appropriée du navigateur, vous pouvez souhaiter d'envisager de supprimer @supports not (contain: inline-size) blocs de code et de continuer à prendre en charge exclusivement les requêtes de conteneur.

Stephanie Eckles a récemment publié un excellent article sur les requêtes de conteneur couvrant diverses stratégies de migration . Je recommande de le vérifier pour plus d'informations sur le sujet.

Scénarios de cas d'utilisation

Comme nous l'avons vu dans les exemples précédents, les requêtes de conteneur sont mieux utilisées pour les composants hautement réutilisables avec une disposition qui dépend du conteneur disponible space et qui peut être utilisé dans divers contextes et ajouté à différents conteneurs sur la page.

D'autres exemples incluent (les exemples nécessitent un navigateur qui prend en charge les requêtes de conteneur):

Conclusion

Une fois la spécification implémentée et largement pris en charge dans les navigateurs, les requêtes de conteneur peuvent devenir une fonctionnalité qui change la donne. Il permettra aux développeurs d'écrire des requêtes au niveau des composants, en rapprochant les requêtes des composants associés, au lieu d'utiliser les requêtes multimédias de la fenêtre distantes et à peine liées. Cela se traduira par des composants plus robustes, réutilisables et maintenables qui pourront s'adapter à divers cas d'utilisation, mises en page et conteneurs.

Dans l'état actuel des choses, les requêtes de conteneurs sont encore dans une phase expérimentale précoce et la mise en œuvre est enclin au changement. Si vous souhaitez commencer à utiliser des requêtes de conteneur dans vos projets dès aujourd'hui, vous devrez les ajouter à l'aide de l'amélioration progressive avec détection des fonctionnalités ou utiliser un polyfill JavaScript. Les deux cas entraîneront une surcharge dans le code, donc si vous décidez d'utiliser des requêtes de conteneur dans cette phase précoce, assurez-vous de planifier la refactorisation du code une fois que la fonctionnalité sera largement prise en charge.

References

 Smashing Editorial "width = "35" height = "46" loading = "lazy" decoding = "async (vf, yk, il)




Source link