Developer News

Making CSS Animations Feel More Natural

Css Tricks - Tue, 01/09/2018 - 5:59am

It used to be that designers designed and coders coded. There was no crossover, and that’s the way it was. But with the advent of CSS transitions and animations, those lines are blurring a bit. It’s no longer as simple as the designer dictating the design and the coder transcribing—designers must now know something about code, and coders must know something about design in order to effectively collaborate.

As an example, let’s say a designer asks a developer to make a box bounce. That’s it—no additional instruction. Without some cross-knowledge and a common vocabulary, both sides are a little lost in this communication: the developer doesn’t have enough information to fully realize the designer’s vision, but the designer doesn’t really know what the options are and how to communicate them. With a very basic interpretation, you might end up with something that looks like this:

See the Pen Bouncing Box 1 by Brandon Gregory (@pulpexploder) on CodePen.

Not very exciting. Although, to be fair, this does meet all of the criteria given. We can definitely do better than this, though.

The first thing to look at is the timing function. In the above example, we’re using a linear timing function, which means that the box is constantly moving at the same speed. In some cases, this is desirable; however, in the real world, motion usually doesn’t work like that.

An easy fix is to simply change the timing function to ease. This makes the beginning and ending of each animation a little slower than the middle part, which adds a more natural look to some animations. Here’s the box with the easing function turned on:

See the Pen Bouncing Box 2 by Brandon Gregory (@pulpexploder) on CodePen.

This is a slight improvement, but there’s still a lot of work to be done. The box still looks mechanical and stiff, with the same animation occurring in the same timeframe over and over. Adding a slight delay between bounces adds some visual contrast that seems a little more natural:

See the Pen Bouncing Box 3 by Brandon Gregory (@pulpexploder) on CodePen.

The box now looks like it’s jumping rather than simply moving up and down. There’s a little wind-up and cool-down between jumps that mimics what a live creature might do if given the same instruction. Even though we have no reference for what a jumping box would look like, we all have a pretty good idea of what a jumping creature would look like. Because we know what would happen in nature, by mimicking that, the animation feels more natural. But we can do more to make that wind-up feel a little more weighty.

If you watch cartoons, you’ll notice that natural movements are often exaggerated, creating a caricature of real life. When done well, this can feel just as natural as something in the real world, with the added bonus of infusing a little charm and character into the animation.

At this stage, collaboration between the designer and developer is crucial?—?but many designers may not even be aware that these options exist. It may be up to the developer to pitch this possibility to the designer.

By adding some subtle distortion to the scale of the box, we can add a lot to the animation:

See the Pen Bouncing Box 4 by Brandon Gregory (@pulpexploder) on CodePen.

Now, the box has character. It feels alive. There are many things to tweak, but this is already moving much farther than the original instruction?—?in a very good way!

We’re going to go a step further and add a little rebound at the end of the jump:

See the Pen Bouncing Box 5 by Brandon Gregory (@pulpexploder) on CodePen.

The second bounce is making this feel more alive, but something still seems off. The bounce looks stiff compared to the rest of the animation. We need to add another bit of distortion like we did for the wind-up:

See the Pen Bouncing Box 6 by Brandon Gregory (@pulpexploder) on CodePen.

That subtle distortion at the end makes the rebound seem much more natural. Overall, a huge improvement from our basic linear bounce in the first example.

That right there may be exactly what we’re looking for, but further tweaks to the rate of movement can be made with a custom cubic Bézier curve:

See the Pen Bouncing Box 7 by Brandon Gregory (@pulpexploder) on CodePen.

Without both the designer and the developer aware of basic animation principles and controls, this level of customization is impossible. Really, this article just scratches the surface of both fields. If you’re a web designer or a web developer who works with designers, I’d strongly urge you to read up on both.

For animation principles, The Illusion of Life: Disney Animation by Ollie Johnston and Frank Thomas is a great primer on how to make that caricature of real life seem alive and real. With that common language in place, communication and collaboration between designers and developers becomes much easier.

amzn_assoc_tracking_id = "csstricks-20"; amzn_assoc_ad_mode = "manual"; amzn_assoc_ad_type = "smart"; amzn_assoc_marketplace = "amazon"; amzn_assoc_region = "US"; amzn_assoc_design = "enhanced_links"; amzn_assoc_asins = "0786860707"; amzn_assoc_placement = "adunit"; amzn_assoc_linkid = "26ac1508fd6ec7043cb51eb46b883858";

For the technical controls and variations of CSS animation, the possibilities are nearly endless. Delay and timing are simple to adjust. As mentioned, if you don’t like the out-of-the-box ease timing function, it’s very possible to create your own using a cubic-bezier(). You can also adjust the level of distortion you want to bring the animation closer to or further from reality. The important thing is that both the designer and developer are thinking about these variations rather than blindly taking everything without customization. Shared knowledge and collaboration can make even simple animations into great ones.

More Resources

Making CSS Animations Feel More Natural is a post from CSS-Tricks

WordPress User Survey Data for 2015-2017

Css Tricks - Mon, 01/08/2018 - 10:54am

A grand total of 77,609 responses from WordPress users and professionals collected by Automattic between 2015 and 2017. The stats for 2015 and 2016 have been shared at the annual State of the Word address and 2017 marks the first time they have been published on WordPress News.

A few items that caught my attention at first glance:

  • Between 66% and 75% of WordPress users installed WordPress on their own. In other words, they were savvy enough to do it without the help of a developer. Hosting providers were next up and clocked in at 13-14% of installs.
  • WordPress professionals described their clients as large and enterprise companies only 6-7% of the time. I guess this makes sense if those companies are relying on in-house resourcing, but I still would have pegged this higher.
  • What do users love most about WordPress? It's simple and user-friendly (49-52%). What frustrates them most about it? Plugins and themes (19-28%). Seems like those two would go hand-in-hand to some degree.

I'm not a statistician and have no idea how much the results of these surveys accurately reflect the 26% of all sites on the internet that are powered by WordPress, but it sure is interesting.

Direct Link to ArticlePermalink

WordPress User Survey Data for 2015-2017 is a post from CSS-Tricks

Careful Now

Css Tricks - Mon, 01/08/2018 - 10:52am

Tom Warren's "Chrome is turning into the new Internet Explorer 6" for The Verge has a title that, to us front-end web developers, suggests that Chrome is turning into a browser far behind in technology and replete with tricky bugs. Aside from the occasional offhand generic, "Chrome is getting so bad lately," comments you hear, we know that's not true. Chrome often leads the pack for good web tech.

Instead, it's about another equally concerning danger: developers building sites specifically for Chrome. In theory, that's not really a thing, because if you build a website with web standards (of which there isn't really much of an alternative) it'll work in Chrome like any other modern web browser. But it is a thing if you build the site to somehow block other browsers and only allow Chrome. Warren:

Google has been at the center of a lot of “works best with Chrome” messages we’re starting to see appear on the web. Google Meet, Allo, YouTube TV, Google Earth, and YouTube Studio Beta all block Windows 10’s default browser, Microsoft Edge, from accessing them and they all point users to download Chrome instead. Google Meet, Google Earth, and YouTube TV are also not supported on Firefox with messages to download Chrome.

I wouldn't call it an epidemic but it's not a good trend. Best I can tell, it's server-side UA sniffing that entirely blocks the sites:


If anything, I'd think you'd just let people use the site and display a warning if you're really worried some particular feature might not work. Or even better, fix it. I have no behind-the-scenes knowledge of why they made the choice to block certain browsers, but it's hard to imagine a technical limitation that would force it. And if it is, I'd suggest letting it be very publicly known to incentivize the other browsers to support what is needed, assuming it's an established standard.

Even more concerning than browser-specific websites is seeing browsers ship non-standardized features just because they want them, not behind any vendor prefix or flag. There was a time when web developers would have got out the pitchforks if a browser was doing this, but I sense some complacency seeping in.

These days, the vibe is more centered around complaining about other browsers lack of support for things. For example, one browser ships something, we see one green dot in caniuse, and we lambast the other browsers to catch up. Instead, we might ask, was it a good idea to ship that feature yet?

No modern browser is shipping vendor prefixes anymore since we all ultimately decided that was a bad idea. A side effect of that is that shipping a new feature in CSS or JavaScript is all the riskier. I would think shipping an unprefixed feature to a stable version of the browser would mean the feature is standardized and not going to significantly change. Yet, it's been happening.

In CSS, Chrome shipped motion-* properties, but then that all changed to offset-*, and the old motion-* properties just stopped working. That's more than just annoying, that kind of thing helps developers justify saying, "I just build this site for Chrome, if you wanna use it, use Chrome." Fine for a demo, perhaps, but bad for the web industry as a whole. Again, I have no special insight into why this happens, I'm just a developer looking in from the outside.

Here's another CSS one I just saw the other day. People are excited about text-decoration-skip: ink; because it looks great and helps people. They are using it a lot. But apparently, that's not the correct name for it? It's been changed to text-decoration-skip-ink: auto; and so Chrome 64 is canning text-decoration-skip: ink;. This stuff is hard to keep up with even while actively trying.

Chris Krycho had a take on it recently as well:

Over the past few years, I’ve increasingly seen articles with headlines that run something like, “New Feature Coming To the Web”?—?followed by content which described how Chrome had implemented an experimental new feature. “You’ll be able to use this soon!” has been the promise.

The reality is a bit more complicated. Sometimes, ideas the Chrome team pioneers make their way out to the rest of the browsers and become tools we can all use. Sometimes… they get shelved because none of the other browsers decide to implement them.

Many times, when this latter tack happens, developers grouse about the other browser makers who are “holding the web back.” But there is a fundamental problem in this way of looking at things: Chrome isn’t the standard. The fact that Chrome proposes something, and even the fact that a bunch of developers like it, does not a standard make. Nor does it impose an obligation to other browsers to prioritize it, or even to ship it.

This isn't all to throw Chrome under the bus. I'm a Chrome fan. I'm sure there are examples from all the major vendors in the same vein. I'd just like my two cents to be careful now. The web is the best platform to build for and generally heading in a direction that makes that even truer. The easiest way to screw that up is not being careful with standards.

Careful Now is a post from CSS-Tricks

Tales of a Non-Unicorn: A Story About the Roller Coaster of Job Searching

Css Tricks - Mon, 01/08/2018 - 5:51am

Hey there! It's Lara, author of the infamous"Tales of a Non-Unicorn: A Story About the Trouble with Job Titles and Descriptions" from a couple years back. If you haven't read that original article, I recommend skimming it to give you some context for this one, but I think you'll still find value here even if you don't.

A lot has happened since I wrote that article in 2015, and this follow-up has been in the works for a good six months. I ended up, not with a solution for the job titles conundrum or a manifesto about the importance of HTML and CSS, rather a simple, honest story about my roller coaster ride.

Okay, enough dilly-dally. Let's go!


In the aftermath of the FizzBuzz drama in 2015, I doubled down on my freelance business and did really well. I got a great contract gig with startup in New York refactoring a Haml/Bootstrap situation that paid the bills and then some. I hired an assistant and started the Tackle Box, an online school sort-of-thing where I taught web development and WordPress. I made a little money off that one, too. I spoke at a handful of conferences and meetups, taught a bunch of classes, and generally had the pedal to the metal.

Then I got really, really tired.

I was sick of writing emails, sick of sending invoices, and sick of being on the computer all the damn time. I wanted to go to work and then leave work at work; something that is very hard to do in our industry, and extra difficult when you are your own boss. I enjoyed coding sometimes, but it was all about the billable hour. Why should I write code or be on the computer at all if I'm not being paid for it? This was burnout, that thing that's become a weird, convoluted rite of passage in our industry.

I wanted to shut down Lara Schenck, LLC and be a ski bum. And you know what? I did. It was time for a break, and I took one for about six months.

Ski Bum Sabbatical

I left New York City in August of 2016 and moved back to my family's farm near Pittsburgh. I got a job cleaning horse stalls for $7/hr at the stable where I used to ride when I was a kid. My plan was to gradually ramp down business while I lived rent-free and prepared myself for the simple life. That December, I would be starting work as a bartender at Goldminer's Daughter Lodge in Alta, Utah, a tiny ski town outside of Salt Lake City. Room and board were included in the job; I'd make enough pocket money for booze, and my life would consist of skiing, sleeping, and socializing. No emails.

Just down the winding road from Alta Ski Area.

The simple life was okay for a little bit, but bartending at a 3:2 beer bar and skiing every day wasn't as fulfilling as I'd hoped. I cut the season short and moved to Los Angeles in March with my partner at the time. We had a mutual friend with an open room in Hollywood, and I was starved for city-living. (I have since learned that LA is not the city-living I expected, at all, but that's another conversation.)

Time to Get a Job (for real this time)

I formally announced I was back on the scene, reached out to old clients and people from my New York network, and was even on a podcast out of the gate. None of that translated into much paying work. Luckily, I had a cushion of savings to float me for a few months (Freelancing Rule #1: You must have savings), but my heart just wasn't in the freelance hustle this time. The prospect of negotiating contracts and engaging new leads was nauseating rather than exciting, and the small business website work I did was no longer the challenging and invigorating experience it had been before.

I decided to get a full-time job, for real this time. Once again, I wanted to work on a team and on bigger projects. I was tired of doing everything myself, and I wanted to learn from and share my experience with others. And, you know, a regular paycheck.

I set to work applying for jobs, putting long hours into carefully crafted cover letters. I had several promising interviews, got my hopes way up a couple of times, and received zero job offers. For one particular role, I'd gotten as far as discussing salary requirements and start dates, and was expecting an offer letter within the week. Then, the next week they were all of a sudden no longer hiring. I didn't run into any FizzBuzz, for better or for worse.

I started to question why my designer/developer skillset appeared to hold so little value now when I'd felt so in demand just a year ago. I stubbornly refused to learn React just so I could have it on my resume—I'm great at other important things, why can't people see that?! I wondered whether the five years of self-employment was a hindrance, or was there something fundamentally wrong with how I interviewed? Did I shoot myself in the foot with this whole "non-unicorn" thing in the first place?

These months were a major ego-check. It turns out, full-time jobs aren't something you can just "get." It's just not that easy, for me at least.

The Value of HTML and CSS

Responding to job posts with those carefully crafted cover letters had a very low return on investment so I decided to change my approach. Instead of putting my time into writing said cover letters, I would focus on writing about real things and becoming a better developer, and the jobs would come to me. I launched a well-thought-out redesign of my website, published a Reverse Job Post, and buckled down on my JavaScript studies.

This was right around the time Mandy Michael wrote "Is there any value in people who cannot write JavaScript?" which hit the nail on the head. I wrote a question into ShopTalk show about this phenomenon and mentioned to Chris that I'd love to come on the show and talk about it if they'd like. The next day, Chris invited both Mandy and me to come on the show and hash it out:

HTML and CSS are valuable, but intimate knowledge of them has become more of a specialist role. Perhaps, one can position their skills as HTML, CSS, plus something else (e.g. UI design or WordPress). The nature of products and rapid feature releases deem quality HTML and CSS an afterthought at many companies so at the moment, maybe the demand just isn't there. Perhaps the rise in accessibility awareness, design systems, and time lost debugging bad CSS will change the tide?

The episode was well received; I was obviously not the only one struggling with this issue. I made a Github repository called Front-end Discourse with the intention of gathering and synthesizing opinions and coming up with a plan of action on the job titles front. Chris even wrote about the job titles conundrum here on CSS-Tricks. The momentum was there; this could be my thing!

But then...I let it die.

An Unexpected Twist

A few days after the ShopTalk episode came out, I received this tweet:

Umm...that's a link to a Google job post.

I thought it was a joke at first, but nope, the tweet author sent me an email later that day, and it was the real deal! They'd been referred to me by a benevolent figure in the web industry whom I'd never met. I had a call with them and another member of their team, and it was magical. They told me all about a new team starting within Developer Relations at Google that would be working to improve the "Web Content Ecosystem." Web Content Ecosystem? That's WordPress! And they were recruiting me! Holy sh#t, this actually happens!

This was my dream job, not a front-end designer/developer role. I didn't even know this was a job! I had already been doing this work on my own time for several years: teaching and speaking about WordPress, writing informational blog posts, recording videos, and helping people use WordPress more responsibly. And they would move me to San Francisco! I was not a huge fan of Los Angeles.

Unfortunately, Google doesn't just "give" people have to interview.

Computer Science Bootcamp

Now we have me, the designer who applied for a JS job and failed FizzBuzz, preparing for the Google interview otherwise known as the grandparent of all technical white-boarding interviews. It was time to swallow any feelings I had toward this interviewing style and get to work.

I had three weeks until a "coaching call" that would unofficially determine whether or not I could skip the technical phone screening and jump straight to the day of on-site interviews because, duh, this was meant to be. Luckily, this coincided with a lull in freelance work, which had also been picking up, so for about a week and a half, I put myself through a self-directed computer science bootcamp. On the way, I wrote a bunch of blog posts about what I learned.

Oh, how I longed to write that Tales of a Non-Unicorn: I GOT A JOB AT GOOGLE, F@#KERS!!! follow-up for all those Reddit haters after it was said and done!

The day of the coaching call arrived, and it was fantastic! I was a little slow on the coding question, but it wasn't as hard as I'd thought, I aced the role-related questions, and the interviewer was excellent. I heard back from the recruiter who was coordinating with me, and he said I could go straight to the on-site interviews.

In the meantime, I went to WordCamp US in Nashville where this particular team at Google was a sponsor. I got to meet a few of the folks I'd be working with, and it seemed like such a great fit. This Google interest and being at WordCamp made me question why, at the beginning of my job search, I had seen my knowledge of WordPress as such a secondary skillset. WordPress is everywhere! And its awesome! I mean, sure, it's not that "cool" yet, but mark my words, it will be in the "cool" ranks soon enough.

The Non-Unicorn Interviews at Google

In the week leading up to the interview, I focused on researching the role and beefing up my passion for improving WordPress and helping those who work with it. This was not a software engineering role, after all; in Developer Relations, passion for and knowledge of your subject is more important than knowing binary tree traversal, right?

Google flew me to San Francisco and put me up in a nice hotel. I had a full day of four interviews—usually, it's five, one was canceled—and a long, enjoyable lunch with the folks I'd been in touch with from the get-go. I didn't feel great about my performance in the technical parts of the interviews, but I did my best and my strategy was to come off as a great coworker who knows when to ask for help. When in doubt, I remembered the strong correlation between "hard interview" and "received offer" on Google's Glassdoor profile.

Back in LA, freelance work kept me busy while I waited for a verdict, which wasn't long. I felt relatively zen about the whole thing. Yes, I had my hopes up, but if it didn't work out, I at least had work to pay the bills, and it wasn't going half-bad. I'd been contracting with an agency and learning a lot; it wasn't the small business WordPress sites I'd been building all by myself previously.

The Thursday after my Monday interview, I got a call from my recruiter contact. They were not going to proceed with the approval process at this time. He said I showed some very promising "Google-y" qualities, but my performance in the coding portion of the interviews wasn't strong enough. He said he had it in his calendar to reconnect with me in six months, and that he would keep an eye out for less technical roles that might be a better fit.


Incredibly, I was able to fend off the majority of the anger and the "I'm a failure and I suck at everything" thoughts that go hand-in-hand with rejection, maybe in part because I received such a nice email from one of the people I'd been in touch with throughout the process. He had applied three times before he got a job there—which apparently is not uncommon—and this simply meant I'd be taking a slightly different path. They were all bummed I didn't make it.

This brings us back to the present. I don't feel sour about algorithms or white-boarding interviews...I have another one to get ready for in six months! Unless, of course, another really awesome opportunity comes my way in the meantime. Who knows.

This whole job search has been such a ridiculous roller coaster of hopes slowly going up then crashing down. If there's one thing I've learned, it's that I still don't know where I'll end up, but I'm doing my best and I'll keep doing it until the right thing comes along.


Whew, that was a lot! Thanks for making it this far. A+ for you, reader!


Before I wrap this thing up, I want to make a few observations about this whole job searching process that I hope can help others on their roller coaster ride.

  1. Algorithms and white-boarding interviews aren't necessarily bad. I think they can be implemented badly. The Big Tech Companies are fully aware that they miss out on great candidates because of algorithm questions, but this interviewing strategy is so good at filtering out bad candidates that they keep it around. It sucks for us, but I don't see that changing anytime soon. Plus, I learned a hell of a lot of stuff preparing for it, and it's made me a better developer and better human being.
  2. Write a "Reverse Job Post." I don't recall where I learned about it, but here's mine for reference. Even if no one reads it, it's a great way to figure out what type of job and company you are looking for, and you could totally paste a link to it in the cover letter field for an application and call it a day.
  3. Learn computer science fundamentals. I know we are already inundated with things to learn, so it's hard to preach this, but having context for what the tools we use actually are has helped me a lot. For example, two months ago I would have had a hard time wrapping my mind around GraphQL, but in my interview preparation I learned about graphs and tree data structures, so I was able to understand the concept relatively easily. Cracking the Coding Interview is not a good place to start, BaseCS and the Impostor's Handbook are. Also, stay tuned for some relevant articles here on CSS-Tricks, from yours truly!
  4. Don't spend all of your time on job boards. It's a crapshoot. I think there are great job boards, but in general, no matter how quality the listing, whether or not the position is actually available or accurately represented in the post is a toss-up.
  5. Be vocal. I doubt any of this Google stuff would have happened if I hadn't written into ShopTalk show and asked Chris to have me on the episode. If you have an impulse to write something or have a question or feel the urge to tweet at someone you don't know, do it (but be a good person about it, obviously). The more web people that know you exist, the more likely it is that something will come your way.

Those are some things that helped me, but I still don't have a job, so maybe don't listen to what I say. I don't know. It's an incredibly difficult and demeaning process, and there's no secret sauce that works for everyone. Our industry is a young one, and as far as I'm aware, there is no such thing as a surefire career path in web development.

I hope I don't write another "Tales of a Non-Unicorn" installment. The whole idea of a "unicorn" is bogus, anyway. We are all just people, with different levels of knowledge in different areas, and if you can honestly say you're doing your best then I think that's all you can do.

What I will be writing, however, are some "Computer Science Study Guides" for the self-taught developer, here on CSS-Tricks, and maybe some stuff about how cool WordPress is nowadays. At the very least, "Intro To Algorithms" will be coming at you, soon!

How about you, reader?

Have you been on this roller coaster ride, too? Where did you end up? What advice can you offer to those of us who are still in the midst of our journey?

Tales of a Non-Unicorn: A Story About the Roller Coaster of Job Searching is a post from CSS-Tricks

Monitoring unused CSS by unleashing the raw power of the DevTools Protocol

Css Tricks - Fri, 01/05/2018 - 10:38am

From Johnny's dev blog:

The challenge: Calculate the real percentage of unused CSS

Our goal is to create a script that will measure the percentage of unused CSS of this page. Notice that the user can interact with the page and navigate using the different tabs.

DevTools can be used to measure the amount of unused CSS in the page using the Coverage tab. Notice that the percentage of unused CSS after the page loads is ~55%, but after clicking on each of the tabs, more CSS rules are applied and the percentage drops down to just ~15%.

That's why I'm so skeptical of anything that attempts to measure "unused CSS." This is an incredibly simple demo (all it does is click some tabs) and the amount of unused CSS changes dramatically.

If you are looking for accurate data on how much unused CSS is in your codebase, in an automated fashion, you'll need to visit every single URL on your site and trigger every possible event on every element and continue doing that until things stop changing. Then do that for every possible state a user could be in—in every possible browser.

Here's another incredibly exotic way I've heard of it being done:

  1. Wait a random amount of time after the page loads
  2. Loop through all the selectors in the CSSOM
  3. Put a querySelector on them and see if it finds anything or not
  4. Report those findings back to a central database
  5. Run this for enough time on a random set of visitors (or all visitors) that you're certain is a solid amount of data representing everywhere on your site
  6. Take your set of selectors that never matched anything and add a tiny 1px transparent GIF background image to them
  7. Run that modified CSS for an equal amount of time
  8. Check your server logs to make sure those images were never requested. If they were, you were wrong about that selector being unused, so remove it from the list
  9. And the end of all that, you have a set of selectors in your CSS that are very likely to be unused.

Clever, but highly unlikely that anyone is using either of these methods in a consistent and useful way.

I'm a little scared for tools like Lighthouse that claim to audit your unused CSS telling you to "remove unused rules from stylesheets to reduce unnecessary bytes consumed by network activity." The chances seem dangerously high that someone runs this, finds this so-called unused CSS and deletes it only to discover it wasn't really unused.

Direct Link to ArticlePermalink

Monitoring unused CSS by unleashing the raw power of the DevTools Protocol is a post from CSS-Tricks

`font-size` With All Viewport Units

Css Tricks - Fri, 01/05/2018 - 8:39am

We've covered fluid type a number of times. This page probably covers it in the best detail. It's a little more complicated than simply using a vw unit to set the font-size since that's far too dramatic. Ideally, the font-size is literally fluid between minimum and maximum values.

Someday there will be min-font-size and max-font-size (probably), but until then, our fluid type implementations will probably need to resort to some @media queries to lock those mins/maxes.


Around a year ago Matt Smith documented a technique I had missed. It calculates font-size using a little bit of vw, a little bit of vh, and a little bit of the smaller of the two...

:root { font-size: calc(1vw + 1vh + .5vmin); }

Of course, it depends on the font and what you are doing with it, but it seems to me this tempers the curve such that you might not really need a min and max.

Direct Link to ArticlePermalink

`font-size` With All Viewport Units is a post from CSS-Tricks

A Round-Up of 2017 Round-Ups

Css Tricks - Fri, 01/05/2018 - 5:03am

This week marked the beginning of a new year and with it came a slew of excellent write-ups from folks in our industry reflecting on the year past. We thought it would be nice to compile them together for easy reference. If you know of any others that should be on everyone's radar, please leave it in the comments.

Now on to the round-up of round-ups!

Rachel Andrew

Having been wandering the globe talking about CSS Grid for almost five years, Grid finally shipped in browsers in 2017. This was good, as I didn’t really want to be some kind of CSS vapourware lady. I knew Grid was important the first time I read the initial spec. I had no idea how my championing of the specification would change my life, and allow me to get to work with so many interesting people.

Read More

Geri Coady

One of my biggest achievements this year was the release of my second book, Color Accessibility Workflows, published by A Book Apart. I’m hugely grateful for any opportunity to talk about color and how it can impact people in the digital world, and writing for A Book Apart has long been a dream of mine.

Read More

Monica Dinculescu

You can tell I hate writing year in reviews because this one is really, really late. I tend to hate bragging, and I definitely hate introspective and, in particular, I always think I am underperforming (and that’s fine). However, that’s usually not true, and writing a year in review forces me to see the awesome things I did, so even if I did end up underperforming, at least I can learn from that. That’s the whole point of post-mortems, right?

Read More

Sarah Drasner

This year has been a surreal one for me. I’ve had years that were particularly tough, years that trended more cheerfully, but 2017 was unique and bizarre because I felt an immense guilt in my happiness.

I think this might have been the year I found the most personal happiness, but the giant caveat in everything was watching the world divide, watching racism, sexism and hatred rise, and seeing some real damage that incurred on people’s lives around the world.

Read More

Brad Frost

Throughout 2017, when people asked how I was doing, I’d say “Great…for the things I can control.” 2017 was a rough year at a macro level for everybody, and I found myself coping with the state of the world in a number of different ways. But on a personal level, I had a rewarding year full of a lot of work, a lot of travel, and even some major life changes.

Read More

Geoff Graham

It feels kind of weird to include my own round-up, but whatever.

I've typically set goals for myself at the start of each year and followed up on them somewhere towards the end of the year. Unfortunately, the last time I did that out loud was in 2014. I’ve been pretty quiet about my goals and general life updates since then and it’s certainly not for lack of things to write about. So, I’m giving this whole reflection thing the ol’ college go once again.

Read More

Jeremy Keith

Jeremy published 78 blog posts in 2017 (or 6.5 per month as he calculates it) and noted his personal favorites.

Read More

Zach Leatherman

I had an incredibly productive year of side projects, learning, and blog posts—I can attribute almost all of that rediscovered time and energy to quitting Facebook very early in the year. It’s also been amazing to see my daughter grow and learn—she turned two this year and I really love being a dad. We now have our own secret handshake and it’s my favorite thing.

Read More

Ethan Marcotte

And finally, one of the things I’m most proud of is, well, this little website, which I launched hastily just over a year ago. And over the last entirely-too-eventful year, I’ve surprised myself with just how much it helped to be blogging again. Because while the world’s been not-so-lightly smoldering, it felt—and feels—good to put words in a place where I can write, think, and tinker, a place that isn’t Twitter, a place that’s mine.

Read More

Eric Meyer

While this is not so much a reflection on the past year, Eric did mark the new year with a livestream redesign of his personal website—the first design update in 13 years.

My core goal was to make the site, particularly blog posts, more readable and inviting. I think I achieved that, and I hope you agree. The design should be more responsive-friendly than before, and I think all my flex and grid uses are progressively enhanced. I do still need to better optimize my use of images, something I hope to start working on this week.

Read More

Dave Rupert

My big work task this year was building a Pattern Library and it’s exciting to see that work beginning to roll out. The most gratifying aspect is seeing the ultimate Pattern Library thesis proven out: Speed. Pages load faster, CMS integrations are faster, and we can successfully turn out new production pages within a 1-day turnaround.

Read More

David Walsh

David used the new year to think about and plot upcoming goals.

Every turn of the year is a new opportunity to start over, set goals, and renew optimism that time can heal wounds and drive us to change and achieve. For me 2018 is my most important year in a long time; 2018 needs to serve as a turning point for this blog and my career.

Read More

Trent Walton

Dave, Reagan, and I celebrated our 10th official year as Paravel. In addition to some shorter-term projects, we undertook a large-scale pattern library and front-end update that is rolling out in phases this year. We’ve also enjoyed bringing in 6+ collaborators/teams to assist with projects when the need has arisen. I bet we do more of this in 2018—collaborating with friends has been fun.

Read More


Think we'd leave out our own round-up? Of all the site stats Chris shared in this post, this one nicely summed up the action around here in 2017:

We were on a publishing roll though! We published 595 posts, blowing away last year with only 442, the previous record. We also published 50 pages (i.e. snippets/videos/almanac entries) beating 43 last year. Certainly, we're in favor of quality over quantity, but I think this is a healthy publishing pace when our goal is to be read, in a sense, like a magazine.

Read More

A Round-Up of 2017 Round-Ups is a post from CSS-Tricks

Front-End Performance Checklist

Css Tricks - Thu, 01/04/2018 - 10:01am

Vitaly Friedman swings wide with a massive list of performance considerations. It's a well-considered mix of old tactics (cutting the mustard, progressive enhancement, etc.) and newer considerations (tree shaking, prefetching, etc.). I like the inclusion of a quick wins section since so much can be done for little effort; it's important to do those things before getting buried in more difficult performance tasks.

Speaking of considering performance, Philip Walton recently dug into what interactive actually means, in a world where we throw around acronyms like TTI:

But what exactly does the term “interactivity” mean?

I think most people reading this article probably know what the word “interactivity” means in general. The problem is, in recent years the word has been given a technical meaning (e.g. in the metric “Time to Interactive” or TTI), and unfortunately the specifics of that meaning are rarely explained.

One reason is that the page depends on JavaScript and that JavaScript hasn't downloaded, parsed, and run yet. That reason is well-trod, but there is another one: the "main thread" might be busy doing other stuff. That is a particularly insidious enemy of performance, so definitely read Philip's article to understand more about that.

Also, if you're into front-end checklists, check out David Dias' Front-End Checklist.

Direct Link to ArticlePermalink

Front-End Performance Checklist is a post from CSS-Tricks

26 Fabulous Scripts Fonts

Css Tricks - Thu, 01/04/2018 - 6:24am

(This is a sponsored post.)

Just $9.

They are nicely constructed as well, with stylistic alternates, ligatures, punctuation, extra characters, and multilingual support.

Direct Link to ArticlePermalink

26 Fabulous Scripts Fonts is a post from CSS-Tricks

Fun Times With Sizing Grid Elements

Css Tricks - Thu, 01/04/2018 - 6:24am

Chris showed us a little while back that CSS grid areas and their elements are not necessarily the same size. It's an interesting point because one might assume that putting things into a grid area would make those things occupy the entire space, but grid areas actually reserve the space defined by the grid and set the element's justify-content and align-items properties to a stretch value by default.

So... yes, they are the same size, but not necessarily.

Chris ended his post by asking "who cares?" while indicating no one in particular. The point was much more geared toward calling this out as a starting point for folks who need to align content in the grid.

I'm not sure I have a better answer, but it made me think it would be fun if we could leverage those auto-assigned stretch values to adapt a user interface in interesting ways.

I'm not saying any of these are great use cases. In fact, they may be downright silly. That said, maybe they can be the starting point for other ideas.

Stretching Form Fields

One idea is to add some interaction to form fields. If our <form> is the grid container then we can set text inputs where they start at their default width using the start value and then expanding them to the full width of the container by switching to the stretch value on a :focus state:

.grid__form { display: grid; } .grid__input { justify-self: start; } .grid__input:focus { justify-self: stretch; }

See the Pen CSS Grid: Grid Child Stretch on Focus by Geoff Graham (@geoffgraham) on CodePen.

Then again, we can already do something similar with Flexbox but with the benefit of the flex being an animated property:

See the Pen Flexbox: Child Stretch on Focus by Geoff Graham (@geoffgraham) on CodePen.

I'm honestly not sure where expanding form fields on focus would make for great UX but it's certainly fun to play with.

Curtain Opening Effect Re-Visited

We posted a good ol' fashioned CSS trick last year that uses the checkbox hack to create the effect of a curtain opening to reveal content behind it.

See the Pen OXJMmY by Geoff Graham (@geoffgraham) on CodePen.

That used widths and positioning to move things around on click, but we could have done something similar with Grid. Again, this is less robust because it lacks animation and the does not allow the curtain to fully open, but it does show how we can leverage the stretch, start and end values of a grid element and its sizing to achieve some interesting ideas.

See the Pen CSS Grid Curtain Reveal by Geoff Graham (@geoffgraham) on CodePen.

What Else?

The fact that grid elements are not always the size of the grid area is a nice tip to keep in our back pockets as we develop layouts. I'd bet we can come up with more ideas to take that concept to another level and have fun with it as a group. Share 'em if you have 'em!

Fun Times With Sizing Grid Elements is a post from CSS-Tricks

CodePen’s Most Hearted of 2017

Css Tricks - Wed, 01/03/2018 - 2:26pm

The most fun year-end list there is, if you ask me.

Direct Link to ArticlePermalink

CodePen’s Most Hearted of 2017 is a post from CSS-Tricks

Array Explorer and Object Explorer

Css Tricks - Wed, 01/03/2018 - 9:38am

Sarah made these incredibly handy interactive code reference... thingers.

The idea is perfect. I'm in this position regularly. I know what I have (i.e. an array or an object). I know what I want to do with it (i.e. get an array of all the keys in my object). But I forget the actual method name. These thingers guide you to the right method by letting you tell it what you got and what you wanna do.

Array Explorer

See the Pen Array Explorer by Sarah Drasner (@sdras) on CodePen.

Object Explorer

See the Pen Object Explorer by Sarah Drasner (@sdras) on CodePen.

Array Explorer and Object Explorer is a post from CSS-Tricks

Improving the Accessibility of 24 ways

Css Tricks - Wed, 01/03/2018 - 4:41am

I’ve been thinking recently about the nature of my work and which aspects of it I enjoy the most. In a role that will often straddle the realms of design and development, whether editing copy, evaluating the design of an interface or refactoring code, I've come to realize that my interests lie in the act of review and refinement.

My work on 24 ways is a case in point. Since Drew McLellan asked me to redesign the site in 2013, I’ve stayed on as part of the team, helping to review, edit and format articles. But I’ve also been able to fulfil the desire I expressed upon launching the redesign:

I'm a big believer in iteration and not treating a website as ever being finished. I hope what’s been released this year can act as a foundation, and that the design will evolve in the years to come.

In the intervening years, as tools have improved and best practices have matured, I've tweaked the design and refactored the code, and developed a component library in the process.

The 24 ways home page A Focus on Accessibility

This year I've been listening to people like Laura Kalbag talk about accessibility in terms of universal design, and followed blogs like Heydon Pickering’s Inclusive Components, which covers how to design and implement common interaction patterns with an inclusive mindset. All of a sudden, the thorny subject of accessibility has felt more approachable and less dogmatic.

With all this knowledge digested, I was keen to see how 24 ways would fare when put under the microscope. In this article, I will cover five areas where I was able to make improvements:

  • Page structure
  • Labelling of elements
  • Keyboard navigation
  • Aural experience
  • General usability

Before I start, a note of thanks. After making an initial set of changes, I asked my friend and accessibility expert Francis Storr to review my work. He uncovered a number of additional issues, partly the result of his experience in this area, but also from having tested the site with a range of different assistive tools.

Rethinking Page Structure

The original design had adopted a mobile-first approach. The navigation was deprioritized and placed towards the bottom of the page. To ensure that it could be accessed from the top of the page in non-JavaScript scenarios, I added a skip to navigation link. If JavaScript was available, this link was co-opted to reveal a navigation drawer, which would slide in from the top or right, depending on the width of the viewport. This resulted in the following page structure:

<header class="c-banner">…</header> <a class="c-menu" href="#menu">Jump to menu</a> <main class="c-main">…</main> <nav class="c-navigation" id="menu"> <div class="c-traverse-nav">…</div> <div class="c-navigation__drawer"/>…</div> </nav> <footer class="c-contentinfo">…</footer>

In retrospect, this was problematic in a number of ways:

  • The menu button (.c-menu) was not adjacent to the element it controlled (c-navigation-drawer). Moving focus around the page like this can be confusing, especially if it’s not managed properly.
  • All navigation on the site was grouped together, even though each set of links served a different purpose.
  • The drawer behaviour relied on having a link behave like a button. However, the first rule of ARIA states:

    If you can use a native HTML element or attribute with the semantics and behavior you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so

    Last year, I updated the JavaScript so that this link would be replaced by a button, yet this complexity was a hint that my original solution was sub-optimal.

Here's the structure I arrived at today:

<header class="c-banner"> … <a class="c-banner__skip" href="#main">Skip to content</a> </header> <div class="c-menu"> <button class="c-menu__button">…</button> <div class="c-menu__drawer">…</div> </div> <main class="c-main" id="main">…</main> <nav class="c-traverse-nav">…</nav> <footer class="c-contentinfo">…</footer>

Moving the navigation towards the top of the page meant the button and drawer were now adjacent to each other. The menu button is no longer two-faced; it is and always will be a button.

A downside to this approach is that the navigation can be heard every time you visit a new page. Again, we can use a skip link, but this time one that points to the content block (#main). Rather than hide this focusable element from certain users, it becomes visible on focus.

This structure may be less ideologically pure, but it’s far more pragmatic. This became a recurring theme. Indeed, having given up any hope of the HTML5 outline algorithm ever being supported by browsers, I stopped using h1 for section headings and followed the recommendation that heading ranks should be used to convey document structure instead.

Improving Keyboard Navigation

As the most interactive component on the site, the menu was the unsurprising focus of my review. The design dictates that the navigation drawer should behave like a dialog, an interface pattern that brings with it a number of assumptions. These are described in detail in eBay's MIND pattern, but essentially a dialog draws focus away from other elements on the page and is modal; only elements within it can be operated while it is open.

I had previously cobbled together various bits of JavaScript to handle focusing (cobbling which at various points produced the odd bug such as failing to draw focus to the first element in the dialog), but had neglected to indicate the menu’s role. Having fixed these issues (adding role='dialog' when the menu is open), Francis pointed out that screen readers could still access links outside the dialog when it was open. In macOS VoiceOver for example, pressing CTRL + OPT + CMD + L to navigate links within the menu, would in fact announce every link on the page.

The solution was to mark everything outside the dialog as "inert". Rob Dodson describes this in more detail in his video Accessible Modal Dialogs. Implementing this can be a little bit fiddly, but a proposal to introduce an inert attribute would make this easier to manage. In the meantime, the proposal provides a polyfill so you can use this feature today.

I’ve found that by thinking about an interface in terms of common interaction patterns, and how they should operate in order to be widely understood, has helped me avoid complexity, and write more robust code. In fact, stepping into the world of accessibility has uncovered a wealth of useful resources, with well-written JavaScript examples a plenty. Given my difficult relationship with the web’s programming language, these have proven invaluable.

Properly Labelling Elements

A good amount of accessibility comes down to labelling things that rely on visual appearance alone to convey meaning. Much like the alt attribute allows us to describe images, aria-label (and its relations) extend this ability to other elements.

Navigation component that allows users to move between articles in a series.

Here is the markup I was using in the navigation element that allows users to traverse previous and next articles within a series:

<div class="c-traverse-nav"> <a rel="prev" href="/2016/we-need-to-talk-about-technical-debt/" data-sequence-title="We Need to Talk About Technical Debt"> <svg width="20" height="20" viewBox="0 0 200 200" role="img"> <path d="M50 100l85 85 7-7-78-78 78-78-7-7"/> </svg> <span class="u-hidden">Previous article</span> </a> <a rel="next" href="/2016/what-the-heck-is-inclusive-design/" data-sequence-title="What the Heck Is Inclusive Design?"> <span class="u-hidden">Next article</span> <svg width="20" height="20" viewBox="0 0 200 200" role="img"> <path d="M150 100l-85 85-7-7 78-78-78-78 7-7"/> </svg> </a> </div>

While I had provided text content for these links, this component still had a number of issues:

  • No indication was given as to the role these links play and their relationship to each other.
  • Using role='img' on the SVG icons, but not providing any accessible names, was akin to including images without alt attributes.
  • Useful information, in this case the title of the previous and next article, was hidden within a data- attribute. This attribute was used in the stylesheet to add content that is shown in animated ‘flaps’ that appear on hover:
.c-traverse-nav a[rel=prev]:hover::after { content: 'Previous: \A' attr(data-sequence-title); } .c-traverse-nav a[rel=next]:hover::after { content: 'Next: \A' attr(data-sequence-title); }

Meaningful content in CSS? That should have been a red flag. I revised this component as follows:

<nav class="c-traverse-nav" aria-label="Articles"> <a rel="prev" href="/2016/what-the-heck-is-inclusive-design/" aria-label="Previous: We Need to Talk About Technical Debt"> <svg width="20" height="20" viewBox="0 0 200 200" focusable="false" aria-hidden="true"> <path d="M50 100l85 85 7-7-78-78 78-78-7-7"/> </svg> </a> <a rel="next" href="/2016/what-the-heck-is-inclusive-design/" aria-label="Next: What the Heck Is Inclusive Design?"> <svg width="20" height="20" viewBox="0 0 200 200" focusable="false" aria-hidden="true"> <path d="M150 100l-85 85-7-7 78-78-78-78 7-7"/> </svg> </a> </nav>

The first thing I did was give this set of links a label. I originally choose Articles navigation. However, in testing VoiceOver would announce: navigation, Articles navigation. As the nav element already describes the role, we need only provide additional information about the type of navigation this is.

Secondly, on the advice of Francis, I added focusable='false' to all inline SVG markup. This is due to a bug in IE11 where SVGs are keyboard focusable by default.

Regarding the labelling of the SVG icons, I had two choices. I could either move the hidden text content to these icons using aria-label, or remove them from the accessibility tree entirely using aria-hidden. In considering the second option, I realised I could merge the hidden text with that in the data- attribute, and use this combined information within an aria-label attribute. All of a sudden, my CSS became much simpler:

.c-traverse-nav a:hover::after { content: attr(aria-label); }

Accessible markup is useful markup.

Considering the Aural Experience

Navigating the site using a screen reader lead to me making a few other small changes as well. For example, a few links on the site include a right-pointing arrow, a visual flourish created using the following CSS:

.c-continue::after { content: ' \203A'; /* Single Right-Pointing Angle Quotation Mark */ }

However, screen-readers typically announce generated content. When these links were read out, you’d hear nonsense like this:

link, more articles by drew single right-pointing angle quotation mark.

Adding speak: none had no effect (CSS aural properties have little support). However, I could create a similar arrow using CSS borders:

.c-continue::after { display: inline-block; vertical-align: middle; height: 0.375em; width: 0.375em; border: 0.1875em solid; border-color: currentColor currentColor transparent transparent; transform: rotate(45deg); content: ''; } Continue links before and after improvements. While they look similar, the revised design sounds much better.

I also made improvements to the styling of author names in article summaries. Originally, these were distinguished from the rest of the excerpt by styling them as uppercase text. Francis pointed out that some screen readers will spell out uppercase letters (regardless of whether they appear in the HTML or have been altered by CSS) if they don’t spell a known word. For example VoiceOver and NVDA have trouble with Chris Coyier's surname, so his name would be read aloud as Chris C-O-Y-I-E-R. The simple fix was to distinguish names using emboldened text instead.

If I'm honest, I’ve been somewhat arrogant in the past, thinking that by using semantic markup and progressive enhancement, I needn’t worry too much about accessibility. While using the right elements, and considering an interface not only in visual terms is important, this is the absolute bare minimum. An understanding of different assistive technologies, and willingness to test with them, is just as important.

Reviewing General Usability

Thinking about accessibility led to me improve overall usability, too.

For this years set of articles, we no longer link to author's websites from article excerpts. This historical holdover was poorly resolved previously; if you happened to click on the author’s name you would be taken to their website, not the article as you would expect. We also included comment counts that were linked to the comment section on the article page (which itself linked to a separate comments page). Madness!

Now, each article has one link; to the article. A home page that once involved tabbing through 24×3 links, is now less noisy and much easier to navigate for everyone.

Other refinements included ensuring the site is responsive in terms of height, as well as width, ensuring the navigation menu can be dismissed when you click outside of it, and a review of overall performance. These might not be considered accessibility improvements, but I’m not so sure. To suggest this would be to think accessibility is an entirely separate concern. In fact, making changes that benefit one set of users will typically benefit all.

Creating something new will always attract attention and admiration, but there’s an under-celebrated nobility in improving what already exists. While not all changes may be visual, they can have just as much impact. I know that, had we decided to redesign the site this year, many of these improvements would not have been made. Hopefully, this overview will encourage you to look at your own projects and think about similar changes you might make.

Having a growing awareness of the issues, and expanding your knowledge of the tools available is an essential requirement of working on the web. However, don’t keep that knowledge saved up for the future; if you can, go back and fix your older projects too.

Improving the Accessibility of 24 ways is a post from CSS-Tricks

You are what you document

Css Tricks - Tue, 01/02/2018 - 11:42am

There are so many little gems in this piece by Yevgeniy Brikman all about documentation. He digs into a lot more than simply documenting code though and focuses on how we can document every phase of our work, from design to process and beyond.

Here’s my favorite lines that made me sit back and shout “Wahoo!”:

When a developer uses your code, they are really learning a new language, so choose the words in it wisely.

...programs must be written for people to read, and only incidentally for machines to execute.

I like how Yevgeniy suggests that there are kinda two different mindsets that we have to get into when writing code: one for making the dang thing work in the first place, and another for explaining how and why we did a specific way. There’s context-switching that takes place between those different stages of work.

Anyway, when seen in this light, documentation could be much more than a nice-to-have. Instead, it might just be 50% of the work.

Direct Link to ArticlePermalink

You are what you document is a post from CSS-Tricks

Additive Animation with the Web Animations API

Css Tricks - Tue, 01/02/2018 - 5:37am

These features have not landed in any stable browsers at the time of writing. However, everything discussed is already in Firefox Nightly by default and key parts are in Chrome Canary (with the Experimental Web Platform Features flag enabled), so I recommend using one of those browsers (when reading this article) to see as many of the features in action as possible.

Regardless your preferred method of animation on the web, there will be times that you need to animate the same property in separate animations. Maybe you have a hover effect that scales an image and a click event that triggers a translate — both affecting the transform. By default, those animations do not know anything about the other, and only one will visually be applied (since they are affecting the same CSS property and the other value will be overridden).

element.animate({ transform: ['translateY(0)', 'translateY(10px)'] }, 1000); /* This will completely override the previous animation */ element.animate({ transform: ['scale(1)', 'scale(1.15)'] }, 1500);

The second animation in this Web Animations API example is the only one that would be visually rendered in this example as both animations play at the same time and it was the last one defined.

Sometimes we even have grander ideas where we want a foundational animation and then based on some user interaction change in state we smoothly modify the animation a bit midway without affecting its existing duration, keyframes, or easing. CSS Animations and the current Web Animations API in stable browsers today cannot do this out of the box.

A New Option

The Web Animations specification introduces the composite property (and the related iterationComposite). The default composite is 'replace' and has the behavior we have had for years now where an actively animating property's value simply replaces any previously set value — either from a rule set or another animation.

The 'add' value is where things change from the previous norms.

element.animate({ transform: ['scale(1)', 'scale(1.5)'] }, { duration: 1000, fill: 'both' }); element.animate({ transform: ['rotate(0deg)', 'rotate(180deg)'] }, { duration: 1500, fill: 'both', composite: 'add' });

Now both animations will be seen as the browser on the fly figures out the appropriate transformation at a given point in the element's timeline accounting for both transformations. In our examples, the easing is 'linear' by default and the animations start at the same time, so we can break out what the effective transform is at any given point. Such as:

  • 0ms: scale(1) rotate(0deg)
  • 500ms: scale(1.25) rotate(60deg) (halfway through first animation, 1/3 through second)
  • 1000ms: scale(1.5) rotate(120deg) (end of first, 2/3 through second)
  • 1500ms: scale(1.5) rotate(180deg) (end of second)

See the Pen Animation Composite by Dan Wilson (@danwilson) on CodePen.

So Let's Get Creative

An individual animation does not just consist of a start state and end state — it can have its own easing, iteration count, duration, and more keyframes in the middle. While an element is mid animation you can throw an additional transformation on it with its own timing options.

See the Pen Add more transform animations by Dan Wilson (@danwilson) on CodePen.

This example lets you apply multiple animations on the same element, all affecting the transform property. To keep from going all out in this example, we limit each animation to a single transformation function at a time (such as only a scale), starting at a default value (such as scale(1) or translateX(0)), and ending at a reasonable random value on that same transformation function, repeated infinitely. The next animation will affect another single function with its own randomized duration and easing.

element.animate(getTransform(), //e.g. { transform: ['rotate(0deg), 'rotate(45deg)'] } { duration: getDuration(), //between 1000 and 6000ms iterations: Infinity, composite: 'add', easing: getEasing() //one of two options });

When each animation starts, the browser will effectively find where it is in its previously applied animations and start a new rotation animation with the specified timing options. Even if there is already a rotation going in the opposite direction, the browser will do the math to figure out how much a rotation needs to happen.
Since each animation has its own timing options, you are unlikely to see the exact same motion repeated in this example once you have added a few. This gives the animation a fresh feel as you watch it.

Since each animation in our example starts at the default value (0 for translations and 1 for scaling) we get a smooth start. If we instead had keyframes such as { transform: ['scale(.5)', 'scale(.8)'] } we would get a jump because the didn't have this scale before and all of a sudden starts its animation at half scale.

How are values added?

Transformation values follow the syntax of in the spec, and if you add a transformation you are appending to a list.

For transform animations A, B, and C the resulting computed transform value will be [current value in A] [current value in B] [current value in C]. For example, assume the following three animations:

element.animate({ transform: ['translateX(0)', 'translateX(10px)'] }, 1000); element.animate({ transform: ['translateY(0)', 'translateY(-20px)'] }, { duration:1000, composite: 'add' }); element.animate({ transform: ['translateX(0)', 'translateX(300px)'] }, { duration:1000, composite: 'add' });

Each animation runs for 1 second with a linear easing, so halfway through the animations the resulting transform would have the value translateX(5px) translateY(-10px) translateX(150px). Easings, durations, delays, and more will all affect the value as you go along.

Transforms are not the only thing we can animate, however. Filters (hue-rotate(), blur(), etc) follow a similar pattern where the items are appended to a filter list.

Some properties use a number as a value, such as opacity. Here the numbers will add up to a single sum.

element.animate({ opacity: [0, .1] }, 1000); element.animate({ opacity: [0, .2] }, { duration:1000, composite: 'add' }); element.animate({ opacity: [0, .4] }, { duration:1000, composite: 'add' });

Since each animation again is 1s in duration with a linear easing, we can calculate the resulting value at any point in that animation.

  • 0ms: opacity: 0 (0 + 0 + 0)
  • 500ms: opacity: .35 (.05 + .1 + .2)
  • 1000ms: opacity: .7 (.1 + .2 + .4)

As such, you won't be seeing much if you have several animations that include the value 1 as a keyframe. That is a max value for its visual state, so adding up to values beyond that will look the same as if it were just a 1.

See the Pen Add more opacity animations by Dan Wilson (@danwilson) on CodePen.

Similar to opacity and other properties that accept number values, properties that accept lengths, percentages, or colors will also sum to a single result value. With colors, you must remember they also have a max value, too (whether a max of 255 in rgb() or 100% for saturation/lightness in hsl()), so your result could max out to a white. With lengths, you can switch between units (such as px to vmin) as though it is inside a calc().

For more details, the specification outlines the different types of animation and how the result is calculated.

Working with Fill Modes

When you are not doing an infinite animation (whether you are using a composite or not) by default the animation will not keep its end state as the animation ends. The fill property allows us to change that behavior. If you want to have a smooth transition when you add a finite animation, you likely will want a fill mode of either forwards or both to make sure the end state remains.

See the Pen Spiral: Composite Add + Fill Forwards by Dan Wilson (@danwilson) on CodePen.

This example has an animation with a spiral path by specifying a rotation and a translation. There are two buttons that add new one second animations with an additional small translation. Since they specify fill: 'forwards' each additional translation effectively remains part of the transform list. The expanding (or shrinking) spiral adapts smoothly with each translation adjustment because it is an additive animation from translateX(0) to a new amount and remains at that new amount.

Accumulating animations

The new composite option has a third value — 'accumulate'. It is conceptually in line with 'add' except certain types of animations will behave differently. Keeping with our transform, let's start with a new example using 'add' and then discuss how 'accumulate' is different.

element.animate({ transform: ['translateX(0)', 'translateX(20px)'] }, { duration: 1000, composite: 'add' }); element.animate({ transform: ['translateX(0)', 'translateX(30px)'] }, { duration: 1000, composite: 'add' }); element.animate({ transform: ['scale(1)', 'scale(.5)'] }, { duration: 1000, composite: 'add' });

At the 1 second mark (the end of the animations), the effective value will be:

transform: translateX(20px) translateX(30px) scale(.5)

Which will visually push an element to the right 50px and then scale it down to half width and half height.

If each animation had been using 'accumulate' instead, then the result would be:

transform: translateX(50px) scale(.5)

Which will visually push an element to the right 50px and then scale it down to half width and half height.

No need for a double take, the visual results are in fact the exact same — so how is 'accumulate' any different?

Technically when accumulating a transform animation we are no longer always appending to a list. If a transformation function already exists (such as the translateX() in our example) we will not append the value when we start our second animation. Instead, the inner values (i.e. the length values) will be added and placed in the existing function.

If our visual results are the same, why does the option to accumulate inner values exist?

In the case of transform, order of the list of functions matters. The transformation translateX(20px) translateX(30px) scale(.5) is different than translateX(20px) scale(.5) translateX(30px) because each function affects the coordinate system of the functions that follow it. When you do a scale(.5) in the middle, the latter functions will also happen at the half scale. Therefore with this example the translateX(30px) will visually render as a 15px translation to the right.

See the Pen Visual Reference: Transform Coordinate Systems by Dan Wilson (@danwilson) on CodePen.

Therefore, with accumulation we can have an order that is different then when we always append the values to the list.

Accumulating for Each Iteration

I mentioned before that there is also a new related iterationComposite property. It provides the ability to do some of the behaviors we have already discussed except on a single animation from one iteration to the next.

Unlike composite, this property only has two valid values: 'replace' (the default behavior you already know and love) and 'accumulate'. With 'accumulate' values follow the already discussed accumulation process for lists (as with transform) or are added together for number based properties like opacity.

As a starting example, the visual result for the following two animations would be identical:

intervals.animate([{ transform: `rotate(0deg) translateX(0vmin)`, opacity: 0 }, { transform: `rotate(50deg) translateX(2vmin)`, opacity: .5 }], { duration: 2000, iterations: 2, fill: 'forwards', iterationComposite: 'accumulate' }); intervals2.animate([{ transform: `rotate(0deg) translateX(0vmin)`, opacity: 0 },{ transform: `rotate(100deg) translateX(4vmin)`, opacity: 1 }], { duration: 4000, iterations: 1, fill: 'forwards', iterationComposite: 'replace' //default value });

The first animation is only bumping up its opacity by .5, rotating 50 degrees, and moving 2vmin for 2000 milliseconds. It has our new iterationComposite value and is set to run for 2 iterations. Therefore, when the animation ends, it will have run for 2 * 2000ms and reached an opacity of 1 (2 * .5), rotated 100 degrees (2 * 50deg) and translated 4vmin (2 * 2vmin).

See the Pen Spiral with WAAPI iterationComposite by Dan Wilson (@danwilson) on CodePen.

Great! We just used a new property that is supported in only Firefox Nightly to recreate what we can already do with the Web Animations API (or CSS)!
The more interesting aspects of iterationComposite come into play when you combine it with other items in the Web Animations spec that are coming soon (and also already in Firefox Nightly).

Setting New Effect Options

The Web Animations API as it stands in stable browsers today is largely on par with CSS Animations with some added niceties like a playbackRate option and the ability to jump/seek to different points. However, the Animation object is gaining the ability to update the effect and timing options on already running animations.

See the Pen WAAPI iterationComposite & composite by Dan Wilson (@danwilson) on CodePen.

Here we have an element with two animations affecting the transform property and relying on composite: 'add' — one that makes the element move across the screen horizontally and one moving it vertically in a staggered manner. The end state is a little higher on the screen than the start state of this second animation, and with iterationComposite: 'accumulate' it keeps getting higher and higher. After eight iterations the animation finishes and reverses itself for another eight iterations back down to the bottom of the screen where the process begins again.

We can change how far up the screen the animation goes by changing the number of iterations on the fly. These animations are playing indefinitely, but you can change the dropdown to a different iteration count in the middle of the animation. If you are, for example, going from seven iterations to nine and you are seeing the sixth iteration currently, your animation keeps running as though nothing has changed. However, you will see that instead of starting a reverse after that next (seventh) iteration, it will continue for two more. You can also swap in new keyframes, and the animation timing will remain unchanged.

animation.effect.timing.iterations = 4; animation.effect.setKeyframes([ { transform: 'scale(1)' }, { transform: 'scale(1.2)' } ]);

Modifying animations midway may not be something you will use every day, but since it is something new at the browser level we will be learning of its possibilities as the functionality becomes more widely available. Changing iteration counts could be handy for a game when a user get a bonus round and gameplay continues longer than originally intended. Different keyframes can make sense when a user goes from some error state to a success state.

Where do we go from here?

The new composite options and the ability to change timing options and keyframes open new doors for reactive and choreographed animations. There is also an ongoing discussion in the CSS Working Group about adding this functionality to CSS, even beyond the context of animations — affecting the cascade in a new way. We have time before any of this will land in a stable major browser, but it is exciting to see new options coming and even more exciting to be able to experiment with them today.

Additive Animation with the Web Animations API is a post from CSS-Tricks

Thank You (2017 Edition)

Css Tricks - Mon, 01/01/2018 - 6:12am

As 2017 comes to a close, as we do each year, let's take a numbers-based glance back at CSS-Tricks. And more importantly, tip our collective hat to all y'all that come here and read the site.

We really do think of the site as somewhere you come and read. While a lot of people's experience with CSS-Tricks is a place that shows up in search results to find the answer to some web design/dev question (and that's awesome), another way to experience the site is to read it like a magazine. We publish an article (or a couple) nearly every day, from a variety of authors, with the hope that it's interesting and exposes us all to new ideas.

According to Google Analytics, which we've had installed and reported from anonymously since day 1 around here, we had 75 million pageviews this year. Very little of CSS-Tricks makes use of any kind of "single page app" type tech, so that's pretty accurate to people visiting and clicking around. It's down from 77 million last year. I'd like to think that's because of ad blockers, which often block Google Analytics, are up in usage for the visitors of CSS-Tricks, but it's just as likely we're just down a smidge this year. Sessions are also down a smidge at 54 million but Users steady at 21 million.

We were on a publishing roll though! We published 595 posts, blowing away last year with only 442, the previous record. We also published 50 pages (i.e. snippets/videos/almanac entries) beating 43 last year. Certainly, we're in favor of quality over quantity, but I think this is a healthy publishing pace when our goal is to be read, in a sense, like a magazine. That has been more clear to me this year. We produce content with complementary goals and one of those goals is that of a magazine. We hope the site is worth reading day after day and week after week. The other is that the content lasts and is referenceable for many years to come. Hopefully thinking of things that way can be a guiding light, balancing news and reference content, while avoiding stuff that is neither.

I always wished there was an easy way to figure out what the most popular articles published that year were, but I still don't have a great way to do that. The top 10 is dominated by our big guides, things like our Guides to Grid, Flexbox, SVG, and centering.

Those top 10 make up about 15% of total traffic, which is a massive slice, but that leaves 85% of traffic as part of the "long tail". That's a satisfying thought when you're in it for the long haul as we are. Not every article is a huge top 10 smash hit, but does contribute to the long tail which is a much bigger slice collectively anyway.

For the last bunch of months, we've been using Algolia for search. My plan only has 7 days of analytics retention, which isn't enough data to expose major trends. In looking at a week of data though, you can see some surprising top terms like React, SVG, grid, flexbox, font, border... Another thing that's clear is that on-site search is quite important. Algolia reports ~15,000 queries a day. I don't think that represents "user typed in a thing and submitted it" because the search happens in real-time, so each character typed can result in a query. Still, likely hundreds or low-thousands of searches a day.

I'm going to convert us back to using Google search. I think Algolia is a fantastic product, I just don't have the developer time right now to give it the work it needs.

The location of y'all seems to be spreading out internationally little by little. The United States is down to 22% of traffic from 23% and India back to down to 11% from 12% (meaning more traffic came from elsewhere). Those are the top 2, then it goes UK, Germany, Canada, France, Netherlands, Poland, Russia, Brazil. What would be really interesting is to figure out visitors per-capita. For example, Singapore has a population of 5.6 million and had 111,319 unique users, so you could say about 2% of Singaporeans visited CSS-Tricks last year. Lols probably not, but hey that's what the back-of-the-napkin math shows. Whereas with the 4.6 million unique visitors from the US compared to the 323 million population means only 1.5% has visited.

We gained about 10,000 newsletter subscribers this year for a total of 31,376. That's about a third of the entire list size. I love our newsletter. I think it has a ton of potential and is always worth reading. To be perfectly honest I'd like to see our newsletter subscriber numbers be higher than our Twitter followers, but that'll be a tall hill to climb.

Search is the origin of 86.6% of the traffic we get. Direct visits and referral links result in another 5% each. Social media just 2.5%. Whenever I look at that I'm reminded of the disproportionate amount of energy spent on it. Still, it aligns with our goal of being a publication people regularly read and being a source of news, so it feels worth it.

Speaking of social media, we rose 44,000 follows on Twitter last year, again an astonishing number, but it's down year-over-year for the last several years. 71,900 likes on Facebook, only rising about 3,000, which isn't bad considering we do hardly anything at all on Facebook. Growth is much more explosive on YouTube. We're at 40,123 subscribers there from 32,174 last year, despite only posting a paultry 6 videos.

This is a classic loop in my head: maybe we should have a dedicated social media person! But even part-time employees are expensive... is it worth it? How much more potential is there? Could they add so much value they pay for themselves? What else could they do? And then the questions swirl around in my head so quickly the idea fizzles out. I guess I'll just say if that kind of thing interests you, reach out!

For once, mobile traffic is actually up. 6.2% this year from below 5% last year. Industry-wide, that's rock bottom. CSS-Tricks is just weird that way. A lot of developers b searching stuff at work, unsurprisingly. Less than 1% is tablets. 30% of the mobile traffic is iPhones.

Y'all left about 5,040 comments on the site this year, which is a smidge down year over year from the past few years, but it actually feels significantly up to me, since we've been much more stringent about what comments we publish this year. I do the vast majority of comment moderation and I trash a lot more than I used to. Anything that off-topic, rude, or unhelpful doesn't see the light of day. I hope that doesn't scare you off from commenting. In fact, I hope it encourages it. Anything on-topic and helpful will absolutely be published and won't be lost in a sea of junk.

We've had 20,238 people use our contact form. Don't worry, I love email.

Goal Review

Double newsletter subscribers. We didn't double but we grew by a third, which is pretty strong. Especially since we did little to nothing to promote it. We probably need to do a better job of promoting it and somehow incentivizing signups, especially since it's such a good way to reach people.

More pairing videos. Pretty hard fail here. The main difficulty is scheduling multiple people together, combined with the pressure of producing something worth watching. It's one thing for an audio podcast like ShopTalk where we can schedule someone and just chit-chat about tech. It's another thing to ask someone to pair with you and essentially do live coding. It's still a good idea, it just needs a more serious time commitment and leader. And honestly, probably a sponsor so that it can be worth everyone's time.

Maintain a mostly-daily publishing schedule. Check and check! This is the first year we've actually kept an honest to god schedule, structured after daily posting. We'll be moving forward with that for sure.

Assemble content in more useful ways. We got a good start on this with Guides. We haven't done a ton with them yet, but we have given ourselves a way to build these without too much effort, and I think the potential in them is fantastic.

New Goals

Publish something in a new format. We have a lot of publishing power around here with lots of writers and a solid platform. Let's use it to publish a book or something book-like.

More editorial vision. Admittedly, what we published each day is a bit random. That's not a terrible thing since the site has a niche anyway, but I'd call it a good goal to exert some editorial guidance to what we publish and when. Meaning commissioning and shepherding work that is a good fit for this site and publishing it with timing that makes some sort of sense.

Interesting sponsorship partners. The most rewarding and powerful partnerships between sponsors and publications are ones of mutual respect and admiration. There are loads of businesses out there I think are doing a terrific job of building what the build, and I'd like to forge relationships with them to promote what they do. And do that promotion in a way that we are uniquely able to do. Get in touch if you think you're a part of that company.

Create another very popular page. It's just a matter of time and topic. I'd like to find at least one web development topic that could really use a strong reference page and spend a good amount of time making what we consider a perfect fit for that, with the goal of it really resonating with developers.

Most importantly

Thank you, again, for being a part of this community.

See the Pen Text Animation with CSS - thank you screen! by Nooray Yemon (@yemon) on CodePen.

Thank You (2017 Edition) is a post from CSS-Tricks

What You Build

Css Tricks - Sat, 12/30/2017 - 5:26am

I tweeted this yesterday and it seemed to resonate with some folks:

Just a little reminder that it’s about 100 times more important what you build than how you build it.

— Chris Coyier (@chriscoyier) December 10, 2017

What I was feeling when I wrote that was a little tired of endless discussions on tech minutia and yearning for more focus on what we are building and discussion about why.

If you're a reader of this site, you and I live in the same bubble. It's a nice bubble. It's full of smart people who like to chat about web design and development. I live it and love it.

It's easy to get into a heated discussion about frameworks, what type of class names make the most sense, which optimization techniques are most important, or what part of your code base is should be responsible for styling. Those are great discussions that guide our industry.

But what is more important? The naming convention you chose or if your user can actually book a flight? Which state store library you picked or if you actually had the scarf your user was looking for? Which command line tool pulled your dependencies or whether someone was able to find and read the instructions to send in their court appeal?

I was trying to encourage people to build and think about what they are building rather than get too discouraged about the how. You're building things for people and that's such a big responsibility. One that outweighs technical choices, as important as they seem.

I enjoyed the pushback I got on it though.

Most of it centered around the fact that if you make poor tech choices, that limits the quality of what you build and slows your ability to change and adapt to changing user needs. Fair enough.

Good tech just might lead to directly better features and UX for your users. Fair enough. Good tech might be a differentiator between you and your competition. Fair enough.

My favorite was calling out the story of the three little pigs. If you aren't familiar, there is a Big Bad Wolf that is trying to eat the piggies. Each of them built a house to protect themselves. I imagine you can guess which of the pigs did better: the one who built their house out of hay, or the pig who built their house out of bricks.

Fair enough.

Drew McLellan gets into this in All That Glisters, but focuses on the old vs new tech issue:

There are so many new tools, frameworks, techniques, styles and libraries to learn. You know what? You don’t have to use them. You’re not a bad developer if you use Grunt even though others have switched to Gulp or Brunch or Webpack or Banana Sandwich. It’s probably misguided to spend lots of project time messing around with build tool fashions when your so last year build tool is already doing what you need.

And this gem:

Software, much like people, is born with a whole lot of potential and not much utility. Newborns — both digital and meaty — are exciting and cute but they also lead to sleepless nights and pools of vomit.

He goes on to say that what you are building might help dictate your tech choices. Ah yes, the what. Not only is what your things does litearlly the only thing people care about, it also helps guide tech choices.

What You Build is a post from CSS-Tricks

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

Css Tricks - Fri, 12/29/2017 - 4:40am

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fill or Fit? What's the difference?

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

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

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

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

Consider the following demo as an example.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Summing Up

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

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

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

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

Five Design Fears to Vanquish With CSS Grid

Css Tricks - Thu, 12/28/2017 - 3:58am

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

The majority of them fall into one of two categories:

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

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

Fear 1: Asymmetry

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

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

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

Speaking of whitespace...

Fear 2: Negative Space

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

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

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

Fear 3: Punk Rock?

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

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

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

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

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

Fear 4: New Sources of Inspiration

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

Punk rock graphic design

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

Vintage movie graphic design

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

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

Learn how to create graphic design grids

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

Fear 5: Fallbacks

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

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

What's next?

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

How will you push the industry forward?

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

? Make the Web Your Playground

Css Tricks - Thu, 12/28/2017 - 3:57am

(This is a sponsored post.)

Here's something you can do: kick off 2018 with your own professional website. The only thing you'll need to get started is your imagination, a little free time, and an innovative website builder.

Wix is the world's most technologically advanced website builder. Sign up for Wix, choose a template, and start customizing it. Whether you’re a novice, a business owner, a sophisticated designer, or a professional website builder, you’ll have full control of your website - from design prototyping to production.

Wix takes care of all the heavy lifting. You get reliable, safe, secure hosting that you'll never need to worry about. You get a custom domain name and email. To get started, all you need is a computer and a little time.

Don't underestimate what you can do with Wix. There are all kinds of advanced design features and functionality if that's something you need. The web is your playground. We’ve come along way from the website building platforms of the 90s. Now, you can create any kind of website you want and even collaborate with friends or coworkers.

Save yourself time and money, and head over to to get started for free. Kick off 2018 strong with your own professional website and share your ideas with the world.

Direct Link to ArticlePermalink

? Make the Web Your Playground is a post from CSS-Tricks

Syndicate content
©2003 - Present Akamai Design & Development.