Tag: Code

How to Disable Code: The Developer’s Production Kill Switch

The following is a guest post written by Carlos Schults.

Being able to disable code in production is a power that many developers aren’t aware of. And that’s a shame. The ability to switch off some portions—or even complete features—of the codebase can dramatically improve the software development process by allowing best practices that can shorten feedback cycles and increase the overall quality.

So, that’s what this post will cover: the mechanisms you can use to perform this switching off, why they’re useful and how to get started. Let’s dig in.

Why Would You Want to Disable Code?

Before we take a deep dive into feature flags, explaining what they are and how they’re implemented, you might be asking: Why would people want to switch off some parts of their codebase? What’s the benefit of doing that?

To answer these questions, we need to go back in time to take a look at how software was developed a couple of decades ago. Time for a history lesson!

The Dark Ages: Integration Hell

Historically, integration has been one of the toughest challenges for teams trying to develop software together. 

Picture several teams inside an organization, working separately for several months, each one developing its own feature. While the teams were working in complete isolation, their versions of the application were evolving in different directions. Now they need to converge again into a single, non conflicting version. This is a Herculean task. 

That’s what “integration hell” means: the struggle to merge versions of the same application that have been allowed to diverge for too long. 

Enter the Solution: Continuous Integration

“If it hurts, do it more often.” What this saying means is that there are problems we postpone solving because doing so is hard. What you often find with these kinds of problems is that solving them more frequently, before they accumulate, is way less painful—or even trivial.

So, how can you make integrations less painful? Integrate more often.

That’s continuous integration (CI) in a nutshell: Have your developers integrate their work with a public shared repository, at the very least once a day. Have a server trigger a build and run the automated test suite every time someone integrates their work. That way, if there are problems, they’re exposed sooner rather than later.

How to Handle Partially Completed Features

One challenge that many teams struggle with in CI is how to deal with features that aren’t complete. If developers are merging their code to the mainline, that means that any developments that take more than one day to complete will have to be split into several parts. 

How can you avoid the customer accessing unfinished functionality? There are some trivial scenarios with similarly trivial solutions, but harder scenarios call for a different approach: the ability to switch off a part of the code completely.

Feature Flags to the Rescue

Defining Feature Flags

There are many names for the mechanisms that allow developers to switch a portion of their code off and on. Some call them “feature toggles” or “kill switches.” But “feature flags” is the most popular name, so that’s what we’ll use for the remainder of this post. So, what are feature flags?

Put simply, feature flags are techniques that allow teams to change the behavior of an application without modifying the code. In general, flags are used to prevent users from accessing and using the changes introduced by some piece of code, because they’re not adequate for production yet for a number of reasons.

Disable Code: What Are the Use Cases?

We’ll now cover some of the most common use cases for disabling code in production.

Switching Off Unfinished Features

As you’ve seen, one of the main use cases for feature flags is preventing users from accessing features that aren’t ready for use yet.

That way, programmers developing features that are more complex and take a longer time to complete aren’t prevented from integrating their work often and benefiting from it.

Enabling A/B Testing

The adoption of feature flags enables the use of several valuable practices in the software development process, one of which is A/B testing

A/B testing is a user experience research technique that consists of comparing two versions of a website or application to decide which one to keep. It entails randomly splitting users into two groups, A and B, and then delivering a different version of the application to each group. One group might receive the current production version, which we call the “control,” whereas the second group would receive the candidate for the new version, called the “treatment.” 

The testers then monitor the behavior of both groups and determine which of the versions achieved better results. 

Feature flags are a practical way to enable A/B testing because they allow you to quickly and conveniently change between the control and treatment versions of your application.

Enabling Canary Releases

If you deliver the new version of your app to your entire userbase at once, 100 percent of your users will be impacted if the release is bad in some way. What if you could gradually roll out the new version instead? You’d first deploy to a small subset of users, monitoring that group to detect issues. If something went wrong, you could roll it back. If everything looked fine, you could then gradually release the version for larger groups. That’s a canary release in a nutshell. It’s another powerful technique that feature flags might help with.

Customizing Features According to Users’ Preferences

It’s not uncommon to have to customize your application according to the needs of specific users, and there are several ways in which software teams can accomplish that—some more efficient, and others less so (companies that create separate branches or entire repositories for each client come to mind).

This is another area where feature flags could help, allowing teams to dynamically switch between different versions of the same functionality.

Disable Code in Production 101

How do you go about disabling code? That’s what we’re going to see now, in three increasingly sophisticated phases.

First Stage: The Most Basic Approach

