What Were the Hottest Front-End Tools in 2021?

Another year has passed and once again I’ve had the privilege of going through the Web Tools Weekly newsletter archives from the past 12 months to hunt down the front-end tools that readers found to be the most interesting during 2021. So, to kick off 2022, I’ve compiled a list of the 60 most popular tools. I’m sure there are at least one or two listed here that you can start using in your front-end projects today.

Some of these front-end tools are super-practical, while others probably only made this list due to curiosity (which I base on the number of unique clicks). And since many of the tools that make my year-end lists are pretty new, I think this is a good indicator of the kinds of front-end tools that will be popular in the coming year.

Counting down from the top!

Table of contents


60. Open Props

Open Props provides a set of hand-crafted design tokens made up of CSS custom properties. I can see this sort of thing being much more common due to the use of this particular CSS feature. These allow you to drop in small collections of useful groups of custom properties, like animations.css, borders.css, fonts.css, zindex.css, etc, with more coming soon. Or you can just use the main Open Props file to grab everything at once.

Screenshot of the Open Props homepage which outlines three things that make it a useful front-end tool, including design tokens, consistent components, and useful in any framework.

This is definitely one front-end tool to keep an eye on and maybe even a good one to contribute to if you want to help build the library of tokens available.

59. NextUI

A modern React library that uses Stitches, a popular CSS-in-JS solution, and includes light and dark UI components out-of-the-box along with a default color palette that might be good for quickly building landing pages or other content that’s not initially tied to any branding.

It’s currently listed as being in Alpha stage of development, so this is another one worth keeping tabs on in the coming year.

58. Dopefolio

If you’re looking for an easy way to put together your own developer portfolio, Dopefolio is a quick solution that’s optimized for SEO and has strong Lighthouse scores out-of-the-box.

The live demo gives you an idea of what it looks like (responsive and all) and it includes a color picker component so you can live-test your own preferred primary color for the template.

57. Vizzu

This is a unique one that made this year’s list of front-end tools. Vizzu an open-source JavaScript library for creating animated data stories and visualizations. Maybe this is popular due the apparent need for creating and embedding medical data nowadays.

This library allows you to easily build static data charts, animated charts, and data stories. You can see some live examples of the animated charts or data stories, which include a data story showing which guest character had the most lines throughout the run of the TV series Friends.

56. 10015 Tools

I seem to find a handful of these types of front-end tools every year. 10015 Tools is a collection of front-end tools rather than one single tool. It includes text tools, image tools, CSS tools, coding tools (e.g. minifiers), color tools, social media tools, and a few others under a miscellaneous category.

This is definitely one of the more comprehensive all-in-one solutions I’ve seen, so I’m sure you’ll find a few useful front-end tools here you can come back to.

55. Snoweb

Icon sets are always popular and I come across at least a dozen new ones every year. This one includes optimized SVG icons, many of which have a built-in animated effect when you hover over the icon (like the open/close envelope icon).

Like many icon websites, you can search by keyword or filter by category, one of which is a “brand” category with icons for Twitter, Facebook, Vimeo, YouTube, Snapchat, etc.

54. Tails

Here’s the first Tailwind-based tool to make the list; something that’s been a trend the past few years as Tailwind continues to grow in popularity. This front-end tool a drag-and-drop page builder for projects using Tailwind CSS.

It includes two free “blocks” for each of the 15 categories, so there’s a decent amount of free stuff here and you can unlock the rest for a monthly fee.

53. MapLibre

This open-source mapping library launched in March and has grown in popularity throughout the year. It includes a JavaScript library as well as an SDK for displaying maps inside of iOS and Android apps.

The docs include a bunch of examples that use JavaScript, if you want to see what’s possible with the web-based front-end tools.

52. SVG Repo

SVG Repo makes the list based on sheer numbers alone. It’s a repository of more than 300,000 free, optimized, SVG-based graphics and icons most of which are licensed for commercial use.

Each icon you select tells you what type of license it falls under. You can search by keyword and “save” icons to your favorites for later use (no login required).

51. Animated Backgrounds

This one made the top 60 this year but probably isn’t the most practical front-end tool of the bunch. Like I said at the outset, some stuff gets clicked on just out of sheer curiosity. It’s a gallery of animated backgrounds, sourced from various CodePen demos.

The gallery is useful in that it displays the backgrounds as pre-recorded videos so you don’t have to worry about all the demos loading and crashing your browser tab. Use these sparingly, if ever, as they often use heavy amounts of JavaScript and CSS.

50. Pico.css

This is a different type of CSS framework compared to what’s popular nowadays. It’s kind of like an anti-Tailwind tool and more of a starter CSS file (like a reset) than a full-fledged framework.

Pico.css provides elegant default styles on all native HTML elements (which you can preview here) without the need to add swaths of classes to your markup — and the whole thing is less than 10kb minified and gzipped.

49. Coding Fonts

Coding fonts seem to be an exciting new trend of late, and CSS-Tricks has taken advantage of that with this little interactive info app.

Select a font on the left to display example code, typeface info (ligatures, italics, etc.), cost (most are free), along with options to display example code for HTML, CSS, or JavaScript.

48. UI-Neumorphism

This React library is based on the old skeumorphism trend that apparently went out of style a number of years ago. Is this trend making a comeback? Probably not. In fact, this React library is about two years old even though I shared it for the first time this past year.

The library includes a slew of different components that all implement “neumorphism” look. Interesting to look at, but might not fit many projects.

47. Beautiful CSS Buttons

Just about every app or website needs buttons, so a collection like this always seems to do well. Many of these are different from what you probably have seen elsewhere.

A lot of the buttons include interesting hover effects and you can easily copy and paste the HTML and CSS for any single button directly on the page.

46. Shaper

This interactive tool lets you fiddle with various UI settings live on the page to build different page elements. Once you’ve tweaked things as you like, you can grab the code, which uses CSS custom properties.

You can switch between demo view and “specs” view (i.e. the code along with other useful info). This tool has a particular focus on typography along with the rest of the UI styles, which is an important part of getting a layout looking right.

45. Prestige

This is a text-based HTTP client in the browser — like Postman but without an interface. It allows you to define requests in plain text, which you can optionally save as a Gist. It includes isolated cookie management, and has both dark and light modes.

As the author explains, “I built Prestige because I needed an app like this when working […] and playing with external APIs.”

44. HTML.cafe

This is probably the simplest tool in the entire list. HTML.cafe is more or less a poor-man’s CodePen, for lack of a better term. I wouldn’t think people would be interested in this sort of thing, since there are already powerful tools that already do what it does. Nonetheless, it’s a really simple HTML editor with live preview.

There are no separate CSS or JavaScript windows like there are CodePen, but you can easily include those in <style> or <script> elements if you wish. I think the best use of this tool might be for teachers helping students who are completely unfamiliar with HTML, as this gets all the complexities out of the way.

43. Charts.css

This front-end tool is sort of like a cross between Tailwind CSS and Chart.js. In short, Charts.css is a CSS framework that lets you use utility classes to build charts using HTML and CSS.

You can create bar charts, line charts, multi-dataset charts, percentage columns, and 3D bar charts. And best of all, the charts are accessible, responsive, and easy to customize to your branding needs.

