Testing for Visual Regressions with Percy

While this post is not sponsored (it is based on Paul’s own personal experience), we have worked with Percy before on a sponsored video, that also goes through the process of setting up Percy on a site. It’s fascinating, powerful, useful stuff and I highly recommend checking it out.


Let me set the stage:

  1. You’ve pushed some code and all the meticulously unit tests you wrote pass. Fantastic! Let’s get this branch into QA.
  2. You receive a Slack message from your QA team asking why a button is now floating off the screen?
  3. “But… I didn’t touch any code in that part of the application,” you think to yourself.
  4. Then you remember you did change some CSS.
  5. Panic! What else has changed in the UI? Does this affect iPad? Will Firefox behave differently than Chrome? What about mobile?

This is a very common scenario many of us face when building large-scale applications that deal with different screen sizes and browsers. It’s a Herculean task to test UI for each and every change to code.

What now, throw in the towel and move to the mountains? Thankfully, no. We have Percy to help save the day! And it’s really the best friend we have for testing unexpected outcomes that impact design and layout. Percy has become an indispensable part of my development stack and I convinced CSS-Tricks to let me share some things about it that have made my code stronger and helped prevent errors from shipping.

Plus, it integrates well with other tooling and is a relative breeze to set up. So hang with me a bit as we walk through what Percy is and how to leverage it for your projects.

So, what exactly is Percy?

According to Percy’s site, it’s an “all in one visual review platform.”

I’ve found that holds true. What it boils down to is that Percy provides a way to test visual regressions. That’s pretty awesome if you think about it. Many changes to a codebase — especially working with CSS …

Revisiting the Rendering Tier

Have you ever created a well-intentioned, thoughtful design system only to watch it grow into an ever-increasing and scary codebase? I’ve been working in sort of the opposite direction, inheriting the scary codebase and trying to create a thoughtful system from it.

Here’s Alex Sanders on the topic, explaining how his team at The Guardian has tackled the task of creating design systems while combating complexity:

Systems that try to contain complexity over long periods of time by convention will inevitably tend toward entropy, because one significant characteristic of convention is that it is trivially simple to break one.

You do not even need to be malicious. A convention is not a line in the sand. You can have a very good case for breaking or stretching one, but once a convention is no longer fully observed, subsequent cases for breaking or stretching it are automatically stronger, because the convention is already weakened. The more this happens, the weaker it gets.

Complexity and entropy can be two outcomes in the same situation, but need not be mutually exclusive. Interesting to think that our best intentions to guard against complexity can be somewhat destructive.

I also love how Alex explains why it’s not possible for their team to use a Tachyons-esque approach to writing styles because of the way that their development environment is kinda slow. It would be painful for the team to make that switch, despite how it could solve some other problems. This reminded me that measuring problems in this way is why there can never be a single way to write CSS. We need that inherent flexibility, even at the expense of introducing inconsistencies. Hence, conventions being less of a line in the sand and more of a guide post.

On a separate note, I really like how Alex describes styles and attributes as the reasons why his team is writing those styles. It’s about aligning with business objectives:

…tens of thousands of rules that are intended to describe a maintainable set of responses to business

Decaying Sites

Websites have a tendency to decay all by themselves. Link rot, they call it. Unpaid domain name registrations. Companies that have gone out of business. Site owners that have lost interest. What’s sadder than a 404? Landing on a holding page of a URL that used to exist, but now has fallen into the hands of some domain hoarder after it expired, hoping someone will pay a premium to get it back.

That stuff is no fun. But what about sites that are totally still around, just old? What kind of fun things could we do to indicate oldness that’s, like, on purpose?

On the CodePen blog, we call out blog posts that haven’t been updated in at least a couple of years. We update documentation, sure, but we tend to leave blog posts alone as a historical record. So, we’re pretty clear about that:

<?php if (get_the_modified_date("Y") < 2017) { ?>
  <p class="callout"><strong>Heads up!</strong> This blog post hasn't been updated in over 2 years. CodePen is an ever changing place, so if this post references features, you're probably better off checking the <a href="/documentation/">docs</a>. Get in touch with <a href="https://codepen.io/support/">support</a> if you have further questions.</p>
<?php } ?>

