Outils pour utilisateurs

Outils du site


issue125:c_c

The last few months of my life have been dedicated to a large project for university. In the course of this project, I was designing a website to go along with a database (the main focus). Therefore, I decided to stick to only the newest CSS technologies, in order to speed up development. During this time, I learned a few neat tricks and uses for CSS grids, that I felt I should share with my readers.

Ces derniers mois ont été dédiés à un grand projet universitaire. Au cours de ce projet, j'ai conçu un site Web pour accompagner une base de données (le sujet central). Par conséquent, j'ai décidé de me tenir uniquement aux technologies CSS les plus récentes, de façon à accélérer le développement. Pendant ce temps, j'ai appris quelques astuces et utilisations sympas des grilles CSS (CSS Grids), qu'il me semblait bon de partager avec mes lecteurs.

Code All code and examples have been placed on Codepen for easy access: https://codepen.io/lswest/pen/NvQMbG

Code

Tout le code et les exemples ont été placés sur Codepen pour un accès facile : https://codepen.io/lswest/pen/NvQMbG

The Plan As most readers probably read in my column in FCM #123, CSS Grids is a new layouting tool that allows you to define columns and rows, and then to either place the direct descendents automatically within this grid, or to define the size and location of the items manually. For anyone who is not experienced with older approaches to layouts in CSS, this was not the case. Originally it was done with floating items left and right (which involved a fair few hacks and caveats), and, more recently, it was done with Flexbox. While CSS Grids do not replace Flexbox, they are more suited to general layout. The reason for this is that Flexbox acts in one direction - horizontally or vertically. Imagine you have 3 elements, and you want a split of 1 element left, and two elements stacked vertically on the right half. With Flexbox you would need to define a container for both the horizontal and the vertical directions. With CSS Grid, you simply define the element on the left as taking up two rows.

Le plan

Comme la plupart des lecteurs l'ont probablement lu dans mon article du FCM n° 123, les grilles CSS sont un nouvel outil d'implantation qui vous permet de définir des colonnes et des lignes, et, ensuite, soit de placer automatiquement les descendants directs dans cette grille, soit de définir la taille et l'emplacement des éléments à la main.

Pour ceux qui n'auraient pas expérimenté les approches anciennes des implantations avec CSS, ce n'était pas le cas. À l'origine, c'était réalisé avec des éléments flottants, à droite et à gauche (ce qui impliquait quelques faiblesses et avertissements) et, plus récemment, c'était fait avec Flexbox. Quoique les grilles CSS ne remplacent pas Flexbox, elles sont mieux adaptées à une disposition générale, parce que Flexbox n'agit que dans une direction - horizontalement ou verticalement. Imaginez que vous ayez trois éléments, et que vous vouliez un découpage avec un élément à gauche et deux éléments l'un sur l'autre dans la moitié droite. Avec Flexbox, vous devriez définir un conteneur pour les directions horizontale et verticale. Avec les grilles CSS, vous définissez simplement l'élément de gauche sur deux rangées.

So far, so good. The problem I originally ran into was that I was applying the ideas of CSS Grids to my ‘usual’ approach - I was redefining everything as I needed to change it for media queries. This means my mobile-first approach (no media query) would define a CSS Grid completely, and later media queries (for larger screens) would completely redefine it. I was then also reassigning elements repeatedly to make sure they appeared in the right locations on the grid. I then read an article on CSS Custom Properties (see Further Reading #1). After reading it, I was rethinking how you could use CSS Custom Properties and media queries to effectively stop repeating yourself. I immediately thought to myself “I can use this with CSS Grids!”. And so some experimenting began - focusing mainly on CSS Grids’ area definitions, and proceeded to the point where I was using only media queries to rewrite CSS Custom Properties, and to relabel my CSS Grid’s areas.

Jusqu'ici, tout va bien. Le problème que j'ai rencontré au début était que j'appliquais les idées des grilles CSS avec mon approche « habituelle ». Je redéfinissais tout, j'avais besoin de tout changer pour les « media queries » (adaptation aux différentes tailles d'écran). Cela signifie que mon approche qui prenait les mobiles d'abord (pas de media queries) définirait complètement une grille CSS et, par la suite, les media queries (pour les plus grands écrans) l'aurait complètement redéfinie. Ensuite, je réassignais les éléments de façon répétitive pour m'assurer qu'ils apparaissaient aux bons emplacements dans la grille.

Après cela, j'ai lu un article sur les propriétés personnalisées de CSS (CCS Custom Properties - voir la première ligne de « Pour aller plus loin »). Après l'avoir lu, j'ai repensé à comment vous pourriez utiliser les propriétés personnalisées de CSS et les media queries pour arrêter de vous répéter. J'ai immédiatement pensé en moi-même « Je peux utiliser ceci avec les grilles CSS ! » Aussi, j'ai commencé quelques expérimentations - centrées principalement sur les définitions de zones des grilles CSS -, et j'ai poursuivi jusqu'à un point où je n'utilisais plus que les media queries pour ré-écrire les propriétés personnalisées de CSS et renommer les zones de ma grille CSS.

The Explanation The plan above may have left you wondering exactly what I meant. That’s what this section is for! At this point, I ask you to please open the Codepen link from above, and to follow along as I explain.

L'explication

Le plan ci-dessus pourrait vous avoir laissé perplexe sur ce que je voulais dire. C'est le rôle de cette partie ! Arrivés ici, je vous demande, s'il vous plaît, d'ouvrir le lien vers Codepen ci-dessus et de le suivre pendant que je l'explique.

CSS Custom Properties I define these right at the top of the CSS file, using the :root selector (which selects the HTML tag, in this case). You can, naturally, do this differently. However, most articles and examples I’ve seen do this also, to ensure that all children inherit the variables properly. I also define only 3 Custom Properties - var-columns which configures the basic columns for our grid, var-rows which does the same for the rows of the grid, and var-aside. The var-aside variable is there only because I have one layout where the sidebar is completely hidden. One could do this step without the Custom Property, but I wanted to stay on theme. So, at the end, we end up with the following variable values: var-columns=1fr 1fr 1fr 1fr, var-rows=6rem 1fr 6rem, var-aside=block. This means we end up with a grid that has 4 equally sized columns, and 3 rows (with a fixed-height header/footer row, and the main content row growing to fill the space).

Les propriétés personnalisées de CSS

Je les définis tout en haut du fichier CSS, en utilisant le sélecteur :root (qui sélectionne l'étiquette HTML, dans ce cas). Vous pouvez, naturellement, le faire autrement. Cependant, la plupart des articles et des exemples que j'ai vus font comme ça, pour assurer que tous les enfants héritent correctement des variables.

Je n'ai aussi défini que 3 propriétés personnalisées - var-columns qui configure les colonnes de base de notre grille, var-rows qui fait de même pour les lignes de la grille et var-aside. La variable var-aside n'est là que parce que j'ai une disposition où la barre latérale est complètement cachée. On peut faire cette étape sans les propriétés personnalisées, mais je voulais rester dans le thème.

Ainsi, au final, nous terminons avec les valeurs des variables suivantes : var-columns=1fr 1fr 1fr 1fr, var-rows=6rem 1fr 6rem, var-aside=block.

Cela signifie que nous finissons avec une grille qui a quatre colonnes de dimensions identiques et 3 lignes (avec une ligne d'entête/pied de page de hauteur fixe et la rangée de contenu principal qui grandit pour remplir l'espace).

Defining Our Areas Moving on to the next selector (line 7), I then define the body of the website. I set the height and width to 100vh and 100vw respectively to ensure the body fills available space (I do this on most websites, but specifically I do this here since I have no content on the page). I also remove any margins on the body, as it causes scrollbars when the body is the full height/width of the viewport. The next few lines are the most important. I define display: grid; to get the process started. Then I load in the rows and columns variables to initialize the grid. The key point is the next declaration, where I define the various areas I want to assign elements to. Think of it as crude ASCII art of the layout. By default, the body should contain one row dedicated to the header, a sidebar taking up the left column, a main section taking the remaining three columns on that row, and another row entirely dedicated to the footer.

Définir nos zones

Dans le sélecteur suivant, (ligne 7), je définis le corps de notre site Web. Je règle la hauteur et la largeur à 100vh et 100vw respectivement pour m'assurer que le corps remplit l'espace disponible (je fais cela dans la plupart des sites Web, mais je le fais expressément ici, car je n'ai aucun contenu dans la page). J'ai supprimé toute marge pour le corps, car cela génère des barres de défilement quand le corps est à la pleine échelle de la fenêtre.

Les quelques lignes suivantes sont les plus importantes. Je définis display: grid; pour initialiser le processus. Ensuite, je charge les variables des lignes et des colonnes pour initialiser la grille. Le point-clé est la déclaration suivante, où je définis les différentes zones auxquelles j'assigne les éléments. Considérez ça comme une grossière technique de disposition en ASCII. Par défaut, le corps devrait contenir une rangée dédiée à l'entête, une barre latérale occupant la colonne de gauche, une section principale sur les trois autres colonnes de cette ligne et une autre ligne entièrement dévolue au pied de page.

Redefining Our Grid The next set of lines (20-61) are all stand-ins for what would typically be media-queries. The reason I use classes here is due to the fact that I wanted to allow users to jump between the layouts without opening a developer console. Instead, I use JavaScript to add classes to the body, effectively emulating the functionality. For clarity, I’ll give you an example (shown top right) of what the body.mobile class would look like as a media query. Now to be fair, I do advocate for a mobile-first approach in actual projects. For the case of this demo, it made more sense to start with a desktop style. Therefore the section in the max-width: 48em; media query would be the default settings, and you would want to use a min-width query to overwrite it with what we used at the start of the CSS file. One very important fact to remember is that your grid-template-areas must have the right number of rows and columns. Even if you’re assigning an entire row with 5 columns to one area, you will need to include the area name for each column.

Redéfinir nos grilles

L'ensemble de lignes suivantes (20-61) remplacent tout ce qui serait généralement des media queries. La raison pour laquelle j'utilise les classes ici est que je voulais permettre aux utilisateurs de passer d'une disposition à l'autre sans ouvrir une console de développeur. À la place, J'utilise JavaScript pour ajouter des classes au corpus principal, émulant efficacement la fonctionnalité. Pour la clarté, je vous donnerai un exemple (voir en haut à droite) de ce à quoi la classe body.mobile peut ressembler comme media query.

Maintenant, pour être honnête, je plaide vraiment pour une première approche pour les mobiles dans les vrais projets. Pour cette démo, c'était plus logique de commencer par le style d'un ordinateur de bureau. Par conséquent, la section dans le media query max-width: 48em; serait les valeurs par défaut et vous utiliseriez une requête min-width pour le remplacer par ce que nous avons utilisé au début du fichier CSS.

Un fait très important à se remémorer est que votre ensemble grid-template-areas doit avoir le bon nombre de lignes et de colonnes. Même si vous assignez une ligne entière sur 5 colonnes à une seule zone, vous devrez inclure le nom de zone de chaque colonne.

Some readers may also be wondering why we’re redefining our variables in a body selector instead of :root. This is the strength of CSS Custom Properties - you can override them like any other CSS property. This means no more need to reset variables (except as needed for children elements). Since we’re only using the variables in body, it made sense to define them there and shorten our media query (by removing a selector). This may become clearer by looking at the no-aside version of the body (lines 47-56). As you can see, the only change needed for the body was the redefining of our grid-template-area (no custom properties were overwritten). However, a second selector (body.no-aside aside) then changes the var-aside variable to none. Since the variable is used later in the CSS file, nothing else needs to be done here. By defining that variable to be none, the display: statement becomes “display: none;” and for other views, the variable is untouched. It also works in this case if you leave out the default declaration (var-aside: block;) as the statement will just silently fail with an invalid variable, and since the default display is “block”, the end result is the same. I wouldn’t recommend doing this, however, as it’s unclear in the long run.

Certains lecteurs peuvent se demander aussi pourquoi nous redéfinissons nos variables dans le sélecteur du corps plutôt que dans :root. C'est la force des propriétés personnalisées de CSS - vous pouvez les écraser comme toute autre propriété de CSS. Cela signifie qu'il n'y a plus besoin de remettre les variables à zéro (sauf au besoin pour les éléments enfants). Comme nous n'utilisons des variables que dans le corps, c'est compréhensible de les définir là et de raccourcir nos media queries (en supprimant le sélecteur).

Cela deviendra plus clair en regardant la version « no-aside » du corps (lignes 47-56). Comme vous pouvez le voir, le seul changement nécessaire dans le corps était de redéfinir notre grid-template-area (aucune propriété personnalisée n'est écrasée). Cependant, un second sélecteur (body.no-aside aside) met ensuite la variable var.aside à zéro. Comme la variable est utilisée par la suite dans le fichier CSS, il n'y a rien d'autre à faire ici. En remettant la variable à zéro, la déclaration display: devient « display:none; » et pour les autres vues, la variable reste inchangée. Cela fonctionne aussi dans ce cas si vous omettez la déclaration par défaut (var-aside: block;) car la déclaration échouera en silence avec une variable invalide et, comme l'affichage par défaut est « block », le résultat final est le même. Cependant, je ne vous recommande pas de le faire, car ce n'est pas clair sur le long terme.

The HTML As you can probably tell, the HTML being used here is pretty clean. There are only the 4 main elements (header, main, aside, and footer). I put the aside tag before main because it was going to be on the left by default, but, with CSS grids, it no longer matters exactly what order the tags appear in. The onclick definitions in the nav tag are also there only to enable the JS swapping of classes. This means you can finally begin writing clear, semantic HTML5 markup!

Le HTML

Comme vous pouvez probablement le voir, le HTML utilisé ici est assez clair. Il n'y a que les quatre éléments principaux (header, main, aside et footer). Je mets l'étiquette aside avant main car elle va être à gauche par défaut, mais, avec les grilles CSS, l'ordre d'apparition des étiquettes n'a pas vraiment d'importance.

Les définitions onclick dans l'étiquette nav sont aussi là pour permettre l'échange de classes avec JS. Cela signifie que vous pouvez enfin commencer à écrire un balisage HTML5 clair et sémantique !

Can Children Inherit the Grid? No. CSS Grids can be applied only to direct descendents of the container element (so header, main, aside, and footer in our above example). Anything deeper than that (nav, for example) cannot be placed on the grid. That being said, you can either nest another CSS grid, or, since this is dealing with only one direction, use Flexbox.

Les enfants peuvent-ils hériter de la grille ?

Non. Les grilles CSS ne peuvent être appliquées qu'aux descendants directs de l'élément conteneur (donc, header, main, aside et footer dans notre exemple ci-dessus). Toute chose plus profonde que ça (nav, par exemple) ne peut pas être placée sur la grille. Cela étant dit, vous pouvez, soit nicher une autre grille CSS, soit, comme ceci ne fonctionne que dans une direction, utiliser Flexbox.

Progressive Enhancement Approach? The reality of the world of web design is that not everyone is using the newest web browsers. Depending on the project you’re working on, it may very well require you to support older systems. My suggestion here is then to define your standard styles to support browsers that support only the basics (depending on what you need to support, this may be floats). Naturally, depending on how complicated the backwards compatibility is, it may be best to create a separate CSS file that newer browsers can ignore (such as a file that is loaded in an IE hack). For browsers that aren’t quite as difficult as IE, you can most likely get away with using @supports to progressively enhance the functionality of your website. Suppose, for example, you’ve defined a basic “fallback” layout, which gives a usable (but different) experience for any browser that doesn’t support flexbox or grid. Then, at the end of the file, you will want to define a @supports(display: grid;) block (for example). In this block, you then define all your CSS Grids. As only browsers that support @supports, and display: grid; will run the block, you can be certain the layout will be used where it is supported. A caveat here is that some newer versions of IE and Edge support @supports, and CSS Grids, but not all features of CSS Grids. Therefore, you may need to check for support of a different CSS Grids property such as @supports(grid-area: auto;). Naturally, only do this if you actually use settings that are unsupported in Microsoft Edge. Similarly, you can check for support of Flexbox before using it in your CSS.

Une approche d'amélioration progressive ?

La réalité du monde de la conception Web est telle que tout le monde n'utilise pas les navigateurs Web les plus récents. Selon le projet sur lequel vous travaillez, vous devez peut-être prendre en compte les anciens systèmes. Ici, ma suggestion est alors de définir vos styles normaux pour tenir compte des navigateurs qui ne supportent que les bases (selon le support dont vous avez besoin, ce pourrait être des « floats »). Naturellement, en fonction de la complexité d'une rétrocompatibilité, il pourrait être préférable de créer un fichier CSS séparé que les navigateurs récents pourraient ignorer (tel qu'un fichier qui est chargé dans un piratage de IE). Pour les navigateurs qui ne sont pas aussi difficiles que IE, vous pouvez, dans le cas général, vous passer d'utiliser @supports pour améliorer progressivement la fonctionnalité de votre site Web.

Supposez, par exemple, que vous avez défini une mise en page basique « de repli », qui donne un rendu utilisable (mais différent) pour tout navigateur qui ne supporte pas flexbox ou les grilles. Alors, en fin de fichier, vous voudrez définir un @supports(display: grid;) block (par exemple). Dans ce « block », vous définissez alors toutes les grilles CSS. Comme seuls les navigateurs qui prennent en compte @supports, et display: grid;, lanceront le block, vous pouvez être certains que la disposition sera utilisée là où elle est prise en charge. Soyez averti ici que certaines versions récentes de IE et Edge supportent @supports et les grilles CSS, mais pas toutes leurs fonctionnalités. Par conséquent, vous pouvez avoir besoin de vérifier la prise en charge d'une propriété des grilles CCS différente, telle que @supports(grid-area: auto;). Naturellement, ne faites cela que si vous utilisez vraiment les réglages qui ne sont pas supportés par Microsoft Edge. De même, vous pouvez vérifier la prise en charge de Flexbox avant de l'utiliser dans vos CSS.

Should I Use It In Production? That depends entirely on what you’re producing. If you’re simply worried that CSS Grids is too new to be used, keep in mind that websites such as the New York Times have already shipped production sites with Grids. If you’re asking because you mainly support IE and Microsoft Edge, then I would say use it as you can, but don’t force yourself to spend massive amounts of time on features both browsers don’t fully support. That being said, Microsoft Edge does support CSS Grids - though there are a few restrictions. However you decide to do it, if you want to use Grids, I recommend you start with the grid layout first. Why? Because it’s by far the most efficient and quick way to lay out a website. I use it for all my prototypes and mockups, because, in those cases, time is of the essence, and I can always pass it to my clients with the indicator that it must be viewed in a modern browser. Only once you’re happy with the new, fast approach, should you slog back into the wasteland that is browser hacks and idiosyncrasies.

L'utiliserais-je en production ?

Ça dépend complètement de ce que vous produisez. Si vous êtes simplement inquiet de ce que les grilles CSS sont trop récentes pour être utilisées, gardez en tête que des sites Web comme le New York Times a déjà mis en production des sites avec Grids. Si vous le demandez parce que vous supportez principalement IE et Microsoft Edge, alors je pourrais dire de l'utiliser quand vous pouvez, mais de ne pas vous forcer à passer un temps monstrueux sur des fonctionnalités qu'aucun des deux navigateurs ne prend en compte complètement. Cela dit, Microsoft Edge supporte les grilles CSS - bien qu'il y ait quelques restrictions.

Peu importe la façon de le faire, si vous voulez utiliser les grilles CSS, je vous recommande de commencer d'abord avec la disposition en grille. Pourquoi ? Parce que c'est de loin la façon la plus efficace et rapide pour mettre en place un site Web. Je l'utilise pour tous mes prototypes et maquettes, parce que, dans ces cas-là, tout est affaire de rapidité et je peux toujours le transmettre à mes clients avec l'indication qu'il doit être vu sur un navigateur moderne. Ce n'est que quand l'approche nouvelle et rapide vous conviendra que vous pourriez consacrer du temps dans le désert des piratages de navigateur et des idiosyncrasies.

I hope this article is interesting for at least a few of my readers. If you’re one of them, feel free to share examples of your CSS Grids projects or talks/presentations about them with me. If anyone has any comments, questions, or requests for future articles, feel free to email me at lswest34@gmail.com. Further Reading https://madebymike.com.au/writing/using-css-variables/ - article on using CSS Custom Properties. https://www.youtube.com/watch?v=7kVeCqQCxlk&index=19&list=PLQjv2GANsZ1JAKzoz631tlyIOZiJ3T2R6 - YouTube Video on CSS Grids (from WordCamp).

J'espère que cet article est intéressant, au moins pour quelques-uns de mes lecteurs. Si vous en êtes un, n'hésitez pas à partager des exemples de vos projets de grilles CSS ou des conférences/présentations à leur sujet. Si quelqu'un a des commentaires, des questions ou des demandes pour de futurs articles, n'hésitez pas à m'envoyer un mail à lswest34@gmail.com.

Pour aller plus loin

https://madebymike.com.au/writing/using-css-variables/ - article sur l'utilisation des propriétés personnalisées de CSS.

https://www.youtube.com/watch?v=7kVeCqQCxlk&index=19&list=PLQjv2GANsZ1JAKzoz631tlyIOZiJ3T2R6 - Vidéo YouTube sur les grilles CSS (issue du WordCamp).

issue125/c_c.txt · Dernière modification : 2017/10/11 11:12 de auntiee