Don’t use empty or low content for your design system grid examples

Dave and I had Jen Simmons on ShopTalk the other day. Jen was talking about Intrinsic Web Design and how one of the core tenets of it is grids with rows and columns that don’t necessarily change at the same rate or ones that have essentially different rules for how they behave.

For example, take this (contrived) grid setup:

.grid { display: grid; grid-template-columns: 1fr minmax(50px, 100px) 20% auto;
}

Each of those columns will behave differently.

I’m just wrapping my head about this, and definitely don’t fully understand it. Here’s what it seems like to me, numbered 1-4 based on the “strength” (I guess?) of the width.

.grid { display: grid; grid-template-columns: 1fr /* #4 - Weakest, will fill remaining space */ minmax(50px, 100px) /* #3 - Will only start changing when other columns force it */ 20% /* #1 - Definite size, steady */ auto /* #2 - Indefinite size, entirely based on content, pushy */ ;
}

This is much different from quite a long history of how we’ve set up grid columns in the past. Float-based grids typically use percentages (a definite size) to set columns. Same with inline-block-based grids, typically.

Even with grid, if you set up all your columns with all percentages or all fractional units, you’d likely have a steady grid in which the content inside won’t mess with sizing. But Jen is saying that it’s interesting to have a grids where the content has a say in how they size. Embrace it. Sounds fun to me.

But anyway, say you’re setting up a grid that uses mixed values for column widths like this. Don’t do that with totally empty columns, otherwise, you’ll get a false sense of how those columns will behave.

Just look at this demo where these four grids have the exact same setup and all that is different is the amount of text in each column.

See the Pen Different Collapse Rates of Different Column Width Values by Chris Coyier (@chriscoyier) on CodePen.

Cool’n’weird.

The post Don’t use empty or low content for your design system grid examples appeared first on CSS-Tricks.

Little Tip: Draw Your Grid in ASCII in Your CSS Comments for Quick Reference

Say you declared a grid like this:

body { display: grid; grid-template-columns: min-content 1fr; grid-template-rows: min-content auto min-content;
}

This depends on content, for sure, but how it’s likely to play out is like this:

+---+-------------+
| | |
| | |
+-----------------+
| | |
| | |
| | |
| | |
| | |
| | |
+-----------------+
| | |
+---+-------------+

That’s really easy to draw out quick in ASCIIFlow Infinity.

Now you want to place elements in that grid, and arguably the easiest way to do that is to specify the grid rows/columns they should start/end at.

/* grid-area: row-start / column-start / row-end / column end */ .logo { grid-area: 1 / 1 / 2 / 2;
} .site-header { grid-area: 1 / 2 / 2 / 3;
} .sidebar-nav { grid-area: 2 / 1 / 3 / 2;
} .main-content { grid-area: 2 / 2 / 3 / 3;
} .site-footer { grid-area: 3 / 1 / 4 / 3;
}

There are other ways to do this. You could use longhand CSS properties. You could name the areas. But say you like doing it this way because it is succinct or whatever. That’s where the ASCII is useful! Leave it in a CSS comment and number the lines.

/* 1 2 3
1 +---+-------------+ | | | | | |
2 +-----------------+ | | | | | | | | | | | | | | | | | |
3 +-----------------+ | | |
4 +---+-------------+
*/

Now you’ve got an visual reference to pick out those grid numbers from.

If you like native apps and wanna get real fancy, there is Monodraw.

The post Little Tip: Draw Your Grid in ASCII in Your CSS Comments for Quick Reference appeared first on CSS-Tricks.

CSS Grid in IE: Faking an Auto-Placement Grid with Gaps

This is the third and final part in a three-part series about using CSS grid safely in Internet Explorer 11 (IE11) without going insane.

In Part 1, I covered some of the common misconceptions that people have about IE11’s native CSS grid implementation. In Part 2, I showed the world how easy it actually is to write IE-friendly CSS grid code.

Today, I’m going step away from CSS grid for a moment to show you a flexbox technique that replicates basic CSS grid auto-placement functionality. This CSS grid replica will even look like a grid-gap has been applied to it. I need to be super clear though: this is not about how to make actual CSS grid auto-placement work in IE.

Article Series:

  1. Debunking Common IE Grid Misconceptions
  2. CSS Grid and the new Autoprefixer
  3. Faking an auto-placement grid with gaps (This Post)

How to make a fake grid with cell gaps

Step 1: HTML

I’ll use this basic HTML as an example:

<div class="grid-wrapper"> <div class="grid"> <div class="grid-cell"></div> <div class="grid-cell"></div> <div class="grid-cell"></div> <div class="grid-cell"></div> <div class="grid-cell"></div> <div class="grid-cell"></div> </div> </div>

Step 2: Border-box box sizing

The first thing that we need to do in the CSS is make sure that all of the boxes are being sized based on border-box rather than content-box. The best way to do that is using the box-sizing: border-box inheritance technique:

html { box-sizing: border-box;
} *, *::before, *::after { box-sizing: inherit;
}

That will be applied globally. If you are working on an an existing project that doesn’t have box-sizing set to border-box, then change html in the snippet to a selector that targets the element you want to turn into a grid.

Step 3: Flex

Next, you will need to turn on some flexbox settings:

.grid { /* Forces equal cell heights */ display: flex; flex-wrap: wrap;
}

Step 4: Widths

Now, set up your column widths. We’ll make ourselves a simple three-column grid:

.grid-cell { /* Sets column count */ width: calc(100% / 3); /* calc() method */ width: 33.33%; /* percentage method */
}

The calc() method allows the column widths to be changed a bit more easily. You state how many columns you want and the browser does the math for you. This is especially handy for when you need a larger number of columns, like 7 or 8. The browser support for calc() is strong but not as strong as a raw percentage value which has been supported by browsers since the dawn of CSS.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
19* 15 4* 10 12 6*

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
6.0-6.1* 46 No 67 67 60

The percentage method has slightly better browser support and can be a bit more stable in IE. If you don’t need to support Opera Mini, I would still recommend going with the calc() method first. Test in IE, and if the layout breaks, first try using 99.999% instead of 100% in the calc function (calc(99.999% / 3)). If that doesn’t work, then try switching to the percentage method. I will be using the calc() method in all of my examples. Note that if you are using a CSS pre-processor like SCSS, you can have the best of both worlds by getting the pre-processor to do the math for you. This comes at the cost of not being as easily able to edit or review the column counts in browser dev tools.

/* Set column count using SCSS */
.grid-cell { width: (100% / 3);
} /* CSS output into the browser */
.grid-cell { width: 33.3333333333%;
}

Let’s give the grid cells some height and an inner box-shadow so that we can see what’s going on. I’m not adding border — I’ll be using that later. 😉

.grid-cell { /* So that we can see the grid cells */ box-shadow: inset 0 0 0 1px #000; height: 100px;
} .grid-wrapper { /* Allows us to see the edges of the grid */ box-shadow: 0 0 10px 2px green;
}

You should now have something that looks like this:

A basic 3 x 2 grid with no gaps

That’s boring though, right? Everyone knows how to do that. Where are these grid gaps I keep talking about? I want my gaps!!!

Step 5: Border

Here’s where we get to the interesting part. Since we set box-sizing to border-box, the 33.33% width now includes the border. What this means is that we can start safely mixing fixed and percentage based units! 😃

.grid { /* Creates an equal outer gap */ padding: 20px 0 0 20px;
} .grid-cell { /* Creates gaps */ border: 0 solid transparent; border-width: 0 20px 20px 0;
}

This results in something that looks like a grid with equal spacing everywhere:

A 3 x 2 grid with equal space between each cell and the outer edges of the grid

To help give you a better idea of what is going on, take a look at the following image:

Color-coded diagram of the grid

The blue area on the top and left sides of the grid is the padding for the .grid element. The yellow outlines show the area that each .grid-cell element takes up. The red areas on the bottom and right sides of each cell are the border for each .grid-cell element.

