Archive for July, 2021

A Shared ESLint Configuration

July 30th, 2021 No comments

Looks like it was almost 9 years ago when Airbnb first published their JavaScript Style Guide. 112k stars on GitHub later, it seems like the de facto preset for Babel / ES Lint. But it’s not the only company out there with public ES Lint setups. Katy recently shared Mapbox’s setup.

ESLint plugins will help keep your code consistent and improve the quality, but they are also excellent teaching tools. When I come across a plugin, I take joy in reading each rule to learn the benefits of enabling or disabling it.

Katy DeCorah, “A shared ESLint configuration”

Sophisticated linting as-you-author is one of those things that has really upped the game of development over the years.

Direct Link to ArticlePermalink

The post A Shared ESLint Configuration appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Conjuring Generative Blobs With The CSS Paint API

July 30th, 2021 No comments
Points 0,0 in the top-left corner, 960, 40 in the center and 1920, 1040 in the bottom left written in purple. in an otherwise blank white space.

As we begin to write our “render” code, this is good to keep in mind.

How our blob is formed, an overview

Before we write any code, I’d like to show you a little SVG animation of how we will create our blob shape. If you are a visual learner like me, you may find an animated reference helpful for understanding this kind of thing:

CodePen Embed Fallback

To break this process down into three steps:

  1. Plot several equally spaced points around the radius of a circle.
  2. Pull each point a random amount towards the center of the circle.
  3. Draw a smooth curve through each of the points.

Now, things are about to get a tiny bit maths-y but don’t worry. We’ve got this!

Defining the blob’s control points

To start, let’s define the radius of our blob. The blob’s radius determines how large or small it is.

We want our blob shape to always “fit” inside the element it is painted on. To ensure this is the case, we check the width and height of the worklet’s target element and set the blob’s radius accordingly. Our blob is essentially a weird circle, and a circle’s total width/height will always be equal to its radius multiplied by two, so we divide this value to match. Let’s add some code to achieve this in our paint() function:

const radius = Math.min(geometry.width, geometry.height) / 2;

Here’s an image to help explain what is happening here:

Cool! Now that we know what the radius of our blob should be, we can initialize its points:

const points = [];

