Open Survey for WordPress Theme Authors on JSON Files and Block Themes

WordPress 5.8 introduced an opt-in system for themes to configure block settings, styles, templates, and more. It is done through a new theme.json file that authors can put at the root of their theme folders. Anne McCarthy, the lead of the FSE Outreach Program, announced a survey earlier today to get feedback from developers on this feature.

“Since this new mechanism is an early step towards a comprehensive style system for the future of WordPress, it’s important to hear from everyone who is currently using theme.json to learn more about how folks are using this tool and what might make sense to include in Core going forward,” she wrote in the announcement.

The survey is open to all theme authors who have used theme.json, giving them a chance to put in some early feedback and help steer the ship going forward.

Because I have worked extensively with this system over the past few months, I had a few things to say. Plus, I just like participating in WordPress-related surveys. I also decided it would be an opportunity to share some of my unfiltered thoughts from a development perspective on the current state of theme.json.

What follows are my responses to the survey’s questions — well, the tidied-up version.

Note: This is a developer-centric post that might not universally appeal to all of our readers. I have attempted to explain some things in user-friendly terminology, but some prerequisite knowledge of theme development may be necessary.

Experience

The first question of the survey is pretty cut-and-dry. It asks what your experience is with building block themes or using theme.json. It provides four choices (and an “other” option):

  • I have built and launched block themes.
  • I have experimented with building block themes.
  • I have explored using theme.json with a classic theme.
  • I have used a block theme, but I have not built one yet.

I chose the first option because I have already built two block themes for family and friends. These were simple personal sites that I already maintain for free — honestly, I need to start charging. I am also working on a theme that I hope to release publicly.

How It Started and How It’s Going

The second question asks how one got started with block themes and theme.json. The choices are between forking an existing theme, using the Empty Theme, or starting from scratch.

Again, this is one of those things where I have experimented with each direction, but I cannot remember the exact starting point. The bulk of my work has come from forking a theme that I last worked on in 2019.

I plan to release this as a new theme for free at some point. I am mostly waiting on the following:

  • Navigation block development to settle down
  • The Post Author block to be split into smaller blocks
  • A robust set of comment-related blocks
  • Post Featured Image block to have a size option

I think I could realistically release a use-at-your-own-risk beta version of my theme today if those items were addressed.

Templates and Template Parts

The survey asked which templates and template parts themers always include in their block-based themes. There was a freeform comment field — steps upon soapbox…

I have a love/hate relationship with block templates at the moment. The static nature of HTML templates reminds me of simpler times when theme development was less complicated. However, this also presents a problem in a dynamic system.

I cannot remember the last time I have built a traditional, PHP-based theme with more than one top-level template: index.php. The dynamic pieces have always been the guts of the thing, which are template parts. With PHP, it is easy to set some variable or use a function call to contextually load the templates parts necessary for whichever page a visitor is currently viewing on a site.

The block template system does not work like that. It essentially forces developers into breaking the Don’t Repeat Yourself (DRY) principle.

For example, if a designer wanted to display a different header template part for pages and posts, they would only need to create a header-page.php or header-post.php template in traditional themes. However, because the block template system is different, they must now create two top-level templates, single.html (post) and page.html, to accomplish the same thing.

This is a “bad thing” because theme authors must duplicate all the other code in each of the top-level templates. There is no way to contextually load different template parts.

To answer the question: I am using almost all of the possible top-level templates out of necessity.

I also answered the second part of the question and listed my most commonly used template parts (broken down by hierarchy):

  • Header
  • Content
    – Loop
    – Sidebar
  • Footer

The content-*.html and loop-*.html template parts are those with the most variations.

Defining Colors

The next section of the survey asks how theme authors define their color palette slugs in theme.json. Believe it or not, naming colors may be the most controversial topic in the theming world in years. The only two things generally agreed upon are “background” and “foreground” colors.

Morten Rand-Hendriksen opened a ticket in 2018 for standardizing a theme color naming scheme. It was not the first discussion and has not been the last. The problem it was meant to address was the slugs for colors in the system, which is how themes define their palettes. Once a user makes use of a preset color, the slug is hardcoded into their content. Switch to another theme with different slugs, and the old colors disappear and do not automatically change to the new theme’s colors.

I use semantic names that follow something that closely resembles the Tailwind CSS framework’s shading system. Instead of red-medium (descriptive), I would use primary-500 (semantic), for example. A semantic approach would allow theme authors to define a set of colors that are updated each time a user switches themes.

Of course, there are other schools of thought, and even everyone who prefers semantic naming does not agree on the same system. I have described my approach in more detail in a more recent GitHub ticket and have a theme.json Gist for others who might want to try it.

Other Theme JSON Settings

Outside of colors and typography, the survey asks what other settings theme authors have used. This is another scenario where I typically use everything — if there is an option for it, I am defining it.

One use case that WordPress does not currently have a preset for is global spacing. Most theme authors use a single value for most vertical margins (whitespace between blocks and elements). It is also often used for default vertical and horizontal padding.

I am unsure if I want a preset because I do not know how WordPress will use it. It is something that others have asked for, and it is nearly ubiquitous in use. Defining an entire system around it could cause headaches down the road, but I would still like to see some discussion around implementing at least a standard global spacing preset.

Per-Block Settings and Styles

This survey section was a yes/no question, simply asking if theme authors included per-block settings or styles in their theme.json files. Of course, I left some additional comments later in the optional comment section.

I am happy with the system when it comes to settings, which allows themers to define which features are enabled globally or on a per-block basis. However, I am not sold on adding styles via theme.json.

Writing CSS in JSON, essentially what we are talking about, feels wrong on so many levels. Currently, it is limited to merely a few configurable styles, so anything beyond that requires diving into an actual CSS file anyway. That is problematic because half of the theme’s CSS code is divided between theme.json and a separate CSS file. From a development standpoint, it makes the codebase harder to maintain.

Initially, I started down the path of configuring per-block and element styles from theme.json. However, I have since moved my styling back to CSS files. It feels more natural, and I have the added benefit of all the tooling I am accustomed to. Right now, I cannot imagine a scenario where I would move back.

Besides saving a few bytes of code, I have not seen many benefits to adding styles for most things via JSON. Maybe that will change in the future, and I will be a convert. For now, I am sticking primarily with CSS.

Other Feedback: A PHP Layer

I have said it before, but it bears repeating. We need a PHP layer for this theme.json configuration system. There is currently an open ticket for addressing this.

There are two main benefits to such a system. Having a PHP API for piecing together configuration will feel far more natural to traditional theme developers. I look at it as a bit of an olive branch, a show of good faith that the core/Gutenberg developers recognize that many theme authors will have an easier time easing into FSE features via a familiar programming language.

The second advantage is that there is an untold number of plugin ideas to extend global styles, site editing, and more if there is an easy way to hook into the theme JSON system and overwrite things. A simple filter hook would make this painless.

Why ETL Needs Open Source to Address the Long Tail of Integrations

Over the last year, our team has interviewed more than 200 companies about their data integration use cases. What we discovered is that data integration in 2021 is still a mess.

The Unscalable Current Situation

At least 80 of the 200 interviews were with users of existing ETL technology, such as Fivetran, StitchData, and Matillion. We found that every one of them was also building and maintaining their own connectors even though they were using an ETL solution (or an ELT one — for simplicity, I will just use the term ETL). Why?

SQL Injection vs. Your Applications in the Modern Age

Developers dealing with web applications see a lot of things threatening to harm the things they build. Some of these things include attacks targeted at people (for example, social engineering), some of these attacks (DoS or DDoS attacks, Cross-Site Scripting, Cross-Site Request Forgery, Broken Authentication, Sensitive Data Exposure, Broken Access Control, Insecure Deserialization, etc.) target parts of web applications. However, some attacks primarily target your database and data stored there — one of such attacks is SQL injection (SQLi for short). In this blog post, we will look at the impacts such an attack might have.

What is SQL Injection and Why Is It Dangerous?

SQL injection is an attack frequently targeted at web applications. The purpose of such an attack frequently is to exfiltrate sensitive data from the database and use it for the personal gain of the attacker. Such an attack is so prevalent and dangerous precisely because many developers overlook the importance of security when creating public, web-facing solutions. When security gaps are overlooked, malicious parties often find and exploit them. These nefarious actors exploit such vulnerabilities because they can profit from selling data stolen during the breach.

PostgreSQL HA and Kubernetes

In the following, I will share my thoughts about how to set up a PostgreSQL Database in Kubernetes with some level of high availability. For that, I will introduce 3 different architectural styles. I do not make a recommendation here because, as always every solution has its pros and cons.

1. Running PostgreSQL Outside of Kubernetes

In the first scenario, you run PostgreSQL outside form Kubernetes. This means Kubernetes does not know anything about the database. This situation is often a result of a historical architecture where PostgreSQL was long before Kubernetes in an evolving architecture.

Event Stream Processing Essentials

With an increasing number of connected, distributed devices, there has been a gradual shift in how data is processed and analyzed. The trend is also based on the growth of emerging technologies, such as the Internet of Things (IoT), microservices, and event-driven applications, which influence the development of real-time analytics. This Refcard dives into how event stream processing represents this evolution by allowing continuous data analysis in the modern technology landscape.

PublishPress Adopts Organize Series Plugin

PublishPress, makers of the PublishPress and PublishPress Blocks plugins, have adopted the Organize Series plugin from Darren Ethier. Organize Series is a 15-year-old plugin for organizing and displaying posts in a series, useful for novel writers, educators, magazine sites, and anyone breaking their longer content up into a series.

image credit: PublishPress

PublishPress is also adopting seven extensions for the plugin that add features like custom post type support, shortcodes, the ability to add a post to multiple series, bulk publishing, and more.

Ethier, who works as an engineer at Automattic, said he began losing interest in maintaining the plugin and knew it was time to search for a new owner.

“Most of you have noticed that I haven’t been actively contributing to Organize Series or it’s extensions for some time now and it’s been bugging me,” he said. “I’ve been gradually losing interest in maintaining the plugin as I’ve expanded my developer horizons and as a result, I’ve struggled with making the time to work on it.”

Ethier connected with PublishPress by describing his situation in a post on the Post Status community and agreed to transfer his plugin and extensions in exchange for a donation to a charity.

“Darren asked us to make a charitable donation as part of the handover,” PublishPress founder Steve Burge said. “We chose the American Journalism Project. Over 2,100 communities in the U.S. have lost their local newspaper since 2004. The AJP is trying to reverse that trend. It is a non-profit that is investing in local news. Their goal is to help grow newsrooms that hold the powerful accountable, combat disinformation, and deepen civic participation.”

Burge assured current users that the free version of Organize Series will remain free on WordPress.org with all of its current features and some improvements. The company will also keep the extensions freely available on GitHub but Burge said they plan to release a commercial version with updated versions of the extensions.

With the adoption of Organize Series, PublishPress now has nine plugins available in its niche collection of publishing extensions as part of its mission to “help WordPress publishers succeed.” In the near future, Organize Series’ website content will be transferred over and the company will be changing the plugin’s name to “PublishPress Series.”

Identity Governance 101: Popular User Stories

What Is Identity Governance

In theory, identity governance refers to the policy-based centralized orchestration of user identity management and access control. In layman’s terms, this refers to managing different aspects of user accounts and how they access the resources offered. It’s believed that the concept of identity governance grew out of the Identity Governance Framework, a now-defunct project by the Liberty Group that aimed to standardize enterprise identity information usage.

That been said, there are some user stories that are identified and catered for in the WSO2 Identity Server, categorized under identity governance. I’m trying to talk about these stories one by one, hoping to have in-depth articles on each of them later.

Salesforce Application Design