That might be the look that you actually want. On the other hand, that isn’t what a grid with a grid-gap setting looks like. That is why we have another step.

Step 6: Margin and overflow

In order to get the grid pressing hard up against the edges of its container, we need a bit of help from negative margins and overflow: hidden:

.grid { /* Pulls grid cells hard against edges */ margin: -20px;
} .grid-wrapper { /* Prevents odd margin behavior */ overflow: hidden;
}

We need to apply overflow: hidden to prevent this from happening:

Top and bottom negative margin is ignored if overflow is not hidden

Applying the negative margin and overflow: hidden will get us to this beautiful recreation of basic grid-gap functionality:

A 3 x 2 grid that looks identical to a CSS grid with a gap setting

The top and left padding on the grid is actually optional. You can opt to leave off the padding and change the margin value as shown below if you prefer:

.grid { /* Margin needs to be this if leaving off the top and left .grid padding */ margin: 0 -20px -20px 0;
}

But, hold on! The job isn’t quite over yet. Take a look at what happens if we add a background color to one of the grid cells:

A pink background applied to the top left cell overflows into the grid gap

Not exactly what we want, so there is one more step.

Step 7: background-clip

In order to prevent the grid cell background from bleeding into our fake grid-gap, we need to add background-clip: padding-box to it.

.grid-cell { /* Prevents background bleed */ background-clip: padding-box;
}

Now we have this:

The background bleed has been fixed!

If you have never heard of the background-clip property before, you might be worried about browser support… well don’t be. background-clip has been around since IE9!

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
15 10.5 4 9 12 7

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
7.0-7.1 10 all 4.4 67 60

Step 8: Media Queries!

Most of the time, grids need to be able to change the number of columns that they have as they grow and shrink. Using other methods can be a massive pain. You might have to calculate a bunch of nth-childs so you can remove the right margin or whatever. With this method, you only have to change a single value! 😃

.grid-cell { /* Sets the default column count */ width: calc(100% / 1); /* 1 column */
} @media (min-width: 400px){ .grid-cell { width: calc(100% / 2); /* 2 columns */ }
} @media (min-width: 600px){ .grid-cell { width: calc(100% / 3); /* 3 columns */ }
}
3 x 2 grid with gaps
2 x 3 grid with gaps
1 x 6 grid with gaps

Here’s how it looks when we put it all together:

See the Pen Fake grid by Daniel Tonon (@daniel-tonon) on CodePen.

Ain’t nobody got time for dat!

That’s a lot of work compared to what modern Grid can do in just three lines of CSS! To make the task easier, I created an SCSS-powered mixin I call Gutter Grid. Once Gutter Grid is installed in the project, you can quickly create a three-column grid with 20px gaps using the following SCSS code:

.grid-wrapper { overflow: hidden; /* Need this for the chrome bug */
} .grid { @include grid($cols: 3, $gutter: 20px);
}

You can write it even shorter like this if that feels too verbose:

.grid-wrapper { overflow: hidden;
} .grid { @include grid(3, 20px);
}

Gutter Grid comes pre-built with a few sets of breakpoints so you may not have to write any breakpoints at all if your grid spans the whole page! If you do need custom breakpoints, though, then Gutter Grid lets you easily customize them like so:

// Verbose custom breakpoints
@include grid($cols: 7, $gutter: 20px, $breakpoints: ( 4 : 960px, // At 960px or below, there will be 4 columns 2 : (max, 600px), // You can use mq-scss syntax here as well 1 : 480px,
)); // Short version @include grid(7, 20px, ( 4 : 960px, 2 : 600px, 1 : 480px,
));

As you might have noticed in the example, Gutter Grid also supports the same media query syntax that this thing called mq-scss uses. If you are wondering what that is, well, it’s a Sass mixin that I created that makes writing and managing media queries about a million times easier. Using mq-scss statements to dictate column count allows for very fine control over when the column count changes.

Adding shadows to the grid cells

Since we are working with shadows now, I’ll take the box shadow off of the example image. Our starting grid looks like this now:

A basic 3 x 2 grid with gaps and a green border around the outside

If we try to add an outer box-shadow to each grid cell right now… well it doesn’t look so good:

Adding shadows to the grid cells causes the shadows to be out of alignment

Let’s fix that.

Step 1: New HTML

In order to create nice shadows, we need to add an extra div inside each grid cell. You can’t really use ::before or ::after for this since they are unable to contain HTML content inside of them.

<div class="grid-wrapper"> <div class="grid"> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> <div class="grid-cell"> <div class="grid-cell-inner"></div> </div> </div>
</div>

Step 2: Flex it

Now, we need to make each grid cell a flex container. This will allow the inner part of the grid cell to take up the full height of its parent. We will also need to set the inner element to a width of 100%. This ensures that it will take up the full dimensions of its parent, both horizontally and vertically:

.grid-cell { /* Forces inner to take up full grid cell height */ display: flex;
} .grid-cell-inner { /* Forces inner to take up full grid cell width */ width: 100%;
}

Let’s see what we get if we try adding box shadows to the inner elements:

.grid-cell-inner { box-shadow: 0 0 10px 3px blue;
}
Box shadows appear around grid cells but are getting cut off

That’s much nicer, but it is still not quite there yet. The hidden overflow that we are using to prevent the Chrome bug is getting in the way.

Step 3: Hacky padding

So, we need to allow overflow but still avoid this Chrome bug. The only other safe way I’ve found to do that is with padding. By adding 1px of padding to the top and bottom of the outer grid wrapper element, it will fix the Chrome bug.

.grid-wrapper { /* Prevents odd margin behaviour in Chrome */ padding: 1px 0;
}

This comes at the expense of having an extra 1px of space at the top and bottom of the grid. The image below demonstrates how this ends up looking. The shadows have been lightened to show the 1px gap more clearly.

1px of padding at the top and bottom of the grid

Note: You can avoid the 1px of top padding by opting not to include the top padding gap value on the grid element. The 1px of bottom padding can’t be avoided though.

A border width applied to the outer grid wrapper will also work, so technically I didn’t need to apply the padding to the example above. Most of the time, if we are applying a shadow to grid cells, then we probably don’t want to see a border wrapped around them. The above example was more demonstrating how minor the padding is.

This is what the grid looks like without the outer border:

3 x 2 shadow cell grid
2 x 3 shadow cell grid
1 x 6 shadow cell grid

Here is a Pen showing the final product:

See the Pen Fake grid with shadows by Daniel Tonon (@daniel-tonon) on CodePen.

Gutter Grid shadows

Let’s cover how to add shadows on Gutter Grid cells. You can use the same HTML structure we used in the previous example.

Now, apply this SCSS to create a three-column grid that has a 20px gutter:

.grid { @include grid(3, 20px, $inners: true);
}

This new $inners: true property tells Gutter Grid that the grid cells each have a single child element that needs to take up the full height and width of its parent grid cell.

Instead of using overflow: hidden, use 1px of bottom padding on the wrapper element.

.grid-wrapper { padding-bottom: 1px;
}

Gutter Grid will not output a top outer gutter if it doesn’t need to. This helps avoid issues around the Chrome negative margin bug. After all, if there is no top outer gutter to negate with a faulty negative margin, then there is no bug to worry about. The bottom outer gutter is still a problem, though, and that is why we need the 1px of bottom padding. This 1px of bottom padding tends to be barely noticeable (if at all), so don’t worry about it too much.

Now, add your shadows and you’ve got yourself a Gutter Grid with shadow cells!

.grid-cell-inner { box-shadow: 0 0 10px 3px blue;
}
3 x 2 shadow cell grid

I’ve only scraped the surface of what Gutter Grid can do in this article. Make sure to read the full documentation to learn what else it’s capable of.

We come to the end of our IE grid adventure

I hope you have enjoyed this foray into the world of IE and CSS grid. Make sure to read through Part 1 and Part 2 if you haven’t already. Having read all three articles, you will now be fully equipped to make some truly stunning layouts that look just as good in IE as they do in modern browsers.