const center = {
  x: geometry.width / 2,
  y: geometry.height / 2,

const angleStep = (Math.PI * 2) / numPoints;

for (let i = 1; i <= numPoints; i++) {
  const angle = i * angleStep;
  const point = {
    x: center.x + Math.cos(angle) * radius,
    y: center.y + Math.sin(angle) * radius,

Phew! In this snippet, we “walk” around the circumference of a circle, plopping down some equally spaced points as we go. How does this work?

To start, we define an angleStep variable. The maximum angle between two points on the circumference of a circle is Pi × 2. By dividing Pi × 2 by the number of “points” we would like to create, we have the desired (equally spaced) angle between each point.

Next, we loop over each point. For each of these points, we define an angle variable. This variable is our angleStep multiplied by the point’s index. Given a radius, an angle, and a center point for a circle, we can use Math.cos() and Math.sin() to plot each point.

Note: If you would like to learn a little more about trigonometric functions, I wholeheartedly recommend Michelle Barker’s

The CSS Paint API (part of the magical Houdini family) opens the door to an exciting new world of design in CSS. Using the Paint API, we can create custom shapes, intricate patterns, and beautiful animations — all with a touch of randomness — in a way that is portable, fast, and responsive.

We are going to dip our toes into the bubbling cauldron of generative CSS magic by creating my favorite shape, the blob. Random blobs are a great starting point for anyone new to generative art/design, and we will be learning the CSS Paint API as we go, so this is an ideal starting point for folks who are new to this world. You’ll be a generative CSS magician in no time!

Let’s hop on our broomsticks and conjure up some shapes.


For some folks reading this, generative art may be an unfamiliar topic. If you are already comfortable with generative art/design, feel free to hop down to the next section. If not, here’s a little example:

Imagine, for a moment, that you are sitting at a desk. You have three stamps, some dice, and a piece of paper. Each of the stamps has a different shape on it. There is a square, a line, and a circle. You roll the dice. If the dice land on one, you use the square stamp on the page. If the dice lands on two, you use the line stamp. If it lands on three, you use the circle stamp. If the dice reads four, five, or six, you do nothing. You repeat the roll-and-stamp process until the page fills with shapes — this is generative art!

It can seem a little scary at first, but really, that’s all “generative” means — something created with an element of chance/unpredictability. We define some rules and let a source of randomness guide us to an outcome. In the “analog” example above, the randomness source is some dice. When we are working in the browser, it could be Math.random() or another similar function.

To bring things back to the land of ones and zeros for a moment, this is what the above example would look like if written in code:

CodePen Embed Fallback

Pretty cool, eh? By defining some simple rules and actioning them at random, we have created a unique pattern. In this tutorial series, we will use generative techniques just like this to create exciting user interfaces.

What is the CSS Paint API, and what’s a worklet?

The CSS Paint API allows us low-level access to CSS itself(!) through an HTML5 -like drawing API. We can harness this power with something called a worklet.

Worklets, in short, are JavaScript classes. Each worklet class must have a paint() function. A worklet’s paint() function can programmatically create an image for any CSS property that expects one.

For example:

.my-element {
  background-image: paint(texture);

Here, we have a fictional texture worklet that generates a beautiful (I’ll leave this up to your imagination), programmatic texture. Where we might usually assign a url(...) value to the background-image property, we instead call paint(worklet_name) — this runs the worklet’s paint() function and renders the output to the target element.

We will be getting into how to write worklets in detail shortly, but I wanted to give you a quick primer on what they are before I start talking about them.

What we are building

So, in this tutorial, we will be building a generative blob worklet. Our worklet will take a few input parameters (as CSS Custom Properties, more on this a little later) and return a beautiful, random blob shape.

Let’s get started by checking out some examples of the finished worklet in action — if a picture paints a thousand words, a CodePen must paint a million, right?

The blob worklet, as a background image

First, here’s a demo of the blob worklet just hanging out on its own, generating a value for the background-image property of an element:

CodePen Embed Fallback

I encourage you to look at the CSS for the above CodePen, change the custom properties, resize the element, and see what happens. See how the shape resizes fluidly and updates when the custom properties change? Don’t worry about understanding how this works right now. At this stage, we are only concerned with what we are building.

Generative image masks, a practical use case

Awesome, now that we have seen the “standalone” worklet, let’s check out how we can use it. In this example, the worklet functions as a generative image mask:

CodePen Embed Fallback

The result (I think) is rather striking. The worklet adds a natural, eye-catching curve to the design. In addition, the mask shape is different each time the page loads, which is a fantastic way to keep the UI fresh and exciting — click “rerun” on the CodePen above to see this effect in action. This ever-changing behavior is subtle, for sure, but I hope it will bring folks who notice it a little bit of joy. The web can be quite a cold, sterile place, and generative touches like this can make it feel a lot more organic!

Note: I’m certainly not suggesting we all start making our entire interfaces change at random. That would be terrible for usability! This kind of behavior works best when applied sparingly and only to presentational elements of your website or app. Think blog post headers, hero images, subtle background patterns, etc.

Now, this is just one example (and simple one, at that), but I hope it gives you some ideas on how you could use the blob worklet in your own design and development. For anyone looking for some extra inspiration, a quick Dribbble search for “blobs” should give you a whole heap of ideas!

Wait, do I need the CSS Paint API to make blobs?

In short, no!

There are, in fact, a plethora of ways to make blobs to use in your UI design. You could reach for a tool like Blobmaker, do some magic with border-radius, use a regular element, whatever! There are tons of roads leading to blob city.

None of these, however, are quite the same as using the CSS Paint API. Why?

Well, to name a few reasons…

It allows us to be expressive in our CSS

Instead of dragging around sliders, tweaking radii, or endlessly clicking “regenerate” in the hope that a perfect blob comes our way, we can use just a few human-readable values to get what we need.

For example, the blob worklet we will be building in this tutorial takes the following input properties:

.worklet-target {
  --blob-seed: 123456;
  --blob-num-points: 8;
  --blob-variance: 0.375;
  --blob-smoothness: 1;
  --blob-fill: #000;

Need your blobs to be super subtle and minimal? Reduce the --blob-variance custom property. Need them to be detailed and overstated? Bring it up!

CodePen Embed Fallback

Fancy redesigning your site in a more brutalist direction? No problem! Instead of re-exporting hundreds of assets or custom coding a bunch of border-radius properties, simply reduce the --blob-smoothness custom property to zero:

CodePen Embed Fallback

Handy, eh? The CSS Paint API, through worklets, allows us to create ever-unique UI elements that fit right in with a design system.

Note: I am using GSAP in the examples above to animate the input properties of the paint worklet we are building in this tutorial.

It is super performant

It just so happens that generative work can get a little heavy, computation-wise. We often find ourselves looping through lots of elements, performing calculations, and other fun stuff. When we factor in that we may need to create multiple programmatic, generative visuals on a page, performance issues could become a risk.

Luckily for us, CSS Paint API worklets do all their magic outside of the main browser thread. The main browser thread is where all of the JavaScript we usually write exists and executes. Writing code this way is perfectly OK (and generally preferable), **but it can have limitations. When we try and do too much on the main browser thread, the can UI become sluggish or even blocked.

As worklets run on a different thread to the main website or app, they will not “block” or slow down the interface. Additionally, this means that the browser can spin up lots of separate worklet instances that it can call on when needed — this is similar to containerization and results in blazing fast performance!

It won’t clutter the DOM

Because the CSS Paint API essentially adds an image to a CSS property, it doesn’t add any extra elements to the DOM. To me, this feels like a super clean approach to creating generative visual elements. Your HTML structure remains clear, semantic, and unpolluted, while your CSS handles how things look.

Browser support

It is worth noting that the CSS Paint API is a relatively new technology, and although support is growing, it is still unavailable in some major browsers. Here is a browser support table:

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


Chrome Firefox IE Edge Safari
65 No No 79 No

Mobile / Tablet

Android Chrome Android Firefox Android iOS Safari
92 No 92 No

Although browser support is still a little thin on the ground — in this tutorial, we will be looking at how to use the css-paint-polyfill maintained by GoogleChromeLabs to make sure users in all browsers can enjoy our creations.

We will, additionally, be looking at how to “fail gracefully” when the CSS Paint API is unsupported. A polyfill means extra JavaScript weight, so for some folks, it is not a viable solution. If this is you, don’t worry. We will be exploring browser support options for everyone.

Let’s code!

OK, OK! We know what we are building and why the CSS Paint API rocks — now let’s get coding! First things first, let’s get a development environment spun up.

Note: if you get a little lost at any point during in this tutorial, you can view a finished version of the worklet.

A simple development environment

To get us started, I have created a worklet-starter-kit repository. As a first step, pop on over to GitHub and clone it. Once you have cloned and navigated inside the repo, run:

npm install

Followed by:

npm run start

Once you have run the above commands, a simple development server fires up in the current directory, and your default browser opens. As worklets must be loaded either over HTTPS or from localhost — this setup ensures that we can use our worklet without any CORS issues. The starter kit also handles automatically refreshing the browser when we make any changes.

As well as serving our content and providing a basic live reload, this repository features a simple build step. Powered by esbuild, this process bundles up any JavaScript imports inside our worklet and outputs the result to a worklet.bundle.js file. Any changes made in worklet.js are automatically reflected in worklet.bundle.js.

If you have a poke around the repository, you might notice that there is already some HTML and CSS kicking around. We have a simple index.html file with a single worklet-canvas div, alongside some CSS to center it on the page and scale it to the viewport. Think of this as a blank canvas for all of your worklet experimentation!

Initializing our worklet

OK, now that we have our development environment up and running, it’s time to create our worklet. Let’s start by navigating to the worklet.js file.

Note: Remember, worklet.bundle.js is automatically generated by our build step. We don’t ever want to edit this file directly.

In our worklet.js file, we can define our Blob class and register it with the registerPaint function. We pass two values to registerPaint — the name we would like our worklet to have (in our case, blob) and the class that defines it:

class Blob {}

registerPaint("blob", Blob);

Excellent! We just took the first step towards creating our blobs!

Adding a paint() function

Now, not much is happening yet, so let’s add a simple paint() function to our Blob class to check things are working OK:

paint(ctx, geometry, properties) {
  console.log(`Element size is ${geometry.width}x${geometry.height}`);

  ctx.fillStyle = "tomato";
  ctx.fillRect(0, 0, geometry.width, geometry.height);

We can think of this paint() function like a callback. It runs, initially, when the worklet’s target element first renders. After this, any time the element’s dimensions change or the worklet’s input properties update, it runs again.

When the paint() function is called, it automatically has a few values passed through it. In this tutorial, we are making use of the first three:

  1. context — a 2D drawing context similar to that of a element, we use this to draw things.
  2. geometry — an object containing the width and height of the target element
  3. properties — an array of custom properties

Now that we have a simple paint() function defined, let’s pop over to the index.html file and load our worklet. To do so, we are going to add a new just before our closing tag:

  if (CSS["paintWorklet"] !== undefined) {

Note: we are registering the bundled version of our worklet!

Excellent. Our blob worklet is now loaded and ready for use in our CSS. Let’s use it to generate a background-image for our worklet-canvas class:

.worklet-canvas {
  background-image: paint(blob);

Once you have added the above snippet, you should see a red square. Our worklet is alive! Nice work. If you resize the browser window, you should see the worklet-canvas element’s dimensions printed in the browser console. Remember, the paint() function runs whenever the worklet target’s dimensions change.

Defining the worklet’s input properties

To allow our worklet to generate beautiful blobs, we need to help it out and pass it some properties. The properties we need are:

  • --blob-seed — a “seed” value for a pseudorandom number generator; more on this in a moment
  • --blob-num-points — how detailed the blob is based on the number of points used along the shape
  • --blob-variance — how varied the blob’s control points are
  • --blob-smoothness — the smoothness/sharpness of the blob’s edges
  • --blob-fill — the blob’s fill color

Let’s tell our worklet that it will receive these properties and that it needs to watch them for changes. To do so, we can head back over to our Blob class and add an inputProperties getter:

static get inputProperties() {
  return [

Cool. Now that our worklet knows what input properties to expect, we should add them to our CSS:

.worklet-canvas {
  --blob-seed: 123456;
  --blob-num-points: 8;
  --blob-variance: 0.375;
  --blob-smoothness: 1;
  --blob-fill: #000;

Now, at this point, we could use the CSS Properties and Values API (another member of the Houdini family) **to assign some defaults and make these custom properties a little easier to parse in our worklet. Unfortunately, however, at this moment, the Properties and Values API does not have the best browser support.

For now, to keep things simple, we are going to leave our custom properties as they are — relying on some basic parsing functions in our worklet instead.

Heading back to our worklet class for a moment, let’s add these utility functions:

propToString(prop) {
  return prop.toString().trim();

propToNumber(prop) {
  return parseFloat(prop);

In the absence of the Properties and Values API, these simple utility functions will help us convert the properties passed to paint() to usable values.

Using our new helper functions, we can parse properties and define some variables to use in our paint() function. Let’s remove the old “debug” code, too:

paint(ctx, geometry, properties) {
  const seed = this.propToNumber(properties.get("--blob-seed"));
  const numPoints = this.propToNumber(properties.get("--blob-num-points"));
  const variance = this.propToNumber(properties.get("--blob-variance"));
  const smoothness = this.propToNumber(properties.get("--blob-smoothness"));
  const fill = this.propToString(properties.get("--blob-fill"));

If you log any of these variables, you should see that the properties made available by the paint() function map exactly to the Custom Properties we defined in our CSS a moment ago.

If you open up dev-tools, inspect the worklet-canvas element, and change any of these custom properties — you should see that the logs re-run and reflect the updated value. Why? Our worklet reacts to any changes to its input properties and re-runs its paint() function when it detects them.

OK, folks, it’s time to start forming our blob shape. To do this, we need a way of generating random numbers. After all, this is what will make our blobs generative!

Now, you may be thinking, “Hey, we can use Math.random() for this!” and in many ways, you would be right on. There is, however, a problem with using a “regular” random number generator in CSS Paint API worklets. Let’s check it out.

The problem with Math.random()

We noticed earlier how a worklet’s paint() function runs rather often. If we use a method such as Math.random() to generate random values within paint() — they will be different each time the function executes. Different random numbers mean a different visual result every time the worklet re-renders. We do not want this at all. Sure, we want our blobs to be random, but only at the point of conception. They shouldn’t change once they exist on the page unless we explicitly tell them to do so.

I found this concept a little tricky to get my head around at first, so I have made a couple of CodePens (best viewed in a browser that natively supports the CSS Paint API) to help demonstrate. In the first example, we have a worklet that sets a random background color, using Math.random():

Warning: resizing the element below will result in a flash of color.

CodePen Embed Fallback

Try resizing the element above and notice how the background color changes as it updates. For some niche applications and fun demos, this might be what you want. In most practical use-cases, though, it isn’t. Aside from being visually jarring, behavior like this could be an accessibility issue for users who are sensitive to motion. Imagine that your worklet contained hundreds of dots that all started flying around and flashing whenever something on the page changed size!

Luckily for us, this issue is quite simple to fix. The solution? A pseudorandom number generator! Pseudorandom number generators (or PRNGs) generate random numbers based on a seed. Given the same seed value, a PRNG always returns the same sequence of random numbers — this is perfect for us, as we can re-initialize the PRNG every time the paint() function runs, ensuring the same sequence of random values!

Here’s a CodePen demonstrating how a PRNG works:

CodePen Embed Fallback

Click “generate” to choose some random numbers — then, click “generate” a few more times. Notice how the sequence of numbers is the same each time you click? Now, try changing the seed value, and repeat this process. The numbers will be different from the previous seed value, but consistent across generations. This is the beauty of a PRNG. Predictable randomness!

Here’s the random-background-color CodePen again, using a PRNG rather than Math.random():

CodePen Embed Fallback

Ah! Much better! The element has a random color set when the page loads, but the background color does not change when it resizes. Perfect! You can test this out by clicking “Rerun” on the CodePen above, and resizing the element.

Adding pseudorandom numbers to our worklet

Let’s go ahead and add a PRNG function above our Blob class definition:

// source:
function mulberry32(a) {
  return function () {
    a |= 0;
    a = (a + 0x6d2b79f5) | 0;
    var t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;

Now, I’d be lying if I said I understand quite literally anything this function is doing. I discovered this beautiful little snippet of code through Jake Archibald’s excellent article on being predictably random with the CSS Paint API, and have used it in a ton of work since. You can find the original repository for this function over at GitHub — it includes a whole heap of excellent PRNGs and is certainly worth a look.

Note: while I don’t fully understand how this function works, I know how to use it. Often, when working in the generative world (if you are anything like me, anyway!), you will find yourself in this situation. When you do, don’t worry! It is absolutely OK to use a snippet of code to create some art/design without knowing exactly how it works. We can learn by doing, and that’s awesome.

OK, great, we have a PRNG function. Let’s add it to paint():

const random = mulberry32(seed);

In this snippet, we call mulberry32() with our --blob-seed custom property as its seed value, and it returns a brand new function. This new function — random — returns a random number between zero and one.

Lovely, let’s put our shiny new PRNG to use.

A quick aside: Drawing with the CSS Paint API

When working with CSS Paint API worklets, just like HTML , we draw everything inside a 2D context. This context has a width and a height. For worklets, the width and height of this context always matches that of the element the worklet is painting to.

Say, for example, we wanted to add a point to the center of a 1920x1080px context, we could visualize it like so:

As we begin to write our “render” code, this is good to keep in mind.

How our blob is formed, an overview

Before we write any code, I’d like to show you a little SVG animation of how we will create our blob shape. If you are a visual learner like me, you may find an animated reference helpful for understanding this kind of thing:

CodePen Embed Fallback

To break this process down into three steps:

  1. Plot several equally spaced points around the radius of a circle.
  2. Pull each point a random amount towards the center of the circle.
  3. Draw a smooth curve through each of the points.

Now, things are about to get a tiny bit maths-y but don’t worry. We’ve got this!

Defining the blob’s control points

To start, let’s define the radius of our blob. The blob’s radius determines how large or small it is.

We want our blob shape to always “fit” inside the element it is painted on. To ensure this is the case, we check the width and height of the worklet’s target element and set the blob’s radius accordingly. Our blob is essentially a weird circle, and a circle’s total width/height will always be equal to its radius multiplied by two, so we divide this value to match. Let’s add some code to achieve this in our paint() function:

const radius = Math.min(geometry.width, geometry.height) / 2;

Here’s an image to help explain what is happening here:

Cool! Now that we know what the radius of our blob should be, we can initialize its points:

const points = [];

const center = {
  x: geometry.width / 2,
  y: geometry.height / 2,

const angleStep = (Math.PI * 2) / numPoints;

for (let i = 1; i <= numPoints; i++) {
  const angle = i * angleStep;
  const point = {
    x: center.x + Math.cos(angle) * radius,
    y: center.y + Math.sin(angle) * radius,

Phew! In this snippet, we “walk” around the circumference of a circle, plopping down some equally spaced points as we go. How does this work?

To start, we define an angleStep variable. The maximum angle between two points on the circumference of a circle is Pi × 2. By dividing Pi × 2 by the number of “points” we would like to create, we have the desired (equally spaced) angle between each point.

Next, we loop over each point. For each of these points, we define an angle variable. This variable is our angleStep multiplied by the point’s index. Given a radius, an angle, and a center point for a circle, we can use Math.cos() and Math.sin() to plot each point.

Note: If you would like to learn a little more about trigonometric functions, I wholeheartedly recommend Michelle Barker’s excellent series!

Now that we have some perfect, beautiful, equally spaced points positioned around the circumference of a circle — we should mess them up. To do so, we can “pull” each one, a random amount, towards the circle’s center.

How can we do this?

First, let’s add a new lerp function (short for linear interpolation) just below where we defined mulberry32:

function lerp(position, target, amt) {
  return {
    x: (position.x += (target.x - position.x) * amt),
    y: (position.y += (target.y - position.y) * amt),

This function takes a start-point, an end-point, and an “amount” value between zero and one. The return value of this function is a new point, placed somewhere between the start and end points.

In our worklet, just below where we define the point variable in our for-loop, we can use this lerp function to “pull” the point towards the center position. We store the modified point in our points array:

points.push(lerp(point, center, variance * random()));

For the linear interpolation amount, we use our --blob-variance property multiplied by a random number generated by random() — as random() always returns a value between zero and one, this amount will always be somewhere between zero, and our --blob-variance number.

Note: A higher --blob-variance will result in crazier blobs, as each point can end up closer to the center.

Drawing the curve

So, we have our blob’s points stored in an array. Right now, though, they aren’t used for anything! For the final step in our blob creation process, we will draw a smooth curve through each of them.

To draw this curve, we are going to use something called a Catmull-Rom spline. A Catmull-Rom spline is, in short, a great way of drawing a smooth Bézier curve through any number of { x, y } points. With a spline, we don’t have to worry about any tricky control point calculation. We pass in an array of points, and get a beautiful, organic curve back. No sweat.

Let’s head over to the start of our worklet.js file and add the following import:

import { spline } from "@georgedoescode/generative-utils";

Then install the package like so:

npm i @georgedoescode/generative-utils

This spline function is quite sizeable and a little complex. For this reason, I have packaged it up and added it to my generative-utils repository, a small collection of handy generative art utilities.

Once we have imported spline — we can use it in our worklet’s paint() function like this:

ctx.fillStyle = fill;

spline(points, smoothness, true, (CMD, data) => {
  if (CMD === "MOVE") {
  } else {


Note: Place this snippet just after your for-loop!

We pass in our points, --blob-smoothness property, and a flag to let spline know it should return a closed shape. In addition, we use our --blob-fill custom property to set the fill color of the blob. Now, if we take a look at our browser window, we should see something like this!

Hooray! We did it! The spline function has successfully drawn a smooth curve through each of our points, thus making a gorgeous (and random) blob shape. If you would like your blob to be a little less rounded, try reducing the --blob-smoothness property.

Now, all we need to do is add a touch more randomness.

A random, random seed value

Right now, our blob’s PRNG seed is a fixed value. We defined this --blob-seed custom property in our CSS earlier, with a value of 123456 — this is great, but it means that the random numbers generated by random() and, therefore, the blob’s core shape, is always the same.

For some instances, this is ideal. You may not want your blobs to be random! You may want to choose some perfect seed values and use them across your site as part of a semi-generative design system. For other cases, though, you may want your blobs to be random — just like the image mask example I showed you earlier.

How can we do this? Randomize the seed!

Now, this isn’t quite as simple as it might seem. Initially, when I was working on this tutorial, I thought, “Hey, I can initialize the seed value in the Blob class’s constructor!” Unfortunately, though, I was wrong.

Since the browser may spin up multiple instances of a worklet to handle calls to paint() — one of several Blob classes may end up rendering the blob! If we initialize our seed value inside the worklet class, this value will be different across instances, and could lead to the visual “glitching” we discussed earlier.

To test this out, add a constructor function to your Blob class with the following code inside:

constructor() {
  console.log(`My seed value is ${Math.random()}`);

Now, check out your browser console, and resize the window. In most cases, you get multiple logs with different random values. This behavior is no good for us; we need our seed value to be constant.

To solve this issue, let’s add a little JavaScript on the main thread. I am popping this in the tag we created earlier:

  .style.setProperty("--blob-seed", Math.random() * 10000);

Excellent! Now when refreshing the browser window, we should see a new blob shape each time.

For our simple demo, this is perfect. In a “real” application, you may want to create a .blob class, target all instances of it on load, and update the seed value of each element. You could also experiment with setting the blob’s variance, number of points, and roundness properties to random values.

For this tutorial, though, that’s it! All we have left to do is make sure our code works OK for users in all browsers, or provide a suitable fallback for when it doesn’t.

Loading a polyfill

By adding a polyfill, our CSS Paint API code will work in all major browsers, with the cost of extra JavaScript weight. Here’s how we can update our CSS.paintWorklet.addModule code to add one to our example:

(async function () {
  if (CSS["paintWorklet"] === undefined) {
    await import("");

Using this snippet, we only load the polyfill if the current browser does not support the CSS Paint API. Nice!

A CSS-based fallback

If extra JavaScript weight isn’t your vibe, that’s cool. I totally get it. Luckily, using @supports, we can define a lightweight, CSS-only fallback for browsers that do not support the CSS Paint API. Here’s how:

.worklet-canvas {
  background-color: var(--blob-fill);
  border-radius: 49% 51% 70% 30% / 30% 30% 70% 70%;

@supports (background: paint(blob)) {
  .worklet-canvas {
    background-color: transparent;
    border-radius: 0;
    background-image: paint(blob);

In this snippet, we apply a background-color and a blob-like border-radius (generated by fancy border radius) to the target element. If the CSS Paint API is supported, we remove these values and use our worklet to paint a generative blob shape. Awesome!

The end of the road

Well, folks, we’re all done. To quote the Grateful Dead — what a long, strange trip it’s been!

I know, there’s a lot to take in here. We have covered core generative art concepts, learned all about the CSS Paint API, and made some awesome generative blobs while we were at it. Not bad going at all, I say.

Now that we have learned the basics, though, we are ready to start creating all kinds of generative magic. Keep an eye out for more generative UI design tutorials from me soon, but in the meantime, try and take what we have learned in this tutorial and experiment! I’m sure you have a ton of fantastic ideas.

Until next time, fellow CSS magicians!

The post Conjuring Generative Blobs With The CSS Paint API appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

GitHub Explains the Open Graph Images

July 29th, 2021 No comments

An explanation of those new GitHub social media images:

[…] our custom Open Graph image service is a little Node.js app that uses the GitHub GraphQL API to collect data, generates some HTML from a template, and pipes it to Puppeteer to “take a screenshot” of that HTML.

Jason Etcovich on The GitHub Blog in “A framework for building Open Graph images”

It’s so satisfying to produce templated images from HTML and CSS. It’s the perfect way to do social media images. If you’re doing it at scale like GitHub, there are a couple of nice tricks in here for speeding it up.

Direct Link to ArticlePermalink

The post GitHub Explains the Open Graph Images appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Developer-Friendly Passwordless Auth

July 29th, 2021 No comments

I’d wager to say that most websites that are business-minded have accounts. A way to log into them. Social media sites, eCommerce sites, CMS systems, you name it, having accounts people log into is at the heart of them. So… make it good. That’s what Magic does (great name!).

Have you heard that language used in a sign-in system like “email me a magic link to sign in”? Well, now you know what can power it. But Magic isn’t just that, it’s all types of auth, including social logins and WebAuthn. Magic is a developer SDK that enables passwordless login in all these methods.

Magic is for teams of any size. Upon signing up, you’ll get $85 in credit which covers 10,000 logins, and each login is $0.0085 after that. That kind of pricing makes it extremely affordable for apps of any size. Small apps will have tiny (or no) bill, and by the time you have tens or hundreds of thousands of users, the cost will feel negligible. Especially considering all the time you saved by not rolling auth from scratch.

Why Magic? What does it offer?

Magic appeals to developers because:

  1. Superior developer experience. It’s easy to use and it’s fast to implement.
  2. Metered pricing — only pay for what you need. Also save money by avoiding the technical debt of your own auth.
  3. The ability to adapt to future authentication methods. Auth is always evolving.
  4. Don’t have to to deal with passwords — less security concerns.
  5. Next-gen security infastructure.

I really like all those, but especially #3. I think of it like image CDNs that offer optimization. The world of images is always evolving as well, and a good image CDN will evolve to support the latest formats and optimization techniques without any work on your end. So too with Magic and Auth.

The “J” and the “a” in Jamstack originally referred to “JavaScript” and “APIs”, which is exactly what Magic offers. Magic fits the Jamstack model very nicely. No server? No problem. Even though Magic absolutely has server-side offerings, and Jamstack could use things like cloud functions, you can get auth done entirely client-side if you’d like. Here’s a great (quick!) tutorial on that.

Here’s the most important thing though: Great UX. Users really like it when the auth of an app feels easy and is never a blocker for them using your app. That’s gonna help your conversion rates.

How do you implement Magic?

First, you need an account. I found it satisfying, of course, that they dog food their own auth signup process, giving you a taste for what you can have right away.

From here, you can scaffold an app out super quickly. The great DX continues here as they offer a way to scaffold out a working app right off the bat:

That’s a web-based starter, for which they have docs, examples, and live demos.

I was able to port a demo over to CodePen Projects super quickly. Check it out!

That’s just a client-side web version. The core of it is really this simple:

import { Magic } from 'magic-sdk'

const m = new Magic(API_KEY)

They’ve got server-side support for Node, Python, Ruby, PHP and Go. Magic is for apps of any scale, including incredibly security-sensitive apps. For example, you can even use client-side auth but then use AWS services, with their Hardware Security Modules (HSMs) and all.

Magic has SDK’s for React Native, iOS, Android, and of course native web. Then in addition to the email magic link style signup, they have social login support for Google, Facebook, Apple, GitHub, GitLab, Bitbucket, Linkedin, Twitter, and Discord. Phew! That’s a lot of support for a lot of things. Magic has you covered.

While I was plucking away with this and logging in myself, I could see all the action on my dashboard.

No Passwords

It’s notable that with Magic, there are literally no passwords. Magic email link flow means users need no passwords, and with social logins, users only need to be logged into that other service, not remember/save a password unique to your app. That’s the Magic thesis, which they spell out clearly in Passwords Suck:

Using passwords is a nightmare. No one wants to memorize yet another passphrase when our heads are already filled with them. Passwords are a huge vector for security breaches precisely because they place the burden of choosing unique and secure secrets on the user, who just can’t be bothered. We end up having one password for all the important stuff like banking, work, and school, one for the social-medias, and one for all the miscellaneous one-off services we don’t care too much about. The result is that a whopping 59% of people reuse their passwords across services, which means a leak anywhere quickly becomes a liability for the whole web.

Going password-less is good for users and good for the web.

Get Started

I’d encourage you to check it out. You can sign up for free, no credit card required, and if you do that today you’ll get 10,000 free logins on your account to try out. If you love it, and you have fellow industry folks you refer to Magic, you get 3,000 bonus logins — up to 90,000 in total.

The post Developer-Friendly Passwordless Auth appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

16 Free Websites for Learning to Code in 2021

July 29th, 2021 No comments

The best free online coding websites for beginners are hubs of education and insight, designed to take your knowledge and career to the next level.

For years, technical careers have been gaining more attention among innovative individuals. In a digital world, people capable of speaking computer language often have the widest selection of job opportunities. However, before you can start leveraging the blossoming job market, you need to hone your skills. That’s where free coding websites come in.

A free online coding website is an environment where you can develop your understanding of various kinds of code, update your programming prowess, and even earn certifications. Today, we’re going to be looking at some of the most impressive coding websites on the market.

Coding Careers: Opportunities in 2021 and Beyond

Before we leap into our overview of the best free coding websites, let’s examine why it’s so important to invest in your coding role. Looking at the US Bureau of Labor Statistics, we see that coders earn an average of $89,190 per year.

Elsewhere, CompTIA notes that technology hiring has accelerated since the end of 2020, with up to 391,000 new positions opening in the US during December.

Though coding careers have been popular for some time now, they have particularly high value following the pandemic, as companies worldwide adapt to the changes associated with remote workforces, digital customer service, and ecommerce. The pandemic has made us more reliant on technology than ever before, as a result:

  • Coding skills are in high demand: Coding skills are essential for the newly digital world. Studies find that the pandemic has accelerated digital transformation by around 7 years. Companies need coding professionals to stay ahead of the curve.
  • Coding knowledge is becoming more versatile: Companies are looking for coding skills in more than just programmers. They want their data analysts, IT workers, artists, designers, and other professionals to have these talents too.
  • People with coding talent can earn more: Jobs requiring coding skills tend to pay more than those that don’t. This reveals the growing need for coding knowledge in the digital ecosystem.

Coding skills provide an avenue to tech professionals for higher-income jobs, and these careers are growing faster on average than other job opportunities.

The Best Websites for Learning to Code

Learning to code or developing your existing coding skills can help you to unlock a host of new opportunities. Today, you can learn coding online for free, just by visiting the right websites.

Even a basic knowledge of coding can drive a range of results, such as helping to support the better management of websites, reducing reliance on outside developers, and opening the door to app development. So whether you want to start a new career or upgrade your existing knowledge, these sites will help:


BitDegree is a wonderful website for anyone interested in web development, coding, data science, and programming. There are various courses to choose from, depending on the career path you want to take. For instance, you can learn about the AWS cloud or start your journey into gaming development. For coding, BitDegree covers languages like:

  • CSS
  • HTML
  • PHP
  • SQL
  • JavaScript
  • jQuery

The best thing about BitDegree is how it makes learning so fun. There are gamified courses and sections where you can really dive into the essentials of coding. In addition, the online coding course collection often features hundreds of discounted options for people on a budget.


One of the most popular sites for learning how to code for free, CodeAcademy is home to over 24 million students who have built their skills. The interactive learning approach lets you apply what you’ve learned immediately. Over 300 million hours of free coding content are available to check out at your leisure. Like most coding platforms, you can learn languages such as:

  • CSS
  • JavaScript
  • HTML
  • PHP
  • jQuery
  • Python
  • PHP
  • Ruby

CodeAcademy is particularly effective for beginners because you get instant feedback after submitting your coding efforts. When you make mistakes, you’ll find out exactly where you went wrong, allowing you to avoid similar mistakes in the future.


Codewars by Qualified is definitely one of the most versatile free platforms for learning how to code. There are dozens of languages you can learn – too many to list right here. Options range from C++ and C# to Ruby, Python, Lean, Java, PHP, Scala, and countless others.

Codewars teaches you your programming language in-depth by selecting challenges designed to put your mind to the test. The goal for each challenge is to help you sharpen your knowledge over time, with tasks that get progressively more difficult over time.

The cool thing about Codewars is it allows you to see how you respond to challenges compared to how other coders have tackled the same issues.


Designed for a younger community of would-be coders, is an engaging and highly accessible introduction to coding. With around 60 million students worldwide, the platform gives you access to a wide range of different learning opportunities intended to suit different needs and learning levels.

The environment is built on a desire to bring coding into the standard curriculum. You can dive into full one-hour tutorials, or you can experiment with a more structured approach to learning, which is ideal for people with different learning styles. There’s also a huge catalog of courses extending from basic coding for younger kids all the way to University-level education.

Free Code Camp

A diverse option in our free coding website list, Free Code Camp is all about developing your coding knowledge while simultaneously networking with other like-minded people in the industry. The solution allows you to learn coding by participating in challenges – which is ideal if you want to put your skills to the test as soon as possible.

To help you jump in, you’ll have access to a range of courses and tutorials designed to help you understand and overcome each challenge. You can even code for non-profits on the platform and build tradeable projects in languages like:

  • HTML5
  • Javascript
  • Node.JS
  • CSS3
  • React.JS
  • Databases
  • Git

If you’re a little nervous about the concept of coding alone, you’ll have a full community to work within the Free Code Camp. You might even meet someone you can work with in the years ahead.

Code Conquest

Code Conquest is less of a course website and more of a comprehensive guide for beginners diving into the world of code. This amazing platform will help you understand all of the basics of coding in no time – even if you’re brand-new to the landscape. You can find out what coding is all about, learn which languages are best to learn for your needs, and more.

The website is full of resources for all kinds of coders, including comprehensive tutorials, reviews, a knowledge center, training packs, and more. You can even choose from a range of languages like:

  • CSS
  • HTML
  • PHP
  • jQuery
  • Ruby
  • JavaScript
  • Python
  • MySQL

To help you figure out where you should get started, the Code Conquest website also gives you recommendations on which tutorials to take next.


One of the better-known free websites for coding on the market today, W3Schools is an environment packed full of example codes, resources, tutorials, exercises, and libraries to help you learn how to code. The site is one of the largest in the world for developers.

To begin coding with W3 Schools, you’ll need to choose the programming language that’s right for you, then either jump into the program immediately or select from a range of learning options. The site comes with a handy quiz to help you define your knowledge level.

Languages range from CSS to SQL, JavaScript, HTML, Python, Java, C++, and many more.

Code Avengers

Code Avengers offers a fun and interactive approach to learning how to program and code. There are various course options to teach you how to create everything from games and apps to entire websites. The good thing about the Code Avengers website is you don’t need a lot of spare time to start learning. Each course takes around 12 hours to complete.

You can choose from languages like HTML, CSS, Python, jQuery, JavaScript, and more, and connect with a wide selection of similar coding enthusiasts, just like you. The biggest downside is that the free trial only lasts for seven days before you’ll need to pay to use the full program.

The Code Player

A simple and effective website for learning how to code and building your existing skills. There are tons of videos and demos to walk you through the process of learning how to code from scratch. All you need to do is click on one of the things you want to learn how to do, like creating a simple web page, and the site will give you a video walkthrough.

Though a little simple compared to other coding resources, the Code Player still has a lot of great video guidance to help beginners jump into various languages. For example, you can learn about CSS and HTML or check out various tools to help you make a more effective website.


If you’re particularly interested in learning about Java, the CodeGym is probably the website for you. This online Java programming course teaches you the basics of Java by allowing you to dive into various tasks. You can get involved with various exercises depending on your existing skill level and play around with games designed to teach you more about the coding landscape.

This website is fantastic for people in all stages of the coding journey. Whenever you suggest a solution to a challenge, the website will give you immediate feedback to learn from. There are more than 500 hours of Java coding exercises and educational resources to explore.

The Odin Project

One of the better-known free coding websites on the market, the Odin Project aims to take the headaches and frustration out of learning web development. If you’re a beginner looking to develop a career in coding, then the Odin Project will give you all the pieces of the puzzle required to decide exactly where you want to go and build the appropriate skills.

This site offers a full-stack curriculum of coding education options, with tons of challenges, tasks, and exercises to help you put your newly gained knowledge to the test. You’ll learn how to program in languages like CSS and HTML, explore the basics of JavaScript and Ruby, and even get tips on how to get hired when your skills are maxed out.

Plural Sight

Previously known as Code School, Plural Sight is a fantastic online learning platform that allows you to build your knowledge through a range of paid and free courses. The comprehensive platform is organized into a wide selection of different learning paths. You can choose how you want to develop your skills based on your chosen language and your existing skillset.

You choose an education path created by professional instructors to achieve specific outcomes, and Plural Sight gives you all the material you need. You can also practice what you’ve learned during the course in your browser and get immediate feedback on what you need to work on. There’s even a gamification aspect that allows you to earn points for every course level you complete.

MIT Open Courseware

Imagine how amazing it would be to get accepted to MIT to learn your new coding skills? What if you didn’t have to go through the headache of an official application. If you have a computer and internet access, you can explore MIT’s course material easily through the MIT Open Courseware website. This dedicated website gives you an insight into all of the courses and materials learned by students at MIT.

You can browse through all the courses available in the programming landscape and filter through results based on things like course features. For instance, you might specifically look for courses with their own online textbook, lecture notes, and videos. It’s a great way to get an insight into how one of the most reputable universities in the world offers coding education.

Web Fundamentals

We’ve already looked at a website offering coding resources specifically for Java, now let’s take a look at one designed for HTML5. Launched about 11 years ago as HTML5 Rocks, the Web Fundamentals website is packed full of tutorials, resources, and insights into the most recent updates to HTML5. This open-source environment allows developers and programmers to really get active with their skills.

You can play around with some of the code already available on the website, and explore tutorials authored by a range of amazing individuals. Although these courses are very comprehensive, it’s worth noting that they might not be the perfect choice for true beginners, as the tutorials can be more complex than most.

Dash General Assembly

If you’re keen to learn the essentials of coding in some of the most popular languages, like CSS, JavaScript, and HTML, then Dash General Assembly is the site for you. This website offers fun and free courses which will guide you through the basics of web development. You even get interactive tasks and challenges you can leverage within your browser, with no downloads required.

Users learn how to do a range of amazing things with this website, including how to code HTML5, build a beautiful website, and balance your layouts for aesthetic appeal and usability. You can even design dynamic interfaces where you can add aminations and effects. Dash General Assembly is a fantastic tool for anyone keen to get started in the world of coding.

Finally, promises beginners a fast and simple way to start learning how to code, while having plenty of fun. This exciting website immerses you within a digital story which takes you on an adventure through the basics of coding. You’ll need to learn real-life coding skills to navigate your way through the rest of the story, which means you can develop your C# knowledge as you go.

This is one of the more unique tools for learning how to code that we’ve found so far. It’s a great way to discover the basics of C# without being bogged down in boring lectures. Remember, though, this website is intended for complete beginners, so you might find it a little basic if you already know some of the coding essentials.

Free Websites for Learning to Code

Free coding websites are an excellent way to develop your skills and unlock new opportunities in the world of coding. If you’re keen to jump into a new career as a programmer or coding developer, make sure you check out some of the options above. There’s no doubt you’ll find a site capable of giving you the boost you need.


Featured image via Unsplash.


The post 16 Free Websites for Learning to Code in 2021 first appeared on Webdesigner Depot.

Categories: Designing, Others Tags:

How to improve your graphic design process

July 29th, 2021 No comments
person using track pad

Graphic design is integral for enterprises that want to develop a viable online presence. From website design to social media posts and more, the power of good graphics is evident across the World Wide Web. 

So, unsurprisingly, graphic design is a highly sought-after skill. Interestingly, 71% of companies create ten times more design assets than they used to in order to support the different channels. As a result, the demand for graphic designers is quite high.

But as the saying goes, there is always room for improvement. Most graphic designers devise their own process to reach their desired output, but it is always possible to streamline it further. 

Let’s discuss how to optimize the structure of your graphic design process and the best practices to follow.

How you should structure your graphic design process 

Of course, some special projects involve specific processes, but you can follow a general format to make sure you can complete it on time without compromising quality. The key steps to follow are:

  1. Create a briefing

The creative brief is often the first step of the graphic design process. It helps the designer better understand the needs of the client, who can be internal or external to the company. This is a critical step because designers need all the necessary information about their clients, the company, and expectations.

The brief serves as the foundation on which you begin working on the project, meaning it affects the entire process. To ensure that the brief is easy to understand and well organized, you should use third-party tools. 

  1. Brainstorm ideas

The brainstorming process is an important step and can only be done once you have entirely understood your client’s brief. To generate ideas for your design, start by grabbing a paper and pen to analyze the purpose of the design.

Consider the thoughts and emotions that you want to trigger through your design. Also, dig deeper to tap into the message you want it to convey. Focus on these points while you come up with ideas. Be sure not to think too hard, though; let your ideas flow because you never know what may end up inspiring a brilliant design. 

For more inspiration, search for ideas on the internet or communities and platforms specifically for designers – more on that later in the article, so keep reading!

  1. Create first sketch & drafts

This step involves the designer drawing up rough sketches based on the ideas they generated. It can be done using any tools you are comfortable with. At this stage, do not worry about how perfect the design is and whether or not it is finalized.

This step is just there to help you know whether or not you are on the right track, and it can also be shared with your client to get their initial feedback. But above all, it will help you get a clearer idea of how to proceed.

  1. Get feedback

Once you have created your first sketch and a couple of drafts, the next step is to get feedback from your client. This is crucial, as the feedback you receive at this stage will influence everything that follows and the direction in which the design is going. 

An online proofing tool like Filestage makes it easy for your client to give precise feedback. Additionally, the commenting and annotation features allow reviewers to leave suggestions and add ideas directly to the design. 

  1. Adapt your graphic designs

This is the fun part, where you get to do your thing and really shine. With the feedback from the previous step in mind, you now have a clear direction and can start detailing your design. During the process, you adapt and advance your sketches and create different variations of your design. 

Creating variations of your design will make your client happy as they can then better focus on the smaller details. At the same time, you have the leverage to play around slightly with typographic pairings, color palettes, and structure. 

  1. Get final approval on your design

After sharing the different variations of your design with the client, you will receive more feedback from them. This helps you to better understand what they want, allowing you to adapt the design until they are happy and you receive their final approval.  

Three best practices to make the most of your process

For nearly 43% of marketers, it is a struggle to remain consistent when creating engaging visual content. 

Therefore, we have three tips to help you deal with this dilemma and make your life as a graphic designer easier: 

  1. Use the right tools for support.

Since graphic design leads to such subjective outcomes, it is always good to have other professionals validate your work and inspire you. Tools such as Dribbble and Canva provide an outlet for designers to take inspiration from others and receive constructive criticism. These can be used during the brainstorming sessions and the first sketch steps.

To find photos and vectors to help embellish your design, you should check out Freepik. It also contains PSDs that can either help inspire you or give you a ready-made structure to build on for projects with tight deadlines. This can be used when you are adapting your designs to get to the final stage.

  1. Set up a clear workflow for feedback and approvals.

Designers rely heavily on their client’s feedback during the design process. Instead of sharing multiple files and long email threads, you can manage the entire feedback workflow in one place. 

Approval software like Filestage streamlines the entire review and approval process for any file type, making it easier for both clients and designers to get on the same page.

On the centralized platform, designers can share their work, and clients can leave their input directly in the design. Plus, designers can react to clients’ comments and feedback in real-time. This makes collaboration much easier and helps avoid misunderstandings.  

  1. Adapt the process to your team’s needs.

It is important to note that there isn’t a ‘one-size-fits-all’ solution to the graphic design process, so adapt the steps described above to best integrate into your existing routine and workflow.

Of course, trends and requirements in the design industry are constantly changing, so this solution is not everlasting. Do not hesitate to rethink your processes and workflows from time to time, taking note of the methods that work best for you.


Whether you are a novice or a pro graphic designer, a smooth and solid process is critical to your success. Also, you do not have to do it by yourself; there are several helpful tools out there to take some of the pressure off you. 

So, be sure to create a solid structure for the graphic design process to help you continually produce high-quality work.

Categories: Others Tags:

The 5 Key Differences Between Shopify and Shopify Plus

July 29th, 2021 No comments

Shopify is one of the most well-known eCommerce platforms, featuring a comprehensive package with an intuitive user interface.

However, Shopify is geared toward small- to medium-sized businesses, and larger companies with a high volume of sales may not find that the platform is able to fulfill all their needs. 

Shopify Plus was designed to be a flexible, fast, and customizable eCommerce platform that is capable of handling the high sales volume and complexities of large enterprises. While Shopify and Shopify Plus share some basic features, there are key differences that make Shopify Plus more effective for enterprises that need additional options. 

Shopify Plus has an Overview Dashboard and Unlimited Staff Accounts 

One of the first major differences companies will notice between Shopify and Shopify Plus is the overview dashboard. The overview dashboard allows you to see how all of your stores are performing at a glance. Metrics, sales, and analytics are all displayed in a format that gives you an instant perspective on how your businesses are performing. 

Shopify Plus also has unlimited staff accounts and gives you the ability to assign more than just a username and login. Shopify Plus also lets you change each user’s permissions, so you can customize specific roles, and assign your employees varying abilities based on their position. 

There is a Shopify Plus Wholesale Channel

Shopify Plus has a wholesale channel, which is optimized for wholesale as well as business-to-business sales. If you’re in the United States, the wholesale channel lets you use Handshake to sell bulk products to other retailers.

With Shopify Plus, you aren’t limited to choosing only wholesale or retail options; you can create an entirely separate, password-protected section of your website dedicated to your wholesale customers. You never have to worry about a retail customer viewing your wholesale prices, and 

Shopify Plus Gives You Access to Dedicated Support and Exclusive Resources

Shopify Plus has a dedicated support team there to ensure that everything is running smoothly at all times. You can get in touch with someone via phone, email, or live chat, and there are even Shopify Plus experts available to hire hourly if you need someone to run your eCommerce site. 

The exclusive resources available to Shopify Plus enterprises include specialized educational content, playbooks, and checklists created by eCommerce experts, and the ability to create custom apps specifically for your online storefront, among many other useful tools and integrations. 

Shopify Plus store owners enjoy tax service integrations with Avalara Avatax, which has up-to-date tax rates from more than 12,000 jurisdictions. With Avalara Avatax, you are now able to customize your tax rules to better suit your needs, as well as create specific rules per product. You can also make current, accurate reports, quickly and easily. 

Shopify Plus has More Powerful Branding and Customization Capabilities

Compared to the standard version of Shopify, Shopify Plus has more powerful branding and customization capabilities that give you complete control over how your company is represented online. Starting with being able to use your own domain (without ending in “”), you can begin to make your online store a reflection of your enterprise. 

With Shopify Plus, adding non-product pages is quick and easy, which makes setting up an FAQ, announcement, or onboarding page a seamless, stress-free process. Shopify Plus also allows you to translate your wholesale storefront into seven languages, giving you global selling power. 

Shopify Scripts are another great way to customize your Shopify Plus website. Shopify Scripts are small sections of code that can customize everything about your customers’ checkout experience, from automatically generating discounts, to changing shipping and payment methods. This leads to increased brand loyalty and lower rates of abandoned carts. 

Shopify Flow connects all of your businesses together, so you can make sweeping or individual changes easily, without logging into each storefront individually. Shopify Flow is used to do things like flag high-risk orders, track and modify inventory and merchandise, and even automate rewards and adding tags to customers. Managing multiple brands used to mean logging into each store’s system individually, but with Shopify Flow, changes can be made quickly on a system-wide or individual basis. 

Dynamic API Integrations and Apps are Included With Shopify Plus 

Shopify Plus allows you to use their API to take your brand to the next level. With the Shopify Plus API, you can do everything from creating and manage gift card codes, to allowing customers to enable a single login called a multipass for all of your businesses and storefronts. Shopify Plus has more ways to customize your online store than ever before. Appearance and themes, products, discounts, the checkout experience, and even payment options can all be changed in a variety of ways to suit your brand. 

Shopify Plus also gives you the opportunity to create custom third-party apps for your business, or you can take advantage of their thriving certified app store, where developers continually solve complex problems faced by large enterprises. With both backend and frontend solutions, and many free options available, the ability to use apps is one of the biggest draws to Shopify Plus.  

Is Shopify Plus Right for Your Enterprise?

While Shopify Plus comes with significant benefits, they come at a much higher cost than the standard Shopify platform. Options start as low as $2,000 a month, with unlimited purchases, a flexible, responsive platform, and accessible support, for many large businesses, Shopify Plus is incredibly affordable when compared to the competition. It offers even more perks if you happen to be involved in wholesale or B2B ventures.

 However, small to medium-sized businesses probably won’t find the higher price tag of Shopify Plus worth the investment, as they can’t take advantage of the ability to complete a high volume of sales, and probably don’t need unlimited user accounts, wholesale capabilities, or a feature-heavy backend. If you have an enterprise-sized business with high sales volume, or if you have a wholesale or B2B business, Shopify Plus may be exactly what you’re looking for.

Categories: Others Tags:

ES2021 Features

July 27th, 2021 No comments

Hemanth HM very succinctly shows off ES2021 features. Gosh it doesn’t feel like that long ago that all we could talk about is ES2015, and now that’s over a half-decade behind us. New things include “arbitrarily chuck underscores in numbers.” I kinda dig that. Like 1_000_000_000 is the same as 1000000000 but more readable. To be honest, I barely even understand the other features. It’s interesting to observe the JavaScript truck moving forward with new features, while also being around people that write Go a lot and how starkly different, philosophically, it seems to me. Like there is only one kind of loop in Go, a for loop, and that’s it. Go doesn’t add syntactic sugar on purpose, while JavaScript feels addicted to it. Sugar is a helluva drug.

Direct Link to ArticlePermalink

The post ES2021 Features appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

CSS Logical Properties and Values

July 27th, 2021 No comments
Screenshot of the BBC website. The header is red with the BBC logo aligned to the right of the screen. The navigation is also in red and aligned to the right. There is a featured article with right-aligned text and a large image to the right of it. Below that are four more article cards in a single row, each with an image above a title and date and aligned right.

Now that cross-browser support is at a tipping point, it’s a good time to take a look at logical properties and values. If you’re creating a website in multiple languages, logical properties and values are incredibly useful. Even if you’re not, there are still some convenient new shorthands it’s worth knowing about.

For example, I’ve lost count of the amount of times I’ve written this to center something:

.thing {
  margin-left: auto;
  margin-right: auto;

We could make it a one-liner with something like margin: 0 auto; but then the top and bottom margins get thrown into the mix. Instead, we can select just the left and right margin with the margin-inline logical property.

CodePen Embed Fallback

Start thinking of things as “inline” or “block”

That last demo is pretty neat, right? The margin-inline property sets both margin-left and margin-right. Similarly, the margin-block property sets both margin-top and margin-bottom. And we’re not only talking margins. Logical properties has similar shorthands to set border and padding. So if you have a visual design that calls for borders only on the sides, you can just use border-inline instead of fussing with each physical direction on its own.

CodePen Embed Fallback
Rather than thinking in physical terms, like left and right, we can think of an “inline” direction and a “block” direction.

So, as we move ahead, we now know that we’re dealing with inline and block directions instead of physical directions. Inline handles the left and right directions, while block manages top and bottom.

That is, until things get swapped around when the writing-mode changes.

Pay attention to direction and writing mode

What we’ve seen so far are examples of CSS logical properties. These are versions of CSS properties were used to like margin and padding, but written in a new way that forgoes physical directions (i.e. left, right, top, and bottom).

CSS was developed with the English language in mind and English is written and read from left-to-right. That’s not the case for all languages though. Arabic, for example, is read from right-to-left. That’s why HTML has a dir attribute.

<html dir="rtl">

CSS has an equivalent property (although it’s recommended to use the HTML attribute just in case the CSS fails to load):

.foreign-language { direction: rtl; }
Two cards, one in english and one in arabic, Both cards have a subtitle in gray above a main heading in a larger black font. The english goes from left to right and indicates the direction with an arrow below the card. The arabic direction is reverse of the english.
Credit: Ahmad Shadeed

Chinese, Japanese, Korean and Mongolian can be written either horizontally from left-to-right, or vertically from top to bottom. The majority of websites in these languages are written horizontally, the same as with English.

Comparatively, vertical writing is more common on Japanese websites. Some sites use a mixture of both vertical and horizontal text.

When written vertically, Chinese, Japanese and Korean are written with the top-right as a starting point, whereas Mongolian reads from left to right. This is exactly why we have the writing-mode property in CSS, which includes the following values:

  • horizontal-tb: This is the default value, setting the the direction left-to-right for languages like English or French, and right-to-left languages like Arabic. The tb stands for “top-to-bottom.”
  • vertical-rl: This changes the direction to right-to-left in a vertical orientation for languages like Chinese, Japanese and Korean.
  • vertical-lr: This is used for vertical left-to-right languages, like Mongolian.

CSS logical properties offer a way to write CSS that is contextual. When using logical properties, spacing and layout are dependent on both the writing-mode and direction (whether set by either CSS or HTML). It therefore becomes possible to reuse CSS styles across different languages. BBC News, for example, rebuild their website in over a dozen languages. That’s a better experience than leaving users to rely on autotranslate. It also means they can better cater specific content to different parts of the world. The visual styling though, remains much the same across regions.

Screenshot of the BBC website. The header is red with the BBC logo aligned to the right of the screen. The navigation is also in red and aligned to the right. There is a featured article with right-aligned text and a large image to the right of it. Below that are four more article cards in a single row, each with an image above a title and date and aligned right.

Let’s look at the example below to see the shortcomings of physical properties. Using the physical margin-left property (shown in red), everything looks good in English. If you were to reuse the CSS but change the writing mode to rtl (shown at the bottom) there’s no space between the text and the icon and there’s excess white space on the left of the text. We can avoid this by using a logical property instead.

Two buttons, both with an envelope icon and a label. The left-to-right version of the button on top shows the spacing between the icon and the label. The right-to-left version shows the spacing to the left of both the label and icon.

What makes logical properties and values so useful is that they will automatically cater to the context of the language. In a left-to-right language like English, margin-inline-start will set the left-side margin. For a right-to-left language like Arabic, Urdu, or Hebrew, it will set the right-hand margin — which solves the layout problem in the above example. That’s right-to-left taken care of. If you have vertical text, margin-inline-start will cater to that context to, adding the margin at the top, which is where you would start reading from in any vertical language (that’s why it’s called margin-inline-start — just think about which direction you start reading from). The direction of inline changes based on the element’s writing-mode. When a vertical writing-mode is set, it handles the vertical direction top and bottom. See how things can get switched around?

An example of the writing direction in Mongolian. (Credit: W3C)

A complete list of logical properties and values

There are dozens of CSS properties that have a logical alternative syntax. Adrian Roselli has a handy visualization where you can toggle between the physical CSS properties that we’re all used to and their logical property equivalents. It’s a nice way to visualize logical properties and the physical properties they map to when the direction is ltr and the writing-mode is horizontal-tb.

CodePen Embed Fallback

Let’s break all of those down even further and map each and every physical CSS property to its logical companion, side-by-side. The tables shown throughout this article show traditional physical CSS in the left column and their logical equivalents (using a left-to-right horizontal mapping) in the right column. Remember though, the whole point of logical properties is that they change based on context!


In a horizontal writing mode, inline-size sets the width of an element, while block-size sets the height. In a vertical writing mode, the opposite is true: inline-size sets the height and block-size sets the width.

CodePen Embed Fallback
Physical property Logical property
width inline-size
max-width max-inline-size
min-width min-inline-size
height block-size
max-height max-block-size
min-height min-block-size

Logical properties for sizing have good cross-browser support.


Everything here has solid cross-browser support among modern browsers.

Physical property Logical property
border-top border-block-start
border-bottom border-block-end
border-left border-inline-start
border-right border-inline-end

Here’s an example of using border-inline-start shown with English, Arabic, and Chinese.

CodePen Embed Fallback

Here’s an example that sets border-block-start dotted and border-block-end dashed:

CodePen Embed Fallback

There are also logical properties for setting the border color, width, and style individually:

Physical property Logical property
border-top-color border-block-start-color
border-top-width border-block-start-width
border-top-style border-block-start-style

So, again, it’s about thinking in terms of “inline” and “block” instead of physical directions, like left and top. We also have shorthand logical properties for borders:

Physical property Logical property
border-top and border-bottom border-block
border-left and border-right border-inline


Here are all the individual logical margin properties:

Physical property Logical property
margin-top margin-block-start
margin-bottom margin-block-end
margin-left margin-inline-start
margin-right margin-inline-end

These logical properties has comprehensive modern cross-browser support, including Samsung Internet, and has been supported in Safari since 12.2.

And, remember, we have the shorthands as well:

Physical property Logical property
margin-top and margin-bottom margin-block
margin-left and margin-right margin-inline


Padding is super similar to margin. Replace margin with padding and we’ve got the same list of properties.

Physical property Logical property
padding-top padding-block-start
padding-bottom padding-block-end
padding-left padding-inline-start
padding-right padding-inline-end
padding-top and padding-bottom padding-block
padding-left and padding-right padding-inline

Just like margins, logical properties for padding have good cross-browser support.


Need to offset an element’s position in a certain direction? We can declare those logically, too.

Physical property Logical property
top inset-block-start
bottom inset-block-end
left inset-inline-start
right inset-inline-end
top and bottom inset-block
left and right inset-inline

In a horizontal writing mode (either left-to-right, or right-to-left) inset-block-start is equivalent to setting top, and inset-block-end is equivalent to setting bottom. In a horizontal writing mode, with a left-to-right direction, inset-inline-start is equivalent to left, while inset-inline-end is equivalent to right, and vice-versa for right-to-left languages.

Conversely, for a vertical writing mode, inset-inline-start is equivalent to top while inset-inline-end is equivalent to bottom. If writing-mode is set to vertical-rl, inset-block-start is equivalent to right and inset-block-end is equivalent to left. If the writing-mode is set to vertical-lr, the opposite is the case and so inset-block-start is equivalent to left.

Logical property Writing mode Equivalent to:
inset-block-start` Horizontal LTR top
inset-block-start Horizontal RTL top
inset-block-start Vertical LTR left
inset-block-start Vertical RTL right

Here’s an example of how the same CSS code for absolute positioning looks in each of the four different writing directions:

CodePen Embed Fallback

Logical properties for positioning are supported in all modern browsers, but only recently landed in Safari.

There’s also a new shorthand for setting all four offsets in one line of code. Here’s an example using inset as a shorthand for setting top, bottom, left, and right in one fell swoop to create a full-page overlay:

CodePen Embed Fallback

I’ve heard inset incorrectly referred to as a logical property. But, a quick look in DevTools shows that it is actually a shorthand for physical values, not logical properties:

What it’s actually doing is defining physical offsets (i.e. left, right, top and bottom) rather than logical ones (i.e. inline, block, start and end). Obviously if you want to set the same value for all four sides, as in the example above, it doesn’t matter.

inset: 10px 20px 5px 8px; /* shorthand for physical properties not logical properties  */

Text alignment

Logical values for text alignment enjoy great browser support and have for many years. When working in English, text-align: start is the same as text-align: left, while text-align: end is the same as text-align-right. If you set the dir attribute to rtl, they switch and text-align: start aligns text to the right.

Physical value Writing mode Equivalent to:
start LTR left
start RTL right
end LTR right
end RTL left

Border radius

So far everything we’ve looked at has decent browser support. However, there are some other logical properties where support is still a work in progress, and border radius is one of them. In other words, we can set a different border-radius value for different corners of an element using logical properties, but browser support isn’t great.

Physical property Logical property
border-top-left-radius border-start-start-radius
border-top-right-radius border-start-end-radius
border-bottom-left-radius border-end-start-radius
border-bottom-right-radius border-end-end-radius
CodePen Embed Fallback

It’s worth noting that the spec doesn’t include shorthand properties, like border-start-radius and border-end-radius. But, like I said, we’re still in early days here, so that might be a space to watch.


Flow-relative values for logical floats have terrible browser support at the time I’m writing this. Only Firefox supports inline-start and inline-end as float values.

Physical value Logical value
float: left float: inline-start
float: right float: inline-end
clear: left clear: inline-start
clear: right clear: inline-end
CodePen Embed Fallback

Other logical properties

There are proposed logical properties for overflow and resize, but they currently have horrendous browser support.

Physical Logical
resize: vertical resize: block
resize: horizontal resize: inline
overflow-y overflow-block
overflow-x overflow-inline

Digging deeper

We explored what it means for a property to be considered “logical” and then mapped out all of the new logical properties and values to their physical counterparts. That’s great! But if you want to go even deeper into CSS Logical Properties and Values, there are a number of resources worth checking out.

  • “RTL Styling 101” (Ahmad Shadeed): A great resource if you’re dealing with Arabic or other right-to-left languages. Ahmad covers everything, from logical properties to considerations when working with specific layout techniques, like flexbox and grid.
  • text-combine-upright (CSS-Tricks): If you’re dealing with vertical text, did you know that this property can rotate text and squeeze multiple characters into the space of a single character? It’s a nice touch of refinement in specific situations where some characters need to go together but still flow with a vertical writing mode.

If you want to view some nice real-world examples of vertical typography from across the web, take a look at the Web Awards for Horizontal and Vertical Writings. There’s a lot of great stuff in there.

Wrapping up

Do you need to rush and swap all of the physical properties out of your codebase? Nope. But it also doesn’t hurt to start using logical properties and values in your work. As we’ve seen, browser support is pretty much there. And even if you’re working on a site that’s just in English, there’s no reason to not use them.

The post CSS Logical Properties and Values appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Collaborative Task Management with Taskade

July 27th, 2021 No comments

Productivity is a crowded space, with countless apps and services promising to make your life and business easier and more profitable. Of all the apps that make that promise, very few deliver, but we’ve found one that does: Taskade.

Flexible Planning With Taskade

Every problem is unique, and part of what defines us as creative professionals is the different ways we approach problems. What suits one person in one situation doesn’t suit another in another. This is where many planning apps fall down: they adopt one singular approach and expect users to fit around the app.

Taskade is different. Like the love-child of Trello, Notion, and Slack, Taskade uses a template approach to create a flexible planning system that you can use in whatever way you prefer.

When you open up Taskade, you’ll see some quick options: ‘blank,’ ‘weekly planner,’ ‘meeting agenda,’ and so forth. But there’s also a ‘more’ option that will give you access to the hundreds of templates Taskade supplies. There are dozens of template categories, and each category contains multiple templates that you can use to drive your planning process.

Whether you’re looking for a task list for launching on Product Hunt, a design system checklist, or a project scrum board, you’ll find the template ready and waiting for you.

If none of the predesigned options are right for the task at hand, Taskade gives you the option to create your own template from the basic building blocks of boards, actions, mind maps, charts, and lists.

Team Collaboration With Taskade

One of Taskade’s main strengths is its ability to work equally well for individuals and teams.

It makes sense when you’re evaluating a product that you do it on your own. But we encourage you to bring team members on board early in the trial because it’s when working with teams that Taskade really excels as a collaborative tool.

Once you’ve created a new planning project, you can invite your team, either by email or — if they’re already registered — by tagging them with their Taskade username.

You can assign tasks to individuals or multiple individuals (a much better option than the free-for-all you find in some to-do apps). You can also set deadlines for tasks so that everyone knows what the schedule is.

Team Chat on Taskade

Another area that Taskade excels for teams is the built-in real-time live chat. You can communicate with team members right in the project instead of jumping onto Slack or email.

For teams working remotely, or even just multi-tasking throughout the day, it’s a great way of ensuring that everyone has the information they need. As a result, mistakes are minimized, and best of all, there’s a written record that can be referred back to at any time.

Chat can be sent to the whole team, or direct messaged to an individual, so you don’t need to worry about filling up everyone’s notifications with messages that don’t apply to them.

Project Management With Taskade

If you’re working on a single project, then you probably know exactly where it is at all times. But for anyone working on multiple projects, it can be hard to keep track of everything. So Taskade has several different options for project managers.

The Mindmap section is one of the most useful parts of Taskade because it gives you a complete overview of everything in your project. You can see what has been completed and how much time it took — that way, you can assess how viable the timeline for your other tasks is.

Another great feature of Taskade is the activity feed. When one of your team makes a change to a project, it will pop up in your activity feed, and the next time you log in, you’ll see the status of your projects with a single glance.


One of our favorite aspects of Taskade is that it works equally well across different platforms. As well as the desktop web app, you’ll also find native apps in the iOS app store and the Android play store.

Syncing your account over different apps is awesome because ideas often occur at inconvenient times — on your commute, walking the dog. Even when you’re at your desk, it’s much handier to grab your phone and make notes than it is to switch to your browser and visit a site.

Easy Registration

If you’re feeling the pressure of a bulging inbox, or to-do lists on multiple post-its, then the last thing you need is another complex, confusing task to add to the pile.

Taskade is super-easy to get started with. Just click the ‘Sign up’ link in the top right of the site, and you’ll have three options: Sign up with Google, sign up with your email, or you can continue as a guest.

If you’re not sold yet, then continue as a guest — essentially a free trial — you can sign in properly later once your curiosity is satisfied.

Free to Use

Taskade is free to use on a limited basis. The free plan comes with 500Mb of storage and a maximum 25Mb file size. You can create individual tasks or whole projects, workflows, and custom templates and share tasks and projects with your team. That’s enough to help you make the most of Taskade for $0.

If you find that the generous free plan isn’t quite enough, paid plans start at just $5 per month. The paid plan gives you unlimited storage and bumps the maximum file size up to 250Mb. You have the same core features as the free plan; it’s just that they’re unlimited, which means you can do even more planning. In addition, the paid plan adds some handy extra features that are great time-savers, such as sorting tasks, creating repeat tasks, and bulk assigning tasks. Just look at how Taskade compares to similar tools.

Most professionals will get along with the free plan just fine, but $5 per month for unlimited storage is a great deal. On top of that, you have future premium features to look forward to, including a project revision history and a calendar view.

You can sign up to Taskade for free now, as a guest, with your email, or with Google.


[– This is a sponsored post on behalf of Taskade –]


The post Collaborative Task Management with Taskade first appeared on Webdesigner Depot.

Categories: Designing, Others Tags: