Archiwum kategorii: CSS

Thank You (2017 Edition)

Post pobrano z: Thank You (2017 Edition)

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 role 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

Post pobrano z: What You Build

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

You are what you document

Post pobrano z: You are what you document

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 Article — Permalink


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

Additive Animation with the Web Animations API

Post pobrano z: Additive Animation with the Web Animations API

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

2017 Staff Favorites

Post pobrano z: 2017 Staff Favorites

It’s been a very productive year for the web community, and as all of us here at CSS-Tricks roamed around to conferences, read posts, and built projects, there were some highlights of contributions that really stuck out to us. Each of us picked 5 resources that were either the most helpful, the most unique, or are things you might have missed that we think are worth checking out.

Sarah’s Picks

The Miracle of Generators

I quite like when someone takes a deep dive on a particular subject and does it well. I had the honor of seeing Bodil Stokke give this talk at Frontend Conference Zurich and it’s as charming and entertaining as it is educational.

Designing with Grid

Jen Simmons covers the status of CSS Grid, and how to work with it from design to development. Jen is a master of grid, and the lab section of her site shows the capability of this medium.

An update since this talk has come out: Grid has also shipped in Microsoft Edge.

Vue Apollo

This is more like two things I’m interested in wrapped up in a single thing. Guillaume Chau has done a great job of creating an Apollo/GraphQL integration for Vue, including a few great demos to explore.

The Coding Train

This resource has been out for a while, but Dan now has such a great collection that it’s a great time to mention it.

Coding Train are small, half-hour chunks of tutorials- everything from creating a star field to learning how Neural Networks work. Dan is an incredibly engaging and lovable instructor and makes you feel very welcome when exploring new concepts.

Motion in Design Systems

Val Head gets to the heart of the matter when it comes to integrating motion into a Design System or Component Library.

It can be really tough to communicate animation because you necessarily need to collaborate between design and engineering. Val gives you some tools to make this process function well.

Robin’s Picks

Design Systems

Design Systems by Alla Kholmatova was one of the best design books I read in 2017.

It’s a book all about how to collaborate with a team and reveals that code quality is only one part of designing great systems on the web. The book isn’t so much about design as much as it’s about learning how to communicate across large groups of people and how we can better communicate with everyone in an organization.

Web Typography

Another great book I read this year was Web Typography by Richard Rutter, this time focusing a great deal more on the relationship between CSS and typesetting.

My favorite part of the book though is where Richard describes that web typography is fundamentally different from other forms of typesetting and requires a series of new skills. It makes for exciting reading.

Purple.pm

For most of this year I’ve been focusing on improving my UX and product design skills and I have to say that Purple was the most useful tool for organizing large amounts of data and research. I used it as an archive that stored every document I made, every Balsamiq wireframe and hi-fi Figma mockup I created all in one place. This made it so much easier to communicate with other teams and explain my thinking on a project.

Figma

This year I switched to using the web-based design tool Figma full time. It’s been so very useful because my day job work requires collaborating with dozens of engineers, product managers and other designers — so being able to quickly share a mockup with them and get feedback has exponentially improved my design chops. Plus, it reminds me of Fireworks which is probably one of the best apps ever made.

Inkwell

This year Hoefler & Co. released Inkwell, a new family of typefaces that mimics a variety of handwriting styles and I can’t stop thinking about them. One great example of their use is on Chris’ blog where all these weird styles shouldn’t work at all but somehow they just do.

Chris’ Picks

A Design System for All Americans by Mina Markham

A masterclass in public speaking if you ask me. Funny, personal, and right on target for the kind of work a lot of us are doing.

Notion

Notion is probably the most significant bit of new software I’ve switched to this year. It’s a notes app at it’s core and it’s feature-rich in that regard. One of my favorites features is that every note is also a folder, so you can get as nested as you like with your organization. If you give it a shot, I bet you’ll be able to see how it quickly can replace lots of other apps.

Most significant to a list like this, is that it’s built for the web, but also has native apps on a variety of platforms. I think 2017 was significant in that we started to really feel a blurring between what is web and what is platform native. I suspect it will get harder and hard to tell, and then with all the advantages the web has inherently, it will make less and less sense to build anywhere else.

CSS

CSS had a banner year. CSS Grid, of course, but we also got font-display starting to ship, which is wonderful for performance. We got landmark selectors like :focus-within that prove parent selectors aren’t impossible. Vector graphics has moved it way into CSS with a collection of properties, including animation and movement. You might say CSS has gotten more capable and easier. I enjoyed writing posts like this one about a slider that shows how far you can get in CSS these days.

RIP Firebug

I think it’s nice the Firebug homepage is an homage, goodbye, and short history to Firebug. Firebug laid the foundation for what good DevTools could be. I’m glad browsers have taken them in-house and turned them into the powerhouses we use now, but that’s all thanks to Firebug.

If I had to pick the most significant three things that have made the web the development platform it is today: 1) DevTooling, started by Firebug 2) The agreement from all browsers that web standards benefit everyone and actually being disciplined about applying that thinking 3) Evergreen browsers.

PWAs

I feel like Progressive Web Apps are essentially good marketing for a collection of good ideas that benefit any website. That’s exactly the case Jason Grigsby makes:

That makes it an easy pick for 2017. HTTPS! Service workers for offline friendliness! Performance focused! Do these things, and be rewarded with more features that native apps enjoy, like a position on the home screen on mobile devices. Blur them lines, y’all! Even if you don’t do everything on the list, there are big advantages for every step along the way.

Geoff’s Picks

CSS Grid

This one comes as no surprise but it’s certainly worthy of multiple mentions. Grid has really rejuvenated my love for CSS. Not only does it take a lot of the complexity of out layouts that used to require creative uses of floats, displays and positioning, but it has allowed me to cut CSS frameworks completely out of my workflow. I mean, it’s that frameworks are bad or should not be used, but I personally leaned on them a lot for their grid systems. That’s no longer the case and the result is one less dependency in my stack and the liberty to write more vanilla CSS.

Prototyping Tools

Robin already mentioned Figma and that is totally in line with what I’m referring to. There seemed to be an explosion of innovation in prototyping tools. Sketch, Figma, InVision and, yes, Adobe all upped their games this year and web designers were the beneficiaries. These tools have opened up have made it easier to collaborate with other designs, critique work, get client feedback, and ultimately get into the browser faster. I have never spent less time in graphic design software and it’s been awesome.

Here’s a taste of what I’m referring to:

Contrast in Accessibility

Often when we talk about accessibility, the focus is on things like semantics, document structure, screen readers ARIA roles. It can get super complicated. That’s why I really enjoyed Lara’s recent post advocating for accessible UI. Aside from being extremely well-written, she presents commonsense approaches to improving accessibility in ways that go beyond code.

One of her suggestions to check color contrasts in the design to ensure good legibility. This one really resonated with me because I recently worked on a project with a visual brand that includes a lot of greens and yellows. Running our designs through the tools Lara recommends revealed that our work failed many accessibility checks. It also taught me that accessibility really does not favor greens and yellows.

Web Typography: Designing Tables to be Read, Not Looked At

If you didn’t catch Richard Rutter’s post on A List Apart, I’ll please go read that right now. Don’t worry, I’ll wait right here for you.

You back? Great!

This one was a splash of cold water in my face. Richard not only convicted me to honestly assess whether I over-design tables but also turned all my preconceptions about what a table is and what a good one looks like. Good design is problem solving and this post is one that reminds me design for solutions before aesthetics.

place-items

Chris snuck this property into a demo and I had no idea it existed. I had to forgive myself a little when I saw that browser support on it is low, but it is a really nice shortcut that combines the align-items and justify-items properties. You may have guessed why I love this: it comes in super handy with Grid and Flexbox. While support is limited it Chrome 59+ and Firefox 45+, I am stoked to see more browsers hop on board.


What are your picks for 2017?


2017 Staff Favorites is a post from CSS-Tricks

Fragmented HTML5 Video

Post pobrano z: Fragmented HTML5 Video

I have seen various implementations of the Voronoi Diagram. Perhaps you’ve seen one without knowing what it was. It almost looks like random stained glass:

Wikipedia:

In mathematics, a Voronoi diagram is a partitioning of a plane into regions based on distance to points in a specific subset of the plane.

It’s even possible to create a Voronoi diagram by hand, as eLVirus88 has documented.

I wanted to give it a try.

The Idea

My idea is to chop up a video into fragmented parts (called cells) and put them into 3D space on a slightly different z-axis. Then, by moving the mouse, you would rotate the whole experience so you would see the cells in different depths.

The Code

Building on top of Raymond Hill’s and Larix Kortbeek’s JavaScript implementation, the first thing I needed to was split up the cells.

I choose to use the <canvas> element, and put each of the cells on different canvas on a differnet 3D plane through CSS.

The Voronoi library takes care of computing all the sites to cells and creating objects with the vertices and edges for us to work with.

Cells to Canvases

First we create the canvases to match the number of Voronoi cells. These will be rendered to the DOM. The canvases and their respective contexts will be saved to an array.

var canv = document.createElement('canvas');
    
canv.id = 'mirror-'+i;
canv.width = canvasWidth;
canv.height = canvasHeight;

// Append to DOM
document.body.appendChild(canv);
document.getElementById('container-mirrors').appendChild(canv);

// Push to array
canvasArray.push(canv);
contextArray.push(canv.getContext('2d'));

Masking

All of the canvases are now a copy of the video.

The desired effect is to show one cell per canvas. The Voronoi library provides us with a compute function. When providing the sites with the bounds we get a detailed object where we extract all of the cells edges. These will be used to create a cut out to each section using the globalCompositeOperation.

// Compute
diagram = voronoi.compute(sites, bounds);

// Find cell
for (i=0;i<sites.length;i++) {
  if (!found) {
    cell = diagram.cells[i];
if (sites[j].voronoiId === cell.site.voronoiId) {
      found = 1;
    }
  }
}

// Create mask to only show the current cell
ctx.globalCompositeOperation = 'destination-in';
ctx.globalAlpha = 1;

ctx.beginPath();

var halfedges = cell.halfedges,
nHalfedges = halfedges.length,
v = halfedges[0].getStartpoint();

ctx.moveTo(v.x,v.y);

for (var iHalfedge=0; iHalfedge<nHalfedges; iHalfedge++) {
  v = halfedges[iHalfedge].getEndpoint();
  ctx.lineTo(v.x,v.y);
}

ctx.fillStyle = sites[j].c;
ctx.fill();

Adding Video

Displaying video to the canvas only takes a couple of lines of code. This will be executed on requestAnimationFrame:

v = document.getElementById('video');
ctx.drawImage(v,0,0,960,540);

It’s also possible to use a video input source (like a webcam), but I didn’t like the result as much for this demo. If you would like to know how to use the webcam to draw to canvas using the getUserMedia() method you can read about it here.

To optimise video drawing performance skip a few frames in between the requestAnimationFrame. Videos for the web are usually encoded with a frame rate not higher than 30 fps.

See the Pen Fragmented HTML5 Video – Demo 1 by virgilspruit (@Virgilspruit) on CodePen.

Conclusion

Demos like this are my favorite things to do. Seeing what’s out there and adding your own layer of interactivity to it. I’m looking forward to seeing what other people will be doing with this nice visual algorithm.

See the Pen Fragmented HTML5 Video – Demo 2 by virgilspruit (@Virgilspruit) on CodePen.

See the Pen Fragmented HTML5 Video – Demo 3 by virgilspruit (@Virgilspruit) on CodePen.

View Demos GitHub Repo


Fragmented HTML5 Video is a post from CSS-Tricks

Further working mode changes at WHATWG

Post pobrano z: Further working mode changes at WHATWG

The Web Hypertext Application Technology Working Group (WHATWG) announced that it has adopted a formal governance structure:

The WHATWG has operated successfully since 2004 with no formal governance structure, guided by a strong culture of pragmatism and collaboration. Although this has worked well for driving the web forward, we realized that we could get broader participation by being clear about what rights and responsibilities members of the community have. Concretely, this involves creating an IPR Policy and governance structure.

WHATWG was founded by folks at Apple, Mozilla and Opera. The new structure will be comprised of individuals from Apple, Google, Microsoft and Mozilla. The Big Four, you might say.

I find this interesting because we often think of the Web as a wild west where standards are always evolving and adopted at a different pace. This change largely keeps public contributions to the Living Standards in tact, but establishes a clearer line of communication between working groups and provides a path to appeal and resolve disputes over standards.

Living Standards are informed by input from contributors, driven by workstream participants, articulated by editors, and coordinated by the Steering Group. If necessary, controversies are resolved by the Steering Group with members appointed from the organizations that develop browser engines.

And, with representatives from leading browsers at the table, we may see more agreement with adoption. I’m speculating here, but it seems reasonable.

If you’re like me and are fuzzy on the differences between WHATWG and W3C, Bruce Lawson has a pretty simple explanation. It still kinda blows my mind that they’re both standards we often refer to but come from two completely different groups.

