Fermer

avril 28, 2023

Écrivez un meilleur CSS en empruntant des idées aux fonctions JavaScript

Écrivez un meilleur CSS en empruntant des idées aux fonctions JavaScript


J’aime penser à écrire du CSS, comme écrire des fonctions qui décrivent comment vos mises en page réagissent au changement. Lorsque nous oublions les principes d’écriture d’une bonne fonction, voici ce qui peut arriver :

  • Nous perdons du temps.
    Lorsque nous devons nous soucier des effets secondaires, les changements prennent plus de temps.
  • Nous créons des bugs.
    Mon exemple préféré est une boutique en ligne où les boutons « Acheter » ont été masqués en raison d’une mauvaise utilisation des unités de fenêtre.
  • Nous construisons moins de fonctionnalités.
    Lorsque les changements sont effrayants et prennent du temps, ils ne se produisent souvent pas.

Voyons comment nous pouvons emprunter les meilleures pratiques et idées de l’écriture de bonnes fonctions JavaScript pour écrire du CSS facile à utiliser, sans effets secondaires indésirables et résistant au changement.

Éviter les effets secondaires indésirables

Lorsque vous changez quelque chose dans votre système, cela ne devrait pas changer quelque chose d’autre par surprise. C’est aussi vrai pour CSS que pour les fonctions JavaScript.

Regardons cette icône de flèche dans un cercle comme exemple :

Icône de flèche droite assise dans un cercle
(Grand aperçu)

Cela semble bien, mais disons que nous voulons une icône de flèche plus étroite :

Flèche droite dans un ovale en forme d'oeuf
(Grand aperçu)

Maintenant, le cercle contenant est écrasé ! Ceci est un exemple d’effet secondaire indésirable. L’utilisation d’une flèche plus étroite ruine la forme du cercle.

Si nous inspectons l’élément dans DevTools, nous pouvons voir que la forme du cercle contenant dépend de la taille de l’icône intérieure et le rembourrage autour de l’icône.

Une flèche vers la droite dans un ovale en forme d'œuf avec des guides de remplissage affichés
(Grand aperçu)

Idéalement, l’icône intérieure ne devrait pas modifier la forme du cercle contenant. Voici une démonstration de la façon de réparer l’icône écrasée :

