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.

The CSS Paint API

The CSS Paint API is extremely exciting, not only for what it is, but what it represents, which is the beginning of a very exciting time for CSS. Let’s go over what it is, why we have it and how to start using it.

What is the CSS Paint API?

The API is just one part of a whole suite of new specifications all under the umbrella of what is known as CSS Houdini. Houdini, in essence, gives developers lower level access to CSS itself. No kidding.

The CSS Paint API specifically allows you to call a paint() function wherever you would normally write a value where an image is expected. A common example is the background-image property, where you might use the url() function to a link to an image file, like this:

area { background-image: url('assets/myimage.jpg');

The CSS Paint API allows you to call the paint() function instead and pass in a paint worklet that you have defined through JavaScript. Think of as a bit of code that allows you to programmatically draw (pretty much) whatever you like. And because it’s JavaScript, you can make it dynamic, too. The API itself is very much like the HTML5 <canvas> API (and we’ll get to how that works in a minute).

This sounds cool, but complicated. I’m already happy using regular images…

That’s great! There’s absolutely nothing wrong with using regular images like you have been doing. Just because something is new and probably cool doesn’t mean we all have to start using it for everything. However, images are static and the idea of generating something dynamic is enticing!

Let’s think about linear-gradient for a moment. It’s extremely powerful. I mean, check these out. But, can you imagine how much less work it would be creating those layered patterns without multiple background images? Not only this, but digging in to the CSS Paint API should also help you understand how these kind of images are generated during runtime, which could be really helpful (and is something we’re about to do).

What about conic-gradient which has no browser support yet…without a polyfill, that is. Harnessing the Paint API would allow you to create a conic gradient and some properties to change it much the same as the actual specification. So, in reality, you would actually be creating your own native polyfill. That’s pretty neat!

Remember, this is all part of the bigger CSS Houdini group of features. Here’s a quote from the CSS Houdini Wiki:

The objective of the CSS-TAG Houdini Task Force (CSS Houdini) is to jointly develop features that explain the “magic” of Styling and Layout on the web.

Sounds nice, right? It is and these new features are aimed at allowing developers to extend the functionality of CSS itself, providing better control, cross-browser support and polyfilling.

The standards process can take a while: from proposing a new CSS feature, to writing a specification, to having the browser vendors implement this new specification. And since developers are often eager to start using a new feature as soon as possible, we have to consider that legacy browsers may not support it and possibly any changes to the specification if it hasn’t been fully implemented — and that’s not to mention the typical nuances of cross-browser implementation. Houdini could go quite a way to help with that, by allowing us to implement browser functionality ourselves while we wait for vendors to catch up.

Philip Walton does a great job of explaining these benefits of Houdini and more in this great article on Smashing Magazine.

You can see how Ana Tudor has already put it to use to create complex animations.

So, can I use it now?

You can! The CSS Paint API is only supported in Chrome 65 at the time of writing, but here’s a support chart that will stay updated over time:

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


Chrome Opera Firefox IE Edge Safari
65 52 No No No No

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
No No No 67 67 No

But, there’s still a ways to go.

Regardless, let’s take a look at how we go about creating the code to use it. I’m going to break this down into three stages. There’s some new JavaScript features we’re going to use along the way, but the code is there for you and we’ll go through each.

Step 1: The CSS

First, we need to name our worklet and call it in the CSS. I’m going to call it awesomePattern, so my CSS would look something like this:

section { background-image: url('fallback.png'); background-image: paint(awesomePattern);

We’re all set up, but nothing is going to happen just yet.

Step 2: The JavaScript

Now, we need to add our paint worklet to our main JavaScript, which is loading another JavaScript file like so:


Still, nothing will happen at this point because it’s within our patternWorklet.js file, where all the work is going to be done.

In patternWorklet.js, we need to register a paint worklet class:

registerPaint('awesomePattern', Shape);

So we call the registerPaint() function and pass what we want to call the paint worklet, in this case awesomePattern, and then a reference to the class we are about to write, in this case Shape. Remember to add this after the class we’re about to define next. Unlike function hoisting in JavaScript, you do need to define classes before you can use them.

Next, we are going to use the ECMAScript2015 classes syntax to write a class that will draw our background for us. Because it is now registered as a paint worklet class, we get some things for free.

class Shape { paint(ctx, geom, properties) { ctx.strokeStyle = 'white'; ctx.lineWidth = 4; ctx.beginPath(); ctx.arc( 200, 200, 50, 0, 2*Math.PI); ctx.stroke(); ctx.closePath(); }

In the paint callback, we have ctx, geom and properties. ctx is the same as a 2D context we would get from a <canvas> element. (Well, almost: a <canvas> element allows the ability to read back pixel data, whereas you can’t with the CSS Paint API.) It allows us to use all the same methods to draw as we would if we were on canvas. In the example above, I am simply drawing a circle with the arc function.

The first two values of the arc function are the X and Y coordinates of where the circle is positioned, in pixels, from the top-left of the element. But, I would like the circle to be central and this is where the geom data comes in handy. It’s actually passing back the PaintSize, which is the size of the area the image would normally fill and we can access width and height information, which is precisely what I need to make the circle central:

See the Pen Simple Circle: CSS Paint API Example by Rumyra (@Rumyra) on CodePen.

Great, but this is a pretty simple example. Let’s switch out the circle for something a little more awesome:

See the Pen Simple Circle: CSS Paint API Example by Rumyra (@Rumyra) on CodePen.

Here, I’ve added a method to the class called drawStar and there’s a whole bunch of canvas functions going on there, that draw the CSS-Tricks logo.”

Step Three: Custom Properties

We can do more! We can harness the power of CSS custom properties (aka variables). We’ve all been really excited by them and this is one of the reasons why.

Let’s say I want to be able to change the size or color of our CSS-Tricks logo? Well we can put those parameters as custom properties in our CSS and access them with the third piece of callback data, properties.

Let’s add a --star-scale property to our CSS, which will eventually make our logo bigger and smaller, and a --star-color property to easily change the color of the logo directly in the CSS.

section { --star-scale: 2; --star-color: hsla(200, 50%, 50%, 1); background-image: paint(awesomePattern)

Back in our paint worklet class, we need to access those custom properties. We do this with the inputProperties method, which gives us access to all CSS properties and their given values:

static get inputProperties() { return ['--star-scale','--star-color']; }

Now, we can access them within the paint method:

const size = parseInt(properties.get('--shape-size').toString());

…and use that value within our code. So, if we change either the --star-scale or --start-color properties within out CSS, it will update the background!

It’s also worth noting that all your usual CSS background properties work as expected, such as background-size and background-repeat. Which is great to know and still really useful!


This is pretty powerful stuff, and not just for custom background images. Imagine a half or a double border on your element. You might normally use the ::before or ::after pseudo-elements, or maybe a cleverly thought-out box-shadow. Well, you could implement that (and more) with the CSS Paint API and the border-image property.

This API really pulls together a lot of cool features, like worklets, ECMAScript2015 classes and canvas. Plus, it gives us the whole interaction layer that comes with JavaScript. You could easily add events to update the custom properties and thus the image itself, like this example from Surma, who harnesses the click event to start updating properties within a requestAnimationFrame function to create an animation every time the user clicks on a button. It even takes the coordinates of the click into account.

This may seem a little convoluted on the face of it, but let’s take a look at some of the other parts of the Houdini suite we’re about to encounter:

  • The CSS Layout API, which should allow us to do something like display: layout('myCustomLayout'), for which the typical example would be a custom masonry type layout, but the scope is a lot more.
  • The CSS Properties and Values API which allows us to specify types for custom properties.
  • The CSS Animation Worklet API, which takes animation processing from the main thread, which should result in silky smooth animations.

So, regardless of whether you’re really interested in this specific new feature or not, it is part of a whole bunch of new technology that will unlock a great deal of power. Watch this space because CSS is about to get even more awesome!

The post The CSS Paint API 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.


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.


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>

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.

Prototyping in the Browser

Prototyping animations and interactions is vital for a number of reasons: they can make your interface feel deceptively fast, they can help focus the user on a specific task, and they can provide a better sense of the current state of your application. Is data being loaded? Is something now unclickable? How long do they have to wait until they can perform an action?

At Gusto, I’ve been working on a lot of tiny interaction details and prototypes lately for these very reasons — sadly there’s not much that I can show you all in detail just yet. But, I think the process of how I’m doing this is far more interesting than what I’m actually working on so that’s what I’m going to share here.

The problem I’ve faced with prototyping animations comes down to the tools because they ultimately feel restrictive to me. Whenever I’ve experimented with them in the past, I feel like one hand is always tied behind my back. It could very well be that I’m not using them correctly, but I feel that none of them really mimic browser behavior quite right and, although I’ve been fascinated to watch tools like Framer, Marvel, Zeplin and Principle gain traction, I don’t think they’re for me. At least not yet anyway.

In my opinion, the best way to prototype a lot of interactions is still with plain ol’ HTML, CSS and (gasp!) a sprinkle of jQuery when I need it.

How I’m prototyping today

With my recent project, I decided to invest a little bit of time into CodePen to help our design team quickly prototype things. Here’s what I built:

See the Pen Gusto Prototype: Header by Robin Rendle (@robinrendle) on CodePen.

No really, that’s it. It’s just a simple prototype that looks like our app.

It’s a pen with all the HTML for the app navigation — and it contains all the CSS, too. This way, a designer at Gusto can fork that pen and start writing HTML and CSS to experiment with a specific bit of Figma and Sketch do a much better job of that. Prototypes like this are mostly useful when figuring out finicky UI interactions like tables, spreadsheets and dropdowns — components that can get complicated real quick.

To make this prototype, I simply copied and pasted all of the HTML and CSS from our web app into a new pen. (In the future, we should probably have a system where we’re always prototyping with the latest up-to-date code from our app but, for now, I think this is a fine starting point.) This pen contains all of the menu and navigation items we need to make it look like the Gusto app. We have a a separate pen for the footer which closes off all the divs that we open up in the header. Lastly, we have one more pen that imports those two other pens like so:

<!-- HEADER -->
[[[]]] <!-- HTML GOES HERE -->
<h1>App Prototype</h1>
<p>You can fork this pen and write all the HTML and CSS you need to prototype interactions and explore ideas right here in your browser.</p> <!-- FOOTER -->

See the Pen Gusto Prototype: Full by Robin Rendle (@robinrendle) on CodePen.

What’s that weird syntax with all the [[[ ]]]? That’s the HTML Include syntax for CodePen. If we put the URL of a pen in between those brackets, CodePen will fetch the code from that pen and place it straight into this new pen. That’s it! Pretty sweet, right?

To wrap things up, I wanted to make a couple of notes about what I’ve learned with this new setup.

Lesson 1: Prototypes should be super easy to share

Ideally, prototypes are easy to share with other designers and engineers, exceptionally fast to get setup, and don’t require prior training or expertise — and Codepen is perfect for that. I like this setup for a bunch of reasons. For one, we don’t have to teach designers CoffeeScript like we have to with Framer and we don’t have to run React or Vue workshops to get them up and running with a complex prototyping app.

Yes, folks do need to learn how HTML and CSS works to make prototypes like this but I think learning the very basics of those two languages is vital for a designer working on the web anyway.

Lesson 2: Bad code is a-okay

Here’s another thing I recently learned while doing prototyping: bad code is okay at this stage. In fact, we should be writing terrible, unforgivable code when prototyping in the browser. We ought to write the sort of CSS and HTML that would keep Harry Roberts up at night because clean, maintainable code gets in the way of the design process when the focus should be on iterating as quickly as possible.

To be quite honest, I don’t care about front-end best practices when I’m making these prototypes — I don’t think about BEM, semantic HTML or even performance. Oh, and I certainly don’t care about the most proficient way to render a React thingamijig.

As long as we ditch all of that prototype code and start from scratch later, and as long as there’s step to break the design into components and ensure that those lego pieces are maintainable, well documented, and highly performant in our production environment, then I believe that writing bad should not only be allowed, but actively encouraged.

This leads to my final takeaway.

Lesson 3: Designers and developers should always translate their code

I reckon that the first time a designer and/or front-end developer writes code, it should never be in a production environment. Having the leeway and freedom to go crazy with the code in a safe environment focuses your attention on the design and making it compatible with a browser’s constraints. After this, you can think about grooming the code from a hot, steaming heap of garbage into lovely, squeaky-clean, production-ready poetry. Translating the static mockups into an interactive prototype is the first step, but it’s vital to have a next step to enforce your code standards.

Does your app use BEM? How should you abstract each of these components into separate files? What do you call all of these new components that you’re introducing into the design system?

I believe all of these questions are easier to answer once you have that interactive prototype. And I would highly recommend that designers and front-end engineers alike experiment making little tools like this. It might feel a little odd at first, but I promise that it will produce much better work in the long run.

The post Prototyping in the Browser appeared first on CSS-Tricks.

The Eleventh Fourth

Holy heck it feels like the last year has flown by! Longtime readers will remember that the fourth of July is CSS-Tricks birthday and we blog it each year. We turned 10 last year, and now we welcome our first palindromic number birthday.

Huge thank you

First, as ever, thank you for being part of CSS-Tricks. However you end up here, we hope that we’re useful to you, know that we’re always trying to be even more useful to you, and know that you make the site possible.

Can we ask you some questions?

The whole point of this survey is to understand you better and use that understanding to make choices that serve you better. That’s it! It’s super helpful to us and totally anonymous.

Take the CSS-Tricks Reader Survey

A new design is coming

Hate to be a tease, as there is nothing to show you yet and no timeline to share, but I suppose this should be of little surprise to you as we’ve never been shy for a bit of a redesign around here. This will be version 17, believe it or not. I mention it in part because of above. We’re asking you questions because you can help inform how the design takes shape.

What’s new in this past year?

What stands out to me is that in the last year we’ve invested way more into CSS-Tricks (literally financially) than ever before. What that means for you is that we’ve brought you way more articles from way more authors than we ever have before. Plus stuff that is higher-budget and longer-form for us, like our new Gutenberg Guide.

We hope the result of that investment is that it makes CSS-Tricks both a more interesting site to subscribe to and read regularly, and adds more referential content for years to come. Articles may come across your path today that are only of passing interest, but become more valuable later should that subject become part of a more active project for you.

It also means a more integrated staff here. We’ve always had a small staff of part-time writers and collaborators, like the venerable Sarah Drasner, who has brought you big stuff like an entire guide to Learning Vue and fascinating insights like how she created a VS Code theme.

Now, notably, we have Geoff Graham as lead editor keeping the site rolling nicely. I’ve gotten to watch Geoff really step into the editor role and become a very strong editor in every way, which is extra challenging on a site like this where that job isn’t just spelling, grammar, readability, formatting and all that, but also very technical. Between Geoff and I, we hope we’re bringing a high level of editorial quality to all our technical posts.

We also have Robin Rendle who produces the newsletter each week, bringing his own voice to that and providing another way to read CSS-Tricks with content unique to it. Robin keeps an eye on our industry quite well, sharing great links and producing his own typography-focused newsletter.

The world of technical writing has exploded.

I don’t think I’m imagining it, there is simply way more technical blogging happening now than there ever has been. My guess is because there are more developers than there ever has been. The world economy is more and more technology focused, so there are massive job opportunities in tech, and education has sprung up to help people get those jobs. So the world has far more educated developers living and loving this world, writing about what they know, and making a name for themselves along the way.

All the classic publications are still around that I immediately think of in this genre, like A List Apart, Smashing Magazine, SitePoint, and Envato’s blogs.

But now we have Medium which is loaded with technical writing. Just look at the JavaScript topic, or huge publications on Medium like freeCodeCamp, UX Planet, and Hacker Noon. freeCodeCamp alone is publishing like 5 articles a day!

How about DEV Community, which, like Medium, has become a hive of technical writing open to anyone. There there are incredibly prolific writers like Flavio Copes who publishes great guides and reference posts literally every day.

It very certainly a good thing for our industry. But since we’re trying to be a business in this atmosphere, it means we need to really stay on our game here and make sure we’re doing the best we can.


I posted this same graph last year, now updated for this year:

I like it because of how zoomed out it is. That’s the entire history of CSS-Tricks traffic in pageviews. Perhaps we’re not growing as fast as the industry is, but we’re growing. That peak in May 2018 is cool to see: it’s the most traffic in a single month in our history. It’s almost a silly statistic, as it’s much more meaningful to know how impactful you are being and how people feel about you, but hey, basic analytics are what we got on a wide scale.

What a wild year of life.

Personal note! Last year in July I got married. Then we sold our house in Milwaukee, Wisconsin and moved to Bend, Oregon where we’re renting a house. We got a brand new business office in Bend. Then we had a baby (Ruby!). Then we bought a new car so we’d have a mountain-worthy 4-wheel drive car that’s super safe. Now we’re looking to close on a new house in Bend. As far as a 12-month period goes, this has been the busiest of my life, not factoring in anything business related at all, which had its own roller coasters.

At Todd Lake in Bend, Oregon

It’s been a wonderful journey, but not without significant stress. I’m living in a whole new world of purpose and worry. Hi.

Speaking of businesses…

Dave Rupert and I are trucking along well past episode 300 now on ShopTalk Show. The ideas come easy and the conversation is as fun and enlightening as it ever was. I consider Dave a mentor, as his broad experience is constantly growing and with it, his perspective. I’m still pretty convinced that podcasts are in the early days of popularity, so it feels good to be still on that train. Gosh I wish we could make time to really redesign that site though. The current one is something I kinda slapped together after we did this big round of cleaning up data on the back end. Now we have great data to work with, but my lame design. Someday!

Most of my time though of course is on CodePen. We have big ideas for what CodePen can become and are always striving to get there as we tend to the lovely place that CodePen already is. We have features of all kinds, from huge to little, coming your way. Hardly a day goes by without us shipping some kind of improvement to CodePen.

CodePen has a podcast too, ya know!

See the Pen Elenium fireworks by JK (@funxer) on CodePen.


I’d love to give a bonus high five to all the sponsors that have generously supported the site. We don’t really sell anything at the moment here at CSS-Tricks, so sponsors entirely make the site possible. I’ve long been a fan of this model. Companies can focus on building the best products and services they can (rather than building an audience), and publications like us can focus on an audience. Then we trade! Companies support us, we can tell you about those companies. Companies that align with our values, of course.

Media Temple has been our long time sponsor and web host. You may have noticed Jetpack sponsorship around here recently, which is quite definitely my favorite WordPress plugin. Those companies power this site!

And a warm welcome to other newcomers like Netlify, HelloSign, Pusher, and An Event Apart.

If your company is interested, here’s more information. We can build custom packages to meet your needs.

What can we do for you?

We have the survey like I mentioned, but I mean more directly. Feel free to comment below or contact us directly.

If your wish was our command, what would you have us do? Is there anything you’d like help learning? A reference guide you wish existed? A resource you’d like to be handed? We’re in the business of making those things happen the best we can for you.

Again, thank you

Whether you ever see this or not, I like writing it. Thanks for all your support. Here’s to another year!

The post The Eleventh Fourth 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

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.

Clearfix: A Lesson in Web Development Evolution

The web community has, for the most part, been a spectacularly open place. As such, a lot of the best development techniques happen right out in the open, on blogs and in forums, evolving as they’re passed around and improved. I thought it might be fun (and fascinating) to actually follow this creative exchange all the way through. To take a look at a popular CSS trick, the clearfix, and find out exactly how a web design technique comes to be.

The clearfix, for those unaware, is a CSS hack that solves a persistent bug that occurs when two floated elements are stacked next to each other. When elements are aligned this way, the parent container ends up with a height of 0, and it can easily wreak havoc on a layout. All you might be trying to do is position a sidebar to the left of your main content block, but the result would be two elements that overlap and collapse on each other. To complicate things further, the bug is inconsistent across browsers. The clearfix was invented to solve all that.

An early illustration of the issue from Position is Everything

But to understand the clearfix, you have to go back even further, to the 2004 and a particular technique called the Holly hack.

2004: The Holly Hack and the origin of Clearfix

The Holly hack is named for its creator, Holly Begevin, a developer and blogger at CommunityMX. The Holly hack combines two different CSS techniques that worked in the days of Netscape Navigator and Internet Explorer (IE) 4 to solve some layout issues. Begevin noticed that if you apply a height of just 1% to each of the floated elements in the above scenario, the problem would actually fix itself (and only because it activated an entirely different bug) in Internet Explorer for Windows.

Unfortunately, the 1% trick didn’t work on a Mac. For that, Begevin added a conditional comment which used a backslash inside of her CSS, which strangely enough, blocked individual CSS rules from IE for Mac in the old days. The result was a CSS trick that looked like this:

/* Hides from IE5-mac \*/
* html .buggybox {height: 1%;}
/* End hide from IE5-mac */

Odd, I know, but it only gets more complicated.

That same year, in May, there were a few more browsers to deal with, and not all of them could be patched with one line of CSS. Tony Aslett posted a new thread to his message board, CSS Creator, proposing a new approach. He called the trick a clearfix because it centered around clearing the floated elements to fix the issue.

Aslett’s approach took advantage of what were, at the time, still very new CSS pseudo-selectors (specifically :after) to automatically clear out two floated elements. There was one pretty massive drawback in Aslett’s first version of the clearfix. Having never heard of the Holly Hack, Aslett’s code required a bit of JavaScript to fix issues that were specifically popping up on IE for Mac. In those days, JavaScript was a relatively untested technology, and relying on it in such a fundamental way was less than ideal.

Thankfully, the web is a place of iteration, and one message board user pointed Aslett in the direction of the aforementioned Holly Hack. By sprinkling in Begevin’s conditional comment, Aslett was able to make his code work in just about every browser with no JavaScript at all.

.floatcontainer:after { content: "."; display: block; height: 0; clear: both; visibility: hidden;
} /* Mark Hadley's fix for IE Mac */ .floatcontainer { display: inline-block;
} /* Hides from IE Mac \*/
* html .floatcontainer {height: 1%;}
/* End Hack */

If you want to pick apart an important slice of web history and innovation, the discussion that followed Aslett’s post about clearfix is a great place to start. One by one, people began to experiment with the new technique, testing it in obscure browsers and devices. When they were done, they’d post their results to the message thread, sometimes alongside a helpful tweak.

For example, the user zulaica pointed out that in Mozilla browsers, the bottom border of floated elements had to be explicitly defined. User pepejeria noticed that you could leave out the dot from content, and user co2 tested the clearfix in the very first version of Apple’s Safari browser. Each time, Aslett would update his code a bit until, after more than a few rapid iterations, the clearfix was ready and, thanks to the community, pretty darn bulletproof.

2006: Clearfix gets an update

But browsers kept on advancing. Some of the more quirky bits of the clearfix code worked because of bugs that were built into older browsers. As browsers patched those bugs, in brand new versions, the clearfix stopped working. When IE 7 came out at the end of 2006, a few adjustments to the technique were needed to make it work.

Fortunately, John “Big John” Gallant was maintaining a page on his blog Position is Everything with an up to date version of the clearfix. After getting some feedback from his readers, Gallant updated his blog to reflect a few new fixes for IE 7 using a new kind of conditional comment that would work inside of Internet Explorer.

<style type="text/css"> .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } </style><!-- main stylesheet ends, CC with new stylesheet below... --> <!--[if IE]>
<style type="text/css"> .clearfix { zoom: 1; /* triggers hasLayout */ } /* Only IE can see inside the conditional comment and read this CSS rule. Don't ever use a normal HTML comment inside the CC or it will close prematurely. */

And once again, users took to their own browsers to test out the latest code to ensure it worked everywhere. And once again, for a time, it did.

2010: Clearfix Reloaded

In fact, this iteration of the clearfix would last until about 2010, when the team at the Yahoo! User Interface Library (YUI) noticed a few issues with the clearfix. The Holly Hack, for instance, was now long gone (IE 5 was but a distance memory), and after switching the box model, margins were handled a bit differently by modern browsers.

But the folks at YUI still needed to line up one element next to another. In fact, the need had only increased, as designers experimented with more advanced grid layouts. In 2010, there were very little options for grid layout, so clearfix had to work. They eventually came up with a few additional tweaks to the CSS ruleset, most notably by taking of advantage of both available pseudo-selectors (:before and :after), to clear out any margins. They posted their new take to their own blog and called it “clearfix reloaded.”

.clearfix:after { content: "."; display: block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1 ;} /* IE < 8 */

2011: The Micro Clearfix

But even when it was published in 2010, clearfix reloaded brought with it some unnecessary baggage from older browsers. The height equals 0 trick wasn’t really a requirement anymore, and in fact, the trick was a lot more reliable when display: table was used instead. People began swapping various variations on the technique on Twitter and on blogs. About a year after the release of clearfix reloaded, developer Nicolas Gallagher compiled these variations into a much more compact version of the hack, which he appropriately labeled the micro clearfix.

After years of back and forth and slight adjustments, the clear fix now required just four CSS rules:

/* * For modern browsers * 1. The space content is one way to avoid an Opera bug when the * contenteditable attribute is included anywhere else in the document. * Otherwise it causes space to appear at the top and bottom of elements * that are clearfixed. * 2. The use of `table` rather than `block` is only necessary if using * `:before` to contain the top-margins of child elements. */
.cf:after { content: " "; /* 1 */ display: table; /* 2 */
} .cf:after { clear: both;
} /* * For IE 6/7 only * Include this rule to trigger hasLayout and contain floats. */
.cf { zoom: 1;

The End of Clearfix?

These days, almost 15 years after it was first proposed, the clearfix is losing a bit of relevance. CSS Grid and Flexbox are filling in the gaps for advanced layout on the web. In January of 2017, Rachel Andrew wrote an article for her blog titled “The end of the clearfix hack?” In it, she describes a way to replace the clearfix hack with a single line of code using a new display mode rule known as flow-root.

.container { display: flow-root;

We are approaching the day when clearfix will no longer be necessary at all.

Even without flow-root, there’s lots of ways to make a grid these days. If you were just starting out on the web, there’d be little reason to even learn about it. That’s a good thing! From the beginning it was always meant as a workaround to make the best of what was available. The irony being that without the dedication and experimentation of the developers who hacked away on the clearfix for so many years, we wouldn’t have the tools today to never have to rely on it again.

Enjoy learning about web history with stories just like this? Jay Hoffmann has a weekly newsletter called The History of the Web you can sign up for here.

The post Clearfix: A Lesson in Web Development Evolution appeared first on CSS-Tricks.

Fitting Text to a Container

There are a number of ways to go about putting some text in a container and having it size itself to fill that container. There are different technologies we can use and different considerations to think about. Let us count the ways.

Magic Number it with viewport units

If you set type with vw (viewport width) units, you can find an exact number where the text pretty closely fits the container and doesn’t break as you resize. I’d call this a magic number.

In this case, font-size: 25.5vw; works down to a 320px viewport, but still will break much lower than that.

See the Pen Fitted Text with Viewport Units by Chris Coyier (@chriscoyier) on CodePen.

This is kind of a less exotic version of fluid typography, which involves more of a sprinkling of viewport units and min/max sizes.


Dave Rupert’s FitText is up for the job. You still need a bit of a magic number to get the sizing just right for any particular job:

See the Pen Fitted Text with FitText by Chris Coyier (@chriscoyier) on CodePen.

FitText without jQuery

If you aren’t using jQuery, there are options. Listed from the repo:

  • non-jQuery FitText from @adactio
  • Angular.js FitText.js from @patrickmarabeas
  • AMP-HTML FitText
  • FitText UMD by @peacechen

Example of the first:

See the Pen Fitted Text with FitText (no jQuery) by Chris Coyier (@chriscoyier) on CodePen.


Swap the words in FitText around and you got yourself textFit! It’s another JavaScript library that adjusts font sizes to fit text into a container. Big caveat here though: textFit is designed for two-dimensions. So you need a width and height on the element for it to do it’s thing.

See the Pen Fitted Text with textFit by Chris Coyier (@chriscoyier) on CodePen.


fitty is more like FitText in that it resizes type to maximize just horizontally, but actually seems to require no magic numbers.

See the Pen Fitted Text with fitty by Chris Coyier (@chriscoyier) on CodePen.


TextFill is jQuery-based and requires a width, height, and a configured maximum font size to work. Here’s the basic demo we’ve been working from:

See the Pen Fitted Text with TextFill by Chris Coyier (@chriscoyier) on CodePen.


FlowType is kind of designed to work on a whole document of text, resizing it all fluidly at once, with minimum and maxium viewport sizes. But you can scope it however you want. You also apply a magic number to get things how you want them.

See the Pen Fitted Text with FlowType by Chris Coyier (@chriscoyier) on CodePen.

Just use SVG

With width: 100% and a viewBox, SVG will be a fullsize box that resizes with an aspect ratio. Pretty neat trick! To set the type, you’ll need some magic numbers to get that viewBox just right and push the text into the right spot — but it’s doable with zero dependencies, just like the viewport units demo.

See the Pen Fitted Text with SVG by Chris Coyier (@chriscoyier) on CodePen.

The post Fitting Text to a Container appeared first on CSS-Tricks.

Empower Through Web Development

As a person with a disability, I appreciate the web and modern-day computing for their many affordances. The web is a great place to work and share and connect. You can make a living, build your dream, and speak your mind.

It’s not easy, though. Beginners struggling with the box model often take to Google in search of guidance (and end up at this very website). More seasoned developers find themselves hopping from framework to framework trying to keep up. We experience plenty of late nights, console logs, and rage quits.

It’s in times like these that I like to remember why I’m doing this thing. And that’s because of the magic of creating. Making websites is empowering because it allows you to shape the world—in ways big and small, public and personal. It’s especially powerful for people with disabilities, who gain influence on the tech that they rely on. And, hey, you can do web stuff for fun and profit.

The magic of craft

I knew I wanted to be a person who makes websites the first time I ever wrote HTML, hit reload, and saw my changes. I felt the power coursing through my veins as I FTP-ed my site to my shiny new web server under my very own domain name. My mind jumped into the future, imagining my vast web empire.

I never got around to making an empire, but I had something most of my friends didn’t—a personal homepage. I don’t care how ugly or weird they might be, I think everyone should have a homepage they made for themselves. I love going to personal web homes—you know, just to check out what they’ve done with the place.

I love that the web can be this artisanal craft. My disability (spinal muscular atrophy) precludes me from practicing many crafts one might pick up. And yet as a child, I watched as my grandfather would take to his workshop and emerge with all sorts of wooden inventions—mostly toys for me, of course. I came to appreciate the focus and dedication he put into it. Regardless of what terrible things were going on in life, he could escape into this wonderful world of creation, systems, and problem-solving. I wanted that too. Years later, I found my craft. What with its quirky boxes, holy wars, and documentation.

But I loved it. I couldn’t get enough. And finally I realized… this can be my life’s work. I can get paid to make things on the internet.

But first, some not great facts about employment

Employment levels of people with disabilities are low, and those who are employed tend to be in low-paying occupations.

— U.S. Department of Labor

The U.S. Department of Labor (DOL) keeps statistics on employment levels for people with disabilities and, let me tell you, they kind of suck. The DOL goes on to say that only a third of working-age people with disabilities were employed, on average, in the 2010-2012 period. In contrast, over two-thirds of people without disabilities were employed in the same period.

This problem affected me personally as I struggled to get a job after college. Fortunately, the web is a great tool for breaking down barriers. With its vast learning resources, free and open source software, and plethora of ways to connect and share, the web makes possible all sorts of employment opportunities. I’m now a designer/developer at Mad Genius and loving it.

I urge anyone—disabled or not—who finds themselves with limited access to more conventional jobs to consider working on the web. Whether you draw, write, design, or code, there’s something here for you. This big web we’re building for everyone should be built by everyone.

We need that thing that you’re going to build

Last fall, I launched A Fine Start, a web service and browser extension for turning your new tab page into a minimal list of links. Some people saw it when Chris mentioned it in an article and it picked up quite a few new users. But what those users don’t know is that A Fine Start began life as an assistive technology.

Because of my extremely weak muscles, I type using a highly customized on-screen keyboard. It’s doable, but tedious, so I use the mouse method of getting things done wherever possible. I could open a new tab and start typing, but I would rather click. As a result, I made Start, a one-file tool that allowed me to save lists of links and get at them quickly when set as my new tab page—no keyboard necessary.

It was fantastic and I realized I needed Start on every computer I used, but I had no way of getting my bookmarks on another device without sticking them in a text file in Dropbox. So, last year, I wrote a backend service, polished the design, made a Chrome extension, and threw my baby out of the nest to see if it would fly. We’ll see.

The point is, there’s something the world needs, waiting to be built. And you are the only one who can build it. The recipe is mediocre ideas, showing up, and persistence. The web needs your perspective. Load up on your caffeinated beverage of choice, roll up your sleeves, and practice your craft. You’ve got the power. Now use it.

The post Empower Through Web Development appeared first on CSS-Tricks.

Vue + TypeScript: A Match Made in Your Code Editor

Vue is so hot right now and I’ve been thinking of doing a serious project with it since quite a while, so when the opportunity popped up, I hopped in. But there was a little problem — one of the requirements of the project was to write it in TypeScript. At first, I was super stressed about how I was going to ever get started on this combo, but vue-cli made it so easy.

I’d be lying if I said this ride was super smooth. There were frustrations, hours of staring at the screen and some fistbumps with my table but after working with Vue + TypeScript for over a month now, I can say it was worth it — and if I had to code another app with Vue, I wouldn’t do it without TypeScript.


This article is about pairing Vue and TypeScript and assumes some basic knowledge of both. If you haven’t had a chance to play with them yet and are curious, Vue has a great guide, and the TypeScript docs are a great place to start.

We need to have vue-cli installed globally, so we can quickly spin up Vue project. Install vue-cli by running the following command in your terminal:

npm install -g @vue/cli

Once we have that installed, we’re good to go. If you don’t have TypeScript installed, we don’t need to do that beforehand, as vue-cli takes care of that when you start a new project and choose TypeScript there.

Getting Started

Now that we have vue-cli installed, all we need to do to get a project with Vue + TypeScript started is to run vue create. While creating a new project, choose TypeScript and we’re good to go.

vue create <app-name>

Here’s the result once our project spins up:

vue-cli also provides us the ability to choose Babel along with TypeScript for polyfills, CSS preprocessors, linter, unit testing libraries (I picked Jest, go Jest!) along with other config. You can even save your choices in a preset, to use it later, for another project.

Here’s a rundown of the handy questions you’ll get asked to configure the project:

One thing I’d like to mention is that vue-cli 3.0 comes with a user interface which makes it even more easy to create a new project. Run vue ui in terminal and vue-cli opens a vue-property-decorator package exposes Vue properties and makes them available to use as decorators. In my application, I ended up using only @Component, @Prop, @Watch but there are others such as @Emit, @Inject and @Model, that make your code much more verbose when used extensively.


Vuex has typings…nuff said! Vuex supports TypeScript to boot and, at first, I didn’t even know it. I started to look for proper ways to combine Vuex with TypeScript and stumbled upon Alex Jover Morales’ course on Vue.js State Management with Vuex and TypeScript. It helped me understand the correct way of managing Vuex state when using TypeScript.

For example:

// actions.ts
import { ActionTree } from 'vuex';
import { RootState, ModuleState } from '@/types'; const actions: ActionTree<ModuleState, RootState> = { // all your actions go here


This is yet another thing that I didn’t know existed when I first started but know wish I had found it sooner. I was creating getters for almost everything, but that didn’t feel right. I started looking for better ways to do this and found an interesting article by Francesco Vitullo which cleared up a few things for me. That’s where I found out about vuex-class which provides decorators for all vuex mappers.

So, now instead of writing a new getter for simply accessing a property in state, I could do this:

import { State,
} from 'vuex-class' @Component
export class MyComp extends Vue { @State(state => stateBar

Development Experience With VS Code

With TypeScript, the coding experience on VS Code is so much better. There is no going back and forth to check what mutation types I declared in mutation-types.ts because VS Code can recognize them and suggest correct ones as I type.

The same goes for modifying state in mutations — with TypeScript, the editor knew what my state structure looks like and suggests correct properties.

If you’re using VS Code, I strongly recommend using the Vetur plugin because it provides Vue tooling and comes with other bells and whistles like syntax highlighting (this works great with Vue single file components) and linting right out of the box.

Final Thoughts

Just like everything else in the JavaScript ecosystem, Vue + TypeScript still has a long way to go. For example, I could not use vuelidate because it doesn’t have typings. But thankfully vee-validate provided a workaround, so I didn’t have to go down the difficult road of writing those myself.

In conclusion, I found the development experience to be much smoother and VS Code is a totally different beast when you work with TypeScript. I don’t really need to sing the praises of Vue — it is very easy to pick up and start building and saves days trying to wrap your head around the inner workings of a framework.

The post Vue + TypeScript: A Match Made in Your Code Editor appeared first on CSS-Tricks.