Archive

Archive for January, 2021

Painters Tape and Fault Tolerance

January 9th, 2021 No comments

Snipping the top bit of Nicholas C. Zakas’s Top of the Month newsletter (go sign up!), with permission.

One of my favorite things in the world is painters tape (also called masking tape). It seems like something silly: some tape you put on a wall when you’re painting to avoid getting paint on the wall. The tape doesn’t have a strong adhesive, so it can be pulled back off the wall without damaging it. What I love about painters tape is the philosophy behind it: painting is messy, and rather than trying to avoid making a mess, painters tape allows you to make a mess initially and then clean it up easily. Even the best, most talented painter is going to splatter some paint here and there, get distracted, or otherwise end up with paint going where it shouldn’t. It’s a lot faster, easier, and less frustrating to use painters tape to cover up areas where paint is likely to go and then remove the tape to create a nice, clean, finished area. What does this have to do with software engineering?

Painters tape is all about a concept called fault tolerance. Instead of expecting everything to go well, you instead expect that there will be mistakes. When you expect there to be mistakes, you make decisions not to avoid all mistakes but rather to easily recover when a mistake occurs. Got paint where it shouldn’t be? It doesn’t matter if that spot was covered by painters tape. Forgot to put on the painters tape? Now that mistake is a bigger deal. As software engineers, we can think the same way with the code we write.

Making your code fault tolerant is about asking yourself the question: how will this fail? Not if it will fail, but assuming that it will fail, and in which ways will it fail?


The post Painters Tape and Fault Tolerance appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

`aspect-ratio` is going to deprecate FitVids

January 8th, 2021 No comments

Jen was just tweetin’ about how the latest Safari Technical Preview has aspect-ratio. Looks like Chrome and Firefox both have it behind a flag, so with Safari joining the party, we’ll all have it soon.

I played with it a while back. It’s awesome and much needed. There are ways to make `aspect-ratio` boxes, but they largely revolve around “padding hacks.”

Dave is excited about being released from jail:

Yesssss! Soon I will be released from my Open Source prison!

Seeing it working in Edge Dev 89 (M1) as well. https://t.co/bSKrWEPQyE

— Dave Rupert (@davatron5000) January 7, 2021

Once we can rely on it, FitVids (which I use on literally every site I make in one form or another) can entirely go away in favor of a handful of CSS applied directly to the elements (usually videos-in-s).

FitVids 2021:

CodePen Embed Fallback

The post `aspect-ratio` is going to deprecate FitVids appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Svelte and Spring Animations

January 8th, 2021 No comments

Spring animations are a wonderful way to make UI interactions come to life. Rather than merely changing a property at a constant rate over a period of time, springs allow us to move things using spring physics, which gives the impression of a real thing moving, and can appear more natural to users.

I’ve written about spring animations previously. That post was based on React, using react-spring for the animations. This post will explore similar ideas in Svelte.

CSS devs! It’s common to think of easing when it comes to controling the feel of animations. You could think of “spring” animations as a subcategory of easing that are based on real-world physics.

Svelte actually has springs built into the framework, without needing any external libraries. We’ll rehash what was covered in the first half my previous post on react-spring. But after that, we’ll take a deep-dive into all the ways these springs can be used with Svelte, and leave the real world implementation for a future post. While that may seem disappointing, Svelte has a number of wonderful, unique features with no counterpart in React, which can be effectively integrated with these animation primitives. We’re going to spend some time talking about them.

One other note: Some of the demos sprinkled throughout may look odd because I configured the springs to be extra “bouncy” to create more obvious effect. If you the code for any of them, be sure to find a spring configuration that works for you.

Here’s a wonderful REPL Rich Harris made to show all the various spring configurations, and how they behave.

A quick primer on Svelte Stores

Before we start, let’s take a very, very quick tour of Svelte stores. While Svelte’s components are more than capable of storing and updating state, Svelte also has the concept of a store, which allows you to store state outside of a component. Since Svelte’s Spring API uses Stores, we’ll quickly introduce the salient parts here.

To create an instance of a store, we can import the writable type, and create it like so:

import { writable } from "svelte/store";
const clicks = writable(0);

The clicks variable is a store that has a value of 0. There’s two ways to set a new value of a store: the set and update methods. The former receives the value to which you’re setting the store, while the latter receives a callback, accepting the current value, and returning the new value.

function increment() {
  clicks.update(val => val + 1);
}
function setTo5() {
  clicks.set(5);
}

State is useless if you can’t actually consume it. For this, stores offer a subscribe method, which allows you to be notified of new values — but when using it inside of a component, you can prefix the store’s name with the $ character, which tells Svelte to not only display the current value of the store, but to update when it changes. For example:

<h1>Value {$clicks}</h1>
<button on:click={increment}>Increment</button>
<button on:click={setTo5}>Set to 5</button>

Here’s a full, working example of this code. Stores offer a number of other features, such as derived stores, which allow you to chain stores together, readable stores, and even the ability to be notified when a store is first observed, and when it no longer has observers. But for the purposes of this post, the code shown above is all we need to worry about. Consult the Svelte docs or interactive tutorial for more info.

A crash course on springs

Let’s walk through a quick introduction of springs, and what they accomplish. We’ll take a look at a simple UI that changes a presentational aspect of some elements — opacity and transform — and then look at animating that change.

This is a minimal Svelte component that toggles the opacity of one

, and toggles the x-axis transform of another (without any animation).

<script>
  let shown = true;
  let moved = 0;

  const toggleShow = () => (shown = !shown);
  const toggleMove = () => (moved = moved ? 0 : 500);
</script>

<div style="opacity: {shown ? 1 : 0}">Content to toggle</div>
<br />
<button on:click={toggleShow}>Toggle</button>
<hr />
<div class="box" style="transform: translateX({moved}px)">I'm a box.</div>
<br />
<button on:click={toggleMove}>Move it!</button>

These changes are applied instantly, so let’s look at animating them. This is where springs come in. In Svelte, a spring is a store that we set the desired value on, but instead of instantly changing, the store internally uses spring physics to gradually change the value. We can then bind our UI to this changing value, to get a nice animation. Let’s see it in action.

<script>
  import { spring } from "svelte/motion";

  const fadeSpring = spring(1, { stiffness: 0.1, damping: 0.5 });
  const transformSpring = spring(0, { stiffness: 0.2, damping: 0.1 });

  const toggleFade = () => fadeSpring.update(val => (val ? 0 : 1));
  const toggleTransform = () => transformSpring.update(val => (val ? 0 : 500));
  const snapTransform = () => transformSpring.update(val => val, { hard: true });
</script>

<div style="opacity: {$fadeSpring}">Content to fade</div>
<br />
<button on:click={toggleFade}>Fade Toggle</button>

<hr />

<div class="box" style="transform: translateX({$transformSpring}px)">I'm a box.</div>
<br />
<button on:click={toggleTransform}>Move it!</button>
<button on:click={snapTransform}>Snap into place</button>

We get our spring function from Svelte, and set up different spring instances for our opacity, and transform animations. The transform spring config is purposefully set up to be extra springy, to help show later how we can temporarily turn off spring animations, and instantly apply desired changes (which will come in handy later). At the end of the script block are our click handlers for setting the desired properties. Then, in the HTML, we bind our changing values directly to our elements… and that’s it! That’s all there is to basic spring animations in Svelte.

The only remaining item is the snapTransform function, where we set our transform spring to its current value, but also pass an object as the second argument, with hard: true. This has the effect of immediately applying the desired value with no animation at all.