42. Buttons Generator

“Buttons Generator” is probably a bit of a misnomer, since the page doesn’t exactly let you “generate” buttons. Like the previous buttons resource, this is a gallery of buttons built with HTML and CSS.

They’re divided up by category, include some neat hover or click effects, and you can click any button to copy the code to your clipboard.

41. Doodad Pattern Generator

This interactive tool allows you to build your own patterned backgrounds that you can export in a variety of formats. You can use the “shuffle” button to generate a random pattern, or select from various category styles. You can also edit colors, filters, and various transforms.

The export dialog lets you save patterns and load previously-saved ones via Local Storage. Export your patterns as JPEG, PNG, inline SVG, SVG file, or CSS background.

40. Kaboom

Every year I come across at least one or two new JavaScript game libraries, and this is the one that made this year’s list. It looks to have a fairly elegant and easy-to-use API and includes a healthy set of components, events, and other built-in functions.

There’s a handy playground to get your feet wet with using it and an introductory tutorial to get started.

39. Skuawk

If you want an alternative to Unsplash, which is likely one of your go-to sources for free stock images, this collection of beautiful public domain images might be a good option with some gorgeous photos.

There are 16 categories of images from various photographers that have all allowed their images to be used under a CC0 license (i.e. do whatever you want).

38. Glassmorphism CSS Generator

This is an online generator that lets you build a “glassmorphism” effect on a page element — kind of like frosted glass. This tool is apparently supposed to be part of a larger UI library that will incorporate this sort of effect on a number of different UI components.

Whatever the case, I like this effect more than the “neumorphism” one and apparently my audience agrees.

37. Kalia

This is one of three VS Code tools that made the list. It’s an attractive color scheme you can use for your VS Code setup.

The extension lists only about 800 installs so far, which is surprising, but it has a nice pastel color look that I think many will enjoy.

36. AdminJS

If you’re a Node developer, this is an open-source admin panel that can be added to a Node.js app. It will generate a UI for you, based on data you’ve added from almost any database, allowing you and your team to manage your app’s content.

You can try it out using this example app, which is based on MongoDB and Postgres.

35. Pancake

Here’s another game engine to build cross-platform HTML5-based 2D games. This one got a lot of traction when I first shared it. While it made the list,it seems to require Python during the build step after you write the game.

The basic API uses plain JavaScript and you can view lots of neat little examples here.

34. Mosaic Lite

I find lots of dashboard templates built with different front-end technologies. This one is made with Tailwind and React and includes optional chart components built with Chart.js.

Like other similar templates, this can be used for SaaS products, admin dashboards, and more. You can view a live demo.

33. Iconduck

Here’s another great source for open-source icons, this one offering well over 100,000 icons that are searchable by keyword and are all available for use in commercial projects.

The site includes ability to like and save icons and icon collections for later use (requires cookies, but no login).

32. Luxa CSS

This is a CSS library that was actually released in mid-to late 2020, but I shared it for the first time in 2021. It’s described as a “minimalist” CSS framework.

Luxa CSS includes some base styles, along with various components, helpers, and layout styles, which you can view in the docs or by checking out this CodePen collection.

31. Glitter

Glitter was definitely one of the strangest — yet coolest — front-end tools I came across over the past year and it seems to have drawn a lot of interest even though it’s as simple as any tool gets.

It’s a generator that produces text in a glitter-like style, which you can save as SVG. Definitely not for 99% of your projects, but a pretty cool text effect.

30. Components AI

When I originally shared this one, I was sharing the theme builder alone, which is what got it on this list. But it’s worth sharing the entire set of 15+ tools.

In addition to the theme builder, there’s a syntax highlighter builder, gradient and shadow tools, SVG pattern generators, animated backgrounds, and lots more.

29. Unicode Arrows

This is pretty straightforward. Unicode Arrows a one-stop location to copy and paste — you guessed it — Unicode arrows along with each arrow’s associated hex code.

Unicode Arrows

Not much else to say about this one except that the site lets you buy Unicode arrow jewellery. Not that a bunch of coding nerds would be interested in that, no way.

28. Type Scale Clamp Generator

This is not the first tool to attempt to generate a type scale for you, but it’s a relatively new one that incorporates CSS’s clamp() function.

The front-end tool allows you to select a range, font, preview text, and you can even test the responsiveness (though I don’t see how useful that latter feature is, considering this is just text).

27. AnimXYZ

This one is described as “the first composable CSS animation toolkit” with support for Vue and React. What that means exactly is that you don’t have to write any keyframes. It seems to be kind of like Tailwind for animations, since you’re only using HTML classes.

In addition to adding classes, the values are built entirely using CSS variables. That means you can customize the values as you wish by modifying the variables themselves.

26. Frontend Toolkit

Here’s another all-in-one tools solution that includes more than 20 tools for doing various coding and image-related tasks.

It includes tools for CSS, JSON, favicons, SVG, image compression, npm, regex, and more.

25. colorpalettes.earth

Here’s one that’s unique in the list and may inspire some cool designs. This tool displays color palettes sourced from images of nature (taken from Unsplash) that are included on the site, with new palettes added regularly.

Click any image and you’ll get a modal with access to the hex value for each of the colors that make up the image-derived palette.

24. Uncut

Adding to the diversity of this list, here’s a typeface catalogue that currently features 90 typefaces with a focus on contemporary, or modern, type.

All fonts included are open-source, so you’re free to use them in personal and commercial projects.

23. Lowdefy

Building internal tools seems to be a hot thing nowadays and this is one solution you might want to look into that lets you build your tools by writing YAML.

It’s described as an “open-source low-code framework to build web apps, admin panels, BI dashboards, workflows, and CRUD apps with ease.”

22. JavaScript Booster

This is a VS Code extension that aims to help you, as the it says on the tin, boost your JavaScript, TypeScript, and React coding productivity. The extension adds a light bulb icon at certain points in your code, indicating that you can instantly trigger predefined code refactorings.

Some examples include converting a regular function to an arrow function, flip an if-else construct, along with some React-specific refactorings.

21. Layout Patterns

This is one of the most recent additions to Google Developers’ web.dev resource that I’m assuming will continue to grow in the coming year.

It includes a number of UI patterns “built using modern CSS APIs.” In other words, it’s a very forward-thinking collection of CSS examples, but should be used with caution since some of the technologies incorporated may not have full browser support yet.

20. Baseline Background Remover

Admittedly, AI-based background remover tools have been a dime-a-dozen recently. This one is free and works really well from my brief testing with it.

You can upload an image of up to 5MB and it will accept JPEG and PNG files. The resulting image is downloaded as JPEG. Seems like the only thing missing from it is the ability to download the result as a transparent PNG, or with a custom background color.

19. Theatre.js

Here’s another animation library, but this time a JavaScript solution that allows you to animate DOM elements or WebGL using a convenient visual editor that works along with the code you write.

This is a really powerful tool that’s hard to encapsulate in just a few paragraphs. There’s a lenghty chapter-based video used throughout the docs that really helps if you want to get familiar with it.

18. Transition.css

Drop-in CSS libraries are always popular and I’ll usually find at least one or two good ones each year. This one includes some neat CSS transitions you probably haven’t seen elsewhere.