Since 2008, Salesforce has allowed developers worldwide to build and manage a custom CRM for their enterprise. This Refcard provides an overview of how to design applications to run on the Salesforce Platform, exploring the no- to-full code spectrum.

A Shared ESLint Configuration

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.

Conjuring Generative Blobs With The CSS Paint API

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.

Generative?

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:

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 <canvas>-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:

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:

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 <canvas> 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!

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:

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.

Desktop

ChromeFirefoxIEEdgeSafari
65NoNo79No

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
92No92No

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 <canvas> 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 <script> just before our closing </body> tag:

<script>
  if (CSS["paintWorklet"] !== undefined) {
    CSS.paintWorklet.addModule("./worklet.bundle.js");
  }
</script>

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 [
    "--blob-seed",
    "--blob-num-points",
    "--blob-variance",
    "--blob-smoothness",
    "--blob-fill",
  ];
}

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.

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:

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():

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: https://github.com/bryc/code/blob/master/jshash/PRNGs.md
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 <canvas>, 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:

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:

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;

ctx.beginPath();
spline(points, smoothness, true, (CMD, data) => {
  if (CMD === "MOVE") {
    ctx.moveTo(...data);
  } else {
    ctx.bezierCurveTo(...data);
  }
});

ctx.fill();

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 <script> tag we created earlier:

document
  .querySelector(".worklet-canvas")
  .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("https://unpkg.com/css-paint-polyfill");
  }
  CSS.paintWorklet.addModule("./worklet.bundle.js");
})();

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.

19+ Free Google Tools Every WordPress Blogger Should Use

Are you looking for the best free Google tools to grow your WordPress blog?

Google offers a wide variety of free tools to help bloggers and website owners improve their SEO, get more traffic, be more productive, and more.

In this article, we highlight the best free Google tools that every WordPress blogger should use.

19+ Free Google tools every WordPress blogger should use

1. Google Analytics

Google Analytics

Google Analytics is the most comprehensive analytics tool for WordPress blogs and websites.

It tells you how your visitors found your website, what devices they used, what pages they viewed, and how they interacted with your website.

This information helps you better understand your audience, so you can plan and execute an effective content strategy. You’ll be able to see what topics and pages convert the best and steadily improve your website over time.

The easiest way to add Google Analytics to WordPress is using MonsterInsights. It’s the best analytics solution for WordPress used by over 3 million websites.

It lets you view your Google Analytics stats directly in your WordPress dashboard.

MonsterInsights stats dashboard

For more details, see our beginner’s guide on how to install Google Analytics in WordPress.

2. Google Search Console

Google Search Console

Google Search Console is a set of tools that helps website owners monitor and maintain their search engine presence and rankings.

It helps you see what keywords people use to find your site, notify you of site errors holding back your rankings, and much more.

Plus, you can submit an XML sitemap via Google Search Console to help search engines crawl your website better.

The easiest way to add Google Search Console to WordPress is by using the All in One SEO plugin. It’s the best SEO plugin for WordPress used by over 2 million websites.

For more details, see our guide on how to add your WordPress site to Google Search Console.

3. Google Programmable Search

Google Programmable Search

The default WordPress search feature is quite limited and not very good at finding relevant content. As your website grows, you’ll want a way to help your visitors find what they’re looking for.

Google Programmable Search gives you an easy way to add custom search to your WordPress site.

You have complete control over the content it will search, and you can design the search feature to fully blend into your website.

For more advanced search with customization options, we recommend using a WordPress search plugin like SearchWP, but Google Programmable Search can be an affordable option to get started.

4. Google Tag Manager

Google Tag Manager

Google Tag Manager allows you to easily add and manage code snippets, or “tags”, to your website. Tags are commonly used by analytics and marketing tools to add tracking or other features to your site.

Adding tags to your WordPress site usually requires custom code. These custom code snippets load an external script, and it’s hard to manage them all.

Google Tag Manager solves this problem by allowing you to manage all your external codes from one dashboard.

You only need to add one Google Tag Manager snippet to your site, and then you can manage the rest from a single dashboard.

For more details, see our guide on how to install and setup Google Tag Manager in WordPress.

5. PageSpeed Insights

Google PageSpeed Insights

Having a fast loading website is one of the most important parts of providing a good user experience and solid WordPress SEO.

Google PageSpeed Insights is a website performance monitoring tool. It tells you how your website is performing on both desktop and mobile devices.

The results are broken down into different sections, so you can see what’s holding your site back. There are also resources and best practices to help you fix any issues you might be having.

PageSpeed Insights results

For more details on running a website speed test, see our guide on how to properly run a website speed test.

If you’ve found that your website has performance and speed issues, then there’s a lot you can do to improve this.

First, we recommend using high performance WordPress hosting, like Bluehost or SiteGround.

Next, you can use a WordPress caching plugin like WP Rocket. Caching plugins reduce the load on your server and speed up your WordPress site.

If you’re serious about boosting your site speed, then check out our ultimate guide to WordPress performance and speed.

6. Google Mobile-Friendly Test Tool

Google Mobile Friendly Test

For many WordPress websites, a high volume of traffic can come from mobile devices. If your website isn’t optimized for mobile, then you’ll create a poor user experience, and you can lose out on search engine rankings.

The Google Mobile-Friendly Test tool will tell you how well your website is optimized for the mobile web. It will give you a detailed breakdown of any issues and what you can do to fix them.

The easiest way to ensure your website is optimized for the mobile web is by using a responsive WordPress theme. These themes will automatically adjust to your visitor’s screen size, so they’ll look perfect on mobile devices.

7. Google Ads Keyword Planner

Google Ads Keyword Tool

The Google Ads Keyword Planner gives you insights into what people are searching for in Google search. It pulls data from the Google search results and paid advertisers.

Using this tool, you can generate a list of keywords related to your blog and see which keywords get the most searches per month. The data doesn’t provide exact numbers, but it does give general estimates.

Google Ads Keyword Tool results

This tool can also help you generate new ideas for your blog posts, plan your content strategy, and run your own pay per click (PPC) advertising campaigns using Google Ads.

If you’re looking for even more ways to do keyword research, then see our list of the best keyword research tools for SEO.

8. Think with Google Research

Think with Google

Think with Google Research is one of the best market research tools. This collection of tools will help you understand your market, spot new trends, and grow your website or online store.

The data and insights you can gain depending on which tools you use.

For example, the Market Insights tool can help you find new regional or global markets to expand into.

Think with Google market insights

There’s another tool that shows retail categories that are growing in popularity, along with the related search terms. This tells you if the niche you’re in is growing in popularity.

Think with Google rising retail categories

For those who have a YouTube channel, or edit videos, you can use the audience finder tool to uncover new audiences on YouTube.

9. Google My Business

Google My Business

Google My Business is a tool that lets you add your local business information to Google, so it can display your business information in search results.

If you run a local business, or provide services to a local area, then Google My Business is something you cannot miss.

Displaying your business information in Google search results will boost your brand’s search visibility, and bring you new customers and potential leads.

You can combine this with the Local SEO features from AIOSEO to further enhance your local business listings in Google.

10. Google Optimize

Google Optimize

Google Optimize is a tool that helps website owners optimize their websites by running A/B split tests. This lets you compare two different versions of a page to see which converts better.

For example, you can run a split test of two different sales pages to see which one leads to more customers.

By split testing, you can gradually optimize pages on your site to get the highest conversions possible.

You can create a split test simply with the drag and drop builder. Google will automatically show the variations to your visitors randomly and gather data.

For more details, see our guide on how to add Google Optimize to WordPress.

11. Google Adsense

Google AdSense

Google Adsense lets bloggers and website owners easily monetize their websites with display ads. Adsense is one of the longest-running display advertising programs.

Once you’re approved for the program, you can add the display ads to your site and start making money.

To easily manage and display your ads, we recommend using a WordPress ad management plugin.

You can also combine revenue from Google Adsense with other income generating activities like affiliate marketing, and selling online courses.

For more details, see our guide on how to properly add Google AdSense to WordPress.

12. Google Docs, Sheets, Slides, Forms, Calendar, & Gmail

Google Docs, Sheets, Slides, Forms

In terms of productivity tools to help you create better content, Google has you covered. You’ll find a wide range of tools for mobile and desktop, including Google Docs, Sheets, Forms, Calendar, Gmail, and more.

The main advantage of using Google’s productivity apps is the easy sharing features, with full privacy control, unlimited revisions, inline comments, and real time collaboration, all without needing to hit the save button.

Plus, there are all kinds of innovative ways to integrate these tools with WordPress. For example, you can connect WordPress forms to Google Sheets, integrate Google Calendar with WordPress, and more.

There’s also a premium version of these same tools called Google Workspace. This gives you the same functionality, plus a professional business email address, more cloud storage, support for two-factor authentication, and more.

13. Google Drive

Google Drive

Google Drive is a cloud storage tool you can use to store all of your Google Docs, Google Sheets files, and more. The free version shares 15GB of storage across your Drive, Gmail, and Google Photos accounts.

You can use the free cloud storage space to store any file you want and sync them across other devices with a Google account.

If you’re looking for a place to store your WordPress backups safely, then this can be an ideal option.

14. Google Maps

Google Maps

Google Maps gives you a great way to embed interactive maps into your WordPress website. Adding a map to your website can show your visitors where you’re physically located.

This is a must have feature for local businesses like restaurants and cafes.

If you’re a travel blogger, then you can also make use of Google Maps by creating and embedding an interactive map of all the places you’ve been.

15. Google Alerts

Google Alerts

Google Alerts will instantly notify you any time your brand or name is mentioned on the web.

It only takes a few seconds to create a Google Alert for your brand name or keywords, so you’ll get email notifications when you’re mentioned online.

It’s an important tool to use for building a strong brand image. Plus, these alerts can help to notify you of backlink opportunities and potential business partnerships.

16. Google Trends

Google Trends

Google Trends gives you a bird’s eye view of what’s trending in the world of search. You can browse through the latest curated data, or search for keywords related to your niche.

This tool can be helpful in addition to other research tools like the Google Ads Keyword Planner. When you enter a keyword, you’ll be able to see if its popularity is trending up or down.

You can use these insights to decide on new niches to go into or new article topics to write about.

17. Google Fonts

Google Fonts

Typography and font choice play a very important role in the design and usability of your website. Google Fonts is a great place to look for free fonts you can use on your website.

You can download and use these fonts directly from Google, or embed them into your website and serve them from Google’s servers.

For more details, see our guide on how to add custom fonts in WordPress.

18. Google Hangouts

Google Hangouts

Google Hangouts is a free conference call and video meeting tool from Google. It offers secure messaging, phone, and video conferencing for teams and businesses.

This is perfect for smaller teams who want to have quick conversations and easily share Google Docs during the call.

Users can join video meetings with a dial-in number or meeting link.

19. YouTube

YouTube

YouTube is not just a video hosting service, it’s also the second most popular search engine on the web. Millions of users are looking for video content on YouTube all the time.

Adding videos to your blog content can help you get more engagement, but we recommend that you never upload videos to WordPress. Instead, we recommend to host them on YouTube.

We have our own WPBeginner YouTube channel where we host all the videos that we embed on our blog.

If you want to add your YouTube videos to WordPress, then see our guide on how to easily embed videos in WordPress.

Free Bonus Google Tools

There are many more Google tools that are free and can be immensely helpful with your WordPress blog. Some of them are:

Google is often launching new tools and services and many of them are available for free or at a very competitive price.

We hope this article helped you find some new free Google tools that every WordPress bloggers should use. You may also want to see our list of 40 useful tools to manage and grow your WordPress blog and our picks of the best push notification software to get more traffic.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post 19+ Free Google Tools Every WordPress Blogger Should Use appeared first on WPBeginner.