This demo, as well as the rest of the basic examples we’ll look at in this post, is here:

Animating height

Animating height is trickier than other CSS properties, since we have to know the actual height to which we’re animating. Sadly, we can’t animate to a value of auto. That wouldn’t make sense for a spring, since the spring needs a real number so it can interpolate the correct values via spring physics. And as it happens, you can’t even animate auto height with regular CSS transitions. Fortunately, the web platform gives us a handy tool for getting the height of an element: a ResizeObserver, which enjoys pretty good support among browsers.

Let’s start with a raw height animation of an element, producing a “slide down” effect that we gradually refine in other examples. We’ll be using ResizeObserver to bind to an element’s height. I should note that Svelte does have an offsetHeight binding that can be used to more directly bind an element’s height, but it’s implemented with some hacks that cause it to only work on elements that can receive children. This would probably be good enough for most use cases, but I’ll use a ResizeObserver because it allows some nice abstractions in the end.

First, we’ll bind an element’s height. It’ll receive the element and return a writable store that initializes a ResizeObserver, which updates the height value on change. Here’s what that looks like:

export default function syncHeight(el) {
  return writable(null, (set) => {
    if (!el) {
      return;
    }
    let ro = new ResizeObserver(() => el && set(el.offsetHeight));
    ro.observe(el);
    return () => ro.disconnect();
  });
}

We’re starting the store with a value of null, which we’ll interpret as “haven’t measured yet.” The second argument to writable is called by Svelte when the store becomes active, which it will be as soon as it’s used in a component. This is when we fire up the ResizeObserver and start observing the element. Then, we return a cleanup function, which Svelte calls for us when the store is no longer being used anywhere.

Let’s see this in action:

<script>
  import syncHeight from "../syncHeight";
  import { spring } from "svelte/motion";

  let el;
  let shown = false;
  let open = false;
  let secondParagraph = false;

  const heightSpring = spring(0, { stiffness: 0.1, damping: 0.3 });
  $: heightStore = syncHeight(el);
  $: heightSpring.set(open ? $heightStore || 0 : 0);

  const toggleOpen = () => (open = !open);
  const toggleSecondParagraph = () => (secondParagraph = !secondParagraph);
</script>