We start with an approach that’s so primitive, it maybe shouldn’t be considered a feature flag at all. Consider the pseudocode below:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {   // return calculateAdditionalWorkHoursSameOldWay(employee, start, end);   return calculateAdditionalWorkHoursImproved(employee, start, end); }

In the code above, we’re just commenting out the old version of some method and replacing it with a new version. When we want the older version to be used, we just do the opposite. (Well, I said it was primitive.) This approach lacks one of the most fundamental properties of a feature flag—the ability to change how the application behaves without changing its code.

However, it plants the seed for more sophisticated approaches.

Second Stage: Taking the Decision Out of the Code

The previous approach didn’t allow developers to select the desired version of the feature without changing the code. Fortunately, that’s not so hard to do. First, we introduce a logical variable to determine which version we’re going to use:

calculateAdditionalWorkHours(Employee employee, Date start, Date end) {    var result = useNewCalculation     ? calculateAdditionalWorkHoursImproved(employee, start, end)     : calculateAdditionalWorkHoursSameOldWay(employee, start, end);    return result; }

Then, we use some mechanism to be able to assign the value to the variable from an external source. We could use a configuration file:

var useNewCalculation = config[newCalculation];

Passing arguments to the application might be another option. What matters is that we now have the ability to modify how the app behaves from the outside, which is a great step toward “true” feature flagging.

Keep in mind that the code examples you see are all pseudocode. Using your favorite programming language, there’s nothing stopping you from starting with this approach and taking it up a notch. You could, for instance, use classes to represent the features and design patterns (e.g., factories) to avoid if statements.

Stage 3: Full-Fledged Feature Flag Management

The previous approach might be enough when your application has only a small number of flags. But as that number grows, things start to become messy.

First, you have the issue of technical debt. Manually implemented feature flags can create terribly confusing conditional flows in your codebase. That only grows worse with new flags being introduced each day. Additionally, they might make the code harder to understand and navigate, especially for more junior developers, which is an invitation for bugs.

Another problem is that as the number of flags grows, it becomes more and more common to forget to delete old, obsolete ones.

The main problem of a homegrown approach is that it doesn’t give you an easy way to see and manage all of your flags at once. That’s why our third and final stage is a single piece of advice: Instead of rolling out your own feature flags approach, adopt a third-party feature flag management system.

Feature Flags Are a CI/CD Enabler

We’ve covered the mechanisms developers can use to disable portions of their codebase in production without having to touch the code. This capability is powerful and enables techniques such as A/B testing and canary releases, which are all hallmarks of a modern, agile-based software development process.

The names for the techniques might vary—feature flags, feature toggles, feature flipper, and so on. The way in which the techniques are implemented can also vary—from a humble if statement to sophisticated cloud-based solutions.

But no matter what you call them, you can’t overstate the benefit these mechanisms offer. They’re an enabler of Continuous Integration, which is essential for any modern software organization that wants to stay afloat.

The post How to Disable Code: The Developer’s Production Kill Switch appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,

My Visual Studio Code Setup: Extensions and Themes

Matthias Ott’s posted his VS Code setup. I find lists like this (I rounded up some recent updates of my own) irresistible, probably because, like y’all, I spend an awful lot of time in VS Code and wanna make sure I’m getting the most out of it.

Things from the list that stood out to me:

  • I didn’t realize Bracket Pair Colorizer had gone v2 and it’s a separate install.
  • I din’t realize you needed an extension to honor .editorconfig files.
  • I wasn’t using anything for PHP, but Matthias listed PHP Intelephense and I’m giving it a whirl. It has fewer users than the non-weirdly named one though? And when I installed that, I saw Format HTML in PHP which I’m also trying because, yes, please! (Even Prettier’s PHP add-on can’t do that.)

Messing with extensions is also a good opportunity to clear out old crap.

Also super interesting…

The main point of that series is cleaning up the interface of VS Code in extreme ways. All the way down to:

Direct Link to ArticlePermalink

The post My Visual Studio Code Setup: Extensions and Themes appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

Some Little Improvements to My VS Code Workflow (Workspaces, Icons, Tasks)

I did a little thing the other day that I didn’t know was possible until then. I had a project folder open in VS Code like I always do, and I added another different root folder to the window. I always assumed when you had a project open, it was one top level root folder and that’s it, if you needed another folder elsewhere open, you would open that in another window. But nope!

We kind of have a “duo repo” thing going on at CodePen (one is the main Ruby on Rails app, and one is our microservices), and now I can open them both together:

Multiple folders open at once. This means I don’t need to deal with my symlinks anymore.

Now I can search across both projects and basically just pretend like it’s one big project.

When you do that for the first time and then close the VS Code window, it will ask you if you want to save a “Workspace.” Meh, maybe later, I always thought. I knew what it meant, but I was too lazy to deal with it. It’ll make a file, I thought, and I don’t really have a place for files like that. (I’d avoid the repo itself, just because I don’t want to force my system on anyone else.)

Well, I finally got over it and did it. I chucked all my .code-workspace files into a local folder. They are actually quite useful as files, because I can put the files in my Dock and one-click open my Workspace just how I like it.

Custom Workspace icons

Workspace files have special little icons like this:

The icon is a little generic, but I like it. A document with a little tiny VS Code icon below it.

Since I’m putting these in my Dock, I saw that as a cool opportunity to make them into custom icons! That’ll make it super clear for me and a little more delightful to use since I’ll probably reach for them many times a day.

Taking a little inspiration from the original, I snagged the SVG logo and plopped it on the bottom-right of my project logos.

Changing logos on macOS is as simple as “Get Info” on the file, clicking the logo in that panel, then pasting the image.

Now I can keep them in my Dock and open everything with a single click:

Launch terminal commands when opening a project

Now that I have these really handy one-click icons for opening my projects, I thought, “How cool would it be if it kicked off the commands to start the project too!” Apparently, that’s what Tasks are for, and it wasn’t too hard to set up (thanks, Andrew!). Right next to that settings file, at .vscode/tasks.json, is where I have this:

{   "version": "2.0.0",   "tasks": [     {       "label": "Run Gulp",       "type": "shell",       "command": "gulp",       "task": "default",       "presentation": {         "focus": false,         "panel": "shared",         "showReuseMessage": true,         "clear": true       },       "runOptions": {         "runOn": "folderOpen"       }     }   ] } 

That kicks off the command gulp for me whenever I open this Workspace. I guess you have to run the task once manually (Terminal → Run Task) so that it has the right permissions, then it works from there on out.

Overrides

I don’t think this is specific to Workspaces necessarily, but I really like how you can have a file like .vscode/settings.json in a project folder to override VS Code settings for a particular project.

For example, here on CSS-Tricks, I have a super basic Sass setup where Gulp preprocesses .scss into .css. That’s all fine, but it’s likely that I’ll search for a selector at some point. I don’t need to see it in .css because I’m not working in vanilla CSS. Like ever. I can put this in that settings file, and know that it’s just for this project, rather than all my projects:

{   "search.exclude": {     "**/*.css": true,   } }

The post Some Little Improvements to My VS Code Workflow (Workspaces, Icons, Tasks) appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , ,
[Top]

Fake Code

Here’s a fun little idea from Knut Synstad. You give it the URL of a GitHub Gist and it converts the Gist into grayscale rounded blobs (SVG) that sorta look like code if you squint. Maybe fun for interesting dynamic backgrounds or for whatever you might use code-looking stock art for.

SVG blobs that look like code.

It reminded me of Christian Naths’s Redacted font, which turns every glyph into a box or squiggles.


And if you need some actual totally fake code, Harry Parton’s Pen is nice for that:

The post Fake Code appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Tips for Writing Animation Code Efficiently

I’ve been coding web animations and helping others do the same for years now. However, I have yet to see a concise list of tips focused on how to efficiently build animations, so here you go!

I will be using the GreenSock Animation Platform (GSAP). It provides a simple, readable API and solves cross-browser inconsistencies so that you can focus on animating. The code and concepts should be understandable even if you’ve never used GSAP. If you’d like to familiarize yourself with the basics of GSAP first so that you can get the most out of this article, the best place to begin is GSAP’s getting started page (includes a video). 

Tip #1: Use an animation library

Some developers think that using an animation library is wasteful because they can just use native browser technologies like CSS transitions, CSS animations or the Web Animations API (WAAPI) to accomplish the same thing without loading a library. In some cases, that’s true. However, here are a few other factors to consider:

  • Browser bugs, inconsistencies, and compatibility: An animation library, like GSAP, solves these for you and is universally compatible. You can even use motion paths in IE9! There are many problematic areas when it comes to cross-browser issues, including handling transform-origin on SVG elements, path stroke measurements, 3D origins in Safari, and many more that we don’t have the space to list.
  • Animation workflow: Building even moderately complex animations is much faster and more fun with a tool like GSAP. You can modularize animations, nest them as deeply as you want, and have their timing adjusted automatically. This makes it so much easier to experiment. Trust me: once you try building an animation sequence in CSS and then in GSAP, you’ll see what I mean. Night and day! Future edits are faster too.
  • Animate beyond the DOM: Canvas, WebGL, generic objects, and complex strings can’t be animated with native technologies. Using one consistent tool for all your animations is much cleaner. 
  • Runtime control: Using a good animation library can enable you to pause, resume, reverse, seek through, or even gradually change the speed of an entire animation sequence. You can control each transform component independently (rotation, scale, x, y, skew, etc.). You can also retrieve those values at any time as well. JavaScript animations give you ultimate flexibility.
  • Easing options (bounce, elastic, etc.): CSS only gives you two control points for eases. GSAP’s CustomEase lets you literally create any ease you can imagine. 
  • Lag smoothing: GSAP can prioritize absolute timing or adjust things on the fly to avoid jumps if the CPU gets bogged down.
  • Advanced capabilities: Using GSAP, it’s easy to morph SVGs, add physics/inertia, edit motion paths directly in the browser, use position-aware staggers, and more.

Most of the top animators in the industry use a tool like GSAP because they’ve learned these same things over the years. Once you get beyond very basic animations, a JavaScript library will make your life much, much easier and open up entirely new possibilities. 

Tip #2: Use timelines

A good animation library will provide some way of creating individual animations (called tweens) and a way to sequence animations in a timeline. Think of a timeline like a container for your tweens where you position them in relation to one another. 

const tl = gsap.timeline();  tl.to(".box", { duration: 1, x: 100 })   .to(".box", { duration: 1, backgroundColor: "#f38630" }, "+=0.5")    .to(".box", { duration: 1, x: 0, rotation: -360 }, "+=0.5") 

By default in GSAP, tweens added to a timeline will wait for the previous tweens to complete before running. The +=0.5 adds an additional offset or delay of a half-second as well, so the second tween will start 0.5 seconds after the first tween finishes no matter how long the first tween’s duration is.

To increase the amount of time between the tween to 1 second, all you need to do is change the +=0.5 to +=1! Super easy. With this approach, you can iterate on your animations quickly without worrying about doing the math to combine previous durations.

Tip #3: Use relative values

By “relative values” I mean three things:

  1. Animate values relative to their current value. GSAP recognizes += and -= prefixes for this. So x: "+=200" will add 200 units (usually pixels) to the current x. And x: "-=200" will subtract 200 from the current value. This is also useful in GSAP’s position parameter when positioning tweens relative to one another.
  2. Use relative units (like vw, vh and, in some cases, %) when values need to be responsive to viewport size changes.
  3. Use methods like .to() and .from() (instead of .fromTo()) whenever possible so that the start or end values are dynamically populated from their current values. That way, you don’t need to declare start and end values in every tween. Yay, less typing! For example, if you had a bunch of differently-colored elements, you could animate them all to black like gsap.to(".class", {backgroundColor: "black" }).

Tip #4: Use keyframes

If you find yourself animating the same target over and over in a row, that’s a perfect time to use keyframes! You do so like this:

gsap.to(".box", { keyframes: [   { duration: 1, x: 100 },   { duration: 1, backgroundColor: "#f38630", delay: 0.5 },    { duration: 1, x: 0, rotation: -360, delay: 0.5 } ]});

No timeline necessary! To space out the tweens we just use the delay property in each keyframe. (It can be negative to create overlaps.)

Tip #5: Use smart defaults

GSAP has default values for properties like ease ("power1.out") and duration (0.5 seconds). So, the following is a valid tween that will animate for half a second.

gsap.to(".box", { color: "black" })

To change GSAP’s global defaults, use gsap.defaults():

// Use a linear ease and a duration of 1 instead gsap.defaults({ ease: "none", duration: 1 });

This can be handy, but it’s more common to set defaults for a particular timeline so that it affects only its children. For example, we can avoid typing duration: 1 for each of the sub-tweens by setting a default on the parent timeline:

const tl = gsap.timeline({ defaults: { duration: 1 } });  tl.to(".box", { x: 100 })   .to(".box", { backgroundColor: "#f38630" }, "+=0.5")    .to(".box", { x: 0, rotation: -360 }, "+=0.5") 

Tip #6: Animate multiple elements at once

We mentioned this briefly in the third tip, but it deserves its own tip.

If you have multiple elements that share the same class of .box, the code above will animate all of the elements at the same time!

You can also select multiple elements with different selectors by using a more complex selector string:

gsap.to(".box, .circle", { ... });

Or you can pass an array of variable references as long as the elements are of the same type (selector string, variable reference, generic object, etc.):

var box = document.querySelector(".box"); var circle = document.querySelector(".circle");  // some time later… gsap.to([box, circle], { ... });

Tip #7: Use function-based values, staggers, and/or loops

Function-based values

Use a function instead of a number/string for almost any property, and GSAP will call that function once for each target when it first renders the tween. Plus, it’ll use whatever gets returned by the function as the property value! This can be really handy for creating a bunch of different animations using a single tween and for adding variance.

GSAP will pass the following parameters into the function:

  1. The index
  2. The specific element being affected
  3. An array of all of the elements affected by the tween

For example, you could set the movement direction based on the index:

Or you could choose items from an array:

Staggers

Make your animations look more dynamic and interesting by offsetting the start times with a stagger. For simple staggered offsets in a single tween, just use stagger: 0.2 to add 0.2 seconds between the start time of each animation.

You can also pass in an object to get more complex stagger effects, including ones that emanate outward from the center of a grid or randomize the timings:

For more information about GSAP’s staggers, check out the stagger documentation.

Loops

It can be helpful to loop through a list of elements to create or apply animations, particularly when they are based on some event, like a user’s interaction (which I’ll discuss later on). 

To loop through a list of items, it’s easiest to use .forEach(). But since this isn’t supported on elements selected with .querySelectorAll() in IE, you can use GSAP’s utils.toArray() function instead.

In the example below, we are looping through each container to add animations to its children that are scoped to that container.

Tip #8: Modularize your animations

Modularization is one of the key principles of programming. It allows you to build small, easy-to-understand chunks that you can combine into larger creations while still keeping things clean, reusable, and easy to modify. It also lets you to use parameters and function scope, increasing the re-usability of your code.

Functions

Use functions to return tweens or timelines and then insert those into a master timeline:

function doAnimation() {   // do something, like calculations, maybe using arguments passed into the function      // return a tween, maybe using the calculations above   return gsap.to(".myElem", { duration: 1, color: "red"}); }  tl.add( doAnimation() );

Nesting timelines can truly revolutionize the way you animate. It lets you sequence really complex animations with ease while keeping your code modular and readable.

function doAnimation() {   const tl = gsap.timeline();   tl.to(...);   tl.to(...);   // ...as many animations as you’d like!    // When you’re all done, return the timeline   return tl; }  const master = gsap.timeline(); master.add( doAnimation() ); master.add( doAnotherAnimation() ); // Add even more timelines! 

Here’s a real-world use case modified from Carl Schooff’s “Writing Smarter Animation Code” post.

Here’s a more complex demo showing the same technique using a Star Wars theme by Craig Roblewsky:

Wrapping your animation-building routines inside functions also makes recreating animations (say, on resize) a breeze!

var tl; // keep an accessible reference to our timeline  function buildAnimation() {   var time = tl ? tl.time() : 0; // save the old time if it exists    // kill off the old timeline if it exists   if (tl) {     tl.kill();   }    // create a new timeline   tl = gsap.timeline();   tl.to(...)     .to(...); // do your animation   tl.time(time); // set the playhead to match where it was }  buildAnimation(); //kick things off  window.addEventListener("resize", buildAnimation); // handle resize

Effects

With effects, you can turn a custom animation into a named effect that can be called anytime with new targets and configurations. This is especially helpful when you have standards for your animations or if you are going to be calling the same animation from different contexts.

Here’s a super-simple “fade” effect to show the concept:

// register the effect with GSAP: gsap.registerEffect({     name: "fade",     defaults: {duration: 2}, //defaults get applied to the "config" object passed to the effect below     effect: (targets, config) => {         return gsap.to(targets, {duration: config.duration, opacity:0});     } });  // now we can use it like this: gsap.effects.fade(".box"); // Or override the defaults: gsap.effects.fade(".box", {duration: 1}); 

Tip #9: Use control methods

GSAP provides many methods to control the state of a tween or timeline. They include .play(), .pause(), .reverse(), .progress(), .seek(), .restart(), .timeScale(), and several others. 

Using control methods can make transitions between animations more fluid (such as being able to reverse part way through) and more performant (by reusing the same tween/timeline instead of creating new instances each time). And by giving you finer control over the state of the animation, it can help with debugging as well.

Here’s a simple example:

One amazing use case is tweening the timeScale of a timeline!

Use case: interaction events that trigger animations

Inside of event listeners for user interaction events, we can use control methods to have fine control over our animation’s play state.

In the example below, we are creating a timeline for each element (so that it doesn’t fire the same animation on all instances), attaching a reference for that timeline to the element itself, and then playing the relevant timeline when the element is hovered, reversing it when the mouse leaves.

Use case: Animating between multiple states of a timeline

You may want a set of animations to affect the same properties of the same elements, but only in certain sequences (e.g. active/inactive states, each with mouseover/mouseout states). It may get tricky to manage. We can simplify it by using states of a timeline and control events. 

Use case: Animating based on the scroll position

We can easily fire animations based on the scroll position by using control methods. For example, this demo plays a full animation once a scroll position has been reached:

You can also attach the progress of an animation to the scroll position for more fancy scroll effects!

But if you’re going to do this, it’s best to throttle the scroll listener for performance reasons:

Hot tip: GreenSock is working on a plugin to make scroll-based animations even easier! You’re in for quite a treat. Keep your eyes peeled for news.

Bonus tip: Use GSAP’s plugins, utility methods, and helper functions

GSAP plugins add extra capabilities to GSAP’s core. Some plugins make it easier to work with rendering libraries, like PixiJS or EaselJS, while other plugins add superpowers like morphing SVG, drag and drop functionality, etc. This keeps the GSAP core relatively small and lets you add features when you need them.

Plugins

MorphSVG morphs between any two SVG shapes, no matter the number of points, and gives you fine control over how the shapes are morphed.

DrawSVG progressively reveals (or hides) the stroke of an SVG element, making it look like it’s being drawn. It works around various browser bugs that affect typical stroke-dashoffset animations.

MotionPath animates anything (SVG, DOM, canvas, generic objects, whatever) along a motion path in any browser. You can even edit the path in-browser using MotionPathHelper!

GSDevTools gives you a visual UI for interacting with and debugging GSAP animations, complete with advanced playback controls, keyboard shortcuts, global synchronization and more.

Draggable provides a surprisingly simple way to make virtually any DOM element draggable, spinnable, tossable, or even flick-scrollable using mouse or touch events. Draggable integrates beautifully (and optionally) with InertiaPlugin so the user can flick and have the motion decelerate smoothly based on momentum.

CustomEase (along with CustomBounce and CustomWiggle) add to GSAP’s already extensive easing capabilities by enabling you to register any ease that you’d like.

SplitText is an easy to use JavaScript utility that allows you to split HTML text into characters, words and lines. It’s easy to use, extremely flexible, works all the way back to IE9, and handles special characters for you.

ScrambleText scrambles the text in a DOM element with randomized characters, refreshing new randomized characters at regular intervals, while gradually revealing your new text (or the original) over the course of the tween. Visually, it looks like a computer decoding a string of text.

Physics2D lets you tween the position of elements based on velocity and acceleration as opposed to going to specific values. PhysicsProps is similar but works with any property, not just 2D coordinates.

Utility methods

GSAP has built-in utility methods that can make some common tasks easier. Most are focused on manipulating values in a particular way, which can be especially helpful when generating or modifying animation values. The ones that I use most often are .wrap(), .random, .interpolate(), .distribute(), .pipe(), and .unitize(), but there are many others you might find helpful.

Helper functions

In a similar light, but not built into GSAP’s core, are some helper functions GreenSock has created over the years to deal with specific use cases. These functions make it easy to FLIP your animations, return a random number based on an ease curve, blend two ease curves, and much more. I highly recommend checking them out!

Conclusion

You’ve made it to the end! Hopefully, you’ve learned a thing or two along the way and this article will continue to be a resource for you in the years to come.

As always, if you have any questions about GSAP, feel free to drop by the GreenSock forums. They’re incredibly helpful and welcoming! As an employee of GreenSock, that’s where I hang out often; I love helping people with animation-related challenges!

The post Tips for Writing Animation Code Efficiently appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Rethinking Code Comments

Justin Duke asks if treating code comments like footnotes could help us understand the code in a file better. In his mockup, all the comments are hidden by default and require a click to reveal:

What a neat idea! Justin’s design reminds me of the way that Instapaper treated inline footnotes.

Instapaper (circa 2012)

I guess the reason I like this idea so much is that a lot of comments don’t need to be read constantly, — they’re sort of a reminder that, “Hey, this needs work in the future” or “Yikes, this is weird and I’m sorry.” Keeping these comments out of the code makes it much easier to scan the whole file, too.

I do wonder if there could be a toggle that shows every comment, just in case you need to read all the comments in sequence rather than clicking to toggle each one.

Anyway, all this talk about comments reminds me of an absolutely fantastic talk by Sarah Drasner at JSConf this year where she discussed why comments are so dang hard to get right:

Direct Link to ArticlePermalink

The post Rethinking Code Comments appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Web Component for a Code Block

We’ll get to that, but first, a long-winded introduction.

I’m still not in a confident place knowing a good time to use native web components. The templating isn’t particularly robust, so that doesn’t draw me in. There is no state management, and I like having standard ways of handling that. If I’m using another library for components anyway, seems like I would just stick with that. So, at the moment, my checklist is something like:

  • Not using any other JavaScript framework that has components
  • Templating needs aren’t particularly complex
  • Don’t need particularly performant re-rendering
  • Don’t need state management

I’m sure there is tooling that helps with these things and more (the devMode episode with some folks from Stencil was good), but if I’m going to get into tooling-land, I’d be extra tempted to go with a framework, and probably not framework plus another thing with a lot of overlap.

The reasons I am tempted to go with native web components are:

  • They are native. No downloads of frameworks.
  • The Shadow DOM is a true encapsulation in a way a framework can’t really do.
  • I get to build my own HTML element that I use in HTML, with my own API design.

It sorta seems like the sweet spot for native web components is design system components. You build out your own little API for the components in your system, and people can use them in a way that is a lot safer than just copy and paste this chunk of HTML. And I suppose if consumers of the system wanted to BYO framework, they could.

So you can use like <our-tabs active-tab="3"> rather than <div class="tabs"> ... <a href="#3" class="tab-is-active">. Refactoring the components certainly gets a lot easier as changes percolate everywhere.

I’ve used them here on CSS-Tricks for our <circle-text> component. It takes the radius as a parameter and the content via, uh, content, and outputs an <svg> that does the trick. It gave us a nice API for authoring that abstracted away the complexity.

So!

It occurred to me a “code block” might be a nice use-case for a web component.

  • The API would be nice for it, as you could have attributes control useful things, and the code itself as the content (which is a great fallback).
  • It doesn’t really need state.
  • Syntax highlighting is a big gnarly block of CSS, so it would be kinda cool to isolate that away in the Shadow DOM.
  • It could have useful functionality like a “click to copy” button that people might enjoy having.

Altogether, it might feel like a yeah, I could use this kinda component.

This probably isn’t really production ready (for one thing, it’s not on npm or anything yet), but here’s where I am so far:

Here’s a thought dump!

  • What do you do when a component depends on a third-party lib? The syntax highlighting here is done with Prism.js. To make it more isolated, I suppose you could copy and paste the whole lib in there somewhere, but that seems silly. Maybe you just document it?
  • Styling web components doesn’t feel like it has a great story yet, despite the fact that Shadow DOM is cool and useful.
  • Yanking in pre-formatted text to use in a template is super weird. I’m sure it’s possible to do without needing a <pre> tag inside the custom element, but it’s clearly much easier if you grab the content from the <pre>. Makes the API here just a smidge less friendly (because I’d prefer to use the <code-block> alone).
  • I wonder what a good practice is for passing along attributes that another library needs. Like is data-lang="CSS" OK to use (feels nicer), and then convert it to class="language-css" in the template because that’s what Prism wants? Or is it better practice to just pass along attributes as they are? (I went with the latter.)
  • People complain that there aren’t really “lifecycle methods” in native web components, but at least you have one: when the thing renders: connectedCallback. So, I suppose you should do all the manipulation of HTML and such before you do that final shadowRoot.appendChild(node);. I’m not doing that here, and instead am running Prism over the whole shadowRoot after it’s been appended. Just seemed to work that way. I imagine it’s probably better, and possible, to do it ahead of time rather than allow all the repainting caused by injecting spans and such.
  • The whole point of this is a nice API. Seems to me thing would be nicer if it was possible to drop un-escaped HTML in there to highlight and it could escape it for you. But that makes the fallback actually render that HTML which could be bad (or even theoretically insecure). What’s a good story for that? Maybe put the HTML in HTML comments and test if <!-- is the start of the content and handle that as a special situation?

Anyway, if you wanna fork it or do anything fancier with it, lemme know. Maybe we can eventually put it on npm or whatever. We’ll have to see how useful people think it could be.

The post Web Component for a Code Block appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

The Three Types of Code

Every time I start a new project, I organize the code I’m looking at into three types, or categories if you like. And I think these types can be applied to any codebase, any language, any technology or open source project. Whether I’m writing HTML or CSS or building a React component, thinking about these different categories has helped me figure out what to refactor and prioritize, and what to leave alone for now.

Those categories: Boring Code, Salt Mine Code, and Radioactive Code.

Let me explain.

Boring Code

Boring code is when it makes perfect sense when you read it. There’s no need to refactor it, and it performs its function in a way that doesn’t make you want to throw yourself into a river. Boring code is good code. It doesn’t do a kick-flip and it’s not trying to impress you. You can use it without having to write even more code or engineer hacks on top of it. Boring code does exactly what it says on the tin and never causes any surprises.

This function makes sense, this prop is clearly named, this React component is straightforward. There are no loops within loops, no mental gymnastics required here.

However, boring code is near impossible to write because our understanding of it is almost always incomplete when we start tackling a problem. Just look at how many considerations can go into a styling a simple paragraph for contrast. To write boring code, we must be diligent, we must endlessly refactor, and we must care for the codebase beyond a paycheck at the end of the month.

Boring code is good because boring code is kind.

Salt Mine Code

This is the type of code that’s bonkers and makes not a lick of sense. It’s the sort of code that we can barely read but it’s buried so deep in the codebase that it’s near impossible to change anyway. However! It’s not leaking into other parts of our code, so we can mostly ignore it. It might not be pretty, and we probably don’t want to ever look at it so long as we live, but it’s not actively causing any damage.

It’s this type of code that we can mostly forget about,. It’s the type of code that is dangerous if opened up and tampered with, but for now, everything is okay.

The trouble is buried deep.

Radioactive Code

Radioactive code is the real problem at the heart of every engineering team. It’s the let’s-not-go-to-work-today sort of code. It’s the stuff that is not only bad but is actively poisoning our codebase and making everything worse over time. Imagine a codebase as a nuclear reactor; radioactive code is the stuff that’s breached the container and is now leaking into every part of our codebase.

An example? For us at Gusto and on the design systems team, I would consider our form components to be radioactive. Each component causes more problems because we can never use the component as is; we have to hack it to get what we want. Each time anyone uses this code they have to write even more code on top of it, making things worse over time, and it encourages everyone on the team to do the same.

In our design system, when we want to add a class name to the div that wraps a form element, we must use the formFieldClass prop in one component, and wrapperClass in another. There is a propType called isDefaultLayout and everyone sets it to false and writes custom CSS classes on top of it. In other words, not only does radioactive code make it hard for us to understand all this nonsense code, it makes it increasingly difficult to understand other parts of the codebase, too. Because the file we’re looking at right now has dependencies on eight different things that we cannot see. The result of removing this radioactive code means changing everything else that depends upon it.

In other words, radioactive code — like our form components — makes it impossible for the codebase to be trusted.

Radioactive code is not only bad for us and our codebase, but it is also bad for our team. It encourages bad habits, cruelty in Slack threads, not to mention that it causes friction between team members that is hard to measure. Radioactive code also encourages other teams in a company to go rogue and introduce new technologies into a codebase when the problem of radioactive code is not the tech itself. Anyone can write this type of code, regardless of the language or the system or the linting when they’re not paying enough attention to the problem. Or when they’re trying to be a little too smart. Or when they’re trying to impress someone.

How do we fix radioactive code? Well, we must draw a circle around it and contain the madness that’s leaking into other parts of the codebase. Then we must do something utterly heroic: we must make it boring.

The post The Three Types of Code appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

Weekly Platform News: Impact of Third-Party Code, Passive Mixed Content, Countries with the Slowest Connections

In this week’s roundup, Lighthouse sheds light on third-party scripts, insecure resources will get blocked on secure sites, and many country connection speeds are still trying to catch up to others… literally.


Measure the impact of third-party code during page load

Lighthouse, Chrome’s built-in auditing tool, now shows a warning when the impact of third-party code on page load performance is too high. The pre-existing “Third-party usage” diagnostic audit will now fail if the total main-thread blocking time caused by third-parties is larger than 250ms during page load.

Note: This feature was added in Lighthouse version 5.3.0, which is currently available in Chrome Canary.

(via Patrick Hulce)

Passive mixed content is coming to an end

Currently, browsers still allow web pages loaded over a secure connection (HTTPS) to load images, videos, and audio over an insecure connection. Such insecurely-loaded resources on securely-loaded pages are known as “passive mixed content,” and they represent a security and privacy risk.

An insecurely-loaded image can allow an attacker to communicate incorrect information to the user (e.g., a fabricated stock chart), mutate client-side state (e.g., set a cookie), or induce the user to take an unintended action (e.g., changing the label on a button).

Starting next February, Chrome will auto-upgrade all passive mixed content to https:, and resources that fail to load over https: will be blocked. According to data from Chrome Beta, auto-upgrade currently fails for about 30% of image loads.

(via Emily Stark)

Fast connections are still not common in many countries

Data from Chrome UX Report shows that there are still many countries and territories in the world where most people access the Internet over a 3G or slower connection. (This includes a number of small island nations that are not visible on this map.)

(via Paul Calvano)

More news…

Read even more news in my weekly Sunday issue that can be delivered to you via email every Monday morning.

More News →

The post Weekly Platform News: Impact of Third-Party Code, Passive Mixed Content, Countries with the Slowest Connections appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , , , , , ,
[Top]

Wufoo Cracks the Code for Forms So You Don’t Have To

There was a lot of buzz about forms last week when Jason Grisby pointed to a missing pattern attribute on Chipotle’s order form that could have been used to help-through millions of dollars in orders. Adrian Roselli followed that up with the common mistake of forgetting for and id attributes on form inputs and the potential cost of it.

Forms are hard. And that’s without thinking about more complex features, like building conditional logic into questions, getting into validation, triggering emails on submission, handling inputs on different devices, storing submissions, or integrating with other services, among many, many other things. Forms aren’t just hard, they are downright complicated.

That’s why I’m glad there’s a company like Wufoo that has all of that sorted out. There’s been many a time where I convince myself I can build a form myself only to abandon the idea for an embedded Wufoo form instead.

Why Wufoo? First off, it’s been around forever. They focus on forms and forms alone, so I’m confident they know exactly what they’re doing. I get all the semantic markup I want based on their tried and tested product and adding it to my (or any other) site is as easy as dropping in a snippet.

Plus, Wufoo continues to innovate! They’re releasing new features all the time. Just this past month, they shipped a new Zapier integration that opens up a ton of possibilities, like sending submissions to a Google spreadsheet, firing off submission notifications in Slack, creating Trello cards from submissions, and more. And again, that’s on top of an already stacked featured set that offers everything from multi-page forms and showing and hiding fields conditionally to collecting payments and allowing file uploads over a secure encrypted connection.

You can see where we use Wufoo here on CSS-Tricks to power the contact form. What’s cool about that simple form is we can direct email notifications to specific inboxes based on the contact selection. It even integrates with Mailchimp, so we can offer an option to sign up for our newsletter directly in the contact form.

We also decided to use Wufoo to improve the way we accept guest posts (and you should definitely submit an idea). We used to lean on plain ol’ email and the contact form, but using Wufoo has allowed us to level up so we can collect more details about a post submission upfront and tailor the form based on the type of submission it is.

I’d say Wufoo is great for any type of form. It handles anything you throw at it, easily integrates into any site, and helps prevent costly mistakes that are apparently worth gobs of cash for some companies.

The post Wufoo Cracks the Code for Forms So You Don’t Have To appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]