Voir le stylo [Arrow Icon Example [forked]](https://codepen.io/smashingmag/pen/OJBpNMv) par .

Voir le stylo Exemple d’icône de flèche [forked] par .

Il y a deux améliorations dans cet exemple :

  1. Les dimensions du conteneur ont été isolées du contenu.
    De cette façon, nous pouvons utiliser différentes icônes sans gâcher le conteneur.
  2. La taille du conteneur a été séparée de l’emplacement de l’icône.
    Parce que nous avons utilisé Flexbox pour centrer l’icône horizontalement et verticalement, la position de l’icône ne sera pas modifiée lorsque la taille du conteneur changera.

Les améliorations de cet exemple peuvent ne pas convenir à tous les cas d’utilisation. Par exemple, si vous avez besoin que la forme et la taille du conteneur changent avec l’icône intérieure, la version « avant » du code pourrait mieux vous convenir.

Quand je dis éviter les effets secondaires indésirables, le mot-clé est « indésirable ». Certains effets secondaires sont souhaitables ! Par exemple, si j’ai trois paragraphes et que j’ajoute plus de texte au premier, j’aimerais que le reste du contenu lui fasse de la place en déplaçant la page vers le bas.

Je suppose que ce que je veux dire, c’est que mon but ici n’est pas de dicter une façon précise de faire les choses. J’espère que vous considérerez les effets secondaires (anticipés et autres) que vous pourriez rencontrer, puis que vous choisirez un plan d’action qui répond à vos besoins. Trop souvent, nous recherchons des solutions publiées aux problèmes des autres sans nous soucier de savoir si ce code crée plus de problèmes qu’il n’en résout.

Plus après saut! Continuez à lire ci-dessous ↓

Écrire un code pratique

Les paramètres de fonction en JavaScript offrent un moyen pratique de définir les entrées que vous souhaitez contrôler. C’est comme décider quels boutons mettre sur un téléviseur.

Nous pouvons écrire du CSS qui est tout aussi facile à contrôler. Pour ce faire, regardons comment éviter deux problèmes que nous pourrions rencontrer lors de l’écriture d’une fonction JavaScript :

  • Trop de paramètres.
    Plus de configurations créent plus de frais généraux et deviennent difficiles à utiliser.
  • Pas assez de paramètres.
    Moins de configurations peuvent ne pas fournir un contrôle suffisant pour vos cas d’utilisation.

Trop de paramètres

Imaginons que nous ayons une fonction JavaScript qui allume et éteint une ampoule. Si notre objectif est de rendre la fonction aussi facile à utiliser que possible, nous souhaiterions probablement y inclure un paramètre qui détermine l’état de l’ampoule.

Voici une fonction pratique et facile à utiliser :

switchLightbulb(ON);

Comparez cela à cette fonction douloureusement complexe :

switchLightbulb(getConnectedWires, isCompleteCircuit, setUpBattery, batteryStatus, isUsingWallOutlet, hasPowerOutage, isElectricityBillPaid, etc);

Dans ce cas, nous voulons simplement allumer l’ampoule, mais lorsque nous avons trop de paramètres, nous avons trop d’autres étapes à compléter. Bien sûr, tous ces autres paramètres sont intéressants et peuvent être utiles dans certaines situations. Ou peut être pas. Quoi qu’il en soit, ils sont hors champ quant à l’objectif essentiel de la fonction : basculer entre un ON état et un OFF État.

Une idée similaire s’applique au CSS. Disons que nous avons une carte avec une image, un titre, un corps de texte et un bouton. Nous voulons changer facilement la largeur de la carte.

Ce one-liner est facile à utiliser et à comprendre :

.card {
  max-width: 300px;
}

Une approche beaucoup moins pratique consiste à définir explicitement le max-width de chaque .card composant:

.card-image {
  max-width: 300px;
}
.card-title-text {
  max-width: 300px;
}
.card-body-text {
  max-width: 300px;
}
.card-button {
  max-width: 300px;
}

Si nous voulons redimensionner la carte dans le deuxième exemple, nous devons effectuer quatre mises à jour pour obtenir un changement. Pour notre cas d’utilisation, le premier exemple est beaucoup plus pratique à utiliser.

Trop peu de paramètres

Maintenant que nous avons vu ce qui peut mal se passer trop paramètres voyons ce qui peut arriver avec Trop peu. Imaginez que nous ayons une fonction qui définit la vitesse d’une voiture et son angle de braquage en degrés. Nous aurons besoin d’au moins deux paramètres pour ces propriétés.

Notre fonction pourrait ressembler à ceci :

setCarState({ speed: 60, turnAngleDegrees: 2 });

On pourrait essayer d’être plus concis et combiner les paramètres :

setCarState({ speedAndTurnAngle: 60 });

Bien sûr, c’est concis, mais c’est aussi terrifiant à utiliser. Imaginez une voiture où accélérer fait aussi tourner le volant ! Nous ne voulons certainement pas regrouper la vitesse et transformer l’angle en un seul paramètre car ce paramètre ne fournit pas suffisamment de contrôle et produit des effets secondaires alarmants.

En CSS, il existe des cas similaires où nous voulons contrôler un paramètre sans en affecter un autre. Par exemple, nous avons peut-être un autre composant de carte, cette fois avec une photo, un nom, une courte biographie et un bouton « Lire plus », et nous voulons changer la largeur de la carte sans que cela n’affecte les dimensions de la photo.

Malheureusement, le max-width L’approche que nous avons utilisée précédemment sur le conteneur de cartes va fournir trop peu de paramètres pour nos besoins :

.card {
  max-width: 300px;
}

Comme nous l’avons noté précédemment, les éléments enfants de la carte s’adapteront à la largeur du conteneur de la carte jusqu’à 300px. Cela inclut l’image, qui rétrécira à mesure que la largeur du conteneur rétrécira en dessous 300px.

Ce dont nous avons besoin, c’est d’un paramètre supplémentaire pour la photo :

.card {
  max-width: 300px;
}
.photo {
  width: max(150px, 50%);
}

Puisque nous voulons changer la largeur de la photo indépendamment de la carte, nous avons besoin de suffisamment de paramètres pour nous donner ce niveau de contrôle. Dans ce cas, cela signifie donner à la photo une largeur distincte de la carte en définissant cette largeur sur une classe étendue à la photo.

Que vous ayez besoin de plus ou moins de paramètres, l’important est de considérez votre cas d’utilisation.

Écrire des styles résilients

Lors de l’écriture d’une fonction, il est utile de demander, Qu’advient-il de la sortie lorsque l’entrée change ?

Nous pouvons poser des variantes de cette même question en CSS, telles que :

  • Si la largeur d’un élément est contrainte, qu’advient-il de sa hauteur ?
  • Si un élément glisse depuis le côté de la fenêtre, qu’advient-il de l’accessibilité de la page ?
  • Si l’utilisateur passe de la souris au toucher, qu’advient-il des interactions au survol ?

Disons que nous avons une mise en page avec trois cartes disposées horizontalement dans un conteneur.

Une mise en page à trois cartes
(Grand aperçu)

Les ensembles CSS max-width: 900px sur le conteneur, et chaque carte obtient un peu de répit avec padding: 5vw. Cela peut sembler correct en surface, mais il y a un problème : le conteneur a une limite supérieure alors que le rembourrage n’en a pas. À mesure que l’écran s’élargit, le contenu est écrasé.

Voir le stylo [Example of padding crushing content [forked]](https://codepen.io/smashingmag/pen/RwepaQQ) par .

Voir le stylo Exemple de contenu d’écrasement de rembourrage [forked] par .

Les solutions possibles incluent :

  • Utiliser des points d’arrêt de fenêtre ou de conteneur pour garder le rembourrage sous contrôle,
  • Utilisation du CSS min() fonction pour définir une limite supérieure sur le rembourrage, ou
  • Utiliser des unités fixes, telles que des pixels, qui ne grandiront pas indéfiniment avec la fenêtre.

Ce que ces solutions ont en commun, c’est qu’elles tiennent compte de ce qui se passe lorsque la largeur de la fenêtre d’affichage change. De même, nous pouvons éviter de nombreux problèmes CSS en considérant la mise en page comme une sortie et en anticipant ce qui pourrait arriver lorsque les entrées changent.

Ahmad Shadeed a un grand nom pour cette technique : CSS défensif. L’idée est que nous pouvons « pérenniser » les styles en les considérant comme des entrées qui génèrent une interface utilisateur et en anticipant les situations qui diminueraient la convivialité de la sortie.

Conclusion

Coder une mise en page ne consiste pas à disposer les choses sur une page, mais décrivant comment ils réagissent au changement. Pour cette raison, il est risqué de traiter CSS comme des constantes plutôt que comme des fonctions.

Heureusement, les mêmes idées qui nous aident à écrire de bonnes fonctions peuvent nous aider à écrire de bons CSS, à savoir :

  • Évitez les effets secondaires indésirables.
  • Utilisez les bons paramètres.
  • Considérez comment les entrées changent les sorties.

Qu’est-ce qui relie ces idées est une question que j’espère que vous vous poserez la prochaine fois que vous écrirez du CSS, Comment cette mise en page devrait-elle réagir au changement ?

Lectures complémentaires sur SmashingMag

Éditorial fracassant
(dd, yk, le)




Source link