If you ever see anyone complaining about not being able to use CSS grid because of IE, you know what to do. Playfully slap them on the head for being so foolish and send them here to get the truth.

Now go forth, my friends, and build some grids! 😃🎉

Article Series:

  1. Debunking Common IE Grid Misconceptions
  2. CSS Grid and the new Autoprefixer
  3. Faking an auto-placement grid with gaps (This Post)

The post CSS Grid in IE: Faking an Auto-Placement Grid with Gaps appeared first on CSS-Tricks.

CSS Grid in IE: CSS Grid and the New Autoprefixer

In Part 1 of this series, I debunked a few misconceptions that many people have around the Internet Explorer (IE) implementation of CSS grid. This article builds on that knowledge. It would be best to go back and read that article first if you haven’t already.

Today I’m going to be tackling the biggest misconception of all: that utilizing the IE implementation of CSS grid is extremely difficult. You can easily use CSS grid in IE right now without having to give it any sort of crappy fallback layout. It really isn’t that hard.

Article Series:

  1. Debunking Common IE Grid Misconceptions
  2. CSS Grid and the new Autoprefixer (This Post)
  3. Faking an auto-placement grid with gaps

Giving IE a crappy fallback layout is a bit of a tough sell to clients. It is especially tough if this is for an intranet where 90% of the users are using IE. If you want IE compatibility, first you need to resign to the fact that you can’t use all of the fancy bells and whistles that can be found in the modern CSS grid spec. Don’t let this get you down though, you would be amazed by how much IE11 can handle, especially if it has some help from Autoprefixer.

Before I get too far into this, you need to know that this isn’t a general “how to use CSS grid” article. This article is for those that understand CSS grid, but are either too afraid or not allowed to use it, thanks to IE.

I’ll be assuming that you already have a good understanding of how to use CSS grid in modern browsers for this article. If you aren’t sure about how to use CSS grid yet, go watch Rachel Andrew’s excellent CSS grid video tutorial series. After that, go play some levels of the browser game Grid Garden to get some hands-on CSS grid experience. Once you understand the basics of how to use CSS grid in modern browsers, come back here and learn how to use it in a way that produces identical results in IE10 and 11.

Setting up Autoprefixer

Before you do anything else, you will want to get Autoprefixer up and running. Autoprefixer is a tool used for automatically adding browser-specific CSS prefixes to your CSS so that you don’t have to. It’s a bit like overview by the creator of Autoprefixer here on CSS Tricks.)

If you have never used Autoprefixer (or any build tool) before, then first install Node on your computer then follow this guide on how to get a basic workflow up and running. The bit in the guide specifically about Autoprefixer is found here. (I recommend the Gulp setup over Grunt if you aren’t sure which to go with.)

If you are already using Autoprefixer in your projects, make sure to update it to the latest version using this command:

npm i autoprefixer@latest -D

Some features used in the latest version of Autoprefixer are not supported in PostCSS version 5. This means that you may also need to update your version of PostCSS to at least version 6. If using Gulp, that means updating gulp-postcss to at least v7.0.0. If using Grunt, you may need to update grunt-postcss to at least v0.9.0.

Once you have an environment up and running, you will need to set the Autoprefixer grid setting to true. Without that setting turned on, Autoprefixer will not be able to do any of the cool stuff that I’m about to show you.

The exact method for turning the grid setting on depends a lot on how you compile your code. If you were using the guide that I linked to earlier, you would have seen this snippet of code:

var processorsArray = [ // snipped for brevity require('autoprefixer')({ browsers: ['last 2 versions', 'ie 6-8', 'Firefox > 20'] })
];

Add grid: true to the options to turn grid prefixing on:

var processorsArray = [ // snipped for brevity require('autoprefixer')({ grid: true, browsers: ['last 2 versions', 'ie 6-8', 'Firefox > 20'] })
];

By the way, the browser settings in the tutorial are pretty outdated and will be outputting far more prefixes than you actually need. Just going with ">1%" will mean that when a browser dies, Autoprefixer will automatically stop writing prefixes for that browser. It bases browser usage on global browser data retrieved from caniuse.com.

So, these are the Autoprefixer settings that you should end up using:

var processorsArray = [ require('autoprefixer')({ grid: true, browsers: ['>1%'] })
];

Now onto the fun stuff! 😃

Autoprefixer has new super powers!

You may have read Rachel Andrew’s article “Should I try to use the IE implementation of CSS Grid Layout?” That article is all about CSS grid and understanding it’s support in IE10 and 11. It’s a great article and very useful for understanding IE’s limitations. Definitely still worth a read if you haven’t already checked it out. Note that it is extremely outdated in terms of its information on Autoprefixer though.

Autoprefixer has come a long way since Rachel wrote her IE11 CSS grid article and Autoprefixer now supports far more CSS grid translations. Take a look at this new, updated version of Rachel’s table based on Autoprefixer version 8.6.4. Note that items in bold represent a change in Autoprefixer support compared to Rachel’s article:

CSS Grid Property IE10 Implementation Autoprefixer? Notes
grid-template-columns -ms-grid-columns Yes
grid-template-rows -ms-grid-rows Yes
grid-template-areas NA Yes Autoprefixer uses this to understand what the grid looks like but does not add any extra properties.
grid-template NA Yes Shorthand for grid-template-columns, grid-template-rows, and grid-template-areas
grid-auto-columns NA No IE doesn’t support auto-placement
grid-auto-rows NA No IE doesn’t support auto-placement
grid-auto-flow NA No IE doesn’t support auto-placement
grid NA No See this GitHub issue as to why this isn’t supported
grid-row-start -ms-grid-row Yes1 Span syntax requires grid-row-end to be defined
grid-column-start -ms-grid-column Yes1 Span syntax requires grid-column-end to be defined
grid-row-end NA Yes1 grid-row-start must be defined
grid-column-end NA Yes1 grid-column-start must be defined
grid-row NA Yes1
grid-column NA Yes1
grid-area NA Yes2 Autoprefixer translates the grid area into column/row coordinates
grid-row-gap NA Yes3 Generates extra rows/columns in IE.
grid-column-gap NA Yes3 Generates extra rows/columns in IE.
grid-gap NA Yes3 Generates extra rows/columns in IE.
NA -ms-grid-column-span Yes Translated from grid-column-end and grid-area.
NA -ms-grid-row-span Yes Translated from grid-row-end and grid-area.
align-self -ms-grid-row-align Yes
justify-self -ms-grid-column-align Yes

Table disclaimers

I will cover these in far more detail later in the article:

  1. Autoprefixer cannot prefix negative integers.
  2. Each grid element must have unique area names.
  3. Autoprefixer only prefixes grid-gap if both grid-template-areas and grid-template-columns have been defined. It also cannot inherit grid-gap through media queries.

grid-template-areas is your new best friend

As you can see from the updated (and much more positive-looking) table, there are a lot of cool new features in Autoprefixer now. The most important of which is its support for grid-template-areas (and by extension grid-template). By supporting grid-template-areas, Autoprefixer now understands exactly what your grid looks like. This paved the way for Autoprefixer to also support (in a limited capacity) grid-gap.

Note that Autoprefixer still does not support the shortcut grid property. This was an intentional design decision that you can learn more about in this GitHub issue. The short story is that the grid property is not only a shortcut for the templating settings but also the auto-placement settings. Since IE can’t do auto-placement and the grid-template property can essentially do anything that the grid property can do (that IE can handle), it was decided that the grid property wasn’t worth supporting.

Back when Rachel wrote her article, this was the sort of grid code you would need to write in order to support IE:

/* IE-friendly source code 26 November 2016 */
/* Code needed to make Autoprefixer work properly */ .grid { display: grid; grid-template-columns: 1fr 10px 1fr; grid-template-rows: 100px 10px 100px;
} .cell-A { grid-column: 1; grid-row: 1;
} .cell-B { grid-column: 3; grid-row: 1;
} .cell-C { grid-column: 1; grid-row: 3;
} .cell-D { grid-column: 3; grid-row: 3;
}

Now, you can write code like this instead:

/* Today’s IE-friendly source code */
/* Autoprefixer can now make this code IE safe */ .grid { display: grid; grid-gap: 10px; grid-template: "a b" 100px "c d" 100px / 1fr 1fr;
} .cell-A { grid-area: a;
} .cell-B { grid-area: b;
} .cell-C { grid-area: c;
} .cell-D { grid-area: d;
}

Autoprefixer will take the above code and translate it into this much more IE-friendly code for you:

/* Autoprefixer’s IE-friendly translation */ .grid { display: -ms-grid; display: grid; grid-gap: 10px; -ms-grid-rows: 100px 10px 100px; -ms-grid-columns: 1fr 10px 1fr; grid-template: "a b" 100px "c d" 100px / 1fr 1fr;
} .cell-A { -ms-grid-row: 1; -ms-grid-column: 1; grid-area: a;
} .cell-B { -ms-grid-row: 1; -ms-grid-column: 3; grid-area: b;
} .cell-C { -ms-grid-row: 3; -ms-grid-column: 1; grid-area: c;
} .cell-D { -ms-grid-row: 3; -ms-grid-column: 3; grid-area: d;
}

Best of all, you can then simply change the grid-template or grid-template-areas property with a media query and Autoprefixer will automatically update all of the grid cell coordinates for you:

/* Changing a grid-template with a media-query */ .grid { display: grid; grid-gap: 10px; grid-template: "a b" 100px "c d" 100px "e f" 100px / 1fr 1fr;
} @media (min-width: 600px){ .grid { /* Autoprefixer 8.6.4 doesn't inherit grid gaps 🙁 */ grid-gap: 10px; grid-template: "a b c" 100px "d e f" 100px / 1fr 1fr 1fr; }
} .cell-A { grid-area: a;
} .cell-B { grid-area: b;
} .cell-C { grid-area: c;
} .cell-D { grid-area: d;
} .cell-E { grid-area: e;
} .cell-F { grid-area: f;
}

The above gets translated into this IE-friendly code:

/* Autoprefixer’s IE-friendly media query translation */ .grid { display: -ms-grid; display: grid; grid-gap: 10px; -ms-grid-rows: 100px 10px 100px 10px 100px; -ms-grid-columns: 1fr 10px 1fr; grid-template: "a b" 100px "c d" 100px "e f" 100px / 1fr 1fr;
} @media (min-width: 600px) { .grid { /* Autoprefixer 8.6.4 doesn't inherit gaps 🙁 */ grid-gap: 10px; -ms-grid-rows: 100px 10px 100px; -ms-grid-columns: 1fr 10px 1fr 10px 1fr; grid-template: "a b c" 100px "d e f" 100px / 1fr 1fr 1fr; }
} .cell-A { -ms-grid-row: 1; -ms-grid-column: 1; grid-area: a;
} .cell-B { -ms-grid-row: 1; -ms-grid-column: 3; grid-area: b;
} .cell-C { -ms-grid-row: 3; -ms-grid-column: 1; grid-area: c;
} .cell-D { -ms-grid-row: 3; -ms-grid-column: 3; grid-area: d;
} .cell-E { -ms-grid-row: 5; -ms-grid-column: 1; grid-area: e;
} .cell-F { -ms-grid-row: 5; -ms-grid-column: 3; grid-area: f;
} @media (min-width: 600px) { .cell-A { -ms-grid-row: 1; -ms-grid-column: 1; } .cell-B { -ms-grid-row: 1; -ms-grid-column: 3; } .cell-C { -ms-grid-row: 1; -ms-grid-column: 5; } .cell-D { -ms-grid-row: 3; -ms-grid-column: 1; } .cell-E { -ms-grid-row: 3; -ms-grid-column: 3; } .cell-F { -ms-grid-row: 3; -ms-grid-column: 5; }
}

The duplicate media query might look a bit ugly but I assure you that this is the best possible way that Autoprefixer can handle the media query translation. The new IE grid cell coordinates could not be placed into the same media query as the grid template definition. Doing so would lead to one of two possible outcomes. One outcome is that the default grid cell positions would override the altered positions stated in the media query. This would cause the media query to have no effect in IE. The other outcome would be for Autoprefixer to shift all of the styles inside the media query (yes, that includes all of the styles that you wrote yourself) to another location in the style sheet, potentially causing horrific CSS specificity issues. You can learn more about the thinking behind this decision in the now closed GitHub issue for it.

Autoprefixer still can’t save you from everything

Even Superman can’t always save everyone and Autoprefixer is no different. While Autoprefixer is able to cut down on a lot of the workload involved in making our grids IE-compatible, it can’t fix everything. It can only translate things that IE can understand. These are the many critical things that you need to be aware of if you don’t want to open the site up in IE one day and have it blow up in your face.

Grid Gap has limited support

As you may have seen in that last example, grid-gap isn’t currently able to be inherited through media queries. If you want to use grid-gap, you will need to duplicate the grid-gap setting across all of the media queries where you define a grid template for that grid. There is an issue open on GitHub about this. Go give it a thumbs up if you want Autoprefixer to support it. Hopefully the issue is fixed soon.

That isn’t the only problem around using grid-gap though. It is only supported by Autoprefixer when both grid-template-areas and grid-template-columns have been defined.

Autoprefixer adds grid-gap support by using grid-template-areas to understand what your grid looks like. It then takes your grid-template-columns and grid-template-rows definitions and injects the grid-gap value between each row and column, creating extra rows and columns in IE.

If you try to use grid-gap on its own without grid-template-areas, Autoprefixer has no way of knowing what cell belongs to what grid. Without that critical knowledge, it cannot safely inject the extra columns and rows that IE needs.

That explains grid-template-areas but why do we also need to define grid-template-columns? Shouldn’t something like this be just as easy for Autoprefixer to translate?

.grid { display: grid; grid-gap: 20px; grid-template-areas: "a b c" "d e f";
} .cell-a { grid-area: a;
} .cell-f { grid-area: f;
}

Rows and columns in CSS grid default to a value of auto so can’t Autoprefixer just add something like -ms-grid-columns: auto 20px auto 20px auto;? It does that for rows, so why can’t it do the same thing for columns?

Well my inquisitive friend, I explained in Part 1 that auto in IE acts a bit differently to auto in modern browsers. When columns are set to auto in IE, they will always shrink down to the value of max-content. Modern grid columns, on the other hand, will expand to 1fr if there are no other fr units being used in that grid template declaration. This discrepancy can cause a massive difference in appearance between the modern and the IE version of a grid. The Autoprefixer team felt that it was too dangerous to make assumptions about this, so they made grid-template-columns a mandatory setting in order for grid-gap to take effect.

So that explains why Autoprefixer doesn’t support grid-gap when grid-template-columns is missing. If auto behaves so differently in IE, then why does Autoprefixer support grid-gap without the user explicitly having to define grid-template-rows? Isn’t that just as bad?

Not really. When you set display: grid; on something, it’s width will grow to the full width of its container. Its height, on the other hand, typically shrinks to the height of its content. Of course this isn’t always the case. There are a number of reasons why a grid might be taller than its content. If the grid is also a flex item and the flex container is taller than the grid, then that would be one reason why the grid might be taller than its content. In general though, if there are no other forces involved, then a grid container will always be the same height as its content.

Since the height of a typical grid is the same height as its content, in most cases, auto in both IE and modern browsers will behave identically to one another. It will only differ in functionality if the height of the grid exceeds the height of the content inside of it. For the best balance between user convenience and browser consistency, the Autoprefixer team made a choice. They decided that supporting a missing grid-template-rows property but not a missing grid-template-columns property was the best way to handle grid-gap support.

No auto-placement! No auto-placement! No auto-placement!

I really can’t say this enough. The most important thing to remember when using CSS grid in IE is that everything must be placed manually. The instant you start thinking about using auto-placement is the instant your site blows up in IE. I have a method for dealing with grids that have an unknown number of cells in them. I’m covering that in Part 3 of this series. The main thing to know right now is that if you want to use CSS grid in an IE-friendly way, you should only ever use it if there are a known number of cells for a known number of rows and columns.

It’s this lack of auto-placement in IE that makes having access to grid areas through Autoprefixer such a blessing. Instead of having to calculate all of the coordinates manually, you can instead name each cell and then let Autoprefixer do the math for you. When using media queries, you only need to redefine the grid template and autoprefixer will recalculate all of the coordinates for you. You rarely have to do any column or row counting. It’s great!

Area names must be unique

The ability to use grid-template-areas is one of Autoprefixer’s greatest strengths, though it has its limits. Autoprefixer does not have any access to the issue open on GitHub that you can add your support to. In the meantime, the easiest way to ensure that each area name is unique is probably adopting a BEM style approach to naming the areas.

.grid-alpha { grid-template-areas: "grid-alpha__delta grid-alpha__echo";
} .grid-beta { grid-template-areas: "grid-beta__echo grid-beta__delta";
} .grid-cell { /* No more conflict 🙂 */ -ms-grid-column: 2; grid-area: grid-alpha__echo;
}

This can be pretty verbose if there are lots of columns and rows. You might want to shorten it down to an abbreviation instead. Of course, the less verbose your area names, the more chance there is of a conflict.

.grid-alpha { grid-template-areas: "ga_delta ga_echo";
} .grid-beta { grid-template-areas: "gb_echo gb_delta";
} .grid-cell { -ms-grid-column: 2; arid-area: ga_echo;
}

There is one major exception. Grid areas in media queries are allowed to be duplicates of other areas as long as the area names defined in the media query are targeted at the same element. Without this exception, it would be impossible to change the grid areas based on screen size. The main thing to remember is that each grid has to have its own set of unique area names that must not be shared with any other grids.

@media (min-width: 600px) { .grid-one { grid-template-areas: "alpha bravo" "alpha charlie"; }
} @media (min-width: 900px) { .grid-one { /* This is fine */ /* It is targeting the same element */ grid-template-areas: "alpha bravo charlie"; }
} @media (min-width: 900px) { /* NOT FINE! */ /* The "alpha" area is being reused on a different element! */ .grid-two { grid-template-areas: "alpha delta"; }
}

Autoprefixer has limited column and row spanning support

There are only two properties in IE’s implementation of CSS grid that will help you span multiple columns. The main one being -ms-grid-column/row-span which tells IE how many columns/rows to span. The other being -ms-grid-column/row which tells IE where to start counting from.

.grid-cell { -ms-grid-column-span: 2; /* number of cells to span */ -ms-grid-column: 1; /* starting cell */
}

In modern browsers, you have access to far more options.

Autoprefixer friendly

Out of the modern ways to span multiple cells, Autoprefixer fully supports the following. Feel free to use any of these methods as much as you like:

Specify a starting line and the number of lines to span (similar to IE):

.grid-cell { grid-column: 1 / span 2;
}

Specify an end line, then span backwards:

.grid-cell { grid-column: span 2 / 3;
}

Specify a starting line and an end line directly:

.grid-cell { grid-column: 1 / 3;
}

Specify only a number of cells to span using grid-column/row-end. Remember that IE can’t do auto-placement though. A starting line will still need to be specified elsewhere in the style sheet:

.grid-cell { /* Make sure you specify a starting line elsewhere */ grid-column-end: span 2;
}

Specify only a starting line:

.grid-cell { /* The short way */ grid-column: 1; /* The more verbose way */ grid-column-start: 1;
}
Autoprefixer unfriendly. Here be dragons!

Now this is where Autoprefixer reaches its limit. The following methods are supported in modern browsers but are not supported by Autoprefixer. This is mainly due to Autoprefixer having no idea what grid the grid cell belongs to since it can only base its decisions on what is in the stylesheet.

Specify a starting line and how many lines from the end of the explicit grid to span:

.grid-cell { grid-column: 1 / -1;
}

Specify both the start and end line from the end of the explicit grid:

.grid-cell { grid-column: -3 / -1;
}

Specify only how many lines to span using the shorthand syntax (issue in GitHub):

.grid-cell { grid-column: span 2;
}

Specify only a backwards span (IE can’t span backwards):

.grid-cell { grid-column-start: span 2;
}

Specify only an end line (IE doesn’t understand end and Autoprefixer doesn’t know where the start is):

.grid-cell { grid-column-end: 3;
}

So, basically avoid counting backwards from the end of the grid and you’ll be fine. 😊

Avoid using line names for now

One of the cool features of modern grids is giving grid templates line names. Instead of using numbers to reference a line, you can give the line a name and reference that instead. Since Autoprefixer supports grid areas, you would think that they would also support line names. Unfortunately, that isn’t the case. As of version 8.6.4, Autoprefixer does not support line names (at the time of writing). Don’t worry though! It’s not that it is impossible to support (at least not entirely), it just hasn’t been a high priority for them. If you love using line names in your grids then let them know about it in the GitHub issue for it. Post your use cases and it will surely increase the priority of the feature. In the meantime, see if you can use grid areas instead for now.

Keep in mind that, if it is going to be implemented, then every line name across your stylesheet would need to be unique. Like with grid areas, Autoprefixer wouldn’t know what line name belongs to what grid. The only way it can tell is if every line name in the stylesheet is unique (excluding media queries).

You still need to test!

IE will behave itself most of the time as long as you follow all of the rules we’ve covered so far. That said, IE can still be a bit unpredictable. Just recently, I made a grid item a vertical flowing flex container and encountered an odd bug in IE11. The column width was set to minmax(min-content, 350px) but IE seemed to treat min-content like max-content in this circumstance. This completely broke the layout. Changing it to minmax(0, 350px) fixed the issue. Just goes to show that IE’s grid implementation isn’t quite perfect.

There are also times when you might accidentally forget to explicitly place grid cells. We build our grids in modern browsers because they have the nice grid development tools (especially Firefox). Modern browsers have auto-placement, though. This means that you might be halfway through building your grid then get called away for a moment. When you return to your desk, you see the layout looking beautiful in your browser, but you completely forget that you haven’t explicitly placed any grid cells yet. You move onto the next thing, blissfully unaware that you have left IE in a completely broken state.

Neither of those issues will reveal themselves until you test your site in IE11. Any time that you get a grid looking good in a modern browser, open it up in IE and double-check that it still looks the way you expect it to.

Autoprefixer control comments

Despite Autoprefixer’s best efforts, there are still some rare occasions when it seems like Autoprefixer is hindering you more than it is helping you. If you ever find yourself in a situation where it would be easier to not have Autoprefixer translating your code, you can turn Autoprefixer off using something called a “control comment.”

autoprefixer: off

This control comment will turn off Autoprefixer translations for the entire CSS block. It will not prefix any styles before or after the point where the comment is made.