You can try them out right on the page. My favourites are the ones that incorporate some hesitation in the animation, for an added uniqueness.

This is sort of a catch-all for design systems as it features component examples sourced from real design systems built in various technologies — React, CSS, Angular, Vue, etc. — by various brands, including eBay, Goldman Sachs, GOV.UK, and lots more.

It works as a handy reference for anyone building their own design system, as you can compare the same components across the existing systems included here.

16. party.js

This is a fun and unique JavaScript library that lets you add particle effects to a web page, specifically confetti and sparkles.

You’ll only use this in very specific circumstances, but it’s nice that you can customize the particle shapes, number of particles, spread, and so on.

15. Headless UI

In the words of Nacho Libre, now we’re really getting down to the nitty gritty. This UI component library was released in late 2020 and has already amassed more than 12,000 stars on GitHub.

The components (dropdown menu, tabs, popover, etc.) are “headless.” That doesn’t mean their capa was detated; it means they’re unstyled so that you can brand them as you please. They’re also fully accessible, designed to integrate with Tailwind CSS, and are compatible with React and Vue. That’s right — this one hits almost every front-end buzzword for 2022.

14. Turbo

This is another one that did well throughout 2021 after a late 2020 release. It’s billed as “the speed of a single-page web application without having to write any JavaScript.”

In brief, Turbo is a library that lets you take advantage of four main features: Turbo Drive, Turbo Frames, Turbo Streams, and Turbo Native. These use web components to add single-page app-like performance and interactivity to your pages without the need to reinvent the wheel with heavy custom scripts.

13. tidy.js

This is a library of data-related JavaScript functions specifically for “tidying up” your data.

It includes 70+ functions under different categories (tidying, grouping, math, sequencing, etc.) and you can mess around with the different features using this playground.

12. Tail-Kit

This is the first Tailwind UI kit on the list of top front-end tools, and it’s a doozy. It has more than 250 open-source components that are compatible with React, Vue, and Angular.

There are components categorized under Elements, Forms, Commerce, Navigation, Sections, and Lists, or you can use from a number of templates, categorized under Dashboards, Landing Pages, and Error Pages.

11. Tailwind Components

And here’s another Tailwind UI kit, again featuring open-source components and templates under 13 more refined categories, along with an “awesome” category that includes free but premium components.

This site is more or less a directory of various community-contributed Tailwind components, rather than a cohesive set of UI elements like other kits.

10. Pikaday

A JavaScript date picker cracks the top 10 tools of the year in 2021 — who would have thunk it? It seems to check all the boxes necessary for a date picker component: No dependencies, lightweight, and uses modular CSS for styling.

Like a few other front-end tools on this list, this isn’t a new tool. It’s been around for a while, but I first shared it in 2021 and it amazingly ended up in this year’s top 10.

9. HTML Boilerplates

This is a practical little online HTML generator that lets you customize the type of HTML starter template you want to generate, providing toggle options for what to include. This is probably most useful for generating a quick template for a landing page or demo.

In all honesty, I think it would be good if the tool was updated to use a few more modern options, but for a simple HTML starting point this gets the job done.

8. Whirl

Here’s another CSS animation library, this time specifically a collection of animations for use as loading spinners. It includes 100+ animated loaders, some of which are really neat and unique.

I like how the animations in the list (which you can try right on the page) are categorized as pseudo-element, single element, and multi-element. The best one by far is the “pong” animation, though I question whether anyone would correctly classify that as indicative of “content loading”!

7. Riju

Imagine if CodePen and JSFiddle had a baby, then you chopped that baby into 224 pieces. That’s what Riju is — a fast online playground for just about every programming language.

I can’t imagine there’s any coding language you’d want to play around with that’s missing here and most of it is stuff that you don’t normally associate with running in the browser.

6. DevUI

This is an Angular toolkit that’s suitable for enterprise-level apps and includes components, icons, an admin dashboard template, and a design system for styling and branding.

I’m guessing this made the top 10 list of front-end tools because I didn’t specifically mention at first that it is for Angular apps (which isn’t clear on the home page either). Nonetheless, I did specify that it’s for enterprise-level projects, and that seemed to grab the attention of many.

5. Pollen

This library works as a foundation for your own design system, and its practicality is evident in its use of CSS custom properties.

It provides you with low-level design tokens that you can easily customize and extend. Modules include Typography, Layout, UI, Grid, and Colors. I’m guessing there will be more added to this, so it’s one to keep an eye on in the coming year.

4. AlterNight

Developers love VS Code, dark mode, and plugins. Combine those three things, and you have a great little front-end tool.

AlterNight is a beautiful VS Code theme and has a modest ~3,000 installs so far, but it was able to crack the top five in this year’s list.

3. UIsual

Here’s a collection of front-end templates, but with a bit of a twist that I think many seemed to appreciate: they’re greyscale.

The set currently includes eight templates with diverse layouts. With the lack of any color-based branding, these are a good option to customize to your own needs without looking like every other landing page out there.

2. Supabase UI

Here’s yet another open-source component library, this one for React and designed specifically for the Supabase product (an open-source Firebase alternative).

It’s Tailwind-ready and I should also point out that it’s still in early development. Nonetheless, it was popular enough to make it to number 2 on this list.

1. CSS Layout Generator

This was the most-clicked tool in my newsletter over the past year. It’s a full-featured CSS and JSX generator for producing different kinds of layouts using the CSS Grid Layout syntax.

Click on any of the five layout styles, and you’ll come to an interactive online editor that lets you mess around with various CSS Grid features like rows, columns, row gap, column gap, direction, grid alignment, and lots more. There’s quite a bit to play around with here, and apparently the tool will later include the Flexbox syntax for some of the examples.

What were your favorite front-end tools of 2021?

That wraps up this year’s list of most interesting front-end tools. I hope you found something here you can bookmark or start using in a new project. It’s pretty cool that this list contained such a variety of tools — there were UI kits, animation libraries, a stock photo site, image tools, and more.

Are there front-end tools not mentioned in this list that you enjoyed discovering over the past year? Feel free to drop it in the comments. You can also subscribe to my newsletter for more front-end tools in 2022 and feel free to hit me up if you’ve built something yourself that you’d like to share in a future issue.


What Were the Hottest Front-End Tools in 2021? originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

Using the CSS Me Not Bookmarklet to See (and Disable) CSS Files

Stoyan is absolutely correct. As much as we all love CSS, it’s still an important player in how websites load and using less of it is a good thing. He has a neat new bookmarklet called CSS Me Not to help diagnose unnecessary CSS files, but we’ll get to that in a moment.

The [problem] is that CSS is in the critical path, it blocks rendering and often even JavaScript execution. We love CSS, it’s magic, it can do unbelievable feats and fix broken UIs and manipulate images and draw amazing pictures. We love CSS. We just want… less of it, because of its inherently blocking nature.

Sometimes our sites use entire stylesheets that are simply unnecessary. I hate to admit it, but WordPress is a notorious offender here, loading stylesheets for plugins and blocks that you might not even really be using. I’m in that position on this site as I write. I just haven’t found the time to root out a couple of little stylesheets I don’t need from loading.

Stoyan created a quick bookmarklet called CSS Me Not to see all those CSS files. The big benefit, of course, is that it lets you know what you’re up against.

You could find these stylesheets in DevTools as well, but the CSS Me Not bookmarklet makes it extra easy and has a killer bonus feature: turning off those stylesheets. Testing the bookmarklet here on CSS-Tricks, I can see four stylesheets that WordPress loads (because of settings and plugins) that I know I don’t need.

Screenshot of a Chrome browser window showing the CSS Me Not bookmarklet circled in red just below the address bar, Below that is a table injected above the CSS-Tricks website showing six stylesheets including an action to disable a sheet, the sheet's media, the sheet's host, and the sheet's name.

If you wanted to do this in DevTools instead, you could filter your Network requests by CSS, find the stylesheet that you want to turn off, right-click and block it, and re-load.

DevTools window screenshot with the Network panel open and the select menu open on a listed stylsheet with the option to block the request URL highlighted in bright blue.

I’ve been fighting this fight for ages, dequeuing scripts and styles in WordPress that I don’t want.

Removing totally unused stylesheets is an obvious win, but there is the more squirrely issue of removing unused CSS. I mention in that post the one-true-way of really knowing if any particular CSS is unused, which is attaching a background-image to every selector and then checking the server logs after a decent amount of production time to see which of those images were never requested. Stoyan corroborates my story here:

UnCSS is sort of a “lab”. The “real world” may surprise you. So a trick we did at SomeCompany Inc. was to instrument all the CSS declarations at build time, where each selector gets a 1×1 transparent background image. Then rummage through the server logs after a week or so to see what is actually used.


Using the CSS Me Not Bookmarklet to See (and Disable) CSS Files originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

Mondrian Art in CSS From 5 Code Artists

Mondrian is famous for paintings with big thick black lines forming a grid, where each cell is white, red, yellow, or blue. This aesthetic pairs well with the notoriously rectangular web, and that hasn’t gone unnoticed over the years with CSS developers. I saw some Mondrian Art in CSS going around the other day and figured I’d go looking for others I’ve seen over the years and round them up.

Vasilis van Gemert:
What if Mondrian used CSS instead of paint?

Many people have tried to recreate a work of art by Mondriaan with CSS. It seems like a nice and simple exercise: rectangles are easy with CSS, and now with grid, it is easy to recreate most of his works. I tried it as well, and it turned out to be a bit more complicated than I thought. And the results are, well, surprising.

Screenshot of a webpage with a large serif font in various sizes reading What if Mondrian Used CSS instead of Paint? above two paragraphs discussing Mondrian Art in CSS.

Jen Simmons Lab:
Mondrian Art in CSS Grid

I love how Jen went the extra mile with the texture. Like most of these examples, CSS grid is used heavily.

Mondrian Art in CSS Grid from Jen Simmons. Includes rough grungy texture across the entire piece.

Jen Schiffer:
var t;: Piet Mondrian

I started with Mondrian not because he is my favorite artist (he is not), or that his work is very recognizeable (it is), but because I thought it would be a fun (yes) and easy start (lol nope) to this project.

Mondrian Art in CSS randomized 12 times in a 4 by 3 grid of boxes. A bright yellow header is above the grid bearing the site title: var t.

Riley Wong:
Make Your Own Mondrian-Style Painting with Code

There is a 12-step tutorial on GitHub.

Adam Fuhrer:
CSS Mondrian

Generative Piet Mondrian style art using CSS grid.

Screenshot of a full page Mondrian art example. There is a refresh button centered at the bottom of the page.

John Broers:
CSS Mondriaan Grid

An example of Mondrian Art in CSS with a "Generate New" option. The example is a square box with plenty of padding around it on the white background page.

Mondrian Art in CSS From 5 Code Artists originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

How to Build Your First Custom Svelte Transition

The Svelte transition API provides a first-class way to animate your components when they enter or leave the document, including custom Svelte transitions. By default, the transition directive uses CSS animations, which generally offer better performance and allow the browser’s main thread to remain unblocked. The API is as simple as this: <element transition:transitionFunction />. You can also specify in or out directives which are uni-directional transitions, only running when the element is mounted or unmounted.

An animated example of a custom Svelte transition showing a to do list. An item is typed and animated into the list of items when entered. Clicking a done button animates the item out of view.
Example of a working Svelte transition (jump to demo)

Svelte offers a runtime svelte/transition package that ships with seven prepackaged Svelte transition functions, all of which can be dropped in and tweaked to your heart’s desire. Pairing this with the svelte/easing package, allows for a wide swath of interactions, without writing any of the transition code yourself. Play around with different transitions and easing functions to get a feel for what is possible.

Looking for instructions on how to get started with Svelte? We have a solid overview for you to check out.

The Svelte Custom Transition API

If you need even more control than what the Svelte Transition API offers out of the box, Svelte permits you to specify your own custom transition function, as long as you adhere to a few conventions. From the docs, here’s what the custom transition API looks like:

transition = (node: HTMLElement, params: any) => 
  delay?: number,
  duration?: number,
  easing?: (t: number) => number,
  css?: (t: number, u: number) => string,
  tick?: (t: number, u: number) => void
 

Let’s break it down. A transition function takes a reference to the DOM node where the transition directive is used and returns an object with some parameters that control the animation and, most importantly, a css or tick function.

The css function’s job is to return a string of CSS that describes the animation, typically including some kind of transform or opacity change. Alternatively, you can opt to return a tick function, which lets you control every aspect of the animation with the power JavaScript, but pays a performance penalty since this type of transition does not use CSS animations.

Both the css and tick functions take two parameters called (t, u) by convention. t is a decimal number that travels from 0.00 to 1.00 while the element is entering the DOM and from 1.00 back to 0.00 when the element is leaving. The u parameter is the inverse of t or 1 - t at any given moment. For example, if you return a string of transform: scale($t), your element would smoothly animate from 0 to 1 on enter, and vice versa on exit.

These concepts may seem a bit abstract, so let’s solidify them by building our own custom Svelte transition!

Building your first custom Svelte transition

First, let’s set up some boilerplate that allows us to toggle an element’s existence in the DOM using a Svelte #if block. Remember, Svelte transitions only run when an element is actually leaving or entering the DOM.

<script>
  let showing = true
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked=showing />

#if showing
  <h1>Hello custom transition!</h1>
/if

You should be able to toggle the checkbox and see our element starkly appear and disappear in place.

Next, let’s set up our custom Svelte transition function and get it wired up to our element.

<script>
  let showing = true
  // Custom transition function
  function whoosh(node) 
    console.log(node)
  
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked=showing />

#if showing
  <h1 transition:whoosh>Hello custom transition!</h1>
/if

Now, if you toggle the checkbox, you will see the <h1> element logged to the console. This proves we have the custom transition connected properly! We won’t actually use the DOM node in our example, but it’s often useful to have access to the element to reference its current styles or dimensions.

For our element to do any animation at all, we need to return an object that contains a css (or tick) function. Let’s have our css function return a single line of CSS that scales our element. We’ll also return a duration property that controls how long the animation takes.

<script>
  function swoop() 
    return 
      duration: 1000,
      css: () => `transform: scale(.5)`
    
  
  let showing = true
</script>

<!-- markup -->

We’ve got something moving! You will notice our element jumps straight to .5 scale when toggling the checkbox. This is something, but it would feel much better if it smoothly transitioned. That’s where the (t, u) parameters come in.

<script>
  function swoop() 
    return 
      duration: 1000,
      css: (t) => `transform: scale($t)`
    
  
  let showing = true
</script>

<!-- markup -->

Now we are talking! Remember, t rolls smoothly from 0.00 to 1.00 when an element enters, and vice versa when it leaves. This allows us to achieve the smooth effect we want. In fact, what we just wrote is essentially the built-in scale transition from the svelte/transition package.

Let’s get a little bit fancier. To live up to our custom Svelte transition’s namesake, swoop, let’s add a translateX to our transform, so that our element zooms in and out from the side.

I want to challenge you to attempt the implementation first before we continue. Trust me, it will be fun! Assume that we want to translate to 100% when the element is leaving and back to 0% when it enters.

[waiting…]

How did it go? Want to compare answers?

Here’s what I got:

css: (t, u) => `transform: scale($t) translateX($u * 100%);`

It’s okay if you have something different! Let me break down what I did.

The key thing here is the usage of the second parameter in the css function. If we think about our animation while the element is entering the screen, we want to end up at scale(1) translateX(0%), so we can’t use unaltered t for both the scale and the transform. This is the convenience behind the u parameter — it is the inverse of t at any given moment, so we know it will be 0 when t is 1! I then multiplied u by 100 to get the percentage value and tacked on the % sign at the end.

Learning the interplay between t and u is an important piece of the custom transition puzzle in Svelte. These two parameters enable a world of dynamism for your animations; they can be divided, multiplied, twisted, or contorted into whatever needs you have.

Let’s slap my favorite svelte/easing function on our transition and call it a day:

<script>
  import  elasticOut  from 'svelte/easing'
  function swoop() 
    return 
      duration: 1000,
      easing: elasticOut,
      css: (t, u) => `transform: scale($t) translateX($u * 100%)`
    
  
  let showing = true
</script>

<label for="showing">
  Showing
</label>
<input id="showing" type="checkbox" bind:checked=showing />

#if showing
  <h1 transition:swoop>Hello custom transition!</h1>
/if

Wrapping up

Congratulations! You can now build a custom Svelte transition function. We have only scratched the surface of what is possible but I hope you feel equipped with the tools to explore even further. I would highly recommend reading the docs and going through the official tutorial to gain even more familiarity.


How to Build Your First Custom Svelte Transition originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

8 Helpful Accessibility Links for January 2022

Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Accessibility is one of those things! Here’s a list of related links to other articles that I’ve been saving up and think are worth sharing.

Screenshot of the Accessibility Maze homepage.

8 Helpful Accessibility Links for January 2022 originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

A Practical Tip For Using Sass Default Parameters

Sass offers functions and mixins that accept parameters. You can use Sass default parameters, that is, parameters that have a value even if you don’t provide them when the function or mixin is called.

Let’s focus on mixins here. Here’s the syntax of a mixin:

@mixin foo($a, $b, $c) 
  // I can use $a, $b, and $c in here, but there is a risk they are null


.el 
  @include foo(1, 2, 3);

  // if I tried to do `@include foo;`
  // ... which is valid syntax... 
  // I'd get `Error: Missing argument $a.` from Sass

It’s safer and more useful to set up default parameters in this Sass mixin:

@mixin foo($a: 1, $b: 2, $c: 3) 


.el 
  // Now this is fine
  @include foo;

  // AND I can send in params as well
  @include foo("three", "little", "pigs");

But what if I wanted to send in $b and $c, but leave $a as the Sass default parameter? The trick is that you send in named parameters:

@mixin foo($a: 1, $b: 2, $c: 3) 


.el 
  // Only sending in the second two params, $a will be the default.
  @include foo($b: 2, $c: 3);

A real-life example using Sass default parameters

Here’s a quick-y mixin that outputs what you need for very basic styled scrollbars (Kitty has one as well):

@mixin scrollbars(
  $size: 10px,
  $foreground-color: #eee,
  $background-color: #333
) 
  // For Google Chrome
  &::-webkit-scrollbar 
    width: $size;
    height: $size;
  
  &::-webkit-scrollbar-thumb 
    background: $foreground-color;
  
  &::-webkit-scrollbar-track 
    background: $background-color;
  

  // Standard version (Firefox only for now)
  scrollbar-color: $foreground-color $background-color;

Now I can call it like this:

.scrollable 
  @include scrollbars;


.thick-but-otherwise-default-scrollable 
  // I can skip $b and $c because they are second and third
  @include scrollbars(30px);


.custom-colors-scrollable 
  // I can skip the first param if all the others are named.
  @include scrollbars($foreground-color: orange, $background-color: black);


.totally-custom-scrollable 
  @include scrollbars(20px, red, black);

I’m just noting this as I had to search around a bit to figure this out. I was trying stuff like sending empty strings or null as the first parameter in order to “skip” it, but that doesn’t work. Gotta do the named parameter approach.


A Practical Tip For Using Sass Default Parameters originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

Parcel CSS: A New CSS Parser, Transformer, and Minifier

Hot off the presses from Devon Govett, creator of Parcel, is Parcel CSS:

A CSS parser, transformer, and minifier written in Rust.

Nice. The CSS world could use a little processing shake up like this.

I just wrote a few weeks ago:

Ya know how esbuild has seriously shaken things up for the JavaScript processing world? Maybe we need a cssbuild? It would process imports and do bundling (something we generally rely on Sass for). The point would be extreme speed. Maybe it would be plugin-based and compatible with the PostCSS API so that existing PostCSS plugins would work on it. Maybe it could make sourcemaps and do modification. Maybe it would run your Sass, too, I dunno. But something to spark the CSS ecosystem like that could be cool.

It looks like it doesn’t do bundling (standalone anyway). I suppose it would have to just invent a syntax for that, as I think Sass somewhat regrets the ambiguity of how it uses @import just like native CSS does and I wouldn’t blame anyone for not wanting to go down that road. It’s tricky territory, for sure, as inventing syntax kinda puts it into a different category of tool. I think it would be worth it though, as breaking up CSS into smaller files but bundling them in development is like… a thing people do.

So why run your CSS through this thing? From the docs, it looks like you’d wanna do that because…

  • it’s a minifier (looks like it’s cssnano under the hood),
  • it does vendor prefixing (looks like it’s Autoprefixer under the hood),
  • it can process as CSS modules (the classic library, not the native ones), and
  • you get sourcemaps.

But it seems like the killer Parcel CSS feature is what they are calling “Syntax lowering” meaning you can use “future” CSS today (like, say, nesting) by having it processed down to things that browsers understand, like Babel does in JavaScript.

Tow line charts chowing how fast Parcel CSS bundles packages and how small the resulting files are.
Parcel CSS is fast and outputs small files. (Source: @devongovett)

I have no idea what powers the syntax lowering bit, though it feels similar in spirit to postcss-preset-env. I’m unsure if that’s what’s being leveraged or not. I guess PostCSS is required for Autoprefixer which is being used, so maybe? I just don’t see it in the package.json.

Will Parcel CSS become an ecosystem?

So I guess the big question is: If Parcel CSS becomes the CSS parser of choice, will we get plugins? And if we do, will it become a robust ecosystem like PostCSS plugins?


Parcel CSS: A New CSS Parser, Transformer, and Minifier originally published on CSS-Tricks. You should get the newsletter and become a supporter.




Source link

Open Source & Sustainability

It’s a god-damned miracle to me that open source is as robust as it is in tech. Consider the options. You could have a job (or be entrepreneurial) with your coding skills and likely be paid quite well. Or, you could write code for free and have strangers yell at you every day at all hours. I like being a contributing kinda guy, but I don’t have the stomach for the latter because of the work that potentially comes with open source.

Fair enough, in reality, most developers do a bit of coding work on both sides. And clearly, they find some value in doing open-source work; otherwise, they wouldn’t do it. But we’ve all heard the stories. It leads to developer burnout, depression, and countless abandoned projects. It’s like we know how to contribute to an open-source project (and even have some ground rules on etiquette), but lack an understanding of how to maintain it.

Dave, in “Sustaining Maintaining,” thinks it might be a lack of education on how to manage open source:

There’s plenty of write-ups on GitHub about how to start a new open source project, or how to add tooling, but almost no information or best practices on how to maintain a project over years. I think there’s a big education gap and opportunity here. GitHub has an obvious incentive to increase num_developers and num_repos, but I think it’s worthwhile to ease the burden of existing developers and increase the quality and security of existing repos. Open source maintenance needs a manual.

That’s a wonderful idea. I’ve been around tech a hot minute, but I don’t feel particularly knowledgeable about how to operate an open-source project. And frankly, that makes me scared of it, and my fear makes me avoid doing it at all.

I know how to set up the basics, but what if the project blows up in popularity? How to I manage my time commitment do it? How do I handle community disputes? Do I need a request for comments workflow? Who can I trust to help? What are the monetization strategies? What are the security concerns? What do I do when there starts to be dozens, then hundreds, then thousands of open issues? What do I do when I stop caring about this project? How do I stop myself from burning it to the ground?

If there was more education around how to do this well, more examples out there of people doing it well and benefitting from it, and some attempts at guardrails from the places that host them, that would go a long way.

Money is a key factor. Whenever I see success in open source, I see actually usable amounts of money coming in. I see big donations appropriately coming into Vue. I see Automattic building an empire around their core open-source products. I see Greensock having an open-source library but offering membership and a license for certain use cases and having that sustain a team long-term.

If you’re interested in monetizing open source, Nicholas C. Zakas has been writing about it lately. It’s a three-parter so far, but starts here in “Making your open source project sponsor-ready, Part 1: Companies and trust”:

While it’s possible to bring in a decent amount of money through individual sponsorships, the real path to open source sustainability is to get larger donations from the companies that depend on your project. Getting $5 to $10 each month from a bunch of individuals is nice, but not as nice as getting $1,000 each month from a bunch of companies.

I think it would be cool to see a lot more developers making a proper healthy living on open source. If nothing else it would make me feel like this whole ecosystem is more stable.


Open Source & Sustainability originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link

How to Make a Pure CSS 3D Package Toggle

You know how you can get cardboard boxes that come totally flat? You fold ‘em up and tape ‘em to make them into a useful box. Then when it’s time to recycle them, you cut them back apart to flatten them. Recently, someone reached out to me about essentially this concept as a 3D animation and I thought it would make an interesting tutorial to do it entirely in CSS, so here we are!

How might that animation look? How could we create that packing timeline? Could the sizing be flexible? Let’s make a pure CSS package toggle.

Here’s what we’re working towards. Tap to pack and unpack the cardboard box.

Where to start?

Where do you even start with something like this? It’s best to plan ahead. We know we’re going to have a template for our package. And that will need folding up in three dimensions. If working with 3D in CSS is new to you, I recommend this article to get you started.

If you’re familiar with 3D CSS, it might be tempting to construct a cuboid and go from there. But, that’s going to pose some problems. We need to consider how a package goes from 2D to 3D.

Let’s start by creating a template. We need to plan ahead with our markup and think about how we want our packing animation to work. Let’s start with some HTML.

<div class="scene">
  <div class="package__wrapper">
    <div class="package">
      <div class="package__side package__side--main">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--tabbed">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
        <div class="package__side package__side--extra">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
          <div class="package__side package__side--flipped">
            <div class="package__flap package__flap--top"></div>
            <div class="package__flap package__flap--bottom"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Mixins are a good idea

There’s quite a bit happening there. It’s a lot of divs. I often like to use Pug for generating markup so I can split things up into reusable blocks. For example, every side will have two flaps. We can create a Pug mixin for the sides and use attributes to apply a modifier class name to make all that markup a lot easier to write.

mixin flaps()
  .package__flap.package__flap--top
  .package__flap.package__flap--bottom
      
mixin side()
  .package__side(class=`package__side--$`)
    +flaps()
    if block
      block

.scene
  .package__wrapper
    .package
      +side()(class="main")
        +side()(class="tabbed")
        +side()(class="extra")
          +side()(class="flipped")

We’re using two mixins. One creates the flaps for each side of the box. The other creates the sides of the box. Notice in the side mixin we are making use of block. That is where children of mixin usage get rendered which is particularly useful, as we need to nest some of the sides to make our lives easier later.

Our generated markup:

<div class="scene">
  <div class="package__wrapper">
    <div class="package">
      <div class="package__side package__side--main">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--tabbed">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
        <div class="package__side package__side--extra">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
          <div class="package__side package__side--flipped">
            <div class="package__flap package__flap--top"></div>
            <div class="package__flap package__flap--bottom"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Nesting the sides

Nesting the sides makes it easier to fold up our package. Much like each side has two flaps. The children of a side can inherit the sides’ transform and then apply their own. If we started with a cuboid, it would be hard to leverage this.

Screenshot showing HTML markup on the left and a rendering the unfolded cardboard box on the right. The markup shows how one of the box’s sides is a parent container that sets the broad side of the box and contains children for the corresponding top and bottom flaps. Orange arrows connect each element to the visual rendering to outline which parts of the box correspond in HTML correspond to the visual rendering.

Check out this demo that flips between nested and non-nested elements to see the difference in action.

Each box has a transform-origin set to the bottom right corner with 100% 100%. Checking the “Transform” toggle rotates each box 90deg. But, see how the behavior of that transform changes if we nest the elements.

We’re flipping between the two versions of markup but not changing anything else.

Nested:

<div class="boxes boxes--nested">
  <div class="box">
    <div class="box">
      <div class="box">
        <div class="box"></div>
      </div>
    </div>
  </div>
</div>

Not nested:

<div class="boxes">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

Transforming all the things

After applying some styles to our HTML, we have our package template.

The styles specify the different colors and position the sides to the package. Each side gets a position that’s relative to the “main” side. (You’ll see why all that nesting is useful in a moment.)

There are some things to be aware of. Much like working with cuboids, we are using --height, --width, and --depth variables for sizing. This will make it easier to change our package sizing down the line.

.package 
  height: calc(var(--height, 20) * 1vmin);
  width: calc(var(--width, 20) * 1vmin);

Why define sizing like this? We are using a unit-less default sizing of 20, an idea I picked up from Lea Verou’s 2016 CSS ConfAsia talk (starting at 52:44). Using custom properties as “data” instead of “values,” we are free to do what we want with them using calc(). Additionally, JavaScript doesn’t have to care about value units and we can change to pixels, a percentage, etc., without having to make changes elsewhere. You could refactor this into a coefficient in the --root, but it could also quickly become overkill.

The flaps for each side also need a size ever so smaller than the sides they are a part of. This is so we can see a slight gap as we would in real life. Also, the flaps on two sides need to sit a little lower. This is so that when we fold them up, we don’t get z-index fighting between them.

.package__flap 
  width: 99.5%;
  height: 49.5%;
  background: var(--flap-bg, var(--face-4));
  position: absolute;
  left: 50%;
  transform: translate(-50%, 0);

.package__flap--top 
  transform-origin: 50% 100%;
  bottom: 100%;

.package__flap--bottom 
  top: 100%;
  transform-origin: 50% 0%;

.package__side--extra > .package__flap--bottom,
.package__side--tabbed > .package__flap--bottom 
  top: 99%;

.package__side--extra > .package__flap--top,
.package__side--tabbed > .package__flap--top 
  bottom: 99%;

We’re also starting to consider the transform-origin for the individual pieces. A top flap will rotate from its bottom edge and a bottom flap will rotate from its top edge.

We can use a pseudo-element for the tab on that right side. We are using clip-path to get that desired shape.

.package__side--tabbed:after 
  content: '';
  position: absolute;
  left: 99.5%;
  height: 100%;
  width: 10%;
  background: var(--face-3);
  clip-path: polygon(0 0%, 100% 20%, 100% 80%, 0 100%);
  -webkit-clip-path: polygon(0 0%, 100% 20%, 100% 80%, 0 100%);
  transform-origin: 0% 50%;

Let’s start working with our template on a 3D plane. We can start by rotating the .scene on the X and Y axis.

.scene 
  transform: rotateX(-24deg) rotateY(-32deg) rotateX(90deg);

Folding up

We’re ready to start folding up our template! Our template will fold up based on a custom property, --packaged. If the value is 1, then we can fold up the template. For example, let’s fold some of the sides and the pseudo-element tab.

.package__side--tabbed,
.package__side--tabbed:after 
  transform: rotateY(calc(var(--packaged, 0) * -90deg)); 

.package__side--extra 
  transform: rotateY(calc(var(--packaged, 0) * 90deg));

Or, we could write a rule for all sides that aren’t the “main” one.

.package__side:not(.package__side--main),
.package__side:not(.package__side--main):after 
  transform: rotateY(calc((var(--packaged, 0) * var(--rotation, 90)) * 1deg));

.package__side--tabbed  --rotation: -90; 

And that would cover all the sides.

Remember when I said the nested sides allow us to inherit a parent’s transform? If we update our demo so we can change the value of --packaged, we can see how the value affects the transforms. Try sliding the --packaged value between 1 and 0 and you’ll see exactly what I mean.

Now that we have a way to toggle the folding state of our template, we can start working on some motion. Our previous demo flips between the two states. We can make use of transition for that. The quickest way? Add a transition to the transform of every child in the .scene.

.scene *,
.scene *::after 
  transition: transform calc(var(--speed, 0.2) * 1s);

Multi-step transitions!

But we don’t fold the template all up in one go — in real life, there’s a sequence to it where we’d fold up one side and its flap first then move on to the next, and so on. Scoped custom properties are perfect for this.

.scene *,
.scene *::after 
  transition: transform calc(var(--speed, 0.2) * 1s) calc((var(--step, 1) * var(--delay, 0.2)) * 1s);

Here we are saying that, for each transition, use a transition-delay of --step multiplied by --delay. The --delay value won’t change but each element can define which “step” it is in the sequence. And then we can be explicit about the order in which things happen.

.package__side--extra 
  --step: 1;

.package__side--tabbed 
  --step: 2;

.package__side--flipped,
.package__side--tabbed::after 
  --step: 3;

Consider the following demo for a better idea of how this works. Change the slider values to update the order in which things happen. Can you change which car wins?

That same technique is key for what we are going to for. We could even introduce an --initial-delay that adds a slight pause to everything for even more realism.

.race__light--animated,
.race__light--animated:after,
.car 
  animation-delay: calc((var(--step, 0) * var(--delay-step, 0)) * 1s);

If we look back at our package, we can take this further and apply a “step” to all the elements that are going to transform. It’s quite verbose but it does the job. Alternatively, you could inline these values in the markup.

.package__side--extra > .package__flap--bottom 
  --step: 4;

.package__side--tabbed > .package__flap--bottom 
  --step: 5;

.package__side--main > .package__flap--bottom 
  --step: 6;

.package__side--flipped > .package__flap--bottom 
  --step: 7;

.package__side--extra > .package__flap--top 
  --step: 8;

.package__side--tabbed > .package__flap--top 
  --step: 9;

.package__side--main > .package__flap--top 
  --step: 10;

.package__side--flipped > .package__flap--top 
  --step: 11;

But, it doesn’t feel very realistic.

Maybe we oughta flip the box, too

If I were folding up the box in real life, I’d likely flip the box up before folding in the top flaps. So how might we do that? Well, those with an eager eye might have noticed the .package__wrapper element. We are going to use this to slide the package. Then we’re going to rotate the package on the x-axis. This will create the impression of flipping the package onto its side.

.package 
  transform-origin: 50% 100%;
  transform: rotateX(calc(var(--packaged, 0) * -90deg));

.package__wrapper 
  transform: translate(0, calc(var(--packaged, 0) * -100%));

Adjusting the --step declarations accordingly gives us something like this.

Unfolding the box

If you flip between the folded and not folded states, you’ll notice that the unfold doesn’t look right. The unfolding sequence should be the exact reverse of the folding sequence. We could flip the --step based on --packaged and the number of steps. Our latest step is 15. We can update our transition to this:

.scene *,
.scene *:after 
  --no-of-steps: 15;
  --step-delay: calc(var(--step, 1) - ((1 - var(--packaged, 0)) * (var(--step) - ((var(--no-of-steps) + 1) - var(--step)))));
  transition: transform calc(var(--speed, 0.2) * 1s) calc((var(--step-delay) * var(--delay, 0.2)) * 1s);

That is quite the mouthful of calc to reverse the transition-delay. But, it works! We must remind ourselves to keep that --no-of-steps value up to date though!

We do have another option. As we continue down the “pure CSS” route, we will eventually make use of the checkbox hack to toggling between the folding states. We could have two sets of defined “steps” where one set is active when our checkbox gets checked. It’s certainly a more verbose solution. But, it does give us more finite control.

/* Folding */
:checked ~ .scene .package__side--extra 
  --step: 1;

/* Unfolding */
.package__side--extra 
  --step: 15;

Sizing and centering

Before we ditch the use of [dat.gui](https://github.com/dataarts/dat.gui) in our demo, let’s have a play with the size of our package. We want to check that our package remains centered while folding and flipping. In this demo, the package has a larger --height and the .scene has a dashed border.

We may as well tweak our transform to better center the package while we’re at it:

/* Considers package height by translating on z-axis */
.scene 
  transform: rotateX(calc(var(--rotate-x, -24) * 1deg)) rotateY(calc(var(--rotate-y, -32) * 1deg)) rotateX(90deg) translate3d(0, 0, calc(var(--height, 20) * -0.5vmin));

/* Considers package depth by sliding the depth before flipping */
.package__wrapper 
  transform: translate(0, calc((var(--packaged, 0) * var(--depth, 20)) * -1vmin));

This gives us reliable centering in the scene. It all comes down to preference though!

Adding in the checkbox hack

Now let’s get dat.gui out of the way and make this “pure” CSS. For this, we need to introduce a bunch of controls in the HTML. We are going to use a checkbox for folding and unfolding our package. Then we’re going to use a radio button to pick a package size.

<input id="package" type="checkbox"/>

<input id="one" type="radio" name="size"/>
<label class="size-label one" for="one">S</label>

<input id="two" type="radio" name="size" checked="checked"/>
<label class="size-label two" for="two">M</label>

<input id="three" type="radio" name="size"/>
<label class="size-label three" for="three">L</label>

<input id="four" type="radio" name="size"/>
<label class="size-label four" for="four">XL</label>

<label class="close" for="package">Close Package</label>
<label class="open" for="package">Open Package</label>

In the final demo, we will hide the inputs and make use of the label elements. For now, though, let’s leave them all visible. The trick is to use the sibling combinator (~) when certain controls get :checked. We can then set custom property values on the .scene.

#package:checked ~ .scene 
  --packaged: 1;

#one:checked ~ .scene 
  --height: 10;
  --width: 20;
  --depth: 20;

#two:checked ~ .scene 
  --height: 20;
  --width: 20;
  --depth: 20;

#three:checked ~ .scene 
  --height: 20;
  --width: 30;
  --depth: 20;

#four:checked ~ .scene 
  --height: 30;
  --width: 20;
  --depth: 30;

And here is the demo with that working!

Final polish

Now we’re in a place to make things look “pretty” and add some extra touches. Let’s start by hiding all the inputs.

input 
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;

We can style the sizing options as rounded buttons:

.size-label 
  position: fixed;
  top: var(--top);
  right: 1rem;
  z-index: 3;
  font-family: sans-serif;
  font-weight: bold;
  color: #262626;
  height: 44px;
  width: 44px;
  display: grid;
  place-items: center;
  background: #fcfcfc;
  border-radius: 50%;
  cursor: pointer;
  border: 4px solid #8bb1b1;
  transform: translate(0, calc(var(--y, 0) * 1%)) scale(var(--scale, 1));
  transition: transform 0.1s;

.size-label:hover 
  --y: -5;

.size-label:active 
  --y: 2;
  --scale: 0.9;

We want to be able to tap anywhere to toggle between folding and unfolding our package. So our .open and .close labels will take up the full screen. Wondering why we have two labels? It’s a little trick. If we use a transition-delay and scale up the appropriate label, we can hide both labels while the package transitions. This is how we combat spam tapping (even though it won’t stop a user hitting the space bar on a keyboard).

.close,
.open 
  position: fixed;
  height: 100vh;
  width: 100vw;
  z-index: 2;
  transform: scale(var(--scale, 1)) translate3d(0, 0, 50vmin);
  transition: transform 0s var(--reveal-delay, calc(((var(--no-of-steps, 15) + 1) * var(--delay, 0.2)) * 1s));


#package:checked ~ .close,
.open 
  --scale: 0;
  --reveal-delay: 0s;

#package:checked ~ .open 
  --scale: 1;
  --reveal-delay: calc(((var(--no-of-steps, 15) + 1) * var(--delay, 0.2)) * 1s);

Check out this demo to see where we’ve added background-color to both .open and .close. Neither label is visible during the transition.

We’ve got complete functionality! But, our package is a little underwhelming at the moment. Let’s add extra details to make things more “box”-like with things like parcel tape and packing labels.

Little details like this are only limited by our imagination! We can use our --packaged custom property to affect anything. For example, the .package__tape is transitioning the scaleY transform:

.package__tape 
  transform: translate3d(-50%, var(--offset-y), -2px) scaleX(var(--packaged, 0));

The thing to remember is that whenever we add a new feature that affects the sequence, we need to update our steps. Not only the --step values, but also the --no-of-steps value.

That’s it!

That’s how you make a pure CSS 3D package toggle. Are you going to drop this into your website? Unlikely! But, it’s fun to see how you might achieve these things with CSS. Custom properties are so powerful.

Why not get super festive and give the gift of CSS!

Stay Awesome! ʕ •ᴥ•ʔ


How to Make a Pure CSS 3D Package Toggle originally published on CSS-Tricks. You should get the newsletter and become a supporter.




Source link

What Would it Take to Prevent CSS Tooltips From Overflowing?

Say you have an elements with CSS tooltips and you’re going to position those tooltips such that it opens up next to the element on hover (or probably better: when clicked/tapped). Next to it where? Above it? What if the element is already really close to the top of the screen? In that case, it should probably open below it. Or vice versa — and the same goes for the left and right edges of the screen. You definitely want it to be visible rather than overflowing the viewport.

Sometimes when you open new UI elements, they need to be edge-aware to prevent the content inside from triggering weird scrollbars, or worse, cutting off content.

A red button and an orange button, both with CSS tooltips, sitting above two large paragraphs of text. The orange button is hovered, revealing a tooltip to the right of it but it is cut off by the edge of the viewport, making the content illegible.
Very important what?!

This is an age-old problem on the web. I remember using jQuery UI tooltips on purpose because it had this special ability to be edge-aware. You can imagine the JavaScript behind it. You figure out where the element is going to be and use positioning math to figure out if it will be within the viewport. If it won’t be, try a different position that does fit.

As ever, everything old is new again. Check out Floating UI, designed just for this problem.

FloatingUI home screen showing a logo that looks like a CSS tooltip with a happy face.

Floating UI is a low-level toolkit to position floating elements while intelligently keeping them in view. Tooltips, popovers, dropdowns, menus, and more.

It looks super well done. I like the focus, the demos are super well done, and it’s a pretty tiny dependency.

But ya know what would be even cooler? If CSS could do this all by itself. That’s the vibe with CSS Anchored Positioning — for now just an “explainer” document:

When building interactive components or applications, authors frequently want to leverage UI elements that can render in a “top-layer”. Examples of such UI elements include content pickers, teaching UI, tooltips, and menus. “Enabling Popups” introduced a new popup element to make many of these top-layer elements easier to author.

Authors frequently wish to “pin” or “anchor” such top-layer UI to a point on another element, referred to here as an “anchor element”. How the top-layer UI is positioned with respect to its anchor element is further influenced or constrained by the edges of the layout viewport.

A four-by-four grid showing the same blue button positioned at different corners of each cell, and a tooltip that avoids the edge of the screen where the button sits.

I love it. The web platform at its best. Seeing what authors are needing to do and reaching for libraries to do, and trying to step in and do it natively (and hopefully better).


What Would it Take to Prevent CSS Tooltips From Overflowing? originally published on CSS-Tricks. You should get the newsletter and become a supporter.


Source link