Outils pour utilisateurs

Outils du site


issue125:c_c

Ceci est une ancienne révision du document !


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 d'existence 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 coller 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, que je sentais pouvoir être partagées 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.

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.

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.

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).

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.

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.

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.

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!

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.

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.

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.

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).

issue125/c_c.1507292737.txt.gz · Dernière modification : 2017/10/06 14:25 de d52fr