Direct Link to Article — Permalink


Further working mode changes at WHATWG is a post from CSS-Tricks

Refactoring Your Way to a Design System

Post pobrano z: Refactoring Your Way to a Design System

Mina Markham on refactoring a large and complex codebase into an agile design system, slowly over time:

If you’re not lucky enough to be able to start a new design system from scratch, you can start small and work on a single feature or component. With each new project comes a new opportunity to flesh out a new part of the system, and another potential case study to secure buy-in and showcase its value. Make sure to carefully and thoroughly document each new portion of the system as it’s built. After a few projects, you’ll find yourself with a decent start to a design system.

As a side note, Mina’s point here also reminds me of an old blog post called „Things You Should Never Do” by Joel Spolsky where he talks about how all this work and all this code you feel you needs to be refactored is actually solving a problem. Deleting everything and starting from scratch is almost never a good idea:

When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years of programming work.

I’m not entirely sure that Joel’s piece about programming fits snuggly with Mina’s point but I think it’s an interesting one to make nonetheless: new code doesn’t necessarily mean that it’s better.

Direct Link to Article — Permalink


Refactoring Your Way to a Design System is a post from CSS-Tricks

Don’t Use My Grid System (or any others)

Post pobrano z: Don’t Use My Grid System (or any others)

This presentation by Miriam at DjangoCon US last summer is not only well done, but an insightful look at the current and future direction of CSS layout tools.

Many of us are familiar with Susy, the roll-your-own Grid system Miriam developed. We published a deep-dive on Susy a few years back to illustrate how easy it makes defining custom grid lines without the same pre-defined measures included in other CSS frameworks, like Foundation or Bootstrap. It really was (and is) a nice tool.

To watch Miriam give a talk that discourages using frameworks—even her very own—is a massive endorsement of more recent CSS developments, like Flexbox and Grid. Her talk feels even more relevant today than it was a few months ago in light of Eric Meyer’s recent post on the declining complexity of CSS.

Yes, today’s CSS toolkit feels more robust and the pace of development seems to have increased in recent years. But with it come new standards that replace the hacks we’ve grown accustomed to and, as a result, our beloved language becomes less complicated and less reliant on dependencies to make it do what we want.

Direct Link to Article — Permalink


Don’t Use My Grid System (or any others) is a post from CSS-Tricks

Comparing Novel vs. Tried and True Image Formats

Post pobrano z: Comparing Novel vs. Tried and True Image Formats

Popular image file formats such as JPG, PNG, and GIF have been around for a long time. They are relatively efficient and web developers have introduced many optimization solutions to further compress their size. However, the era of JPGs, PNGs, and GIFs may be coming to an end as newer, more efficient image file formats aim to take their place.

We’re going to explore these newer file formats in this post along with an analysis of how they stack up against one another and the previous formats. We will also cover optimization techniques to improve the delivery of your images.

Why do we need new image formats at all?

Aside from image quality, the most noticeable difference between older and newer image formats is file size. New formats use algorithms that are more efficient at compressing data, so the file sizes can be much smaller. In the context of web development, smaller files mean faster load times, which translates into lower bounce rates, more traffic, and more conversions. All good things that we often preach.

As with most technological innovations, the rollout of new image formats will be gradual as browsers consider and adopt their standards. In the meantime, we as web developers will have to accommodate users with varying levels of support. Thankfully, Can I Use is already on top of that and reporting on browser support for specific image formats.

The New Stuff

As we wander into a new frontier of image file formats, we’ll have lots of format choices. Here are a few candidates that are already popping up and making cases to replace the existing standard bearers.

WebP

WebP was developed by Google as an alternative to JPG and can be up to 80 percent smaller than JPEGs containing the same image.

WebP browser support is improving all the time. Opera and Chrome currently support it. Firefox announced plans to implement it. For now, Internet Explorer and Safari are the holdouts. Large companies with tons of influence like Google and Facebook are currently experimenting with the format and it already makes up about 95 percent of the images on eBay’s homepage. YouTube also uses WebP for large thumbnails.

If you’re using a CMS like WordPress or Joomla, there are extensions to help you easily implement support for WebP, such as Optimus and Cache Enabler for WordPress and Joomla’s own supported extension. These will not break your website for browsers that don’t support the format so long as you provide PNG or JPG fallbacks. As a result, browsers that support the newer formats will see a performance boost while others get the standard experience. Considering that browser support for WebP is growing, it’s a great opportunity to save on latency.

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