<button on:click={ toggleOpen }>Toggle</button>
<button on:click={ toggleSecondParagraph }>Toggle More</button>
<div style="overflow: hidden; height: { $heightSpring }px">
  <div bind:this={el}>
    <div>...</div>
    <br />
    {#if secondParagraph}
    <div>...</div>
    {/if}
  </div>
</div>

Our el variable holds the element we’re animating. We tell Svelte to set it to the DOM element via bind:this={el}. heightSpring is our spring that holds the height value of the element when it’s open, and zero when it’s closed. Our heightStore is what keeps it up to date with the element’s current height. el is initially undefined, and syncHeight returns a junk writable store that basically does nothing. As soon as el is assigned to the

node, that line will re-fire — thanks to the $: syntax — and get our writable store with the ResizeObserver listening.

Then, this line:

$: heightSpring.set(open ? $heightStore || 0 : 0);

…listens for changes to the open value, and also changes to the height value. In either case, it updates our spring store. We bind the height in HTML, and we’re done!

Be sure to remember to set overflow to hidden on this outer element so the contents are properly clipped as the elements toggles between its opened and closed states. Also, changes to the element’s height also animate into place, which you can see with the “Toggle More” button. You can run this in the embedded demo in the previous section.

Note that this line above:

$: heightStore = syncHeight(el);

…currently causes an error when using server-side rendering (SSR), as explained in this bug. If you’re not using SSR you don’t need to worry about it, and of course by the time you read this that bug may have been fixed. But the workaround is to merely do this:

let heightStore;
$: heightStore = syncHeight(el);

…which works but is hardly ideal.

We probably don’t want the

to spring open on first render. Also, the opening spring effect is nice, but when closing, the effect is janky due to some content flickering. We can fix that. To prevent our initial render from animating, we can use the { hard: true } option we saw earlier. Let’s change our call to heightSpring.set to this:

$: heightSpring.set(open ? $heightStore || 0 : 0, getConfig($heightStore));

…and then see about writing a getConfig function that returns an object with the hard property that was set to true for the first render. Here’s what I came up with:

let shown = false;

const getConfig = val => {
  let active = typeof val === "number";
  let immediate = !shown && active;
  //once we've had a proper height registered, we can animate in the future
  shown = shown || active;
  return immediate ? { hard: true } : {};
};

Remember, our height store initially holds null and only gets a number when the ResizeObserver starts running. We capitalize on this by checking for an actual number. If we have a number, and we haven’t yet shown anything, then we know to show our content immediately, and we we do that by setting the immediate value. That value ultimately triggers the hard config value in the spring, which we saw before.

Now let’s tweak the animation to be a bit less, well, springy when we close our content. That way, things won’t flicker when they close. When we initially created our spring, we specified stiffness and damping, like so

const heightSpring = spring(0, { stiffness: 0.1, damping: 0.3 });

It turns out the spring object itself maintains those properties, which can be set anytime. Let’s update this line:

$: heightSpring.set(open ? $heightStore || 0 : 0, getConfig($heightStore));

That detects changes to the open value (and the heightStore itself) to update the spring. Let’s also update the spring’s settings based on whether we’re opening or closing. Here’s what it looks like:

$: {
  heightSpring.set(open ? $heightStore || 0 : 0, getConfig($heightStore));
  Object.assign(
    heightSpring,
    open ? { stiffness: 0.1, damping: 0.3 } : { stiffness: 0.1, damping: 0.5 }
  );
}

Now when we get a new open or height value, we call heightSpring.set just like before, but we also set stiffness and damping values on the spring that are applied based on whether the element is open. If it’s closed, we set damping up to 0.5, which reduces the springiness. Of course, you’re welcome to tweak all these values and configure them as you’d like! You can see this in the “Animate Height Different Springs” section of the demo.

You might notice our code is starting to grow pretty quickly. We’ve added a lot of boilerplate to cover some of these use cases, so let’s clean things up. Specifically, we’ll make a function that creates our spring and that also exports a sync function to handle our spring config, initial render, etc.

import { spring } from "svelte/motion";

const OPEN_SPRING = { stiffness: 0.1, damping: 0.3 };
const CLOSE_SPRING = { stiffness: 0.1, damping: 0.5 };

export default function getHeightSpring() {
  const heightSpring = spring(0);
  let shown = false;

  const getConfig = (open, val) => {
    let active = typeof val === "number";
    let immediate = open && !shown && active;
    // once we've had a proper height registered, we can animate in the future
    shown = shown || active;
    return immediate ? { hard: true } : {};
  };

  const sync = (open, height) => {
    heightSpring.set(open ? height || 0 : 0, getConfig(open, height));
    Object.assign(heightSpring, open ? OPEN_SPRING : CLOSE_SPRING);
  };

  return { sync, heightSpring };
}

There’s a lot of code here, but it’s all the code we’ve been writing so far, just packaged into a single function. Now our code to use this animation is simplified to just this

const { heightSpring, sync } = getHeightSpring();
$: heightStore = syncHeight(el);
$: sync(open, $heightStore);

You can see in the “Animate Height Cleanup” section of the demo.

Some Svelte-specific tricks

Let’s pause for a moment and consider some ways Svelte differs from React, and how we might leverage that to improve what we have even further.

First, the stores we’ve been using to hold springs and change height values are, unlike React’s hooks, not tied to component rendering. They’re plain JavaScript objects that can be consumed anywhere. And, as alluded to above, we can imperatively subscribe to them so that they manually observe changing values.

Svelte also something called actions. These are functions that can be added to a DOM element. When the element is created, Svelte calls the function and passes the element as the first argument. We can also specify additional arguments for Svelte to pass, and provide an update function for Svelte to re-run when those values change. Another thing we can do is provide a cleanup function for Svelte to call when it destroys the element.

Let’s put these tools together in a single action that we can simply drop onto an element to handle all the animation we’ve been writing so far:

export default function slideAnimate(el, open) {
  el.parentNode.style.overflow = "hidden";

  const { heightSpring, sync } = getHeightSpring();
  const doUpdate = () => sync(open, el.offsetHeight);
  const ro = new ResizeObserver(doUpdate);

  const springCleanup = heightSpring.subscribe((height) => {
    el.parentNode.style.height = `${ height }px`;
  });

  ro.observe(el);

  return {
    update(isOpen) {
      open = isOpen;
      doUpdate();
    },
    destroy() {
      ro.disconnect();
      springCleanup();
    }
  };
}

Our function is called with the element we want to animate, as well as the open value. We’ll set the element’s parent to have overflow: hidden. Then we use the same getHeightSpring function from before, set up our ResizeObserver, etc. The real magic is here.

const springCleanup = heightSpring.subscribe((height) => {
  el.parentNode.style.height = `${height}px`;
});

Instead of binding our heightSpring to the DOM, we manually subscribe to changes, then set the height ourselves, manually. We wouldn’t normally do manual DOM updates when using a JavaScript framework like Svelte but, in this case, it’s for a helper library, which is just fine in my opinion.

In the object we’re returning, we define an update function which Svelte will call when the open value changes. We update the original argument to this function, which the function closes over ( i.e. creates a closure around) and then calls our update function to sync everything. Svelte calls the destroy function when our DOM node is destroyed.

Best of all, using this action is a snap:

<div use:slideAnimate={open}>

That’s it. When open changes, Svelte calls our update function.

Before we move on, let’s make one other tweak. Notice how we remove the springiness by changing the spring config when we collapse the pane with the “Toggle” button; however, when we make the element smaller by clicking the “Toggle More” button, it shrinks with the usual springiness. I dislike that, and prefer shrinking sizes move with the same physics we’re using for collapsing.

Let’s start by removing this line in the getHeightSpring function:

Object.assign(heightSpring, open ? OPEN_SPRING : CLOSE_SPRING);

That line is inside the sync function that getHeightSpring created, which updates our spring settings on every change, based on the open value. With it gone, we can start our spring with the “open” spring config:

const heightSpring = spring(0, OPEN_SPRING);

Now let’s change our spring settings when either the height of our content changes, or when the open value changes. We already have the ability to observe both of those things changing — our ResizeObserver callback fires when the size of the content changes, and the update function of our action fires whenever open changes.

Our ResizeObserver callback can be changed, like this:

let currentHeight = null;
const ro = new ResizeObserver(() => {
  const newHeight = el.offsetHeight;
  const bigger = newHeight > currentHeight;

  if (typeof currentHeight === "number") {
    Object.assign(heightSpring, bigger ? OPEN_SPRING : CLOSE_SPRING);
  }
  currentHeight = newHeight;
  doUpdate();
});

currentHeight holds the current value, and we check it on size changes to see which direction we’re moving. Next up is the update function. Here’s what it looks like after our change:

update(isOpen) {
  open = isOpen;
  Object.assign(heightSpring, open ? OPEN_SPRING : CLOSE_SPRING);
  doUpdate();
},

Same idea, but now we’re only checking whether open is true or false. You can see these iterations in the “Slide Animate” and “Slide Animate 2” sections of the demo.

Transitions

We’ve talked about animating items already on the page so far, but what about animating an object when it first renders? And when it un-mounts? That’s called a transition, and it’s built into Svelte. The docs do a superb job covering the common use cases, but there’s one thing that’s not yet (directly) supported: spring-based transitions.

/explanation Note that what Svelte calls a “transition” and what CSS calls a “transition” are very different things. CSS means transitioning one value to another. Svelte is referring to elements as they “transition” into and out of the DOM entirely (something that CSS doesn’t help with much at all).

To be clear, the work we’re doing here is made for adding spring-based animations into Svelte’s transitions. This is not currently supported, so it requires some tricks and workarounds that we’ll get into. If you don’t care about using springs, then Svelte’s built-in transitions can be used, which are significantly simpler. Again, check the docs for more info.

The way transitions work in Svelte is that we provide a duration in milliseconds (ms) along with an optional easing function, then Svelte provides us a callback with a value running from 0 to 1, representing how far along the transition is, and we turn that into whatever CSS we want. For example:

const animateIn = () => {
  return {
    duration: 2000,
    css: t => `transform: translateY(${t * 50 - 50}px)`
  };
};

…is used like this:

<div in:animateIn out:animateOut class="box">
  Hello World!
</div>

When that

first mounts, Svelte:

  • calls our animateIn function,
  • rapidly calls the CSS function on our resulting object ahead of time with values from 0 to 1,
  • collects our changing CSS result, then
  • compiles those results into a CSS keyframes animation, which it then applies to the incoming
    .

This means that our animation will run as a CSS animation — not as JavaScript on the main thread — offering a nice performance boost for free.

The variable t starts at 0, which results in a translation of -50px. As t gets closer to 1, the translation approaches 0, its final value. The out transition is about the same, but in reverse, with the added feature of detecting the box’s current translation value, starting from there. So, if we add it then quickly remove it, the box will start to leave from its current position rather than jumping ahead. However, if we then re-add it while it’s leaving, it will jump, something we’ll talk about in just moment.

You can run this in the “Basic Transition” section of the demo.

Transitions, but with springs

While there’s a number of easing functions that alter the flow of an animation, there’s no ability to directly use springs. But what we could do is find some way to run a spring ahead of time, collect the resulting values, and then, when our css function is called with the a t value running from 0 to 1, look up the right spring value. So, if t is 0, we obviously need the first value from thespring. When t is 0.5, we want the value right in the middle, and so on. We also need a duration, which is number_of_spring_values * 1000 / 60 since there’s 60 frames per second.

We won’t write that code here. Instead, we’ll use the solution that already exists in the svelte-helpers library, a project I started. I grabbed one small function from the Svelte codebase, spring_tick, then wrote a separate function to repeatedly call it until it’s finished, collecting the values along the way. That, along with a translation from t to the correct element in that array (or a weighted average if there’s not a direct match), is all we need. Rich Harris gave a helping hand on the latter, for which I’m grateful.

Animate in

Let’s pretend a big red

is a modal that we want to animate in, and out. Here’s what an animateIn function looks like:

import { springIn, springOut } from "svelte-helpers/animation";
const SPRING_IN = { stiffness: 0.1, damping: 0.1 };

const animateIn = node => {
  const { duration, tickToValue } = springIn(-80, 0, SPRING_IN);
  return {
    duration,
    css: t => `transform: translateY(${ tickToValue(t) }px)`
  };
};

We feed the values we want to spring to, as well as our spring config to the springIn function. That gives us a duration, and a function for translating the current tickToValue into the current value to apply in the CSS. That’s it!

Animate out

Closing the modal is the same thing, with one small tweak

const SPRING_OUT = { stiffness: 0.1, damping: 0.5, precision: 3 };

const animateOut = node => {
  const current = currentYTranslation(node);
  const { duration, tickToValue } = springOut(current ? current : 0, 80, SPRING_OUT);
  return {
    duration: duration,
    css: t => `transform: translateY(${ tickToValue(t) }px)`
  };
};

Here, we’re check the modal’s current translation position, then use that as a starting point for the animation. This way, if the user opens and then quickly closes the modal, it’ll exit from its current position, rather than teleporting to 0, and then leaving. This works because the animateOut function is called when the element un-mounts, at which point we generate the object with the duration property and css function so the animation can be computed.

Sadly, it seems re-mounting the object while it’s in the process of leaving does not work, at least well. The animateIn function is not called de novo, but rather the original animation is re-used, which means it’ll always start at -80. Fortunately this almost certainly would not matter for a typical modal component, since a modal is usually removed by clicking on something, like the background overlay, meaning we are unable to re-show it until that overlay has finished animating out. Besides, repeatedly adding and removing an element with bidirectional transitions might make for a fun demo, but they’re not really common in practice, at least in my experience.

One last quick note on the outgoing spring config: You may have noticed that I set the precision ridiculously high (3 when the default is 0.01). This tells Svelte how close to get to the target value before deciding it is “done.” If you leave the default at 0.01, the modal will (almost) hit its destination, then spend quite a few milliseconds imperceptibly getting closer and closer before deciding it’s done, then remove itself from the DOM. This gives the impression that the modal is stuck, or otherwise delayed. Moving the precision to a value of 3 fixes this. Now the modal animates to where it should go (or close enough), then quickly goes away.

More animation

Let’s add one final tweak to our modal example. Let’s have it fade in and out while animating. We can’t use springs for this, since, again, we need to have one canonical duration for the transition, and our motion spring is already providing that. But spring animations usually make sense for items actually moving, and not much else. So let’s use an easing function to create a fade animation.

If you need help picking the right easing function, be sure to check out this handy visualization from the Svelte docs. I’ll be using the quintOut and quadIn functions.

import { quintOut, quadIn } from "svelte/easing";

Our new animateIn function looks pretty similar. Our css function does what it did before, but also runs the tickToValue value through the quintOut easing function to get our opacity value. Since t runs from 0 to 1 during an in transition, and 1 to 0 during an out transition, we don’t have to do anything further to it before applying to opacity.

const SPRING_IN = { stiffness: 0.1, damping: 0.1 };
const animateIn = node =>; {
  const { duration, tickToValue } = springIn(-80, 0, SPRING_IN);
  return {
    duration,
    css: t => {
      const transform = tickToValue(t);
      const opacity = quintOut(t);
      return `transform: translateY(${ transform }px); opacity: ${ opacity };`;
    }
  };
};

Our animateOut function is similar, except we want to grab the element’s current opacity value, and force the animation to start there. So, if the element is in the process of fading in, with an opacity of, say, 0.3, we don’t want to reset it to 1, and then fade it out. Instead, we want to fade it out from 0.3.

Multiplying that starting opacity by whatever value the easing function returns accomplishes this. If our t value starts at 1, then 1 * 0.3 is 0.3. If t is 0.95, we do 0.95 * 0.3 to get a value, which is a little less than 0.3, and so on.

Here’s the function:

const animateOut = node => {
  const currentT = currentYTranslation(node);
  const startOpacity = +getComputedStyle(node).opacity;
  const { duration, tickToValue } = springOut(
    currentT ? currentT : 0,
    80,
    SPRING_OUT
  );
  return {
    duration,
    css: t => {
      const transform = tickToValue(t);
      const opacity = quadIn(t);
      return `transform: translateY(${ transform }px); opacity: ${ startOpacity * opacity }`;
    }
  };
};

You can run this example in the demo with the “Spring Transition With Fade component.

Parting thoughts

Svelte is a lot of fun! In my (admittedly limited) experience, it tends to provide extremely simple primitives, and then leaves you to code up whatever you need. I hope this post has helped explain how the spring animations can be put to good use in your web applications.

And, hey, just a quick reminder to consider accessibility when working with springs, just as you would do with any other animation. Pairing these techniques with something like prefers-reduced-motion can ensure that only folks who prefer animations are the ones who get them.


The post Svelte and Spring Animations appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

How CentOS Became 2020’s Final Victim

January 8th, 2021 No comments

If you were paying close attention to your IT department around the 8th of December, you might have heard some quiet sobbing and the occasional wail of, “Why? Why?! WHY?!” Now, it was the year 2020, so this might have seemed normal to you, but it’s actually something of a problem that could affect your business: CentOS is pretty much dead.

For the non-total-nerds among us, here’s the skinny: CentOS is a Linux-based operating system, typically used on servers. CentOS has been incredibly popular, and quite a few businesses run on it. But now, that’s changing.

CentOS is a Linux-based operating system, typically used on servers…But now, that’s changing

CentOS used to be released in thoroughly tested versions, the latest being CentOS 8. CentOS 8 was released in September of 2019 and was supposed to be supported for ten years. Now, it’s been decided that CentOS will no longer have versioned releases, opting for a rolling-release style of updates. That means there’ll be one version that constantly gets new software.

That’s cool in theory, but it means the operating system will be less stable overall. Essentially, it’s going to be used as a development branch of / testing ground for Red Hat Enterprise Linux and is no longer its own OS. If you have CentOS-based servers, you should migrate to another OS sooner rather than later.

And I just got my own CentOS-based VPS set up the way I wanted it.

Wait, What Does Red Hat Have To Do With This?

Here’s the short, short version of the history of CentOS: Red Hat (an OS developer) has two Linux distributions of its own and has had for a long time. There’s the free and community-focused Fedora and the business-focused highly expensive Red Hat Enterprise Linux (AKA RHEL).

Funny story: RHEL, despite its expensive licenses, is still mostly made from open source code, which anyone can access and use. And it’s a good OS, particularly for people who like stability.

In 2004, some smart people took all the open-source parts of RHEL and made a brand new, nearly identical operating system with it: the Community Enterprise Operating System, or CentOS. Basically, people could download and use an enterprise-level server OS for free. All the documentation for RHEL was compatible, and you could get support from the community.

It was the perfect alternative for anyone who didn’t have the budget for expensive software licenses.

In 2014, Red Hat offered to partner with the CentOS community. The idea was basically this: “It’s pretty much the same software. If our company and your community work together, both our products will be better! We make our money from enterprise customers, anyway.”

Most importantly, with Red Hat doing a lot of the heavy lifting in terms of updates and support, the CentOS community could focus on growing in other ways.

Red Hat pinky swore [citation needed] that they were in this for the long haul, and CentOS did continue to flourish. You know, until 2020.

Well, So Much For Pinky Swearing

Red Hat must have eventually decided that having a popular free version of its own enterprise software and managing it themselves no less — wasn’t that good for business. So they all but shut the project down.

Well, technically, they just changed how it operated. Instead of producing tested, production-ready versions, CentOS is merely a testing ground for RHEL. It is no longer, in my opinion, a good option for anyone who wants to run a stable server.

Current and Future CentOS Alternatives

So if you jumped on the CentOS 8 bandwagon, what should you put on your physical and virtual servers now? Well, you’ve got options.

Debian / Ubuntu

For those who don’t mind going to a very different kind of Linux, Debian has been the picture of OS stability and sysadmin-friendliness for a long time. If you want more frequent software updates, the Debian-based Ubuntu Server is popular and pretty good.

Oracle Linux

Yes, that Oracle has a RHEL-compatible Linux distribution of its own. But it’s not a clone, exactly. I mean, this is Oracle. It’s set up to use their tools and ecosystem, so I hope you like Oracle products. But hey, the OS itself is free!

ClearOS

ClearOS is another RHEL-compatible OS that’s mostly doing its own thing, though I’m not entirely sure what that thing is. Does the company have some deal with Hewlett-Packard? Anyway, they do have a free community edition and paid editions for home and business use.

The CloudLinux RHEL Fork

This is an upcoming release from the makers of CloudLinuxOS. It looks like they intend to load the new RHEL-based OS with some of their own tools, such as reboot-less server update tech. The first release is intended to be a more or less drop-in replacement for CentOS 8.

Rocky Linux

So the community that made and loved CentOS in the first place is, to say the least, ticked. They are so ticked that Greg Kurtzer (a co-founder of CentOS) has decided to do it all over again by making Rocky Linux and keep it in the community this time.

Again, the goal is to make a re-build of RHEL, a drop-in replacement for CentOS (at least for now). Eventually, the goal is to migrate from CentOS to Rocky Linux as easy as using a single, one-line command. The ETA for initial release isn’t quite set in stone, but I can personally vouch for how hard the community is working.

[See, full disclosure here… after writing this article, I joined the Rocky Linux documentation team.]

So Yeah, You Have Options

Some are out now, and others will be soon. Again, CentOS 8 will be supported until the end of 2021. CentOS 7, weirdly, will be supported until June 2024.

Migration shouldn’t be too complicated. Still, a pain in the rear that we have to do this at all, though.

Source

The post How CentOS Became 2020’s Final Victim first appeared on Webdesigner Depot.

Categories: Designing, Others Tags:

Creating CSS APIs without JavaScript With the datasette-css-properties plugin

January 7th, 2021 No comments

Simon Willison has a project called Datasette, an open source multi-tool for exploring and publishing data. I’m not sure I’m qualified to explain it, but it’s like a tool to make handling data easier and doing more — through the web — with data you have. Like making that data queryable and giving it an API.

I would think, typically, you’d get the results of an API call against your data in something useful, like JSON. But Simon made a plugin that outputs the results as CSS custom properties instead, and blogged it:

It’s very, very weird—it adds a .css output extension to Datasette which outputs the result of a SQL query using CSS custom property format. This means you can display the results of database queries using pure CSS and HTML, no JavaScript required!

Here’s what I said just recently in “Custom Properties as State”:

This makes me think that a CDN-hosted CSS file like this could have other useful stuff, like today’s date for usage in pseudo content, or other special time-sensitive stuff. Maybe the phase of the moon? Sports scores?! Soup of the day?!

And Simon is like, how about roadside attractions?

CodePen Embed Fallback

My brain automatically worries about the accessibility of that, but… aren’t pseudo-elements fairly and reliably read in screen readers these days? You still can’t select the text though, or find-on-page, which are both usability and accessibility issues, so don’t consider this like a real thing that you really do for production work with unknown users.

His blog post demonstrates a slightly more dynamic example where the time of day outputs a different color. That makes me think of @property and declaring types for custom properties. I think this gets a smidge more useful when you can use the values that come back as specific syntaxes.


The post Creating CSS APIs without JavaScript With the datasette-css-properties plugin appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Theming and Theme Switching with React and styled-components

January 7th, 2021 No comments
A simple heading 1 that says Theme Builder in black on a white background.

I recently had a project with a requirement to support theming on the website. It was a bit of a strange requirement, as the application is mostly used by a handful of administrators. An even bigger surprise was that they wanted not only to choose between pre-created themes, but build their own themes. I guess the people want what they want!

Let’s distill that into a complete list of more detailed requirements, then get it done!

  • Define a theme (i.e. background color, font color, buttons, links, etc.)
  • Create and save multiple themes
  • Select and apply a theme
  • Switch themes
  • Customize a theme

We delivered exactly that to our client, and the last I heard, they were using it happily!

Let’s get into building exactly that. We’re going to use React and styled-components. All the source code used in the article can be found in the GitHub Repository.

The setup

Let’s set up a project with React and styled-components. To do that, we will be using the create-react-app. It gives us the environment we need to develop and test React applications quickly.

Open a command prompt and use this command to create the project:

npx create-react-app theme-builder

The last argument, theme-builder, is just the name of the project (and thus, the folder name). You can use anything you like.

It may take a while. When done, navigate it to it in the command line with cd theme-builder. Open the file src/App.js file and replace the content with the following:

import React from 'react';

function App() {
  return (
    <h1>Theme Builder</h1>
  );
}

export default App;

This is a basic React component that we will modify soon. Run the following command from the project root folder to start the app:

# Or, npm run start
yarn start

You can now access the app using the URL http://localhost:3000.

create-react-app comes with the test file for the App component. As we will not be writing any tests for the components as part of this article, you can choose to delete that file.

We have to install a few dependencies for our app. So let’s install those while we’re at it:

# Or, npm i ...
yarn add styled-components webfontloader lodash

Here’s what we get:

  • styled-components: A flexible way to style React components with CSS. It provides out-of-the-box theming support using a wrapper component called, . This component is responsible for providing the theme to all other React components that are wrapped within it. We will see this in action in a minute.
  • Web Font Loader: The Web Font Loader helps load fonts from various sources, like Google Fonts, Adobe Fonts, etc. We will use this library to load fonts when a theme is applied.
  • lodash: This is a JavaScript utility library for some handy little extras.

Define a theme

This is the first of our requirements. A theme should have a certain structure to define appearance, including colors, fonts, etc. For our application, we will define each theme with these properties:

  • unique identifier
  • theme name
  • color definitions
  • fonts
Screenshot of a code editor showing the organized structure of properties for a sea wave theme.
A theme is a structured group of properties that we’ll use in the application.

You may have more properties and/or different ways to structure it, but these are the things we’re going to use for our example.

Create and save multiple themes

So, we just saw how to define a theme. Now let’s create multiple themes by adding a folder in the project at src/theme and a file in it called, schema.json. Here’s what we can drop in that file to establish “light” and “sea wave” themes:

{
  "data" : {
    "light" : {
      "id": "T_001",
      "name": "Light",
      "colors": {
        "body": "#FFFFFF",
        "text": "#000000",
        "button": {
          "text": "#FFFFFF",
          "background": "#000000"
        },
        "link": {
          "text": "teal",
          "opacity": 1
        }
      },
      "font": "Tinos"
    },
    "seaWave" : {
      "id": "T_007",
      "name": "Sea Wave",
      "colors": {
        "body": "#9be7ff",
        "text": "#0d47a1",
        "button": {
          "text": "#ffffff",
          "background": "#0d47a1"
        },
        "link": {
          "text": "#0d47a1",
          "opacity": 0.8
        }
      },
      "font": "Ubuntu"
    }
  }
}

The content of the schema.json file can be saved to a database so we can persist all the themes along with the theme selection. For now, we will simply store it in the browser’s localStorage. To do that, we’ll create another folder at src/utils with a new file in it called, storage.js. We only need a few lines of code in there to set up localStorage:

export const setToLS = (key, value) => {
  window.localStorage.setItem(key, JSON.stringify(value));
}

export const getFromLS = key => {
  const value = window.localStorage.getItem(key);

  if (value) {
    return JSON.parse(value);
  }
}

These are simple utility functions to store data to the browser’s localStorage and to retrieve from there. Now we will load the themes into the browser’s localStorage when the app comes up for the first time. To do that, open the index.js file and replace the content with the following,

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import * as themes from './theme/schema.json';
import { setToLS } from './utils/storage';

const Index = () => {
  setToLS('all-themes', themes.default);
  return(
    <App />
  )
}

ReactDOM.render(
  <Index />
  document.getElementById('root')
);

Here, we are getting the theme information from the schema.json file and adding it to the localStorage using the key all-themes. If you have stopped the app running, please start it again and access the UI. You can use DevTools in the browser to see the themes are loaded into localStorage.

The theme with DevTools open and showing the theme properties in the console.
All of the theme props are properly stored in the browser’s localStorage, as seen in DevTools, under Application ? Local Storage.

Select and apply a theme

We can now use the theme structure and supply the theme object to the wrapper.

First, we will create a custom React hook. This will manage the selected theme, knowing if a theme is loaded correctly or has any issues. Let’s start with a new useTheme.js file inside the src/theme folder with this in it:

import { useEffect, useState } from 'react';
import { setToLS, getFromLS } from '../utils/storage';
import _ from 'lodash';

export const useTheme = () => {
  const themes = getFromLS('all-themes');
  const [theme, setTheme] = useState(themes.data.light);
  const [themeLoaded, setThemeLoaded] = useState(false);

  const setMode = mode => {
    setToLS('theme', mode)
    setTheme(mode);
  };

  const getFonts = () => {
    const allFonts = _.values(_.mapValues(themes.data, 'font'));
    return allFonts;
  }

  useEffect(() =>{
    const localTheme = getFromLS('theme');
    localTheme ? setTheme(localTheme) : setTheme(themes.data.light);
    setThemeLoaded(true);
  }, []);

  return { theme, themeLoaded, setMode, getFonts };
};

This custom React hook returns the selected theme from localStorage and a boolean to indicate if the theme is loaded correctly from storage. It also exposes a function, setMode, to apply a theme programmatically. We will come back to that in a bit. With this, we also get a list of fonts that we can load later using a web font loader.

It would be a good idea to use global styles to control things, like the site’s background color, font, button, etc. styled-components provides a component called, createGlobalStyle that establishes theme-aware global components. Let’s set those up in a file called, GlobalStyles.js in the src/theme folder with the following code:

import { createGlobalStyle} from "styled-components";

export const GlobalStyles = createGlobalStyle`
  body {
    background: ${({ theme }) => theme.colors.body};
    color: ${({ theme }) => theme.colors.text};
    font-family: ${({ theme }) => theme.font};
    transition: all 0.50s linear;
  }

  a {
    color: ${({ theme }) => theme.colors.link.text};
    cursor: pointer;
  }

  button {
    border: 0;
    display: inline-block;
    padding: 12px 24px;
    font-size: 14px;
    border-radius: 4px;
    margin-top: 5px;
    cursor: pointer;
    background-color: #1064EA;
    color: #FFFFFF;
    font-family: ${({ theme }) => theme.font};
  }

  button.btn {
    background-color: ${({ theme }) => theme.colors.button.background};
    color: ${({ theme }) => theme.colors.button.text};
  }
`;

Just some CSS for the , links and buttons, right? We can use these in the App.js file to see the theme in action by replace the content in it with this:

// 1: Import
import React, { useState, useEffect } from 'react';
import styled, { ThemeProvider } from "styled-components";
import WebFont from 'webfontloader';
import { GlobalStyles } from './theme/GlobalStyles';
import {useTheme} from './theme/useTheme';

// 2: Create a cotainer
const Container = styled.div`
  margin: 5px auto 5px auto;
`;

function App() {
  // 3: Get the selected theme, font list, etc.
  const {theme, themeLoaded, getFonts} = useTheme();
  const [selectedTheme, setSelectedTheme] = useState(theme);

  useEffect(() => {
    setSelectedTheme(theme);
   }, [themeLoaded]);

  // 4: Load all the fonts
  useEffect(() => {
    WebFont.load({
      google: {
        families: getFonts()
      }
    });
  });

  // 5: Render if the theme is loaded.
  return (
    <>
    {
      themeLoaded && <ThemeProvider theme={ selectedTheme }>
        <GlobalStyles/>
        <Container style={{fontFamily: selectedTheme.font}}>
          <h1>Theme Builder</h1>
          <p>
            This is a theming system with a Theme Switcher and Theme Builder.
            Do you want to see the source code? <a href="https://github.com/atapas/theme-builder" target="_blank">Click here.</a>
          </p>
        </Container>
      </ThemeProvider>
    }
    </>
  );
}

export default App;

A few things are happening here:

  1. We import the useState and useEffect React hooks which will help us to keep track of any of the state variables and their changes due to any side effects. We import ThemeProvider and styled from styled-components. The WebFont is also imported to load fonts. We also import the custom theme, useTheme, and the global style component, GlobalStyles.
  2. We create a Container component using the CSS styles and styled component.
  3. We declare the state variables and look out for the changes.
  4. We load all the fonts that are required by the app.
  5. We render a bunch of text and a link. But notice that we are wrapping the entire content with the wrapper which takes the selected theme as a prop. We also pass in the component.

Refresh the app and we should see the default “light” theme enabled.

The theme with a white background and black text.
Hey, look at that clean, stark design!

We should probably see if switching themes works. So, let’s open the useTheme.js file and change this line:

localTheme ? setTheme(localTheme) : setTheme(themes.data.light);

…to:

localTheme ? setTheme(localTheme) : setTheme(themes.data.seaWave);

Refresh the app again and hopefully we see the “sea wave” theme in action.

The same theme in with a blue color scheme with a light blue background and dark blue text and a blue button.
Now we’re riding the waves of this blue-dominant theme.

Switch themes

Great! We are able to correctly apply themes. How about creating a way to switch themes just with the click of a button? Of course we can do that! We can also provide some sort of theme preview as well.

A heading instructs the user to select a theme and two card components are beneath the heading, side-by-side, showing previews of the light theme and the sea wave theme.
A preview of each theme is provided in the list of options.

Let’s call each of these boxes a ThemeCard, and set them up in a way they can take its theme definition as a prop. We’ll go over all the themes, loop through them, and populate each one as a ThemeCard component.

{
  themes.length > 0 && 
  themes.map(theme =>(
    <ThemeCard theme={data[theme]} key={data[theme].id} />
  ))
}

Now let’s turn to the markup for a ThemeCard. Yours may look different, but notice how we extract its own color and font properties, then apply them:

const ThemeCard = props => {
  return(
    <Wrapper 
      style={{backgroundColor: `${data[_.camelCase(props.theme.name)].colors.body}`, color: `${data[_.camelCase(props.theme.name)].colors.text}`, fontFamily: `${data[_.camelCase(props.theme.name)].font}`}}>
      <span>Click on the button to set this theme</span>
      <ThemedButton
        onClick={ (theme) => themeSwitcher(props.theme) }
        style={{backgroundColor: `${data[_.camelCase(props.theme.name)].colors.button.background}`, color: `${data[_.camelCase(props.theme.name)].colors.button.text}`, fontFamily: `${data[_.camelCase(props.theme.name)].font}`}}>
        {props.theme.name}
      </ThemedButton>
    </Wrapper>
  )
}

Next up, let’s create a file called ThemeSelector.js in our the src folder. Copy the content from here and drop it into the file to establish our theme switcher, which we need to import in App.js:

import ThemeSelector from './ThemeSelector';

Now we can use it inside the Container component:

<Container style={{fontFamily: selectedTheme.font}}>
  // same as before
  <ThemeSelector setter={ setSelectedTheme } />
</Container>

Let’s refresh the browser now and see how switching themes works.

An animated screenshot showing the theme changing when it is selected from the list of theme card options.

The fun part is, you can add as many as themes in the schema.json file to load them in the UI and switch. Check out this schema.json file for some more themes. Please note, we are also saving the applied theme information in localStorage, so the selection will be retained when you reopen the app next time.

Selected theme stored in the Local Storage.

Customize a theme

Maybe your users like some aspects of one theme and some aspects of another. Why make them choose between them when they can give them the ability to define the theme props themselves! We can create a simple user interface that allows users to select the appearance options they want, and even save their preferences.

Animated screenshot showing a modal opening with a list of theme options to customize the appearance, including the them name, background color, text color, button text color, link color, and font.

We will not cover the theme creation code explanation in details but, it should be easy by following the code in the GitHub Repo. The main source file is CreateThemeContent.js and it is used by App.js. We create the new theme object by gathering the value from each input element change event and add the object to the collection of theme objects. That’s all.

Before we end…

Thank you for reading! I hope you find what we covered here useful for something you’re working on. Theming systems are fun! In fact, CSS custom properties are making that more and more a thing. For example, check out this approach for color from Dieter Raber and this roundup from Chris. There’s also this setup from Michelle Barker that relies on custom properties used with Tailwind CSS. Here’s yet another way from Andrés Galente.

Where all of these are great example for creating themes, I hope this article helps take that concept to the next level by storing properties, easily switching between themes, giving users a way to customize a theme, and saving those preferences.

Let’s connect! You can DM me on Twitter with comments, or feel free to follow.


The post Theming and Theme Switching with React and styled-components appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Win a Copy of Zell Liew’s Learn JavaScript Course

January 7th, 2021 No comments

Zell Liew is giving away 10 free copies of his Learn JavaScript course, and entering the giveaway is pretty easy: sign up for his newsletter. I’ve personally subscribed for some time now and all I get is as occasional hand-written email with useful JavaScript gems. It’s sort of like winning no matter if you get the course or not.

If you jump down to the lesson plan, you’ll see that the course is chock-full of material, so this is no cheapie. There’s something like 300 lessons in there. Plus, Zell is a master at explaining incredibly complex things in a way that’s accessible to anyone, whether you’re getting started or looking to brush up your skills. Believe me, I’ve edited his work and I learn something from it every time.

That’s the spiel! Enter before Wednesday, January 13, to throw your hat in the ring.

Direct Link to ArticlePermalink


The post Win a Copy of Zell Liew’s Learn JavaScript Course appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

12 Best WordPress Themes for 2021 and their awesome features

January 7th, 2021 No comments

In all likelihood, you’ve already discovered the benefits of WordPress, and worked with one or more popular WordPress themes or other design aids.

Top WordPress themes typically bring both advantages and limitations to the table. As a consequence, a web designer is confronted with finding a theme that maximizes the former and minimizes the latter when addressing the task at hand.

Finding “the best WP theme” among the large number currently on the market can be a daunting task.

Fortunately, you don’t have to spend hours sifting through and evaluating a lengthy list of potential candidates. This collection of 12 top WordPress themes should make it easy to find one that will help you get your New Year off to a roaring start.

  1. Be Theme

With its 40+ core design features that includes a selection of 600+ pre-built websites, BeTheme easily qualifies as being the biggest multipurpose WordPress theme of them all. In addition, more than 200,000 sales attests to its popularity.

Every one of the core features brings something important or even necessary to the web designer. While there’s insufficient space here to cover them all, this sampling should suffice:

  • BeTheme’s Muffin Builder is a powerful page builder that when used with its other core features makes website building a quick, easy, and coding free adventure.
  • The Admin Panel and Shortcode Generator gives users all the options andflexibility needed to make it a genuine “if you can think of it you can build it” tool kit.
  • BeTheme’s 600+ customizable pre-built websites make it possible to get virtually any project off to a quick start. These professionally-crafted design aids cover 30 business sectors, a wide range of small business niches, and the major website types.

Click on the banner. There’s much more to see.

  1. Total WordPress Theme

Total was designed with perfection in mind, but the author still managed to make it a fast, friendly, and extremely flexible WordPress theme.

  • Total’s multiplicity of useful features won’t slow you down. You can disable any feature you won’t be working with.
  • Total’s Dynamic Template Function gives you the flexibility to customize a layout exactly the way you want to
  • The Theme Customizer allows you to change fonts, colors, column widths, or section widths as the need arises
  • Total features the WPBakery page builder, a host of pre-made demos and page-building modules.
  • Total is WooCommerce and WordPress plugin friendly.
  • To learn more about this drag and drop website-building theme simply click on the banner.
  1. Avada Theme

Avada stands out for a number of reasons, one being sales. This WordPress theme is the all-time best selling theme on the market. It’s trusted by more than 450,000 users, which says a lot.

That alone might be enough to convince you it would be “the best” theme for you, but let’s dig a little deeper.

  • Avada’s portable one-click demos, pre-built websites, and design elements give web designers plenty to work with
  • The drag and drop Fusion Builder, and the Fusion Theme Options and Fusion Page Options enable users to build complex sites without coding
  • Free lifetime updates ensure Avada is going to continue to improve, and 5-star support is there should you ever need it.

Avada lets you design what you want and in the way you want it. Click on the banner to find out more about this best-selling theme.

  1. Rey Theme

Lightweight, highly modular, WooCommerce and Elementor integrations, and stunning design elements all contribute to make Rey one of the most innovative WordPress themes on the market.

Rey features:

  • A selection of specialized WooCommerce tools
  • A library of professionally-designed templates
  • Easy set up and powerful performance
  • Built-in SVG support

Rey is SEO friendly, and developer friendly as well.

  1. TheGem – Creative Multi-Purpose High-Performance WordPress Theme

TheGem is the best-selling theme on ThemeForest, which isn’t surprising since its multiplicity of features has led to it’s being called the Swiss Army knife of WordPress themes.

  • TheGem WP theme includes more than 400 premium pre-built multi-page and onepage websites and templates with flexible customization options
  • Available for Elementor and WPBakery page builders
  • With extended WooCommerce tools & features for best online shopping
  • A large selection of TheGem blocks (pre-designed web-page sections) is also included in the package

TheGem is 5-star rated and is trusted by more than 50,000 customers.

  1. Uncode – Creative Multiuse & WooCommerce WordPress Theme

Uncode is a pixel-perfect multi-use popular theme that is ideal for artists and other creative types, agencies, and businesses.

  • Uncode is a ThemeForest best seller with 80.000+ sales to date
  • Uncode features a unique WooCommerce Custom Builder that gives site users supreme shopping experiences
  • This theme’s showcase of user-built websites is a “must see”. Click on the banner, visit the site, and be prepared to be impressed.
  1. Kalium – Professional theme for multiple uses

This top selling, highly rated premium theme is suitable for beginners as well a more advanced WordPress users.

  • Kalium features a large selection of professionally-designed demos and design elements that can easily be imported and put to immediate use
  • All of the popular WordPress plugins are supported. Slider Revolution, WPBakery, Elementor, WooCommerce and other plugins are included in the price.

Kalium is responsive, SEO friendly, and GDPR compliant.

  1. KnowAll – Knowledge Base Theme

If you’re spending an excessive amount of time answering repetitive questions and customers find your site’s FAQ page a source of irritation rather than an aide, it might be the time to invest in KnowAll.

KnowAll:

  • Provides instant answers to customers 24/7.
  • Provides detailed answers including related content suggestions
  • Helps customers formulate questions with its search capability

Customers will love what KnowAll does and your business will profit from it.

  1. Pofo – Creative Portfolio, Blog and eCommerce WordPress Theme

Pofo is ideal for use by creative types and agencies, and for creating portfolio, blogging, and eCommerce sites.

  • Pofo is extremely flexible, blazing fast, and SEO optimized
  • WPBakery and Revolution Slider plugins are included together with more than 150 pre-built elements and a large selection of home and demo pages
  • Detailed documentation is available online

Users can expect exceptional support.

  1. Hongo – Modern & Multipurpose WooCommerce WordPress Theme

This modern multipurpose theme with its trendy demos, templates, and creative design elements is a good choice for company websites, eCommerce store owners, and bloggers.

  • Hongo’s out of the box features include premium plugins and WPBakery custom shortcodes
  • Product page tools include quick view, compare, wish lists, filters, catalog mode, and more

Hongo is well documented and offers first-class customer and user support.

  1. XStore – The Most Complete & Customizable WooCommerce Theme

The XStore theme is focused on those things related to WooCommerce. As such, it is to be recommended if your next project is going to be an online store.

  • A key feature is its selection of 100+ go-to-go shops
  • The package also includes a built-in WooCommerce Email Builder, a Full Ajax Shop, a Single Product page builder, and $500+ worth of premium plugins

Developed by an 8Theme Elite Power Author, XStore has more than 20,000+ sales.

  1. Typer – Amazing Theme with Multi Author Publishing Features

Typer can transform your blog website into high-powered multi-author platform. Front-end publishing, article bookmarks, and searches and recommendations for like articles are among Typer’s many features.

  • Typer is Elementor and Gutenberg compatible
  • Beautiful user profiles and multiple article layouts will dress up your site
  • Features include an activity feed and weekly digest

Typer was developed by and Elite Author and enjoys a 5-star user rating.

*****

Any selection from a above listing of great WordPress themes should put you in a good place for the website design challenges you may encounter going into the New Year.

Since each of these top WordPress themes features the latest website and website design trends, there’s at least one here for you, whether your project is for your personal use or for a corporate entity.

We hope you enjoy your shopping experience.

Read More at 12 Best WordPress Themes for 2021 and their awesome features

Categories: Designing, Others Tags:

Styling Code In and Out of Blocks

January 6th, 2021 No comments

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

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

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

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

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

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

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

So you can use like rather than

... . Refactoring the components certainly gets a lot easier as changes percolate everywhere.

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

So!

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

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

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

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

CodePen Embed Fallback

Here’s a thought dump!

  • What do you do when a component depends on a third-party lib? The syntax highlighting here is done with Prism.js. To make it more isolated, I suppose you could copy and paste the whole lib in there somewhere, but that seems silly. Maybe you just document it?
  • Styling web components doesn’t feel like it has a great story yet, despite the fact that Shadow DOM is cool and useful.
  • Yanking in pre-formatted text to use in a template is super weird. I’m sure it’s possible to do without needing a
     tag inside the custom element, but it's clearly much easier if you grab the content from the 

    . Makes the API here just a smidge less friendly (because I'd prefer to use the  alone).
  • I wonder what a good practice is for passing along attributes that another library needs. Like is data-lang="CSS" OK to use (feels nicer), and then convert it to class="language-css" in the template because that's what Prism wants? Or is it better practice to just pass along attributes as they are? (I went with the latter.)
  • People complain that there aren't really “lifecycle methods” in native web components, but at least you have one: when the thing renders: connectedCallback. So, I suppose you should do all the manipulation of HTML and such before you do that final shadowRoot.appendChild(node);. I'm not doing that here, and instead am running Prism over the whole shadowRoot after it's been appended. Just seemed to work that way. I imagine it's probably better, and possible, to do it ahead of time rather than allow all the repainting caused by injecting spans and such.
  • The whole point of this is a nice API. Seems to me thing would be nicer if it was possible to drop un-escaped HTML in there to highlight and it could escape it for you. But that makes the fallback actually render that HTML which could be bad (or even theoretically insecure). What's a good story for that? Maybe put the HTML in HTML comments and test if <!-- is the start of the content and handle that as a special situation?

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


The post Styling Code In and Out of Blocks appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags:

Whack-a-Mole: The CSS Edition

January 6th, 2021 No comments

We’ve seen the checkbox hack and how it can be used to build a complete state machine in CSS. Today, we’ll take that line of thought a step further and build a simple game of Whack-A-Mole, where the player needs to react quickly to win … all without a touch of JavaScript.

This might seem a little silly in a language that doesn’t have any notion of timers or intervals, but the secret is that CSS does — it’s just packaged in a little feature called CSS Animations.

Take a look at this double-click handler. Note that CSS doesn’t know what a click is, much less a double click:

CodePen Embed Fallback

How does it work? Here’s a recording of the important elements, recolored and slowed down:

The idea is that when you click on the button for the first time, it moves the double-click element in place under the cursor, but it also causes a masking element to start moving up to cover it.

  • If the second click comes quickly enough after the first (as on the left side of the recording), it happens on the double-click (blue) element.
  • Otherwise (as on the right side of the recording), it happens on the masking (yellow) element, which has the effect of a single-click element.

(For an in-depth explanation, take a look at my write-up on the pure-CSS double-click handler here.)

There are two ideas in play here:

  1. Animations can be used to manage states according to a set pattern. (I’m using the term “state” loosely.)
  2. By changing an element’s position, we can change whether or not an user is allowed to take an action.

That’s all we need!

Now, instead of having our target scroll into view, we could instead use animation-timing-function: step-end to have it pop in and out, sort of like a mole in a hole:

CodePen Embed Fallback

I tried a few different options for moving the mole out of the way, and changing its absolute position — here left — seems to work the best. Using a translation would be convenient, but unfortunately leaves Firefox thinking the cursor is on the wrong element because changing transform in the Gecko layout engine doesn’t trigger a re-layout. (Normally, this would be a good thing for performance reasons, but not so much for our little demo!)

With a bit of styling, we can make it look more like a game element:

CodePen Embed Fallback

The “mole” here is basically a restyled CSS label that triggers the checkbox hack. So is the hole. When the mole’s animation takes it over the hole, clicking in the region triggers the mole’s radio input; when the mole is out of the way, clicking triggers the hole’s radio input.

The next step is to put a couple of holes next to each other and have the moles bounce around among them, each on a different negative animation-delay. With a state machine reading off which of the moles have been hit and which of the holes have been collapsed, it turns into a neat little game.

I used short Python scripts to generate both the state machine selectors and the mole keyframes. It gets a bit unwieldy for hand-coding otherwise. This is mostly because CSS also has no concept of random numbers, which leaves us no choice but to hardcode the “random” mole behavior.

CodePen Embed Fallback

There we have it: a complete reaction-based game, entirely in HTML and CSS.


The post Whack-a-Mole: The CSS Edition appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Categories: Designing, Others Tags: