Build A Static RSS Reader To Fight Your Inner FOMO

Featured Imgs 23

In a fast-paced industry like tech, it can be hard to deal with the fear of missing out on important news. But, as many of us know, there’s an absolutely huge amount of information coming in daily, and finding the right time and balance to keep up can be difficult, if not stressful. A classic piece of technology like an RSS feed is a delightful way of taking back ownership of our own time. In this article, we will create a static Really Simple Syndication (RSS) reader that will bring you the latest curated news only once (yes: once) a day.

We’ll obviously work with RSS technology in the process, but we’re also going to combine it with some things that maybe you haven’t tried before, including Astro (the static site framework), TypeScript (for JavaScript goodies), a package called rss-parser (for connecting things together), as well as scheduled functions and build hooks provided by Netlify (although there are other services that do this).

I chose these technologies purely because I really, really enjoy them! There may be other solutions out there that are more performant, come with more features, or are simply more comfortable to you — and in those cases, I encourage you to swap in whatever you’d like. The most important thing is getting the end result!

The Plan

Here’s how this will go. Astro generates the website. I made the intentional decision to use a static site because I want the different RSS feeds to be fetched only once during build time, and that’s something we can control each time the site is “rebuilt” and redeployed with updates. That’s where Netlify’s scheduled functions come into play, as they let us trigger rebuilds automatically at specific times. There is no need to manually check for updates and deploy them! Cron jobs can just as readily do this if you prefer a server-side solution.

During the triggered rebuild, we’ll let the rss-parser package do exactly what it says it does: parse a list of RSS feeds that are contained in an array. The package also allows us to set a filter for the fetched results so that we only get ones from the past day, week, and so on. Personally, I only render the news from the last seven days to prevent content overload. We’ll get there!

But first...

What Is RSS?

RSS is a web feed technology that you can feed into a reader or news aggregator. Because RSS is standardized, you know what to expect when it comes to the feed’s format. That means we have a ton of fun possibilities when it comes to handling the data that the feed provides. Most news websites have their own RSS feed that you can subscribe to (this is Smashing Magazine’s RSS feed: https://www.smashingmagazine.com/feed/). An RSS feed is capable of updating every time a site publishes new content, which means it can be a quick source of the latest news, but we can tailor that frequency as well.

RSS feeds are written in an Extensible Markup Language (XML) format and have specific elements that can be used within it. Instead of focusing too much on the technicalities here, I’ll give you a link to the RSS specification. Don’t worry; that page should be scannable enough for you to find the most pertinent information you need, like the kinds of elements that are supported and what they represent. For this tutorial, we’re only using the following elements: <title>, <link>, <description>, <item>, and <pubDate>. We’ll also let our RSS parser package do some of the work for us.

Creating The State Site

We’ll start by creating our Astro site! In your terminal run pnpm create astro@latest. You can use any package manager you want — I’m simply trying out pnpm for myself.

After running the command, Astro’s chat-based helper, Houston, walks through some setup questions to get things started.

 astro   Launch sequence initiated.

   dir   Where should we create your new project?
         ./rss-buddy

  tmpl   How would you like to start your new project?
         Include sample files

    ts   Do you plan to write TypeScript?
         Yes

   use   How strict should TypeScript be?
         Strict

  deps   Install dependencies?
         Yes

   git   Initialize a new git repository?
         Yes

I like to use Astro’s sample files so I can get started quickly, but we’re going to clean them up a bit in the process. Let’s clean up the src/pages/index.astro file by removing everything inside of the <main></main> tags. Then we’re good to go!

From there, we can spin things by running pnpm start. Your terminal will tell you which localhost address you can find your site at.

Pulling Information From RSS feeds

The src/pages/index.astro file is where we will make an array of RSS feeds we want to follow. We will be using Astro’s template syntax, so between the two code fences (---), create an array of feedSources and add some feeds. If you need inspiration, you can copy this:

const feedSources = [
  'https://www.smashingmagazine.com/feed/',
  'https://developer.mozilla.org/en-US/blog/rss.xml',
  // etc.
]

Now we’ll install the rss-parser package in our project by running pnpm install rss-parser. This package is a small library that turns the XML that we get from fetching an RSS feed into JavaScript objects. This makes it easy for us to read our RSS feeds and manipulate the data any way we want.

Once the package is installed, open the src/pages/index.astro file, and at the top, we’ll import the rss-parser and instantiate the Partner class.

import Parser from 'rss-parser';
const parser = new Parser();

We use this parser to read our RSS feeds and (surprise!) parse them to JavaScript. We’re going to be dealing with a list of promises here. Normally, I would probably use Promise.all(), but the thing is, this is supposed to be a complicated experience. If one of the feeds doesn’t work for some reason, I’d prefer to simply ignore it.

Why? Well, because Promise.all() rejects everything even if only one of its promises is rejected. That might mean that if one feed doesn’t behave the way I’d expect it to, my entire page would be blank when I grab my hot beverage to read the news in the morning. I do not want to start my day confronted by an error.

Instead, I’ll opt to use Promise.allSettled(). This method will actually let all promises complete even if one of them fails. In our case, this means any feed that errors will just be ignored, which is perfect.

Let’s add this to the src/pages/index.astro file:

interface FeedItem {
  feed?: string;
  title?: string;
  link?: string;
  date?: Date;
}

const feedItems: FeedItem[] = [];

await Promise.allSettled(
  feedSources.map(async (source) => {
    try {
      const feed = await parser.parseURL(source);
      feed.items.forEach((item) => {
        const date = item.pubDate ? new Date(item.pubDate) : undefined;

          feedItems.push({
            feed: feed.title,
            title: item.title,
            link: item.link,
            date,
          });
      });
    } catch (error) {
      console.error(Error fetching feed from ${source}:, error);
    }
  })
);

This creates an array (or more) named feedItems. For each URL in the feedSources array we created earlier, the rss-parser retrieves the items and, yes, parses them into JavaScript. Then, we return whatever data we want! We’ll keep it simple for now and only return the following:

  • The feed title,
  • The title of the feed item,
  • The link to the item,
  • And the item’s published date.

The next step is to ensure that all items are sorted by date so we’ll truly get the “latest” news. Add this small piece of code to our work:

const sortedFeedItems = feedItems.sort((a, b) => (b.date ?? new Date()).getTime() - (a.date ?? new Date()).getTime());

Oh, and... remember when I said I didn’t want this RSS reader to render anything older than seven days? Let’s tackle that right now since we’re already in this code.

We’ll make a new variable called sevenDaysAgo and assign it a date. We’ll then set that date to seven days ago and use that logic before we add a new item to our feedItems array.

This is what the src/pages/index.astro file should now look like at this point:

---
import Layout from '../layouts/Layout.astro';
import Parser from 'rss-parser';
const parser = new Parser();

const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

const feedSources = [
  'https://www.smashingmagazine.com/feed/',
  'https://developer.mozilla.org/en-US/blog/rss.xml',
]

interface FeedItem {
  feed?: string;
  title?: string;
  link?: string;
  date?: Date;
}

const feedItems: FeedItem[] = [];

await Promise.allSettled(
  feedSources.map(async (source) => {
    try {
      const feed = await parser.parseURL(source);
      feed.items.forEach((item) => {
        const date = item.pubDate ? new Date(item.pubDate) : undefined;
        if (date && date >= sevenDaysAgo) {
          feedItems.push({
            feed: feed.title,
            title: item.title,
            link: item.link,
            date,
          });
        }
      });
    } catch (error) {
      console.error(Error fetching feed from ${source}:, error);
    }
  })
);

const sortedFeedItems = feedItems.sort((a, b) => (b.date ?? new Date()).getTime() - (a.date ?? new Date()).getTime());

---

<Layout title="Welcome to Astro.">
  <main>
  </main>
</Layout>
Rendering XML Data

It’s time to show our news articles on the Astro site! To keep this simple, we’ll format the items in an unordered list rather than some other fancy layout.

All we need to do is update the <Layout> element in the file with the XML objects sprinkled in for a feed item’s title, URL, and publish date.

<Layout title="Welcome to Astro.">
  <main>
  {sortedFeedItems.map(item => (
    <ul>
      <li>
        <a href={item.link}>{item.title}</a>
        <p>{item.feed}</p>
        <p>{item.date}</p>
      </li>
    </ul>
  ))}
  </main>
</Layout>

Go ahead and run pnpm start from the terminal. The page should display an unordered list of feed items. Of course, everything is styled at the moment, but luckily for you, you can make it look exactly like you want with CSS!

And remember that there are even more fields available in the XML for each item if you want to display more information. If you run the following snippet in your DevTools console, you’ll see all of the fields you have at your disposal:

feed.items.forEach(item => {}
Scheduling Daily Static Site Builds

We’re nearly done! The feeds are being fetched, and they are returning data back to us in JavaScript for use in our Astro page template. Since feeds are updated whenever new content is published, we need a way to fetch the latest items from it.

We want to avoid doing any of this manually. So, let’s set this site on Netlify to gain access to their scheduled functions that trigger a rebuild and their build hooks that do the building. Again, other services do this, and you’re welcome to roll this work with another provider — I’m just partial to Netlify since I work there. In any case, you can follow Netlify’s documentation for setting up a new site.

Once your site is hosted and live, you are ready to schedule your rebuilds. A build hook gives you a URL to use to trigger the new build, looking something like this:

https://api.netlify.com/build_hooks/your-build-hook-id

Let’s trigger builds every day at midnight. We’ll use Netlify’s scheduled functions. That’s really why I’m using Netlify to host this in the first place. Having them at the ready via the host greatly simplifies things since there’s no server work or complicated configurations to get this going. Set it and forget it!

We’ll install @netlify/functions (instructions) to the project and then create the following file in the project’s root directory: netlify/functions/deploy.ts.

This is what we want to add to that file:

// netlify/functions/deploy.ts

import type { Config } from '@netlify/functions';

const BUILD_HOOK =
  'https://api.netlify.com/build_hooks/your-build-hook-id'; // replace me!

export default async (req: Request) => {
  await fetch(BUILD_HOOK, {
    method: 'POST',
  }).then((response) => {
    console.log('Build hook response:', response.json());
  });

  return {
    statusCode: 200,
  };
};

export const config: Config = {
  schedule: '0 0 * * *',
};

If you commit your code and push it, your site should re-deploy automatically. From that point on, it follows a schedule that rebuilds the site every day at midnight, ready for you to take your morning brew and catch up on everything that you think is important.



Gain $200 in a week
from Articles on Smashing Magazine — For Web Designers And Developers https://ift.tt/R5SEY48

CSS Anchor Positioning Guide

Featured Imgs 23

Not long ago, if we wanted a tooltip or popover positioned on top of another element, we would have to set our tooltip’s position to something other than static and use its inset/transform properties to place it exactly where we want. This works, but the element’s position is susceptible to user scrolls, zooming, or animations since the tooltip could overflow off of the screen or wind up in an awkward position. The only way to solve this was using JavaScript to check whenever the tooltip goes out of bounds so we can correct it… again in JavaScript.

CSS Anchor Positioning gives us a simple interface to attach elements next to others just by saying which sides to connect — directly in CSS. It also lets us set a fallback position so that we can avoid the overflow issues we just described. For example, we might set a tooltip element above its anchor but allow it to fold underneath the anchor when it runs out of room to show it above.

Anchor positioning is different from a lot of other features as far as how quickly it’s gained browser support: its first draft was published on June 2023 and, just a year later, it was released on Chrome 125. To put it into perspective, the first draft specification for CSS variables was published in 2012, but it took four years for them to gain wide browser support.

So, let’s dig in and learn about things like attaching target elements to anchor elements and positioning and sizing them.

Quick reference

/* Define an anchor element */
.anchor {
  anchor-name: --my-anchor;
}
/* Anchor a target element */
.target {
  position: absolute;
  position-anchor: --my-anchor;
}
/* Position a target element */
.target { 
  position-area: start end;
}

Basics and terminology

At its most basic, CSS Anchor Positioning introduces a completely new way of placing elements on the page relative to one another. To make our lives easier, we’re going to use specific names to clarify which element is connecting to which:

  • Anchor: This is the element used as a reference for positioning other elements, hence the anchor name.
  • Target: This is an absolutely positioned element placed relative to one or more anchors. The target is the name we will use from now on, but you will often find it as just an “absolutely positioned element” in the spec.

For the following code examples and demos, you can think of these as just two <div> elements next to one another.

<div class="anchor">anchor</div>
<div class="target">target</div>

CSS Anchor Positioning is all about elements with absolute positioning (i.e., display: absolute), so there are also some concepts we have to review before diving in.

  • Containing Block: This is the box that contains the elements. For an absolute element, the containing block is the viewport the closest ancestor with a position other than static or certain values in properties like contain or filter.
  • Inset-Modified Containing Block (IMCB): For an absolute element, inset properties (top, right, bottom, left, etc.) reduce the size of the containing block into which it is sized and positioned, resulting in a new box called the inset-modified containing block, or IMCB for short. This is a vital concept to know since properties we’re covering in this guide — like position-area and position-try-order — rely on this concept.

Attaching targets to anchors

We’ll first look at the two properties that establish anchor positioning. The first, anchor-name, establishes the anchor element, while the second, position-anchor, attaches a target element to the anchor element.

Square labeled as "anchor"

anchor-name

A normal element isn’t an anchor by default — we have to explicitly make an element an anchor. The most common way is by giving it a name, which we can do with the anchor-name property.

anchor-name: none | <dashed-ident>#

The name must be a <dashed-ident>, that is, a custom name prefixed with two dashes (--), like --my-anchor or --MyAnchor.

.anchor {
  anchor-name: --my-anchor;
}

This gives us an anchor element. All it needs is something anchored to it. That’s what we call the “target” element which is set with the position-anchor property.

Square labeled as "target"

position-anchor

The target element is an element with an absolute position linked to an anchor element matching what’s declared on the anchor-name property. This attaches the target element to the anchor element.

position-anchor: auto | <anchor-element>

It takes a valid <anchor-element>. So, if we establish another element as the “anchor” we can set the target with the position-anchor property:

.target {
  position: absolute;
  position-anchor: --my-anchor;
}

Normally, if a valid anchor element isn’t found, then other anchor properties and functions will be ignored.

Positioning targets

Now that we know how to establish an anchor-target relationship, we can work on positioning the target element in relation to the anchor element. The following two properties are used to set which side of the anchor element the target is positioned on (position-area) and conditions for hiding the target element when it runs out of room (position-visibility).

Anchor element with target elements spanning around it.

position-area

The next step is positioning our target relative to its anchor. The easiest way is to use the position-area property, which creates an imaginary 3×3 grid around the anchor element and lets us place the target in one or more regions of the grid.

position-area: auto | <position-area>

It works by setting the row and column of the grid using logical values like start and end (dependent on the writing mode); physical values like topleftrightbottom and the center shared value, then it will shrink the target’s IMCB into the region of the grid we chose.

.target {
  position-area: top right;
  /* or */
  position-area: start end;
}

Logical values refer to the containing block’s writing mode, but if we want to position our target relative to its writing mode we would prefix it with the self value.

.target {
  position-area: self-start self-end;
}

There is also the center value that can be used in every axis.

.target {
  position-area: center right;
  /* or */
  position-area: start center;
}

To place a target across two adjacent grid regions, we can use the prefix span- on any value (that isn’t center) a row or column at a time.

.target {
  position-area: span-top left;
  /* or */
  position-area: span-start start;
}

Finally, we can span a target across three adjacent grid regions using the span-all value.

.target {
  position-area: bottom span-all;
  /* or */
  position-area: end span-all;
}

You may have noticed that the position-area property doesn’t have a strict order for physical values; writing position-area: top left is the same as position-area: left top, but the order is important for logical value since position-area: start end is completely opposite to position-area: end start.

We can make logical values interchangeable by prefixing them with the desired axis using y-, x-, inline- or block-.

.target {
  position-area: inline-end block-start;
  /* or */
  position-area: y-start x-end;
}
Examples on each position-visibility value: always showing the target, anchors-visible hiding it when the anchor goes out of screen and no-overflow hiding it when the target overflows

position-visibility

It provides certain conditions to hide the target from the viewport.

position-visibility: always | anchors-visible | no-overflow
  • always: The target is always displayed without regard for its anchors or its overflowing status.
  • no-overflow: If even after applying the position fallbacks, the target element is still overflowing its containing block, then it is strongly hidden.
  • anchors-visible: If the anchor (not the target) has completely overflowed its containing block or is completely covered by other elements, then the target is strongly hidden.
position-visibility: always | anchors-visible | no-overflow

Setting fallback positions

Once the target element is positioned against its anchor, we can give the target additional instructions that tell it what to do if it runs out of space. We’ve already looked at the position-visibility property as one way of doing that — we simply tell the element to hide. The following two properties, however, give us more control to re-position the target by trying other sides of the anchor (position-try-fallbacks) and the order in which it attempts to re-position itself (position-try-order).

The two properties can be declared together with the position-try shorthand property — we’ll touch on that after we look at the two constituent properties.

Examples on each try-tactic: flip-block flipping the target from the top to the bottom, flip-inline from left to right and flip-start from left to top (single value) and top right to left bottom (two values)

position-try-fallbacks

This property accepts a list of comma-separated position fallbacks that are tried whenever the target overflows out of space in its containing block. The property attempts to reposition itself using each fallback value until it finds a fit or runs out of options.

position-try-fallbacks: none | [ [<dashed-ident> || <try-tactic>] | <'inset-area'>  ]#
  • none: Leaves the target’s position options list empty.
  • <dashed-ident>: Adds to the options list a custom @position-try fallback with the given name. If there isn’t a matching @position-try, the value is ignored.
  • <try-tactic>: Creates an option list by flipping the target’s current position on one of three axes, each defined by a distinct keyword. They can also be combined to add up their effects.
    • The flip-block keyword swaps the values in the block axis.
    • The flip-inline keyword swaps the values in the inline axis.
    • The flip-start keyword swaps the values diagonally.
  • <dashed-ident> || <try-tactic>: Combines a custom @try-option and a <try-tactic> to create a single-position fallback. The <try-tactic> keywords can also be combined to sum up their effects.
  • <"position-area"> Uses the position-area syntax to move the anchor to a new position.
.target {
  position-try-fallbacks:
    --my-custom-position,
    --my-custom-position flip-inline,
    bottom left;
}
two targets sorrounding an anchor, positioned where the IMCB is the largest.

position-try-order

This property chooses a new position from the fallback values defined in the position-try-fallbacks property based on which position gives the target the most space. The rest of the options are reordered with the largest available space coming first.

position-try-order: normal | most-width | most-height | most-block-size | most-inline-size

What exactly does “more space” mean? For each position fallback, it finds the IMCB size for the target. Then it chooses the value that gives the IMCB the widest or tallest size, depending on which option is selected:

  • most-width
  • most-height
  • most-block-size
  • most-inline-size
.target {
  position-try-fallbacks: --custom-position, flip-start;
  position-try-order: most-width;
}

position-try

This is a shorthand property that combines the position-try-fallbacks and position-try-order properties into a single declaration. It accepts first the order and then the list of possible position fallbacks.

position-try: < "position-try-order" >? < "position-try-fallbacks" >;

So, we can combine both properties into a single style rule:

.target {
  position-try: most-width --my-custom-position, flip-inline, bottom left;
}

Custom position and size fallbacks

@position-try

This at-rule defines a custom position fallback for the position-try-fallbacks property.

@position-try <dashed-ident> {
  <declaration-list>
}

It takes various properties for changing a target element’s position and size and grouping them as a new position fallback for the element to try.

Imagine a scenario where you’ve established an anchor-target relationship. You want to position the target element against the anchor’s top-right edge, which is easy enough using the position-area property we saw earlier:

.target {
  position: absolute;
  position-area: top right;
  width: 100px;
}

See how the .target is sized at 100px? Maybe it runs out of room on some screens and is no longer able to be displayed at anchor’s the top-right edge. We can supply the .target with the fallbacks we looked at earlier so that it attempts to re-position itself on an edge with more space:

.target {
  position: absolute;
  position-area: top right;
  position-try-fallbacks: top left;
  position-try-order: most-width;
  width: 100px;
}

And since we’re being good CSSer’s who strive for clean code, we may as well combine those two properties with the position-try shorthand property:

.target {
  position: absolute;
  position-area: top right;
  position-try: most-width, flip-inline, bottom left;
  width: 100px;
}

So far, so good. We have an anchored target element that starts at the top-right corner of the anchor at 100px. If it runs out of space there, it will look at the position-try property and decide whether to reposition the target to the anchor’s top-left corner (declared as flip-inline) or the anchor’s bottom-left corner — whichever offers the most width.

But what if we want to simulataneously re-size the target element when it is re-positioned? Maybe the target is simply too dang big to display at 100px at either fallback position and we need it to be 50px instead. We can use the @position-try to do exactly that:

@position-try --my-custom-position {
  position-area: top left;
  width: 50px;
}

With that done, we now have a custom property called --my-custom-position that we can use on the position-try shorthand property. In this case, @position-try can replace the flip-inline value since it is the equivalent of top left:

@position-try --my-custom-position {
  position-area: top left;
  width: 50px;
}

.target {
  position: absolute;
  position-area: top right;
  position-try: most-width, --my-custom-position, bottom left;
  width: 100px;
}

This way, the .target element’s width is re-sized from 100px to 50px when it attempts to re-position itself to the anchor’s top-right edge. That’s a nice bit of flexibility that gives us a better chance to make things fit together in any layout.

Anchor functions

anchor()

You might think of the CSS anchor() function as a shortcut for attaching a target element to an anchor element — specify the anchor, the side we want to attach to, and how large we want the target to be in one fell swoop. But, as we’ll see, the function also opens up the possibility of attaching one target element to multiple anchor elements.

This is the function’s formal syntax, which takes up to three arguments:

anchor( <anchor-element>? && <anchor-side>, <length-percentage>? )

So, we’re identifying an anchor element, saying which side we want the target to be positioned on, and how big we want it to be. It’s worth noting that anchor() can only be declared on inset-related properties (e.g. top, left, inset-block-end, etc.)

.target {
  top: anchor(--my-anchor bottom);
  left: anchor(--my-anchor end, 50%);
}

Let’s break down the function’s arguments.

<anchor-element>

This argument specifies which anchor element we want to attach the target to. We can supply it with either the anchor’s name (see “Attaching targets to anchors”).

We also have the choice of not supplying an anchor at all. In that case, the target element uses an implicit anchor element defined in position-anchor. If there isn’t an implicit anchor, the function resolves to its fallback. Otherwise, it is invalid and ignored.

<anchor-side>

This argument sets which side of the anchor we want to position the target element to, e.g. the anchor’s top, left, bottom, right, etc.

But we have more options than that, including logical side keywords (inside, outside), logical direction arguments relative to the user’s writing mode (start, end, self-start, self-end) and, of course, center.

  • <anchor-side>: Resolves to the <length> of the corresponding side of the anchor element. It has physical arguments (top, left, bottom right), logical side arguments (inside, outside), logical direction arguments relative to the user’s writing mode (start, end, self-start, self-end) and the center argument.
  • <percentage>: Refers to the position between the start (0%) and end (100%). Values below 0% and above 100% are allowed.
<length-percentage>

This argument is totally optional, so you can leave it out if you’d like. Otherwise, use it as a way of re-sizing the target elemenrt whenever it doesn’t have a valid anchor or position. It positions the target to a fixed <length> or <percentage> relative to its containing block.

Let’s look at examples using different types of arguments because they all do something a little different.

Using physical arguments
targets sorrounding the anchor. each with a different position

Physical arguments (top, right, bottom, left) can be used to position the target regardless of the user’s writing mode. For example, we can position the right and bottom inset properties of the target at the anchor(top) and anchor(left) sides of the anchor, effectively positioning the target at the anchor’s top-left corner:

.target {
  bottom: anchor(top);
  right: anchor(left);
}
Using logical side keywords
targets sorrounding the anchor. each with a different position

Logical side arguments (i.e., insideoutside), are dependent on the inset property they are in. The inside argument will choose the same side as its inset property, while the outside argument will choose the opposite. For example:

.target {
  left: anchor(outside);
  /* is the same as */
  left: anchor(right);

  top: anchor(inside);
  /* is the same as */
  top: anchor(top);
}
Using logical directions
targets sorrounding the anchor. each with a different position

Logical direction arguments are dependent on two factors:

  1. The user’s writing mode: they can follow the writing mode of the containing block (start, end) or the target’s own writing mode (self-start, self-end).
  2. The inset property they are used in: they will choose the same axis of their inset property.

So for example, using physical inset properties in a left-to-right horizontal writing would look like this:

.target {
  left: anchor(start);
  /* is the same as */
  left: anchor(left);

  top: anchor(end);
  /* is the same as */
  top: anchor(bottom);
}

In a right-to-left writing mode, we’d do this:

.target {
  left: anchor(start);
  /* is the same as */
  left: anchor(right);

  top: anchor(end);
  /* is the same as */
  top: anchor(bottom);
}

That can quickly get confusing, so we should also use logical arguments with logical inset properties so the writing mode is respected in the first place:

.target {
  inset-inline-start: anchor(end);
  inset-block-start: anchor(end);
}
Using percentage values
targets sorrounding the anchor. each with a different position

Percentages can be used to position the target from any point between the start (0%) and end (100% ) sides. Since percentages are relative to the user writing mode, is preferable to use them with logical inset properties.

.target {
  inset-inline-start: anchor(100%);
  /* is the same as */
  inset-inline-start: anchor(end);

  inset-block-end: anchor(0%);
  /* is the same as */
  inset-block-end: anchor(start);
}

Values smaller than 0% and bigger than 100% are accepted, so -100% will move the target towards the start and 200% towards the end.

.target {
  inset-inline-start: anchor(200%);
  inset-block-end: anchor(-100%);
}
Using the center keyword
targets sorrounding the anchor. each with a different position

The center argument is equivalent to 50%. You could say that it’s “immune” to direction, so there is no problem if we use it with physical or logical inset properties.

.target {
  position: absolute;
  position-anchor: --my-anchor;

  left: anchor(center);
  bottom: anchor(top);
}

anchor-size()

The anchor-size() function is unique in that it sizes the target element relative to the size of the anchor element. This can be super useful for ensuring a target scales in size with its anchor, particularly in responsive designs where elements tend to get shifted, re-sized, or obscured from overflowing a container.

The function takes an anchor’s side and resolves to its <length>, essentially returning the anchor’s width, height, inline-size or block-size.

anchor-size( [ <anchor-element> || <anchor-size> ]? , <length-percentage>? )
anchor with an anchor-size() function on each side

Here are the arguments that can be used in the anchor-size() function:

  • <anchor-size>: Refers to the side of the anchor element.
  • <length-percentage>: This optional argument can be used as a fallback whenever the target doesn’t have a valid anchor or size. It returns a fixed <length> or <percentage> relative to its containing block.

And we can declare the function on the target element’s width and height properties to size it with the anchor — or both at the same time!

.target {
  width: anchor-size(width, 20%); /* uses default anchor */`
  height: anchor-size(--other-anchor inline-size, 100px);
}

Multiple anchors

We learned about the anchor() function in the last section. One of the function’s quirks is that we can only declare it on inset-based properties, and all of the examples we saw show that. That might sound like a constraint of working with the function, but it’s actually what gives anchor() a superpower that anchor positioning properties don’t: we can declare it on more than one inset-based property at a time. As a result, we can set the function multiple anchors on the same target element!

Here’s one of the first examples of the anchor() function we looked at in the last section:

.target {
  top: anchor(--my-anchor bottom);
  left: anchor(--my-anchor end, 50%);
}

We’re declaring the same anchor element named --my-anchor on both the top and left inset properties. That doesn’t have to be the case. Instead, we can attach the target element to multiple anchor elements.

.anchor-1 { anchor-name: --anchor-1; }
.anchor-2 { anchor-name: --anchor-2; }
.anchor-3 { anchor-name: --anchor-3; }
.anchor-4 { anchor-name: --anchor-4; }

.target {
  position: absolute;
  inset-block-start: anchor(--anchor-1);
  inset-inline-end: anchor(--anchor-2);
  inset-block-end: anchor(--anchor-3);
  inset-inline-start: anchor(--anchor-4);
}

Or, perhaps more succintly:

.anchor-1 { anchor-name: --anchor-1; }
.anchor-2 { anchor-name: --anchor-2; }
.anchor-3 { anchor-name: --anchor-3; }
.anchor-4 { anchor-name: --anchor-4; }

.target {
  position: absolute;
  inset: anchor(--anchor-1) anchor(--anchor-2) anchor(--anchor-3) anchor(--anchor-4);
}

The following demo shows a target element attached to two <textarea> elements that are registered anchors. A <textarea> allows you to click and drag it to change its dimensions. The two of them are absolutely positioned in opposite corners of the page. If we attach the target to each anchor, we can create an effect where resizing the anchors stretches the target all over the place almost like a tug-o-war between the two anchors.

The demo is only supported in Chrome at the time we’re writing this guide, so let’s drop in a video so you can see how it works.

Accessibility

The most straightforward use case for anchor positioning is for making tooltips, info boxes, and popovers, but it can also be used for decorative stuff. That means anchor positioning doesn’t have to establish a semantic relationship between the anchor and target elements. You can probably spot the issue right away: non-visual devices, like screen readers, are left in the dark about how to interpret two seemingly unrelated elements.

As an example, let’s say we have an element called .tooltip that we’ve set up as a target element anchored to another element called .anchor.

<div class="anchor">anchor</div>
<div class="toolip">toolip</div>
.anchor {
  anchor-name: --my-anchor;
}

.toolip {
  position: absolute;
  position-anchor: --my-anchor;
  position-area: top;
}

We need to set up a connection between the two elements in the DOM so that they share a context that assistive technologies can interpret and understand. The general rule of thumb for using ARIA attributes to describe elements is generally: don’t do it. Or at least avoid doing it unless you have no other semantic way of doing it.

This is one of those cases where it makes sense to reach for ARIA atributes. Before we do anything else, a screen reader currently sees the two elements next to one another without any remarking relationship. That’s a bummer for accessibility, but we can easily fix it using the corresponding ARIA attribute:

<div class="anchor" aria-describedby="tooltipInfo">anchor</div>
<div class="toolip" role="tooltip" id="tooltipInfo">toolip</div>

And now they are both visually and semantically linked together! If you’re new to ARIA attributes, you ought to check out Adam Silver’s “Why, How, and When to Use Semantic HTML and ARIA” for a great introduction.

Browser support

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

Desktop

Chrome Firefox IE Edge Safari
125 No No 125 No

Mobile / Tablet

Android Chrome Android Firefox Android iOS Safari
129 No 129 No

Spec changes

CSS Anchor Positioning has undergone several changes since it was introduced as an Editor’s Draft. The Chrome browser team was quick to hop on board and implement anchor positioning even though the feature was still being defined. That’s caused confusion because Chromium-based browsers implemented some pieces of anchor positioning while the specification was being actively edited.

We are going to outline specific cases for you where browsers had to update their implementations in response to spec changes. It’s a bit confusing, but as of Chrome 129+, this is the stuff that was shipped but changed:

position-area

The inset-area property was renamed to position-area (#10209), but it will be supported until Chrome 131.

.target {
  /* from */
  inset-area: top right;

  /* to */
  position-area: top right;
}

position-try-fallbacks

The position-try-options was renamed to position-try-fallbacks (#10395).

.target {
  /* from */
  position-try-options: flip-block, --smaller-target;

  /* to */
  position-try-fallbacks: flip-block, --smaller-target;
}

inset-area()

The inset-area() wrapper function doesn’t exist anymore for the position-try-fallbacks (#10320), you can just write the values without the wrapper:

.target {
  /* from */
  position-try-options: inset-area(top left);

  /* to */
  position-try-fallbacks: top left;
}

anchor(center)

In the beginning, if we wanted to center a target from the center, we would have to write this convoluted syntax:

.target {
  --center: anchor(--x 50%);
  --half-distance: min(abs(0% - var(--center)), abs(100% - var(--center)));

  left: calc(var(--center) - var(--half-distance));
  right: calc(var(--center) - var(--half-distance));
}

The CWSSG working group resolved (#8979) to add the anchor(center) argument to prevent us from having to do all that mental juggling:

.target {
  left: anchor(center);
}

Known bugs

Yes, there are some bugs with CSS Anchor Positioning, at least at the time this guide is being written. For example, the specification says that if an element doesn’t have a default anchor element, then the position-area does nothing. This is a known issue (#10500), but it’s still possible to replicate.

So, the following code…

.container {
  position: relative;
}

.element {
  position: absolute;
  position-area: center;
  margin: auto;
}

…will center the .element inside its container, at least in Chrome:

Credit to Afif13 for that great demo!

Another example involves the position-visibility property. If your anchor element is out of sight or off-screen, you typically want the target element to be hidden as well. The specification says that property’s the default value is anchors-visible, but browsers default to always instead.

The current implemenation in Chrome isn’t reflecting the spec; it indeed is using always as the initial value. But the spec is intentional: if your anchor is off-screen or otherwise scrolled off, you usually want it to hide. (#10425)

Almanac references

Anchor position properties

Anchor position functions

Anchor position at-rules

Further reading


CSS Anchor Positioning Guide originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/XFqIaUB
Gain $200 in a week
via Read more

Interview With Björn Ottosson, Creator Of The Oklab Color Space

Featured Imgs 23

Oklab is a new perceptual color space supported in all major browsers created by the Swedish engineer Björn Ottosson. In this interview, Philip Jägenstedt explores how and why Björn created Oklab and how it spread across the ecosystem.

Note: The original interview was conducted in Swedish and is available to watch.

About Björn

Philip Jägenstedt: Tell me a little about yourself, Björn.

Björn Ottosson: I worked for many years in the game industry on game engines and games like FIFA, Battlefield, and Need for Speed. I've always been interested in technology and its interaction with the arts. I’m an engineer, but I’ve always held both of these interests.

On Working With Color

Philip: For someone who hasn’t dug into colors much, what’s so hard about working with them?

Björn: Intuitively, colors can seem quite simple. A color can be lighter or darker, it can be more blue or more green, and so on. Everyone with typical color vision has a fairly similar experience of color, and this can be modeled.

However, the way we manipulate colors in software usually doesn’t align with human perception of colors. The most common color space is sRGB. There’s also HSL, which is common for choosing colors, but it’s also based on sRGB.

One problem with sRGB is that in a gradient between blue and white, it becomes a bit purple in the middle of the transition. That’s because sRGB really isn’t created to mimic how the eye sees colors; rather, it is based on how CRT monitors work. That means it works with certain frequencies of red, green, and blue, and also the non-linear coding called gamma. It’s a miracle it works as well as it does, but it’s not connected to color perception. When using those tools, you sometimes get surprising results, like purple in the gradient.

On Color Perception

Philip: How do humans perceive color?

Björn: When light enters the eye and hits the retina, it’s processed in many layers of neurons and creates a mental impression. It’s unlikely that the process would be simple and linear, and it’s not. But incredibly enough, most people still perceive colors similarly.

People have been trying to understand colors and have created color wheels and similar visualizations for hundreds of years. During the 20th century, a lot of research and modeling went into color vision. For example, the CIE XYZ model is based on how sensitive our photoreceptor cells are to different frequencies of light. CIE XYZ is still a foundational color space on which all other color spaces are based.

There were also attempts to create simple models matching human perception based on XYZ, but as it turned out, it’s not possible to model all color vision that way. Perception of color is incredibly complex and depends, among other things, on whether it is dark or light in the room and the background color it is against. When you look at a photograph, it also depends on what you think the color of the light source is. The dress is a typical example of color vision being very context-dependent. It is almost impossible to model this perfectly.

Models that try to take all of this complexity into account are called color appearance models. Although they have many applications, they’re not that useful if you don’t know if the viewer is in a light or bright room or other viewing conditions.

The odd thing is that there’s a gap between the tools we typically use — such as sRGB and HSL — and the findings of this much older research. To an extent, this makes sense because when HSL was developed in the 1970s, we didn’t have much computing power, so it’s a fairly simple translation of RGB. However, not much has changed since then.

We have a lot more processing power now, but we’ve settled for fairly simple tools for handling colors in software.

Display technology has also improved. Many displays now have different RGB primaries, i.e., a redder red, greener green, or bluer blue. sRGB cannot reach all colors available on these displays. The new P3 color space can, but it's very similar to sRGB, just a little wider.

On Creating Oklab

Philip: What, then, is Oklab, and how did you create it?

Björn: When working in the game industry, sometimes I wanted to do simple color manipulations like making a color darker or changing the hue. I researched existing color spaces and how good they are at these simple tasks and concluded that all of them are problematic in some way.

Many people know about CIE Lab. It’s quite close to human perception of color, but the handling of hue is not great. For example, a gradient between blue and white turns out purple in CIE Lab, similar to in sRGB. Some color spaces handle hue well but have other issues to consider.

When I left my job in gaming to pursue education and consulting, I had a bit of time to tackle this problem. Oklab is my attempt to find a better balance, something Lab-like but “okay”.

I based Oklab on two other color spaces, CIECAM16 and IPT. I used the lightness and saturation prediction from CIECAM16, which is a color appearance model, as a target. I actually wanted to use the datasets used to create CIECAM16, but I couldn’t find them.

IPT was designed to have better hue uniformity. In experiments, they asked people to match light and dark colors, saturated and unsaturated colors, which resulted in a dataset for which colors, subjectively, have the same hue. IPT has a few other issues but is the basis for hue in Oklab.

Using these three datasets, I set out to create a simple color space that would be “okay”. I used an approach quite similar to IPT but combined it with the lightness and saturation estimates from CIECAM16. The resulting Oklab still has good hue uniformity but also handles lightness and saturation well.

Philip: How about the name Oklab? Why is it just okay?

Björn: This is a bit tongue-in-cheek and some amount of humility.

For the tasks I had in mind, existing color spaces weren’t okay, and my goal was to make one that is. At the same time, it is possible to delve deeper. If a university had worked on this, they could have run studies with many participants. For a color space intended mainly for use on computer and phone screens, you could run studies in typical environments where they are used. It’s possible to go deeper.

Nevertheless, I took the datasets I could find and made the best of what I had. The objective was to make a very simple model that’s okay to use. And I think it is okay, and I couldn’t come up with anything better. I didn’t want to call it Björn Ottosson Lab or something like that, so I went with Oklab.

Philip: Does the name follow a tradition of calling things okay? I know there’s also a Quite OK Image format.

Björn: No, I didn’t follow any tradition here. Oklab was just the name I came up with.

On Oklab Adoption

Philip: I discovered Oklab when it suddenly appeared in all browsers. Things often move slowly on the web, but in this case, things moved very quickly. How did it happen?

Björn: I was surprised, too! I wrote a blog post and shared it on Twitter.

I have a lot of contacts in the gaming industry and some contacts in the Visual Effects (VFX) industry. I expected that people working with shaders or visual effects might try this out, and maybe it would be used in some games, perhaps as an effect for a smooth color transition.

But the blog post was spread much more widely than I thought. It was on Hacker News, and many people read it.

The code for Oklab is only 10 lines long, so many open-source libraries have adopted it. This all happened very quickly.

Chris Lilley from the W3C got in touch and asked me some questions about Oklab. We discussed it a bit, and I explained how it works and why I created it. He gave a presentation at a conference about it, and then he pushed for it to be added to CSS.

Photoshop also changed its gradients to use Oklab. All of this happened organically without me having to cheer it on.

On Okhsl

Philip: In another blog post, you introduced two other color spaces, Okhsv and Okhsl. You’ve already talked about HSL, so what is Okhsl?

Björn: When picking colors, HSL has a big advantage, which is that the parameter space is simple. Any value 0-360 for hue (H) together with any values 0-1 for saturation (S) and lightness (L) are valid combinations and result in different colors on screen. The geometry of HSL is a cylinder, and there’s no way to end up outside that cylinder accidentally.

By contrast, Oklab contains all physically possible colors, but there are combinations of values that don’t work where you reach colors that don’t exist. For example, starting from light and saturated yellow in Oklab and rotating the hue to blue, that blue color does not exist in sRGB; there are only darker and less saturated blues. That’s because sRGB in Oklab has a strange shape, so it’s easy to end up going outside it. This makes it difficult to select and manipulate colors with Oklab or Oklch.

Okhsl was an attempt at compromise. It maintains Oklab’s behavior for colors that are not very saturated, close to gray, and beyond that, stretches out to a cylinder that contains all of sRGB. Another way to put it is that the strange shape of sRGB in Oklab has been stretched into a cylinder with reasonably smooth transitions.

The result is similar to HSL, where all parameters can be changed independently without ending up outside sRGB. It also makes Okhsl more complicated than Oklab. There are unavoidable compromises to get something with the characteristics that HSL has.

Everything with color is about compromises. Color vision is so complex that it's about making practical compromises.

This is an area where I wish there were more research. If I have a white background and want to pick some nice colors to put on it, then you can make a lot of assumptions. Okhsl solves many things, but is it possible to do even better?

On Color Compromises

Philip: Some people who have tried Oklab say there are too many dark shades. You changed that in Okhsl with a new lightness estimate.

Björn: This is because Oklab is exposure invariant and doesn’t account for viewing conditions, such as the background color. On the web, there’s usually a white background, which makes it harder to see the difference between black and other dark colors. But if you look at the same gradient on a black background, the difference is more apparent.

CIE Lab handles this, and I tried to handle it in Okhsl, too. So, gradients in Okhsl look better on a white background, but there will be other issues on a black background. It’s always a compromise.

And, Finally…

Philip: Final question: What’s your favorite color?

Björn: I would have to say Burgundy. Burgundy, dark greens, and navy blues are favorites.

Philip: Thank you for your time, Björn. I hope our readers have learned something, and I’ll remind them of your excellent blog, where you go into more depth about Oklab and Okhsl.

Björn: Thank you!



Gain $200 in a week
from Articles on Smashing Magazine — For Web Designers And Developers https://ift.tt/p0n1ylf

Slide Through Unlimited Dimensions With CSS Scroll Timelines

Featured Imgs 23

The creator of CSS has said he originally envisaged CSS as the main web technology to control behavior on web pages, with scripting as a fallback when things weren’t possible declaratively in CSS. The rationale for a CSS-first approach was that “scripting is programming and programming is hard.” Since introducing the :hover pseudo-class, CSS has been standardizing patterns developers create in JavaScript and “harvesting” them into CSS standards. When you think about it like that, it’s almost as if JavaScript is the hack and CSS is the official way.

We can, therefore, feel less dirty implementing script-like behavior with CSS, and we shouldn’t be surprised that something like the new scroll-timeline feature has appeared with pretty good browser support. Too many developers implemented clever parallax scrolling websites, which has summoned the CSS feature genie we cannot put back in its bottle. If you don’t want janky main-thread animations for your next parallax-scrolling website, you must now come to the dark side of hacking CSS. Just kidding, there is also a new JavaScript API for scroll-linked animations if imperative programming better fits your use case.

Migrating a JavaScript sample to CSS

It was satisfyingly simple to fork Chris Coyier’s pre-scroll-timeline example of a scroll-linked animation by replacing the CSS Chris was using to control the animations with just one line of CSS and completely deleting the JavaScript!

body, .progress, .cube {
  animation-timeline: scroll();
}

Using the scroll() function without parameters sets up an “anonymous scroll progress timeline” meaning the browser will base the animation on the nearest ancestor that can scroll vertically if our writing mode is English. Unfortunately, it seems we can only choose to animate based on scrolling along the x or y-axis of a particular element but not both, which would be useful. Being a function, we can pass parameters to scroll(), which provides more control over how we want scrolling to run our animation.

Experimenting with multiple dimensions

Even better is the scroll-scope property. Applying that to a container element means we can animate properties on any chosen ancestor element based on any scrollable element that has the same assigned scope. That got me thinking… Since CSS Houdini lets us register animation-friendly, inheritable properties in CSS, we can combine animations on the same element based on multiple scrollable areas on the page. That opens the door for interesting instructional design possibilities such as my experiment below.

Scrolling the horizontal narrative on the light green card rotates the 3D NES console horizontally and scrolling the vertical narrative on the dark green card rotates the NES console vertically. In my previous article, I noted that my past CSS hacks have always boiled down to hiding and showing finite possibilities using CSS. What interests me about this scroll-based experiment is the combinatorial explosion of combined vertical and horizontal rotations. Animation timelines provide an interactivity in pure CSS that hasn’t been possible in the past.

The implementation details are less important than the timeline-scope usage and the custom properties. We register two custom angle properties:

@property --my-y-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}

@property --my-x-angle {
  syntax: "<angle>";
  inherits: true;
  initial-value: -35deg;
}

Then, we “borrow” the NES 3D model from the samples in Julian Garner’s amazing CSS 3D modeling app. We update the .scene class for the 3D to base the rotation on our new variables like this:

.scene {
  transform: rotateY(var(--my-y-angle)) rotateX(var(--my-x-angle));
}

Next, we give the <body> element a timeline-scope with two custom-named scopes.

body {
  timeline-scope: --myScroller,--myScroller2; 
}

I haven’t seen anything officially documented about passing in multiple scopes, but it does work in Google Chrome and Edge. If it’s not a formally supported feature, I hope it will become part of the standard because it is ridiculously handy.

Next, we define the named timelines for the two scrollable cards and the axes we want to trigger our animations.

.card:first-child {
  scroll-timeline-axis: x;
  scroll-timeline-name: --myScroller;
}

.card:nth-child(2) {
  scroll-timeline-axis: y;
  scroll-timeline-name: --myScroller2;
}

And add the animations to the scene:

.scene {
  animation: rotateHorizontal,rotateVertical;
  animation-timeline: --myScroller,--myScroller2;
}

@keyframes rotateHorizontal {
  to {
    --my-y-angle: 360deg;
  }
}

@keyframes rotateVertical {
  to {
    --my-x-angle: 360deg;
  }
}

Since the 3D model inherits the x and y angles from the document body, scrolling the cards now rotates the model in combinations of vertical and horizontal angle changes.

User-controlled animations beyond scrollbars

When you think about it, this behavior isn’t just useful for scroll-driven animations. In the above experiment, we are using the scrollable areas more like sliders that control the properties of our 3D model. After getting it working, I went for a walk and was daydreaming about how cool it would be if actual range inputs could control animation timelines. Then I found out they can! At least in Chrome. Pure CSS CMS anyone?

While we’re commandeering 3D models from Julian Garner, let’s see if we can use range inputs to control his X-wing model.

It’s mind-boggling that we can achieve this with just CSS, and we could do it with an arbitrary number of properties. It doesn’t go far enough for me. I would love to see other input controls that can manipulate animation timelines. Imagine text fields progressing animations as you fill them out, or buttons able to play or reverse animations. The latter can be somewhat achieved by combining the :active pseudo-class with the animation-play-state property. But in my experience when you try to use that to animate multiple custom properties, the browser can get confused. By contrast, animation timelines have been implemented with this use case in mind and therefore work smoothly and exactly as I expected.

I’m not the only one who has noticed the potential for hacking this emergent CSS feature. Someone has already implemented this clever Doom clone by combining scroll-timeline with checkbox hacks. The problem I have is it still doesn’t go far enough. We have enough in Chrome to implement avatar builders using scrollbars and range inputs as game controls. I am excited to experiment with unpredictable, sophisticated experiences that are unprecedented in the era before the scroll-timeline feature. After all, if you had to explain the definition of a video game to an alien, wouldn’t you say it is just a hyper-interactive animation?


Slide Through Unlimited Dimensions With CSS Scroll Timelines originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/pUX7wjR
Gain $200 in a week
via Read more

How To Manage Dangerous Actions In User Interfaces

Featured Imgs 23

By definition, an interface is a layer between the user and a system, serving the purpose of communication between them. Interacting with the interface usually requires users to perform certain actions.

Different actions can lead to various outcomes, some of which might be critical.

While we often need to provide additional protection in case users attempt to perform dangerous or irreversible actions, It’s good to remember that one of the ten usability heuristics called “Error Prevention” says:

“Good error messages are important, but the best designs carefully prevent problems from occurring in the first place. Either eliminate error-prone conditions or check for them and present users with a confirmation option before they commit to the action.”
What Is A Dangerous Action?

Surprisingly, when we talk about dangerous actions, it doesn’t necessarily mean that something is being deleted.

Here’s an example of a dangerous action from the banking application I use:

The bank approved a loan for me, and as soon as I clicked “Get Money,” it meant that I had signed the necessary documents and accepted the loan. All I have to do is tap the yellow button, and I’ll get the money.

As a result of an accidental tap, you might end up taking a loan when you didn’t intend to, which is why this action can be considered significant and dangerous.

Therefore, a dangerous action does not necessarily mean deleting something.

Some examples may include the following:

  • Sending an email,
  • Placing an order,
  • Publishing a post,
  • Making a bank transaction,
  • Signing a legal document,
  • Permanently blocking a user,
  • Granting or revoking permissions.
Ways To Confirm Dangerous Actions

There are many methods to prevent users from losing their data or taking irreversible actions unintentionally. One approach is to ask users to explicitly confirm their actions.

There are several ways to implement this, each with its own pros and cons.

Modal Dialogs

First of all, we should understand the difference between modal and non-modal dialogs. It’s better to think about modality state since dialogs, popups, alerts — all of these might be presented either in the modal state or not. I will use the term dialogs as a general reference, but the keyword here is modality.

“Modality is a design technique that presents content in a separate, dedicated mode that prevents interaction with the parent view and requires an explicit action to dismiss.”

Apple design guides

Modal dialogs require immediate user action. In other words, you cannot continue working with an application until you respond in some way.

Non-modal dialogs, on the other hand, allow you to keep using the application without interruption. A common example of a non-modal element is a toast message that appears in the corner of the screen and does not require you to do anything to continue using the app.

When used properly, modal dialogs are an effective way to prevent accidental clicks on dangerous actions.

The main problem with them is that if they are used to confirm routine actions (such as marking a task as done), they can cause irritation and create a habit of mindlessly confirming them on autopilot.

However, this is one of the most popular methods. Besides, it can be combined with other methods, so let’s dive into it deeper.

When To Use Them

Use modal dialogs when a user action will have serious consequences, especially if the result of the action is irreversible. Typical cases include deleting a post or project, confirming a transaction, and so on.

It depends on what kind of action users want to take, but the main thing to keep in mind is how serious the consequences are and whether the action is reversible or not.

Things To Keep In Mind

  1. Avoid vague language.
    If you ask users, “Are you sure?” chances are, they will not have any doubts.
  2. In the title, specify what exactly will happen or which entity will be affected (e.g., project name, user name, amount of money).
  3. Provide an icon that indicates that the action is dangerous.
    It both increases the chances that users will not automatically confirm it and is good for accessibility reasons (people with color blindness will notice the icon even if it appears grey to them, signaling its importance).
  4. In the description, be specific and highlight the necessary information.
  5. The CTA button should also contain a word that reflects the action.
    Instead of “Yes” or “Confirm,” use more descriptive options like “Delete,” “Pay $97,” “Make Transaction,” “Send Message,” and so on — including the entity name or amount of money in the button is also helpful. Compare: “Confirm” versus “Pay $97.” The latter is much more specific.

However, this might not be enough.

In some cases, you may require an extra action. A typical solution is to ask users to type something (e.g., a project name) to unblock the CTA button.

Here are a few examples:

ConvertKit asks users to type “DO IT” when removing subscribers.

Pro tip: Note that they placed the buttons on the left side! This is a nice example of applying proximity law. It seems reasonable since the submit button is closer to the form (even if it consists of only one input).

Resend asks users to type “DELETE” if they want to delete an API key, which could have very serious consequences. The API key might be used in many of your apps, and you don’t want to break anything.

This modal is one of the best examples of following the best practices:

  • The title says what the action is (“Delete API Key”).
  • In the text, they mentioned the name of the API Key in bold and in a different color (“Onboarding”).
  • The red label that the action can not be undone makes it clearer that this is a serious action.
  • Extra action is required (typing “DELETE”).
  • The CTA button has both a color indicator (red usually is used for destructive actions) and a proper label — “Delete API Key”. Not a general word, e.g., “Confirm” or “Delete.”

Notice that Resend also places buttons on the left side, just as ConvertKit does.

Note: While generally disabling submit buttons is considered bad practice, this is one of the cases where it is acceptable. The dialog’s request is clear and straightforward both in ConvertKit and Resend examples.

Moreover, we can even skip the submit button altogether. This applies to cases where users are asked to input an OTP, PIN, or 2FA code. For example, the bank app I use does not even have a log in button.

On the one hand, we still ask users to perform an extra action (input the code). On the other hand, it eliminates the need for an additional click.

Accessibility Concerns

There is ongoing debate about whether or not to include a submit button when entering a simple OTP. By “simple,” I mean one that consists of 4-6 digits.

While I am not an accessibility expert, I don’t see any major downsides to omitting the submit button in straightforward cases like this.

First, the OTP step is typically an intermediate part of the user flow, meaning a form with four inputs appears during some process. The first input is automatically focused, and users can navigate through them using the Tab key.

The key point is that, due to the small amount of information required (four digits), it is generally acceptable to auto-submit the form as soon as the digits are entered, even if a mistake is made.

On the one hand, if we care about accessibility, nothing stops us from providing users control over the inputs. On the other hand, auto-submission streamlines the process in most cases, and in the rare event of an error, the user can easily re-enter the digits.

Danger Zones

For the most critical actions, you may use the so-called “Danger zone” pattern.

A common way to implement this is to either have a dedicated page or place the set of actions at the bottom of the settings/account page.

It might contain one or more actions and is usually combined with other methods, e.g., a modal dialog. The more actions you have, the more likely you’ll need a dedicated page.

When To Use Them

Use a Danger Zone to group actions that are irreversible or have a high potential for data loss or significant outcomes for users.

These actions typically include things like account deletion, data wiping, or permission changes that could affect the user’s access or data.

Things To Keep In Mind

  1. Use colors like red, warning icons, or borders to visually differentiate the Danger Zone from the rest of the page.
  2. Each action in the Danger Zone should have a clear description of what will happen if the user proceeds so that users understand the potential consequences.
  3. Ask users for extra effort. Usually, the actions are irreversible and critical. In this case, you may ask users to repeat their password or use 2FA because if someone else gets access to the page, it will not be that easy to do the harmful action.
  4. Keep only truly critical actions there. Avoid making a danger zone for the sake of having one.

Inline Guards

Recently, I discovered that some apps have started using inline confirmation. This means that when you click on a dangerous action, it changes its label and asks you to click again.

This pattern is used by apps like Zapier and Typefully. While at first it seems convenient, it has sparked a lot of discussion and questions on X and Linkedin.

I’ve seen attempts to try to fix accidental double-clicking by changing the position of the inline confirmation label that appears after the first click.

But this creates layout shifts. When users work with the app daily, it may cause more irritation than help.

As an option, we can solve this issue by adding a tiny delay, e.g., 100-200ms, to prevent double-clicking.

It also matters who your users are. Remember the good old days when we used to click a dozen times to launch Internet Explorer and ended up with dozens of open instances?

If your target audience is likely to do this, apparently, the pattern will not work.

However, for apps like Zapier or Typefully, my assumption is that the target audience might benefit from the pattern.

Two-factor Authorization Confirmation

This method involves sending a confirmation request, with or without some kind of verification code, to another place, such as:

  • SMS,
  • Email,
  • Authenticator app on mobile,
  • Push notifications (e.g., instead of sending SMS, you may choose to send push notifications),
  • Messengers.

Notice: I’m not talking about authentication (namely, login process), but rather a confirmation action.

An example that I personally face a lot is an app for sending cryptocurrency. Since this is a sensitive request, apart from submitting the requisition from a website, I should also approve it via email.

When To Use It

It can be used for such operations as money transfers, ownership transfers, and account deletion (even if you have a danger zone). Most of us use this method quite often when we pay online, and our banks send us OTP (one-time password or one-time code).

It may go after the first initial protection method, e.g., a confirmation dialog.

As you can see, the methods are often combined and used together. We should not consider each of them in isolation but rather in the context of the whole business process.

Passkeys

Passkeys are a modern, password-less authentication method designed to enhance both security and user experience.

“Passkeys are a replacement for passwords. A password is something that can be remembered and typed, and a passkey is a secret stored on one’s devices, unlocked with biometrics.”

passkeys.dev

There are a few pros of using passkeys over 2FA, both in terms of security and UX:

  1. Unlike 2FA, which typically requires entering a code from another device or app (e.g., SMS or authenticator apps), passkeys streamline the confirmation process. They don’t require switching between devices or waiting for a code to arrive, providing immediate authentication.
  2. While 2FA provides extra protection, it is vulnerable to phishing, SIM-swapping, or interception. Passkeys are much more resistant to such attacks because they use public-private key cryptography. This means no secret code is ever sent over the network, making it phishing-resistant and not reliant on SMS or email, which can be compromised.
  3. Passkeys require less mental effort from users. There’s no need to remember a password or type a code — just authenticate with a fingerprint, facial recognition, or device-specific PIN. This way, we reduce cognitive load.
  4. With passkeys, the authentication process is almost instant. Unlike 2FA, where users might have to wait for a code or switch to another device, passkeys give us the opportunity to confirm actions without switching context, e.g., opening your email inbox or copying OTP from a mobile device.

The passkeys are widely supported and more and more companies adopt it.

Second-person Confirmation

This is a mechanism when two users are involved in the process. We may call them initiator and approver.

In this case, the initiator makes a request to take some action while the approver decides whether to confirm it or not.

In both roles, a confirmation dialog or other UI patterns may be used. However, the main idea is to separate responsibilities and decrease the probability of a bad decision.

Actually, you have likely encountered this method many times before. For example, a developer submits a pull request, while a code reviewer decides whether to confirm it or decline.

When To Use It

It is best suited for situations when the seriousness of decisions requires few people involved.

There is a direct analogy from real life. Take a look at the picture below:

The Council of Physicians reminds us that in medicine, seeking a second opinion is crucial, as collaboration and diverse perspectives often result in more informed decisions and better patient care. This is a perfect example of when a second opinion or an approver is essential.

Here, you will find some apps that use this method:

  • GitHub, as previously mentioned, for merging pull requests.
  • Jira and other similar apps. For example, when you move issues through a certain workflow stage, it may require manager approval.
  • Banking applications. When you make a high-value transaction, it could be necessary to verify it for legal issues.
  • Deel, which is a global hiring and payroll. One part (e.g., employer) draws up a contract and sends it to another part (e.g., freelancer), and the freelancer accepts it.

But here is the thing: We can consider it a separate method or rather an approach for implementing business logic because even if another person confirms an action, it is still a dangerous action, with the only difference being that now it’s another person who should approve it.

So, all of the examples mentioned above are not exactly a standalone specific way to protect users from making wrong decisions from the UI point of view. It’s rather an approach that helps us to reduce the number of critical mistakes.

Do We Actually Need To Ask Users?

When you ask users to take action, you should be aware of its original purpose.

The fact that users make actions does not mean that they make them consciously.

There are many behavioral phenomena that come from psychology, to name a few:

  • Cognitive inertia: The tendency of a person to stick to familiar decisions, even if they are not suitable for the current situation. For instance, the vast majority of people don’t read user agreements. They simply agree with the lengthy text because it’s necessary from the legal point of view.
  • Availability Heuristic: People often make decisions based on information that is easily accessible or familiar to them rather than making a mental effort. When users see the same confirmation popups, they might automatically accept them based on their previous successful experience. Of course, sooner or later, it might not work, and the acceptance of required action can lead to bad consequences.
  • Cognitive Miser: The human mind is considered to be a cognitive miser due to the tendency of humans to think and solve problems in simpler and less effortful ways rather than in more sophisticated and effortful ways, regardless of intelligence. This explains why many users just click “yes” or “agree” without carefully reading the text.
  • Quite a representative example is banner blindness, even though not related to confirmation but, in fact, revolves around the same human behavior idiosyncrasies.

A reasonable question that may arise: What are the alternatives?

Even though we cannot entirely affect users’ behavior, there are a few tactics we can use.

Delaying

In some scenarios, we can artificially delay the task execution in a graceful way.

One of my favorite examples is an app called Glovo, which is a food delivery app. Let’s have a look at the three screens you will see when you order something.

The first screen is a cart with items you chose to buy (and an annoying promotion of subscription that takes ⅓ of the screen).

After you tap the “confirm order” button, you’ll see the second screen, which asks you whether everything is correct. However, the information appears gradually with fade-in animation. Also, you can see there is a progress bar, which is a fake one.

After a few seconds, you’ll see another screen that shows that the app is trying to charge your card; this time, it’s a real process. After the transaction proceeds, you’ll see the status of the order and approximate delivery time.

Pro tip: When you show the status of the order and visually highlight or animate the first step, it makes users more confident that the order will be completed. Because of the trick that is called Goal-Gradient Effect.

You’ve just paid, and “something starts happening” (at least visually), which is a sign that “Oh, they should have already started preparing my order. That’s nice!”

The purpose of the screen with a fake progress bar is to let users verify the order details and confirm them.

But this is done in a very exquisite way:

  1. On the first screen, you click “confirm order”. It doesn’t invoke any modals or popups, such as “Are you sure?”.
  2. On the second screen, users can see how information about their order appears right away, and the scroll bar at the bottom goes further. It seems like that app is doing something, but it’s an illusion. An illusion that makes you take another quick look at what you’ve just ordered.

In the previous version of the app, you couldn’t even skip the process; you could only cancel it. Now they added the “Continue” button, which is essentially “Yes, I’m sure” confirmation.

This means that we return back again to the drawbacks of classic confirmation modals since users can skip the process. But the approach is different: it’s a combination of a feedback loop from the app and skipping the process.

This combination makes users pay attention to the address, order, and price at least sometimes, and it gives them time to cancel the order, while in the classic approach, the confirmation is “yes or no?” which is more likely to be confirmed right away.

The Undo Option

The undo pattern allows users to reverse an action they have just performed, providing a safety net that reduces anxiety around making mistakes.

Unlike confirmation modals that interrupt the workflow to ask for user confirmation, the undo pattern provides a smoother experience by allowing actions to be completed with the option to reverse them if needed.

When To Use It

It works perfectly fine for non-destructive, reversible actions &mdashl actions that don’t have significant and immediate consequences:

  • Reversing actions when editing a document (The beloved ctrl + z shortcut);
  • Removing a file (if it goes to the trash bin first);
  • Changing the status of a task (e.g., if you accidentally marked a task completed);
  • Deleting a message in a chat;
  • Applying filters to a photo.

Combined with a timer, you can extend the number of options since such tasks as sending an email or making a money transfer could be undone.

When You Cannot Use It

It’s not suitable for actions that have serious consequences, such as the following:

  • Deleting an account;
  • Submitting legal documents;
  • Purchasing goods (refund is not the same as the undo option);
  • Making requests for third-party APIs (in most cases).

How To Implement Them?

  1. The most common way that most people use every day is to provide a shortcut (ctrl + z). However, it’s constrained to some cases, such as text editors, moving files between folders, and so on.
  2. Toasts are probably the most common way to implement these web and mobile apps. The only thing that you should keep in mind is that it should stand out enough to be noticed. Hiding them in a corner with a tiny message and color that is not noticeable might not work — especially on wide screens.
  3. A straightforward solution is simply to have a button that does the undo option. Preferably close to the button that evokes the action that you want to undo.

The undo option is tightly related to the concept called soft deleting, which is widely used in backend frameworks such as Laravel.

The concept means that when users delete something via the UI, it looks like it has been deleted, but in the database, we keep the data but mark it as deleted. The data is not lost, which is why the undo option is possible since we don’t actually delete anything but rather mark it as deleted.

This is a good technique to ensure that data is never lost. However, not every table needs this.

For example, if you delete an account and don't want users to restore it (perhaps due to legal regulations), then you should erase the data completely. But in many cases, it might be a good idea to consider soft deleting. In the worst case, you’ll be able to manually restore user data if it cannot be done via the UI for some reason.

Conclusion

There’s something I want everyone to keep in mind, regardless of who you are or what you do.

Every situation is unique. A certain approach might work or fail for a variety of reasons. You might sometimes wonder why a specific decision was made, but you may not realize how many times the interface was revised based on real user feedback.

User behavior is affected by many factors, including country, age, culture, education, familiarity with certain patterns, disabilities, and more.

What’s crucial is to stay in control of your data and users and be prepared to respond when something goes wrong. Following best practices is important, but you must still verify if they work in your specific case.

Just like in chess, there are many rules — and even more exceptions.

Further Reading



Gain $200 in a week
from Articles on Smashing Magazine — For Web Designers And Developers https://ift.tt/B9mtKbJ

Aggregating my distributed self

Featured Imgs 23

Miriam Suzanne’s in the middle of a redesign of her personal website. It began in August 2022. She’s made an entire series out of the work that’s worth your time, but I wanted to call out the fifth and latest installment because she presents a problem that I think we can all relate to:

But the walls got in my way. Instead of minimal renovation, I got just far enough to live with it and then started a brand new Eleventy repo.

The plan was to prototype […] and bring back well-formed solutions. To echo Dave Rupert, prototyping is useful. It’s easier to play with new ideas when you’re not carrying a decade of content and old code along with you.

But prototyping evolved into what I would call tinkering (complimentary). Maybe I mean procrastinating (also complimentary), but it’s a wandering process that also helps me better understand what I want from a website. I might not make visible progress over two years, but I start to form a point of view […]. Keeping things easy is always where things get complicated. And it brings me back to where my redesign started – a desire to clarify the information architecture. Not only for visitors, but for myself.

Don’t even tell me you’ve never been there! Jim Neilsen blogged along similar lines. You get a stroke of inspiration that’s the kernel of some idea that motivates you to start, you know, working on it. There’s no real plan, perhaps. The idea and inspiration are more than enough to get you going… that is until you hit a snag. And what I appreciate about Miriam’s post is that she’s calling out content as the snag. Well, not so much a snag as a return to the founding principle for the redesign: a refined content architecture.

  • Sometimes I do events where I speak, or teach a workshop, or perform. Events happen at a time and place.
  • Sometimes I create artifacts like a book or an album, a website, or specification. Artifacts often have a home URL. They might have a launch date, but they are not date-specific.
  • Some of my projects are other channels with their own feeds, their own events and artifacts.
  • Those channels are often maintained by an organization that I work with long-term. A band, a web agency, a performance company, etc.

These boundaries aren’t always clean. A post that remains relevant could be considered an artifact. Events can generate artifacts, and vice versa. An entire organization might exist to curate a single channel.

So, Miriam’s done poking at visual prototypes and ready to pour the filling into the pie crust. I relate with this having recently futzed with the content architecure of this site. I find it tough to start with a solidified design before I know what content is going into it. But I also find it tough to work with no shape at all. In my case, CSS-Tricks has a well-established design that’s evolved, mostly outside of me. I love the design but it’s an inherited one and I’m integrating content around it. Design is the constraint. If I had the luxury of stripping the building to the studs, I might take a different approach because then I could “paint” around it. Content would be the constraint.

It’s yet another version of the Chicken-Egg dilemma. I still think of the (capital-W) Web as a content medium at least in a UA style sense in that it’s the default. It’s more than that, of course. I’m a content designer at heart (and trade) but I’m hesitant to cry “content is king” which reminded me of something I wrote for an end-of-year series we did here answering the question: What is one thing people can do to make their website better? My answer: Read your website.

We start to see the power of content when we open up our understanding of what it is, what it does, and where it’s used. That might make content one of the most extensible problem-solving tools in your metaphorical shed—it makes sites more accessible, extracts Google-juicing superpowers, converts sales, and creates pathways for users to accomplish what they need to do.

And as far as prioritizing content or design, or…?

The two work hand-in-hand. I’d even go so far as to say that a lot of design is about enhancing what is communicated on a page. There is no upstaging one or the other. Think of content and design as supporting one another, where the sum of both creates a compelling call-to-action, long-form post, hero banner, and so on. We often think of patterns in a design system as a collection of components that are stitched together to create something new. Pairing content and design works much the same way.

I’d forgotten those words, so I appreciate Miriam giving me a reason to revisit them. We all need to be recalibrated every so often — swap out air filters, top off the fluids, and rotate the ol’ tires. And an old dog like me needs it a little more often. I spent a few more minutes in that end-of-year series and found a few other choice quotes about the content-design continuum that may serve as inspiration for you, me, or maybe even Miriam as she continues the process of aggragating her distributed self.

This sounds serious, but don’t worry — the site’s purpose is key. If you’re building a personal portfolio, go wild! However, if someone’s trying to file a tax return, whimsical loading animations aren’t likely to be well-received. On the other hand, an animated progress bar could be a nice touch while providing visual feedback on the user’s action.

Cassie Evans, “Empathetic Animation”

Remember, the web is an interactive platform — take advantage of that, where appropriate (less is more, accessibility is integral, and you need to know your audience). Whether that’s scrollytelling, captioned video, and heck, maybe for your audience, now’s the time to start looking into AR/VR! Who knows. Sometimes you just need to try stuff out and see what sticks. Just be careful. Experimentation is great, but we need to make sure we’re bringing everyone along for the ride.

Mel Choyce, “Show, Don’t Tell”

Your personal site is a statement of who you are and what you want to do. If you showcase your favorite type of work, you’ll get more requests for similar projects or jobs — feeding back into a virtuous cycle of doing more of what you love.

Amelia Wattenberger, “Exactly What You Want”

And one of my favorites:

But the prime reason to have a personal website is in the name: it is your personalhome on the web. Since its early days, the web has been about sharing information and freedom of expression. Personal websites still deliver on that promise. Nowhere else do you have that much freedom to create and share your work and to tell your personal story. It is your chance to show what you stand for, to be different, and to be specific. Your site lets you be uniquely you and it can be whatever you imagine it to be.

So if you have a personal site, make sure to put in the work and attention to make it truly yours. Make it personal. Fine-tune the typography, add a theme switcher, or incorporate other quirky little details that add personality. As Sarah Drasner writes, you can feel it if a site is done with care and excitement. Those are the sites that are a joy to visit and will be remembered.

Matthias Ott, “Make it Personal”

That last one has the added perk of reminding me how incredibly great Sarah Drasner is.


Aggregating my distributed self originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/uJi9qQz
Gain $200 in a week
via Read more

Catching Up on the WordPress 🚫 WP Engine Sitch

Featured Imgs 23

Many of you — perhaps most of you — have been sitting on the sidelines while WordPress and WP Engine trade legal attacks on one another. It’s been widely covered as we watch it unfold in the open; ironically, in a sense.

These things can take twists and turns and it doesn’t help that this just so happens to be an emotionally charged topic in certain circles. WordPress is still the leading CMS after all these years and by a long shot. Many developers make their living in the WordPress ecosystem. All of those developers need hosting. WP Engine is still the leading WordPress-flavored host after many years. Many developers host their agencies there and use it to administrate their clients’ sites.

And I haven’t even gotten to the drama. That’s not really the point. The point is that there’s a bunch of heated words flying around and it can be difficult to know where they’re coming from, who they are aimed at, and most importantly, why they’re being said in the first place. So, I’m going to round up a few key voices contributing to the discussion for the sake of context and to help catch up.

Editor’s Note: Even though CSS-Tricks has no involvement with either company, I think it’s mentioning that Automattic was a looooooong time sponsor. This site was also once hosted by Flywheel, a company acquired by WP Engine before we moved to Cloudways following the DigitalOcean acquisition. Me? My personal site runs on WP Engine, but I’m not precious about it having only been there one year.

Prelude to a tweet

We had fair warning that something was coming up when WordPress co-founder Matt Mullenweg sent this out over X:

There’s the ammo: Don’t let private equity bully you into speaking up against the company you work for when its contributions to WordPress are on the slim side of things.

Private equity. Lack of participation in the WordPress community. Making a big public deal of it. Remember these things because this is one day before…

WordCamp US 2024

Matt spoke at WordCamp US (WCUS) 2024 in Portland, OR, last week. September 20 to be exact. Making big, bold statements at WCUS isn’t a new thing for Matt, as many of us still have “Learn JavaScript deeply” tattooed on the brain from 2016.

Matt’s statements this year were less inspirational (instructional?) as they took direct aim at WP Engine as part of a presentation on the merits of open-source collaboration. You can watch and listen to where the first jab was thrown roughly around the 10:05 marker of the recording.

Let’s break down the deal. Matt begins by comparing the open-source contributions to WordPress from his company, Automattic, to those of WP Engine. These things are tracked on WordPress.org as part of a campaign called “Five for the Future” that’s designed to give organizations an influential seat at the table to form the future of WordPress in exchange for open-source contributions back to the WordPress project. Automattic has a page totaling its contributions. So does WP Engine.

Before Matt reveals the numbers, he goes out of his way to call out the fact that both Automattic and WP Engine are large players in the neighborhood of $500 million dollars. That’s the setup for Matt to demonstrate how relatively little WP Engine contributes to WordPress against Matt’s own company. Granted, I neither have absolutely no clue what factors into contributions, nor how the pages are administrated or updated. But here’s what they show…

Automattic 116 contributors with 3,968 hours per week. WP Engine 11 contributors with 40 hours per week.

Quite the discrepancy! I’d imagine Automattic dwarfs every other company that’s pledged to the campaign. Maybe it would be better to compare the contributions of another non-Automattic pledge that has a fairly strong reputation for participating in WordPress community. 10up is one of the companies that comes straight to my mind and they are showing up for 191 hours per week, or roughly five times WP Engine’s reported time. I get conflicting info on 10up’s revenue, valuation, and size, so maybe the comparison isn’t fair. Or maybe it is fair because 10up is certainly smaller than WP Engine, and no estimate I saw was even close to the $500 million mark.

Whatever the case, bottom line: Matt calls out WP Engine for its lack of effort on a very public stage — maybe the largest — in WordPress Land. He doesn’t stop there, going on to namecheck Silver Lake, a ginormous private equity firm bankrolling the company. The insinuation is clear: there’s plenty of money and resources, so pony up.

That’s bad enough for attendees to raise eyebrows, but it doesn’t end there. Matt encourages users and developers alike to vote with money by not purchasing hosting from WP Engine (11:31) and seems to suggest (23:05) that he’ll provide financial support to any WP Engine employees who lose their jobs from speaking up against their employer.

I think I can get behind the general idea that some companies need a little prodding to pull their weight to something like the Five for the Future campaign. Encouraging developers to pull their projects from a company and employees to jeopardize their careers? Eek.

“WP Engine is not WordPress”

This is when I believe things got noisy. It’s one thing to strongarm a company (or its investors) into doing more for the community. But in a post on his personal blog the day after WCUS, Matt ups the ante alleging that “WP Engine isn’t WordPress.” You’d think this is part of the tough-guy stance he had from the stage, but his argument is much different in this post. Notice it’s about how WP Engine uses WordPress in its business rather than how much the company invests in it:

WordPress is a content management system, and the content is sacred. Every change you make to every page, every post, is tracked in a revision system, just like the Wikipedia. This means if you make a mistake, you can always undo it. It also means if you’re trying to figure out why something is on a page, you can see precisely the history and edits that led to it. These revisions are stored in our database. This is very important, it’s at the core of the user promise of protecting your data, and it’s why WordPress is architected and designed to never lose anything.

WP Engine turns this off. They disable revisions because it costs them more money to store the history of the changes in the database, and they don’t want to spend that to protect your content. It strikes to the very heart of what WordPress does, and they shatter it, the integrity of your content.

OK, gloves off. This is more personal. It’s no longer about community contributions but community trust and how WP Engine erodes trust by preventing WordPress users from accessing core WordPress features for their own profit.

Required reading

That’s where I’d like to end this, at least for now. Several days have elapsed since Matt’s blog post and there are many, many more words flying around from him, community members, other companies, and maybe even your Great Aunt. But if you’re looking for more signal than noise, I’ve rounded up a few choice selections that I feel contribute to the (heated) discussion.

Reddit: Matt Mullenweg needs to step down from WordPress.org leadership ASAP

Matt responds to the requisite calls for him to step down, starting with:

To be very clear, I was 100% cordial and polite to everyone at the booth, my message was:

* I know this isn’t about them, it’s happening several levels above, it’s even above their CEO, it’s coming from their owner, Silver Lake and particularly their board member Lee Wittlinger.

* Several people inside WP Engine have been anonymously leaking information to me about their bad behavior, and I wanted to let them know if they were caught or faced retaliation that I would support them in every way possible, including covering their salaries until they found a new job.

* That *if* we had to take down the WP Engine booth and ban WP Engine that evening, my colleague Chloé could print them all new personal badges if they still wanted to attend the conference personally, as they are community members, not just their company.

This was delivered calmly, and they said thank you, and their head of comms, Lauren Cox, who was there asked that they have time to regroup and discuss.

Automattic’s Actionable Misconduct Directed to WP Engine

WP Engine issues a cease and desist letter designed to stop Matt from disparaging them publicly. But hold up, because there’s another juicy claim in there:

In the days leading up to Mr. Mullenweg’s September 20th keynote address at the WordCamp US Convention, Automattic suddenly began demanding that WP Engine pay Automattic large sums of money, and if it didn’t, Automattic would wage a war against WP Engine.

And yes, they did issue it from their own site’s /wp-content directory. That’s easy to lose, so I’ve downloaded it to link it for posterity.

Open Source, Trademarks, and WP Engine

Just today, Matt published a cease and desist letter to the Auttomatic blog where he alleges that WP Engine’s commercial modifications to WordPress Core violate the WordPress trademark. Again, this has become about licensing, not contributions:

WP Engine’s business model is based on extensive and unauthorized use of these trademarks in ways that mislead consumers into believing that WP Engine is synonymous with WordPress. It’s not.

This is trademark abuse, not fair competition.

This is no longer WordPress vs. WP Engine. It’s more like Automattic vs. WP Engine. But with Matt’s name quite literally in the name Automattic, let’s be real and call this Matt Mullenweg vs. WP Engine.

WP Tavern coverage

WP Tavern is still the closest thing we have to an official WordPress news outlet. Nevermind that it’s funded and hired by Automattic (among others). I respect it, though I honestly have been less attentive to it since the team turned earlier this year. It’s still a great spot to catch up on the post-event coverage:

There’s another more recent WP Tavern article I want to call out because it’s a huge development in this saga…

WP Engine Banned from Using WordPress.org Resources

Dang. This is the point of no return. It not only affects WP Engine proper, but the Flywheel hosting it also owns.

WordPress.org has blocked WP Engine customers from updating and installing plugins and themes via WP Admin. 

I was able to update plugins on my site as recently as yesterday, but let’s see as of this morning.

Aww, biscuits.

Maybe I can still see details about my installed plugins…

Double biscuits!

This is a bad, bad situatiuon. I have thoughts about it and neither side looks good. Using real people with no dog in the fight to make a point is never gonna be a good look. Then again, both sides have valid points and I can see where they’re coming from. I just hate to see it come to a head like this.


Catching Up on the WordPress 🚫 WP Engine Sitch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/iWfR0UC
Gain $200 in a week
via Read more

BCD Watch

Featured Imgs 23

A new tool from Eric Meyer, Brian Kardell, and Stephanie Stimac backed with Igalia’s support. Brian announced it on his blog, as did Eric, describing it like this:

What BCD Watch does is, it grabs releases of the Browser Compatibility Data (BCD) repository that underpins the support tables on MDN and services like caniuse.com.  It then analyzes what’s changed since the previous release.

Every Monday, BCD Watch produces two reports. The Weekly Changes Report lists all the changes to BCD that happened in the previous week — what’s been added, removed, or renamed in the whole of BCD.  It also tells you which of the Big Three browsers newly support (or dropped support for) each listed feature, along with a progress bar showing how close the feature is to attaining Baseline status.

Browser support data is at MDN. There’s also plenty at Caniuse.com. The two share data, in fact, though not all of it. We now have Baseline, which is also cited in MDN and Caniuse alike. It’s nice to see an effort at cracking a central spot for all this — organized by date, no less.

Oh, and hey, there’s a feed. Even better.

You can also poke at its repo. Thanks a bunch, Eric, Brian, Stephanie, and Igalia! This is super helpful and already part of my toolkit.


BCD Watch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/edOZbip
Gain $200 in a week
via Read more

Color Mixing With Animation Composition

Featured Imgs 23

Mixing colors in CSS is pretty much a solved deal, thanks to the more recent color-mix() function as it gains support. Pass in two color values — any two color values at all — and optionally set the proportions.

background-color: color-mix(#000 30%, #fff 70%);

We also have the relative color syntax that can manipulate colors from one color space to another and modify them from there. The preeminent use case being a way to add opacity to color values that don’t support it, such as named colors.

background-color: hsl(from black h s l); /* hsl(0 0% 0%) */
background-color: hsl(from black h s l / 50%); /* hsl(0 0% 0% / 50%) */

We can get hacky and overlay one opaque element with another, I suppose.

Same general idea maybe, but with mix-blend-mode?

Another roundabout way of getting there is something I saw this morning when looking over the updates that Ryan added to the animation property in the Almanac. Now, we all know that animation is shorthand for about a gajillion other properties (the order of which always eludes me). One of those is animation-composition and it’s used to… well, Ryan nails the explanation:

Defining a property in CSS also sets what is considered the underlying value of the property. By default, keyframe animations will ignore the underlying value, as they only consider the effect values defined within the animation. Keyframes create a stack of effect values, which determines the order in which the animation renders to the browser. Composite operations are how CSS handles the underlying effect combined with the keyframe effect value.

Manuel Matuzović and Robin Rendle also have excellent ways of explaining the property, the former of which sparked us to update the Almanac.

OK! We have three values supported by animation-composition to replace the underlying property value in favor of the effect value defined in keyframes, add to them, or accumulate for combining multiple values. The add value is what’s interesting to us because… oh gosh, let’s just let Ryan take it:

[I]nstead of replacing an underlying background-color property value with the keyframe’s effect value, the color type values are combined, creating new colors.

A-ha! The example goes like this:

See that? The add value blends the two colors as one transitions to the other. Notice, too, how much smoother that transition is than the replace value, although we wind up with a completely new color at the 100% mark rather than the color we declared in the keyframes. What if we pause the animation at some arbitrary point? Can we extract a new color value from it?

Ryan made this so that hovering on the elements pauses the animation. If we crack open DevTools and force the :hover pseudo on the element, maybe we can head over to the Computed tab to get the new color value.

DevTools showing an RGB color value for the demo's background color property equal to rgb(241, 212, 255).

Interestingly, we get some RGB conversions in there. Probably because updating color channels is easier than converting one hex to another? Browsers do smart stuff.

Now I want to go update my old color interpolation demo…

Hmm, not any different to my untrained eye. Maybe that’s only because we’re changing the HSL’s hue channel and it’s super subtle. Whatever the case, animation-composition can produce new computed color values. What you need those for and what you’d do with them? I dunno, but go wild.


Color Mixing With Animation Composition originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/i03n4Jf
Gain $200 in a week
via Read more

Embracing Introversion In UX

Featured Imgs 23

I place myself firmly in the category of being an introvert when it comes to my role as a UX researcher. I love the process of planning and executing research. I have never felt a need to be the loudest or most talkative person in a meeting. I contribute after I have developed something worth saying (or have a really bad joke worked up).

I also love interviews and usability testing, where I interact with users and engage in meaningful conversation. And then I am exhausted. I love speaking about the findings of research and sharing the spotlight with my colleagues during a presentation, and then I want to go to bed underneath the conference room table. I facilitate workshops with ease but have trouble mustering up the energy required to attend what often feels like mandatory post-workshop socializing.

In truth, I have sometimes felt introverted tendencies set me back at work, particularly as a consultant who needs to build relationships to keep the work flowing (in theory). An example would be getting called out by a manager in my junior days for not engaging in as many networking activities as I could have been with some of our clients. My defense of feeling overstimulated, overwhelmed, and uninterested in socializing fell on deaf ears.

I think we have grown in our understanding of introverts and what they need to be high performers, particularly since Susan Cain’s 2013 best-selling book Quiet: The Power of Introverts in a World That Can’t Stop Talking was released.

This article aims to celebrate the power of introversion in UX research and design. We’ll debunk common misconceptions, explore the unique strengths introverted researchers and designers bring to the table, and offer practical tips for thriving in a field that sometimes seems tailored for extroverts. My goal is to build on some of the work on UX and introversion that already exists. I’ve cited other articles where appropriate and shared the resources I’ve found on UX and introversion at the end of this article.

Introversion is not the same thing as being shy, just as extroversion isn’t the same thing as being brash. For simplicity and the sake of this article, I am going to use the following definitions provided by de Jongh & de la Croix:

“Extroverts get energy from interaction with others and like to share ideas with others to help develop their thinking, whereas introverts need to recharge on their own after much social contact and prefer to share ideas only when they are fully formed.”

There are many potential reasons one could have introvert or extrovert tendencies (McCulloch 2020), and these come on a scale where one might lean or introvert or extrovert depending on the occasion. Those who straddle the middle ground of introversion and extroversion are considered ambiverts.

As Jonathan Walter notes in a series of articles on introverts and UX, many UX professionals find themselves drawn to the field because of their introverted nature. Introversion, often misunderstood as shyness or social awkwardness, is simply a preference for internal reflection and processing. It’s about drawing energy from solitude and finding fulfillment in deep thought and meaningful connections.

As UX is clearly a space where introverts are drawn, there is already a decent amount of literature aimed at introverted UX practitioners. In writing this article, I wanted to differentiate from what is already out there, as well as extend.

I wanted to include some personal stories of introverts who aren’t myself and work in UX. To do this, I went to LinkedIn and asked people to send me personal anecdotes. My post, at least by my standards, was well received, with over 100 reactions and a dozen people sending me direct messages sharing anecdotes. I was even introduced to Tim Yeo, who has recently released a book on introverts in the workplace. I’ll be sharing some of the stories people shared with me over LinkedIn, where appropriate (and with their permission), throughout this article to help draw the connections to real life.

First, let’s talk a little about what we know about measuring if you (or others) are introverted, extroverted, or in between.

Measuring Introversion & Extroversion: Self-Assessment Tools

Understanding where you and your team members fall on the introversion-extroversion spectrum can be invaluable for tailoring your approach to work, collaboration, and personal development. Reinoud de Jongh and Anne de la Croix, two medical school professors, write that medical educators should know where they fall on the introversion — extroversion spectrum to deliver great teaching experiences. I’d extend this to UX practitioners, including UX managers, UX researchers, and designers. If we collaborate with others, we will benefit from knowing where we fall on this scale.

While there’s no single definitive test, here are a few simple and accessible tools that can offer insights:

  1. Online Quizzes: Numerous online quizzes and assessments are available, often based on established personality frameworks like the Myers-Briggs Type Indicator (MBTI) or the Big Five personality traits. These quizzes can provide a general sense of your tendencies and preferences. Popular options include:
    • 16Personalities: Offers a free, comprehensive assessment based on the MBTI.
    • Truity: Provides a variety of personality tests, including the Big Five and Enneagram.
    • Verywell Mind: Offers a quiz specifically focused on introversion and extroversion.
  2. Reflection and Journaling: Take some time to reflect on your daily experiences and interactions. Ask yourself the following questions:
    • What activities energize me vs. drain me?
    • Do I prefer to work alone or in groups?
    • How do I recharge after a long day?
    • Do I prefer deep conversations with a few people or socializing with a larger group?
  3. Observation: Pay attention to your behavior and reactions in different social settings. Notice what triggers your stress response and what environments make you feel most comfortable and productive.
  4. Professional Assessment: If you’re seeking a more in-depth analysis, consider consulting a career coach or psychologist who specializes in personality assessment. They can administer standardized tests and provide personalized feedback and guidance.
    • Multidimensional Introversion-Extroversion Scales (MIES): This scale specifically focuses on the multifaceted nature of introversion and extroversion. It measures several sub-traits associated with each dimension, such as social engagement, assertiveness, enjoyment of social interaction, and preference for solitude. Professional psychologists often reference this test, which can be accessed freely here, but might be best done with the guidance of a professional.

There’s no right or wrong answer when it comes to introversion or extroversion. You might even find some folks are ambiverts who display different personalities in different settings. You can’t force your teammates to take these types of tests. But if you are able to get buy-in, it can be a fun activity to see who considers themselves more introverted or more extroverted. The goal is to understand your own preferences and tendencies and those of your colleagues so you can create a work environment that supports your well-being and maximizes your potential.

Introverts’ Super Powers

The idea that UX is an extrovert’s game couldn’t be further from the truth. As Jeremy Bird notes in his article on the strengths of introverts in design, it’s a field that demands a wide range of skills, including deep listening, empathy, observation, analysis, and creativity — all of which introverts excel at. With so much information already available from articles on UX and introversion noted in the biography below, I’m going to briefly highlight the commonly accepted strengths of introverts.

Deep Listening

Introverts are often exceptional listeners. In user interviews, they give participants the space to fully express their thoughts and feelings, picking up on subtle cues and nuances that others might miss. This active listening leads to a deeper understanding of user needs and motivations, which is crucial for both research and design.

One practitioner shared their experience on LinkedIn:

“In a nutshell, being introverted gives a natural advantage in giving the user space to tell their story. I’m more likely to embrace pauses that others may feel are awkward, but this allows users to either double down on their point or think of another point to add (“lightbulb” moment).”

— Dominique S. Microsoft User Research via LinkedIn

Empathy

Many introverts possess a high degree of empathy. They can easily put themselves in users’ shoes, feeling their frustrations and celebrating their successes. This empathy fuels user-centered design, ensuring that products and services are not only functional but also emotionally resonant.

Observational Skills

Introverts are naturally observant. They notice details in user behavior, interface interactions, and environmental context that others might overlook.

Thoughtful Analysis

Introverts often prefer to process information internally, engaging in deep, solitary reflection before sharing their insights. This leads to well-considered and insightful findings and well-crafted data-informed design.

Independent Work

Introverts tend to thrive in independent work environments. As Heather McCulloch notes, teachers should allow introverted students to work independently or in pairs. This way, they can focus deeply on research tasks, design problems, or data analysis without the distractions that come with constant collaboration.

Now that we’ve covered the commonly recognized strengths introverts bring to the table, let’s cover some common hurdles and explore effective strategies for overcoming them that empower introverts to thrive.

Potential Challenges (And How To Overcome Them)

Being introverted can bring up some challenges when it comes to doing things that require a lot of social energy. However, many introverts in UX find ways to push beyond their natural tendencies to meet the demands of their profession. One UX practitioner shared their experience on LinkedIn:

“I’ve been extremely introverted all my life, but have always been able to proceed beyond my introverted boundaries because of a commitment to (perceived) duty. My passion for synergizing user needs, business needs, and the assorted bevy of constraints that arise helps me downplay and overlook any challenges arising from my tendency to be withdrawn.”

— Darren H. MS UXD via LinkedIn

Networking

Introverts might initially feel overwhelmed in networking situations or workshops due to the continual social interaction and the need to navigate unfamiliar environments and interact with new people, which can be particularly daunting for those who prefer solitude or small-group conversations.

  • Researchers & Designers: Building professional relationships can be challenging for introverts. Large conferences or networking events can feel overwhelming. Small talk can feel forced and inauthentic.
    • Solutions for researchers and designers:
      • Focus on quality over quantity: Instead of trying to meet as many people as possible, focus on building a few meaningful connections.
      • Utilize online communities: Connect with other UX professionals on platforms like LinkedIn or Twitter. Engage in discussions, share your insights, and build relationships virtually before meeting in person.
      • Attend smaller events: Look for niche conferences or meetups focused on specific areas of interest. These tend to be more intimate and less overwhelming than large-scale events.
      • Leverage existing relationships: Don’t be afraid to ask a colleague or mentor to introduce you to someone new.

Presenting Work and Public Speaking

Introverts may initially avoid presenting because they tend to prefer avoiding the spotlight. They may also worry about being judged or scrutinized by others.

  • Researchers: May feel anxious about presenting research findings to stakeholders, especially if they have to do so in front of a large audience.
  • Designers: Can struggle with pitching design concepts or justifying their decisions to clients or colleagues, fearing criticism or pushback.

For the introvert, you might not like this, but you need to get comfortable presenting, and the sooner you do, the better.

Solutions for researchers and designers:

  • Practice, practice, practice
    The more you rehearse your presentation or pitch, the more comfortable you’ll feel. Practice in front of a mirror, record yourself or ask a trusted friend for feedback.
  • Use visual aids
    Slides, mockups, or prototypes can help you illustrate your points and keep your audience engaged.
  • Focus on clear communication
    Structure your presentation logically, use simple language, and avoid jargon. Speak slowly and confidently, and make eye contact with your audience.
  • Build confidence over time
    Start with small presentations or informal feedback sessions. As you gain experience and positive feedback, your confidence will naturally increase.

I’ve personally found presenting in front of a large anonymous crowd to be less intimidating than smaller, intimate meetings where you might know a few people mixed in with a few strangers. In the end, I always remind myself I am supposed to be the expert on what I’ve been asked to present or that my job is to clearly state the outcome of our research to stakeholders hungry to see the relevance of their work. The audience wants to support you and see you succeed. I take confidence in that. I’m also exhausted after giving a presentation where I’ve left it all on the floor.

Now, let’s move on to topics beyond what I’ve found covered in existing articles on UX and introversion and cover workshop facilitation and managing group dynamics.

Managing Group Dynamics

Introverts may find group dynamics challenging, as they often prefer solitary activities and may feel overwhelmed or drained by social interactions. In group settings, introverts may have difficulty asserting themselves, sharing their ideas, or actively participating in discussions. They may also feel uncomfortable being the center of attention or having to make decisions on the spot.

Additionally, introverts may struggle to build relationships with their peers in a group setting, as they may be hesitant to initiate conversations or join in on group activities. These challenges can make it difficult for introverts to fully engage and contribute in group settings, leading to feelings of isolation and exclusion.

One UX designer responding over LinkedIn eloquently shared their experience with communication challenges:

“Introversion can sometimes create challenges in communication, as my thoughtful nature can be misinterpreted as shyness or disinterest. To step out of my shell, I need to build trust with those around me before I can feel truly comfortable. However, I don’t see this as the worst thing in the world. Instead, I view it as an opportunity to identify areas where I need to improve and learn to advocate for myself more effectively in the future. In embracing both the strengths and challenges of being an introvert, I’ve found that my introverted nature not only enhances my work as a designer but also drives continuous personal and professional growth, ultimately leading to better outcomes for both myself and my team.”

— Arafa A. via LinkedIn
  • Challenge: Large groups can be overwhelming, and introverted facilitators might find it difficult to assert control or manage dominant personalities who may derail the discussion.
  • Solutions:
    • Clear Ground Rules: Establish explicit ground rules at the beginning of the workshop to ensure respectful communication and equal participation.
    • Assertive Communication: Practice techniques like “broken record” or “fogging” to politely but firmly redirect the conversation when necessary.
    • Partner with a Co-Facilitator: Collaborate with an extroverted colleague who can complement your strengths. They can take the lead in managing group dynamics and energizing participants.

Managing group dynamics covers a broad number of situations UX professionals face on a daily basis. Let’s get a little more specific and focus on how introverted UXers can thrive as workshop facilitators.

Facilitating Workshops

If you’re an introverted UX professional who shies away from leading workshops, it’s time to reconsider. Here are some of the reasons introverts can be perfect workshop facilitators:

  1. Preparation:
    • Introverts tend to be meticulous planners. We thrive on preparation and often go above and beyond to ensure a workshop is well-structured, organized, and aligned with learning objectives. This thoroughness translates to a smooth, well-paced session that instills confidence in participants.
  2. Thoughtful Facilitation:
    • Introverts are known for their active listening skills. We genuinely want to hear what others have to say and create a safe space for diverse perspectives to emerge. We ask thoughtful questions, encourage reflection, and facilitate meaningful discussions that lead to deeper understanding.
  3. Empathy & Connection: We’ve already discussed in the section on superpowers how introverts excel at empathy and connection.
  4. Observation Skills: We’ve already discussed in the section on superpowers how introverts excel at observational skills.
  5. Comfort with Silence:
    • Introverts understand the power of silence. We’re not afraid to pause and allow reflection after asking a question or during a brainstorming session. This creates space for deeper thinking and prevents premature conclusions or groupthink.

We’ve reviewed many of the challenges introverts might face in their daily work life. Let’s turn our attention to a more recent phenomenon, at least in terms of its widespread availability as an option for many UX professionals: remote work.

Working Remotely

Increased telecommuting offers a unique opportunity for some introverts. Introverts, who often find comfort in solitude and derive energy from spending time alone, sometimes find the constant socialization and bustle of open-plan offices overwhelming and draining.

Remote work provides introverts with an opportunity to control their surroundings and create a workspace that promotes focus, productivity, and creativity. Remote work allows introverts to communicate and collaborate on their own terms. Introverts often prefer one-on-one interactions over large group meetings, and remote work makes it easier for them to engage in meaningful conversations with colleagues and clients.

Potential Challenges For Introverts Working Remotely

While remote work has been a game-changer for many introverts, it is important to acknowledge that it is not without its challenges. Introverts may miss the camaraderie and social connections of an in-person workplace, and they may need to make a conscious effort to stay connected with colleagues and maintain a healthy work-life balance.

Introverts working remotely may need to develop strategies for self-advocacy and communication to ensure that their voices are heard and their contributions are valued in a virtual work environment.

  • Isolation and Disconnect: The lack of face-to-face interaction can lead to feelings of isolation and detachment from the team.
  • Communication Barriers: Virtual communication can be less nuanced, making it harder to convey complex ideas or build rapport with colleagues.
  • Meeting Overload: Excessive video calls can be exhausting for introverts, leading to burnout and decreased productivity.
  • Limited Non-Verbal Cues: Virtual interactions lack the subtle body language and facial expressions that introverts rely on to understand others’ perspectives.

Overcoming Challenges: Strategies For Introverts Working Remotely

Introverted remote employees can implement some of these strategies and tactics to enhance their productivity, reduce burnout, and maintain a positive work environment:

  • Proactive Communication: Initiate regular check-ins with colleagues and managers, both for work-related updates and casual conversations.
  • Schedule Breaks: During long virtual meetings, take short breaks to recharge and refocus.
  • Advocate for Your Needs: If you’re feeling overwhelmed by meetings or social interactions, don’t hesitate to speak up and suggest alternatives, such as asynchronous communication or smaller group discussions.
  • Build Virtual Relationships: Participate in virtual social events, share personal anecdotes in team channels, and find opportunities to connect with colleagues on a personal level.
  • Embrace Video Calls (Strategically): While video calls can be tiring, they can also be valuable for building rapport and understanding non-verbal cues. Use them strategically for important discussions or when you need to connect with a colleague on a deeper level.

Implementing what we’ve covered in this section will help to reduce the likelihood of frustration from both remote working introverts and their colleagues.

Tips For Introverted UX Researchers And Designers

We’ve covered a lot of ideas in this article. If you find yourself nodding along as an introvert or perhaps coming to the realization you or someone on your team is more introverted, this section and the next will end this article on a high note, introducing some actionable tips for introverted researchers and designers, and their managers and teammates, to create a more comfortable and successful working environment for introverts to thrive alongside their extroverted colleagues.

Self-Care

Everyone needs to engage in an appropriate amount of self-care to feel their best. For an introvert, this is often done in solitude, particularly after engaging in a day or week full of social interaction. Some tips that could apply to anyone but are of particular relevance to introverts include the following:

  • Schedule downtime: Block out time in your calendar for quiet reflection and recharging after meetings or social interactions. This could be a walk in nature, reading a book, or simply sitting in silence.
  • Honor your energy levels: Pay attention to when you’re feeling drained. Don’t be afraid to decline invitations or reschedule meetings if you need time to recharge.
  • Create a calming workspace: Surround yourself with things that promote relaxation and focus, such as plants, calming music, or inspiring artwork.

Play To Your Strengths

Introverts know themselves best and have spent a lifetime reflecting on who they are and what makes them wake up happy to go to work. As such, introverts may have a high awareness of their strengths. This allows an introvert to do the following:

  • Identify your unique talents: Are you a meticulous researcher, a creative problem-solver, or a passionate user advocate? Focus on tasks and projects that align with your strengths.
  • Communicate your preferences: Let your manager or team know what type of work you thrive in. Perhaps you prefer to work independently on research tasks or focus on the visual aspects of design.
  • Build on your skills: Seek opportunities to develop your existing skills and acquire new ones. This could involve taking online courses, attending workshops, or seeking mentorship from experienced researchers and designers.

Communication

Introverts might hesitate to speak up when the room is crowded with unknown future friends. However, anyone, introverted or not, needs to be their own best advocate when it comes to making colleagues and management aware of how to create the best workplace environment to thrive in:

  • Advocate for your needs: Don’t be afraid to speak up and ask for what you need to succeed. This could involve requesting a quiet workspace, suggesting alternative meeting formats, or simply letting your team know when you need some time to yourself.
  • Develop your communication skills: Even though you may prefer written communication or one-on-one conversations, it’s important to be able to communicate effectively in various settings. Practice public speaking, participate in team discussions, and learn to articulate your ideas clearly and confidently.

It’s essential for introverts to advocate for their needs and communicate their preferred work styles to their colleagues and managers. One UX professional shared their experience on LinkedIn:

“I do my best work when I have time to think and prepare vs. on-demand thinking, speaking, & decision making. So, I ask for agendas, context, and pre-reads to help me make the most impact in meetings. When I shared this fact, it really helped my outgoing teammates, who never thought that others might operate differently than they do. I got feedback that this was a learning experience for them, and so I have continued to share this fact with new teammates to set expectations and advocate for myself since I find it to be an extrovert-centered business world.”

— Anonymous UXer on LinkedIn

Another LinkedIn UXer provided additional tactics for how they navigate communication styles and expectations, particularly in a fast-paced or extrovert-dominated environment.

“The longer I work with people in a creative capacity, the more I recognize the power of delay. Plenty of introverts are also high-achieving people pleasers (raises hand 🙋🏻). This has caused stress over the years when working with extroverts or verbal processors because there can be a perceived sense of urgency to every thought or ask.
[slowing things down] can look like using certain phrases to help slow down the implied urgency to allow me to more thoughtfully process the ask:
  • “Ah, interesting! Could you say more about that?”
  • “Can you clarify the ‘why’ behind this for me? I want to make sure I’ve got it right.”
  • “How does this support our goals for < x project / user >?”
And if the ask comes through asynchronously via email or Slack, I ask myself the following:
  1. Was this sent during working hours?
  2. Am I the only one who can answer this question / address this issue?
  3. Can I provide a short response that lets the person know their message was seen and that it’s on my radar?”
— Kait L. UXer via LinkedIn

Group Dynamics

Introverts may not initially thrive when it comes to group dynamics. They might wish to observe the group before deeply engaging. They can find it difficult to assert themselves in a group setting and may feel overwhelmed by the constant need for social interaction.

Additionally, introverts may find it harder to contribute to discussions or be slower to form meaningful connections with others in a group. The extroverted nature of group dynamics can be draining for introverts, and they may require more time to recharge after being in a group setting.

  • Prepare in advance: Gather your thoughts, jot down key points, or even practice your delivery. This can help you feel more confident and articulate in group settings.
  • Take breaks: If a meeting is dragging on, step out for a few minutes to recharge. A quick walk or a moment of solitude can do wonders for your energy levels.
  • Seek one-on-one interactions: If you’re struggling to be heard in a group, try scheduling separate meetings with key stakeholders to share your insights or design concepts in a more intimate setting.
  • Utilize virtual collaboration tools: If in-person meetings are particularly draining, suggest using tools like Slack, Miro, or Figma for asynchronous collaboration and feedback.

Introverts often find creative ways to navigate the challenges of large group settings. One UX researcher shared their experience on LinkedIn:

“I have a monthly meeting with many employees (50+) to go over survey results. I realized it was super awkward for me just to wait as people joined the meeting. I tried to make small talk about upcoming weekend plans or what people had done over the weekend, but engagement was still pretty low, and I was not equipped enough to carry on conversations. I decided to fill the time with memes. I would search for user research memes and tie them into why user research is important. More people started coming to my meetings just to see the meme! As time went on, I became known as the meme person. While I can’t necessarily say if that’s a good thing — brand awareness is powerful! At least people know user research exists and that we’re fun — even if it all started from being awkward and introverted.”

— Anonymous LinkedIn UXer

Guidance For Moving Up As An Introverted Researcher Or Designer

I turned to Tim Yeo to provide some insight into how introverts can best prepare for moving up the career ladder. Tim provided some tactical advice focusing on teamwork and people skills:

“Practice your people skills. If you, as an individual, could do it all on your own, you would’ve probably done it already. If you can’t, then you need to work with people to bring your creation to life. It takes a team.”

Tim also shared the strategic reason behind the importance of leaders having excellent people skills:

“We also like to believe that higher management is always more sure, more right, and has all the answers. In my experience, the reality is almost the opposite. Problems get fuzzier, messier, and more complex the higher up the organization you go. Making decisions with incomplete, imperfect information is the norm. To operate successfully in this environment requires steering people to your worldview, and that takes people skills.”

You can find some additional information on ways for introverts (and extroverts) to gain people skills in some of the references listed at the end of this article.

Let’s move on and wrap up with some tips for those who are working alongside introverts.

Tips For Managers And Colleagues of Introverts

If you are a manager of a team consisting of more than yourself, you likely have an introvert among your team. Tim Yeo states, “Research from Susan Cain’s book, Quiet, shows that 1/3 to 1/2 of our population identify as quiet or introverted.”

Therefore,

“If you work in a diverse team, it follows that 1/3 to 1/2 of your team are quiet. So if you don’t create a space for quiet ones to be heard, that means you are missing out on 1/3 to 1/2 of ideas.”

UX managers of teams, including introverts and extroverts, should engage in some of the following suggested practices to create an inclusive work environment where everyone feels valued, heard, and able to contribute effectively to the team’s success. UX managers can use these tips to foster a diverse and productive team dynamic that drives innovation and creativity.

  • Flexibility
    • Offer communication options: Not everyone thrives in the same communication environment. Provide alternatives to large meetings, such as email updates, one-on-one check-ins, or asynchronous communication tools like Slack.
    • Embrace different work styles: Recognize that not everyone is most productive in a bustling office environment. Allow for flexible work arrangements, such as remote work or flexible hours, to accommodate different needs and preferences.
  • Value Diversity
    • Recognize the strengths of introverts: Introverts bring a unique perspective and valuable skills to the table. Encourage their contributions, celebrate their successes, and create an environment where they feel comfortable sharing their ideas.
    • Foster inclusivity: Make sure everyone on the team feels heard and valued, regardless of their personality type. Encourage open communication, active listening, and mutual respect.
  • Create Safe Spaces
    • Provide quiet spaces: Designate areas in the office where people can go to work independently or simply decompress.
    • Encourage breaks: Remind your team to take regular breaks throughout the day to recharge. This could involve stepping outside for fresh air, taking a short walk, or simply closing their eyes for a few minutes of meditation.
  • Professional Development
    • Offer tailored training: Provide opportunities for introverted researchers and designers to develop their communication and presentation skills in a supportive environment. This could involve workshops, coaching, or mentorship programs.

As a bonus, if you’re an introverted UX Manager and you are managing a team composed of introverts and extroverts, remember to encourage a variety of communication channels for your team members. You might default to your preferred style of communication but recognize that different team members may prefer different communication channels.

Some extroverted team members might enjoy brainstorming in large meetings, and introverted team members might prefer to contribute their ideas through written channels such as email, chat, or discussion boards.

Encouraging a variety of communication channels ensures that all team members feel comfortable sharing their thoughts and ideas.

Tim Yeo provided this list of tactics for encouraging and engaging introverts in participating in discussion:

  • Sharing the agenda before the meeting (so your quiet teammates, who are amazing preppers, by the way, can prepare and be ready to contribute).
  • Using a mix of silent and think-out-loud activities in meetings (so people who process information differently can all perform).
  • Give a heads-up before you call on a quiet colleague to speak.
  • Offer to be a thinking partner (when your quiet colleague appears to be stuck on a piece of work).

Now, let’s move on to focus on some tips for managing remote workers.

Recommendations For Managers And Teams Working Remotely

Managers and colleagues play a crucial role in creating a supportive and inclusive environment for introverted researchers and designers on dispersed teams. Here are some strategies to consider:

  1. Intentional Communication
    • Asynchronous First: Prioritize asynchronous communication methods (email, project management tools, shared documents) for brainstorming, feedback, and routine updates. This gives introverts time to process information and craft thoughtful responses.
    • One-on-One Check-Ins: Schedule regular one-on-one meetings with introverted team members to build rapport, discuss their concerns, and offer individualized support.
    • Mindful Meeting Management: Be mindful of meeting frequency and duration. Consider alternatives to video calls when possible, such as shared documents or asynchronous communication channels. When video calls are necessary, ensure they have a clear agenda and purpose.
  2. Creating Virtual Water Cooler Moments
    • Casual Communication Channels: Set up dedicated IM channels or virtual spaces for non-work-related conversations, allowing for informal social interaction and team bonding.
    • Virtual Social Events: Organize virtual coffee chats, game nights, or team-building activities to foster camaraderie and connection outside of work-related tasks.
    • Collaborative Tools: Utilize virtual whiteboards or shared documents for brainstorming sessions, encouraging participation and idea generation from all team members.
  3. Cultivating Empathy and Understanding
    • Education and Awareness: Share articles or resources about introversion with the team to foster understanding and appreciation for different personality types.
    • Open Dialogue: Encourage open conversations about communication styles and preferences, creating a safe space for everyone to express their needs.
    • Celebrate Strengths: Highlight the unique contributions that introverted team members bring to the table, such as their deep listening skills, thoughtful analysis, and ability to advocate for users.
  4. Leadership Support
    • Model Inclusive Behavior: Managers should lead by example, demonstrating respect for different communication styles and creating opportunities for all team members to contribute.
    • Provide Resources: Offer training or workshops on effective virtual communication and collaboration, tailoring them to the needs of introverted team members.
    • Check-In Regularly: Regularly touch base with introverted team members to gauge their well-being, address any concerns, and offer support.

Managers and teams can implement these strategies to create a work environment that values and empowers introverted researchers and designers, enabling them to thrive and make significant contributions to the team’s success.

Conclusion

We create a more inclusive and productive environment when we understand and appreciate the unique needs and preferences of introverts. Whether you’re an introverted UXer navigating the challenges of remote work or a manager looking to foster a diverse and engaged team, the strategies and insights shared in this article can help you unlock the full potential of introverted talent.

“The superpower of introspection that comes with introversion has enabled me to reflect on my behaviours and engineer myself to become more of an omnivert — able to adapt to different situations.

Being self-aware and working hard to ladder up through increasingly more challenging experiences has taken me from an introvert who was too concerned to tweet to an active leader in the community, delivering seminars, speaking at an international conference and now running a mentorship program for hundreds of UX professionals across the globe.”

— Chris C. UX Master Certified, via LinkedIn

Introversion is not a weakness to be overcome but a valuable asset to be embraced. We build stronger teams, foster innovation, and ultimately deliver more meaningful and impactful user experiences when we create a culture that celebrates both introverted and extroverted strengths. The best solutions often emerge from a blend of diverse perspectives, including the quiet voices that deserve to be heard.

In closing, I’d like to use the words of Tim Yeo, who provides us with some inspiration and positive reinforcement of who we are as introverts:

“You are enough. The world may continue to favour the extrovert ideal, but pretending to be someone you are not will never feel right. Know that there is a different path to have impact at work where you don’t have to pretend to be someone you are not. That path comes from tiny habits, done well, accumulated over time.”

[You can learn more about tiny habits in Tim’s book The Quiet Achiever]

Biography And Additional Resources



Gain $200 in a week
from Articles on Smashing Magazine — For Web Designers And Developers https://ift.tt/98A3ICK

Re-Working the CSS Almanac

Featured Imgs 23

Getting right to it: the CSS-Tricks Almanac got a big refresh this week!

I’m guessing you’re already familiar with this giant ol’ section of CSS-Tricks called the Almanac. This is where we publish references for CSS selectors and properties. That’s actually all we’ve published in there since the beginning of time… or at least since 2009 when most of the original work on it took place. That might as well be the beginning of time in web years. We might even call it Year 1 BR, or one year before responsive.

You don’t need me telling you how different writing CSS is today in the Year 14 AR. Quite simply, the Almanac hasn’t kept pace with CSS which is much, much more than properties and selectors. The truth is that we never really wanted to touch the Almanac because of how it’s configured in the back end and I’m pretty sure I spotted a ghost or two in there when I poked at it.

Visiting the Alamanc now, you’ll find a wider range of CSS information, including dedicated sections for pseudo class selectors, functions, and at-rules in addition to the existing properties and selectors sections. We’ve still got plenty of work to do filling those in (you should help!) but the architecture is there and there’s room to scale things up a little more if needed.

The work was non-trivial and as scary as I thought it would be. Let me walk you around some of what I did.

The situation

We’re proudly running WordPress and have since day one. There’s a lot of benefit to that, especially as templating goes. It may not be everyone’s favorite jam, but I’m more than cool with it and jumped in — damn the torpedoes!

If you’re familiar with WordPress, then you know that content is largely sliced up into two types: pages and posts. The difference between the two is fairly minimal — and nearly indistinguishable as they both employ the same editing interface. There are nuances, of course, but pages are largely different in that they are hierarchal, meaning they’re best for establishing parent-child page relationships for a nicely structured sitemap. Posts, meanwhile, are more meta-driven in the sense that we get to organize things by slapping tags on them or dropping them into a category group or whatever custom taxonomy we might have in reach.

The Almanac is built on pages, not posts. Pages are boss at hierarchy, and the Alamanc is a highly structured area that has a typical sitemap-like flow, and it just so happens to follow alphabetical order. For example, an entry for a CSS property, let’s say aspect-ratio, goes: Almanac → Properties → A → Aspect Ratio.

That doesn’t sound like a bad thing, right? It’s not, but pages are tougher to query in a template than posts, which have a lot more meta we can use for filtering and whatnot. Pages, on the other hand, not so much. (Well, not obviously so much.) They’re usually returned as structured objects because, you know, hierarchy. But it also means we have to manually create all of those pages, unlike tags and categories that automatically generqte archives. It feels so dang silly creating an empty page for the letter “A” that’s a child of the “Properties” page — which is a child of the Almanac itself — just so there’s a logical place to insert properties that begin with the letter A. And that has to happen for both properties and selectors.

The real problem is that the Almanac simply tapped out. We want to publish other CSS-y things in there, like functions and at-rules, but the Almanac was only ever built to show two groups. That’s why we never published anything else. It’s also why general selectors and pseudo-selectors were in the same bucket.

Expanding the place to hold more content was the scope I worked with, knowing that I’d have some chances to style things along the way.

One template to rule them all

That’s how things were done. The original deal was a single template used for the Almanac index and the alphabetical pages that list selectors and properties. It was neat, really. The page first checked if the current page is the Almamac page that sits atop the page hierarchy. If it is that page, then the template spits out the results for selectors and properties on the same page, in two different columns.

Previous version of the Almanac showing a large Almanac heading, a sub navigation with jump links to alphabetical letters, and the selector and properties lists.

The query for that is quite impressive.

<?php
function letterOutput($letter, $selectorID, $propertyID) {
  $selector_query = new WP_Query(array(
    'post_type' => 'page',
    'post_status' => 'publish',
    'post_parent' => $selectorID,
    'posts_per_page' => -1,
    'orderby' => 'title',
    'order' => "ASC"
  ));

  $html = '<div class="almanac-group">';
  $html .= '<div class="group-letter"><a id="letter-' . $letter . '">' . $letter . '</a></div>';
  $html .= '<div class="group-list">';

  while ($selector_query->have_posts()) : $selector_query->the_post();

    $html .= '<details id="post-' . get_the_id() . '" class="link-item"><summary>';
    $html .= '<h2><code>';
    $html .= get_the_title();
    $html .= '</code></h2>';
    $html .= '</summary>';
    $html .= get_the_excerpt();
    $html .= '<pre rel="CSS" class="almanac-example"><code class="language-css">';
    $html .= get_post_meta(get_the_id(), 'almanac_example_code', true);
    $html .= '</code></pre>';
    $html .= '<a class="button" href="' . get_the_permalink() . '">Continue Reading</a>';
    $html .= '</details>';
endwhile;
  
  $html .= "</div>";
  $html .= "</div>";

  return $html;
}

That’s actually half the snippet. Notice it’s only marked up for a $selector_query. It loops through this thing again for a $property_query.

From there, the function needs to be called 26 times: one for each letter of the alphabet. It takes three parameters, namely the letter (e.g. A) and the page IDs for the “A” pages (e.g. 14146, 13712) that are children of the selectors and properties.

<?php 
  echo letterOutput("A", 14146, 13712);
  // B, C, D, E F, G, etc.
?>

And if we’re not currently on the index page? The template spits out just the alphabetical list of child pages for that particular section, e.g. properties. One template is enough for all that.

Querying child pages

I could have altered the letterOutput() function to take more page IDs to show the letter pages for other sections. But honestly, I just didn’t want to go there. I chose instead to reduce the function to one page ID argument instead of two, then split the template up: one for the main index and one for the “sub-sections” if you will. Yes, that means I wound up with more templates in my WordPress theme directory, but this is mostly for me and I don’t mind. I can check which sub-page I’m on (whether it’s a property index, selector index, at-rules index, etc.) and get just the child pages for those individually.

The other trouble with the function? All the generated markup is sandwiched inside a while()statement. Even if I wanted to parse the query by section to preserve a single template architecture, it’s not like I can drop an if() statement anywhere I want in there without causing a PHP fatal error or notice. Again, I had no interest in re-jiggering the function wholesale.

Letter archives

Publishing all those empty subpages for the letters of each section and then attaching them to the correct parent page is a lot of manual work. I know because I did it. There’s certainly a better, even programmatic, way but converting things from pages to posts and working from that angle didn’t appeal to me and I was working on the clock. We don’t always get to figure out an “ideal” way of doing things.

It’s a misnomer calling any of these letter pages “archives” according to WordPress parlance, but that’s how I’m looking at the child pages for the different sections — and that’s how it would have been if things were structured as posts instead of pages. If I have a section for Pseudo-Selectors, then I’m going to need individual pages for letters A through Z that, in turn, act as the parent pages for the individual pseudos. Three new sections with 26 letters each means I made 78 new pages. Yay.

You get to a letter page either through the breadcrumbs of an Almanac page (like this one for the aspect-ratio property) or by clicking the large letter in any of the sections (like this one for properties).

We’ve never taken those pages seriously. They’re there for structure, but it’s not like many folks ever land on them. They’re essentially placeholders. Helpful, yes, but placeholders nonetheless. We have been so unserious about these pages that we never formally styled them. It’s a model of CSS inheritance, tell you what.

Page for the letter A in the Almanac's properties section. The first four alphabetical properties are displayed as large links.
Yup, you can stop gushing now. 😍

This is where I took an opportunity to touch things up visually. I’ve been working with big, beefy things in the design since coming back to this job a few months ago. Things like the oversized headings and thick-as-heck shadows you see.

Updated design for the letter A.

It’s not my natural aesthetic, but I think it works well with CSS-Tricks… and maybe, just maybe, there’s a tear of joy running down Chris Coyier’s face because of it. Maybe.

Another enhancement was added to the navigation displayed on the main index page. I replaced the alphabetical navigation at the top with a nav that takes you to each section and now we can edit the page directly in WordPress without having to dev around.

The old version of the almanac header above the new version.
Before (top) and after (bottom)

The only thing that bothers me is that I hardcoded the dang thing instead of making it a proper WordPress menu that I can manage from the admin. [Adds a TODO to his list.]

Since I freed up the Alamanc index from displaying the selector and property lists in full, I could truly use it as an index for the larger number of sections we’re adding.

There may be a time when we’ll want to make the main page content less redundant with the navigation but I’ll take this as a good start that we can build up from. Plus, it’s now more consistent with the rest of the “top-level” pages linked up in the site’s main menu as far as headers go and that can’t be bad.

Oh yeah, and while we’re talking about navigating around, the new sections have been added to the existing left sidebar on individual Almanac pages to help jump to other entries in any section without having to return to the index.

Yes, that’s really how little content we have in there right now!

Quickly reference things

The last enhancement I’ll call out is minor but I think it makes a positive difference. If you head over to any subpage of the index — i.e., Selectors, Properties, Pseudos, Functions, At-Rules — a snippet and high-level definition is available for each item at the ready without having to jump to the full page.

We’ve always been big on “get to the examples quickly” and I think this helps that cause quite a bit.

“You could’ve also done [x]…”

Yeah, lots more opportunities to tighten things up. The only goal I had in mind was to change things up just enough for the Almanac to cover more than selectors and properties, and maybe take some styling liberties here and there. There’s plenty more I wanna do and maybe we’ll get there, albeit incrementally.

What sort of things? Well, that hardcoded index navigation for one. But more than that, I’d like to keep pushing on the main page. It was serving a great purpose before and I pretty much wiped that out. It’d be good to find a way to list all of the entries — for all sections — the way we did when it was only twe sections. That’s something I plan to poke at.

And, yes, we want to cover even more CSS-y items in there, like general terminology, media and user preference queries, possibly specifications… you get the idea. The Almanac is a resource for us here on the team as much as it is for you, and we refer to it on the daily. We want it flush with useful information.

That’s all.

You can stop reading now and just head on over to the Almanac for a virtual stroll.


Re-Working the CSS Almanac originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/JfRN06L
Gain $200 in a week
via Read more

Creating Custom Lottie Animations With SVGator

Featured Imgs 23

This article is a sponsored by SVGator

SVGator has gone through a series of updates since our last article, which was published in 2021, when it was already considered to be the most advanced web-based tool for vector animation. The first step toward more versatile software came with the mobile export feature that made it possible to implement the animations in iOS and Android applications.

The animation tool continued its upgrade with a series of new export options: video formats including MP4, AVI, MKV, MOV, and WebM, as well as image formats such as GIF, Animated PNG, WebP, and image sequence. By covering a larger area of users’ needs, the app now enables anyone to create animated stickers, social media, and newsletter animations, video assets, and many more types of visual content on demand.

The goal of becoming a “one tool for all” still lacked the last piece of the puzzle, namely full support for Lottie files. Lottie, just like SVG, is a vector-based format, but it has even better comprehensive multi-platform support, a fact that makes it super popular among developers and design professionals. It is built for use across various platforms, enabling smooth integration into both web and mobile applications. Its file size is minimal, it is infinitely scalable, and developers find it straightforward to implement once they get familiar with the format. Lottie can incorporate raster graphics and also supports interactivity.

SVGator’s latest version has everything you need for your various applications without the need for any third-party apps or plug-ins.

Note: You can test all of SVGator’s functionalities free of charge before committing to the Pro plan. However, you can export up to three watermarked files, with videos and GIFs limited to basic quality.

In this article, we will follow a creation process made of these steps:

  • Importing an existent Lottie JSON and making some minor adjustments;
  • Importing new animated assets created with SVGator (using the library);
  • Creating and animating new elements from scratch;
  • Exporting the Lottie animation.
Getting Started With SVGator

The sign-up process is simple, fast, and straightforward, and no credit card is required. Sign up either with Google or Facebook or, alternatively, by providing your name, email address, and password. Start a project either with a Lottie animation or a static SVG. If you don’t have an existing file, you can design and animate everything starting from a blank canvas.

Now that you’ve created your account, let’s dive right into the fun part. Here’s a preview of how your animation is going to look by the time you’re done following this guide. Neat, right?

(Large preview) Create A New Project

After logging in and clicking on the New Project option, you will be taken to the New Project Panel, where you can choose between starting from a blank project or uploading a file. Let’s start this project with an existing Lottie JSON.

  1. Click on the Upload file button and navigate to the directory where you have saved your Lottie file.

  2. Select the “Fast response.json” file and click Open.

    Hit play in the editor, and the animation should look like this:

    (Large preview)

Note: Make sure to hit Save after each step to make sure you don’t lose any of your progress while working on this project alongside our guide.

Import An Animated Asset

In this step, you will learn how to use the Library to import new assets to your project. You can easily choose from a variety of ready-made SVGs stored in different categories, load new files from your computer (Lottie, static SVG, and images), or save animations from other SVGator projects and reuse them.

In this case, let’s use an animated message bubble previously created and saved to the Uploads section of the Library.

Learn how to create and save animated assets with this short video tutorial.

  1. Navigate to the left sidebar of the app and switch to the Library tab, then click the “+” icon to upload the message bubble asset that you downloaded earlier.
  2. After it is loaded in the uploads section, simply click on it to add it to your project.

    All the animated properties of the asset are now present in the timeline, and you can edit them if you want.

    Note: Make sure the playhead is at the second “0” before adding the animated asset. When adding an animated asset, it will always start animating from the point where the playhead is placed.
  3. Freely adjust its position and size as you wish.
  4. With the playhead at the second 0, click on the Animate button, then choose Position.

At this point, you should have the first Position keyframe automatically added at the second 0, and you are ready to start animating.

Animate The Message Bubble
  1. Start by dragging the playhead on the timeline at 0.2 seconds:

  2. Then, drag the message bubble up a few pixels. The second keyframe will appear in the timeline, marking the element’s new position, thus creating the 2 milliseconds animation.

    Note: You can hit Play at any moment to check how everything looks!

    Next, you can use the Scale animator to make the bubble disappear after the dots representing the typing are done animating by scaling it down to 0 for both the X and Y axes:

  3. With the message bubble still selected, drag the playhead at 2.2 seconds, click on Animate, and select Scale (or just press Shift + S on the keyboard) to set the first Scale keyframe, then drag the playhead at 2.5 seconds.
  4. Set the scale properties to 0 for both the X and Y axes (in the right side panel). The bubble won’t be visible anymore at this point.

    Note: To maintain the ratio while changing the scale values, make sure you have the Maintain proportions on (the link icon next to the scale inputs).

    To add an extra touch of interest to this scaling motion, add an easing function preset:

  5. First, jump back to the first Scale keyframe (you can also double-click the keyframe to jump the playhead right at it).
  6. Open the Easing Panel next to the time indicator and scroll down through the presets list, then select Ease in Back. Due to its bezier going out of the graph, this easing function will create a bounce-back effect for the scale animation.

    Note: You can adjust the bezier of a selected easing preset and create a new custom function, which will appear at the top of the list.

    Keep in mind that you need at least one keyframe selected if you intend to apply an easing. The easing function will apply from the selected keyframe toward the next keyframe at its right. Of course, you can apply a certain easing for multiple keyframes at once.

    To get a smoother transition when the message bubble disappears, add an Opacity animation of one millisecond at the end of the scaling:

  7. Choose Opacity from the animators’ list and set the first keyframe at 2.4 seconds, then drag the playhead at 2.5 seconds to match the ending keyframe from the scale animation above.
  8. From the Appearance panel, drag the Opacity slider all the way to the left, at 0%.
Create An Email Icon

For the concept behind this animation to be complete, let’s create (and later animate) a “new email” notification as a response to the character sending that message.

Once again, SVGator’s asset library comes in handy for this step:

  1. Go to the search bar from the Library and type in “mail,” then click on the mail asset from the results.
  2. Place it somewhere above the laptop. Edit the mail icon to better fit the style of the animation:

  3. Open the email group and select the rectangle from the back.
  4. Change its fill color to a dark purple.
  5. Round up the corners using the Radius slider.

  6. Make the element’s design minimal by deleting these two lines from the lower part of the envelope.

  7. Select the envelope seal flap, which is the Polyline element in the group, above the rectangle.
  8. Add a lighter purple for the fill, set the stroke to 2 px width, and also make it white.

    To make the animation even more interesting, create a notification alert in the top-right corner of the envelope:

  9. Use the Ellipse tool (O) from the toolbar on top and draw a circle in the top-right corner of the envelope.
  10. Choose a nice red color for the fill, and set the stroke to white with a 2 px width.

  11. Click on the “T” icon to select the Text tool.
  12. Click on the circle and type “1”.
  13. Set the color to white and click on the “B” icon to make it bold.

  14. Select both the red circle and the number, and group them: right-click, and hit Group.

    You can also hit Command or Ctrl + G on your keyboard. Double-click on the newly created group to rename it to “Notification.”

  15. Select both the notification group and email group below and create a new group, which you can name “new email.”
Animate The New Email Group

Let’s animate the new email popping out of the laptop right after the character has finished texting his message:

  1. With the “New email” group selected, click twice on the Move down icon from the header to place the group last.
    You can also press Command or Ctrl + arrow down on your keyboard.
  2. Drag the group behind the laptop (on the canvas) to hide it entirely, and also scale it down a little.
  3. With the playhead at 3 seconds, add the animators Scale and Position.
    You can also do that by pressing Shift + S and Shift + P on your keyboard.

  4. Drag the playhead at the second 3.3 on the timeline.
  5. Move the New Email group above the laptop and scale it up a bit.
  6. You can also bend the motion path line to create a curved trajectory for the position animation.

  7. Select the first keyframes at the second 3.
  8. Open the easing panel.
  9. And click on the Ease Out Cubic preset to add it to both keyframes.
Animate The Notification

Let’s animate the notification dot separately. We’ll make it pop in while the email group shows up.

  1. Select the Notification group.
  2. Create a scale-up animation for it with 0 for both the X and Y axes at 3.2 and 1 at 3.5 seconds.
  3. Select the first keyframe and, from the easing panel, choose Ease Out Back. This easing function will ensure the popping effect.
Add Expressiveness To The Character

Make the character smile while looking at the email that just popped out. For this, you need to animate the stroke offset of the mouth:

  1. Select the mouth path. You can use the Node tool to select it directly with one click.
  2. Drag the playhead at 3.5 seconds, which is the moment from where the smile will start.
  3. Select the last keyframe of the Stroke offset animator from the timeline and duplicate it at second 3.5, or you can also use Ctrl or Cmd + D for duplication.

  4. Drag the playhead at second 3.9.
  5. Go to the properties panel and set the Offset to 0. The stroke will now fill the path all the way, creating a stroke offset animation of 4 milliseconds.
Final Edits

You can still make all kinds of adjustments to your animation before exporting it. In this case, let’s change the color of the initial Lottie animation we used to start this project:

  1. Use the Node tool to select all the green paths that form the character’s arms and torso.
  2. Change the color as you desire.
Export Lottie

Once you’re done editing, you can export the animation by clicking on the top right Export button and selecting the Lottie format. Alternatively, you can press Command or Ctrl + E on your keyboard to jump directly to the export panel, from where you can still select the animation you want to export.

  1. Make sure the Lottie format is selected from the dropdown. In the export panel, you can set a name for the file you are about to export, choose the frame rate and animation speed, or set a background color.
  2. You can preview the Lottie animation with a Lottie player.
    Note: This step is recommended to make sure all animations are supported in the Lottie format by previewing it on a webpage using the Lottie player. The preview in the export panel isn’t an actual Lottie animation.
  3. Get back to the export panel and simply click Export to download the Lottie JSON.
Final Thoughts

Now that you’re done with your animation don’t forget that you have plenty of export options available besides Lottie. You can post the same project on social media in video format, export it as an SVG animation for the web, or turn it into a GIF sticker or any other type of visual you can think of. GIF animations can also be used in Figma presentations and prototypes as a high-fidelity preview of the production-ready Lottie file.

We hope you enjoyed this article and that it will inspire you to create amazing Lottie animations in your next project.

Below, you can find a few useful resources to continue your journey with SVG and SVGator:

  • SVGator tutorials
    Check out a series of short video tutorials to help you get started with SVGator.
  • SVGator Help Center
    It answers the most common questions about SVGator, its features, and membership plans.


Gain $200 in a week
from Articles on Smashing Magazine — For Web Designers And Developers https://ift.tt/qRDdmBN

Clever Polypane Debugging Features I’m Loving

Featured Imgs 23

I’m working on a refresh of my personal website, what I’m calling the HD remaster. Well, I wouldn’t call it a “full” redesign. I’m just cleaning things up, and Polypane is coming in clutch. I wrote about how much I enjoy developing with Polypane on my personal blog back in March 2023. In there, I say that I discover new things every time I open the browser up and I’m here to say that is still happening as of August 2024.

Polypane, in case you’re unfamiliar with it, is a web browser specifically created to help developers in all sorts of different ways. The most obvious feature is the multiple panes displaying your project in various viewport sizes:

Polypane browser displaying ryantrimble.com in three different viewport sizes simultaneously

I’m not about to try to list every feature available in Polypane; I’ll leave that to friend and creator, Kilian Valkhof. Instead, I want to talk about a neat feature that I discovered recently.

Outline tab

Inside Polypane’s sidebar, you will find various tabs that provide different bits of information about your site. For example, if you are wondering how your social media previews will look for your latest blog post, Polypane has you covered in the Meta tab.

Preview card displaying how open graph information will display on Mastodon.

The tab I want to focus on though, is the Outline tab. On the surface, it seems rather straightforward, Polypane scans the page and provides you outlines for headings, landmarks, links, images, focus order, and even the full page accessibility tree.

Polypane sidebar, outline tab, the view select options display the different views available: Headings, Landmarks, Links, Images, Focus order, and Accessibility Tree

Seeing your page this way helps you spot some pretty obvious mistakes, but Polypane doesn’t stop there. Checking the Show issues option will point out some of the not-so-obvious problems.

Polypane sidebar, outline tab, Landsmarks view, the "Show issues" option is enabled. In the outline, red text describes an error: Multiple banner elements at the same level found.

In the Landmarks view, there is an option to Show potentials as well, which displays elements that could potentially be page landmarks.

Polypane sidebar, Outline tab, Landmark view - the outline displays a red symbol indicating a potential landmark element

In these outline views, you also can show an overlay on the page and highlight where things are located.

Polypane laptop viewport view of ryantrimble.com, the landmark overlay feature is enabled, which outlines landmark elements in blue while also displaying their value

Now, the reason I even stumbled upon these features within the Outline tab is due to a bug I was tracking down, one specifically related to focus order. So, I swapped over to the “Focus order” outline to inspect things further.

Polypane sidebar, outline tab, Focus order view, displays an outline of the focusable elements on the page

That’s when I noticed the option to see an overlay for the focus order.

Polypane laptop view with focus order overlay enabled, displays guide lines marking the location of each focusable items

This provides a literal map of the focus order of your page. I found this to be incredibly useful while troubleshooting the bug, as well as a great way to visualize how someone might navigate your website using a keyboard.

These types of seemingly small, but useful features are abundant throughout Polypane.

Amazing tool

When I reached out to Kilian, mentioning my discovery, his response was “Everything’s there when you need it!”

I can vouch for that.


Clever Polypane Debugging Features I’m Loving originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/YiazXRm
Gain $200 in a week
via Read more

Smashing Hour With Lynn Fisher

Featured Imgs 23

I’m a big Lynn Fisher fan. You probably are, too, if you’re reading this. Or maybe you’re reading her name for the first time, in which case you’re in for a treat.

That’s because I had a chance to sit down with Lynn for a whopping hour to do nothing more than gab, gab, and gab some more. I love these little Smashing Hours because they’re informal like that and I feel like I really get to know the person I’m talking with. And this was my very first time talking with Lynn, we had a ton to talk about — her CSS art, her annual site refreshes, where she finds inspiration for her work, when the web started to “click” for her… and so much more.

Don’t miss the bit where Lynn discusses her current site design (~24 min.) because it’s a masterclass in animation and creativity.


Smashing Hour With Lynn Fisher originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/53YiGAM
Gain $200 in a week
via Read more

Two CSS Properties for Trimming Text Box Whitespace

Featured Imgs 23

The text-box-trim and text-box-edge properties in CSS enable developers to trim specifiable amounts of the whitespace that appear above the first formatted line of text and below the last formatted line of text in a text box, making the text box vertically larger than the content within.

This whitespace is called leading, and it appears above and below (so it’s two half-leadings, actually) all lines of text to make the text more readable. However, we only want it to appear in between lines of text, right? We don’t want it to appear along the over or under edges of our text boxes, because then it interferes with our margins, paddings, gaps, and other spacings.

As an example, if we implement a 50px margin but then the leading adds another 37px, we’d end up with a grand total of 87px of space. Then we’d need to adjust the margin to 13px in order to make the space 50px in practice.

The word incendiary showing its text box and whitespace above and below it.

As a design systems person, I try to maintain as much consistency as possible and use very little markup whenever possible, which enables me to use the adjacent-sibling combinator (+) to create blanket rules like this:

/* Whenever <element> is followed by <h1> */
<element> + h1 {
  margin-bottom: 13px; /* instead of margin-bottom: 50px; */
}

This approach is still a headache since you still have to do the math (albeit less of it). But with the text-box-trim and text-box-edge properties, 50px as defined by CSS will mean 50px visually:

The word incendiary with its text box flush against its top and bottom edges.

Disclaimer: text-box-trim and text-box-edge are only accessible via a feature flag in Chrome 128+ and Safari 16.4+, as well as Safari Technology Preview without a feature flag. See Caniuse for the latest browser support.

Start with text-box-trim

text-box-trim is the CSS property that basically activates text box trimming. It doesn’t really have a use beyond that, but it does provide us with the option to trim from just the start, just the end, both the start and end, or none:

text-box-trim: trim-start;
text-box-trim: trim-end;
text-box-trim: trim-both;
text-box-trim: none;

Note: In older web browsers, you might need to use the older start/end/both values in place of the newer trim-start/trim-end/trim-both values, respectively. In even older web browsers, you might need to use top/bottom/both. There’s no reference for this, unfortunately, so you’ll just have to see what works.

Now, where do you want to trim from?

You’re probably wondering what I mean by that. Well, consider that a typographic letter has multiple peaks.

There’s the x-height, which marks the top of the letter “x” and other lowercase characters (not including ascenders or overshoots), the cap height, which marks the top of uppercase characters (again, not including ascenders or overshoots), and the alphabetic baseline, which marks the bottom of most letters (not including descenders or overshoots). Then of course there’s the ascender height and descender height too.

You can trim the whitespace between the x-height, cap height, or ascender height and the “over” edge of the text box (this is where overlines begin), and also the white space between the alphabetic baseline or descender height and the “under” edge (where underlines begin if text-underline-position is set to under).

Don’t trim anything

text-box-edge: leading means to include all of the leading; simply don’t trim anything. This has the same effect as text-box-trim: none or forgoing text-box-trim and text-box-edge entirely. You could also restrict under-edge trimming with text-box-trim: trim-start or over edge trimming with text-box-trim: trim-end. Yep, there are quite a few ways to not even do this thing at all!

Newer web browsers have deviated from the CSSWG specification working drafts by removing the leading value and replacing it with auto, despite the “Do not ship (yet)” warning (*shrug*).

Naturally, text-box-edge accepts two values (an instruction regarding the over edge, then an instruction regarding the under edge). However, auto must be used solo.

text-box-edge: auto; /* Works */
text-box-edge: ex auto; /* Doesn't work */
text-box-edge: auto alphabetic; /* Doesn't work */

I could explain all the scenarios in which auto would work, but none of them are useful. I think all we want from auto is to be able to set the over or under edge to auto and the other edge to something else, but this is the only thing that it doesn’t do. This is a problem, but we’ll dive into that shortly. 

Trim above the ascenders and/or below the descenders

The text value will trim above the ascenders if used as the first value and below the descenders if used as the second value and is also the default value if you fail to declare the second value. (I think you’d want it to be auto, but it won’t be.)

text-box-edge: ex text; /* Valid */
text-box-edge: ex; /* Computed as `text-box-edge: ex text;` */
text-box-edge: text alphabetic; /* Valid */
text-box-edge: text text; /* Valid */
text-box-edge: text; /* Computed as `text-box-edge: text text;` */

It’s worth noting that ascender and descender height metrics come from the fonts themselves (or not!), so text can be quite finicky. For example, with the Arial font, the ascender height includes diacritics and the descender height includes descenders, whereas with the Fraunces font, the descender height includes diacritics and I don’t know what the ascender height includes. For this reason, there’s talk about renaming text to from-font.

The word incendiary written in two variations with accents showing how the test box is affected.

Trim above the cap height only

To trim above the cap height:

text-box-edge: cap; /* Computed as text-box-edge: cap text; */
The word incendiary with the D character slightly outside the top of the text box boundary.

Remember, undeclared values default to text, not auto (as demonstrated above). Therefore, to opt out of trimming the under edge, you’d need to use trim-start instead of trim-both:

text-box-trim: trim-start; /* Not text-box-trim: trim-both; */
text-box-edge: cap; /* Not computed as text-box-edge: cap text; */

Trim above the cap height and below the alphabetic baseline

To trim above the cap height and below the alphabetic baseline:

text-box-trim: trim-both;
text-box-edge: cap alphabetic;
The word incendiary with no whitespace.

By the way, the “Cap height to baseline” option of Figma’s “Vertical trim” setting does exactly this. However, its Dev Mode produces CSS code with outdated property names (leading-trim and text-edge) and outdated values (top and bottom).

Figma screenshot of text settings.

Trim above the x-height only

To trim above the x-height only:

text-box-trim: trim-start;
text-box-edge: ex;
The word incendiary with slight spacing along the bottom edge of its text box.

Trim above the x-height and below the alphabetic baseline

To trim above the x-height and below the alphabetic baseline:

text-box-trim: trim-both;
text-box-edge: ex alphabetic;
The word incendiary with no whitespace.

Trim below the alphabetic baseline only

To trim below the alphabetic baseline only, the following won’t work (things were going so well for a moment, weren’t they?):

text-box-trim: trim-end;
text-box-edge: alphabetic;

This is because the first value is always the mandatory over-edge value whereas the second value is an optional under-edge value. This means that alphabetic isn’t a valid over-edge value, even though the inclusion of trim-end suggests that we won’t be providing one. Complaints about verbosity aside, the correct syntax would have you declare any over-edge value even though you’d effectively cancel it out with trim-end:

text-box-trim: trim-end;
text-box-edge: [any over edge value] alphabetic;
The word incendiary with slight whitespace along the upper edge of its text box.

What about ideographic glyphs?

It’s difficult to know how web browsers will trim ideographic glyphs until they do, but you can read all about it in the spec. In theory, you’d want to use the ideographic-ink value for trimming and the ideographic value for no trimming, both of which aren’t unsupported yet:

text-box-edge: ideographic; /* No trim */
text-box-edge: ideographic-ink; /* Trim */
text-box-edge: ideographic-ink ideographic; /* Top trim */
text-box-edge: ideographic ideographic-ink; /* Bottom trim */

text-box, the shorthand property

If you’re not keen on the verbosity of text box trimming, there’s a shorthand text-box property that makes it somewhat inconsequential. All the same rules apply.

/* Syntax */
text-box: [text-box-trim] [text-box-edge (over)] [text-box-edge (under)]?

/* Example */
text-box: trim-both cap alphabetic;

Final thoughts

At first glance, text-box-trim and text-box-edge might not seem all that interesting, but they do make spacing elements a heck of a lot simpler.

Is the current proposal the best way to handle text box trimming though? Personally, I don’t think so. I think text-box-trim-start and text-box-trim-end would make a lot more sense, with text-box-trim being used as the shorthand property and text-box-edge not being used at all, but I’d settle for some simplification and/or consistent practices. What do you think?

There are some other concerns too. For example, should there be an option to include underlines, overlines, hanging punctuation marks, or diacritics? I’m going to say yes, especially if you’re using text-underline-position: under or a particularly thick text-decoration-thickness, as they can make the spacing between elements appear smaller.


Two CSS Properties for Trimming Text Box Whitespace originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/ozKcrLJ
Gain $200 in a week
via Read more

What’s Old is New

Featured Imgs 23

I collect a bunch of links in a bookmarks folder. These are things I fully intend to read, and I do — eventually. It’s a good thing bookmarks are digital, otherwise, I’d need a bigger coffee table to separate them from the ever-growing pile of magazines.

The benefit of accumulating links is that the virtual pile starts revealing recurring themes. Two seemingly unrelated posts published a couple months apart may congeal and become more of a dialogue around a common topic.

I spent time pouring through a pile of links I’d accumulated over the past few weeks and noticed a couple of trending topics. No, that’s not me you’re smelling — there’s an aroma of nostalgia in the air., namely a newfound focus on learning web fundamentals and some love for manual deployments.

Web Developers, AI, and Development Fundamentals

Alvaro Montero:

Ultimately, it is not about AI replacing developers, but about developers adapting and evolving with the tools. The ability to learn, understand, and apply the fundamentals is essential because tools will only take you so far without the proper foundation.

ShopTalk 629: The Great Divide, Global Design + Web Components, and Job Titles

Chris and Dave sound off on The Great Divide in this episode and the rising value of shifting back towards fundamentals:

Dave: But I think what is maybe missing from that is there was a very big feeling of disenfranchisement from people who are good and awesome at CSS and JavaScript and HTML. But then were being… The market was shifting hard to these all-in JavaScript frameworks. And a lot of people were like, “I don’t… This is not what I signed up for.”

[…]

Dave: Yeah. I’m sure you can be like, “Eat shit. That’s how it is, kid.” But that’s also devaluing somebody’s skillset. And I think what the market is proving now is if you know JavaScript or know HTML, CSS, and regular JavaScript (non-framework JavaScript), you are once again more valuable because you understand how a line of CSS can replace 10,000 lines of JavaScript – or whatever it is.

Chris: Yeah. Maybe it’s coming back just a smidge–

Dave: A smidge.

Chris: –that kind of respecting the fundamental stuff because there’s been churn since then, since five years ago. Now it’s like these exclusively React developers we hired, how useful are they anymore? Were they a little too limited and fundamental people are knowing more? I don’t know. It’s hard to say that the job industry is back when it doesn’t quite feel that way to me.

Dave: Yeah, yeah. Yeah, who knows. I just think the value in knowing CSS and HTML, good HTML, are up more than they maybe were five years ago.

Just a Spec: HTML Finally Gets the Respect It Deserves

Jared and Ayush riffin’ on the first ever State of HTML survey, why we need it, and whether “State of…” surveys are representative of people who work with HTML.

[…] once you’ve learned about divs and H’s 1 through 6, what else is there to know? Quite a lot, as it turns out. Once again, we drafted Lea Verou to put her in-depth knowledge of the web platform to work and help us craft a survey that ended up reaching far beyond pure HTML to cover accessibility, web components, and much more.

[…]

You know, it’s perfectly fine to be an expert at HTML and CSS and know very little JavaScript. So, yeah, I think it’s important to note that as we talk about the survey, because the survey is a snapshot of just the people who know about the survey and answer the questions, right? It’s not necessarily representative of the broad swath of people around the world who have used HTML at all.

[…]

So yeah, a lot of interest in HTML. I’m talking about HTML. And yeah, in the conclusion, Lea Verou talks about we really do have this big need for more extensibility of HTML.

In a more recent episode:

I’m not surprised. I mean, when someone who’s only ever used React can see what HTML does, I think it’s usually a huge revelation to them.

[…]

It just blows their minds. And it’s kind of like you just don’t know what you’re missing out on up to a point. And there is a better world out there that a lot of folks just don’t know about.

[…]

I remember a while back seeing a post come through on social media somewhere, somebody’s saying, oh, I just tried working with HTML forms, just standard HTML forms the first time and getting it to submit stuff. And wait, it’s that easy?

Yeah, last year when I was mentoring a junior developer with the Railsworld conference website, she had come through Bootcamp and only ever done React, and I was showing her what a web component does, and she’s like, oh, man, this is so cool. Yeah, it’s the web platform.

Reckoning: Part 4 — The Way Out

Alex Russell in the last installment of an epic four-part series well worth your time to fully grasp the timeline, impact, and costs of modern JavsaScript frameworks to today’s development practices:

Never, ever hire for JavaScript framework skills. Instead, interview and hire only for fundamentals like web standards, accessibility, modern CSS, semantic HTML, and Web Components. This is doubly important if your system uses a framework.

Semi-Annual Reminder to Learn and Hire for Web Standards

Adrian Roselli:

This is a common cycle. Web developers tire of a particular technology — often considered the HTML killer when released — and come out of it calling for a focus on the native web platform. Then they decide to reinvent it yet again, but poorly.

There are many reasons companies won’t make deep HTML / CSS / ARIA / SVG knowledge core requirements. The simplest is the commoditization of the skills, partly because framework and library developers have looked down on the basics.

The anchor element

Heydon Pickering in a series dedicated to HTML elements, starting alphabetically with the good ol’ anchor <a>:

Sometimes, the <a> is referred to as a hyperlink, or simply a link. But it is not one of these and people who say it is one are technically wrong (the worst kind of wrong).

[…]

Web developers and content editors, the world over, make the mistake of not making text that describes a link actually go inside that link. This is collosally unfortunate, given it’s the main thing to get right when writing hypertext.

AI Myth: It lets me write code I can’t on my own

Chris Ferndandi:

At the risk of being old and out-of-touch: if you don’t know how to write some code, you probably shouldn’t use code that Chat GPT et al write for you.

[…]

It’s not bulletproof, but StackOverflow provides opportunities to learn and understand the code in a way that AI-generated code does not.

What Skills Should You Focus on as Junior Web Developer in 2024?

Frontend Masters:

Let’s not be old-man-shakes-fist-at-kids.gif about this, but learning the fundamentals of tech is demonstrateably useful. It’s true in basketball, it’s true for the piano, and it’s true in making websites. If you’re aiming at a long career in websites, the fundamentals are what powers it.

[…]

The point of the fundamentals is how long-lasting and transferrable the knowledge is. It will serve you well no matter what other technologies a job might have you using, or when the abstractions over them change, as they are want to do.

As long as we’re talking about learning the fundamentals…

The Basics

Oh yeah, and of course there’s this little online course I released this summer for learning HTML and CSS fundamentals that I describe like this:

The Basics is more for your clients who do not know how to update the website they paid you to make. Or the friend who’s learning but still keeps bugging you with questions about the things they’re reading. Or your mom, who still has no idea what it is you do for a living. It’s for those whom the entry points are vanishing. It’s for those who could simply sign up for a Squarespace account but want to understand the code it spits out so they have more control to make a site that uniquely reflects them.

Not all this nostalgia is reserved only for HTML and CSS, but for deploying code, too. A few recent posts riff on what it might look like to ship code with “buildless” or near “buildless” workflows.

Raw-Dogging Websites

Brad Frost:

It is extraordinarily liberating. Yes, there are some ergonomic inefficiencies, but at the end of the day it comes out in the wash. You might have to copy-and-paste some HTML, but in my experience I’d spend that much time or more debugging a broken build or dependency hell.

Going Buildless

Max Böck in a follow-up to Brad:

So, can we all ditch our build tools soon?

Probably not. I’d say for production-grade development, we’re not quite there yet. Performance tradeoffs are a big part of it, but there are lots of other small problems that you’d likely run into pretty soon once you hit a certain level of complexity.

For smaller sites or side projects though, I can imagine going the buildless route – just to see how far I can take it.

Manual ’till it hurts

Jeremy Keith in a follow-up to Max:

If you’re thinking that your next project couldn’t possibly be made without a build step, let me tell you about a phrase I first heard in the indie web community: “Manual ‘till it hurts”. It’s basically a two-step process:

  1. Start doing what you need to do by hand.
  2. When that becomes unworkable, introduce some kind of automation.

It’s remarkable how often you never reach step two.

I’m not saying premature optimisation is the root of all evil. I’m just saying it’s premature.


That’s it for this pile of links and good gosh my laptop feels lighter for it. Have you read other recent posts that tread similar ground? Share ’em in the comments.


What’s Old is New originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.



from CSS-Tricks https://ift.tt/c7EQXyz
Gain $200 in a week
via Read more