Desktop

Chrome Opera Firefox IE Edge Safari
23 12 No No No No

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
No 11.1 all 4.2-4.3 62 No

HEIF

High efficiency image files (or HEIF) actually bear the extension HEIC (.heic), which stands for high efficiency image container, but the two acronyms are being used interchangeably. Earlier this year, Apple announced that its newest line of products will support HEIF format by default.

On top of smaller file sizes, HEIF offers more versatility than other formats since it can support both still images and image sequences. Therefore, it’s possible to store burst photos, focal stacks, exposure stacks, images captured from video and other image collections in a single file. HEIF also supports transparency, 3D, and 4K.

In addition to images, HEIF files can hold image properties, thumbnails, metadata and auxiliary data such as depth maps and audio. Image derivations can be stored as well thanks to non-destructive editing operations. That means cropping, rotations, and other alterations can be undone at any time. Imagine all of your image variations contained in a single file!

Apple is doing everything it can to make the transition as seamless as possible. For example, when users share HEIF files with apps that do not support the format, Apple will automatically convert the image to a more compatible format such as JPG.

There is no browser support for HEIF at the time of this writing.

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

Desktop

Chrome Opera Firefox IE Edge Safari
No No No No No No

Mobile / Tablet

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

That being said, the file format offers impressive file savings for both video and images. This is becoming increasingly important as our devices become stronger and are able to take higher quality images and videos, thus resulting in a greater need for efficient media files.

FLIF

Free Lossless Image Format (or FLIF) uses a compression algorithm that results in files that are 14-74 percent smaller than older formats without sacrificing quality (i.e. lossless). Therefore, FLIF is a great fit for any type image or animation.

The FLIF homepage claims that FLIF files are 43% percent smaller on average than typical PNG files. The graph below illustrates how FILF compares to other formats in this regard.

FLIF often winds up being the most efficient format in tests.

FLIF takes advantage of something called meta-adaptive near-zero integer arithmetic coding, or (appropriately) MANIAC. FLIF also supports progressive interlacing so that images appear whole as soon as they begin downloading, which is another feature that has shown to reduce web page bounce rates.

The potential of FLIF is very exciting, but there is no browser support at the moment nor does it look like any browsers are currently considering adding it. While creators of the format are working hard on achieving native support for popular web browsers and image editing tools, developers can access the FLIF source code and snag a polyfill solution to test it out.

The Existing Stuff

As mentioned earlier, we’re likely still years away from the new formats completely taking over. In some cases, it might be better to stick with the tried and true. Let’s review what formats we’re talking about and discuss how they’ve stuck around for so long.

JPG

As the ruling standard for most digital cameras and photo sharing devices, JPG is the most frequently used image format on the internet. W3Techs reports that nearly three-quarters of all websites use JPG files. Similarly, most popular photo editing software save images as JPG files by default.

JPG is named after Joint Photographic Experts Group, the organization that developed the technology; hence why JPG is alternatively called JPEG. You may see these acronyms used interchangeably.

The format dates all the way back to 1992, and was created to facilitate lossy compression of bitmap images. Lossy compression is an irreversible process that relies on inexact approximations. The idea was to allow developers to adjust compression ratios to achieve their desired balance between file size and image quality.

The JPG format is terrific for captured photos; however, as the name implies, lossy compression comes with a reduction in image quality. Quality degrades further each time an image is edited and re-saved, which is why developers are taught to refrain from resizing images multiple times.

GIF

GIF is short for graphics interchange format. It depends on a compression algorithm called LZW, which doesn’t degrade image quality. The GIF format lacks the color support of JPG and PNG, but it has stuck around nonetheless thanks to its ability to render animations by bundling multiple images into a single file. Images stored inside a GIF file can render in succession to create a short movie-like effect. GIFs can be configured to display image sequences a set number of times or loop infinitely.

Image courtesy of Giphy.com

PNG

The good old portable network graphic (PNG) was originally conceptualized as the successor to the GIF format and debuted in 1996. It was designed specifically for representing images on the web. In terms of popularity, PNG is a close runner-up to JPG. W3Techs claims that 72 percent of websites use this format. Unlike JPG, PNG images are capable of lossless compression (meaning no image quality is lost).

Another advantage over JPG is that PNG supports transparency and opacity. Since large photos tend to look superior in the JPG format, the PNG format is typically used for non-complex graphics and illustrations.