/* Input CSS */ .normal-behavior { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .off-behavior { display: grid; /* autoprefixer: off */ grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .normal-behavior-again { display: grid;
}
/* Output CSS */ .normal-behavior { display: -ms-grid; display: grid; -ms-grid-columns: 1fr 1fr; grid-template-columns: 1fr 1fr; -ms-grid-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .off-behavior { display: grid; /* autoprefixer: off */ grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .normal-behavior-again { display: -ms-grid; display: grid;
}

autoprefixer: ignore next

If you are after more of a scalpel than a sledge hammer, the /* autoprefixer: ignore next */ control comment is more for you. “Ignore next” will skip the next CSS declaration rather than ignoring the entire CSS block.

/* Input CSS */ .normal-behavior { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .ignore-next-behavior { display: grid; /* autoprefixer: ignore next */ grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr;
}
/* Output CSS */ .normal-behavior { display: -ms-grid; display: grid; -ms-grid-columns: 1fr 1fr; grid-template-columns: 1fr 1fr; -ms-grid-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
} .ignore-next-behavior { display: -ms-grid; display: grid; /* autoprefixer: ignore next */ grid-template-columns: 1fr 1fr; -ms-grid-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
}

Pre-processor comments

If you are using Sass (or another CSS pre-processor) in your project, do not use the double slash (//) method for writing these comments. Sass will strip those comments out before Autoprefixer has a chance to translate the code.

/* Input SCSS */ .normal-behavior { display: grid;
} .failed-off-behavior { // autoprefixer: off display: grid;
} .successful-off-behavior { /* autoprefixer: off */ display: grid;
}
/* Output CSS */ .normal-behavior { display: -ms-grid; display: grid;
} .failed-off-behavior { display: -ms-grid; display: grid;
} .successful-off-behavior { /* autoprefixer: off */ display: grid;
}

Let’s recap!

So, after all that, here is the list of all the things you need to remember to be an IE11 CSS grid master:

  • Use the latest version of Autoprefixer (npm i autoprefixer@latest -D).
  • Turn on the Autoprefixer grid setting.
  • Do not attempt to use auto-placement, every cell must be placed manually.
  • Use grid-template-areas as your primary method for placing grid cells into position.
  • Use grid-template (not grid) as a shortcut.
  • Don’t use duplicate area names unless they are inside a media query targeting the same element. Also, give this GitHub issue your support if you would like Autoprefixer to warn you when you have used a duplicate area name.
  • You can use grid-gap as long as you define both grid-template-areas and grid-template-columns.
  • grid-gap is currently not inherited through media queries. Go give this GitHub issue a thumbs up if you want to write less grid-gap code.
  • When spanning multiple columns and rows, avoid counting backwards from the end of the grid. Autoprefixer doesn’t understand your grids well enough to supports this.
  • Avoid using line names for now. Give this GitHub issue a thumbs up if you want to start using them.
  • Use control comments /* autoprefixer: off */ and /* autoprefixer: ignore next */ to prevent Autoprefixer from translating certain parts of your style-sheet that are causing problems.
  • Don’t forget to test!

…and from Part 1:

  • IE does have an implicit grid.
  • IE supports repeat functionality.
  • minmax(), min-content and max-content are all natively supported.
  • fit-content() isn’t natively supported but you can work around this with auto and max-width settings.
  • IE auto is not equal to auto in modern browsers.

If you have any questions, or if this really helped you out, let me know in the comments! I’m also @Daniel_Tonon on Twitter. 😁

Up next…

In Part 3, I will be covering how to make a fully responsive flexbox-based grid in IE11. This flexbox technique even replicates grid-gap functionality!

Article Series:

  1. Debunking Common IE Grid Misconceptions
  2. CSS Grid and the new Autoprefixer (This Post)
  3. Faking an auto-placement grid with gaps

The post CSS Grid in IE: CSS Grid and the New Autoprefixer appeared first on CSS-Tricks.

Grid Level 2 and Subgrid

I find the concept of subgrid a little hard to wrap my mind around.

I do understand the idea that we want to use nested semantic markup as we like and have elements participate in one grid so we don’t have to flatten our markup just for layout reasons. But that is largely handled by display: contents;.

Rachel Andrew explains it in a way that finally clicked for me:

I have an item spanning three column tracks of the grid, it is also a Grid Container with three column tracks – however these do not line up with the tracks of the parent…

If the nested grid columns were to be defined as a subgrid, we would use the subgrid value of grid-template-columns on that child element. The child would then use the three column tracks that it spanned, and its children would lay out on those tracks.

It’s not that the parent disappears, it’s that it shares grid lines with the parent so that getting internal elements to line up with everything else happens naturally.

Direct Link to Article — Permalink

The post Grid Level 2 and Subgrid appeared first on CSS-Tricks.

CSS Grid Layout Module Level 2

The second iteration of CSS Grid is already in the works and the public editor’s draft was released last week! While it is by no means the final W3C recommendation, this draft is the start of discussions around big concepts many of us have been wanting to see since the first level was released, including subgrids:

In some cases it might be necessary for the contents of multiple grid items to align to each other. A grid container that is itself a grid item can defer the definition of its rows and columns to its parent grid container, making it a subgrid. In this case, the grid items of the subgrid participate in sizing the grid of the parent grid container, allowing the contents of both grids to align.

The currently defined characters of subgrid items are particularly interesting because they illustrate the differences between a subgrid and its parent grid. For example:

The subgrid is always stretched in both dimensions in its subgridded dimension(s): the align-self/justify-self properties on it are ignored, as are any specified width/height constraints.

In addition to subgrids, aspect-ratio-controlled gutters and conformance are also defined in the draft and worth a read. It’s great to see so much momentum around grids!

Direct Link to Article — Permalink


CSS Grid Layout Module Level 2 is a post from CSS-Tricks

Counting With CSS Counters and CSS Grid

You’ve heard of CSS Grid, I’m sure of that. It would be hard to miss it considering that the whole front-end developer universe has been raving about it for the past year.

Whether you’re new to Grid or have already spent some time with it, we should start this post with a short definition directly from the words of W3C:

Grid Layout is a new layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents. Unlike Flexible Box Layout, which is single-axis–oriented, Grid Layout is optimized for 2-dimensional layouts: those in which alignment of content is desired in both dimensions.

In my own words, CSS Grid is a mesh of invisible horizontal and vertical lines. We arrange elements in the spaces between those lines to create a desired layout. An easier, stable, and standardized way to structure contents in a web page.

Besides the graph paper foundation, CSS Grid also provides the advantage of a layout model that’s source order independent: irrespective of where a grid item is placed in the source code, it can be positioned anywhere in the grid across both the axes on screen. This is very important, not only for when you’d find it troublesome to update HTML while rearranging elements on page but also at times when you’d find certain source placements being restrictive to layouts.

Although we can always move an element to the desired coordinate on screen using other techniques like translate, position, or margin, they’re both harder to code and to update for situations like building a responsive design, compared to true layout mechanisms like CSS Grid.

In this post, we’re going to demonstrate how we can use the source order independence of CSS Grid to solve a layout issue that’s the result of a source order constraint. Specifically, we’re going to look at checkboxes and CSS Counters.

Counting With Checkboxes

If you’ve never used CSS Counters, don’t worry, the concept is pretty simple! We set a counter to count a set of elements at the same DOM level. That counter is incremented in the CSS rules of those individual elements, essentially counting them.

Here’s the code to count checked and unchecked checkboxes:

<input type="checkbox">Checkbox #1<br>
<input type="checkbox">Checkbox #2
<!-- more checkboxes, if we want them --> <div class="total"> <span class="totalChecked"> Total Checked: </span><br> <span class="totalUnChecked"> Total Unchecked: </span>
</div>
::root { counter-reset: checked-sum, unchecked-sum;
} input[type="checkbox"] { counter-increment: unchecked-sum;
} input[type="checkbox"]:checked { counter-increment: checked-sum;
} .totalUnChecked::after { content: counter(unchecked-sum);
} .totalChecked::after { content: counter(checked-sum);
}

In the above code, two counters are set at the root element using the counter-reset property and are incremented at their respective rules, one for checked and the other for unchecked checkboxes, using counter-increment. The values of the counters are then shown as contents of two empty <span>s’ pseudo elements using counter().

Here’s a stripped-down version of what we get with this code:

See the Pen CSS Counter Grid by CSS-Tricks (@css-tricks) on CodePen.

This is pretty cool. We can use it in to-do lists, email inbox interfaces, survey forms, or anywhere where users toggle boxes and will appreciate being shown how many items are checked and how many are unselected. All this with just CSS! Useful, isn’t it?

But the effectiveness of counter() wanes when we realize that an element displaying the total count can only appear after all the elements to be counted in the source code. This is because the browser first needs the chance to count all the elements, before showing the total. Hence, we can’t simply change the markup to place the counters above the checkboxes like this:

<!-- This will not work! -->
<div class="total"> <span class="totalChecked"> Total Checked: </span><br> <span class="totalUnChecked"> Total Unchecked: </span>
</div>
<input type="checkbox">Checkbox #1<br>
<input type="checkbox">Checkbox #2

Then, how else can we get the counters above the checkboxes in our layout? This is where CSS Grid and its layout-rendering powers come into play.

Adding Grid

We’re basically wrapping the previous HTML in a new <div> element that’ll serve as the grid container:

<div class="grid"> <input type=checkbox id="c-1"> <label for="c-1">checkbox #1</label> <input type=checkbox id="c-2"> <label for="c-2">checkbox #2</label> <input type=checkbox id="c-3"> <label for="c-3">checkbox #3</label> <input type=checkbox id="c-4"> <label for="c-4">checkbox #4</label> <input type=checkbox id="c-5"> <label for="c-5">checkbox #5</label> <input type=checkbox id="c-6"> <label for="c-6">checkbox #6</label> <div class=total> <span class="totalChecked"> Total Checked: </span> <span class="totalUnChecked"> Total Unchecked: </span> </div> </div>

And, here is the CSS for our grid:

.grid { display: grid; /* creates the grid */ grid-template-columns: repeat(2, max-content); /* creates two columns on the grid that are sized based on the content they contain */
} .total { grid-row: 1; /* places the counters on the first row */ grid-column: 1 / 3; /* ensures the counters span the full grid width, forcing other content below */
}

This is what we get as a result (with some additional styling):

See the Pen CSS Counter Grid by Preethi (@rpsthecoder) on CodePen.

See that? The counters are now located above the checkboxes!

We defined two columns on the grid element in the CSS, each accommodating its own content to their maximum size.

When we grid-ify an element, its contents (text including) block-ify, meaning they acquire a grid-level box (similar to block-level box) and are automatically placed in the available grid cells.

In the demo above, the counters take up both the grid cells in the first row as specified, and following that, every checkbox resides in the first column and the text after each checkbox stays in the last column.

The checkboxes are forced below the counters without changing the actual source order!

Since we didn’t change the source order, the counter works and we can see the running total count of checked and unchecked checkboxes at the top the same way we did when they were at the bottom. The functionality is left unaffected!

To be honest, there’s a staggering number of ways to code and implement a CSS Grid. You can use grid line numbers, named grid areas, among many other methods. The more you know about them, the easier it gets and the more useful they become. What we covered here is just the tip of the iceberg and you may find other approaches to create a grid that work equally well (or better).


Counting With CSS Counters and CSS Grid is a post from CSS-Tricks

Auto-Sizing Columns in CSS Grid: `auto-fill` vs `auto-fit`

One of the most powerful and convenient CSS Grid features is that, in addition to explicit column sizing, we have the option to repeat-to-fill columns in a Grid, and then auto-place items in them. More specifically, our ability to specify how many columns we want in the grid and then letting the browser handle the responsiveness of those columns for us, showing fewer columns on smaller viewport sizes, and more columns as the screen estate allows for more, without needing to write a single media query to dictate this responsive behavior.

We’re able to do that using just one line of CSS — the one-liner that reminds me of when Dumbledore just waved his wand in Horace’s apartment and “the furniture flew back to its original places; ornaments reformed in midair, feathers zoomed into their cushions; torn books repaired themselves as they landed upon their shelves…”.

This magical, media-query-less responsiveness is achieved using the repeat() function and the auto placement keywords.

Much has been written about this particular one-liner, so I won’t be elaborating on how it works. Tim Wright has a great writeup on this that I recommend reading.

To summarize, the repeat() function allows you to repeat columns as many times as needed. For example, if you’re creating a 12-columns grid, you could write the following one-liner:

.grid { display: grid; /* define the number of grid columns */ grid-template-columns: repeat(12, 1fr);
}

The 1fr is what tells the browser to distribute the space between the columns so that each column equally gets one fraction of that space. That is, they’re all fluid, equal-width columns. And the grid will, in this example, always have 12 columns regardless of how wide it is. This, as you have probably guessed, is not good enough, as the content will be too squished on smaller viewports.

So we need to start by specifying a minimum width for the columns, making sure they don’t get too narrow. We can do that using the minmax() function.

grid-template-columns: repeat( 12, minmax(250px, 1fr) );

But the way CSS Grid works, this will cause overflow in the row. The columns will not wrap into new rows if the viewport width is too narrow to fit them all with the new minimum width requirement, because we’re explicitly telling the browser to repeat the columns 12 times per row.

To achieve wrapping, we can use the auto-fit or auto-fill keywords.

grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );

These keywords tell the browser to handle the column sizing and element wrapping for us, so that the elements will wrap into rows when the width is not large enough to fit them in without any overflow. The fraction unit we used also ensures that, in case the width allows for a fraction of a column to fit but not a full column, that space will instead be distributed over the column or columns that already fit, making sure we aren’t left with any empty space at the end of the row.

At first glace of the names, it might seem like auto-fill and auto-fit are opposites. But in fact, the difference between is quite subtle.

Maybe it seems like you are getting extra space at the end of the column with auto-fit. But when and how?

Let’s take a look at what is really happening under the hood.

Fill or Fit? What’s the difference?

In a recent CSS workshop, I summarized the difference between auto-fill and auto-fit as follows:

auto-fill FILLS the row with as many columns as it can fit. So it creates implicit columns whenever a new column can fit, because it’s trying to FILL the row with as many columns as it can. The newly added columns can and may be empty, but they will still occupy a designated space in the row.

auto-fit FITS the CURRENTLY AVAILABLE columns into the space by expanding them so that they take up any available space. The browser does that after FILLING that extra space with extra columns (as with auto-fill ) and then collapsing the empty ones.

This may sound confusing at first, but it makes a lot more sense when you visualize this behavior. So we’ll be doing exactly that, with the Firefox DevTools’ Grid Inspector helping us visualize the size and position of our Grid items and columns.

Consider the following demo as an example.

See the Pen auto-fill vs auto-fit by Sara Soueidan (@SaraSoueidan) on CodePen.

The columns are defined using the repeat() function and have a minimum width of 100px, and a maximum set to 1fr , so that they would expand and equally share any extra space when it is available. As for the number of columns per row, we’re going to use the auto-placement keywords, so that we let the browser take care of the responsiveness of the grid and will wrap the columns into new rows when needed.

The browser will place and size the columns in the first example using the auto-fill keyword, and it will use auto-fit for the second.

.grid-container--fill { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
} .grid-container--fit { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

Up to a certain point, both auto-fill and auto-fit show identical results.

But they don’t have identical behavior under the hood. It just so happens that they will give the same result up to a certain viewport width.

The point at which these two keywords start exhibiting different behaviors depends on the number and size of columns defined in grid-template-columns, so it will differ from one example to another.

The difference between these two keywords is made apparent when the viewport gets wide enough to fit one (or more) extra column(s) (that) into the row. At that point, the browser is presented with two ways to handle the situation, and how it handles it largely depends on whether or not there is content to be placed into that extra column.

So, when the row can fit a new column, the browser goes like:

  1. “I have some space to fit a new column in there. Do I have any content (i.e. grid items) to go into that extra column? Yes? OK, all good. I’ll add the column into the row, and it will wrap into a new row on smaller viewports.”
  2. In the case where there is no content to place into a new column: “Do I allow this new column to occupy space in the row (and, therefore, affect the position and size of the rest of the rows)? or do I collapse that column and use its space to expand the other columns?”

auto-fill and auto-fit provide the answer to that last question in particular, and dictate how the browser should handle this scenario. To collapse or not to collapse, that is the question. And that is also the answer.
Whether you want it to collapse or not depends on your content, and how you want that content to behave in the context of a responsive design.

Let’s see how this works. To visualize the difference between auto-fill and auto-fit, take a look at the following screen recording. I’m resizing the viewport enough to create horizontal space that’s enough to fit one (or more) column(s) into the row. Remember that these two rows are identical, and have the exact same of content and column number. The only difference in this demo is that I’m using auto-fill for the first one and auto-fit for the second.

Notice what is happening there? If it’s still not clear, the following recording should make it clearer:

auto-fill behavior: “fill that row up! Add as many columns as you can. I don’t care if they’re empty — they should all still show up. If you have enough space to add a column, add it. I don’t care if it’s empty or not, it’s still occupying space in the row as if it were filled (as in: filled with content/grid items).”

While auto-fill fills the row with as many columns as it can, even if those columns are empty, auto-fit behaves a little differently.
auto-fit does, too, fill the row with more columns are the viewport width increases, but the only difference is that the newly added columns (and any column gaps associated with them) are collapsed. The Grid inspector is a fantastic way to visualize this. You’ll notice that columns are being added when you keep your eye on the Grid line numbers, which will increase as the viewport width increases.

auto-fit behavior: “make whatever columns you have fit into the available space. Expand them as much as you need to fit the row size. Empty columns must not occupy any space. Put that space to better use by expanding the filled (as in: filled with content/grid items) columns to fit the available row space.”

A useful tip to remember here is that the columns added in both cases (whether collapsed or not) are not implicit columns — that has specific meaning in the spec. In our case, we are adding/creating columns in the explicit grid in the same way as if we declared you wanted 12 columns, for example. So column number -1 will work to target the end of this grid, which it doesn’t if you are creating columns in the implicit grid. Props to Rachel Andrew for this tip.

Summing Up

The difference between auto-fill and auto-fit for sizing columns is only noticeable when the row is wide enough to fit more columns in it.

If you’re using auto-fit, the content will stretch to fill the entire row width. Whereas with auto-fill, the browser will allow empty columns to occupy space in the row like their non-empty neighbors — they will be allocated a fraction of the space even if they have no grid items in them, thus affecting the size/width of the latter.

Which behavior you want or prefer is completely up to you. I have yet to think of a use case where auto-fill would make more sense than auto-fit. Do you have any use cases? If you do, please feel free to share them in the comments below.


Auto-Sizing Columns in CSS Grid: `auto-fill` vs `auto-fit` is a post from CSS-Tricks

Five Design Fears to Vanquish With CSS Grid

CSS grid, along with a handful of other new CSS properties, are revolutionizing web design. Unfortunately, the industry hasn’t embraced that revolution yet and a lot of it is centered around fear that we can trace back to problems with the current state of CSS grid tutorials.

The majority of them fall into one of two categories:

  1. Re-creating classic web design patterns. Grid is great at replicating classic web design patterns like card grids and “holy grail” pages.
  2. Playing around. Grid is also great for creating fun things like Monopoly boards or video game interfaces.

These types of tutorials are important for new technology. They’re a starting point. Now is the time, as Jen Simmons says, to get out of our ruts. To do that, we must cast off our design fears.

Fear 1: Asymmetry

We’ve been trained in the era of frameworks that symmetric and orderly designs are better. It’s true that for many applications a symmetric design or an orderly grid of items is preferred. Yet, asymmetry has the ability to capture the eye and mind in a way that symmetry never will. Asymmetry is interesting in its disorder. If you’re nervous, you can always start small.

See the Pen Asymmetric Promo Grid by Bryan Robinson (@brob) on CodePen.

In this example, we have a simple promotional space. By using an asymmetric vertical and horizontal layout, we can make a stronger visual match between our icon and our button. This isn’t a large space, but it’s not afraid of using whitespace to draw the user’s eye where we want it to go.

Speaking of whitespace…

Fear 2: Negative Space

As we left the early 2000s, we decided it was OK if users had to scroll. We began introducing whitespace into our designs and most of this fell between rows of content. This made our designs much cleaner, but is vertical whitespace the only valid option?

In this example, the design incorporates negative space to create a sense of exploration through the page. By not using traditional content rows, the user’s eye is given a chance to scan and take things in at a slower pace.

See the Pen Experimental Homepage by Bryan Robinson (@brob) on CodePen.

Fear 3: Punk Rock?

There’s no shortage of design talks focused on the print layouts of the 1970s. It was a time of great stability in design tooling, which allowed creativity to bloom. With that came inspired and avant-garde design work that centered around the punk-rock scene.

So my question is this: Can we be punk rockers in web design?

In this example, the design doesn’t care about your preconceptions. Text overlap is a bug? Nope, it’s a feature. Images shouldn’t compete with each other? Survival of the fittest!

See the Pen Grid Overlap and Punk Rock Meditation by Bryan Robinson (@brob) on CodePen.

As this example asks, is this a good idea? It’s completely up for debate. What I know is this: our tools have matured and become more stable; now is the time for experimentation. Do we want the web to look the same year after year, or do we want to dream up new and exciting patterns?

Fear 4: New Sources of Inspiration

Sources of inspiration shouldn’t cause fear, but they do often cause headaches. Remember, inspiration doesn’t mean a 1:1 translation of a concept.

Punk rock graphic design

I mentioned earlier the amazing designs that came out of the ’70s and ’80s. Here are some links to continue researching punk-rock design:

  • The Art of Punk Posters by Sean O’Hagan
  • The Art of Chaos: Punk Rock’s Timeless Influence on Graphic Design by Simon Martin

Vintage movie graphic design

Studying film in college gave me a great appreciation for vintage movie graphic design. One of my professors once told me: “You should be able to tell the tone and subject of a film by its title cards.”

This is especially true of post-World War II films. Their title sequences and posters are a treasure trove of design ideas for setting a scene.

  • The Graphic Art of Film Title Design Throughout Cinema History by Rebecca Gross
  • Saul Bass on His Approach to Designing Movie Title Sequences by The Academy of Motion Picture Arts & Sciences

Learn how to create graphic design grids

Graphic designers have been using grids for layout for centuries, and there’s a lot of great literature on the creation of these grids:

  • Video: Mark Boulton | Designing Grids | CSS Day 2017
  • Guity Novin’s A History of Graphic Design: Chapter 58, History of Layout Design and Modern Newspapers and Magazines
  • Layout Essentials: 100 Design Principles for Using Grids by Beth Tondreau

Fear 5: Fallbacks

It’s true that Grid has only 74% support in the U.S. (at the time of this writing).

That should not stop you from pushing your designs forward. There are plenty of strategies for starting with support for all browsers and then pushing forward into new patterns.

  • Using CSS Grid: Supporting Browsers Without Grid by Rachel Andrew
  • Video: Progressing Our Layouts by Jen Simmons
  • Falling Forward — Rethinking Progressive Enhancement, Graceful Degradation and Developer Morality by Bryan Robinson

What’s next?

It falls to each of us to push our industry forward. The technology is in place to challenge ourselves to create new and interesting designs. This doesn’t have to be as pointed and intense as some of these examples. It starts by realizing we can do amazing things … or we can stagnate.

How will you push the industry forward?


Five Design Fears to Vanquish With CSS Grid is a post from CSS-Tricks

Calendar with CSS Grid

Here’s a nifty post by Jonathan Snook where he walks us through how to make a calendar interface with CSS Grid and there’s a lot of tricks in here that are worth digging into a little bit more, particularly where Jonathan uses grid-auto-flow: dense which will let Grid take the wheels of a design and try to fill up as much of the allotted space as possible.

As I was digging around, I found a post on Grid’s auto-placement algorithm by Ian Yates which kinda fleshes things out more succinctly. Might come in handy.

Oh, and we have an example of a Grid-based calendar in our ongoing collection of CSS Grid starter templates.

Direct Link to Article — Permalink


Calendar with CSS Grid is a post from CSS-Tricks