We style it up like a little warning:

But what if it was less obvious? What if the text just kinda started going all to crap? Words falling off their lines and going out of focus? The older the content, the more decay:

See the Pen
Decayed Text
by Chris Coyier (@chriscoyier)
on CodePen.

What if you let a site decaye on purpose? Say, perhaps, you’re holding oto client work and the client hasn’t paid their bill. Dragoi Ciprian has a little idea (repo) for that. You set the due date and deadline:

var due_date = new Date('2017-02-27');
var days_deadline = 60;

Here’s a demo of that. As I write, I’m 30 days into a 90-day deadline. If the demo looks blank to you, well, I guess I should have paid my bill so this …

A Couple of New Wufoo Tips

(This is a sponsored post.)

High fives to Wufoo, our long-time sponsor here on CSS-Tricks. It’s powered the vast majority of forms I’ve built over the past decade. If you’ve never used it or heard of it: it’s a form builder. It makes the arduous task of implementing forms trivially easy. Building a form on Wufoo means you’ll get a form that does everything right UX-wise, gives you full design control, integrates with anything, and that you can put anywhere.

The feature list is too long to cover in the confines of a single post, so I always like to cover little bits that I’ve used recently and liked.

  1. They just released a much quicker way to rename a form both in the Form Manager and inside the form itself.
  2. Don’t forget they have a robust API. I used the API to submit form entries on a form just the other day. I wanted to do some special things on a form, like be able to react to the DOM event of submitting the form. That’s not really possible when the form is in an <iframe>, but just fine when you host the form yourself and submit via API. Worked great.

Direct Link to ArticlePermalink

The post A Couple of New Wufoo Tips appeared first on CSS-Tricks.

from CSS-Tricks https://ad.doubleclick.net/ddm/trackclk/N7439.1063086.CSS-TRICKS.COM/B7043538.237730278;dc_trk_aid=434779083;dc_trk_cid=110714071;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=…

Fixed Headers, On-Page Links, and Overlapping Content, Oh My!

Let’s take a basic on-page link:

<a href="#section-two">Section Two</a>

When clicked, the browser will scroll itself to the element with that ID: <section id="section-two"></section>. A browser feature as old as browsers themselves, just about.

But as soon as we position: fixed; came into play, it became a bit of an issue. The browser will still jump to bring the newly targeted element into view, but that element may be obscured by a fixed position element, which is pretty bad UX.

I called this “headbutting the browswer window” nearly 10 years ago, and went over some possible solutions. Nicolas Gallager documented five different techniques. I’m even using a fixed position header here in v17 of CSS-Tricks, and I don’t particularly love any of those techniques. I sort of punted on it and added top padding to all my <h3> elements, which is big enough for the header to fit there.

There is a new way though! Finally!

Šime Vidas documented this in Web Platform News. There are a bunch of CSS properties that go together as part of CSS scroll snapping, but it turns out that scroll-padding and scroll-margin can be used outside of a scroll snapping container.

body {
  scroll-padding-top: 70px; /* height of sticky header */
}

This only works in Chromium browsers:

See the Pen
Scroll Padding on Fixed Postion Headers
by Chris Coyier (@chriscoyier)
on CodePen.

This is such a useful thing we shoot hoot and holler for WebKit and Firefox to do it.

The post Fixed Headers, On-Page Links, and Overlapping Content, Oh My! appeared first on CSS-Tricks.

from CSS-Tricks https://css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/…

Responsible JavaScript

We just made a note about this article by Jeremy Wagner in our newsletter but it’s so good that I think it’s worth linking to again as Jeremy writes about how our obsession with JavaScript can lead to accessibility and performance issues:

What we tend to forget is that the environment websites and web apps occupy is one and the same. Both are subject to the same environmental pressures that the large gradient of networks and devices impose. Those constraints don’t suddenly vanish when we decide to call what we build “apps”, nor do our users’ phones gain magical new powers when we do so.

It’s our responsibility to evaluate who uses what we make, and accept that the conditions under which they access the internet can be different than what we’ve assumed. We need to know the purpose we’re trying to serve, and only then can we build something that admirably serves that purpose—even if it isn’t exciting to build.

That last part is especially interesting because it’s in the same vein as what Chris wrote just the other day about embracing simplicity in our work. But it’s also interesting because I’ve overheard a lot of engineers at work asking how we might use CSS-in-JS tools like Emotion or Styled Components, both of which are totally neat in and of themselves. But my worry is about jumping to a cool tool before we understand the problem that we want to tackle first.

Jumping on a bandwagon because a Twitter celebrity told us to do so, or because Netflix uses tool X, Y or Z is not a proper response to complex problems. And this connects to what Jeremy says here:

This is not to say that inaccessible patterns occur only when frameworks are used, but rather that a sole preference for JavaScript will eventually surface gaps in our understanding of HTML and CSS. These knowledge gaps will often result in mistakes we may not even be aware of. Frameworks can be useful tools that increase our productivity,

What Are Design Tokens?

I’ve been hearing a lot about design tokens lately, and although I’ve never had to work on a project that’s needed them, I think they’re super interesting and worth jotting down a few notes about. As I understand it, the general idea is this: design tokens are an agnostic way to store variables such as typography, color, and spacing so that your design system can be shared across platforms like iOS, Android, and regular ol’ websites.

Design tokens are starting to gain a bit of momentum in the design systems community, but they’re not an entirely new concept. There’s a great talk with Jina Anne and Jon Levine from 2016 where they talk about how design tokens are used in the Lightning Design System at Salesforce. They describe the complexity of the world we’re living in where a single organization that is building multiple web apps and native applications need to feel and look the same whilst not slowing down the development team. Jina also has made an in-depth video course about design tokens and in the preview for that she writes:

With design tokens, you can capture low-level values and then use them to create the styles for your product or app. You can maintain a scalable and consistent visual system for UI development.

Let’s take just one example: you probably have a typographic scale that you want to be identical across a bunch of platforms. Instead of storing the values for that scale in a CSS file and replicating them in every app or website, they can be stored in a JSON file that will then be transformed into the code needed for all those other platforms. Something like this:

{
  "global": {
    "type": "token",
    "category": "typography"
  },
  "aliases": {
    "TYPE_SIZE_SM": {
      "value": "14px"
    },
    "TYPE_SIZE_MD": {
      "value": "25px"
    },
    "TYPE_SIZE_LG": {
      "value": "44px"
    }
  },

You could write your own code to take this JSON file and convert it into all the variables you might need, for example, a Sass file would depend upon these tokens and …

An Illustrated (and Musical) Guide to Map, Reduce, and Filter Array Methods

Map, reduce, and filter are three very useful array methods in JavaScript that give developers a ton of power in a short amount of space. Let’s jump right into how you can leverage (and remember how to use!) these super handy methods.

Array.map()

Array.map() updates each individual value in a given array based on a provided transformation and returns a new array of the same size. It accepts a callback function as an argument, which it uses to apply the transform.

let newArray = oldArray.map((value, index, array) => {
  ...
});

A mnemonic to remember this is MAP: Morph Array Piece-by-Piece.

Instead of a for-each loop to go through and apply this transformation to each value, you can use a map. This works when you want to preserve each value, but update it. We’re not potentially eliminating any values (like we would with a filter), or calculating a new output (like we would use reduce for). A map lets you morph an array piece-by-piece. Let’s take a look at an example:

[1, 4, 6, 14, 32, 78].map(val => val * 10)
// the result is: [10, 40, 60, 140, 320, 780]

In the above example, we take an initial array ([1, 4, 6, 14, 32, 78]) and map each value in it to be that value times ten (val * 10). The result is a new array with each value of the original array transformed by the equation: [10, 40, 60, 140, 320, 780].

An illustration of the code examples covered in this section.

Array.filter()

Array.filter() is a very handy shortcut when we have an array of values and want to filter those values into another array, where each value in the new array is a value that passes a specific test.

This works like a search filter. We’re filtering out values that pass the parameters we provide.

For example, if we have an array of numeric values, and want to filter them to just the values that are larger than 10, we could write:

[1, 4, 6, 14, 32, 78].filter(val => val > 

Buddy: 15 Minutes to Automation Nirvana

(This is a sponsored post.)

Deploying a website to the server in 2019 requires much more effort than 10 years ago. For example, here’s what needs to be done nowadays to deliver a typical JS app:

  • split the app into chunks
  • configure webpack bundle
  • minify .js files
  • set up staging environment
  • upload the files to the server

Running these steps manually takes time, so an automation tool seems like an obvious choice. Unfortunately, most of contemporary CI/CD software provide nothing more than infrastructure in which you have to manually configure the process anyway: spend hours reading the documentation, writing scripts, testing the outcome, and maintaining it later on. Ain’t nobody got time for that!

This is why we created Buddy: to simplify deployment to the absolute minimum by creating a robust tool whose UI/UX allows you configure the whole process in 15 minutes.

Here’s how the delivery process looks in Buddy CI/CD:

This is a delivery pipeline in Buddy. You select the action that you need, configure the details, and put it down in place—just like you’re building a house of bricks. No scripting, no documentation, no nothing. Currently, Buddy sports over 100 actions: builds, tests, deployments, notifications, DevOps tools & many more.

Super-Smooth Deployments

Buddy’s deployments are based on changesets which means only changed files are deployed – there’s no need to upload the whole repository every time.

Configuration is very simple. For example, in order to deploy to SFTP, you just need to enter authentication details and the target path on the server:

Buddy supports deployments to all popular stacks, PaaS, and IaaS services, including AWS, Google Cloud, Microsoft Azure, and DigitalOcean. Here’s a small part of the supported integrations:

Faster Builds, Better Apps

Builds are run in isolated containers with a preconfigured dev environment. Dependencies and packages are downloaded on the first execution and cached in the container, which massively improves build performance.

Buddy supports all popular web developer languages and frameworks, including Node.js, PHP, Ruby, WordPress, Python, .NET Core and Go:

Docker

Understanding Event Emitters

Consider, a DOM Event:

const button = document.querySelector("button");

button.addEventListener("click", (event) => /* do something with the event */)

We added a listener to a button click. We’ve subscribed to an event being emitted and we fire a callback when it does. Every time we click that button, that event is emitted and our callback fires with the event.

There may be times you want to fire a custom event when you’re working in an existing codebase. Not specifically a DOM event like clicking a button, but let’s say you want to emit an event based on some other trigger and have an event respond. We need a custom event emitter to do that.

An event emitter is a pattern that listens to a named event, fires a callback, then emits that event with a value. Sometimes this is referred to as a “pub/sub” model, or listener. It’s referring to the same thing.

In JavaScript, an implementation of it might work like this:

let n = 0;
const event = new EventEmitter();

event.subscribe("THUNDER_ON_THE_MOUNTAIN", value => (n = value));

event.emit("THUNDER_ON_THE_MOUNTAIN", 18);

// n: 18

event.emit("THUNDER_ON_THE_MOUNTAIN", 5);

// n: 5

In this example, we’ve subscribed to an event called “THUNDER_ON_THE_MOUNTAIN” and when that event is emitted our callback value => (n = value) will be fired. To emit that event, we call emit().

This is useful when working with async code and a value needs to be updated somewhere that isn’t co-located with the current module.

A really macro-level example of this is React Redux. Redux needs a way to externally share that its internal store has updated so that React knows those values have changed, allowing it to call setState() and re-render the UI. This happens through an event emitter. The Redux store has a subscribe function, and it takes a callback that provides the new store and, in that function, calls React Redux’s <Provider> component, which calls setState() with the new store value. You can look through the whole implementation here.

Now we have two different parts of …