Comparing the transparency support of JPG (left) and PNG (right).

Ways to Improve Image Optimization and Delivery

There are a few vital things to consider when optimizing images for the web because any file format—including the new ones—can end up adding yet another layer of complexity. Images typically account for the bulk of the bytes on a web page, so image optimization is considered low-hanging fruit for improving a website’s performance. The Google Dev Guide has a comprehensive article on the topic, but here is a condensed list of tips for speeding up your image delivery.

Implement Support for New Image Formats

Since newer formats like WebP aren’t yet universally supported, you must configure your applications so that they serve up the appropriate resources to your users.

You must be able to detect which formats the client supports and deliver the best option. In the case of WebP, there are a few ways to do this.

Invest in a CDN

A content delivery network (CDN) accelerates the delivery of images by caching them on their network of edge servers. Therefore, when visitors come to your website, they get routed to the nearest edge server instead of the origin server. This can produce massive time savings especially if your users are far from your origin server.

We have a whole post on the topic to help understand how CDNs work and how to leverage them for your projects.

Use CSS Instead of Images

Because older browsers didn’t support image shadows and rounded corners, veteran web developers are used to displaying certain elements like buttons as images. Remember the days when displaying a custom font required making images for headlines? These practices are still out in the wild, but are terribly inefficient approaches. Instead, use CSS whenever you can.

Check Your Image Cache Settings

For image files that don’t change very often, you can utilize HTTP caching directives to improve load times for your regular visitors. That way, when someone visits your website for the first time, their browser will cache the image so that it doesn’t have to be downloaded again on subsequent visits. This practice can also save you money by reducing bandwidth costs.

Of course, improper caching can cause problems. Adding a fingerprint, such as a timestamp, to your images can help prevent caching conflicts. Fortunately, most web development platforms do this automatically.

Resize Images for Different Devices

Figuring out how to best accommodate mobile devices with inferior screen resolutions is an ongoing process. Some developers don’t even bother and simply offer the same image files for all users, but this approach wastes your bandwidth and your mobile visitors’ time. Consider using srcset so that the browser determines which image size it should deliver based on the client’s size dimensions.

Image Compression Tests

It’s always interesting to see the size differences each image format provides. In the case of this article, we’re comparing lossless and lossy image formats together. Of course, that’s not common practice as many times lossy will be smaller in size than lossless as the quality of the image suffers in order to produce a smaller image size.

In any case, choosing between lossless and lossy image formats should be based on how image intensive your site is and how fast it already runs. For example, an e-commerce shop may be comfortable with a slightly degraded image in exchange for faster load times while a photographer website is likely the opposite in order to showcase talent.

To compare the sizes of each of the six image formats mentioned in this article, we began with three JPG images and converted them into each of the other formats. Here are the performance results.

As previously mentioned, the results below vary significantly due to lossless/lossy image formats. For instance, PNG and FLIF images are both lossless, therefore resulting in larger image files.

Image 1 Size Image 2 Size Image 3 Size
WebP 1.8 MB 293 KB 1.6 MB
HEIF 1.2 MB 342 KB 1.1 MB
FLIF 7.4 MB 2.5 MB 6.6 MB
JPG 3.9 MB 1.3 MB 3.5 MB
GIF 6.3 MB 3.9 MB 6.7 MB
PNG 13.2 MB 5 MB 12.5 MB

According to the results above, HEIF images were smaller overall than any other format. However, due to their lack of support, it currently isn’t possible to integrate the HEIF format into web applications. WebP came in at a fairly close second and does offer ways to work around the less-than-ideal amount of browser support. For users who are using Chrome or Opera, WebP images will certainly help accelerate delivery.

As for the lossless image formats, PNG is significantly larger than it’s lossy JPG counterpart. However, when optimized with FLIF, savings of about 50 percent were realized. This makes FLIF a great alternative for those who require high-quality images at a smaller file size. That said FLIF currently isn’t supported by another web browsers yet, similar to HEIF.


Conclusion

The old image formats will likely still be around for many years to come, but more developers will embrace the newer formats once they realize the size-saving benefits.

Cameras, mobile devices and many gadgets, in general, are becoming more and more sophisticated meaning that the images and videos taken are of higher quality and taking up more space. New formats must be adopted to mitigate this and it looks like we have some extremely promising options to look forward to, even if it will take some time to see them officially adopted.


Comparing Novel vs. Tried and True Image Formats is a post from CSS-Tricks